'use client'; import React, { useState } from 'react'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { Button } from '@/components/ui/button'; import { Loader } from '@/app/components/ui/loader'; export interface AccountFormField { name: string; label: string; type?: 'text' | 'email' | 'password'; autoComplete?: string; required?: boolean; } interface AccountFormProps { title: string; description?: string; fields: AccountFormField[]; submitLabel: string; endpoint: string; /** Merged into the request body alongside the field values. */ extraPayload?: Record; /** Where to go on success; omit to show `successMessage` instead. */ redirectTo?: string; successMessage?: string; footer?: React.ReactNode; } const AccountForm: React.FC = ({ title, description, fields, submitLabel, endpoint, extraPayload, redirectTo, successMessage, footer, }) => { const router = useRouter(); const [values, setValues] = useState>({}); const [error, setError] = useState(null); const [done, setDone] = useState(false); const [submitting, setSubmitting] = useState(false); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); if (submitting) return; try { setSubmitting(true); setError(null); const response = await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...values, ...extraPayload }), }); const data = await response.json(); if (!response.ok) { setError(data.error ?? 'Something went wrong. Please try again.'); return; } if (redirectTo) { // refresh() so server components re-read the new session cookie. router.push(redirectTo); router.refresh(); } else { setDone(true); } } catch { setError('Could not reach the server. Please try again.'); } finally { setSubmitting(false); } }; return (

{title}

{description && (

{description}

)} {done && successMessage ? (

{successMessage}

) : (
{fields.map((field) => ( ))} {error &&

{error}

}
)} {footer && (
{footer}
)}
); }; export const AccountFormLink: React.FC<{ href: string; children: React.ReactNode }> = ({ href, children, }) => ( {children} ); export default AccountForm;