feat: add send email counter
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
import { getUserSendEmailCount, saveUserSendEmail } from "@/lib/dto/email";
|
||||
import { checkUserStatus } from "@/lib/dto/user";
|
||||
import { resend } from "@/lib/email";
|
||||
import { getCurrentUser } from "@/lib/session";
|
||||
import { isValidEmail } from "@/lib/utils";
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const user = checkUserStatus(await getCurrentUser());
|
||||
if (user instanceof Response) return user;
|
||||
|
||||
const { from, to, subject, html } = await req.json();
|
||||
|
||||
if (!from || !to || !subject || !html) {
|
||||
@@ -27,9 +33,29 @@ export async function POST(req: NextRequest) {
|
||||
return NextResponse.json("Failed to send email", { status: 500 });
|
||||
}
|
||||
|
||||
await saveUserSendEmail(user.id, from, to, subject, html);
|
||||
|
||||
return NextResponse.json("success", { status: 200 });
|
||||
} catch (error) {
|
||||
console.log("Error sending email:", error);
|
||||
return NextResponse.json("Internal server error", { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const user = checkUserStatus(await getCurrentUser());
|
||||
if (user instanceof Response) return user;
|
||||
|
||||
const { searchParams } = new URL(req.url);
|
||||
const all = searchParams.get("all") || "false";
|
||||
|
||||
const count = await getUserSendEmailCount(
|
||||
user.id,
|
||||
user.role === "ADMIN" && all === "true",
|
||||
);
|
||||
return NextResponse.json(count);
|
||||
} catch (error) {
|
||||
return NextResponse.json("Internal server error", { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,14 @@ export default function EmailSidebar({
|
||||
{ dedupingInterval: 5000 },
|
||||
);
|
||||
|
||||
const { data: sendEmails } = useSWR<number>(
|
||||
`/api/email/send?all=${isAdminModel}`,
|
||||
fetcher,
|
||||
{
|
||||
dedupingInterval: 5000,
|
||||
},
|
||||
);
|
||||
|
||||
if (!selectedEmailAddress && data && data.list.length > 0) {
|
||||
onSelectEmail(data.list[0].emailAddress);
|
||||
}
|
||||
@@ -332,7 +340,7 @@ export default function EmailSidebar({
|
||||
</div>
|
||||
|
||||
{/* Sent Emails */}
|
||||
<div className="flex cursor-pointer flex-col items-center gap-1 rounded-md bg-neutral-200 px-1 pb-1 pt-2 transition-colors hover:bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700">
|
||||
<div className="flex cursor-pointer flex-col items-center gap-1 rounded-md bg-neutral-100 px-1 pb-1 pt-2 transition-colors hover:bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700">
|
||||
<div className="flex items-center gap-1">
|
||||
<Icons.send className="size-3" />
|
||||
<p className="line-clamp-1 text-start font-medium">
|
||||
@@ -340,7 +348,7 @@ export default function EmailSidebar({
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-sm font-semibold text-gray-900 dark:text-gray-100">
|
||||
{/* <CountUp count={0} /> */}--
|
||||
<CountUp count={sendEmails || 0} />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -517,3 +517,30 @@ export async function markAllEmailsAsRead(userEmailId: string, userId: string) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function saveUserSendEmail(
|
||||
userId: string,
|
||||
from: string,
|
||||
to: string,
|
||||
subject: string,
|
||||
html: string,
|
||||
) {
|
||||
return prisma.userSendEmail.create({
|
||||
data: {
|
||||
userId,
|
||||
from,
|
||||
to,
|
||||
subject,
|
||||
html,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function getUserSendEmailCount(userId: string, admin: boolean) {
|
||||
if (admin) {
|
||||
return prisma.userSendEmail.count();
|
||||
}
|
||||
return prisma.userSendEmail.count({ where: { userId } });
|
||||
}
|
||||
|
||||
@@ -261,3 +261,20 @@ ON DELETE SET NULL
|
||||
ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "user_urls" ADD COLUMN "password" TEXT NOT NULL DEFAULT '';
|
||||
|
||||
CREATE TABLE "user_send_emails"
|
||||
(
|
||||
"id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
"userId" TEXT NOT NULL,
|
||||
"from" TEXT NOT NULL,
|
||||
"fromName" TEXT DEFAULT '',
|
||||
"to" TEXT NOT NULL,
|
||||
"subject" TEXT DEFAULT 'No Subject',
|
||||
"text" TEXT DEFAULT '',
|
||||
"html" TEXT DEFAULT '',
|
||||
"replyTo" TEXT DEFAULT '',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
);
|
||||
|
||||
CREATE INDEX "user_send_emails_userId_idx" ON "user_send_emails" ("userId");
|
||||
+28
-7
@@ -62,12 +62,13 @@ model User {
|
||||
updatedAt DateTime @default(now()) @map(name: "updated_at")
|
||||
role UserRole @default(USER)
|
||||
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
UserRecord UserRecord[]
|
||||
UserUrl UserUrl[]
|
||||
ScrapeMeta ScrapeMeta[]
|
||||
UserEmail UserEmail[]
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
UserRecord UserRecord[]
|
||||
UserUrl UserUrl[]
|
||||
ScrapeMeta ScrapeMeta[]
|
||||
UserEmail UserEmail[]
|
||||
UserSendEmail UserSendEmail[]
|
||||
|
||||
@@map(name: "users")
|
||||
}
|
||||
@@ -183,7 +184,7 @@ model ScrapeMeta {
|
||||
}
|
||||
|
||||
model ForwardEmail {
|
||||
id String @id @default(uuid()) // 使用 UUID 作为主键
|
||||
id String @id @default(uuid())
|
||||
from String
|
||||
fromName String
|
||||
to String
|
||||
@@ -222,3 +223,23 @@ model UserEmail {
|
||||
|
||||
@@map("user_emails")
|
||||
}
|
||||
|
||||
model UserSendEmail {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
|
||||
from String
|
||||
fromName String? @default("")
|
||||
to String
|
||||
subject String? @default("No Subject")
|
||||
text String? @default("")
|
||||
html String? @default("")
|
||||
replyTo String? @default("")
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@map("user_send_emails")
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user