[RAPID-micro] 메일 작성 다이얼로그에 보내는 사람 계정 선택 추가

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-01 15:11:11 +09:00
parent 3a218c6b92
commit 67e7e19bae
2 changed files with 44 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import LinkExtension from "@tiptap/extension-link";
@@ -15,7 +15,15 @@ import {
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
import { sendUserMail } from "@/lib/api/userMail";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { toast } from "sonner";
import { sendUserMail, UserMailAccount } from "@/lib/api/userMail";
interface ComposeDialogProps {
open: boolean;
@@ -34,6 +42,7 @@ interface ComposeDialogProps {
sending: boolean;
setSending: (v: boolean) => void;
accountId: number | null;
accounts: UserMailAccount[];
}
export default function ComposeDialog({
@@ -43,8 +52,14 @@ export default function ComposeDialog({
initialHtml, setInitialHtml,
inReplyTo, references,
sending, setSending,
accountId,
accountId, accounts,
}: ComposeDialogProps) {
const [fromAccountId, setFromAccountId] = useState<number | null>(accountId);
useEffect(() => {
setFromAccountId(accountId ?? (accounts[0]?.id ?? null));
}, [accountId, accounts, open]);
const editor = useEditor({
extensions: [StarterKit, LinkExtension.configure({ openOnClick: false })],
content: initialHtml,
@@ -58,11 +73,11 @@ export default function ComposeDialog({
}, [initialHtml, editor]);
async function handleSend() {
if (!accountId || !editor) return;
if (!fromAccountId || !editor) return;
setSending(true);
try {
const html = editor.getHTML();
const result = await sendUserMail(accountId, {
const result = await sendUserMail(fromAccountId, {
to,
cc: cc || undefined,
subject,
@@ -74,7 +89,7 @@ export default function ComposeDialog({
onOpenChange(false);
setTo(""); setCc(""); setSubject(""); setInitialHtml("");
} else {
alert(result.message);
toast.error(result.message);
}
} finally {
setSending(false);
@@ -90,6 +105,24 @@ export default function ComposeDialog({
</DialogTitle>
</DialogHeader>
<div className="space-y-3">
<div>
<Label> </Label>
<Select
value={fromAccountId?.toString() ?? ""}
onValueChange={(v) => setFromAccountId(Number(v))}
>
<SelectTrigger>
<SelectValue placeholder="계정을 선택하세요" />
</SelectTrigger>
<SelectContent className="z-[10002]">
{accounts.map((acc) => (
<SelectItem key={acc.id} value={acc.id.toString()}>
{acc.displayName} ({acc.email})
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div>
<Label></Label>
<Input value={to} onChange={(e) => setTo(e.target.value)} placeholder="to@example.com" />
@@ -109,7 +142,7 @@ export default function ComposeDialog({
</div>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}></Button>
<Button onClick={handleSend} disabled={sending || !to || !subject}>
<Button onClick={handleSend} disabled={sending || !to || !subject || !fromAccountId}>
{sending ? <Loader2 className="w-4 h-4 animate-spin mr-2" /> : <Send className="w-4 h-4 mr-2" />}
</Button>

View File

@@ -87,7 +87,8 @@ import {
SendMailDto,
} from "@/lib/api/userMail";
const ComposeDialogDynamic = dynamic(() => import("./ComposeDialog"), { ssr: false });
import type ComposeDialogType from "./ComposeDialog";
const ComposeDialogDynamic = dynamic(() => import("./ComposeDialog"), { ssr: false }) as typeof ComposeDialogType;
const IMAP_PRESETS = [
{ label: "직접 입력", value: "custom", host: "", port: 993, useTls: true },
@@ -897,6 +898,7 @@ export default function ImapMailPage() {
references={composeReferences}
sending={composeSending} setSending={setComposeSending}
accountId={selectedAccount?.id ?? null}
accounts={imapAccounts}
/>
{/* 계정 추가/편집 다이얼로그 */}
@@ -937,7 +939,7 @@ export default function ImapMailPage() {
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[220px] p-0" align="start">
<PopoverContent className="w-[220px] p-0 z-[10002]" align="start">
<Command>
<CommandInput
placeholder="호스트 직접 입력..."