diff --git a/app/(protected)/dashboard/page.tsx b/app/(protected)/dashboard/page.tsx index 3caf512..399f0de 100644 --- a/app/(protected)/dashboard/page.tsx +++ b/app/(protected)/dashboard/page.tsx @@ -57,14 +57,7 @@ export default async function DashboardPage() { icon="globeLock" /> - + - + ); diff --git a/app/(protected)/dashboard/urls/live-logs.tsx b/app/(protected)/dashboard/urls/live-logs.tsx index 4fa1149..6b9f93d 100644 --- a/app/(protected)/dashboard/urls/live-logs.tsx +++ b/app/(protected)/dashboard/urls/live-logs.tsx @@ -155,7 +155,7 @@ export default function LiveLog({ admin }: { admin: boolean }) { Live Log - Real-time updates of short URL visits. + Real-time logs of short link visits. @@ -164,9 +164,7 @@ export default function LiveLog({ admin }: { admin: boolean }) { variant={"outline"} size="sm" className={`ml-auto gap-2 bg-primary-foreground transition-colors hover:border-blue-600 hover:text-blue-600 ${ - isLive - ? "animate-pulse border-dashed border-blue-600 text-blue-500" - : "" + isLive ? "border-dashed border-blue-600 text-blue-500" : "" }`} > {isLive ? "Stop" : "Live"} diff --git a/components/email/EmailList.tsx b/components/email/EmailList.tsx index 0df9d80..4f8ec7c 100644 --- a/components/email/EmailList.tsx +++ b/components/email/EmailList.tsx @@ -1,7 +1,6 @@ "use client"; -import { useEffect, useState, useTransition } from "react"; -import dynamic from "next/dynamic"; +import { useEffect, useState } from "react"; import Link from "next/link"; import { ForwardEmail } from "@prisma/client"; import { toast } from "sonner"; @@ -9,11 +8,19 @@ import useSWR from "swr"; import { cn, fetcher, htmlToText, timeAgo } from "@/lib/utils"; +import BlurImage from "../shared/blur-image"; import { Icons } from "../shared/icons"; import { PaginationWrapper } from "../shared/pagination"; -import { Badge } from "../ui/badge"; +// import { Badge } from "../ui/badge"; import { Button } from "../ui/button"; -import { Input } from "../ui/input"; +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 { @@ -24,28 +31,7 @@ import { } from "../ui/tooltip"; import EmailDetail from "./EmailDetail"; import Loader from "./Loader"; - -import "react-quill/dist/quill.snow.css"; - -import { BlurImg } from "../shared/blur-image"; -import { Checkbox } from "../ui/checkbox"; -import { - Drawer, - DrawerClose, - DrawerContent, - DrawerFooter, - DrawerHeader, - DrawerTitle, -} from "../ui/drawer"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "../ui/dropdown-menu"; - -const ReactQuill = dynamic(() => import("react-quill"), { ssr: false }); +import { SendEmailModal } from "./SendEmailModal"; interface EmailListProps { emailAddress: string | null; @@ -66,11 +52,7 @@ export default function EmailList({ const [isAutoRefresh, setIsAutoRefresh] = useState(false); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); - const [showSendDrawer, setShowSendDrawer] = useState(false); - const [sendForm, setSendForm] = useState({ to: "", subject: "", html: "" }); - const [isPending, startTransition] = useTransition(); const [selectedEmails, setSelectedEmails] = useState([]); - const [showMutiCheckBox, setShowMutiCheckBox] = useState(false); const { data, error, isLoading, mutate } = useSWR<{ @@ -83,11 +65,10 @@ export default function EmailList({ fetcher, { refreshInterval: isAutoRefresh ? 5000 : 0, - dedupingInterval: 2000, // 避免短时间内重复请求 + dedupingInterval: 2000, }, ); - // 切换email address时,清空选中的email useEffect(() => { if (emailAddress && selectedEmailId) { const emailExists = data?.list.some( @@ -99,68 +80,6 @@ export default function EmailList({ } }, [emailAddress, data, selectedEmailId]); - if (!emailAddress) { - return ( -
- - -

- No Email Address Selected -

- -

- Please select an email address from the list to view your inbox. Once - selected, your emails will appear here automatically. -

- -
    -
  • - - How to use email to send or receive emails? - -
  • -
  • - - Will my email or inbox expire? - -
  • -
  • - - What is the limit? It's free? - -
  • -
- -
- - - -
-
- ); - } - - // 处理单封邮件标记为已读 const handleMarkAsRead = async (emailId: string) => { try { await fetch("/api/email/read", { @@ -173,38 +92,32 @@ export default function EmailList({ } }; - // 处理批量标记为已读 const handleMarkSelectedAsRead = async () => { if (selectedEmails.length === 0) { toast.error("Please select at least one email"); return; } - startTransition(async () => { - try { - const response = await fetch("/api/email/read", { - method: "PUT", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ emailIds: selectedEmails }), - }); + 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"); + 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) => { - console.log(emailId); - setSelectedEmails((prev) => prev.includes(emailId) ? prev.filter((id) => id !== emailId) @@ -224,47 +137,6 @@ export default function EmailList({ } }; - const handleOpenSendEmailModal = () => { - setShowSendDrawer(true); - setSendForm({ to: "", subject: "", html: "" }); - }; - - const handleSendEmail = async () => { - if (!emailAddress) { - toast.error("No email address selected"); - return; - } - if (!sendForm.to || !sendForm.subject || !sendForm.html) { - toast.error("Please fill in all fields"); - return; - } - - startTransition(async () => { - try { - const response = await fetch("/api/email/send", { - method: "POST", - body: JSON.stringify({ - from: emailAddress, - to: sendForm.to, - subject: sendForm.subject, - html: sendForm.html, - }), - }); - - if (response.ok) { - toast.success("Email sent successfully"); - setShowSendDrawer(false); - } else { - toast.error("Failed to send email", { - description: await response.text(), - }); - } - } catch (error) { - toast.error(error.message || "Error sending email"); - } - }); - }; - const handleEmailSelection = (emailId: string | null) => { if (emailId) { const selectedEmail = data?.list?.find((email) => email.id === emailId); @@ -275,35 +147,23 @@ export default function EmailList({ onSelectEmail(emailId); }; + if (!emailAddress) { + return EmptyInboxSection(); + } + return (
INBOX - {data && data.total > 0 && ( - - {data.total} - - )} -
- - + handleSetAutoRefresh(value)} + onCheckedChange={handleSetAutoRefresh} defaultChecked={isAutoRefresh} aria-label="Auto refresh" /> @@ -311,10 +171,9 @@ export default function EmailList({ Auto refresh - {selectedEmails.length > 0 && ( - <> - - + + + + + + - - - - - - - - - - - - + + + + + + + )}
@@ -454,7 +306,6 @@ export default function EmailList({ )}
)} - {data && Math.ceil(data.total / pageSize) > 1 && ( )} - - {/* 发送邮件 Modal */} - - - - - Send Email{" "} - - - - - - -
-
- - -
-
- - - setSendForm({ ...sendForm, to: e.target.value }) - } - placeholder="recipient@example.com" - className="mt-1" - /> -
-
- - - setSendForm({ ...sendForm, subject: e.target.value }) - } - placeholder="Enter subject" - className="mt-1" - /> -
-
- - setSendForm({ ...sendForm, html: value })} - className="mt-1 h-40 rounded-lg" - theme="snow" - placeholder="Enter your message" - /> -
-
- - - - - - -
-
+ + ); +} + +export function EmptyInboxSection() { + return ( +
+ +

No Email Address Selected

+

+ Please select an email address from the list to view your inbox. Once + selected, your emails will appear here automatically. +

+
    +
  • + + How to use email to send or receive emails? + +
  • +
  • + + Will my email or inbox expire? + +
  • +
  • + + What is the limit? It's free? + +
  • +
+
+ + + +
); } diff --git a/components/email/EmailSidebar.tsx b/components/email/EmailSidebar.tsx index 4376e7c..0ff5af6 100644 --- a/components/email/EmailSidebar.tsx +++ b/components/email/EmailSidebar.tsx @@ -37,6 +37,7 @@ import { } from "../ui/select"; import { Skeleton } from "../ui/skeleton"; import { Switch } from "../ui/switch"; +import { SendEmailModal } from "./SendEmailModal"; interface EmailSidebarProps { user: User; @@ -394,7 +395,7 @@ export default function EmailSidebar({ key={email.id} onClick={() => onSelectEmail(email.emailAddress)} className={cn( - `border-gray-5 m-1 cursor-pointer bg-neutral-50 p-2 transition-colors hover:bg-neutral-100 dark:border-zinc-700 dark:bg-neutral-800 dark:hover:bg-neutral-900`, + `border-gray-5 group m-1 cursor-pointer bg-neutral-50 p-2 transition-colors hover:bg-neutral-100 dark:border-zinc-700 dark:bg-neutral-800 dark:hover:bg-neutral-900`, selectedEmailAddress === email.emailAddress ? "bg-gray-100 dark:bg-neutral-900" : "", @@ -419,25 +420,32 @@ export default function EmailSidebar({ {!isCollapsed && ( <> - + } /> handleOpenEditEmail(email)} /> { setEmailToDelete(email.id); setShowDeleteModal(true); }} /> + )} diff --git a/components/email/SendEmailModal.tsx b/components/email/SendEmailModal.tsx new file mode 100644 index 0000000..1e5d510 --- /dev/null +++ b/components/email/SendEmailModal.tsx @@ -0,0 +1,170 @@ +"use client"; + +import { useState, useTransition } from "react"; +import dynamic from "next/dynamic"; +import { toast } from "sonner"; + +import { Icons } from "../shared/icons"; +import { Button } from "../ui/button"; +import { + Drawer, + DrawerClose, + DrawerContent, + DrawerFooter, + DrawerHeader, + DrawerTitle, +} from "../ui/drawer"; +import { Input } from "../ui/input"; + +import "react-quill/dist/quill.snow.css"; + +const ReactQuill = dynamic(() => import("react-quill"), { ssr: false }); + +interface SendEmailModalProps { + className?: string; + emailAddress: string | null; + triggerButton?: React.ReactNode; // 自定义触发按钮 + onSuccess?: () => void; // 发送成功后的回调 +} + +export function SendEmailModal({ + className, + emailAddress, + triggerButton, + onSuccess, +}: SendEmailModalProps) { + const [isOpen, setIsOpen] = useState(false); + const [sendForm, setSendForm] = useState({ to: "", subject: "", html: "" }); + const [isPending, startTransition] = useTransition(); + + const handleSendEmail = async () => { + if (!emailAddress) { + toast.error("No email address selected"); + return; + } + if (!sendForm.to || !sendForm.subject || !sendForm.html) { + toast.error("Please fill in all fields"); + return; + } + + startTransition(async () => { + try { + const response = await fetch("/api/email/send", { + method: "POST", + body: JSON.stringify({ + from: emailAddress, + to: sendForm.to, + subject: sendForm.subject, + html: sendForm.html, + }), + }); + + if (response.ok) { + toast.success("Email sent successfully"); + setIsOpen(false); + setSendForm({ to: "", subject: "", html: "" }); + onSuccess?.(); + } else { + toast.error("Failed to send email", { + description: await response.text(), + }); + } + } catch (error) { + toast.error(error.message || "Error sending email"); + } + }); + }; + + return ( + <> + {triggerButton ? ( +
setIsOpen(true)}>{triggerButton}
+ ) : ( + + )} + + + + + + Send Email{" "} + + + + + + +
+
+ + +
+
+ + + setSendForm({ ...sendForm, to: e.target.value }) + } + placeholder="recipient@example.com" + className="mt-1" + /> +
+
+ + + setSendForm({ ...sendForm, subject: e.target.value }) + } + placeholder="Enter subject" + className="mt-1" + /> +
+
+ + setSendForm({ ...sendForm, html: value })} + className="mt-1 h-40 rounded-lg" + theme="snow" + placeholder="Enter your message" + /> +
+
+ + + + + + +
+
+ + ); +} diff --git a/config/dashboard.ts b/config/dashboard.ts index 0cbc047..24f872c 100644 --- a/config/dashboard.ts +++ b/config/dashboard.ts @@ -9,9 +9,9 @@ export const sidebarLinks: SidebarNavItem[] = [ title: "MENU", items: [ { href: "/dashboard", icon: "dashboard", title: "Dashboard" }, - { href: "/dashboard/records", icon: "globeLock", title: "DNS Records" }, { href: "/dashboard/urls", icon: "link", title: "Short Urls" }, { href: "/emails", icon: "mail", title: "Emails" }, + { href: "/dashboard/records", icon: "globeLock", title: "DNS Records" }, ], }, { diff --git a/lib/enums.ts b/lib/enums.ts index 66da8dd..e4b1070 100644 --- a/lib/enums.ts +++ b/lib/enums.ts @@ -3,6 +3,14 @@ export const EXPIRATION_ENUMS = [ value: "-1", label: "Never", }, + { + value: "10", // 10s + label: "10s", + }, + { + value: "60", // 1 min + label: "60s", + }, { value: "600", // 10 min label: "10min", @@ -200,6 +208,64 @@ export const reservedAddressSuffix = [ "system", "noreply", "no-reply", + "info", + "contact", + "help", + "hello", + "hi", + "inquiries", + "feedback", + "suggestions", + "service", + "customerservice", + "supportteam", + "care", + "assistance", + "complaints", + "sales", + "marketing", + "business", + "partnerships", + "advertising", + "promo", + "deals", + "accounts", + "payment", + "finance", + "invoicing", + "refunds", + "subscriptions", + "webmaster", + "postmaster", + "hostmaster", + "tech", + "it", + "ops", + "dev", + "developer", + "engineering", + "privacy", + "abuse", + "legal", + "compliance", + "trust", + "fraud", + "report", + "news", + "updates", + "alerts", + "notifications", + "welcome", + "verify", + "confirmation", + "team", + "staff", + "hr", + "jobs", + "careers", + "press", + "media", + "events", ]; export const LOGS_LIMITEs_ENUMS = [ diff --git a/public/sw.js.map b/public/sw.js.map index 26f19d7..9daf208 100644 --- a/public/sw.js.map +++ b/public/sw.js.map @@ -1 +1 @@ -{"version":3,"file":"sw.js","sources":["../../../../../../private/var/folders/9b/3qmyp8zd2xvdspdrp149fyg00000gn/T/84bb8fd07ab0c33a97ed8bd52d078bc2/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-routing@6.6.0/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-core@6.6.0/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"sw.js","sources":["../../../../../../private/var/folders/9b/3qmyp8zd2xvdspdrp149fyg00000gn/T/fe0e9c0eb870f87d2504317056344005/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-routing@6.6.0/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-core@6.6.0/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"} \ No newline at end of file