[RAPID-micro] 메일관리 IMAP 서비스 프리셋 추가 (Gmail, Naver, Outlook 등)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,10 @@ import {
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { toast } from "sonner";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ChevronsUpDown, Check } from "lucide-react";
|
||||
import {
|
||||
ResizablePanelGroup,
|
||||
ResizablePanel,
|
||||
@@ -85,6 +89,15 @@ import {
|
||||
} from "@/lib/api/userMail";
|
||||
const ComposeDialogDynamic = dynamic(() => import("./ComposeDialog"), { ssr: false });
|
||||
|
||||
const IMAP_PRESETS = [
|
||||
{ label: "직접 입력", value: "custom", host: "", port: 993, useTls: true },
|
||||
{ label: "Gmail", value: "gmail", host: "imap.gmail.com", port: 993, useTls: true },
|
||||
{ label: "Naver", value: "naver", host: "imap.naver.com", port: 993, useTls: true },
|
||||
{ label: "Outlook / Hotmail", value: "outlook", host: "outlook.office365.com", port: 993, useTls: true },
|
||||
{ label: "Kakao", value: "kakao", host: "imap.kakao.com", port: 993, useTls: true },
|
||||
{ label: "Daum", value: "daum", host: "imap.daum.net", port: 993, useTls: true },
|
||||
];
|
||||
|
||||
const DEFAULT_FORM: CreateUserMailAccountDto = {
|
||||
displayName: "",
|
||||
email: "",
|
||||
@@ -131,6 +144,7 @@ export default function ImapMailPage() {
|
||||
const [pendingDeleteMail, setPendingDeleteMail] = useState<ReceivedMail | null>(null);
|
||||
const [pendingDeleteAccount, setPendingDeleteAccount] = useState<UserMailAccount | null>(null);
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [hostPopoverOpen, setHostPopoverOpen] = useState(false);
|
||||
|
||||
const detailCacheRef = useRef<Map<string, MailDetail>>(new Map());
|
||||
const prefetchingRef = useRef<Set<string>>(new Set());
|
||||
@@ -416,6 +430,7 @@ export default function ImapMailPage() {
|
||||
setForm(DEFAULT_FORM);
|
||||
setTestResult(null);
|
||||
setShowPassword(false);
|
||||
setHostPopoverOpen(false);
|
||||
setShowDialog(true);
|
||||
}
|
||||
|
||||
@@ -913,11 +928,46 @@ export default function ImapMailPage() {
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs">IMAP 호스트</Label>
|
||||
<Input
|
||||
value={form.host}
|
||||
onChange={(e) => setForm((p) => ({ ...p, host: e.target.value }))}
|
||||
placeholder="imap.gmail.com"
|
||||
/>
|
||||
<Popover open={hostPopoverOpen} onOpenChange={setHostPopoverOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="outline" role="combobox" className="w-full justify-between font-normal">
|
||||
<span className={cn("truncate", !form.host && "text-muted-foreground")}>
|
||||
{form.host || "imap.gmail.com"}
|
||||
</span>
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-[220px] p-0" align="start">
|
||||
<Command>
|
||||
<CommandInput
|
||||
placeholder="호스트 직접 입력..."
|
||||
value={form.host}
|
||||
onValueChange={(v) => setForm((p) => ({ ...p, host: v }))}
|
||||
/>
|
||||
<CommandList>
|
||||
<CommandEmpty>직접 입력한 값을 사용합니다</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{IMAP_PRESETS.filter((p) => p.value !== "custom").map((preset) => (
|
||||
<CommandItem
|
||||
key={preset.value}
|
||||
value={preset.host}
|
||||
onSelect={() => {
|
||||
setForm((p) => ({ ...p, host: preset.host, port: preset.port, useTls: preset.useTls }));
|
||||
setHostPopoverOpen(false);
|
||||
}}
|
||||
>
|
||||
<Check className={cn("mr-2 h-4 w-4", form.host === preset.host ? "opacity-100" : "opacity-0")} />
|
||||
<div>
|
||||
<div className="text-sm font-medium">{preset.label}</div>
|
||||
<div className="text-xs text-muted-foreground">{preset.host}</div>
|
||||
</div>
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs">포트</Label>
|
||||
|
||||
Reference in New Issue
Block a user