feat: implement add device functionality with validation and error handling; refactor related components for improved state management
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 11m49s

This commit is contained in:
2025-06-25 20:10:32 +05:00
parent 406733b360
commit d2b281281f
3 changed files with 115 additions and 102 deletions

View File

@ -1,6 +1,7 @@
"use server";
import { authOptions } from "@/app/auth";
import type { AddDeviceFormState, initialState } from "@/components/user/add-device-dialog";
import type { ApiError, ApiResponse, Device } from "@/lib/backend-types";
import { checkSession } from "@/utils/session";
import { handleApiResponse } from "@/utils/tryCatch";
@ -46,32 +47,63 @@ export async function getDevice({ deviceId }: { deviceId: string }) {
return handleApiResponse<Device>(response, "getDevice");
}
export async function addDevice({
name,
mac,
}: {
name: string;
mac: string;
}) {
type SingleDevice = Pick<Device, "name" | "mac">;
const session = await getServerSession(authOptions);
const response = await fetch(
`${process.env.SARLINK_API_BASE_URL}/api/devices/`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Token ${session?.apiToken}`,
export async function addDeviceAction(
prevState: AddDeviceFormState,
formData: FormData
): Promise<AddDeviceFormState> {
const name = formData.get("name") as string;
const mac_address = formData.get("mac_address") as string;
const errors: typeof initialState.fieldErrors = {};
if (!name || name.length < 2) {
errors.name = ["Device name is required and must be at least 2 characters."];
}
if (!mac_address || !/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/.test(mac_address)) {
errors.mac_address = ["Invalid MAC address format."];
}
if (Object.keys(errors).length > 0) {
return {
message: "Validation failed.",
fieldErrors: errors,
payload: formData,
};
}
try {
const session = await getServerSession(authOptions);
if (!session?.apiToken) {
return { message: "Authentication required.", fieldErrors: {}, payload: formData };
}
const response = await fetch(
`${process.env.SARLINK_API_BASE_URL}/api/devices/`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Token ${session.apiToken}`,
},
body: JSON.stringify({
name: name,
mac: mac_address,
registered: true,
}),
},
body: JSON.stringify({
name: name,
mac: mac,
registered: true,
}),
},
);
revalidatePath("/devices");
return handleApiResponse<SingleDevice>(response, "addDevice");
);
await handleApiResponse<Device>(response, "addDeviceAction");
revalidatePath("/devices");
return { message: "Device successfully added!", fieldErrors: {}, payload: formData };
} catch (error: unknown) {
console.error("Server Action Error:", error);
return { message: (error as ApiError).message || "An unexpected error occurred.", fieldErrors: {}, payload: formData };
}
}
export async function blockDevice({