A
Anonymous

D O C Dialog - Copy this React, Tailwind Component to your project

"use client"; import { generate_doc } from "@/api/ai"; import { get_docs } from "@/api/user"; import { DBFile } from "@/models/model"; import { useEffect, useState } from "react"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "./ui/dialog"; import { SidebarMenuButton } from "./ui/sidebar"; import { FileIcon, Loader2Icon } from "lucide react"; import { Input } from "./ui/input"; import { Button } from "./ui/button"; import Link from "next/link"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandShortcut, } from "@/components/ui/command"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "./ui/select"; import { format } from "date fns"; import { RecordingButton } from "./RecordingButton"; import { useDOCDialogStore } from "@/store/doc_dialog"; import { Checkbox } from "./ui/checkbox"; import { Label } from "./ui/label"; type PromptStyle = | "lawyer" | "bank" | "academic" | "corporate" | "marketing" | "research" | "other"; const predefinedPrompts: Record<Exclude<PromptStyle, "other">, string> = { lawyer: ` You are a professional legal writer. Create a formal legal document that includes: Clear section headings and subheadings in bold (e.g., "Agreement Terms," "Responsibilities"). Key legal terms and clauses highlighted for emphasis. Bullet points or numbered lists where necessary. Justified text alignment and a professional tone suitable for a legal agreement or notice. Do NOT include content structured like an email (e.g., greetings, email body, or signatures). Input: `, bank: ` You are a professional business writer specializing in formal banking documents. Generate a document that includes: Polished language suitable for official communications. Headings/subheadings in bold for clear structure. Key financial details emphasized for clarity. Justified alignment for a clean, professional look. Input: `, academic: ` You are an academic writer. Generate a formal document like a recommendation letter or a student profile summary. Ensure: Bold achievements or impactful statements. Italics for supplementary info. Headings/subheadings for structured sections. A concise yet formal tone. Input: `, corporate: ` You are a professional corporate writer. Draft a formal document, such as an employment offer letter or HR policy. Include: Bold headings and critical terms (roles, salary, deadlines). Bullet points or numbered lists to summarize information effectively. A polite, professional tone suitable for corporate communication. Input: `, marketing: ` You are a professional marketing writer. Generate a persuasive, professional document, such as a business proposal or sales pitch. Include: Bold headings for each section. Key selling points in bold, supplementary info in italics. A clear structure with justified alignment and a professional tone. Input: `, research: ` You are a professional research and analysis writer. Generate a detailed document that: Includes sections like Abstract, Introduction, Methodology, Results, Analysis, and Conclusion. Uses bold for section headings and key findings. Italicizes supplementary details or references to additional research. Maintains a formal tone suitable for academic or professional reports, with consistent formatting (justified text, 1 inch margins, Times New Roman). Input: `, }; type GeneratedParentDoc = { parent_doc_uuid: string; }; export default function DOCDialog() { const { prompt, setPrompt, showGenerate, setShowGenerate, showDOCDialog, setShowDOCDialog, } = useDOCDialogStore(); const [selectedStyle, setSelectedStyle] = useState<PromptStyle>("lawyer"); const [customStyle, setCustomStyle] = useState(""); // Additional state for "other" style const [docs, setDocs] = useState<DBFile[]>([]); const [disabled, setDisabled] = useState(false); const [internetSearch, setInternetSearch] = useState(false); const comp_get_docs = async () => { const { docs } = await get_docs(); setDocs(docs); }; useEffect(() => { comp_get_docs(); }, []); const comp_generate_doc = async (): Promise<string> => { setDisabled(true); let finalPrompt = ""; if (selectedStyle === "other") { finalPrompt = ` You are a professional writer using a custom style: "${customStyle}". Generate a document with the following specifications: Justified text alignment. 1 inch margins. Bold headings and italicized supplementary details. Maintain a professional tone. Input: ${prompt} `; } else { const basePrompt = predefinedPrompts[selectedStyle]; finalPrompt = `${basePrompt} ${prompt}`; } const { doc } = (await generate_doc({ prompt: finalPrompt, topic: prompt, internet_search: internetSearch, })) as { doc: GeneratedParentDoc }; const docUrl = `/emails/viewer/drf/${doc.parent_doc_uuid}`; setDisabled(false); return docUrl; }; return ( <Dialog open={showDOCDialog} onOpenChange={setShowDOCDialog}> <DialogTrigger asChild> <SidebarMenuButton> <FileIcon /> <p>DOC</p> </SidebarMenuButton> </DialogTrigger> <DialogContent> <DialogHeader> <DialogTitle>Generate DOC</DialogTitle> <DialogDescription> Select a style and enter your prompt to generate a document </DialogDescription> </DialogHeader> {showGenerate ? ( <> <form className="flex flex col gap 4"> <div> <label htmlFor="style" className="block text sm font medium"> Select Document Style </label> <Select onValueChange={(value) => { setSelectedStyle(value as PromptStyle); setCustomStyle(""); }} > <SelectTrigger id="style"> <SelectValue placeholder="Select a style" /> </SelectTrigger> <SelectContent> <SelectItem value="lawyer">Lawyer</SelectItem> <SelectItem value="bank">Bank</SelectItem> <SelectItem value="academic">Academic</SelectItem> <SelectItem value="corporate">Corporate</SelectItem> <SelectItem value="marketing">Marketing</SelectItem> <SelectItem value="research">Research</SelectItem> <SelectItem value="other">Other</SelectItem> </SelectContent> </Select> </div> {selectedStyle === "other" && ( <div> <label htmlFor="customStyle" className="block text sm font medium" > Custom Style Name/Description </label> <Input id="customStyle" placeholder="e.g., 'Personal letter style'" type="text" value={customStyle} onChange={(e) => setCustomStyle(e.currentTarget.value)} /> </div> )} <Input placeholder="Enter prompt" type="text" required onChange={(v) => setPrompt(v.currentTarget.value)} value={prompt} /> <div className="flex items center pl 1 space x 2"> <Checkbox checked={internetSearch} onCheckedChange={(v) => setInternetSearch(v.valueOf() as boolean) } id="internet" /> <Label htmlFor="internet">Internet search</Label> </div> <div className="flex justify between items center"> <Button type="button" variant="outline" onClick={() => { setShowGenerate(false); setPrompt(""); setCustomStyle(""); setSelectedStyle("lawyer"); }} > Cancel </Button> <div className="flex gap 2"> <RecordingButton setUserMessage={setPrompt} /> <Button type="submit" disabled={disabled} onClick={async () => { const url = await comp_generate_doc(); const ele = document.createElement("a"); ele.setAttribute("href", url); document.documentElement.appendChild(ele); ele.click(); }} > Submit {disabled && <Loader2Icon className="ml 2 animate spin" />} </Button> </div> </div> </form> </> ) : ( <div className="flex flex col gap 4"> <Button onClick={() => setShowGenerate(true)}>Generate</Button> <Command> <CommandInput placeholder="Search doc..." /> <CommandList> <CommandEmpty>No results found.</CommandEmpty> <CommandGroup heading="History"> {docs.map((ppt, k) => ( <Link href={`/emails/viewer/drf/${ppt.uuid}`} key={k} target="_blank" > <CommandItem value={ppt.file_name + " " + ppt.uuid} className="hover:cursor pointer" > <div className="flex items center w full"> <div className="flex gap 2 items center"> <FileIcon /> <span>{ppt.file_name}</span> </div> <CommandShortcut> {format(ppt.created_at, "dd MM")} </CommandShortcut> </div> </CommandItem> </Link> ))} </CommandGroup> </CommandList> </Command> </div> )} </DialogContent> </Dialog> ); } add hover effects and other UI improvements and give the full code bback

Prompt
Component Preview

About

DOCDialog - Generate documents with style selection, custom prompts, and internet search options, professionally built with React and Tailwind. Access free code!

Share

Last updated 1 month ago