227 lines
6.4 KiB
TypeScript
227 lines
6.4 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { ChevronDown, ChevronUp, Paperclip, X } from 'lucide-react';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Label } from '@/components/ui/label';
|
|
import { Textarea } from '@/components/ui/textarea';
|
|
|
|
interface ComposeEmailFormProps {
|
|
to: string;
|
|
setTo: (value: string) => void;
|
|
cc: string;
|
|
setCc: (value: string) => void;
|
|
bcc: string;
|
|
setBcc: (value: string) => void;
|
|
subject: string;
|
|
setSubject: (value: string) => void;
|
|
emailContent: string;
|
|
setEmailContent: (value: string) => void;
|
|
showCc: boolean;
|
|
setShowCc: (value: boolean) => void;
|
|
showBcc: boolean;
|
|
setShowBcc: (value: boolean) => void;
|
|
attachments: Array<{
|
|
name: string;
|
|
content: string;
|
|
type: string;
|
|
}>;
|
|
onAttachmentAdd: (files: FileList) => void;
|
|
onAttachmentRemove: (index: number) => void;
|
|
}
|
|
|
|
export default function ComposeEmailForm({
|
|
to,
|
|
setTo,
|
|
cc,
|
|
setCc,
|
|
bcc,
|
|
setBcc,
|
|
subject,
|
|
setSubject,
|
|
emailContent,
|
|
setEmailContent,
|
|
showCc,
|
|
setShowCc,
|
|
showBcc,
|
|
setShowBcc,
|
|
attachments,
|
|
onAttachmentAdd,
|
|
onAttachmentRemove
|
|
}: ComposeEmailFormProps) {
|
|
const fileInputRef = React.useRef<HTMLInputElement>(null);
|
|
|
|
const handleAttachmentClick = () => {
|
|
fileInputRef.current?.click();
|
|
};
|
|
|
|
const handleFileSelection = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
if (e.target.files && e.target.files.length > 0) {
|
|
onAttachmentAdd(e.target.files);
|
|
}
|
|
|
|
// Reset the input value so the same file can be selected again
|
|
if (fileInputRef.current) {
|
|
fileInputRef.current.value = '';
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="p-4 space-y-4">
|
|
<div className="space-y-3">
|
|
{/* To field */}
|
|
<div className="flex items-center">
|
|
<Label htmlFor="to" className="w-16 flex-shrink-0">To:</Label>
|
|
<Input
|
|
id="to"
|
|
value={to}
|
|
onChange={(e) => setTo(e.target.value)}
|
|
placeholder="Email address..."
|
|
className="flex-grow"
|
|
/>
|
|
</div>
|
|
|
|
{/* CC field - conditionally shown */}
|
|
{showCc && (
|
|
<div className="flex items-center">
|
|
<Label htmlFor="cc" className="w-16 flex-shrink-0">Cc:</Label>
|
|
<Input
|
|
id="cc"
|
|
value={cc}
|
|
onChange={(e) => setCc(e.target.value)}
|
|
placeholder="CC address..."
|
|
className="flex-grow"
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{/* BCC field - conditionally shown */}
|
|
{showBcc && (
|
|
<div className="flex items-center">
|
|
<Label htmlFor="bcc" className="w-16 flex-shrink-0">Bcc:</Label>
|
|
<Input
|
|
id="bcc"
|
|
value={bcc}
|
|
onChange={(e) => setBcc(e.target.value)}
|
|
placeholder="BCC address..."
|
|
className="flex-grow"
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{/* CC/BCC toggle buttons */}
|
|
<div className="flex items-center space-x-2 ml-16">
|
|
{!showCc && (
|
|
<Button
|
|
type="button"
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => setShowCc(true)}
|
|
className="h-6 px-2 text-xs text-gray-500 hover:text-gray-700"
|
|
>
|
|
Add Cc <ChevronDown className="ml-1 h-3 w-3" />
|
|
</Button>
|
|
)}
|
|
|
|
{!showBcc && (
|
|
<Button
|
|
type="button"
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => setShowBcc(true)}
|
|
className="h-6 px-2 text-xs text-gray-500 hover:text-gray-700"
|
|
>
|
|
Add Bcc <ChevronDown className="ml-1 h-3 w-3" />
|
|
</Button>
|
|
)}
|
|
|
|
{showCc && (
|
|
<Button
|
|
type="button"
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => setShowCc(false)}
|
|
className="h-6 px-2 text-xs text-gray-500 hover:text-gray-700"
|
|
>
|
|
Remove Cc <ChevronUp className="ml-1 h-3 w-3" />
|
|
</Button>
|
|
)}
|
|
|
|
{showBcc && (
|
|
<Button
|
|
type="button"
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => setShowBcc(false)}
|
|
className="h-6 px-2 text-xs text-gray-500 hover:text-gray-700"
|
|
>
|
|
Remove Bcc <ChevronUp className="ml-1 h-3 w-3" />
|
|
</Button>
|
|
)}
|
|
</div>
|
|
|
|
{/* Subject field */}
|
|
<div className="flex items-center">
|
|
<Label htmlFor="subject" className="w-16 flex-shrink-0">Subject:</Label>
|
|
<Input
|
|
id="subject"
|
|
value={subject}
|
|
onChange={(e) => setSubject(e.target.value)}
|
|
placeholder="Email subject..."
|
|
className="flex-grow"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Email content */}
|
|
<Textarea
|
|
value={emailContent}
|
|
onChange={(e) => setEmailContent(e.target.value)}
|
|
placeholder="Write your message here..."
|
|
className="w-full min-h-[200px]"
|
|
/>
|
|
|
|
{/* Attachments */}
|
|
{attachments.length > 0 && (
|
|
<div className="border rounded-md p-2">
|
|
<h3 className="text-sm font-medium mb-2">Attachments</h3>
|
|
<div className="space-y-2">
|
|
{attachments.map((file, index) => (
|
|
<div key={index} className="flex items-center justify-between text-sm border rounded p-2">
|
|
<span className="truncate max-w-[200px]">{file.name}</span>
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => onAttachmentRemove(index)}
|
|
className="h-6 w-6 p-0"
|
|
>
|
|
<X className="h-4 w-4" />
|
|
</Button>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Attachment input (hidden) */}
|
|
<input
|
|
type="file"
|
|
multiple
|
|
ref={fileInputRef}
|
|
onChange={handleFileSelection}
|
|
className="hidden"
|
|
/>
|
|
|
|
{/* Attachments button */}
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={handleAttachmentClick}
|
|
className="flex items-center"
|
|
>
|
|
<Paperclip className="mr-2 h-4 w-4" />
|
|
Attach Files
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|