From 23cd43b26ca1ded844c189a9b34d6d30deee2fa0 Mon Sep 17 00:00:00 2001 From: Vitalsine85 Date: Wed, 4 Sep 2024 15:23:31 -0400 Subject: [PATCH 1/2] create IdentityInfoCard in Portal --- .../app/components/identity-info-card.tsx | 133 ++++++++++++++++++ apps/portal/app/routes/app+/identity+/$id.tsx | 40 ++++-- 2 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 apps/portal/app/components/identity-info-card.tsx diff --git a/apps/portal/app/components/identity-info-card.tsx b/apps/portal/app/components/identity-info-card.tsx new file mode 100644 index 000000000..07e78182e --- /dev/null +++ b/apps/portal/app/components/identity-info-card.tsx @@ -0,0 +1,133 @@ +import { + Button, + ButtonVariant, + cn, + HoverCard, + HoverCardContent, + HoverCardTrigger, + Icon, + Identity, + IdentityTag, + IdentityType, + ProfileCard, + Text, + TextVariant, + Trunctacular, +} from '@0xintuition/1ui' +import { ClaimPresenter } from '@0xintuition/api' + +import { PATHS } from '@consts/paths' + +export interface IdentityInfoCardProps + extends React.HTMLAttributes { + variant: IdentityType + list: ClaimPresenter + username: string + avatarImgSrc: string + id: string + description: string + link: string + ipfsLink: string + timestamp: string +} + +const IdentityInfoCard = ({ + variant = Identity.user, + list, + username, + avatarImgSrc, + id, + description, + link, + ipfsLink, + timestamp, + className, + ...props +}: IdentityInfoCardProps) => { + const formattedDate = new Intl.DateTimeFormat('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + }).format(new Date(timestamp)) + + return ( +
+ {list && ( +
+ + List + +
+ + + + + +
+
+ )} +
+ + Creator + +
+ + + + + + + + + +
+ + {link && ( + + + + )} +
+
+
+ + + {formattedDate} + +
+
+
+ ) +} + +export { IdentityInfoCard } diff --git a/apps/portal/app/routes/app+/identity+/$id.tsx b/apps/portal/app/routes/app+/identity+/$id.tsx index 3c6b1fdf8..4bfa22f1d 100644 --- a/apps/portal/app/routes/app+/identity+/$id.tsx +++ b/apps/portal/app/routes/app+/identity+/$id.tsx @@ -4,7 +4,6 @@ import { Banner, Icon, Identity, - InfoCard, PieChartVariant, PositionCard, PositionCardLastUpdated, @@ -18,9 +17,15 @@ import { TagsContent, TagWithValue, } from '@0xintuition/1ui' -import { IdentityPresenter, TagEmbeddedPresenter } from '@0xintuition/api' +import { + ClaimPresenter, + ClaimsService, + IdentityPresenter, + TagEmbeddedPresenter, +} from '@0xintuition/api' import { ErrorPage } from '@components/error-page' +import { IdentityInfoCard } from '@components/identity-info-card' import NavigationButton from '@components/navigation-link' import ImageModal from '@components/profile/image-modal' import SaveListModal from '@components/save-list/save-list-modal' @@ -34,6 +39,7 @@ import { stakeModalAtom, tagsModalAtom, } from '@lib/state/store' +import { getSpecialPredicate } from '@lib/utils/app' import logger from '@lib/utils/logger' import { calculatePercentageOfTvl, @@ -51,12 +57,12 @@ import { requireUser, requireUserWallet } from '@server/auth' import { getVaultDetails } from '@server/multivault' import { BLOCK_EXPLORER_URL, + CURRENT_ENV, MULTIVAULT_CONTRACT_ADDRESS, NO_WALLET_ERROR, PATHS, } from 'app/consts' import TwoPanelLayout from 'app/layouts/two-panel-layout' -import { ExtendedIdentityPresenter } from 'app/types/identity' import { VaultDetailsType } from 'app/types/vault' import { useAtom } from 'jotai' @@ -79,6 +85,21 @@ export async function loader({ request, params }: LoaderFunctionArgs) { throw new Response('Not Found', { status: 404 }) } + let list: ClaimPresenter | null = null + + try { + const listResult = await ClaimsService.searchClaims({ + predicate: getSpecialPredicate(CURRENT_ENV).tagPredicate.id, + object: identity.id, + }) + + if (listResult && listResult.data.length > 0) { + list = listResult.data[0] + } + } catch (error) { + logger('Failed to fetch list:', error) + } + let vaultDetails: VaultDetailsType | null = null if (!!identity && identity.vault_id) { @@ -97,6 +118,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) { logger('[$ID] -- END') return json({ identity, + list, isPending, vaultDetails, userWallet, @@ -105,18 +127,15 @@ export async function loader({ request, params }: LoaderFunctionArgs) { export interface IdentityLoaderData { identity: IdentityPresenter + list: ClaimPresenter vaultDetails: VaultDetailsType userWallet: string isPending: boolean } export default function IdentityDetails() { - const { identity, vaultDetails, userWallet, isPending } = useLiveLoader<{ - identity: ExtendedIdentityPresenter - vaultDetails: VaultDetailsType - userWallet: string - isPending: boolean - }>(['attest', 'create']) + const { identity, list, vaultDetails, userWallet, isPending } = + useLiveLoader(['attest', 'create']) const navigate = useNavigate() const { user_assets, assets_sum } = vaultDetails ? vaultDetails : identity @@ -236,8 +255,9 @@ export default function IdentityDetails() { /> )} - Date: Wed, 4 Sep 2024 15:30:45 -0400 Subject: [PATCH 2/2] add support for claims --- ...ity-info-card.tsx => detail-info-card.tsx} | 10 +++---- apps/portal/app/routes/app+/claim+/$id.tsx | 27 ++++++++++++------- apps/portal/app/routes/app+/identity+/$id.tsx | 4 +-- 3 files changed, 24 insertions(+), 17 deletions(-) rename apps/portal/app/components/{identity-info-card.tsx => detail-info-card.tsx} (95%) diff --git a/apps/portal/app/components/identity-info-card.tsx b/apps/portal/app/components/detail-info-card.tsx similarity index 95% rename from apps/portal/app/components/identity-info-card.tsx rename to apps/portal/app/components/detail-info-card.tsx index 07e78182e..81a7bda9b 100644 --- a/apps/portal/app/components/identity-info-card.tsx +++ b/apps/portal/app/components/detail-info-card.tsx @@ -18,10 +18,10 @@ import { ClaimPresenter } from '@0xintuition/api' import { PATHS } from '@consts/paths' -export interface IdentityInfoCardProps +export interface DetailInfoCardProps extends React.HTMLAttributes { variant: IdentityType - list: ClaimPresenter + list?: ClaimPresenter username: string avatarImgSrc: string id: string @@ -31,7 +31,7 @@ export interface IdentityInfoCardProps timestamp: string } -const IdentityInfoCard = ({ +const DetailInfoCard = ({ variant = Identity.user, list, username, @@ -43,7 +43,7 @@ const IdentityInfoCard = ({ timestamp, className, ...props -}: IdentityInfoCardProps) => { +}: DetailInfoCardProps) => { const formattedDate = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', @@ -130,4 +130,4 @@ const IdentityInfoCard = ({ ) } -export { IdentityInfoCard } +export { DetailInfoCard } diff --git a/apps/portal/app/routes/app+/claim+/$id.tsx b/apps/portal/app/routes/app+/claim+/$id.tsx index 7bf0bd3c4..5dd782bae 100644 --- a/apps/portal/app/routes/app+/claim+/$id.tsx +++ b/apps/portal/app/routes/app+/claim+/$id.tsx @@ -4,7 +4,6 @@ import { ClaimStakeCard, Icon, Identity, - InfoCard, PieChartVariant, PositionCard, PositionCardLastUpdated, @@ -21,6 +20,7 @@ import { SortDirection, } from '@0xintuition/api' +import { DetailInfoCard } from '@components/detail-info-card' import { ErrorPage } from '@components/error-page' import NavigationButton from '@components/navigation-link' import StakeModal from '@components/stake/stake-modal' @@ -28,6 +28,7 @@ import { useGoBack } from '@lib/hooks/useGoBack' import { useLiveLoader } from '@lib/hooks/useLiveLoader' import { getClaimOrPending } from '@lib/services/claims' import { stakeModalAtom } from '@lib/state/store' +import { getSpecialPredicate } from '@lib/utils/app' import { calculatePercentageOfTvl, formatBalance, @@ -39,10 +40,15 @@ import { invariant, } from '@lib/utils/misc' import { json, LoaderFunctionArgs } from '@remix-run/node' -import { Outlet, useNavigate } from '@remix-run/react' +import { Outlet } from '@remix-run/react' import { requireUserWallet } from '@server/auth' import { getVaultDetails } from '@server/multivault' -import { BLOCK_EXPLORER_URL, NO_WALLET_ERROR, PATHS } from 'app/consts' +import { + BLOCK_EXPLORER_URL, + CURRENT_ENV, + NO_WALLET_ERROR, + PATHS, +} from 'app/consts' import TwoPanelLayout from 'app/layouts/two-panel-layout' import { VaultDetailsType } from 'app/types/vault' import { useAtom } from 'jotai' @@ -108,8 +114,6 @@ export default function ClaimDetails() { vaultDetails: VaultDetailsType isPending: boolean }>(['create', 'attest']) - const navigate = useNavigate() - const [stakeModalActive, setStakeModalActive] = useAtom(stakeModalAtom) const direction: 'for' | 'against' = isPending @@ -285,8 +289,14 @@ export default function ClaimDetails() { } /> )} - { - navigate(`/app/profile/${claim.creator?.wallet}`) - }} - className="hover:cursor-pointer w-full" + className="w-full" /> ) diff --git a/apps/portal/app/routes/app+/identity+/$id.tsx b/apps/portal/app/routes/app+/identity+/$id.tsx index 4bfa22f1d..dc639eeed 100644 --- a/apps/portal/app/routes/app+/identity+/$id.tsx +++ b/apps/portal/app/routes/app+/identity+/$id.tsx @@ -24,8 +24,8 @@ import { TagEmbeddedPresenter, } from '@0xintuition/api' +import { DetailInfoCard } from '@components/detail-info-card' import { ErrorPage } from '@components/error-page' -import { IdentityInfoCard } from '@components/identity-info-card' import NavigationButton from '@components/navigation-link' import ImageModal from '@components/profile/image-modal' import SaveListModal from '@components/save-list/save-list-modal' @@ -255,7 +255,7 @@ export default function IdentityDetails() { /> )} -