50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
import { useT } from "../../i18n";
|
|||
|
|
import type { DraftOut } from "../../lib/types";
|
||
|
|
|
||
|
|
function timeLabel(iso: string): string {
|
||
|
|
const d = new Date(iso);
|
||
|
|
const now = new Date();
|
||
|
|
if (d.toDateString() === now.toDateString())
|
||
|
|
return d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
||
|
|
return d.toLocaleDateString([], { month: "short", day: "numeric" });
|
||
|
|
}
|
||
|
|
|
||
|
|
// Local drafts live in the `drafts` table (not an IMAP mailbox), so the Drafts
|
||
|
|
// folder lists them here rather than through the thread list.
|
||
|
|
export function DraftsList({
|
||
|
|
drafts,
|
||
|
|
onOpen,
|
||
|
|
}: {
|
||
|
|
drafts: DraftOut[];
|
||
|
|
onOpen: (draft: DraftOut) => void;
|
||
|
|
}) {
|
||
|
|
const t = useT();
|
||
|
|
if (drafts.length === 0) {
|
||
|
|
return <div className="p-6 text-sm text-app-faint">{t("compose.noDrafts")}</div>;
|
||
|
|
}
|
||
|
|
return (
|
||
|
|
<div className="h-full overflow-y-auto" data-testid="drafts-list">
|
||
|
|
{drafts.map((draft) => {
|
||
|
|
const recipients = draft.payload.to.join(", ") || t("compose.noRecipient");
|
||
|
|
const preview = draft.payload.text.trim();
|
||
|
|
return (
|
||
|
|
<button
|
||
|
|
key={draft.id}
|
||
|
|
onClick={() => onOpen(draft)}
|
||
|
|
className="flex w-full flex-col gap-1 border-b border-app-border px-3 py-2.5 text-left hover:bg-app-hover"
|
||
|
|
>
|
||
|
|
<div className="flex items-center gap-2">
|
||
|
|
<span className="flex-1 truncate text-sm text-app-fg">{recipients}</span>
|
||
|
|
<span className="shrink-0 text-[11px] text-app-faint">{timeLabel(draft.updated_at)}</span>
|
||
|
|
</div>
|
||
|
|
<div className="truncate text-[13px] font-medium text-app-fg">
|
||
|
|
{draft.payload.subject || t("compose.noSubject")}
|
||
|
|
</div>
|
||
|
|
{preview && <div className="truncate text-xs text-app-faint">{preview}</div>}
|
||
|
|
</button>
|
||
|
|
);
|
||
|
|
})}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|