"use client"; import { useEffect, useState } from "react"; import { useSession } from "next-auth/react"; import { notFound } from "next/navigation"; import { FileText, Loader2, Plus, Download, Edit2, Eye, Save } from "lucide-react"; import { EntityView, EntityViewHeader, EntityViewSection, EmptyState, } from "~/components/ui/entity-view"; import { useBreadcrumbsEffect } from "~/components/ui/breadcrumb-provider"; import { Button } from "~/components/ui/button"; import { Badge } from "~/components/ui/badge"; import { api } from "~/trpc/react"; import { toast } from "sonner"; import { PageHeader } from "~/components/ui/page-header"; import { useEditor, EditorContent } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; import { Markdown } from 'tiptap-markdown'; import { Table } from '@tiptap/extension-table'; import { TableRow } from '@tiptap/extension-table-row'; import { TableCell } from '@tiptap/extension-table-cell'; import { TableHeader } from '@tiptap/extension-table-header'; import { Bold, Italic, List, ListOrdered, Heading1, Heading2, Quote, Table as TableIcon } from "lucide-react"; import { downloadPdfFromHtml } from "~/lib/pdf-generator"; const Toolbar = ({ editor }: { editor: any }) => { if (!editor) { return null; } return (
); }; interface StudyFormsPageProps { params: Promise<{ id: string; }>; } export default function StudyFormsPage({ params }: StudyFormsPageProps) { const { data: session } = useSession(); const utils = api.useUtils(); const [resolvedParams, setResolvedParams] = useState<{ id: string } | null>(null); const [editorTarget, setEditorTarget] = useState(""); useEffect(() => { const resolveParams = async () => { const resolved = await params; setResolvedParams(resolved); }; void resolveParams(); }, [params]); const { data: study } = api.studies.get.useQuery( { id: resolvedParams?.id ?? "" }, { enabled: !!resolvedParams?.id }, ); const { data: activeConsentForm, refetch: refetchConsentForm } = api.studies.getActiveConsentForm.useQuery( { studyId: resolvedParams?.id ?? "" }, { enabled: !!resolvedParams?.id }, ); // Only sync once when form loads to avoid resetting user edits useEffect(() => { if (activeConsentForm && !editorTarget) { setEditorTarget(activeConsentForm.content); } }, [activeConsentForm, editorTarget]); const editor = useEditor({ extensions: [ StarterKit, Table.configure({ resizable: true, }), TableRow, TableHeader, TableCell, Markdown.configure({ transformPastedText: true, }), ], content: editorTarget || '', immediatelyRender: false, onUpdate: ({ editor }) => { // @ts-ignore setEditorTarget(editor.storage.markdown.getMarkdown()); }, }); // Sync Tiptap when editorTarget is set (e.g., from DB) but make sure not to overwrite active edits useEffect(() => { if (editor && editorTarget && editor.isEmpty) { editor.commands.setContent(editorTarget); } }, [editorTarget, editor]); const generateConsentMutation = api.studies.generateConsentForm.useMutation({ onSuccess: (data) => { toast.success("Default Consent Form Generated!"); setEditorTarget(data.content); editor?.commands.setContent(data.content); void refetchConsentForm(); void utils.studies.getActivity.invalidate({ studyId: resolvedParams?.id ?? "" }); }, onError: (error) => { toast.error("Error generating consent form", { description: error.message }); }, }); const updateConsentMutation = api.studies.updateConsentForm.useMutation({ onSuccess: () => { toast.success("Consent Form Saved Successfully!"); void refetchConsentForm(); void utils.studies.getActivity.invalidate({ studyId: resolvedParams?.id ?? "" }); }, onError: (error) => { toast.error("Error saving consent form", { description: error.message }); }, }); const handleDownloadConsent = async () => { if (!activeConsentForm || !study || !editor) return; try { toast.loading("Generating Document...", { id: "pdf-gen" }); await downloadPdfFromHtml(editor.getHTML(), { filename: `Consent_Form_${study.name.replace(/\s+/g, "_")}_v${activeConsentForm.version}.pdf` }); toast.success("Document Downloaded Successfully!", { id: "pdf-gen" }); } catch (error) { toast.error("Error generating PDF", { id: "pdf-gen" }); console.error(error); } }; useBreadcrumbsEffect([ { label: "Dashboard", href: "/dashboard" }, { label: "Studies", href: "/studies" }, { label: study?.name ?? "Study", href: `/studies/${resolvedParams?.id}` }, { label: "Forms" }, ]); if (!session?.user) { return notFound(); } if (!study) return
Loading...
; return (
{activeConsentForm && ( )}
} > {activeConsentForm ? (

{activeConsentForm.title}

v{activeConsentForm.version} • Status: Active

Active
) : ( )}
); }