diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx
index 2f1eeb3..ba8adb2 100644
--- a/app/(auth)/login/page.tsx
+++ b/app/(auth)/login/page.tsx
@@ -41,12 +41,21 @@ export default function LoginPage() {
+ By clicking continue, you agree to our{" "}
- Don't have an account? Sign Up
+ Terms of Service
+ {" "}
+ and{" "}
+
+ Privacy Policy
+ .
diff --git a/app/(protected)/dashboard/record-list.tsx b/app/(protected)/dashboard/record-list.tsx
index 97d9bbd..914ca72 100644
--- a/app/(protected)/dashboard/record-list.tsx
+++ b/app/(protected)/dashboard/record-list.tsx
@@ -4,8 +4,8 @@ import { useState } from "react";
import Link from "next/link";
import { UserRecordFormData } from "@/actions/cloudflare-dns-record";
import { User } from "@prisma/client";
-import { ArrowUpRight } from "lucide-react";
-import useSWR from "swr";
+import { ArrowUpRight, DotSquareIcon, RefreshCwIcon } from "lucide-react";
+import useSWR, { useSWRConfig } from "swr";
import { TTL_ENUMS } from "@/lib/cloudflare";
import { fetcher } from "@/lib/utils";
@@ -66,6 +66,7 @@ export default function UserRecordsList({ user }: RecordListProps) {
const [currentEditRecord, setCurrentEditRecord] =
useState(null);
+ const { mutate } = useSWRConfig();
const { data, error, isLoading } = useSWR(
"/api/record",
fetcher,
@@ -74,6 +75,10 @@ export default function UserRecordsList({ user }: RecordListProps) {
},
);
+ const handleRefresh = () => {
+ mutate("/api/record", undefined);
+ };
+
return (
<>
@@ -84,18 +89,31 @@ export default function UserRecordsList({ user }: RecordListProps) {
All Dns Records
-
+
+
+
+
{isShowForm && (
@@ -105,6 +123,7 @@ export default function UserRecordsList({ user }: RecordListProps) {
setShowForm={setShowForm}
type={formType}
initData={currentEditRecord}
+ onRefresh={handleRefresh}
/>
)}
@@ -179,7 +198,18 @@ export default function UserRecordsList({ user }: RecordListProps) {
You don't have any record yet. Start creating record.
-
+
)}
diff --git a/app/api/record/add/route.ts b/app/api/record/add/route.ts
index 90dbdae..c903d85 100644
--- a/app/api/record/add/route.ts
+++ b/app/api/record/add/route.ts
@@ -7,11 +7,14 @@ import {
import { env } from "@/env.mjs";
import { createDNSRecord } from "@/lib/cloudflare";
import { getCurrentUser } from "@/lib/session";
+import { checkUserStatus } from "@/lib/user";
import { generateSecret } from "@/lib/utils";
export async function POST(req: Request) {
try {
- const user = await getCurrentUser();
+ const user = checkUserStatus(await getCurrentUser());
+ if (user instanceof Response) return user;
+
const { records } = await req.json();
const {
CLOUDFLARE_ZONE_ID,
@@ -20,13 +23,6 @@ export async function POST(req: Request) {
NEXT_PUBLIC_FREE_RECORD_QUOTA,
} = env;
- if (!user?.id) {
- return Response.json("Unauthorized", {
- status: 401,
- statusText: "Unauthorized",
- });
- }
-
if (!CLOUDFLARE_ZONE_ID || !CLOUDFLARE_API_KEY || !CLOUDFLARE_EMAIL) {
return Response.json("API keyćzone iD and email are required", {
status: 400,
@@ -106,9 +102,9 @@ export async function POST(req: Request) {
}
} catch (error) {
console.error(error);
- return Response.json(error, {
- status: 500,
- statusText: "Server error",
+ return Response.json(error?.statusText || error, {
+ status: error?.status || 500,
+ statusText: error?.statusText || "Server error",
});
}
}
diff --git a/app/api/record/delete/route.ts b/app/api/record/delete/route.ts
index 65e700a..439600e 100644
--- a/app/api/record/delete/route.ts
+++ b/app/api/record/delete/route.ts
@@ -1,28 +1,38 @@
import { deleteUserRecord } from "@/actions/cloudflare-dns-record";
import { env } from "@/env.mjs";
+import { deleteDNSRecord } from "@/lib/cloudflare";
import { getCurrentUser } from "@/lib/session";
+import { checkUserStatus } from "@/lib/user";
export async function POST(req: Request) {
try {
- const user = await getCurrentUser();
- if (!user?.id) {
- return Response.json("Unauthorized", {
- status: 401,
- statusText: "Unauthorized",
- });
- }
+ const user = checkUserStatus(await getCurrentUser());
+ if (user instanceof Response) return user;
const { record_id, zone_id, active } = await req.json();
const { CLOUDFLARE_ZONE_ID, CLOUDFLARE_API_KEY, CLOUDFLARE_EMAIL } = env;
- await deleteUserRecord(user.id, record_id, zone_id, active);
- // await
+ // Delete cf dns record first.
+ const res = await deleteDNSRecord(
+ CLOUDFLARE_ZONE_ID,
+ CLOUDFLARE_API_KEY,
+ CLOUDFLARE_EMAIL,
+ record_id,
+ );
+ if (res && res.result?.id) {
+ // Then delete user record.
+ await deleteUserRecord(user.id, record_id, zone_id, active);
+ return Response.json({
+ status: 200,
+ statusText: "success",
+ });
+ }
} catch (error) {
console.error(error);
- return Response.json(error, {
- status: 500,
- statusText: "Server error",
+ return Response.json(error?.statusText || error, {
+ status: error.status || 500,
+ statusText: error.statusText || "Server error",
});
}
}
diff --git a/app/api/record/route.ts b/app/api/record/route.ts
index 7f94fc0..a074261 100644
--- a/app/api/record/route.ts
+++ b/app/api/record/route.ts
@@ -2,26 +2,21 @@ import { getUserRecords } from "@/actions/cloudflare-dns-record";
import { env } from "@/env.mjs";
import { getCurrentUser } from "@/lib/session";
+import { checkUserStatus } from "@/lib/user";
export async function GET(req: Request) {
try {
- const user = await getCurrentUser();
- if (!user?.id) {
- return Response.json("Unauthorized", {
- status: 401,
- statusText: "Unauthorized",
- });
- }
-
+ const user = checkUserStatus(await getCurrentUser());
+ if (user instanceof Response) return user;
// const { CLOUDFLARE_ZONE_ID, CLOUDFLARE_API_KEY, CLOUDFLARE_EMAIL } = env;
const user_records = await getUserRecords(user.id, 1);
return Response.json(user_records);
} catch (error) {
- return Response.json(error, {
- status: 500,
- statusText: "Server error",
+ return Response.json(error?.statusText || error, {
+ status: error.status || 500,
+ statusText: error.statusText || "Server error",
});
}
}
diff --git a/app/api/record/update/route.ts b/app/api/record/update/route.ts
index fb573e3..d4957bc 100644
--- a/app/api/record/update/route.ts
+++ b/app/api/record/update/route.ts
@@ -1,8 +1,10 @@
import { env } from "@/env.mjs";
import { getCurrentUser } from "@/lib/session";
+import { checkUserStatus } from "@/lib/user";
export async function POST(req: Request) {
try {
+ const user = checkUserStatus(await getCurrentUser());
} catch (error) {
console.error(error);
return Response.json(error, {
diff --git a/components/forms/record-form.tsx b/components/forms/record-form.tsx
index ab3710d..94770c3 100644
--- a/components/forms/record-form.tsx
+++ b/components/forms/record-form.tsx
@@ -38,6 +38,7 @@ export interface RecordFormProps {
setShowForm: Dispatch>;
type: FormType;
initData?: UserRecordFormData | null;
+ onRefresh: () => void;
}
export function RecordForm({
@@ -46,8 +47,10 @@ export function RecordForm({
setShowForm,
type,
initData,
+ onRefresh,
}: RecordFormProps) {
const [isPending, startTransition] = useTransition();
+ const [isDeleting, startDeleteTransition] = useTransition();
const {
handleSubmit,
@@ -66,68 +69,79 @@ export function RecordForm({
});
const onSubmit = handleSubmit((data) => {
- startTransition(async () => {
- if (type === "add") {
- handleCreateRecord(data);
- } else if (type === "edit") {
- handleUpdateRecord(data);
- }
- });
+ if (type === "add") {
+ handleCreateRecord(data);
+ } else if (type === "edit") {
+ handleUpdateRecord(data);
+ }
});
const handleCreateRecord = async (data: CreateDNSRecord) => {
- const response = await fetch("/api/record/add", {
- method: "POST",
- body: JSON.stringify({
- records: [data],
- }),
- });
- if (!response.ok || response.status !== 200) {
- toast.error("Created Failed!", {
- description: response.statusText,
+ startTransition(async () => {
+ const response = await fetch("/api/record/add", {
+ method: "POST",
+ body: JSON.stringify({
+ records: [data],
+ }),
});
- } else {
- const res = await response.json();
- toast.success(`Created successfully!`);
- setShowForm(false);
- }
+ if (!response.ok || response.status !== 200) {
+ toast.error("Created Failed!", {
+ description: response.statusText,
+ });
+ } else {
+ const res = await response.json();
+ toast.success(`Created successfully!`);
+ setShowForm(false);
+ onRefresh();
+ }
+ });
};
const handleUpdateRecord = async (data: CreateDNSRecord) => {
- const response = await fetch("/api/record/update", {
- method: "POST",
- body: JSON.stringify({
- records: [data],
- }),
+ startTransition(async () => {
+ if (type === "edit") {
+ const response = await fetch("/api/record/update", {
+ method: "POST",
+ body: JSON.stringify({
+ records: [data],
+ }),
+ });
+ if (!response.ok || response.status !== 200) {
+ toast.error("Update Failed", {
+ description: response.statusText,
+ });
+ } else {
+ const res = await response.json();
+ toast.success(`Update successfully!`);
+ setShowForm(false);
+ onRefresh();
+ }
+ }
});
- if (!response.ok || response.status !== 200) {
- toast.error("Update Failed", {
- description: response.statusText,
- });
- } else {
- const res = await response.json();
- toast.success(`Update successfully!`);
- setShowForm(false);
- }
};
const handleDeleteRecord = async () => {
- const response = await fetch("/api/record/delete", {
- method: "POST",
- body: JSON.stringify({
- record_id: initData?.record_id,
- zone_id: initData?.zone_id,
- active: initData?.active,
- }),
- });
- if (!response.ok || response.status !== 200) {
- toast.error("Delete Failed", {
- description: response.statusText,
+ if (type === "edit") {
+ startTransition(async () => {
+ const response = await fetch("/api/record/delete", {
+ method: "POST",
+ body: JSON.stringify({
+ record_id: initData?.record_id,
+ zone_id: initData?.zone_id,
+ active: initData?.active,
+ }),
+ });
+ if (!response.ok || response.status !== 200) {
+ toast.error("Delete Failed", {
+ description: response.statusText,
+ });
+ } else {
+ await response.json();
+ toast.success(`Success`);
+ setShowForm(false);
+ onRefresh();
+ }
});
- } else {
- await response.json();
- toast.success(`Delete successfully!`);
- setShowForm(false);
}
};
@@ -261,16 +275,22 @@ export function RecordForm({
{type === "edit" && (
)}