diff --git a/src/app/personal/components/contactCard.tsx b/src/app/personal/components/contactCard.tsx new file mode 100644 index 00000000..8d80dd8e --- /dev/null +++ b/src/app/personal/components/contactCard.tsx @@ -0,0 +1,40 @@ +import { useQuery } from '@tanstack/react-query'; + +import { useNDK } from '@libs/ndk/provider'; +import { useStorage } from '@libs/storage/provider'; + +import { LoaderIcon } from '@shared/icons'; + +import { compactNumber } from '@utils/number'; + +export function ContactCard() { + const { db } = useStorage(); + const { ndk } = useNDK(); + const { status, data } = useQuery({ + queryKey: ['contacts'], + queryFn: async () => { + const user = ndk.getUser({ hexpubkey: db.account.pubkey }); + return await user.follows(); + }, + refetchOnWindowFocus: false, + }); + + return ( +
+ {status === 'pending' ? ( +
+ +
+ ) : ( +
+

+ {compactNumber.format(data.size)} +

+
+ Contacts +
+
+ )} +
+ ); +} diff --git a/src/app/personal/components/postCard.tsx b/src/app/personal/components/postCard.tsx new file mode 100644 index 00000000..1a9fb05a --- /dev/null +++ b/src/app/personal/components/postCard.tsx @@ -0,0 +1,51 @@ +import { useQuery } from '@tanstack/react-query'; + +import { useStorage } from '@libs/storage/provider'; + +import { LoaderIcon } from '@shared/icons'; + +import { compactNumber } from '@utils/number'; + +export function PostCard() { + const { db } = useStorage(); + const { status, data } = useQuery({ + queryKey: ['user-stats', db.account.pubkey], + queryFn: async ({ signal }: { signal: AbortSignal }) => { + const res = await fetch( + `https://api.nostr.band/v0/stats/profile/${db.account.pubkey}`, + { + signal, + } + ); + + if (!res.ok) { + throw new Error('Error'); + } + + return await res.json(); + }, + refetchOnWindowFocus: false, + refetchOnMount: false, + refetchOnReconnect: false, + staleTime: Infinity, + }); + + return ( +
+ {status === 'pending' ? ( +
+ +
+ ) : ( +
+

+ {compactNumber.format(data.stats[db.account.pubkey].pub_note_count)} +

+
+ Posts +
+
+ )} +
+ ); +} diff --git a/src/app/personal/components/profileCard.tsx b/src/app/personal/components/profileCard.tsx new file mode 100644 index 00000000..16ada6b1 --- /dev/null +++ b/src/app/personal/components/profileCard.tsx @@ -0,0 +1,58 @@ +import * as Avatar from '@radix-ui/react-avatar'; +import { minidenticon } from 'minidenticons'; + +import { useStorage } from '@libs/storage/provider'; + +import { LoaderIcon } from '@shared/icons'; + +import { useProfile } from '@utils/hooks/useProfile'; +import { displayNpub } from '@utils/shortenKey'; + +export function ProfileCard() { + const { db } = useStorage(); + const { status, user } = useProfile(db.account.pubkey); + + const svgURI = + 'data:image/svg+xml;utf8,' + + encodeURIComponent(minidenticon(db.account.pubkey, 90, 50)); + + return ( +
+ {status === 'pending' ? ( +
+ +
+ ) : ( +
+
+ + + + {db.account.pubkey} + + +
+

+ {user?.display_name || user?.name} +

+

+ {user.nip05 || displayNpub(db.account.pubkey, 16)} +

+
+
+
+ )} +
+ ); +} diff --git a/src/app/personal/components/relayCard.tsx b/src/app/personal/components/relayCard.tsx new file mode 100644 index 00000000..1bcb7570 --- /dev/null +++ b/src/app/personal/components/relayCard.tsx @@ -0,0 +1,40 @@ +import { useQuery } from '@tanstack/react-query'; + +import { useNDK } from '@libs/ndk/provider'; +import { useStorage } from '@libs/storage/provider'; + +import { LoaderIcon } from '@shared/icons'; + +import { compactNumber } from '@utils/number'; + +export function RelayCard() { + const { db } = useStorage(); + const { ndk } = useNDK(); + const { status, data } = useQuery({ + queryKey: ['relays'], + queryFn: async () => { + const user = ndk.getUser({ hexpubkey: db.account.pubkey }); + return await user.relayList(); + }, + refetchOnWindowFocus: false, + }); + + return ( +
+ {status === 'pending' ? ( +
+ +
+ ) : ( +
+

+ {compactNumber.format(data.relays.length)} +

+
+ Relays +
+
+ )} +
+ ); +} diff --git a/src/app/personal/components/zapCard.tsx b/src/app/personal/components/zapCard.tsx new file mode 100644 index 00000000..7741553f --- /dev/null +++ b/src/app/personal/components/zapCard.tsx @@ -0,0 +1,53 @@ +import { useQuery } from '@tanstack/react-query'; + +import { useStorage } from '@libs/storage/provider'; + +import { LoaderIcon } from '@shared/icons'; + +import { compactNumber } from '@utils/number'; + +export function ZapCard() { + const { db } = useStorage(); + const { status, data } = useQuery({ + queryKey: ['user-stats', db.account.pubkey], + queryFn: async ({ signal }: { signal: AbortSignal }) => { + const res = await fetch( + `https://api.nostr.band/v0/stats/profile/${db.account.pubkey}`, + { + signal, + } + ); + + if (!res.ok) { + throw new Error('Error'); + } + + return await res.json(); + }, + refetchOnWindowFocus: false, + refetchOnMount: false, + refetchOnReconnect: false, + staleTime: Infinity, + }); + + return ( +
+ {status === 'pending' ? ( +
+ +
+ ) : ( +
+

+ {compactNumber.format( + data.stats[db.account.pubkey].zaps_received.msats / 1000 + )} +

+
+ Sats received +
+
+ )} +
+ ); +} diff --git a/src/app/personal/index.tsx b/src/app/personal/index.tsx index c6dc0404..268f0aeb 100644 --- a/src/app/personal/index.tsx +++ b/src/app/personal/index.tsx @@ -1,9 +1,19 @@ -import { useStorage } from '@libs/storage/provider'; - -import { UserProfile } from '@shared/userProfile'; +import { ContactCard } from '@app/personal/components/contactCard'; +import { PostCard } from '@app/personal/components/postCard'; +import { ProfileCard } from '@app/personal/components/profileCard'; +import { RelayCard } from '@app/personal/components/relayCard'; +import { ZapCard } from '@app/personal/components/zapCard'; export function PersonalScreen() { - const { db } = useStorage(); - - return
; + return ( +
+ +
+ + + + +
+
+ ); } diff --git a/src/main.jsx b/src/main.jsx index 88fe7483..039b2bd9 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -25,7 +25,17 @@ const container = document.getElementById('root'); const root = createRoot(container); root.render( - + { + if (query.queryKey !== 'widgets') return true; + }, + }, + }} + >