NEAR Price:
All Filters
Txns
Blocks
Addresses
Tokens
MT Tokens
Switch Network
Toggle Theme
Home
Blockchain
Tokens
Developers
Languages
Toggle Menu
Transaction Details
API
Overview
Execution Plan
Enhanced Plan
Tree Plan
Receipts Summary
Output
Inspect
Result:
Logs:
NEAR Price:
$1.84
(+2.89%)
set
TRANSFER
Hide 108956 bytes
JSON
UTF-8
Hex
Base64
Raw
{
"data"
:
{
"devhub.efiz.near"
:
{
"widget"
:
{
"app"
:
{
""
:
"/**\\n * This is the main entry point for the DevHub application.\\n * Page route gets passed in through params, along with all other page props.\\n */\\n\\nconst { page, ...passProps } = props;\\n\\n// Import our modules\\nconst { AppLayout } = VM.require(\\n \\\"devhub.efiz.near/widget/devhub.components.templates.AppLayout\\\"\\n);\\n\\nif (!AppLayout) {\\n return <p>Loading modules...</p>;\\n}\\n\\n// CSS styles to be used across the app.\\n// Define fonts here, as well as any other global styles.\\nconst Theme = styled.div`\\n a {\\n color: inherit;\\n }\\n\\n .attractable {\\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\\n transition: box-shadow 0.6s;\\n\\n &:hover {\\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\\n }\\n }\\n`;\\n\\nif (!page) {\\n // If no page is specified, we default to the feed page TEMP\\n page = \\\"home\\\";\\n}\\n\\n// This is our navigation, rendering the page based on the page parameter\\nfunction Page() {\\n const routes = page.split(\\\".\\\");\\n switch (routes[0]) {\\n case \\\"home\\\": {\\n return (\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.page.home\\\"\\n props={passProps}\\n />\\n );\\n }\\n // ?page=communities\\n case \\\"communities\\\": {\\n return (\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.page.communities\\\"}\\n props={passProps}\\n />\\n );\\n }\\n // ?page=community\\n case \\\"community\\\": {\\n return (\\n // Considering to consolsidate this into a single widget,\\n // where each level handles its own routing.\\n // Modularizing a page just like we do with addons\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.entity.community.Provider\\\"}\\n props={{\\n ...passProps,\\n Children: (p) => {\\n // passing props from the Provider into the Children\\n switch (routes[1]) {\\n // ?page=community.configuration\\n case \\\"configuration\\\": {\\n return (\\n <Widget\\n src={\\n \\\"devhub.efiz.near/widget/devhub.page.community.configuration\\\"\\n }\\n props={{\\n ...passProps,\\n ...p,\\n }}\\n />\\n );\\n }\\n // ?page=community\\n default: {\\n return (\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.page.community.index\\\"}\\n props={{\\n ...passProps,\\n ...p,\\n }}\\n />\\n );\\n }\\n }\\n },\\n }}\\n />\\n );\\n }\\n // ?page=feed\\n case \\\"feed\\\": {\\n return (\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.page.feed\\\"}\\n props={passProps}\\n />\\n );\\n }\\n // ?page=create\\n case \\\"create\\\": {\\n return (\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.page.create\\\"}\\n props={passProps}\\n />\\n );\\n }\\n // ?page=about\\n case \\\"about\\\": {\\n return (\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.page.about\\\"}\\n props={passProps}\\n />\\n );\\n }\\n case \\\"contribute\\\": {\\n return (\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.page.contribute\\\"}\\n props={passProps}\\n />\\n );\\n }\\n case \\\"profile\\\": {\\n return (\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.page.profile\\\"}\\n props={passProps}\\n />\\n );\\n }\\n // ?page=blog\\n case \\\"blog\\\": {\\n return (\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.page.blog\\\"}\\n props={passProps}\\n />\\n );\\n }\\n case \\\"post\\\": {\\n return (\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.page.post\\\"}\\n props={passProps}\\n />\\n );\\n }\\n\\n default: {\\n // TODO: 404 page\\n return <p>404</p>;\\n }\\n }\\n}\\n\\nreturn (\\n <Theme>\\n <AppLayout page={page}>\\n <Page />\\n </AppLayout>\\n </Theme>\\n);\\n"
}
,
"devhub.page.post"
:
{
""
:
"const { id } = props;\\n\\nreturn (\\n <div className=\\\"p-5\\\">\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.entity.post.Post\\\"}\\n props={{\\n id,\\n }}\\n />\\n </div>\\n);\\n"
}
,
"devhub.entity.post.List"
:
{
""
:
"// This component implementation was forked from [IndexFeed], but it does not fully implement lazy loading.\\n// While this component uses InfiniteScroll, it still loads the whole list of Post IDs in one view call.\\n// The contract will need to be extended with pagination support, yet, even in the current state the page loads much faster.\\n// [IndexFeed]: https://near.social/#/mob.near/widget/WidgetSource?src=mob.near/widget/IndexFeed\\n\\nconst { href } = VM.require(\\\"devhub.efiz.near/widget/core.lib.url\\\");\\n\\nhref || (href = () => {});\\n\\n/* INCLUDE: \\\"core/lib/draftstate\\\" */\\nconst DRAFT_STATE_STORAGE_KEY = \\\"POST_DRAFT_STATE\\\";\\nlet is_edit_or_add_post_transaction = false;\\nlet transaction_method_name;\\n\\nif (props.transactionHashes) {\\n const transaction = fetch(\\\"https://rpc.mainnet.near.org\\\", {\\n method: \\\"POST\\\",\\n headers: {\\n \\\"content-type\\\": \\\"application/json\\\",\\n },\\n body: JSON.stringify({\\n jsonrpc: \\\"2.0\\\",\\n id: \\\"dontcare\\\",\\n method: \\\"tx\\\",\\n params: [props.transactionHashes, context.accountId],\\n }),\\n });\\n transaction_method_name =\\n transaction?.body?.result?.transaction?.actions[0].FunctionCall.method_name;\\n\\n is_edit_or_add_post_transaction =\\n transaction_method_name == \\\"add_post\\\" ||\\n transaction_method_name == \\\"edit_post\\\";\\n\\n if (is_edit_or_add_post_transaction) {\\n Storage.privateSet(DRAFT_STATE_STORAGE_KEY, undefined);\\n }\\n}\\n\\nconst onDraftStateChange = (draftState) =>\\n Storage.privateSet(DRAFT_STATE_STORAGE_KEY, JSON.stringify(draftState));\\nlet draftState;\\ntry {\\n draftState = JSON.parse(Storage.privateGet(DRAFT_STATE_STORAGE_KEY));\\n} catch (e) {}\\n/* END_INCLUDE: \\\"core/lib/draftstate\\\" */\\n\\nconst QUERYAPI_ENDPOINT = `https://near-queryapi.api.pagoda.co/v1/graphql/`;\\n\\nconst queryName =\\n props.queryName ?? `bo_near_devhub_v17_posts_with_latest_snapshot`;\\n\\nconst query = `query DevhubPostsQuery($limit: Int = 100, $offset: Int = 0, $where: ${queryName}_bool_exp = {}) {\\n ${queryName}(\\n limit: $limit\\n offset: $offset\\n order_by: {block_height: desc}\\n where: $where\\n ) {\\n post_id\\n }\\n }\\n`;\\n\\nfunction fetchGraphQL(operationsDoc, operationName, variables) {\\n return asyncFetch(QUERYAPI_ENDPOINT, {\\n method: \\\"POST\\\",\\n headers: { \\\"x-hasura-role\\\": `bo_near` },\\n body: JSON.stringify({\\n query: operationsDoc,\\n variables: variables,\\n operationName: operationName,\\n }),\\n });\\n}\\n\\nfunction searchConditionChanged() {\\n return (\\n props.author != state.author ||\\n props.term != state.term ||\\n props.tag != state.tag ||\\n props.recency != state.recency\\n );\\n}\\n\\nfunction updateSearchCondition() {\\n State.update({\\n author: props.author,\\n term: props.term,\\n tag: props.tag,\\n recency: props.recency,\\n loading: true,\\n });\\n}\\n\\nfunction getPostIds() {\\n if (searchConditionChanged()) {\\n updateSearchCondition();\\n return;\\n }\\n let where = {};\\n let authorId = props.author;\\n let label = props.tag;\\n if (authorId) {\\n where = { author_id: { _eq: authorId }, ...where };\\n }\\n if (props.term) {\\n where = { description: { _ilike: `%${props.term}%` }, ...where };\\n }\\n if (label) {\\n if (typeof label === \\\"string\\\") {\\n // Handle a single label\\n where = { labels: { _contains: label }, ...where };\\n } else if (Array.isArray(label)) {\\n // Handle an array of labels\\n where = {\\n labels: {\\n _containsAny: label,\\n },\\n ...where,\\n };\\n }\\n }\\n if (!props.recency) {\\n // show only top level posts\\n where = { parent_id: { _is_null: true }, ...where };\\n }\\n\\n // Don\\\'t show blog\\n where = {\\n _not: {\\n labels: { _contains: \\\"blog\\\" },\\n parent_id: { _is_null: true },\\n post_type: { _eq: \\\"Comment\\\" },\\n },\\n ...where,\\n };\\n\\n console.log(\\\"searching for\\\", where);\\n fetchGraphQL(query, \\\"DevhubPostsQuery\\\", {\\n limit: 100,\\n offset: 0,\\n where,\\n }).then((result) => {\\n if (result.status === 200) {\\n console.log(\\\"search success\\\");\\n if (result.body.data) {\\n const data = result.body.data[queryName];\\n State.update({\\n postIds: data.map((p) => p.post_id),\\n loading: false,\\n });\\n console.log(\\\"found:\\\");\\n console.log(data);\\n }\\n } else {\\n console.error(\\\"error:\\\", result.body);\\n State.update({ loading: false });\\n }\\n });\\n}\\n\\nState.init({\\n period: \\\"week\\\",\\n});\\n\\ngetPostIds();\\n\\nfunction defaultRenderItem(postId, additionalProps) {\\n if (!additionalProps) {\\n additionalProps = {};\\n }\\n // It is important to have a non-zero-height element as otherwise InfiniteScroll loads too many items on initial load\\n return (\\n <div className=\\\"py-2\\\" style={{ minHeight: \\\"150px\\\" }}>\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.entity.post.Post\\\"}\\n props={{\\n id: postId,\\n expandable: true,\\n defaultExpanded: false,\\n isInList: true,\\n draftState,\\n isPreview: false,\\n onDraftStateChange,\\n ...additionalProps,\\n referral: postId,\\n }}\\n />\\n </div>\\n );\\n}\\n\\nconst renderItem = props.renderItem ?? defaultRenderItem;\\n\\nconst cachedRenderItem = (item, i) => {\\n if (props.term) {\\n return renderItem(item, {\\n searchKeywords: [props.term],\\n });\\n }\\n\\n const key = JSON.stringify(item);\\n\\n if (!(key in state.cachedItems)) {\\n state.cachedItems[key] = renderItem(item);\\n State.update();\\n }\\n return state.cachedItems[key];\\n};\\n\\nconst initialRenderLimit = props.initialRenderLimit ?? 3;\\nconst addDisplayCount = props.nextLimit ?? initialRenderLimit;\\n\\nconst ONE_DAY = 60 * 60 * 24 * 1000;\\nconst ONE_WEEK = 60 * 60 * 24 * 1000 * 7;\\nconst ONE_MONTH = 60 * 60 * 24 * 1000 * 30;\\n\\nfunction getHotnessScore(post) {\\n //post.id - shows the age of the post, should grow exponentially, since newer posts are more important\\n //post.likes.length - linear value\\n const age = Math.pow(post.id, 5);\\n const comments = post.comments;\\n const commentAge = comments.reduce((sum, age) => sum + Math.pow(age, 5), 0);\\n const totalAge = age + commentAge;\\n //use log functions to make likes score and exponentially big age score close to each other\\n return Math.log10(post.likes.length) + Math.log(Math.log10(totalAge));\\n}\\n\\nconst getPeriodText = (period) => {\\n let text = \\\"Last 24 hours\\\";\\n if (period === \\\"week\\\") {\\n text = \\\"Last week\\\";\\n }\\n if (period === \\\"month\\\") {\\n text = \\\"Last month\\\";\\n }\\n return text;\\n};\\n\\nlet postIds = state.postIds ?? null;\\n\\nconst loader = (\\n <div className=\\\"loader\\\" key={\\\"loader\\\"}>\\n <span\\n className=\\\"spinner-grow spinner-grow-sm me-1\\\"\\n role=\\\"status\\\"\\n aria-hidden=\\\"true\\\"\\n />\\n Loading ...\\n </div>\\n);\\n\\nif (postIds === null) {\\n return loader;\\n}\\nconst initialItems = postIds;\\n//const initialItems = postIds.map(postId => ({ id: postId, ...Near.view(nearDevGovGigsContractAccountId, \\\"get_post\\\", { post_id: postId }) }));\\n\\n// const computeFetchFrom = (items, limit) => {\\n// if (!items || items.length < limit) {\\n// return false;\\n// }\\n// const blockHeight = items[items.length - 1].blockHeight;\\n// return index.options.order === \\\"desc\\\" ? blockHeight - 1 : blockHeight + 1;\\n// };\\n\\n// const mergeItems = (newItems) => {\\n// const items = [\\n// ...new Set([...newItems, ...state.items].map((i) => JSON.stringify(i))),\\n// ].map((i) => JSON.parse(i));\\n// items.sort((a, b) => a.blockHeight - b.blockHeight);\\n// if (index.options.order === \\\"desc\\\") {\\n// items.reverse();\\n// }\\n// return items;\\n// };\\n\\nconst jInitialItems = JSON.stringify(initialItems);\\nif (state.jInitialItems !== jInitialItems) {\\n // const jIndex = JSON.stringify(index);\\n // if (jIndex !== state.jIndex) {\\n State.update({\\n jIndex,\\n jInitialItems,\\n items: initialItems,\\n fetchFrom: false,\\n //nextFetchFrom: computeFetchFrom(initialItems, index.options.limit),\\n nextFetchFrom: false,\\n displayCount: initialRenderLimit,\\n cachedItems: {},\\n });\\n // } else {\\n // State.update({\\n // jInitialItems,\\n // items: mergeItems(initialItems),\\n // });\\n // }\\n}\\n\\nif (state.fetchFrom) {\\n // TODO: fetchFrom\\n // const limit = addDisplayCount;\\n // const newItems = Social.index(\\n // index.action,\\n // index.key,\\n // Object.assign({}, index.options, {\\n // from: state.fetchFrom,\\n // subscribe: undefined,\\n // limit,\\n // })\\n // );\\n // if (newItems !== null) {\\n // State.update({\\n // items: mergeItems(newItems),\\n // fetchFrom: false,\\n // nextFetchFrom: computeFetchFrom(newItems, limit),\\n // });\\n // }\\n}\\n\\nconst makeMoreItems = () => {\\n State.update({\\n displayCount: state.displayCount + addDisplayCount,\\n });\\n if (\\n state.items.length - state.displayCount < addDisplayCount * 2 &&\\n !state.fetchFrom &&\\n state.nextFetchFrom &&\\n state.nextFetchFrom !== state.fetchFrom\\n ) {\\n State.update({\\n fetchFrom: state.nextFetchFrom,\\n });\\n }\\n};\\n\\nconst fetchMore =\\n props.manual &&\\n (state.fetchFrom && state.items.length < state.displayCount\\n ? loader\\n : state.displayCount < state.items.length && (\\n <div key={\\\"loader more\\\"}>\\n <a href=\\\"javascript:void\\\" onClick={(e) => makeMoreItems()}>\\n {props.loadMoreText ?? \\\"Load more...\\\"}\\n </a>\\n </div>\\n ));\\n\\nconst items = state.items ? state.items.slice(0, state.displayCount) : [];\\n\\nconst renderedItems = items.map(cachedRenderItem);\\n\\nconst Head =\\n props.recency == \\\"hot\\\" ? (\\n <div class=\\\"row\\\">\\n <div class=\\\"fs-5 col-6 align-self-center\\\">\\n <i class=\\\"bi-fire\\\"></i>\\n <span>Hottest Posts</span>\\n </div>\\n <div class=\\\"col-6 dropdown d-flex justify-content-end\\\">\\n <a\\n class=\\\"btn btn-secondary dropdown-toggle\\\"\\n href=\\\"#\\\"\\n role=\\\"button\\\"\\n id=\\\"dropdownMenuLink\\\"\\n data-bs-toggle=\\\"dropdown\\\"\\n aria-expanded=\\\"false\\\"\\n >\\n {getPeriodText(state.period)}\\n </a>\\n\\n <ul class=\\\"dropdown-menu\\\" aria-labelledby=\\\"dropdownMenuLink\\\">\\n <li>\\n <button\\n class=\\\"dropdown-item\\\"\\n onClick={() => {\\n State.update({ period: \\\"day\\\" });\\n }}\\n >\\n {getPeriodText(\\\"day\\\")}\\n </button>\\n </li>\\n <li>\\n <button\\n class=\\\"dropdown-item\\\"\\n onClick={() => {\\n State.update({ period: \\\"week\\\" });\\n }}\\n >\\n {getPeriodText(\\\"week\\\")}\\n </button>\\n </li>\\n <li>\\n <button\\n class=\\\"dropdown-item\\\"\\n onClick={() => {\\n State.update({ period: \\\"month\\\" });\\n }}\\n >\\n {getPeriodText(\\\"month\\\")}\\n </button>\\n </li>\\n </ul>\\n </div>\\n </div>\\n ) : (\\n <></>\\n );\\n\\nreturn (\\n <>\\n {Head}\\n {state.loading ? loader : null}\\n {is_edit_or_add_post_transaction ? (\\n <p class=\\\"text-secondary mt-4\\\">\\n Post {transaction_method_name == \\\"edit_post\\\" ? \\\"edited\\\" : \\\"added\\\"}{\\\" \\\"}\\n successfully. Back to{\\\" \\\"}\\n <Link\\n style={{\\n color: \\\"#3252A6\\\",\\n }}\\n className=\\\"fw-bold\\\"\\n to={href({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"feed\\\" },\\n })}\\n >\\n feed\\n </Link>\\n </p>\\n ) : state.items.length > 0 ? (\\n <InfiniteScroll\\n pageStart={0}\\n loadMore={makeMoreItems}\\n hasMore={state.displayCount < state.items.length}\\n loader={loader}\\n >\\n {renderedItems}\\n </InfiniteScroll>\\n ) : (\\n <p class=\\\"text-secondary\\\">\\n No posts{\\\" \\\"}\\n {props.term || props.tag || props.author ? \\\"matches search\\\" : \\\"\\\"}\\n {props.recency === \\\"hot\\\"\\n ? \\\" in \\\" + getPeriodText(state.period).toLowerCase()\\n : \\\"\\\"}\\n </p>\\n )}\\n </>\\n);\\n"
}
,
"devhub.entity.post.Post"
:
{
""
:
"// Ideally, this would be a page\\n\\nconst { href } = VM.require(\\\"devhub.efiz.near/widget/core.lib.url\\\");\\n\\nhref || (href = () => {});\\n\\nconst ButtonWithHover = styled.button`\\n background-color: #fff;\\n &:hover {\\n background-color: #e9ecef;\\n color: #000;\\n }\\n`;\\n\\nconst postId = props.post.id ?? (props.id ? parseInt(props.id) : 0);\\nconst post =\\n props.post ??\\n Near.view(\\\"devgovgigs.near\\\", \\\"get_post\\\", { post_id: postId });\\nif (!post) {\\n return <div>Loading ...</div>;\\n}\\n\\nconst referral = props.referral;\\nconst currentTimestamp = props.timestamp ?? post.snapshot.timestamp;\\nconst compareTimestamp = props.compareTimestamp ?? \\\"\\\";\\nconst swapTimestamps = currentTimestamp < compareTimestamp;\\n\\nconst snapshotHistory = post.snapshot_history;\\nconst snapshot =\\n currentTimestamp === post.snapshot.timestamp\\n ? post.snapshot\\n : (snapshotHistory &&\\n snapshotHistory.find((s) => s.timestamp === currentTimestamp)) ??\\n null;\\nconst compareSnapshot =\\n compareTimestamp === post.snapshot.timestamp\\n ? post.snapshot\\n : (snapshotHistory &&\\n snapshotHistory.find((s) => s.timestamp === compareTimestamp)) ??\\n null;\\n\\n// If this post is displayed under another post. Used to limit the size.\\nconst isUnderPost = props.isUnderPost ? true : false;\\nconst parentId = Near.view(\\\"devgovgigs.near\\\", \\\"get_parent_id\\\", {\\n post_id: postId,\\n});\\n\\nconst childPostIdsUnordered =\\n Near.view(\\\"devgovgigs.near\\\", \\\"get_children_ids\\\", {\\n post_id: postId,\\n }) ?? [];\\n\\nconst childPostIds = props.isPreview ? [] : childPostIdsUnordered.reverse();\\nconst expandable = props.isPreview ? false : props.expandable ?? false;\\nconst defaultExpanded = expandable ? props.defaultExpanded : true;\\n\\nconst draftState = props.draftState;\\n\\nfunction readableDate(timestamp) {\\n var a = new Date(timestamp);\\n return a.toDateString() + \\\" \\\" + a.toLocaleTimeString();\\n}\\n\\nconst timestamp = readableDate(\\n snapshot.timestamp ? snapshot.timestamp / 1000000 : Date.now()\\n);\\n\\nconst postSearchKeywords = props.searchKeywords ? (\\n <div style={{ \\\"font-family\\\": \\\"monospace\\\" }} key=\\\"post-search-keywords\\\">\\n <span>Found keywords: </span>\\n {props.searchKeywords.map((tag) => (\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.components.atom.Tag\\\"}\\n props={{ linkTo: \\\"Feed\\\", tag }}\\n />\\n ))}\\n </div>\\n) : (\\n <div key=\\\"post-search-keywords\\\"></div>\\n);\\n\\nconst searchKeywords = props.searchKeywords ? (\\n <div class=\\\"mb-4\\\" key=\\\"search-keywords\\\">\\n <small class=\\\"text-muted\\\">{postSearchKeywords}</small>\\n </div>\\n) : (\\n <div key=\\\"search-keywords\\\"></div>\\n);\\n\\nconst allowedToEdit =\\n !props.isPreview &&\\n Near.view(\\\"devgovgigs.near\\\", \\\"is_allowed_to_edit\\\", {\\n post_id: postId,\\n editor: context.accountId,\\n });\\n\\nconst btnEditorWidget = (postType, name) => {\\n return (\\n <li>\\n <a\\n class=\\\"dropdown-item\\\"\\n role=\\\"button\\\"\\n onClick={() =>\\n State.update({ postType, editorType: \\\"EDIT\\\", showEditor: true })\\n }\\n >\\n {name}\\n </a>\\n </li>\\n );\\n};\\n\\nconst editControl = allowedToEdit ? (\\n <div class=\\\"btn-group\\\" role=\\\"group\\\">\\n <a\\n class=\\\"card-link px-2\\\"\\n role=\\\"button\\\"\\n title=\\\"Edit post\\\"\\n data-bs-toggle=\\\"dropdown\\\"\\n aria-expanded=\\\"false\\\"\\n type=\\\"button\\\"\\n >\\n <div class=\\\"bi bi-pencil-square\\\"></div>\\n </a>\\n <ul class=\\\"dropdown-menu\\\">\\n {btnEditorWidget(\\\"Idea\\\", \\\"Edit as an idea\\\")}\\n {btnEditorWidget(\\\"Submission\\\", \\\"Edit as a solution\\\")}\\n {btnEditorWidget(\\\"Attestation\\\", \\\"Edit as an attestation\\\")}\\n {btnEditorWidget(\\\"Sponsorship\\\", \\\"Edit as a sponsorship\\\")}\\n {btnEditorWidget(\\\"Comment\\\", \\\"Edit as a comment\\\")}\\n </ul>\\n </div>\\n) : (\\n <div></div>\\n);\\n\\nconst shareButton = props.isPreview ? (\\n <div></div>\\n) : (\\n <Link\\n class=\\\"card-link text-dark\\\"\\n to={href({\\n gateway: \\\"near.org\\\",\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"post\\\", id: postId },\\n })}\\n role=\\\"button\\\"\\n target=\\\"_blank\\\"\\n title=\\\"Open in new tab\\\"\\n >\\n <div class=\\\"bi bi-share\\\"></div>\\n </Link>\\n);\\n\\nconst ProfileCardContainer = styled.div`\\n @media screen and (max-width: 960px) {\\n width: 100%;\\n }\\n`;\\n\\n// card-header\\nconst header = (\\n <div key=\\\"header\\\">\\n <small class=\\\"text-muted\\\">\\n <div class=\\\"row justify-content-between\\\">\\n <div class=\\\"d-flex align-items-center flex-wrap\\\">\\n <ProfileCardContainer>\\n <Widget\\n src={\\n \\\"devhub.efiz.near/widget/devhub.components.molecule.ProfileCard\\\"\\n }\\n props={{\\n accountId: post.author_id,\\n nearDevGovGigsWidgetsAccountId: \\\"devhub.efiz.near\\\",\\n }}\\n />\\n </ProfileCardContainer>\\n <div class=\\\"d-flex ms-auto\\\">\\n {editControl}\\n {timestamp}\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.entity.post.History\\\"}\\n props={{\\n post,\\n timestamp: currentTimestamp,\\n }}\\n />\\n {shareButton}\\n </div>\\n </div>\\n </div>\\n </small>\\n </div>\\n);\\n\\n// const emptyIcons = {\\n// Idea: \\\"bi-lightbulb\\\",\\n// Comment: \\\"bi-chat\\\",\\n// Submission: \\\"bi-rocket\\\",\\n// Attestation: \\\"bi-check-circle\\\",\\n// Sponsorship: \\\"bi-cash-coin\\\",\\n// Github: \\\"bi-github\\\",\\n// Like: \\\"bi-heart\\\",\\n// Reply: \\\"bi-reply\\\",\\n// };\\n\\nconst emptyIcons = {\\n Idea: \\\"\\u{1f4a1}\\\",\\n Comment: \\\"bi-chat\\\",\\n Submission: \\\"\\u{1f680}\\\",\\n Attestation: \\\"\\u{2705}\\\",\\n Sponsorship: \\\"\\u{1fa99}\\\",\\n Github: \\\"bi-github\\\",\\n Like: \\\"bi-heart\\\",\\n Reply: \\\"bi-reply\\\",\\n};\\n\\nconst fillIcons = {\\n Idea: \\\"\\u{1f4a1}\\\",\\n Comment: \\\"bi-chat-fill\\\",\\n Submission: \\\"\\u{1f680}\\\",\\n Attestation: \\\"\\u{2705}\\\",\\n Sponsorship: \\\"\\u{1fa99}\\\",\\n Github: \\\"bi-github\\\",\\n Like: \\\"bi-heart-fill\\\",\\n Reply: \\\"bi-reply-fill\\\",\\n};\\n\\n// Trigger saving this widget.\\n\\nconst borders = {\\n Idea: \\\"border-light\\\",\\n Comment: \\\"border-light\\\",\\n Submission: \\\"border-light\\\",\\n Attestation: \\\"border-light\\\",\\n Sponsorship: \\\"border-light\\\",\\n Github: \\\"border-light\\\",\\n};\\n\\nconst containsLike = props.isPreview\\n ? false\\n : post.likes.find((l) => l.author_id == context.accountId);\\nconst likeBtnClass = containsLike ? fillIcons.Like : emptyIcons.Like;\\n// This must be outside onLike, because Near.view returns null at first, and when the view call finished, it returns true/false.\\n// If checking this inside onLike, it will give `null` and we cannot tell the result is true or false.\\nlet grantNotify = Near.view(\\\"social.near\\\", \\\"is_write_permission_granted\\\", {\\n predecessor_id: \\\"devgovgigs.near\\\",\\n key: context.accountId + \\\"/index/notify\\\",\\n});\\nif (grantNotify === null) {\\n return;\\n}\\nconst onLike = () => {\\n if (!context.accountId) {\\n return;\\n }\\n let likeTxn = [\\n {\\n contractName: \\\"devgovgigs.near\\\",\\n methodName: \\\"add_like\\\",\\n args: {\\n post_id: postId,\\n },\\n deposit: Big(10).pow(21).mul(2),\\n gas: Big(10).pow(12).mul(100),\\n },\\n ];\\n\\n if (grantNotify === false) {\\n likeTxn.unshift({\\n contractName: \\\"social.near\\\",\\n methodName: \\\"grant_write_permission\\\",\\n args: {\\n predecessor_id: \\\"devgovgigs.near\\\",\\n keys: [context.accountId + \\\"/index/notify\\\"],\\n },\\n deposit: Big(10).pow(23),\\n gas: Big(10).pow(12).mul(30),\\n });\\n }\\n Near.call(likeTxn);\\n};\\n\\nconst btnCreatorWidget = (postType, icon, name, desc) => {\\n return (\\n <li class=\\\"py-1\\\">\\n <a\\n class=\\\"dropdown-item text-decoration-none d-flex align-items-center lh-sm\\\"\\n style={{ color: \\\"rgb(55,109,137)\\\" }}\\n role=\\\"button\\\"\\n onClick={() =>\\n State.update({ postType, editorType: \\\"CREATE\\\", showEditor: true })\\n }\\n >\\n <i class={`bi ${icon}`} style={{ fontSize: \\\"1.5rem\\\" }}>\\n {\\\" \\\"}\\n </i>\\n <div class=\\\"ps-2 text-wrap\\\" style={{ width: \\\"18rem\\\" }}>\\n <div>{name}</div>\\n <small class=\\\"fw-light text-secondary\\\">{desc}</small>\\n </div>\\n </a>\\n </li>\\n );\\n};\\n\\nconst FooterButtonsContianer = styled.div`\\n width: 66.66666667%;\\n\\n @media screen and (max-width: 960px) {\\n width: 100%;\\n }\\n`;\\n\\nconst buttonsFooter = props.isPreview ? null : (\\n <div class=\\\"row\\\" key=\\\"buttons-footer\\\">\\n <FooterButtonsContianer>\\n <div class=\\\"btn-group\\\" role=\\\"group\\\" aria-label=\\\"Basic outlined example\\\">\\n <ButtonWithHover\\n type=\\\"button\\\"\\n class=\\\"btn d-flex align-items-center\\\"\\n style={{ border: \\\"0px\\\" }}\\n onClick={onLike}\\n >\\n <i class={`bi ${likeBtnClass}`}> </i>\\n {post.likes.length == 0 ? (\\n \\\"Like\\\"\\n ) : (\\n <Widget\\n // TODO: LEGACY.\\n src=\\\"devhub.efiz.near/widget/gigs-board.components.layout.LikeButton.Faces\\\"\\n props={{\\n likesByUsers: Object.fromEntries(\\n post.likes.map(({ author_id }) => [author_id, \\\"\\\"])\\n ),\\n }}\\n />\\n )}\\n </ButtonWithHover>\\n <div class=\\\"btn-group\\\" role=\\\"group\\\">\\n <ButtonWithHover\\n type=\\\"button\\\"\\n class=\\\"btn\\\"\\n style={{ border: \\\"0px\\\" }}\\n data-bs-toggle=\\\"dropdown\\\"\\n aria-expanded=\\\"false\\\"\\n >\\n \\u{21aa} Reply\\n </ButtonWithHover>\\n <ul class=\\\"dropdown-menu\\\">\\n {btnCreatorWidget(\\n \\\"Idea\\\",\\n emptyIcons.Idea,\\n \\\"Idea\\\",\\n \\\"Get feedback from the community about a problem, opportunity, or need.\\\"\\n )}\\n {btnCreatorWidget(\\n \\\"Submission\\\",\\n emptyIcons.Submission,\\n \\\"Solution\\\",\\n \\\"Provide a specific proposal or implementation to an idea, optionally requesting funding.\\\"\\n )}\\n {btnCreatorWidget(\\n \\\"Attestation\\\",\\n emptyIcons.Attestation,\\n \\\"Attestation\\\",\\n \\\"Formally review or validate a solution as a recognized expert.\\\"\\n )}\\n {btnCreatorWidget(\\n \\\"Sponsorship\\\",\\n emptyIcons.Sponsorship,\\n \\\"Sponsorship\\\",\\n \\\"Offer to fund projects, events, or proposals that match your needs.\\\"\\n )}\\n <li>\\n <hr class=\\\"dropdown-divider\\\" />\\n </li>\\n {btnCreatorWidget(\\n \\\"Comment\\\",\\n emptyIcons.Comment,\\n \\\"Comment\\\",\\n \\\"Ask a question, provide information, or share a resource that is relevant to the thread.\\\"\\n )}\\n </ul>\\n </div>\\n <ButtonWithHover\\n type=\\\"button\\\"\\n class=\\\"btn\\\"\\n style={{ border: \\\"0px\\\" }}\\n data-bs-toggle=\\\"collapse\\\"\\n href={`#collapseChildPosts${postId}`}\\n aria-expanded={defaultExpanded}\\n aria-controls={`collapseChildPosts${postId}`}\\n >\\n <i class=\\\"bi bi-chevron-down\\\"> </i>{\\\" \\\"}\\n {`Expand Replies (${childPostIds.length})`}\\n </ButtonWithHover>\\n\\n {isUnderPost || !parentId ? (\\n <div key=\\\"link-to-parent\\\"></div>\\n ) : (\\n <Link\\n to={href({\\n gateway: \\\"near.org\\\",\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"post\\\", id: parentId },\\n })}\\n >\\n <ButtonWithHover\\n type=\\\"button\\\"\\n style={{ border: \\\"0px\\\" }}\\n className=\\\"btn\\\"\\n key=\\\"link-to-parent\\\"\\n >\\n <i class=\\\"bi bi-arrow-90deg-up\\\"></i>Go to parent\\n </ButtonWithHover>\\n </Link>\\n )}\\n </div>\\n </FooterButtonsContianer>\\n </div>\\n);\\n\\nconst CreatorWidget = (postType) => {\\n return (\\n <div\\n class={`collapse ${\\n draftState?.parent_post_id == postId && draftState?.postType == postType\\n ? \\\"show\\\"\\n : \\\"\\\"\\n }`}\\n id={`collapse${postType}Creator${postId}`}\\n data-bs-parent={`#accordion${postId}`}\\n >\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.entity.post.PostEditor\\\"}\\n props={{\\n postType,\\n onDraftStateChange: props.onDraftStateChange,\\n draftState:\\n draftState?.parent_post_id == postId ? draftState : undefined,\\n parentId: postId,\\n mode: \\\"Create\\\",\\n }}\\n />\\n </div>\\n );\\n};\\n\\nconst tokenMapping = {\\n NEAR: \\\"NEAR\\\",\\n USDT: {\\n NEP141: {\\n address: \\\"usdt.tether-token.near\\\",\\n },\\n },\\n USDC: {\\n NEP141: {\\n address:\\n \\\"17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1\\\",\\n },\\n },\\n // Add more tokens here as needed\\n};\\n\\nconst reverseTokenMapping = Object.keys(tokenMapping).reduce(\\n (reverseMap, key) => {\\n const value = tokenMapping[key];\\n if (typeof value === \\\"object\\\") {\\n reverseMap[JSON.stringify(value)] = key;\\n }\\n return reverseMap;\\n },\\n {}\\n);\\n\\nfunction tokenResolver(token) {\\n if (typeof token === \\\"string\\\") {\\n return token;\\n } else if (typeof token === \\\"object\\\") {\\n const tokenString = reverseTokenMapping[JSON.stringify(token)];\\n return tokenString || null;\\n } else {\\n return null; // Invalid input\\n }\\n}\\n\\nconst EditorWidget = (postType) => {\\n return (\\n <div\\n class={`collapse ${\\n draftState?.edit_post_id == postId && draftState?.postType == postType\\n ? \\\"show\\\"\\n : \\\"\\\"\\n }`}\\n id={`collapse${postType}Editor${postId}`}\\n data-bs-parent={`#accordion${postId}`}\\n >\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.entity.post.PostEditor\\\"}\\n props={{\\n postType,\\n postId,\\n mode: \\\"Edit\\\",\\n author_id: post.author_id,\\n labels: post.snapshot.labels,\\n name: post.snapshot.name,\\n description: post.snapshot.description,\\n amount: post.snapshot.amount,\\n token: tokenResolver(post.snapshot.sponsorship_token),\\n supervisor: post.snapshot.supervisor,\\n githubLink: post.snapshot.github_link,\\n onDraftStateChange: props.onDraftStateChange,\\n draftState:\\n draftState?.edit_post_id == postId ? draftState : undefined,\\n }}\\n />\\n </div>\\n );\\n};\\n\\nconst isDraft =\\n (draftState?.parent_post_id === postId &&\\n draftState?.postType === state.postType) ||\\n (draftState?.edit_post_id === postId &&\\n draftState?.postType === state.postType);\\n\\nfunction Editor() {\\n return (\\n <div class=\\\"row\\\" id={`accordion${postId}`} key=\\\"editors-footer\\\">\\n <div\\n key={`${state.postType}${state.editorType}${postId}`}\\n className={\\\"w-100\\\"}\\n >\\n {state.editorType === \\\"CREATE\\\" ? (\\n <>\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.entity.post.PostEditor\\\"}\\n props={{\\n postType: state.postType,\\n onDraftStateChange: props.onDraftStateChange,\\n draftState:\\n draftState?.parent_post_id == postId ? draftState : undefined,\\n parentId: postId,\\n mode: \\\"Create\\\",\\n }}\\n />\\n </>\\n ) : (\\n <>\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.entity.post.PostEditor\\\"}\\n props={{\\n postType: state.postType,\\n postId,\\n mode: \\\"Edit\\\",\\n author_id: post.author_id,\\n labels: post.snapshot.labels,\\n name: post.snapshot.name,\\n description: post.snapshot.description,\\n amount: post.snapshot.amount,\\n token: tokenResolver(post.snapshot.sponsorship_token),\\n supervisor: post.snapshot.supervisor,\\n githubLink: post.snapshot.github_link,\\n onDraftStateChange: props.onDraftStateChange,\\n draftState:\\n draftState?.edit_post_id == postId ? draftState : undefined,\\n }}\\n />\\n </>\\n )}\\n </div>\\n </div>\\n );\\n}\\n\\nconst renamedPostType =\\n snapshot.post_type == \\\"Submission\\\" ? \\\"Solution\\\" : snapshot.post_type;\\n\\nconst tags = post.snapshot.labels ? (\\n <div\\n class=\\\"card-title d-flex flex-wrap align-items-center\\\"\\n style={{ margin: \\\"20px 0\\\" }}\\n key=\\\"post-labels\\\"\\n >\\n {post.snapshot.labels.map((tag, idx) => (\\n <Link\\n to={href({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"feed\\\", tag: tag },\\n })}\\n >\\n <div\\n className=\\\"d-flex gap-3 align-items-center my-3 me-3\\\"\\n style={{ cursor: \\\"pointer\\\", textDecoration: \\\"none\\\" }}\\n >\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.components.atom.Tag\\\"}\\n props={{\\n tag,\\n black: true,\\n }}\\n />\\n\\n {idx !== post.snapshot.labels.length - 1 && \\\"\\u{2022}\\\"}\\n </div>\\n </Link>\\n ))}\\n </div>\\n) : (\\n <div key=\\\"post-labels\\\"></div>\\n);\\n\\nconst Title = styled.h5`\\n margin: 1rem 0;\\n\\n color: #151515;\\n font-size: 1.15rem;\\n font-style: normal;\\n font-weight: 700;\\n line-height: 1.625rem; /* 55.556% */\\n`;\\n\\nconst postTitle =\\n snapshot.post_type == \\\"Comment\\\" ? (\\n <div key=\\\"post-title\\\"></div>\\n ) : (\\n <Title key=\\\"post-title\\\">\\n {emptyIcons[snapshot.post_type]} {renamedPostType}: {snapshot.name}\\n </Title>\\n );\\n\\nconst postExtra =\\n snapshot.post_type == \\\"Sponsorship\\\" ? (\\n <div key=\\\"post-extra\\\">\\n <h6 class=\\\"card-subtitle mb-2 text-muted\\\">\\n Maximum amount: {snapshot.amount}{\\\" \\\"}\\n {tokenResolver(snapshot.sponsorship_token)}\\n </h6>\\n <h6 class=\\\"card-subtitle mb-2 text-muted\\\">\\n Supervisor:{\\\" \\\"}\\n <Widget\\n src={\\\"neardevgov.near/widget/ProfileLine\\\"}\\n props={{ accountId: snapshot.supervisor }}\\n />\\n </h6>\\n </div>\\n ) : (\\n <div></div>\\n );\\n\\nconst childPostHasDraft = childPostIds.find(\\n (childId) =>\\n childId == draftState?.edit_post_id || childId == draftState?.parent_post_id\\n);\\nif (\\n (childPostHasDraft || state.childrenOfChildPostsHasDraft) &&\\n props.expandParent\\n) {\\n props.expandParent();\\n}\\n\\nconst postsList =\\n props.isPreview || childPostIds.length == 0 ? (\\n <div key=\\\"posts-list\\\"></div>\\n ) : (\\n <div class=\\\"row\\\" key=\\\"posts-list\\\">\\n <div\\n class={`collapse ${\\n defaultExpanded ||\\n childPostHasDraft ||\\n state.childrenOfChildPostsHasDraft\\n ? \\\"show\\\"\\n : \\\"\\\"\\n }`}\\n id={`collapseChildPosts${postId}`}\\n >\\n {childPostIds.map((childId) => (\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.entity.post.Post\\\"\\n props={{\\n id: childId,\\n isUnderPost: true,\\n onDraftStateChange: props.onDraftStateChange,\\n draftState,\\n expandParent: () =>\\n State.update({ childrenOfChildPostsHasDraft: true }),\\n referral: `subpost${childId}of${postId}`,\\n }}\\n />\\n ))}\\n </div>\\n </div>\\n );\\n\\nconst LimitedMarkdown = styled.div`\\n max-height: 20em;\\n`;\\n\\n// Determine if located in the post page.\\nconst isInList = props.isInList;\\nconst contentArray = snapshot.description.split(\\\"\\\\n\\\");\\nconst needClamp = isInList && contentArray.length > 5;\\n\\ninitState({\\n clamp: needClamp,\\n});\\n\\nconst clampedContent = needClamp\\n ? contentArray.slice(0, 3).join(\\\"\\\\n\\\")\\n : snapshot.description;\\n\\n// Should make sure the posts under the currently top viewed post are limited in size.\\nconst descriptionArea = isUnderPost ? (\\n <LimitedMarkdown className=\\\"overflow-auto\\\" key=\\\"description-area\\\">\\n {/* {widget(\\\"components.molecule.markdown-viewer\\\", {\\n text: snapshot.description,\\n })} */}\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.components.molecule.MarkdownViewer\\\"}\\n props={{\\n text: snapshot.description,\\n }}\\n />\\n </LimitedMarkdown>\\n) : (\\n <div>\\n <div class={state.clamp ? \\\"clamp\\\" : \\\"\\\"}>\\n {/* {widget(\\\"components.molecule.markdown-viewer\\\", {\\n text: state.clamp ? clampedContent : snapshot.description,\\n })} */}\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.components.molecule.MarkdownViewer\\\"}\\n props={{\\n text: state.clamp ? clampedContent : snapshot.description,\\n }}\\n />\\n </div>\\n {state.clamp ? (\\n <div class=\\\"d-flex justify-content-start\\\">\\n <a\\n style={{ cursor: \\\"pointer\\\", color: \\\"#00ec97\\\" }}\\n class=\\\"btn-link text-dark fw-bold text-decoration-none\\\"\\n onClick={() => State.update({ clamp: false })}\\n >\\n See more\\n </a>\\n </div>\\n ) : (\\n <></>\\n )}\\n </div>\\n);\\n\\nconst timestampElement = (_snapshot) => {\\n return (\\n <Link\\n class=\\\"text-muted\\\"\\n href={href({\\n gateway: \\\"near.org\\\",\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: {\\n page: \\\"post\\\",\\n id: postId,\\n timestamp: _snapshot.timestamp,\\n compareTimestamp: null,\\n referral,\\n },\\n })}\\n >\\n {readableDate(_snapshot.timestamp / 1000000).substring(4)}\\n\\n <Widget\\n src=\\\"mob.near/widget/ProfileImage\\\"\\n props={{\\n accountId: _snapshot.editor_id,\\n style: {\\n width: \\\"1.25em\\\",\\n height: \\\"1.25em\\\",\\n },\\n imageStyle: {\\n transform: \\\"translateY(-12.5%)\\\",\\n },\\n }}\\n />\\n {_snapshot.editor_id.substring(0, 8)}\\n </Link>\\n );\\n};\\n\\nfunction combineText(_snapshot) {\\n return (\\n \\\"## \\\" +\\n _snapshot.post_type +\\n \\\": \\\" +\\n _snapshot.name +\\n \\\"\\\\n\\\" +\\n _snapshot.description\\n );\\n}\\n\\nconst CardContainer = styled.div`\\n padding: 1.5rem 3rem !important;\\n border-radius: 16px !important;\\n border: 1px solid rgba(129, 129, 129, 0.3) !important;\\n background: #fffefe !important;\\n\\n @media screen and (max-width: 960px) {\\n padding: 1rem !important;\\n }\\n`;\\n\\nreturn (\\n <CardContainer className={`card ${borders[snapshot.post_type]} attractable`}>\\n {header}\\n <div className=\\\"card-body\\\" style={{ padding: 0 }}>\\n {searchKeywords}\\n {compareSnapshot ? (\\n <div\\n class=\\\"border rounded\\\"\\n style={{ marginTop: \\\"16px\\\", marginBottom: \\\"16px\\\" }}\\n >\\n <div class=\\\"d-flex justify-content-end\\\" style={{ fontSize: \\\"12px\\\" }}>\\n <div class=\\\"d-flex w-50 justify-content-end mt-1 me-2\\\">\\n {timestampElement(snapshot)}\\n {snapshot !== compareSnapshot && (\\n <>\\n <div class=\\\"mx-1 align-self-center\\\">\\n <i class=\\\"bi bi-file-earmark-diff\\\" />\\n </div>\\n {timestampElement(compareSnapshot)}\\n </>\\n )}\\n </div>\\n </div>\\n\\n <Widget\\n src=\\\"markeljan.near/widget/MarkdownDiff\\\"\\n props={{\\n post: post,\\n currentCode: combineText(\\n swapTimestamps ? compareSnapshot : snapshot\\n ),\\n prevCode: combineText(\\n swapTimestamps ? snapshot : compareSnapshot\\n ),\\n showLineNumber: true,\\n }}\\n />\\n </div>\\n ) : (\\n <>\\n {postTitle}\\n {postExtra}\\n {descriptionArea}\\n </>\\n )}\\n {tags}\\n {buttonsFooter}\\n {!props.isPreview && (isDraft || state.showEditor) && <Editor />}\\n {postsList}\\n </div>\\n </CardContainer>\\n);\\n"
}
,
"devhub.page.community.index"
:
{
""
:
"const Button = styled.button`\\n height: 40px;\\n font-size: 14px;\\n border-color: #e3e3e0;\\n background-color: #ffffff;\\n`;\\n\\nconst Banner = styled.div`\\n max-width: 100%;\\n min-height: 240px;\\n height: 240px;\\n`;\\n\\nconst CenteredMessage = styled.div`\\n display: flex;\\n flex-direction: column;\\n justify-content: center;\\n align-items: center;\\n width: 100%;\\n height: ${(p) => p.height ?? \\\"100%\\\"};\\n`;\\n\\nconst NavUnderline = styled.ul`\\n cursor: pointer;\\n a {\\n color: #151515;\\n text-decoration: none;\\n }\\n\\n a.active {\\n font-weight: bold;\\n border-bottom: 4px solid #00ec97;\\n }\\n`;\\n\\nconst { tab, permissions, community, view } = props;\\n\\nconst { href } = VM.require(\\\"devhub.efiz.near/widget/core.lib.url\\\");\\n\\nif (!href) {\\n return <></>;\\n}\\n\\nif (!tab) {\\n tab = \\\"Activity\\\";\\n}\\n\\nconst [isLinkCopied, setLinkCopied] = useState(false);\\n\\nconst tabs = [\\n {\\n title: \\\"Activity\\\",\\n view: \\\"devhub.efiz.near/widget/devhub.entity.community.Activity\\\",\\n params: {\\n handle: community.handle,\\n },\\n },\\n {\\n title: \\\"Teams\\\",\\n view: \\\"devhub.efiz.near/widget/devhub.entity.community.Teams\\\",\\n params: {\\n handle: community.handle,\\n },\\n },\\n];\\n\\n(community.addons || []).map((addon) => {\\n addon.enabled &&\\n tabs.push({\\n title: addon.display_name,\\n view: \\\"devhub.efiz.near/widget/devhub.page.addon\\\",\\n params: { addon },\\n });\\n});\\n\\nconst onShareClick = () =>\\n clipboard\\n .writeText(\\n href({\\n gateway: \\\"near.org\\\",\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"community\\\", handle: community.handle },\\n })\\n )\\n .then(setLinkCopied(true));\\n\\nlet currentTab = tabs.find((it) => it.title === tab);\\n\\nconst CommunityName = styled.span`\\n color: #151515;\\n font-size: 2.25rem;\\n font-style: normal;\\n font-weight: 700;\\n line-height: 100%; /* 48px */\\n`;\\n\\nconst CommunityDetails = styled.span`\\n color: #818181;\\n font-size: 1rem;\\n font-style: normal;\\n font-weight: 400;\\n line-height: 120%; /* 28.8px */\\n`;\\n\\nfunction trimHttps(url) {\\n if (url.startsWith(\\\"https://\\\")) {\\n return url.substring(8);\\n }\\n return url;\\n}\\n\\nconst socialLinks = [\\n ...((community.website_url?.length ?? 0) > 0\\n ? [\\n {\\n href: `https://${trimHttps(community.website_url)}`,\\n iconClass: \\\"bi bi-globe\\\",\\n name: trimHttps(community.website_url),\\n },\\n ]\\n : []),\\n\\n ...((community.github_handle?.length ?? 0) > 0\\n ? [\\n {\\n href: `https://github.com/${community.github_handle}`,\\n iconClass: \\\"bi bi-github\\\",\\n name: community.github_handle,\\n },\\n ]\\n : []),\\n\\n ...((community.twitter_handle?.length ?? 0) > 0\\n ? [\\n {\\n href: `https://twitter.com/${community.twitter_handle}`,\\n iconClass: \\\"bi bi-twitter\\\",\\n name: community.twitter_handle,\\n },\\n ]\\n : []),\\n\\n ...(community.telegram_handle.length > 0\\n ? community.telegram_handle.map((telegram_handle) => ({\\n href: `https://t.me/${telegram_handle}`,\\n iconClass: \\\"bi bi-telegram\\\",\\n name: telegram_handle,\\n }))\\n : []),\\n];\\n\\nconst NavlinksContainer = styled.div`\\n background: white;\\n padding: 0 3rem;\\n\\n @media screen and (max-width: 960px) {\\n padding: 0 1rem;\\n }\\n`;\\n\\nreturn (\\n <div\\n className=\\\"d-flex flex-column gap-3 w-100\\\"\\n style={{ background: \\\"#F4F4F4\\\" }}\\n >\\n <Banner\\n className=\\\"object-fit-cover\\\"\\n style={{\\n background: `center / cover no-repeat url(${community.banner_url})`,\\n }}\\n />\\n\\n <div className=\\\"container d-flex flex-wrap justify-content-between align-items-center align-items-md-start gap-4\\\">\\n <div className=\\\"d-flex flex-column ms-3\\\">\\n <div className=\\\"position-relative\\\">\\n <div style={{ width: 150, height: 45 }}>\\n <img\\n alt=\\\"Loading logo...\\\"\\n className=\\\"rounded-circle position-absolute\\\"\\n width=\\\"160\\\"\\n height=\\\"160\\\"\\n src={community.logo_url}\\n style={{ top: -124 }}\\n />\\n </div>\\n </div>\\n\\n <div className=\\\"d-flex flex-column gap-3 ps-md-3 pt-md-3 pb-md-2\\\">\\n <CommunityName className=\\\"text-nowrap\\\">\\n {community.name}\\n </CommunityName>\\n <CommunityDetails>{community.description}</CommunityDetails>\\n </div>\\n\\n <div className=\\\"mt-3 ps-3 d-flex gap-3 align-items-center\\\">\\n {socialLinks.map((link, index) => (\\n <a\\n href={link.href}\\n style={{\\n marginLeft: index !== 0 ? \\\"0px\\\" : \\\"0px\\\",\\n color: \\\"#818181\\\",\\n }}\\n key={link.href}\\n target=\\\"_blank\\\"\\n >\\n <i className={link.iconClass}></i>\\n </a>\\n ))}\\n </div>\\n </div>\\n\\n <div className=\\\"d-flex align-items-end gap-3 ms-auto mb-md-5\\\">\\n {permissions.can_configure && (\\n <Link\\n to={`/devhub.efiz.near/widget/app?page=community.configuration&handle=${community.handle}`}\\n >\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.components.molecule.Button\\\"}\\n props={{\\n classNames: { root: \\\"btn-outline-light text-dark shadow-none\\\" },\\n notRounded: true,\\n style: {\\n display: \\\"flex\\\",\\n padding: \\\"0.75rem 1rem\\\",\\n alignItems: \\\"center\\\",\\n gap: \\\"16px\\\",\\n\\n borderRadius: \\\"4px\\\",\\n border: \\\"1px solid #00EC97\\\",\\n background: \\\"rgba(129, 129, 129, 0.00)\\\",\\n },\\n icon: {\\n type: \\\"bootstrap_icon\\\",\\n variant: \\\"bi-gear-wide-connected\\\",\\n },\\n label: \\\"Configure community\\\",\\n }}\\n />\\n </Link>\\n )}\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.components.molecule.Button\\\"}\\n props={{\\n classNames: { root: \\\"btn-outline-light text-dark shadow-none\\\" },\\n notRounded: true,\\n style: {\\n display: \\\"flex\\\",\\n padding: \\\"0.75rem 1rem\\\",\\n alignItems: \\\"center\\\",\\n gap: \\\"16px\\\",\\n\\n borderRadius: \\\"4px\\\",\\n border: \\\"1px solid #00EC97\\\",\\n background: \\\"rgba(129, 129, 129, 0.00)\\\",\\n },\\n label: \\\"Share \\u{2197}\\\",\\n onClick: onShareClick,\\n onMouseLeave: () => setLinkCopied(false),\\n title: \\\"Copy link to clipboard\\\",\\n }}\\n />\\n </div>\\n </div>\\n <NavlinksContainer>\\n <NavUnderline className=\\\"nav gap-4 my-4\\\">\\n {tabs.map(\\n ({ title }) =>\\n title && (\\n <li className=\\\"nav-item\\\" key={title}>\\n <Link\\n to={href({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: {\\n page: \\\"community\\\",\\n handle: community.handle,\\n tab: title,\\n },\\n })}\\n aria-current={tab === title && \\\"page\\\"}\\n className={[\\n \\\"d-inline-flex gap-2\\\",\\n tab === title ? \\\"nav-link active\\\" : \\\"nav-link\\\",\\n ].join(\\\" \\\")}\\n >\\n <span>{title}</span>\\n </Link>\\n </li>\\n )\\n )}\\n </NavUnderline>\\n <div\\n className=\\\"my-4 d-flex align-items-center justify-content-between\\\"\\n style={{ gap: \\\"2.5rem\\\" }}\\n >\\n <div class=\\\"d-flex align-items-center justify-content-between\\\">\\n <small class=\\\"text-muted\\\">\\n <span>Required tags:</span>\\n <Link\\n to={href({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"feed\\\", tag: community.tag },\\n })}\\n >\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.components.atom.Tag\\\"}\\n props={{\\n tag: community.tag,\\n }}\\n />\\n </Link>\\n </small>\\n </div>\\n {context.accountId && (\\n <Widget\\n src={\\n \\\"devhub.efiz.near/widget/devhub.components.molecule.PostControls\\\"\\n }\\n props={{\\n title: \\\"Post\\\",\\n href: href({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: {\\n page: \\\"create\\\",\\n labels: [community.tag],\\n },\\n }),\\n }}\\n />\\n )}\\n </div>\\n </NavlinksContainer>\\n {currentTab && (\\n <div className=\\\"d-flex w-100 h-100\\\" key={currentTab.title}>\\n <Widget\\n src={currentTab.view}\\n props={{\\n ...currentTab.params,\\n view, // default view for an addon, can come as a prop from a community or from a direct link to page.addon\\n\\n // below is temporary prop drilling until kanban and github are migrated\\n permissions,\\n handle: community.handle,\\n }}\\n />\\n </div>\\n )}\\n </div>\\n);\\n"
}
,
"devhub.entity.addon.blog.Card"
:
{
""
:
"function Card({ data }) {\\n const { category, title, description, date } = data;\\n\\n const Container = styled.div`\\n min-height: 12.5rem;\\n display: flex;\\n padding: 1rem;\\n flex-direction: column;\\n align-items: flex-start;\\n gap: 1rem;\\n flex-shrink: 0;\\n\\n border-radius: 1rem;\\n border: 1px solid rgba(129, 129, 129, 0.3);\\n background: #fffefe;\\n\\n h5 {\\n margin: 0;\\n color: #151515;\\n font-size: 1.5rem;\\n font-style: normal;\\n font-weight: 700;\\n line-height: 110%; /* 39.6px */\\n }\\n\\n ${category &&\\n `\\n span.category {\\n color: ${\\n category.toLowerCase() === \\\"news\\\"\\n ? \\\"#F40303\\\"\\n : category.toLowerCase() === \\\"guide\\\"\\n ? \\\"#004BE1\\\"\\n : category.toLowerCase() === \\\"reference\\\" && \\\"#FF7A00\\\"\\n };\\n font-size: 1rem;\\n font-style: normal;\\n font-weight: 700;\\n line-height: 20px; /* 125% */\\n text-transform: uppercase;\\n }\\n `}\\n\\n span.date {\\n color: #818181;\\n font-size: 16px;\\n font-style: normal;\\n font-weight: 400;\\n line-height: 20px; /* 125% */\\n }\\n\\n p {\\n margin: 0;\\n color: #151515;\\n font-size: 1rem;\\n font-style: normal;\\n font-weight: 400;\\n line-height: 120%; /* 28.8px */\\n }\\n `;\\n\\n const options = { year: \\\"numeric\\\", month: \\\"short\\\", day: \\\"numeric\\\" };\\n const formattedDate = new Date(date).toLocaleString(\\\"en-US\\\", options);\\n\\n return (\\n <Container>\\n {category && <span className=\\\"category\\\">{category}</span>}\\n <h5>{title}</h5>\\n <p>{description}</p>\\n <span className=\\\"date\\\">{formattedDate}</span>\\n </Container>\\n );\\n}\\n\\nreturn { Card };\\n"
}
,
"devhub.entity.addon.blog.Feed"
:
{
""
:
"const { Item } = props;\\n\\nconst Container = styled.div``;\\n\\nconst Layout = styled.div`\\n display: grid;\\n grid-template-columns: repeat(3, minmax(0, 1fr));\\n gap: 1rem;\\n\\n @media screen and (max-width: 768px) {\\n display: flex;\\n flex-direction: column;\\n gap: 1rem;\\n }\\n`;\\n\\nconst Loader = styled.div`\\n text-align: center;\\n padding: 20px;\\n`;\\n\\nconst Notification = styled.p`\\n text-align: center;\\n color: #3252a6;\\n`;\\n\\nconst Heading = styled.h3`\\n color: #151515;\\n font-size: 2.5rem;\\n font-style: normal;\\n font-weight: 700;\\n line-height: 120%; /* 48px */\\n margin-bottom: 2rem;\\n\\n @media screen and (max-width: 768px) {\\n font-size: 2rem;\\n }\\n`;\\n\\nconst QUERYAPI_ENDPOINT = `https://near-queryapi.api.pagoda.co/v1/graphql/`;\\nconst DISPLAY_COUNT = 10;\\n\\nconst fetchGraphQL = (operationsDoc, operationName, variables) => {\\n return asyncFetch(QUERYAPI_ENDPOINT, {\\n method: \\\"POST\\\",\\n headers: { \\\"x-hasura-role\\\": `bo_near` },\\n body: JSON.stringify({\\n query: operationsDoc,\\n variables: variables,\\n operationName: operationName,\\n }),\\n });\\n};\\n\\nconst queryName =\\n props.queryName ?? `bo_near_devhub_v17_posts_with_latest_snapshot`;\\n\\nconst query = `query DevhubPostsQuery($limit: Int = 100, $offset: Int = 0, $where: ${queryName}_bool_exp = {}) {\\n ${queryName}(\\n limit: $limit\\n offset: $offset\\n order_by: {block_height: desc}\\n where: $where\\n ) {\\n post_id\\n }\\n }\\n`;\\n\\nconst [postIds, setPostIds] = useState([]);\\nconst [loading, setLoading] = useState(false);\\nconst [cachedItems, setCachedItems] = useState({});\\nconst [hasNext, setHasNext] = useState(true);\\n\\nconst buildWhereClause = () => {\\n let where = {};\\n if (props.author) {\\n where = { author_id: { _eq: props.author }, ...where };\\n }\\n if (props.term) {\\n where = { description: { _ilike: `%${props.term}%` }, ...where };\\n }\\n if (props.includeLabels && Array.isArray(props.includeLabels)) {\\n const labelConditions = props.includeLabels.map((label) => ({\\n labels: { _contains: label },\\n }));\\n\\n where = { _and: [...labelConditions, where] };\\n }\\n if (props.excludeLabels && Array.isArray(props.excludeLabels)) {\\n const labelConditions = props.excludeLabels.map((label) => ({\\n labels: { _nin: label },\\n }));\\n\\n where = { _and: [...labelConditions, where] };\\n }\\n if (!props.recency) {\\n where = { parent_id: { _is_null: true }, ...where };\\n }\\n return where;\\n};\\n\\nconst fetchPostIds = (offset) => {\\n if (!offset) {\\n offset = 0;\\n }\\n if (loading) return;\\n setLoading(true);\\n const variables = { limit: DISPLAY_COUNT, offset, where: buildWhereClause() };\\n const result = fetchGraphQL(query, \\\"DevhubPostsQuery\\\", variables).then(\\n (result) => {\\n if (result.status === 200) {\\n if (result.body.data) {\\n const data = result.body.data[queryName];\\n const newPostIds = data.map((p) => p.post_id);\\n setPostIds(offset === 0 ? newPostIds : [...postIds, ...newPostIds]);\\n setHasNext(data.length >= variables.limit);\\n } else {\\n console.error(\\\"GraphQL Error:\\\", result.errors);\\n }\\n setLoading(false);\\n }\\n }\\n );\\n};\\n\\nuseEffect(() => {\\n fetchPostIds();\\n}, [props.author, props.term, props.tag, props.recency]);\\n\\nconst handleLoadMore = () => {\\n if (!hasNext) return;\\n fetchPostIds(postIds.length);\\n};\\n\\nconst renderLoader = () => <Loader>Loading...</Loader>;\\n\\nconst renderItem = (postId) => (\\n <div key={postId}>\\n {(props.renderItem && props.renderItem(postId)) || <div>Post {postId}</div>}\\n </div>\\n);\\n\\nconst cachedRenderItem = (postId) => {\\n if (!(postId in cachedItems)) {\\n cachedItems[postId] = renderItem(postId);\\n setCachedItems({ ...cachedItems });\\n }\\n return cachedItems[postId];\\n};\\n\\nreturn (\\n <Container>\\n {loading && renderLoader()}\\n {postIds.length > 0 ? (\\n <InfiniteScroll\\n pageStart={0}\\n dataLength={postIds.length}\\n loadMore={handleLoadMore}\\n hasMore={hasNext}\\n loader={renderLoader()}\\n >\\n <Heading>Latest Blog Posts</Heading>\\n <Layout>\\n {/* Layout */}\\n {postIds.map(cachedRenderItem)}\\n </Layout>\\n </InfiniteScroll>\\n ) : (\\n <p class=\\\"text-secondary\\\">No posts</p>\\n )}\\n </Container>\\n);\\n"
}
,
"devhub.entity.addon.blog.Page"
:
{
""
:
"const imagelink =\\n \\\"https://ipfs.near.social/ipfs/bafkreiajzvmy7574k7mp3if6u53mdukfr3hoc2kjkhjadt6x56vqhd5swy\\\";\\n\\nfunction Page({ data }) {\\n const { category, title, description, subtitle, date, content } = data;\\n const Container = styled.div`\\n display: flex;\\n flex-direction: column;\\n width: 100%;\\n\\n padding: 0 3rem;\\n\\n ${category &&\\n `\\n span.category {\\n color: ${\\n category.toLowerCase() === \\\"news\\\"\\n ? \\\"#F40303\\\"\\n : category.toLowerCase() === \\\"guide\\\"\\n ? \\\"#004BE1\\\"\\n : category.toLowerCase() === \\\"reference\\\" && \\\"#FF7A00\\\"\\n };\\n font-size: 1.5rem;\\n font-style: normal;\\n font-weight: 700;\\n line-height: 20px; /* 125% */\\n text-transform: uppercase;\\n }\\n `}\\n\\n span.date {\\n color: #818181;\\n font-size: 1rem;\\n font-style: normal;\\n font-weight: 400;\\n line-height: 20px; /* 125% */\\n margin: 1.5rem 0;\\n }\\n\\n h1 {\\n color: #151515;\\n font-size: 3.5rem;\\n font-style: normal;\\n font-weight: 700;\\n line-height: 100%; /* 88px */\\n margin: 1rem 0;\\n }\\n\\n p.subtitle {\\n color: #555;\\n font-size: 1.5rem;\\n font-style: normal;\\n font-weight: 400;\\n line-height: 110%; /* 35.2px */\\n margin: 0;\\n }\\n\\n @media screen and (max-width: 768px) {\\n padding: 0 1rem;\\n\\n span.category {\\n font-size: 0.75rem;\\n }\\n\\n h1 {\\n font-size: 2rem;\\n }\\n\\n p.subtitle {\\n font-size: 1rem;\\n }\\n }\\n `;\\n\\n const BackgroundImage = styled.img`\\n width: 100%;\\n height: auto;\\n object-fit: cover;\\n margin-bottom: 1rem;\\n `;\\n\\n const options = { year: \\\"numeric\\\", month: \\\"short\\\", day: \\\"numeric\\\" };\\n const formattedDate = new Date(date).toLocaleString(\\\"en-US\\\", options);\\n\\n return (\\n <>\\n <BackgroundImage src={imagelink} />\\n <Container>\\n {category && <span className=\\\"category\\\">{category}</span>}\\n <h1>{title}</h1>\\n <p className=\\\"subtitle\\\">{subtitle}</p>\\n <span className=\\\"date\\\">{formattedDate}</span>\\n <p>{description}</p>\\n <Widget\\n src={\\n \\\"devhub.efiz.near/widget/devhub.components.molecule.MarkdownViewer\\\"\\n }\\n props={{ text: content }}\\n />\\n </Container>\\n </>\\n );\\n}\\n\\nreturn { Page };\\n"
}
,
"devhub.entity.addon.wiki.Viewer"
:
{
""
:
"const { content, title, subtitle, textAlign } = props;\\n\\nconst Container = styled.div`\\n display: flex;\\n flex-direction: column;\\n width: 100%;\\n\\n padding: 0 3rem;\\n\\n margin: 0 auto;\\n text-align: ${(p) => p.textAlign ?? \\\"left\\\"};\\n\\n h1 {\\n color: #151515;\\n font-size: 3.5rem;\\n font-style: normal;\\n font-weight: 700;\\n line-height: 100%; /* 88px */\\n margin: 1rem 0;\\n }\\n\\n p.subtitle {\\n color: #555;\\n font-size: 1.5rem;\\n font-style: normal;\\n font-weight: 400;\\n line-height: 110%; /* 35.2px */\\n margin: 0;\\n }\\n\\n @media screen and (max-width: 768px) {\\n padding: 0 1rem;\\n\\n span.category {\\n font-size: 0.75rem;\\n }\\n\\n h1 {\\n font-size: 2rem;\\n }\\n\\n p.subtitle {\\n font-size: 1rem;\\n }\\n }\\n\\n a {\\n color: #0000EE;\\n }\\n`;\\n\\nconst Content = styled.div`\\n margin: 20px 0;\\n text-align: left;\\n`;\\n\\nconst Title = styled.h1`\\n margin-bottom: 10px;\\n`;\\n\\nconst Subtitle = styled.p`\\n margin-bottom: 20px;\\n`;\\n\\nconst CenteredMessage = styled.div`\\n display: flex;\\n flex-direction: column;\\n justify-content: center;\\n align-items: center;\\n width: 100%;\\n height: ${(p) => p.height ?? \\\"100%\\\"};\\n`;\\n\\nif (!content) {\\n return (\\n <CenteredMessage height={\\\"384px\\\"}>\\n <h2>No Wiki Configured</h2>\\n </CenteredMessage>\\n );\\n} else {\\n return (\\n <Container textAlign={textAlign}>\\n <h1>{title}</h1>\\n <p className=\\\"subtitle\\\">{subtitle}</p>\\n <Content>\\n <Widget\\n src={\\n \\\"devhub.efiz.near/widget/devhub.components.molecule.MarkdownViewer\\\"\\n }\\n props={{ text: content }}\\n />\\n </Content>\\n </Container>\\n );\\n}\\n"
}
,
"devhub.entity.community.Activity"
:
{
""
:
"const { handle } = props;\\n\\nconst { getCommunity } = VM.require(\\n \\\"devhub.efiz.near/widget/core.adapter.devhub-contract\\\"\\n);\\n\\nconst { href } = VM.require(\\\"devhub.efiz.near/widget/core.lib.url\\\");\\n\\nif (!getCommunity || !href) {\\n return <p>Loading modules...</p>;\\n}\\n\\n// TODO: Why do we need to get community data again? Isn\\\'t the tag the handle...\\nconst communityData = getCommunity({ handle });\\n\\nif (communityData === null) {\\n return <div>Loading...</div>;\\n}\\n\\nconst MainContent = styled.div`\\n max-width: 73.5%;\\n\\n @media screen and (max-width: 960px) {\\n max-width: 100%;\\n }\\n`;\\n\\nconst SidebarContainer = styled.div`\\n max-width: 25%;\\n\\n @media screen and (max-width: 960px) {\\n display: none;\\n }\\n`;\\n\\nreturn (\\n <div style={{ maxWidth: \\\"100%\\\" }}>\\n <div class=\\\"col\\\">\\n <div class=\\\"d-flex w-100\\\">\\n <MainContent>\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.feature.post-search.panel\\\"}\\n props={{\\n hideHeader: true,\\n tag: communityData.tag,\\n children: (\\n <Widget\\n src={\\n \\\"devhub.efiz.near/widget/devhub.components.molecule.PostControls\\\"\\n }\\n props={{\\n title: \\\"Post\\\",\\n href: href({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: {\\n page: \\\"create\\\",\\n labels: [communityData.tag],\\n },\\n }),\\n }}\\n />\\n ),\\n recency,\\n transactionHashes: props.transactionHashes,\\n }}\\n />\\n </MainContent>\\n <SidebarContainer>\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.entity.community.Sidebar\\\"}\\n props={{ community: communityData }}\\n />\\n </SidebarContainer>\\n </div>\\n </div>\\n </div>\\n);\\n"
}
,
"devhub.feature.post-search.panel"
:
{
""
:
"const { href } = VM.require(\\\"devhub.efiz.near/widget/core.lib.url\\\");\\n\\nhref || (href = () => {});\\n\\nState.init({\\n tag: props.tag,\\n term: \\\"\\\",\\n});\\n\\nconst updateInput = (term) => {\\n State.update({\\n term: term,\\n });\\n};\\n\\nconst buttonStyle = {\\n backgroundColor: \\\"#0C7283\\\",\\n color: \\\"#f3f3f3\\\",\\n};\\n\\nconst PageTitle = styled.h5`\\n color: #00ec97;\\n font-size: 24px;\\n font-style: normal;\\n font-weight: 400;\\n line-height: 120%; /* 28.8px */\\n letter-spacing: -0.24px;\\n\\n margin: 0;\\n margin-bottom: 1rem;\\n`;\\n\\nconst Container = styled.div`\\n padding: 24px;\\n width: 100%;\\n`;\\n\\nconst PostContainer = styled.div`\\n margin: 0 1rem;\\n`;\\n\\nconst InputContainer = styled.div`\\n display: flex;\\n flex-direction: row;\\n position: relative;\\n width: 25%;\\n\\n @media screen and (max-width: 768px) {\\n width: 100%;\\n }\\n`;\\n\\nreturn (\\n <>\\n {!props.hideHeader && (\\n <Container>\\n <div className=\\\"w-100\\\">\\n <PageTitle>Activity Feed</PageTitle>\\n <div>\\n <div className=\\\"d-flex flex-column flex-lg-row gap-4\\\">\\n <InputContainer>\\n <div className=\\\"position-absolute d-flex ps-3 flex-column h-100 justify-center\\\">\\n <i class=\\\"bi bi-search m-auto\\\"></i>\\n </div>\\n <input\\n type=\\\"search\\\"\\n className=\\\"ps-5 form-control border border-0 bg-light\\\"\\n value={state.term ?? \\\"\\\"}\\n onChange={(e) => updateInput(e.target.value)}\\n onKeyDown={(e) => e.key == \\\"Enter\\\" && search()}\\n placeholder={props.placeholder ?? `Search by content`}\\n />\\n </InputContainer>\\n <div class=\\\"dropdown\\\">\\n <button\\n class=\\\"btn btn-light dropdown-toggle\\\"\\n type=\\\"button\\\"\\n data-bs-toggle=\\\"dropdown\\\"\\n aria-expanded=\\\"false\\\"\\n >\\n Sort{props.recency === \\\"all\\\" ? \\\": All replies\\\" : \\\": Latest\\\"}\\n </button>\\n <ul class=\\\"dropdown-menu px-2 shadow\\\">\\n <li>\\n <a\\n style={{ borderRadius: \\\"5px\\\" }}\\n class=\\\"dropdown-item link-underline link-underline-opacity-0\\\"\\n href={href({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"feed\\\" },\\n })}\\n >\\n Latest\\n </a>\\n </li>\\n <li>\\n <a\\n style={{ borderRadius: \\\"5px\\\" }}\\n class=\\\"dropdown-item link-underline link-underline-opacity-0\\\"\\n href={href({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"feed\\\" },\\n recency: \\\"all\\\",\\n })}\\n >\\n All replies\\n </a>\\n </li>\\n </ul>\\n </div>\\n <div class=\\\"dropdown\\\">\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.feature.post-search.by-author\\\"\\n props={{\\n author: state.author,\\n onAuthorSearch: (author) => {\\n State.update({ author });\\n },\\n }}\\n />\\n </div>\\n <div>\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.feature.post-search.by-tag\\\"\\n props={{\\n tag: state.tag,\\n onTagSearch: (tag) => {\\n State.update({ tag });\\n },\\n }}\\n />\\n </div>\\n <div className=\\\"d-flex flex-row-reverse flex-grow-1\\\">\\n {props.children}\\n </div>\\n </div>\\n </div>\\n </div>\\n </Container>\\n )}\\n <PostContainer>\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.entity.post.List\\\"\\n props={{\\n author: state.author,\\n tag: state.tag,\\n term: state.term,\\n recency: props.recency,\\n transactionHashes: props.transactionHashes,\\n }}\\n />\\n </PostContainer>\\n </>\\n);\\n"
}
,
"devhub.components.organism.Navbar"
:
{
""
:
"const page = props.page;\\n\\nconst [showMenu, setShowMenu] = useState(false);\\n\\nconst { href: linkHref } = VM.require(\\\"devhub.efiz.near/widget/core.lib.url\\\");\\n\\nlinkHref || (linkHref = () => {});\\n\\nconst Logo = () => {\\n const Wrapper = styled.div`\\n @media screen and (max-width: 768px) {\\n svg {\\n width: 90px;\\n height: 12px;\\n }\\n }\\n `;\\n\\n return (\\n <Wrapper>\\n <Link\\n to={linkHref({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"home\\\" },\\n })}\\n >\\n <svg\\n xmlns=\\\"http://www.w3.org/2000/svg\\\"\\n width=\\\"180\\\"\\n height=\\\"24\\\"\\n viewBox=\\\"0 0 180 24\\\"\\n fill=\\\"none\\\"\\n >\\n <g clip-path=\\\"url(#clip0_530_29)\\\">\\n <path\\n d=\\\"M8.62185 6.09766C11.8428 6.09766 14.5995 7.77588 14.5995 12.7821V20.8888H10.508V13.1803C10.508 10.7057 9.55041 9.39721 7.49016 9.39721C5.37187 9.39721 4.15313 10.8763 4.15313 13.4079V20.8888H0.0616455V6.26832H3.63081L4.00804 8.08877C4.96563 6.95099 6.32945 6.09766 8.62185 6.09766ZM23.911 21.0594C18.9489 21.0594 15.9601 18.1297 15.9601 13.607C15.9601 9.05588 19.007 6.09766 23.6208 6.09766C28.0895 6.09766 31.1073 8.82832 31.1654 13.1234C31.1654 13.5501 31.1364 14.0337 31.0493 14.4888H20.2257V14.6879C20.3128 16.7643 21.6766 18.0159 23.7369 18.0159C25.3909 18.0159 26.5516 17.3048 26.8998 15.9394H30.9332C30.4689 18.7839 27.8864 21.0594 23.911 21.0594ZM20.3128 11.8719H27.0449C26.7547 10.0799 25.5069 9.08432 23.6498 9.08432C21.8797 9.08432 20.5449 10.1368 20.3128 11.8719ZM47.0396 17.5039H47.5039V20.8888H45.4146C43.2963 20.8888 42.6289 19.8932 42.6579 18.4994C41.6133 20.1208 40.1044 21.0594 37.783 21.0594C34.562 21.0594 32.2406 19.5519 32.2406 16.7643C32.2406 13.6639 34.6201 11.9003 39.0888 11.9003H42.0486V11.1892C42.0486 9.88077 41.091 9.02743 39.3789 9.02743C37.783 9.02743 36.7093 9.73854 36.5352 10.8194H32.5888C32.879 7.97499 35.5486 6.09766 39.495 6.09766C43.6736 6.09766 46.082 7.9181 46.082 11.4168V16.5937C46.082 17.3617 46.4012 17.5039 47.0396 17.5039ZM42.0486 14.8585V14.5741H39.0598C37.3477 14.5741 36.3611 15.2568 36.3611 16.4799C36.3611 17.5039 37.2026 18.1581 38.5665 18.1581C40.7138 18.1581 42.0196 16.8497 42.0486 14.8585ZM56.8924 6.26832H57.5889V9.90921H55.9639C53.5264 9.90921 52.5978 11.5021 52.5978 13.7208V20.8888H48.5064V6.26832H52.2206L52.5978 8.45854C53.4103 7.1501 54.571 6.26832 56.8924 6.26832Z\\\"\\n fill=\\\"#00EC97\\\"\\n />\\n <path\\n d=\\\"M60.7221 23.961H59.2422L67.4542 0.124512H68.9341L60.7221 23.961ZM82.8081 8.08896V0.977843H86.8996V20.889H83.3304L82.9242 18.8694C81.9376 20.121 80.4867 21.0596 78.3394 21.0596C74.335 21.0596 71.4042 18.1867 71.4042 13.5503C71.4042 9.02762 74.335 6.09785 78.3104 6.09785C80.3706 6.09785 81.8505 6.89429 82.8081 8.08896ZM79.239 17.7885C81.4733 17.7885 82.8662 16.0818 82.8662 13.6072C82.8662 11.1041 81.4733 9.36896 79.239 9.36896C77.0046 9.36896 75.5827 11.0756 75.5827 13.5787C75.5827 16.0818 77.0046 17.7885 79.239 17.7885ZM96.2521 21.0596C91.2901 21.0596 88.3013 18.1298 88.3013 13.6072C88.3013 9.05607 91.3482 6.09785 95.962 6.09785C100.431 6.09785 103.449 8.82851 103.507 13.1236C103.507 13.5503 103.478 14.0338 103.39 14.489H92.5669V14.6881C92.6539 16.7645 94.0178 18.0161 96.078 18.0161C97.732 18.0161 98.8927 17.305 99.2409 15.9396H103.274C102.81 18.7841 100.228 21.0596 96.2521 21.0596ZM92.6539 11.8721H99.386C99.0959 10.0801 97.8481 9.08451 95.991 9.08451C94.2209 9.08451 92.8861 10.137 92.6539 11.8721ZM108.081 20.889L102.713 6.26851H107.094L110.692 16.793L114.233 6.26851H118.527L113.159 20.889H108.081ZM120.906 23.961H119.427L127.639 0.124512H129.118L120.906 23.961ZM140.671 6.09785C143.979 6.09785 146.707 7.83296 146.707 12.7823V20.889H142.615V13.1236C142.615 10.7343 141.629 9.3974 139.597 9.3974C137.508 9.3974 136.26 10.8765 136.26 13.3796V20.889H132.169V0.977843H136.26V8.06051C137.218 6.92273 138.553 6.09785 140.671 6.09785ZM158.367 13.5787V6.26851H162.459V20.889H158.832L158.454 19.1254C157.497 20.2632 156.191 21.0596 154.073 21.0596C150.997 21.0596 148.153 19.5521 148.153 14.3752V6.26851H152.245V13.8347C152.245 16.4516 153.115 17.7316 155.146 17.7316C157.178 17.7316 158.367 16.281 158.367 13.5787ZM173.022 6.09785C177.027 6.09785 179.928 8.91385 179.928 13.5503C179.928 18.073 177.027 21.0596 172.993 21.0596C170.846 21.0596 169.366 20.1494 168.408 18.8978L168.002 20.889H164.433V0.977843H168.524V8.1174C169.511 6.95118 170.962 6.09785 173.022 6.09785ZM172.094 17.7885C174.328 17.7885 175.779 16.0818 175.779 13.5787C175.779 11.0756 174.328 9.36896 172.094 9.36896C169.859 9.36896 168.466 11.0756 168.466 13.5503C168.466 16.0534 169.859 17.7885 172.094 17.7885Z\\\"\\n fill=\\\"#151515\\\"\\n />\\n </g>\\n <defs>\\n <clipPath id=\\\"clip0_530_29\\\">\\n <rect width=\\\"180\\\" height=\\\"24\\\" fill=\\\"white\\\" />\\n </clipPath>\\n </defs>\\n </svg>\\n </Link>\\n </Wrapper>\\n );\\n};\\n\\nconst ProfileIcon = () => {\\n const Wrapper = styled.svg`\\n padding: 0.25rem;\\n @media screen and (max-width: 768px) {\\n display: none;\\n }\\n `;\\n return (\\n <Link\\n to={linkHref({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"profile\\\", accountId: context.accountId },\\n })}\\n >\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.components.molecule.ProfileCard\\\"\\n props={{ iconOnly: true, accountId: context.accountId || null }}\\n />\\n </Link>\\n );\\n};\\n\\nconst MenuIcon = () => (\\n <svg\\n xmlns=\\\"http://www.w3.org/2000/svg\\\"\\n width=\\\"16\\\"\\n height=\\\"16\\\"\\n viewBox=\\\"0 0 16 16\\\"\\n fill=\\\"none\\\"\\n >\\n <path\\n fill-rule=\\\"evenodd\\\"\\n clip-rule=\\\"evenodd\\\"\\n d=\\\"M2 12.2986H14V13.3732H2V12.2986ZM2 9.07471H14V10.1493H2V9.07471ZM2 5.85083H14V6.92546H2V5.85083ZM2 2.62695H14V3.70158H2V2.62695Z\\\"\\n fill=\\\"#818181\\\"\\n />\\n </svg>\\n);\\n\\nconst Navbar = styled.div`\\n padding: 1.5rem 3rem;\\n\\n display: flex;\\n flex-direction: row;\\n justify-content: space-between;\\n align-items: center;\\n\\n background: #f4f4f4;\\n\\n @media screen and (max-width: 768px) {\\n padding: 1.875rem 1.375rem;\\n }\\n`;\\n\\nconst LinksContainer = styled.div`\\n display: flex;\\n flex-direction: row;\\n align-items: center;\\n gap: 1.5rem;\\n\\n @media screen and (max-width: 768px) {\\n display: none;\\n }\\n`;\\n\\nconst MobileMenu = styled.button`\\n all: unset;\\n display: none;\\n\\n @media screen and (max-width: 768px) {\\n display: block;\\n }\\n`;\\n\\nconst links = [\\n {\\n title: \\\"/communities\\\",\\n href: \\\"communities\\\",\\n links: [],\\n },\\n {\\n title: \\\"/activity feed\\\",\\n href: \\\"feed\\\",\\n links: [],\\n },\\n {\\n title: \\\"/about\\\",\\n links: [\\n { title: \\\"mission\\\", href: \\\"mission\\\" },\\n { title: \\\"blog\\\", href: \\\"blog\\\" },\\n { title: \\\"newsletter\\\", href: \\\"newsletter\\\" },\\n { title: \\\"calendar\\\", href: \\\"calendar\\\" },\\n { title: \\\"brand kit\\\", href: \\\"brand-kit\\\" },\\n ],\\n },\\n];\\n\\nconst MobileNav = styled.div`\\n display: none;\\n\\n @media screen and (max-width: 768px) {\\n display: flex;\\n }\\n\\n position: absolute;\\n top: 0;\\n right: 0;\\n\\n width: 207px;\\n\\n padding: 24px 36px 36px 16px;\\n flex-direction: column;\\n align-items: flex-end;\\n gap: 2.5rem;\\n flex-shrink: 0;\\n\\n border-radius: 0px 0px 0px 16px;\\n background: rgba(41, 41, 41, 0.6);\\n backdrop-filter: blur(5px);\\n\\n z-index: 50;\\n`;\\n\\nconst MobileLink = styled.a`\\n color: #f4f4f4 !important;\\n font-size: 20px;\\n font-style: normal;\\n font-weight: 400;\\n line-height: 20px; /* 100% */\\n margin-bottom: 1rem;\\n\\n &.active {\\n color: #00ec97 !important;\\n }\\n`;\\n\\nreturn (\\n <Navbar className=\\\"position-relative\\\">\\n <Logo />\\n <div className=\\\"d-flex gap-3 align-items-center\\\">\\n <LinksContainer>\\n {links.map((link) => (\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.components.molecule.NavbarDropdown\\\"\\n props={{\\n title: link.title,\\n href: link.href,\\n links: link.links,\\n page: page,\\n }}\\n />\\n ))}\\n </LinksContainer>\\n {context.accountId && <ProfileIcon />}\\n <MobileMenu onClick={() => setShowMenu(!showMenu)}>\\n <MenuIcon />\\n </MobileMenu>\\n </div>\\n {showMenu && (\\n <MobileNav>\\n <div\\n onClick={() => setShowMenu(!showMenu)}\\n style={{ cursor: \\\"pointer\\\" }}\\n >\\n <i className=\\\"bi bi-x\\\" style={{ fontSize: 20, color: \\\"#F4F4F4\\\" }}></i>\\n </div>\\n <div className=\\\"d-flex flex-column gap-2\\\">\\n {links.map((link, idx) =>\\n link.href ? (\\n <MobileLink\\n key={`mobile-link-${idx}`}\\n className={link.href === props.page && \\\"active\\\"}\\n href={`/devhub.efiz.near/widget/app?page=${link.href}`}\\n >\\n {link.title}\\n </MobileLink>\\n ) : (\\n link.links.map((it, idx) => (\\n <MobileLink\\n key={`nested-link-${idx}`}\\n className={link.href === props.page && \\\"active\\\"}\\n href={`/devhub.efiz.near/widget/app?page=${it.href}`}\\n >\\n {it.title}\\n </MobileLink>\\n ))\\n )\\n )}\\n </div>\\n </MobileNav>\\n )}\\n </Navbar>\\n);\\n"
}
,
"devhub.components.island.participate"
:
{
""
:
"const { href } = VM.require(\\\"devhub.efiz.near/widget/core.lib.url\\\");\\n\\nhref || (href = () => {});\\n\\nconst Container = styled.div`\\n margin-top: 2.25rem;\\n\\n display: flex;\\n flex-direction: row;\\n justify-content: space-between;\\n width: 100%;\\n\\n @media screen and (max-width: 768px) {\\n flex-direction: column;\\n margin-top: 0;\\n }\\n`;\\n\\nconst LinkItem = styled.a`\\n color: #00ec97;\\n font-size: 1.25rem;\\n font-style: normal;\\n font-weight: 400;\\n line-height: 120%; /* 28.8px */\\n\\n display: flex;\\n align-items: center;\\n\\n &:hover {\\n text-decoration: none;\\n color: #04146e;\\n }\\n`;\\n\\nconst Links = [\\n {\\n links: [\\n { title: \\\"Propose an idea\\\", href: \\\"#\\\", count: 1 },\\n { title: \\\"Build a solution\\\", href: \\\"#\\\", count: 2 },\\n { title: \\\"Host an Event\\\", href: \\\"#\\\", count: 3 },\\n ],\\n },\\n {\\n links: [\\n { title: \\\"Improve NEAR Docs\\\", href: \\\"#\\\", count: 4 },\\n { title: \\\"Join forum discussions\\\", href: \\\"#\\\", count: 5 },\\n ],\\n },\\n {\\n links: [\\n { title: \\\"Become a Mentee/Mentor\\\", href: \\\"#\\\", count: 6 },\\n { title: \\\"Join NEAR Campus\\\", href: \\\"#\\\", count: 7 },\\n ],\\n },\\n];\\n\\nconst CTA = styled.a`\\n display: flex;\\n padding: 0.875rem 1rem;\\n align-items: center;\\n gap: 0.5rem;\\n\\n border-radius: 1rem;\\n background: #00ec97;\\n\\n color: #f4f4f4 !important;\\n font-size: 1.5rem;\\n font-style: normal;\\n font-weight: 700;\\n line-height: 120%; /* 28.8px */\\n letter-spacing: -0.03rem;\\n\\n width: max-content;\\n margin-top: 1.5rem;\\n\\n &:hover {\\n background: #04a46e;\\n text-decoration: none !important;\\n }\\n\\n @media screen and (max-width: 768px) {\\n color: #f4f4f4 !important;\\n font-size: 20px;\\n font-style: normal;\\n font-weight: 700;\\n line-height: 120%; /* 24px */\\n\\n display: flex;\\n padding: 14px 16px;\\n align-items: center;\\n gap: 8px;\\n\\n border-radius: 16px;\\n background: #04a46e;\\n\\n &:hover {\\n //background: #04A46E;\\n text-decoration: none;\\n }\\n }\\n`;\\n\\nconst SectionPadding = styled.div`\\n padding: 3rem;\\n padding-top: 0;\\n\\n display: flex;\\n flex-direction: column;\\n\\n @media screen and (max-width: 768px) {\\n padding: 1rem;\\n padding-top: 0;\\n }\\n`;\\n\\nconst LinksContainer = styled.div`\\n width: 30%;\\n\\n @media screen and (max-width: 768px) {\\n width: 100%;\\n margin-bottom: 1rem;\\n }\\n`;\\n\\nconst Content = (\\n <SectionPadding>\\n <Container>\\n {Links.map((it) => (\\n <LinksContainer key={Math.random()}>\\n <div className=\\\"d-flex flex-column gap-3 gap-md-2\\\">\\n {it.links.map((link) => (\\n <div className=\\\"d-flex flex-row\\\">\\n <span\\n style={{\\n color: \\\"#04A46E\\\",\\n border: \\\"2px #04A46E solid\\\",\\n fontSize: 12,\\n padding: 4,\\n width: 22,\\n height: 22,\\n }}\\n className=\\\"rounded-circle d-flex align-items-center justify-content-center me-1\\\"\\n >\\n {link.count}\\n </span>{\\\" \\\"}\\n <LinkItem href={link.href}>{link.title}</LinkItem>\\n </div>\\n ))}\\n </div>\\n </LinksContainer>\\n ))}\\n </Container>\\n\\n <Link\\n to={href({\\n widgetSrc: \\\"devhub.efiz.near/widget/app\\\",\\n params: { page: \\\"contribute\\\" },\\n })}\\n style={{ textDecoration: \\\"none\\\" }}\\n >\\n <CTA>Learn more \\u{2192}</CTA>\\n </Link>\\n </SectionPadding>\\n);\\n\\nreturn (\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.components.island.home-section\\\"\\n props={{\\n title: \\\"/participate\\\",\\n titleColor: \\\"#04A46E\\\",\\n description:\\n \\\"There are many ways to start your contribution journey. You can:\\\",\\n children: Content,\\n }}\\n />\\n);\\n"
}
,
"devhub.entity.addon.wiki.Configurator"
:
{
""
:
"const { data, onSubmit } = props;\\n\\nconst initialData = data;\\nconst [content, setContent] = useState(data.content || \\\"\\\");\\nconst [title, setTitle] = useState(data.title || \\\"\\\");\\nconst [subtitle, setSubtitle] = useState(data.subtitle || \\\"\\\");\\n\\nconst [textAlign, setTextAlign] = useState(data.textAlign || \\\"left\\\");\\n\\nconst Container = styled.div`\\n width: 100%;\\n margin: 0 auto;\\n padding: 20px;\\n text-align: left;\\n`;\\n\\nconst FormContainer = styled.div`\\n padding-top: 1rem;\\n\\n & > *:not(:last-child) {\\n margin-bottom: 1rem;\\n }\\n`;\\n\\nconst hasDataChanged = () => {\\n return (\\n content !== initialData.content ||\\n title !== initialData.title ||\\n subtitle !== initialData.subtitle ||\\n textAlign !== initialData.textAlign\\n );\\n};\\n\\nconst handleSubmit = () => {\\n if (title) onSubmit({ title, subtitle, content, textAlign });\\n};\\n\\nreturn (\\n <Container>\\n <ul className=\\\"nav nav-tabs\\\" id=\\\"editPreviewTabs\\\" role=\\\"tablist\\\">\\n <li className=\\\"nav-item\\\" role=\\\"presentation\\\">\\n <button\\n className=\\\"nav-link active\\\"\\n id=\\\"edit-tab\\\"\\n data-bs-toggle=\\\"tab\\\"\\n data-bs-target=\\\"#edit\\\"\\n type=\\\"button\\\"\\n role=\\\"tab\\\"\\n aria-controls=\\\"edit\\\"\\n aria-selected=\\\"true\\\"\\n >\\n Edit\\n </button>\\n </li>\\n <li className=\\\"nav-item\\\" role=\\\"presentation\\\">\\n <button\\n className=\\\"nav-link\\\"\\n id=\\\"preview-tab\\\"\\n data-bs-toggle=\\\"tab\\\"\\n data-bs-target=\\\"#preview\\\"\\n type=\\\"button\\\"\\n role=\\\"tab\\\"\\n aria-controls=\\\"preview\\\"\\n aria-selected=\\\"false\\\"\\n >\\n Preview\\n </button>\\n </li>\\n </ul>\\n <div className=\\\"tab-content\\\" id=\\\"editPreviewTabsContent\\\">\\n <div\\n className=\\\"tab-pane show active p-4\\\"\\n id=\\\"edit\\\"\\n role=\\\"tabpanel\\\"\\n aria-labelledby=\\\"edit-tab\\\"\\n style={{ position: \\\"relative\\\" }}\\n >\\n <div style={{ position: \\\"absolute\\\", top: 10, right: 0 }}>\\n <Widget\\n // LEGACY\\n src=\\\"devhub.efiz.near/widget/gigs-board.components.molecule.button-switch\\\"\\n props={{\\n currentValue: textAlign,\\n key: \\\"textAlign\\\",\\n onChange: (e) => setTextAlign(e.target.value),\\n options: [\\n { label: \\\"Left\\\", value: \\\"left\\\" },\\n { label: \\\"Center\\\", value: \\\"center\\\" },\\n { label: \\\"Right\\\", value: \\\"right\\\" },\\n ],\\n }}\\n />\\n </div>\\n <FormContainer>\\n <div className=\\\"flex-grow-1\\\">\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.components.molecule.Input\\\"\\n props={{\\n label: \\\"Title\\\",\\n className: \\\"flex-grow-1\\\",\\n onChange: (e) => setTitle(e.target.value),\\n value: title,\\n inputProps: {\\n min: 2,\\n max: 60,\\n required: true,\\n },\\n }}\\n />\\n </div>\\n <div className=\\\"flex-grow-1\\\">\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.components.molecule.Input\\\"\\n props={{\\n label: \\\"Subtitle\\\",\\n className: \\\"flex-grow-1\\\",\\n onChange: (e) => setSubtitle(e.target.value),\\n value: subtitle,\\n inputProps: {\\n min: 2,\\n max: 250,\\n },\\n }}\\n />\\n </div>\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.components.molecule.MarkdownEditor\\\"\\n props={{ data: { content }, onChange: setContent }}\\n />\\n </FormContainer>\\n <div\\n className={\\\"d-flex align-items-center justify-content-end gap-3 mt-4\\\"}\\n >\\n <Widget\\n src={\\\"devhub.efiz.near/widget/devhub.components.molecule.Button\\\"}\\n props={{\\n classNames: { root: \\\"btn-success\\\" },\\n disabled: !hasDataChanged() || !title || !content,\\n icon: {\\n type: \\\"bootstrap_icon\\\",\\n variant: \\\"bi-check-circle-fill\\\",\\n },\\n label: \\\"Publish\\\",\\n onClick: handleSubmit,\\n }}\\n />\\n </div>\\n </div>\\n <div\\n className=\\\"tab-pane\\\"\\n id=\\\"preview\\\"\\n role=\\\"tabpanel\\\"\\n aria-labelledby=\\\"preview-tab\\\"\\n >\\n <div className=\\\"w-100 h-100 p-4\\\">\\n <Widget\\n src=\\\"devhub.efiz.near/widget/devhub.entity.addon.wiki.Viewer\\\"\\n props={{ title, subtitle, content, textAlign }}\\n />\\n </div>\\n </div>\\n </div>\\n </Container>\\n);\\n"
}
,
"devhub.components.molecule.ProfileCard"
:
{
""
:
"const MutedText = styled.span`\\n color: #818181;\\n\\n font-size: 16px;\\n font-style: normal;\\n font-weight: 400;\\n line-height: 20px; /* 125% */\\n`;\\n\\nconst AccountName = styled.span`\\n color: #818181;\\n font-size: 16px;\\n font-style: normal;\\n font-weight: 500;\\n line-height: 20px;\\n\\n max-width: 30ch;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n white-space: nowrap;\\n`;\\n\\nconst ProfileCard = (props) => {\\n const accountId = props.accountId ?? context.accountId;\\n const link = props.link ?? true;\\n // const hideAccountId = props.hideAccountId;\\n // const hideName = props.hideName;\\n const hideImage = props.hideImage;\\n const iconOnly = props.iconOnly;\\n\\n const profile = props.profile ?? Social.getr(`${accountId}/profile`);\\n\\n const name = profile.name ?? accountId;\\n const title = props.title ?? `${name} @${accountId}`;\\n const tooltip =\\n props.tooltip && (props.tooltip === true ? title : props.tooltip);\\n\\n let inner = (\\n <div className=\\\"d-flex flex-row justify-content-center align-items-center\\\">\\n {!hideImage && (\\n <Widget\\n key=\\\"image\\\"\\n src=\\\"mob.near/widget/ProfileImage\\\"\\n props={{\\n style: { width: \\\"3em\\\", height: \\\"3em\\\", marginRight: \\\"0.3em\\\" },\\n profile,\\n accountId,\\n className: \\\"d-inline-block flex-shrink-0\\\",\\n imageClassName: \\\"rounded-circle w-100 h-100 align-top\\\",\\n }}\\n />\\n )}\\n {!iconOnly && (\\n <div className=\\\"d-flex flex-column gap-1\\\">\\n <AccountName key=\\\"accountName\\\">{name}</AccountName>\\n <AccountName key=\\\"accountId\\\">@{accountId}</AccountName>\\n </div>\\n )}\\n </div>\\n );\\n\\n inner = link ? (\\n <a\\n href={\\n link !== true\\n ? link\\n : `devhub.efiz.near/widget/ProfilePage?accountId=${accountId}`\\n }\\n className=\\\"link-dark text-truncate d-inline-flex\\\"\\n >\\n {inner}\\n </a>\\n ) : (\\n <span className=\\\"text-truncate d-inline-flex\\\">{inner}</span>\\n );\\n\\n if (props.tooltip === true) {\\n return (\\n <Widget\\n src=\\\"mob.near/widget/Profile.OverlayTrigger\\\"\\n props={{ accountId, children: inner }}\\n />\\n );\\n }\\n if (tooltip) {\\n inner = (\\n <OverlayTrigger placement=\\\"auto\\\" overlay={<Tooltip>{tooltip}</Tooltip>}>\\n {inner}\\n </OverlayTrigger>\\n );\\n }\\n return (\\n <div className=\\\"d-flex flex-row align-items-center\\\">\\n {inner}\\n <Widget\\n src=\\\"neardevgov.near/widget/BadgesList\\\"\\n props={{\\n accountId,\\n mode: \\\"compact\\\",\\n }}\\n />\\n </div>\\n );\\n};\\n\\nreturn ProfileCard(props);\\n"
}
}
}
}
}
Output
Inspect
Result:
Empty Result
Logs:
No Logs