ultisuite-client/lib/api/scheduled-mail.ts
2026-05-16 20:30:50 +02:00

211 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* API envois planifiés / attente / envoi immédiat — placeholders jusquau branchement serveur.
* Remplacer par fetch() vers vos routes (ex. POST /api/mail/scheduled, …).
*/
import type { Email } from "@/lib/email-data"
export type ScheduleSendPayload = {
sendAtIso: string
to: { name: string; email: string }[]
subject: string
previewText: string
bodyHtml: string
}
let scheduledStore: Email[] = []
let snoozedStore: Email[] = []
let sentPlaceholderStore: Email[] = []
export function __resetScheduledMailPlaceholderStoreForTests() {
scheduledStore = []
snoozedStore = []
sentPlaceholderStore = []
}
export async function listScheduledSends(): Promise<Email[]> {
// TODO: fetch GET /api/mail/scheduled
await Promise.resolve()
return [...scheduledStore]
}
export async function listSnoozedSends(): Promise<Email[]> {
// TODO: fetch GET /api/mail/snoozed
await Promise.resolve()
return [...snoozedStore]
}
export async function listSentPlaceholder(): Promise<Email[]> {
// TODO: fusion avec réponse serveur « Envoyés »
await Promise.resolve()
return [...sentPlaceholderStore]
}
export async function createScheduledSend(
payload: ScheduleSendPayload
): Promise<{ id: string }> {
// TODO: POST /api/mail/scheduled
await Promise.resolve()
const id = `sched-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`
const first = payload.to[0]
const toName = first?.name?.trim() || first?.email || "Destinataire"
const row: Email = {
id,
sender: toName,
senderEmail: first?.email,
subject: payload.subject.trim() || "(Sans objet)",
preview: payload.previewText.slice(0, 200),
body: payload.bodyHtml,
date: payload.sendAtIso,
read: true,
starred: false,
important: false,
labels: ["scheduled"],
scheduledSendAt: payload.sendAtIso,
scheduledToName: toName,
}
scheduledStore = [row, ...scheduledStore.filter((e) => e.id !== id)]
return { id }
}
export async function deleteScheduledSend(id: string): Promise<void> {
// TODO: DELETE /api/mail/scheduled/:id
await Promise.resolve()
scheduledStore = scheduledStore.filter((e) => e.id !== id)
}
export async function archiveScheduledSend(id: string): Promise<void> {
// TODO: POST /api/mail/scheduled/:id/archive
await Promise.resolve()
scheduledStore = scheduledStore.filter((e) => e.id !== id)
}
/** Retire de « planifié » et place dans « En attente » (snooze). */
export async function snoozeScheduledSend(id: string): Promise<void> {
// TODO: POST /api/mail/scheduled/:id/snooze
await Promise.resolve()
const i = scheduledStore.findIndex((e) => e.id === id)
if (i === -1) return
const row = scheduledStore[i]!
scheduledStore = scheduledStore.filter((e) => e.id !== id)
const wake = new Date(Date.now() + 24 * 60 * 60 * 1000)
const wakeIso = wake.toISOString()
snoozedStore.unshift({
...row,
labels: ["snoozed"],
scheduledSendAt: undefined,
scheduledToName: undefined,
snoozeWakeAt: wakeIso,
sender: row.scheduledToName ?? row.sender,
read: true,
})
}
export async function rescheduleScheduledSend(
id: string,
sendAtIso: string
): Promise<void> {
// TODO: PATCH /api/mail/scheduled/:id { sendAt }
await Promise.resolve()
const idx = scheduledStore.findIndex((e) => e.id === id)
if (idx === -1) return
scheduledStore[idx] = {
...scheduledStore[idx]!,
scheduledSendAt: sendAtIso,
}
}
function rowToSchedulePayload(row: Email): ScheduleSendPayload {
const email = row.senderEmail?.trim() ?? ""
const name = row.scheduledToName ?? row.sender
return {
sendAtIso: row.scheduledSendAt ?? new Date().toISOString(),
to: email ? [{ name: name, email }] : [],
subject: row.subject,
previewText: row.preview,
bodyHtml: row.body ?? `<p></p>`,
}
}
/** Lecture seule pour ouvrir le compose sans retirer de la liste « Planifié ». */
export async function getScheduledSendPayloadForEdit(
id: string
): Promise<ScheduleSendPayload | null> {
// TODO: GET /api/mail/scheduled/:id/edit
await Promise.resolve()
const row = scheduledStore.find((e) => e.id === id)
if (!row) return null
return rowToSchedulePayload(row)
}
/** Met à jour contenu + date denvoi pour un id planifié existant. */
export async function updateScheduledSend(
id: string,
payload: ScheduleSendPayload
): Promise<void> {
// TODO: PUT /api/mail/scheduled/:id
await Promise.resolve()
const idx = scheduledStore.findIndex((e) => e.id === id)
if (idx === -1) return
const row = scheduledStore[idx]!
const first = payload.to[0]
const toName = first?.name?.trim() || first?.email || "Destinataire"
scheduledStore[idx] = {
...row,
sender: toName,
senderEmail: first?.email,
subject: payload.subject.trim() || "(Sans objet)",
preview: payload.previewText.slice(0, 200),
body: payload.bodyHtml,
scheduledSendAt: payload.sendAtIso,
scheduledToName: toName,
}
}
/** Retire le planifié et renvoie le contenu (ex. flux legacy). */
export async function popScheduledSendForEdit(
id: string
): Promise<ScheduleSendPayload | null> {
// TODO: POST /api/mail/scheduled/:id/edit-session
await Promise.resolve()
const i = scheduledStore.findIndex((e) => e.id === id)
if (i === -1) return null
const row = scheduledStore[i]!
scheduledStore = scheduledStore.filter((e) => e.id !== id)
return rowToSchedulePayload(row)
}
export async function sendScheduledNow(id: string): Promise<void> {
// TODO: POST /api/mail/scheduled/:id/send-now
await Promise.resolve()
const i = scheduledStore.findIndex((e) => e.id === id)
if (i === -1) return
const row = scheduledStore[i]!
scheduledStore = scheduledStore.filter((e) => e.id !== id)
const now = new Date()
sentPlaceholderStore.unshift({
id: `sent-now-${Date.now()}-${Math.random().toString(36).slice(2, 5)}`,
sender: row.scheduledToName ?? row.sender,
senderEmail: row.senderEmail,
subject: row.subject,
preview: row.preview,
body: row.body,
date: now.toISOString(),
read: true,
starred: false,
important: false,
labels: ["sent"],
})
}
export async function markScheduledSendReadState(
id: string,
read: boolean
): Promise<void> {
// TODO: PATCH
await Promise.resolve()
const i = scheduledStore.findIndex((e) => e.id === id)
if (i === -1) return
scheduledStore[i] = { ...scheduledStore[i]!, read }
}