Skip to content

Commit

Permalink
feat: add settings page
Browse files Browse the repository at this point in the history
  • Loading branch information
sina-saeedi committed Nov 19, 2024
1 parent a9b2eb9 commit 1577eb8
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 2 deletions.
15 changes: 13 additions & 2 deletions frontend/src/app/(dashboard)/dashboard/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import {Metadata} from "next";
import {Stack} from "@mantine/core";
import {Stack, Paper} from "@mantine/core";
import {DashboardBreadcrumbs} from "@/features/dashboard/components/breadcrumbs";
import {AppSettingForm} from "@/features/dashboard/app-setting-form";
import {fetchConfigs} from "@/dal";

const PAGE_TITLE = "تنظیمات";

export const metadata: Metadata = {
title: PAGE_TITLE,
};

function SettingsPage() {
async function SettingsPage() {
const config = await fetchConfigs();

return (
<Stack>
<DashboardBreadcrumbs
Expand All @@ -18,6 +22,13 @@ function SettingsPage() {
},
]}
/>
<Paper p="lg" withBorder>
<AppSettingForm
config={{
userDefaultRoles: config.user_default_roles.join(""),
}}
/>
</Paper>
</Stack>
);
}
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/dal/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ export async function fetchConfigs() {
const response = await apiClient.get("dashboard/config");
return response.data;
}

export async function updateConfigs(data: any) {
return await apiClient.put("dashboard/config", data);
}
1 change: 1 addition & 0 deletions frontend/src/dal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export * from "./files";
export * from "./users";
export * from "./permissions";
export * from "./password";
export * from "./config";
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use server";
import {revalidatePath} from "next/cache";
import {updateConfigs, AxiosError} from "@/dal";
import {convertFormDataActionToObject} from "@/lib/transformers";
import {APP_PATHS} from "@/lib/app-paths";

type FormState = {
success: boolean;
fieldErrors?: Record<string, string>;
};

export async function updateSettingAction(
formState: FormState,
formData: FormData,
): Promise<FormState> {
try {
const data = convertFormDataActionToObject(formData);
if (typeof data.user_default_roles === "string") {
data.user_default_roles = data.user_default_roles.split(",");
}
await updateConfigs(data);
} catch (error) {
if (error instanceof AxiosError && error.status === 400) {
return {
success: false,
fieldErrors: error.response?.data.errors,
};
}
return {
success: false,
};
}

revalidatePath(APP_PATHS.dashboard.settings);
return {
success: true,
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use client";
import {useFormState} from "react-dom";
import {Group, Stack, Textarea} from "@mantine/core";
import {FormButton} from "@/components/form-button";
import {updateSettingAction} from "../actions/update-setting";

type Props = {
config: {
userDefaultRoles: string[];
};
};

export function AppSettingForm({config}: Props) {
const [state, dispatch] = useFormState(updateSettingAction, {success: false});

return (
<form action={dispatch}>
<Stack>
<Textarea
name="user_default_roles"
label="نقش پیشفرض کاربران"
rows={4}
defaultValue={config.userDefaultRoles}
dir="ltr"
styles={{
input: {
textAlign: "left",
},
}}
error={state.fieldErrors?.user_default_roles || ""}
/>
<Group justify="flex-end" mt="md">
<FormButton>بروزرسانی</FormButton>
</Group>
</Stack>
</form>
);
}
1 change: 1 addition & 0 deletions frontend/src/features/dashboard/app-setting-form/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {AppSettingForm} from "./components/app-setting-form";
12 changes: 12 additions & 0 deletions frontend/src/lib/transformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,15 @@ export function axiosToFetchResponse(
headers: headersObj,
});
}

export function convertFormDataActionToObject(formData: FormData) {
const object: Record<string, string | string[]> = {};

formData.forEach((value, key) => {
if (value.toString() && key.includes("$") === false) {
object[key] = value.toString();
}
});

return object;
}

0 comments on commit 1577eb8

Please sign in to comment.