diff --git a/packages/commonwealth/client/scripts/helpers/feature-flags.ts b/packages/commonwealth/client/scripts/helpers/feature-flags.ts index b6d64604011..449f2452cc4 100644 --- a/packages/commonwealth/client/scripts/helpers/feature-flags.ts +++ b/packages/commonwealth/client/scripts/helpers/feature-flags.ts @@ -40,6 +40,7 @@ const featureFlags = { trustLevel: buildFlag(process.env.FLAG_TRUST_LEVEL), tokenizedThreads: buildFlag(process.env.FLAG_TOKENIZED_THREADS), partnershipWallet: buildFlag(process.env.FLAG_PARTNERSHIP_WALLET), + newProfilePage: buildFlag(process.env.FLAG_NEW_PROFILE_PAGE), }; export type AvailableFeatureFlag = keyof typeof featureFlags; diff --git a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityStake/CommunityStake.scss b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityStake/CommunityStake.scss new file mode 100644 index 00000000000..32c0674e8b5 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityStake/CommunityStake.scss @@ -0,0 +1,7 @@ +@import '../../../../../../styles/mixins/colors.module'; + +.CommunityStake { + .green-500 { + color: $green-500; + } +} diff --git a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityStake/CommunityStake.tsx b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityStake/CommunityStake.tsx new file mode 100644 index 00000000000..4ad2166ccd2 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityStake/CommunityStake.tsx @@ -0,0 +1,52 @@ +import React, { useRef } from 'react'; + +import { ExtendedCommunity } from '@hicommonwealth/schemas'; +import { useCommunityCardPrice } from 'client/scripts/hooks/useCommunityCardPrice'; +import { useGetCommunityByIdQuery } from 'client/scripts/state/api/communities'; +import { CWText } from 'client/scripts/views/components/component_kit/cw_text'; +import { useFetchTokenUsdRateQuery } from 'state/api/communityStake/index'; +import { trpc } from 'utils/trpcClient'; +import { z } from 'zod'; +import './CommunityStake.scss'; + +interface CommunityStakeProps { + communityId: string; +} + +export const CommunityStake = ({ communityId }: CommunityStakeProps) => { + const { data: community } = useGetCommunityByIdQuery({ + id: communityId, + includeNodeInfo: true, + }); + + const { data: ethUsdRateData } = useFetchTokenUsdRateQuery({ + tokenSymbol: 'ETH', + }); + const ethUsdRate = ethUsdRateData?.data?.data?.amount; + + const oneDayAgo = useRef(new Date().getTime() - 24 * 60 * 60 * 1000); + + const { data: historicalPrices } = + trpc.community.getStakeHistoricalPrice.useQuery({ + past_date_epoch: oneDayAgo.current / 1000, + }); + + const { stakeValue } = useCommunityCardPrice({ + community: community as z.infer, + // @ts-expect-error + ethUsdRate, + stakeId: 2, + // @ts-expect-error + historicalPrice: historicalPrices, + }); + + return ( +
+ {stakeValue && ( + + {stakeValue} ETH + + )} +
+ ); +}; diff --git a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityTab.scss b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityTab.scss new file mode 100644 index 00000000000..51463273bc1 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityTab.scss @@ -0,0 +1,4 @@ +@import '../../../../../styles/shared.scss'; +.CommunityTab { + padding: 0px; +} diff --git a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityTab.tsx b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityTab.tsx new file mode 100644 index 00000000000..1409b5f86a2 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/CommunityTab.tsx @@ -0,0 +1,63 @@ +import React from 'react'; + +import useUserStore from 'state/ui/user'; +import { CWText } from '../../../component_kit/cw_text'; +import { CWTable } from '../../../component_kit/new_designs/CWTable'; +import { CommunityStake } from './CommunityStake/CommunityStake'; +import './CommunityTab.scss'; +import { LastActive } from './LastActive/LastActive'; +import { Role } from './Role/Role'; + +export const CommunityTab = () => { + const user = useUserStore(); + + const columns = [ + { + key: 'name', + header: 'Community', + numeric: false, + sortable: true, + }, + { + key: 'role', + header: 'Role', + numeric: false, + sortable: true, + }, + { + key: 'stake', + header: 'Stake', + numeric: true, + sortable: true, + }, + { + key: 'lastActive', + header: 'Last Active', + numeric: false, + sortable: true, + }, + ]; + + const rowData = user.communities.map((community) => ({ + name: community.name, + stake: , + role: , + lastActive: , + avatars: { + name: { + avatarUrl: community.iconUrl, + address: null, + }, + }, + })); + + return ( +
+ {user.communities.length > 0 ? ( + + ) : ( + No communities found + )} +
+ ); +}; diff --git a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/LastActive/LastActive.tsx b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/LastActive/LastActive.tsx new file mode 100644 index 00000000000..0ccf60fa22c --- /dev/null +++ b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/LastActive/LastActive.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { trpc } from 'utils/trpcClient'; +import { CWText } from '../../../../component_kit/cw_text'; + +interface LastActiveProps { + communityId: string; +} + +export const LastActive = ({ communityId }: LastActiveProps) => { + const { data: memberData } = trpc.community.getMembers.useQuery({ + community_id: communityId, + limit: 1, + order_by: 'last_active', + include_roles: true, + }); + + const lastActive = memberData?.results?.[0]?.last_active; + const formattedDate = lastActive + ? new Date(lastActive).toLocaleDateString() + : '-'; + + return {formattedDate}; +}; diff --git a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/Role/Role.tsx b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/Role/Role.tsx new file mode 100644 index 00000000000..a6fcdafbc4f --- /dev/null +++ b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/Role/Role.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { trpc } from 'utils/trpcClient'; +import { CWText } from '../../../../component_kit/cw_text'; + +interface RoleProps { + communityId: string; +} + +export const Role = ({ communityId }: RoleProps) => { + const { data: memberData } = trpc.community.getMembers.useQuery({ + community_id: communityId, + limit: 1, + include_roles: true, + }); + + const role = memberData?.results?.[0]?.addresses?.[0]?.role || 'member'; + + return ( + + {role} + + ); +}; diff --git a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/index.ts b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/index.ts new file mode 100644 index 00000000000..bb51b002b92 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/CommunityTab/index.ts @@ -0,0 +1,3 @@ +import { CommunityTab } from './CommunityTab'; + +export default CommunityTab; diff --git a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/ProfileActivity.scss b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/ProfileActivity.scss index c5c06b8c0cd..31b45c127eb 100644 --- a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/ProfileActivity.scss +++ b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/ProfileActivity.scss @@ -73,6 +73,9 @@ &.removePadding { padding: 0 !important; } + &.communityPadding { + padding: 0 12px !important; + } .ThreadCard { padding-left: 0px !important; padding-right: 0px !important; diff --git a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/ProfileActivity.tsx b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/ProfileActivity.tsx index ce9a8404039..29f5faaaa46 100644 --- a/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/ProfileActivity.tsx +++ b/packages/commonwealth/client/scripts/views/components/Profile/ProfileActivity/ProfileActivity.tsx @@ -2,11 +2,13 @@ import React, { useState } from 'react'; import './ProfileActivity.scss'; +import { useFlag } from 'client/scripts/hooks/useFlag'; import { mapProfileThread } from 'client/scripts/utils/mapProfileThread'; import clsx from 'clsx'; import type Comment from 'models/Comment'; import type Thread from 'models/Thread'; import type { IUniqueId } from 'models/interfaces'; +import useUserStore from 'state/ui/user'; import { CWTab, CWTabsRow } from '../../component_kit/new_designs/CWTabs'; import ProfileActivityContent, { ProfileActivityType, @@ -22,9 +24,12 @@ type ProfileActivityProps = { }; const ProfileActivity = ({ comments, threads }: ProfileActivityProps) => { + const newProfilePageEnabled = useFlag('newProfilePage'); + const [selectedActivity, setSelectedActivity] = useState( ProfileActivityType.Comments, ); + const user = useUserStore(); return (
@@ -56,6 +61,20 @@ const ProfileActivity = ({ comments, threads }: ProfileActivityProps) => { }} isSelected={selectedActivity === ProfileActivityType.MyTokens} /> + {newProfilePageEnabled && ( + + Communities +
{user.communities.length}
+
+ } + onClick={() => { + setSelectedActivity(ProfileActivityType.Communities); + }} + isSelected={selectedActivity === ProfileActivityType.Communities} + /> + )}
{ selectedActivity === ProfileActivityType.Threads ? 'removePadding' : '', + selectedActivity === ProfileActivityType.Communities + ? 'communityPadding' + : '', )} > ; } + if (option === ProfileActivityType.Communities) { + return ; + } + const allActivities: Array = [ ...comments, ...threads, diff --git a/packages/commonwealth/client/vite.config.ts b/packages/commonwealth/client/vite.config.ts index bd5a512d47b..93de64701e0 100644 --- a/packages/commonwealth/client/vite.config.ts +++ b/packages/commonwealth/client/vite.config.ts @@ -63,6 +63,9 @@ export default defineConfig(({ mode }) => { 'process.env.FLAG_PARTNERSHIP_WALLET': JSON.stringify( env.FLAG_PARTNERSHIP_WALLET, ), + 'process.env.FLAG_NEW_PROFILE_PAGE': JSON.stringify( + env.FLAG_NEW_PROFILE_PAGE, + ), }; const config = {