Spaces:
Running
Running
| "use client"; | |
| import { useState } from "react"; | |
| import { EmailDraftData, EmailActionOptions } from "@/types/chat"; | |
| interface Props { | |
| data: EmailDraftData; | |
| onAction: (content: string, options: EmailActionOptions) => void; | |
| } | |
| export default function EmailDraftCard({ data, onAction }: Props) { | |
| const [subject, setSubject] = useState(data.subject); | |
| const [body, setBody] = useState(data.body); | |
| const [submitted, setSubmitted] = useState<null | "send" | "cancel">(null); | |
| const disabled = submitted !== null; | |
| const handleSend = () => { | |
| if (disabled || !subject.trim() || !body.trim()) return; | |
| setSubmitted("send"); | |
| onAction("send", { | |
| emailAction: "send", | |
| emailPayload: { subject: subject.trim(), body: body.trim() }, | |
| displayContent: "✅ Approve & send the email", | |
| }); | |
| }; | |
| const handleCancel = () => { | |
| if (disabled) return; | |
| setSubmitted("cancel"); | |
| onAction("cancel", { emailAction: "cancel", displayContent: "✕ Discard the draft" }); | |
| }; | |
| return ( | |
| <div className="mt-3 rounded-xl border border-[#E2E8F0] overflow-hidden shadow-sm"> | |
| {/* Header */} | |
| <div className="bg-white px-5 py-4 border-b border-[#E2E8F0]"> | |
| <div className="flex items-center gap-2 mb-1"> | |
| <div className="w-1 h-4 rounded-full bg-brand-gradient-h" /> | |
| <h3 className="text-sm font-semibold text-[#1A202C] flex items-center gap-2"> | |
| <MailIcon /> Email draft — review before sending | |
| </h3> | |
| </div> | |
| <p className="text-xs text-[#64748B] ml-3"> | |
| You can edit the subject and body below. Nothing is sent until you click Send. | |
| </p> | |
| </div> | |
| <div className="bg-white px-5 py-4 space-y-3"> | |
| {/* To */} | |
| <div className="flex items-center gap-2 text-xs"> | |
| <span className="font-semibold text-[#475569] w-16 flex-shrink-0">To</span> | |
| <span className="text-[#1A202C] bg-[#F1F5F9] border border-[#E2E8F0] rounded px-2 py-1 flex-1 truncate"> | |
| {data.to || "—"} | |
| </span> | |
| </div> | |
| {data.reply_to && ( | |
| <div className="flex items-center gap-2 text-xs"> | |
| <span className="font-semibold text-[#475569] w-16 flex-shrink-0">Reply-To</span> | |
| <span className="text-[#64748B] bg-[#F8FAFC] border border-[#E2E8F0] rounded px-2 py-1 flex-1 truncate"> | |
| {data.reply_to} | |
| </span> | |
| </div> | |
| )} | |
| {/* Subject */} | |
| <div className="flex items-start gap-2 text-xs"> | |
| <span className="font-semibold text-[#475569] w-16 flex-shrink-0 mt-2">Subject</span> | |
| <input | |
| value={subject} | |
| onChange={(e) => setSubject(e.target.value)} | |
| disabled={disabled} | |
| className="flex-1 text-[#1A202C] border border-[#E2E8F0] rounded px-2 py-1.5 focus:outline-none focus:border-[#47C3A6] disabled:opacity-60 disabled:bg-[#F8FAFC]" | |
| /> | |
| </div> | |
| {/* Body */} | |
| <div className="flex items-start gap-2 text-xs"> | |
| <span className="font-semibold text-[#475569] w-16 flex-shrink-0 mt-2">Body</span> | |
| <textarea | |
| value={body} | |
| onChange={(e) => setBody(e.target.value)} | |
| disabled={disabled} | |
| rows={9} | |
| className="flex-1 text-[#334155] leading-relaxed border border-[#E2E8F0] rounded px-2 py-1.5 resize-y focus:outline-none focus:border-[#47C3A6] disabled:opacity-60 disabled:bg-[#F8FAFC] font-sans" | |
| /> | |
| </div> | |
| </div> | |
| {/* Actions */} | |
| <div className="bg-[#F8FAFC] px-5 py-3 border-t border-[#E2E8F0] flex items-center justify-between gap-3"> | |
| <p className="text-[10px] text-[#94A3B8]"> | |
| {submitted === "send" | |
| ? "Sending…" | |
| : submitted === "cancel" | |
| ? "Draft discarded." | |
| : "Tip: you can also type changes in the chat to have the AI rewrite it."} | |
| </p> | |
| <div className="flex items-center gap-2"> | |
| <button | |
| onClick={handleCancel} | |
| disabled={disabled} | |
| className="text-xs font-medium text-[#64748B] px-3 py-1.5 rounded-lg border border-[#E2E8F0] bg-white hover:bg-[#F1F5F9] hover:text-[#475569] transition-colors disabled:opacity-40" | |
| > | |
| Cancel | |
| </button> | |
| <button | |
| onClick={handleSend} | |
| disabled={disabled || !subject.trim() || !body.trim()} | |
| className="text-xs font-semibold text-white px-4 py-1.5 rounded-lg bg-brand-gradient hover:opacity-90 active:scale-95 transition-all disabled:opacity-40 flex items-center gap-1.5" | |
| > | |
| <SendIcon /> Send Email | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } | |
| function MailIcon() { | |
| return ( | |
| <svg width="14" height="14" viewBox="0 0 20 20" fill="none" className="text-[#47C3A6]"> | |
| <rect x="2" y="4" width="16" height="12" rx="2" stroke="currentColor" strokeWidth="1.6" /> | |
| <path d="M3 5l7 5 7-5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" /> | |
| </svg> | |
| ); | |
| } | |
| function SendIcon() { | |
| return ( | |
| <svg width="12" height="12" viewBox="0 0 14 14" fill="none"> | |
| <path | |
| d="M13 1L7 7M13 1L9 13L7 7M13 1L1 5L7 7" | |
| stroke="white" | |
| strokeWidth="1.6" | |
| strokeLinecap="round" | |
| strokeLinejoin="round" | |
| /> | |
| </svg> | |
| ); | |
| } | |