diff --git a/app/(app)/forms/forms-client.tsx b/app/(app)/forms/forms-client.tsx index edb8e0c..c507754 100644 --- a/app/(app)/forms/forms-client.tsx +++ b/app/(app)/forms/forms-client.tsx @@ -6,6 +6,7 @@ import { PageHeader, PageTitle } from '@/components/ui/page-title' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription } from '@/components/ui/empty' +import { CopyLinkButton } from '@/components/forms/copy-link-button' type FormRow = { id: string @@ -76,6 +77,9 @@ export function FormsClient({ forms, spaceSlug }: { forms: FormRow[]; spaceSlug: {f.status}
+ {f.visibility !== 'members' && f.status === 'published' && ( + + )} diff --git a/app/(app)/my-forms/page.tsx b/app/(app)/my-forms/page.tsx index 2481a64..8d5b775 100644 --- a/app/(app)/my-forms/page.tsx +++ b/app/(app)/my-forms/page.tsx @@ -5,6 +5,7 @@ import { PageHeader, PageTitle } from '@/components/ui/page-title' import { Badge } from '@/components/ui/badge' import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription } from '@/components/ui/empty' import { ClipboardList } from 'lucide-react' +import { CopyLinkButton } from '@/components/forms/copy-link-button' export const dynamic = 'force-dynamic' @@ -20,15 +21,17 @@ export default async function MyFormsPage() { const { data: member } = await supabase .from('space_members') - .select('space_id') + .select('space_id, spaces(slug)') .eq('user_id', user.id) .in('status', ['current', 'unverified', 'late']) .single() if (!member) redirect('/login') + const spaceSlug = (member.spaces as { slug?: string } | null)?.slug ?? '' + const { data: forms } = await supabase .from('forms') - .select('id, title, description, kind, status') + .select('id, title, description, kind, status, slug, visibility') .eq('space_id', member.space_id) .eq('status', 'published') .order('created_at', { ascending: false }) @@ -55,24 +58,36 @@ export default async function MyFormsPage() { ) : (
- {list.map(f => ( - -
-
- {f.title} - {f.kind === 'waiver' && Waiver} + {list.map(f => { + const isPublic = f.visibility !== 'members' + return ( +
+
+
+ + {f.title} + + {f.kind === 'waiver' && Waiver} +
+ {f.description && ( +

{f.description}

+ )} + {isPublic && ( +

+ /f/{spaceSlug}/{f.slug} +

+ )}
- {f.description && ( -

{f.description}

- )} + {isPublic && } + + Open → +
- Open → - - ))} + ) + })}
)}
diff --git a/components/forms/copy-link-button.tsx b/components/forms/copy-link-button.tsx new file mode 100644 index 0000000..0783b39 --- /dev/null +++ b/components/forms/copy-link-button.tsx @@ -0,0 +1,33 @@ +'use client' + +import { useState } from 'react' +import { Check, Copy } from 'lucide-react' +import { toast } from 'sonner' +import { Button } from '@/components/ui/button' + +// One reusable copy-to-clipboard control for a form's public link. Shared by +// the admin forms list and the member forms list so the behaviour and styling +// never drift. +export function CopyLinkButton({ path, label = 'Copy link' }: { path: string; label?: string }) { + const [copied, setCopied] = useState(false) + + async function copy() { + const url = + typeof window !== 'undefined' ? `${window.location.origin}${path}` : path + try { + await navigator.clipboard?.writeText(url) + setCopied(true) + toast.success('Public link copied') + setTimeout(() => setCopied(false), 2000) + } catch { + toast.error('Could not copy — copy it manually') + } + } + + return ( + + ) +}