From aea66d11e2fe1bdc570195a4c0f0f5d184936b7e Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Thu, 3 Sep 2026 21:18:02 +0700 Subject: [PATCH] Fix 78 pre-existing TypeScript errors surfaced by npm test - useDirectMessages: correct nip44 getConversationKey (Uint8Array) + finalizeEvent EventTemplate (remove pubkey/unused ephemeralPubkey/bytesToHex) - Access current-user metadata via useCurrentUser() spread instead of user.metadata across ~10 files (rename to userMetadata where author metadata already bound) - useCrewGoal: explicit UseQueryResult return type (fixes CrewForm/CrewTreasuryCard {} inference) - New useCommentCounts hook; fix EventsPage/MapPage misuse of useComments(string[]) - CoachDetailPage: typed pget/pbool accessors for craft-specific union fields - MapPage: shop entries include tags/category to satisfy SkateSpot - SkateGlobe: read event.tags; LabPage: remove duplicate serviceType; LabCrewsStrip: add 'judging' - Icon prop widened to accept style; ReportDialog subtype guard; SecuritySettings/TourCard/EventsPage comparisons; CashuWallet onClick; ConversationPage recipients; useLoggedInAccounts NLoginType import; LicensePage icon; TourDetailPage ZapButton target + real npub link; TestApp useSkateRelay Co-authored-by: shakespeare.diy --- src/components/CraftProfileForm.tsx | 4 +-- src/components/LabCrewsStrip.tsx | 2 +- src/components/ReportDialog.tsx | 4 +-- src/components/SecuritySettings.tsx | 2 +- src/components/SkateGlobe.tsx | 14 ++++---- src/components/TourCard.tsx | 2 +- src/components/wallet/CashuWallet.tsx | 2 +- src/hooks/useCommentCounts.ts | 45 ++++++++++++++++++++++++ src/hooks/useCrewGoal.ts | 4 +-- src/hooks/useDirectMessages.ts | 16 +++++---- src/hooks/useListingRestrictions.ts | 4 +-- src/hooks/useLoggedInAccounts.ts | 2 +- src/pages/BecomeBuilderPage.tsx | 4 +-- src/pages/BecomeCoachPage.tsx | 4 +-- src/pages/BecomeFilmerPage.tsx | 4 +-- src/pages/BecomePhotographerPage.tsx | 4 +-- src/pages/CoachDetailPage.tsx | 50 +++++++++++++++++---------- src/pages/CommunityStatsPage.tsx | 2 +- src/pages/ConversationPage.tsx | 2 +- src/pages/CreateEventPage.tsx | 4 +-- src/pages/CreateListingPage.tsx | 6 ++-- src/pages/EventsPage.tsx | 9 +++-- src/pages/LabPage.tsx | 1 - src/pages/LicensePage.tsx | 2 +- src/pages/MapPage.tsx | 12 +++---- src/pages/PrivacyPage.tsx | 2 +- src/pages/ShopDetailPage.tsx | 4 +-- src/pages/SpotDetailPage.tsx | 4 +-- src/pages/SupportersPage.tsx | 2 +- src/pages/TourDetailPage.tsx | 5 +-- src/test/TestApp.tsx | 1 + 31 files changed, 142 insertions(+), 81 deletions(-) create mode 100644 src/hooks/useCommentCounts.ts diff --git a/src/components/CraftProfileForm.tsx b/src/components/CraftProfileForm.tsx index ceb4ea5..17d2fd2 100644 --- a/src/components/CraftProfileForm.tsx +++ b/src/components/CraftProfileForm.tsx @@ -89,7 +89,7 @@ export function CraftProfileForm({ config }: { config: CraftFormConfig }) { } = config; const navigate = useNavigate(); - const { user } = useCurrentUser(); + const { user, metadata } = useCurrentUser(); const author = useAuthor(user?.pubkey || ''); const { mutateAsync: createEvent, isPending } = useNostrPublish(); const { mutateAsync: uploadFile, isPending: isUploading } = useUploadFile(); @@ -252,7 +252,7 @@ export function CraftProfileForm({ config }: { config: CraftFormConfig }) { ); } - const hasNip05 = user?.metadata?.nip05; + const hasNip05 = metadata?.nip05; const entityCoord = `${kind}:${user.pubkey}:${identifier}`; return ( diff --git a/src/components/LabCrewsStrip.tsx b/src/components/LabCrewsStrip.tsx index ac339a7..d342b64 100644 --- a/src/components/LabCrewsStrip.tsx +++ b/src/components/LabCrewsStrip.tsx @@ -8,7 +8,7 @@ import { Skeleton } from '@/components/ui/skeleton'; /** The Lab page's own ServiceType union (kept in sync with LabPage). */ type ServiceType = | 'coaching' | 'filming' | 'editing' | 'photography' | 'building' - | 'art' | 'graffiti' | 'tattoo' | 'training' | 'music'; + | 'art' | 'graffiti' | 'tattoo' | 'training' | 'music' | 'judging'; /** Translate the Lab page's ServiceType into a crew focus scene. */ function focusForLabService(serviceType: ServiceType): Exclude { diff --git a/src/components/ReportDialog.tsx b/src/components/ReportDialog.tsx index b7c71e1..07b379a 100644 --- a/src/components/ReportDialog.tsx +++ b/src/components/ReportDialog.tsx @@ -97,7 +97,7 @@ export function ReportDialog({ if (!user || !selectedReason) return; const reason = REPORT_REASONS.find( - (r) => r.id === selectedReason || r.subtype === selectedReason + (r) => r.id === selectedReason || ('subtype' in r && r.subtype === selectedReason) ); if (!reason) return; @@ -159,7 +159,7 @@ export function ReportDialog({ }; const getReasonKey = (reason: typeof REPORT_REASONS[number]) => { - return reason.subtype || reason.id; + return ('subtype' in reason ? reason.subtype : undefined) || reason.id; }; if (!user) { diff --git a/src/components/SecuritySettings.tsx b/src/components/SecuritySettings.tsx index 119a856..47eb549 100644 --- a/src/components/SecuritySettings.tsx +++ b/src/components/SecuritySettings.tsx @@ -188,7 +188,7 @@ export function SecuritySettings() { {loginType === 'bunker' && ( <>You're logged in with a remote signer (bunker). Your recovery code is held by your signer service, not SkateSpots. Back it up there. )} - {loginType === 'extension' && ( + {(loginType as string) === 'extension' && ( <>You're logged in with a browser extension. Your recovery code lives in the extension — use its own backup/export option. SkateSpots never sees your key. )} {!loginType && ( diff --git a/src/components/SkateGlobe.tsx b/src/components/SkateGlobe.tsx index 88e5006..78f8b1a 100644 --- a/src/components/SkateGlobe.tsx +++ b/src/components/SkateGlobe.tsx @@ -130,13 +130,14 @@ export function SkateGlobe({ if (showSpots && spots) { for (const s of spots) { - if (!s?.tags || !Array.isArray(s.tags)) continue; - const c = getCoords(s.tags); + const evTags = s?.event?.tags; + if (!evTags || !Array.isArray(evTags)) continue; + const c = getCoords(evTags); if (!c) continue; out.push({ id: `spot-${s.id}`, lat: c.lat, lng: c.lng, - label: getName(s.tags, 'Unnamed Spot'), + label: s.title || getName(evTags, 'Unnamed Spot'), type: 'spot', spot: s, }); } @@ -144,13 +145,14 @@ export function SkateGlobe({ if (showShops && shops) { for (const sh of shops) { - if (!sh?.tags || !Array.isArray(sh.tags)) continue; - const c = getCoords(sh.tags); + const evTags = sh?.event?.tags; + if (!evTags || !Array.isArray(evTags)) continue; + const c = getCoords(evTags); if (!c) continue; out.push({ id: `shop-${sh.id}`, lat: c.lat, lng: c.lng, - label: getName(sh.tags, 'Skate Shop'), + label: sh.name || getName(evTags, 'Skate Shop'), type: 'shop', shop: sh, }); } diff --git a/src/components/TourCard.tsx b/src/components/TourCard.tsx index 6340379..693d1da 100644 --- a/src/components/TourCard.tsx +++ b/src/components/TourCard.tsx @@ -229,7 +229,7 @@ export function TourCard({ tour, compact = false }: TourCardProps) { className="backdrop-blur-sm shadow-lg font-bold text-xs uppercase" style={{ backgroundColor: `${categoryInfo.color}dd`, - color: categoryInfo.color === '#ccff00' ? 'black' : 'white' + color: (categoryInfo.color as string) === '#ccff00' ? 'black' : 'white' }} > {categoryInfo.emoji} {categoryInfo.label} diff --git a/src/components/wallet/CashuWallet.tsx b/src/components/wallet/CashuWallet.tsx index 66d70b6..d39b758 100644 --- a/src/components/wallet/CashuWallet.tsx +++ b/src/components/wallet/CashuWallet.tsx @@ -513,7 +513,7 @@ export function CashuWallet() { className="bg-gray-800 border-gray-700 font-mono text-xs" /> diff --git a/src/test/TestApp.tsx b/src/test/TestApp.tsx index 23f7bae..b8b994b 100644 --- a/src/test/TestApp.tsx +++ b/src/test/TestApp.tsx @@ -23,6 +23,7 @@ export function TestApp({ children }: TestAppProps) { const defaultConfig: AppConfig = { theme: 'dark', + useSkateRelay: true, relayMetadata: { relays: [ { url: 'wss://auth.nostr1.com', read: true, write: true },