Files
webmail-client/frontend/src/components/compose/SaveTemplateDialog.tsx
T

70 lines
2.4 KiB
TypeScript
Raw Normal View History

import { useState } from "react";
import { useT } from "../../i18n";
import { ApiError } from "../../lib/api";
import type { MailTemplate } from "../../lib/types";
import { AppDialog, DialogButtons } from "../AppDialog";
/** Compose → More → Templates → Save as template: name it, save it. A name
* already taken turns the button into "Replace" rather than asking again. */
export function SaveTemplateDialog({
initialName,
existing,
onSave,
onClose,
}: {
initialName: string;
existing: MailTemplate[];
onSave: (name: string) => Promise<void>;
onClose: () => void;
}) {
const t = useT();
const [name, setName] = useState(initialName);
const [saving, setSaving] = useState(false);
const [error, setError] = useState("");
const trimmed = name.trim();
const taken = existing.some((x) => x.name.toLowerCase() === trimmed.toLowerCase());
const submit = async (e: React.FormEvent) => {
e.preventDefault();
if (!trimmed || saving) return;
setSaving(true);
setError("");
try {
await onSave(trimmed);
onClose();
} catch (err) {
setError(err instanceof ApiError ? err.message : t("compose.templateSaveFailed"));
setSaving(false);
}
};
return (
<AppDialog title={t("compose.saveTemplateTitle")} onClose={onClose}>
<form onSubmit={submit}>
<p className="mt-2 text-sm text-app-muted">{t("compose.saveTemplateHint")}</p>
<label className="mt-4 block text-sm">
<span className="text-app-muted">{t("compose.templateName")}</span>
<input
className="mt-1 w-full rounded-lg border border-app-border bg-app-bg px-3 py-1.5 text-app-fg placeholder:text-app-faint focus:border-app-accent focus:outline-none"
value={name}
maxLength={80}
placeholder={t("compose.templateNamePlaceholder")}
onChange={(e) => setName(e.target.value)}
autoFocus
onFocus={(e) => e.currentTarget.select()}
/>
</label>
{taken && <p className="mt-2 text-xs text-amber-600 dark:text-amber-400">{t("compose.templateReplaceNote")}</p>}
{error && <p className="mt-2 text-xs text-red-500">{error}</p>}
<DialogButtons
submit
confirmLabel={saving ? t("compose.templateSaving") : taken ? t("compose.templateReplaceAction") : t("common.save")}
disabled={!trimmed || saving}
onCancel={onClose}
/>
</form>
</AppDialog>
);
}