refactor: enhance parental control features and improve device blocking logic 🔨

This commit is contained in:
2025-07-02 23:29:40 +05:00
parent 40bf8413f8
commit c90b003167
7 changed files with 229 additions and 192 deletions

View File

@ -3,6 +3,7 @@
import { revalidatePath } from "next/cache";
import { getServerSession } from "next-auth";
import { authOptions } from "@/app/auth";
import { BlockDeviceFormState } from "@/components/block-device-dialog";
import type { AddDeviceFormState, initialState } from "@/components/user/add-device-dialog";
import type { ApiError, ApiResponse, Device } from "@/lib/backend-types";
import { checkSession } from "@/utils/session";
@ -114,33 +115,77 @@ export async function addDeviceAction(
}
}
export async function blockDevice({
deviceId,
reason_for_blocking,
blocked_by,
}: {
deviceId: string;
reason_for_blocking: string;
blocked_by: "ADMIN" | "PARENT";
}) {
console.log("Blocking device:", deviceId, reason_for_blocking, blocked_by);
const session = await getServerSession(authOptions);
const response = await fetch(
`${process.env.SARLINK_API_BASE_URL}/api/devices/${deviceId}/block/`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Token ${session?.apiToken}`,
export async function blockDeviceAction(
prevState: BlockDeviceFormState,
formData: FormData
): Promise<BlockDeviceFormState> {
const deviceId = formData.get("deviceId") as string;
const reason_for_blocking = formData.get("reason_for_blocking") as string;
const action = formData.get("action") as "block" | "unblock" | "simple-block";
const blocked_by = formData.get("blocked_by") as "ADMIN" | "PARENT";
try {
const session = await getServerSession(authOptions);
if (!session?.apiToken) {
return {
success: false,
message: "Authentication required.",
fieldErrors: {},
payload: formData
};
}
// Validation only for admin block with reason
if (action === "block" && session?.user?.is_superuser && (!reason_for_blocking || reason_for_blocking.trim().length < 5)) {
return {
success: false,
message: "Reason for blocking is required and must be at least 5 characters.",
fieldErrors: {
reason_for_blocking: ["Reason is required and must be at least 5 characters."]
},
payload: formData
};
}
const isBlocking = action === "block" || action === "simple-block";
const response = await fetch(
`${process.env.SARLINK_API_BASE_URL}/api/devices/${deviceId}/block/`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Token ${session.apiToken}`,
},
body: JSON.stringify({
blocked: isBlocking,
reason_for_blocking: session?.user?.is_superuser
? reason_for_blocking || (action === "simple-block" ? "Blocked by admin" : "")
: isBlocking ? "Blocked by parent" : "",
blocked_by: session?.user?.is_superuser ? blocked_by : "PARENT",
}),
},
body: JSON.stringify({
blocked: true,
reason_for_blocking: session?.user?.is_superuser
? reason_for_blocking
: "Blocked by parent",
blocked_by: session?.user?.is_superuser ? "ADMIN" : "PARENT",
}),
},
);
return handleApiResponse<Device>(response, "blockDevice");
}
);
const result = await handleApiResponse<Device>(response, "blockDeviceAction");
revalidatePath("/devices");
revalidatePath("/parental-control");
return {
success: true,
message: isBlocking ? "Device blocked successfully!" : "Device unblocked successfully!",
fieldErrors: {},
payload: formData
};
} catch (error: unknown) {
console.error("Block Device Action Error:", error);
return {
success: false,
message: (error as ApiError).message || "An unexpected error occurred.",
fieldErrors: {},
payload: formData
};
}
}