diff --git a/package.json b/package.json index d5fe35c..e98ed89 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "skate-spots", "private": true, - "version": "1.2.27", + "version": "1.2.28", "type": "module", "homepage": "https://skate-spots.com", "scripts": { diff --git a/src/components/ExistingLabProfileNotice.tsx b/src/components/ExistingLabProfileNotice.tsx new file mode 100644 index 0000000..331ebac --- /dev/null +++ b/src/components/ExistingLabProfileNotice.tsx @@ -0,0 +1,60 @@ +import { Link } from 'react-router-dom'; +import { AlertTriangle, Eye } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { useCurrentUser } from '@/hooks/useCurrentUser'; +import { useLabProfile } from '@/hooks/useLabProfiles'; + +/** + * Lab provider profiles (coach, filmer, editor, photographer, builder…) are + * addressable events keyed by a fixed `d` identifier per type + * (e.g. "coach-profile"). That means re-publishing REPLACES the existing one. + * + * The "Become a …" forms start blank and don't reconstruct prior state, so a + * returning provider who submits again would silently wipe every field they'd + * set before (bio, rate, spots, contact…). This notice makes that consequence + * explicit: it appears only when the current user already has a profile of this + * type, warns that submitting will overwrite it, and links them to view it. + */ +export function ExistingLabProfileNotice({ + identifier, + label, +}: { + /** The fixed `d` identifier for this Lab profile type, e.g. "coach-profile". */ + identifier: string; + /** Human label for the profile type, e.g. "coach". */ + label: string; +}) { + const { user } = useCurrentUser(); + const { data: existing } = useLabProfile(identifier, user?.pubkey); + + if (!user || !existing) return null; + + return ( +
+
+ +
+

+ You already have a {label} profile +

+

+ Publishing this form replaces your + current {label} profile — anything you don't re-enter here will be lost. Review your + existing profile first so you don't drop details you already set. +

+ +
+
+
+ ); +} diff --git a/src/pages/BecomeBuilderPage.tsx b/src/pages/BecomeBuilderPage.tsx index efd3267..2a0b449 100644 --- a/src/pages/BecomeBuilderPage.tsx +++ b/src/pages/BecomeBuilderPage.tsx @@ -22,6 +22,7 @@ import { SpotPicker } from '@/components/SpotPicker'; import { NofferField } from '@/components/NofferField'; import { PaymentReadinessNote } from '@/components/PaymentReadinessNote'; import { EntityTypeField } from '@/components/EntityTypeField'; +import { ExistingLabProfileNotice } from '@/components/ExistingLabProfileNotice'; import { CrewLinkField } from '@/components/CrewLinkField'; import { SKATE_BUILDER_KIND, @@ -354,6 +355,8 @@ export default function BecomeBuilderPage() { Tell the scene what you build and how you work + +
diff --git a/src/pages/BecomeCoachPage.tsx b/src/pages/BecomeCoachPage.tsx index a0effef..126b505 100644 --- a/src/pages/BecomeCoachPage.tsx +++ b/src/pages/BecomeCoachPage.tsx @@ -22,6 +22,7 @@ import { NofferField } from '@/components/NofferField'; import { PaymentReadinessNote } from '@/components/PaymentReadinessNote'; import { EntityTypeField } from '@/components/EntityTypeField'; import { CrewLinkField } from '@/components/CrewLinkField'; +import { ExistingLabProfileNotice } from '@/components/ExistingLabProfileNotice'; import { SKATE_COACH_KIND, SKATE_SPOT_KIND, COACH_SKILL_LABELS, COACH_SKILL_DESCRIPTIONS, isValidNoffer, type EntityType } from '@/lib/types'; import { cn } from '@/lib/utils'; import { GraduationCap, Upload, X, Loader2, ArrowLeft, MapPin, Wallet, ExternalLink } from 'lucide-react'; @@ -313,6 +314,8 @@ export default function BecomeCoachPage() { Tell students about your experience + +
diff --git a/src/pages/BecomeEditorPage.tsx b/src/pages/BecomeEditorPage.tsx index 2bf3653..26cac98 100644 --- a/src/pages/BecomeEditorPage.tsx +++ b/src/pages/BecomeEditorPage.tsx @@ -29,6 +29,7 @@ import { type EntityType, } from '@/lib/types'; import { EntityTypeField } from '@/components/EntityTypeField'; +import { ExistingLabProfileNotice } from '@/components/ExistingLabProfileNotice'; import { CrewLinkField } from '@/components/CrewLinkField'; import { cn } from '@/lib/utils'; import { Scissors, Upload, X, Loader2, ArrowLeft, MapPin, Wallet, ExternalLink, Monitor } from 'lucide-react'; @@ -283,6 +284,8 @@ export default function BecomeEditorPage() { Tell the community about your editing style and skills + + {/* Identity */}
diff --git a/src/pages/BecomeFilmerPage.tsx b/src/pages/BecomeFilmerPage.tsx index 9e92cda..b59fa27 100644 --- a/src/pages/BecomeFilmerPage.tsx +++ b/src/pages/BecomeFilmerPage.tsx @@ -21,6 +21,7 @@ import { SpotPicker } from '@/components/SpotPicker'; import { NofferField } from '@/components/NofferField'; import { PaymentReadinessNote } from '@/components/PaymentReadinessNote'; import { EntityTypeField } from '@/components/EntityTypeField'; +import { ExistingLabProfileNotice } from '@/components/ExistingLabProfileNotice'; import { CrewLinkField } from '@/components/CrewLinkField'; import { SKATE_FILMER_KIND, SKATE_SPOT_KIND, FILMING_SERVICE_LABELS, FILMING_SERVICE_DESCRIPTIONS, FILMING_SKILL_LABELS, FILMING_SKILL_DESCRIPTIONS, isValidNoffer, type EntityType } from '@/lib/types'; import { cn } from '@/lib/utils'; @@ -329,6 +330,8 @@ export default function BecomeFilmerPage() { Tell clients about your filming expertise + +
diff --git a/src/pages/BecomePhotographerPage.tsx b/src/pages/BecomePhotographerPage.tsx index e373a75..b121728 100644 --- a/src/pages/BecomePhotographerPage.tsx +++ b/src/pages/BecomePhotographerPage.tsx @@ -21,6 +21,7 @@ import { SpotPicker } from '@/components/SpotPicker'; import { NofferField } from '@/components/NofferField'; import { PaymentReadinessNote } from '@/components/PaymentReadinessNote'; import { EntityTypeField } from '@/components/EntityTypeField'; +import { ExistingLabProfileNotice } from '@/components/ExistingLabProfileNotice'; import { CrewLinkField } from '@/components/CrewLinkField'; import type { EntityType } from '@/lib/types'; import { @@ -371,6 +372,8 @@ export default function BecomePhotographerPage() { Tell riders about your eye, your kit and your services + +