"use client"; import { useState } from "react"; import { Button } from "@calcom/ui/components/button"; import { FileUploader, type FileData } from "@calcom/ui/components/file-uploader"; import { Label, TextArea } from "@calcom/ui/components/form"; import { Icon } from "@calcom/ui/components/icon"; import { Popover, PopoverContent, PopoverTrigger } from "@calcom/ui/components/popover"; import { showToast } from "@calcom/ui/components/toast"; interface ContactFormData { name: string; email: string; message: string; attachments?: FileData[]; } const PlainContactForm = () => { const [isOpen, setIsOpen] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitted, setIsSubmitted] = useState(false); const [isUploadingImage, setIsUploadingImage] = useState(false); const [data, setData] = useState<{ message: string; attachmentIds: string[]; }>({ message: "", attachmentIds: [], }); const [uploads, setUploads] = useState< { attachmentId?: string; uploading: boolean; file: File; id: string; }[] >([]); const handleUpload = async (allFiles: FileData[], newFiles: FileData[], removedFiles: FileData[]) => { if (newFiles.length > 0) { const newFile = newFiles[0]; setUploads((prev) => [...prev, { file: newFile.file, uploading: true, id: newFile.id }]); setIsUploadingImage(true); const { file } = newFile; const res = await fetch(`/api/support/upload?name=${file.name}&size=${file.size}`); if (!res.ok) { showToast("Error uploading attachment", "error"); setIsUploadingImage(false); return; } const { uploadFormUrl, uploadFormData, attachment: { id: attachmentId }, } = await res.json(); setIsUploadingImage(false); const formData = new FormData(); uploadFormData.forEach(({ key, value }: any) => { formData.append(key, value); }); formData.append("file", file); const uploadRes = await fetch(uploadFormUrl, { method: "POST", body: formData, }); if (!uploadRes.ok) { showToast(`Failed while uploading file: ${uploadRes.text}`, "error"); setIsUploadingImage(false); return; } setUploads((prev) => prev.map((upload) => (upload.file === file ? { ...upload, uploading: false, attachmentId } : upload)) ); setData((prev) => ({ ...prev, attachmentIds: [...prev.attachmentIds, attachmentId], })); setIsUploadingImage(false); showToast("File uploaded successfully", "success"); } else if (removedFiles.length > 0) { const removedFile = removedFiles[0]; const file = uploads.find((upload) => upload.id === removedFile.id); if (!file) { console.warn("File not found in uploads: ", removedFile.id); return; } setData((prev) => ({ ...prev, attachmentIds: prev.attachmentIds.filter((id) => id !== file.attachmentId), })); setUploads((prev) => prev.filter((upload) => upload.id !== removedFile.id)); } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setIsSubmitting(true); try { const response = await fetch("/api/support", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); if (!response.ok) { const errorData = await response.json(); showToast(errorData.message ?? "Failed to submit contact form", "error"); setIsSubmitting(false); return; } setIsSubmitted(true); setIsSubmitting(false); setData({ message: "", attachmentIds: [], }); } catch (err) { showToast(err instanceof Error ? err.message : "An error occurred", "error"); setIsSubmitting(false); } }; const resetForm = () => { setIsSubmitted(false); setData({ message: "", attachmentIds: [], }); setUploads([]); }; return (
Contact support
Thank you for contacting us. We'll get back to you as soon as possible.