"use client"; import { useEffect, useState, useTransition } from "react"; import Link from "next/link"; import { ForwardEmail } from "@prisma/client"; import { useTranslations } from "next-intl"; import { toast } from "sonner"; import useSWR from "swr"; import { cn, fetcher, htmlToText } from "@/lib/utils"; import BlurImage from "../shared/blur-image"; import { Icons } from "../shared/icons"; import { PaginationWrapper } from "../shared/pagination"; import { TimeAgoIntl } from "../shared/time-ago"; // import { Badge } from "../ui/badge"; import { Button } from "../ui/button"; import { Checkbox } from "../ui/checkbox"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "../ui/dropdown-menu"; import { Skeleton } from "../ui/skeleton"; import { Switch } from "../ui/switch"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../ui/tooltip"; import EmailDetail from "./EmailDetail"; import Loader from "./Loader"; import { SendEmailModal } from "./SendEmailModal"; interface EmailListProps { emailAddress: string | null; selectedEmailId: string | null; onSelectEmail: (emailId: string | null) => void; className?: string; isAdminModel: boolean; } export default function EmailList({ emailAddress, selectedEmailId, onSelectEmail, className, isAdminModel, }: EmailListProps) { const t = useTranslations("Email"); const [isRefreshing, setIsRefreshing] = useState(false); const [isAutoRefresh, setIsAutoRefresh] = useState(false); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); const [selectedEmails, setSelectedEmails] = useState([]); const [showMutiCheckBox, setShowMutiCheckBox] = useState(false); const [isDeleting, startDeleteTransition] = useTransition(); const { data, error, isLoading, mutate } = useSWR<{ total: number; list: ForwardEmail[]; }>( emailAddress ? `/api/email/inbox?emailAddress=${emailAddress}&page=${currentPage}&size=${pageSize}` : null, fetcher, { refreshInterval: isAutoRefresh ? 5000 : 0, dedupingInterval: 2000, }, ); useEffect(() => { if (emailAddress && selectedEmailId) { const emailExists = data?.list.some( (email) => email.id === selectedEmailId, ); if (!emailExists) { onSelectEmail(null); } } }, [emailAddress, data, selectedEmailId]); const handleMarkAsRead = async (emailId: string) => { await fetch("/api/email/read", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ emailId }), }).then(() => mutate()); }; const handleMarkSelectedAsRead = async () => { if (selectedEmails.length === 0) { toast.error("Please select at least one email"); return; } try { const response = await fetch("/api/email/read", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ emailIds: selectedEmails }), }); if (response.ok) { setSelectedEmails([]); mutate(); } else { const errorData = await response.json(); toast.error(errorData.error || "Failed to mark emails as read"); } } catch (error) { toast.error("Error marking emails as read"); } }; const handleSelectEmail = (emailId: string) => { setSelectedEmails((prev) => prev.includes(emailId) ? prev.filter((id) => id !== emailId) : [...prev, emailId], ); }; const handleSelectAllEmails = () => { setSelectedEmails(data?.list.map((email) => email.id) || []); }; const handleSetAutoRefresh = (value: boolean) => { setIsAutoRefresh(value); }; const handleManualRefresh = async () => { if (!isAutoRefresh) { setIsRefreshing(true); await mutate(); setIsRefreshing(false); } }; const handleEmailSelection = (emailId: string | null) => { if (emailId) { const selectedEmail = data?.list?.find((email) => email.id === emailId); if (selectedEmail && !selectedEmail.readAt) { handleMarkAsRead(emailId); } } onSelectEmail(emailId); }; const handleDeletEmails = async (ids: string[]) => { startDeleteTransition(async () => { await fetch("/api/email/inbox", { method: "DELETE", body: JSON.stringify({ ids }), }).then((v) => { v.status === 200 && mutate(); }); }); }; if (!emailAddress) { return ; } return (
{t("INBOX")}
{t("Auto refresh")} {showMutiCheckBox && ( )}
{isLoading && (
{[...Array(9)].map((_, index) => ( ))}
)} {!isLoading && !error && (
{selectedEmailId ? ( email.id === selectedEmailId)} selectedEmailId={selectedEmailId} onClose={() => onSelectEmail(null)} onMarkAsRead={() => handleMarkAsRead(selectedEmailId)} /> ) : ( <> {data && data.total > 0 ? ( data.list.map((email) => (
{showMutiCheckBox && (
e.stopPropagation()} > handleSelectEmail(email.id)} className="mr-3 size-4 border-neutral-300 bg-neutral-100 data-[state=checked]:border-neutral-900 data-[state=checked]:bg-neutral-600 data-[state=checked]:text-neutral-100 dark:border-neutral-700 dark:bg-neutral-800 dark:data-[state=checked]:border-neutral-300 dark:data-[state=checked]:bg-neutral-300" />
)}
handleEmailSelection(email.id)} >
{email.fromName || email.subject || "Untitled"} {email.readAt && ( )}
{email.subject}
{email.html ? htmlToText(email.html) : email.text || "No content"}
)) ) : (

{t("Waiting for emails")}...

)} )}
)} {data && Math.ceil(data.total / pageSize) > 1 && ( )}
); } export function EmptyInboxSection() { const t = useTranslations("Email"); return (

{t("No Email Address Selected")}

{t("Please select an email address from the list to view your inbox")}. {t("Once selected, your emails will appear here automatically")}.

  • {t("How to use email to send or receive emails?")}
  • {t("Will my email or inbox expire?")}
  • {t("What is the limit? It's free?")}
  • {t("How to create emails with api?")}
); }