From 1ecbef39b4b3e1e0e3e44b8e305b1fcc5a1ceac6 Mon Sep 17 00:00:00 2001 From: admin Date: Sat, 22 Aug 2026 23:10:22 +0000 Subject: [PATCH] Terminal --- src/routes/_authenticated/mail.tsx | 689 ----------------------------- 1 file changed, 689 deletions(-) delete mode 100644 src/routes/_authenticated/mail.tsx diff --git a/src/routes/_authenticated/mail.tsx b/src/routes/_authenticated/mail.tsx deleted file mode 100644 index 81ee795..0000000 --- a/src/routes/_authenticated/mail.tsx +++ /dev/null @@ -1,689 +0,0 @@ -import { createFileRoute } from "@tanstack/react-router"; -import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; -import { useAuth } from "@/hooks/use-auth"; -import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { Textarea } from "@/components/ui/textarea"; -import { Switch } from "@/components/ui/switch"; -import { Badge } from "@/components/ui/badge"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogDescription, -} from "@/components/ui/dialog"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; -import { - Mail, - Inbox, - Loader2, - Paperclip, - RefreshCw, - Reply, - Send, - Settings, - Trash2, - AlertTriangle, -} from "lucide-react"; -import { useState } from "react"; -import { toast } from "sonner"; -import { - getMailSetup, - getAttachment, - getMessage, - listFolders, - listMessages, - myMailboxStatus, - removeUserMailbox, - saveMailSettings, - sendMail, - setUserMailbox, - type MailSettings, -} from "@/lib/mail.functions"; - -export const Route = createFileRoute("/_authenticated/mail")({ - head: () => ({ meta: [{ title: "Mail — School Portal" }] }), - component: MailPage, -}); - -const fmt = (iso: string | null) => - iso ? new Date(iso).toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" }) : "—"; - -function MailPage() { - const { roles } = useAuth(); - const isAdmin = roles.includes("admin"); - const qc = useQueryClient(); - const [folder, setFolder] = useState("INBOX"); - const [openUid, setOpenUid] = useState(null); - const [composing, setComposing] = useState(null); - const [setupOpen, setSetupOpen] = useState(false); - - const status = useQuery({ - queryKey: ["mail-status"], - queryFn: () => myMailboxStatus({}), - }); - - const folders = useQuery({ - queryKey: ["mail-folders"], - enabled: !!status.data?.email, - queryFn: () => listFolders({}), - retry: false, - }); - - const messages = useQuery({ - queryKey: ["mail-messages", folder], - enabled: !!status.data?.email, - queryFn: () => listMessages({ data: { folder, limit: 40 } }), - retry: false, - }); - - if (status.isLoading) { - return ( -
- Loading mail… -
- ); - } - - // Nothing set up yet: tell the admin what to do, and tell everyone else who to ask. - if (!status.data?.email) { - return ( -
-

- Mail -

-
- {!status.data?.serverConfigured ? ( - <> -
The mail server isn't configured yet.
-

- {isAdmin - ? "Enter your provider's IMAP and SMTP details, then give each staff member their mailbox login." - : "An administrator needs to set up the school mail server before you can use this page."} -

- - ) : ( - <> -
You don't have a mailbox yet.
-

- The mail server is configured, but no mailbox has been assigned to your account. - {isAdmin ? " Assign one below." : " Ask an administrator to set one up."} -

- - )} - {isAdmin && ( - - )} -
- {setupOpen && ( - { - setSetupOpen(false); - qc.invalidateQueries({ queryKey: ["mail-status"] }); - }} - /> - )} -
- ); - } - - const err = (messages.error ?? folders.error) as Error | undefined; - - return ( -
-
-
-

- Mail -

-

{status.data.email}

-
-
- - - {isAdmin && ( - - )} -
-
- - {err && ( -
- -
-
Couldn't reach the mail server
-
{err.message}
-
-
- )} - -
-
- {(folders.data ?? [{ path: "INBOX", name: "Inbox", specialUse: null }]).map((f) => ( - - ))} -
- -
- {messages.isLoading ? ( -
- Loading messages… -
- ) : (messages.data?.messages ?? []).length === 0 ? ( -
- No messages in this folder. -
- ) : ( -
- {(messages.data?.messages ?? []).map((m) => ( - - ))} -
- )} - {messages.data ? ( -

- Showing {messages.data.messages.length} of {messages.data.total} in{" "} - {messages.data.folder}. -

- ) : null} -
-
- - {openUid !== null && ( - { - setOpenUid(null); - qc.invalidateQueries({ queryKey: ["mail-messages", folder] }); - }} - onReply={(c) => { - setOpenUid(null); - setComposing(c); - }} - /> - )} - {composing && setComposing(null)} />} - {setupOpen && ( - { - setSetupOpen(false); - qc.invalidateQueries({ queryKey: ["mail-status"] }); - }} - /> - )} -
- ); -} - -function MessageDialog({ - folder, - uid, - onClose, - onReply, -}: { - folder: string; - uid: number; - onClose: () => void; - onReply: (c: { - to: string; - subject: string; - inReplyTo: string | null; - references: string | null; - }) => void; -}) { - const { data, isLoading, error } = useQuery({ - queryKey: ["mail-message", folder, uid], - queryFn: () => getMessage({ data: { folder, uid } }), - retry: false, - }); - - const download = async (filename: string) => { - try { - const a = await getAttachment({ data: { folder, uid, filename } }); - const bytes = Uint8Array.from(atob(a.base64), (ch) => ch.charCodeAt(0)); - const url = URL.createObjectURL(new Blob([bytes], { type: a.contentType })); - const el = document.createElement("a"); - el.href = url; - el.download = a.filename; - el.click(); - URL.revokeObjectURL(url); - } catch (e) { - toast.error((e as Error).message); - } - }; - - return ( - !o && onClose()}> - - - {data?.subject ?? "Message"} - - {isLoading && ( -
- Loading… -
- )} - {error &&

{(error as Error).message}

} - {data && ( -
-
-
- From: {data.from} -
-
- To: {data.to} -
- {data.cc && ( -
- Cc: {data.cc} -
- )} -
{fmt(data.date)}
-
- - {data.attachments.length > 0 && ( -
- {data.attachments.map((a) => ( - - ))} -
- )} - - {/* Remote HTML is deliberately not rendered — an