This commit is contained in:
2026-02-25 01:34:09 +00:00
parent 6e8ee69311
commit 0226608d8f
8 changed files with 296 additions and 43 deletions
@@ -1,10 +1,18 @@
import { useEffect, useRef } from 'react';
import { useEffect, useRef, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { Mail } from 'lucide-react';
import { FileViewerProvider, FileViewerHeader, FileViewerBody } from 'officerdev';
import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog';
import { useClient } from 'hooks/useClient';
import { useGlobal } from 'hooks/useGlobal';
import type { EmailMessage } from 'types';
type OpenAttachment = {
filePath: string;
fileName: string;
root: string;
};
const HtmlBody = ({ html }: { html: string }) => {
const iframeRef = useRef<HTMLIFrameElement>(null);
@@ -36,6 +44,7 @@ const HtmlBody = ({ html }: { html: string }) => {
export const EmailReader = () => {
const client = useClient();
const [selectedId] = useGlobal<string | null>('EMAIL_SELECTED', null);
const [openAttachment, setOpenAttachment] = useState<OpenAttachment | null>(null);
const { data: message, isLoading } = useQuery({
queryKey: ['email-message', selectedId],
@@ -43,6 +52,12 @@ export const EmailReader = () => {
enabled: !!selectedId,
});
const extractAttachment = async (index: number) => {
if (!selectedId) return;
const result = await client.post<OpenAttachment>(`/email/messages/${selectedId}/attachments/${index}/extract`);
setOpenAttachment(result);
};
if (!selectedId) {
return (
<div className="flex h-full flex-col items-center justify-center gap-2 text-sm opacity-50">
@@ -83,9 +98,13 @@ export const EmailReader = () => {
{message.attachments.length > 0 && (
<div className="flex flex-wrap gap-1.5 pt-1">
{message.attachments.map((att: { filename: string; size: number; contentType: string }, i: number) => (
<span key={i} className="rounded bg-accent px-2 py-0.5 text-xs">
<button
key={i}
className="cursor-pointer rounded bg-accent px-2 py-0.5 text-xs hover:bg-accent/80"
onClick={() => extractAttachment(i)}
>
{att.filename} ({Math.round(att.size / 1024)}KB)
</span>
</button>
))}
</div>
)}
@@ -97,6 +116,26 @@ export const EmailReader = () => {
<pre className="whitespace-pre-wrap p-4 text-sm">{message.text}</pre>
)}
</div>
<Dialog open={!!openAttachment} onOpenChange={(open) => !open && setOpenAttachment(null)}>
<DialogContent className="flex h-[80vh] max-w-4xl flex-col gap-0 p-0">
<DialogTitle className="sr-only">{openAttachment?.fileName}</DialogTitle>
{openAttachment && (
<FileViewerProvider
filePath={openAttachment.filePath}
fileName={openAttachment.fileName}
root={openAttachment.root}
>
<div className="flex shrink-0 items-center gap-2 border-b px-4 py-1.5">
<FileViewerHeader />
</div>
<div className="min-h-0 flex-1">
<FileViewerBody />
</div>
</FileViewerProvider>
)}
</DialogContent>
</Dialog>
</div>
);
};