Skip to content

Commit

Permalink
Send create/edit request to backend
Browse files Browse the repository at this point in the history
  • Loading branch information
robines committed Oct 27, 2024
1 parent 8b7b513 commit eedfb97
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useTranslation } from 'react-i18next';
import { useLoaderData } from 'react-router-dom';
import { useRouteLoaderData } from 'react-router-dom';
import { AdminPageLayout } from '~/PagesAdmin/AdminPageLayout/AdminPageLayout';
import { RoleForm } from '~/PagesAdmin/RoleFormAdminPage/components';
import { KEY } from '~/i18n/constants';
Expand All @@ -8,7 +8,7 @@ import { lowerCapitalize } from '~/utils';

export function RoleFormAdminPage() {
const { t } = useTranslation();
const data = useLoaderData() as RoleLoader | undefined;
const data = useRouteLoaderData('role') as RoleLoader | undefined;

const title = lowerCapitalize(`${t(data?.role ? KEY.common_edit : KEY.common_create)} ${t(KEY.common_role)}`);
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { useQuery } from '@tanstack/react-query';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useMemo } from 'react';
import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { toast } from 'react-toastify';
import { z } from 'zod';
import {
Alert,
Expand All @@ -18,20 +19,22 @@ import {
} from '~/Components';
import type { DropDownOption } from '~/Components/Dropdown/Dropdown';
import { MultiSelect } from '~/Components/MultiSelect';
import { getPermissions } from '~/api';
import { createRole, editRole, getPermissions } from '~/api';
import type { RoleDto } from '~/dto';
import { KEY } from '~/i18n/constants';
import { ROLE_CONTENT_TYPE } from '~/schema/role';
import { ROLE_CONTENT_TYPE, ROLE_NAME } from '~/schema/role';
import styles from './RoleForm.module.scss';

const schema = z.object({
name: z.string(),
name: ROLE_NAME,
permissions: z.array(z.number()),
content_type: ROLE_CONTENT_TYPE,
content_type: ROLE_CONTENT_TYPE.nullish(),
});

type SchemaType = z.infer<typeof schema>;

type ContentTypeSchemaType = z.infer<typeof ROLE_CONTENT_TYPE>;

type Props = {
role?: RoleDto;
};
Expand All @@ -48,6 +51,22 @@ export function RoleForm({ role }: Props) {
queryFn: getPermissions,
});

const edit = useMutation({
mutationFn: editRole,
onSuccess: () => {
toast.success(t(KEY.common_save_successful));
},
});

const create = useMutation({
mutationFn: createRole,
onSuccess: () => {
toast.success(t(KEY.common_creation_successful));
},
});

const isPending = edit.isPending || create.isPending;

const permissionOptions = useMemo<DropDownOption<number>[]>(() => {
if (!allPermissions) {
return [];
Expand All @@ -74,27 +93,30 @@ export function RoleForm({ role }: Props) {
defaultValues: {
name: role?.name ?? '',
permissions: role?.permissions ?? [],
content_type: (role?.content_type ?? '') as z.infer<typeof ROLE_CONTENT_TYPE>,
content_type: (role?.content_type ?? '') as ContentTypeSchemaType,
},
});

function onSubmit(values: SchemaType) {
console.log(values);
if (role) {
edit.mutate({ id: role.id, ...values });
} else {
create.mutate(values);
}
}

const contentTypeLabels: Record<z.infer<typeof ROLE_CONTENT_TYPE>, string> = {
const contentTypeLabels: Record<ContentTypeSchemaType, string> = {
'': t(KEY.common_any),
Organization: t(KEY.recruitment_organization),
Gang: t(KEY.common_gang),
Section: t(KEY.common_section),
organization: t(KEY.recruitment_organization),
gang: t(KEY.common_gang),
section: t(KEY.common_section),
};

const contentTypeOptions: DropDownOption<z.infer<typeof ROLE_CONTENT_TYPE>>[] = ROLE_CONTENT_TYPE.options.map(
(ct) => ({
value: ct,
label: contentTypeLabels[ct],
}),
);
const contentTypeOptions: DropDownOption<ContentTypeSchemaType>[] = ROLE_CONTENT_TYPE.options.map((ct) => ({
value: ct,
label: contentTypeLabels[ct],
}));

return (
<Form {...form}>
Expand All @@ -105,7 +127,7 @@ export function RoleForm({ role }: Props) {
<FormItem>
<FormLabel>{t(KEY.common_name)}</FormLabel>
<FormControl>
<Input {...field} />
<Input type="text" disabled={isLoading || isPending} {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -117,7 +139,7 @@ export function RoleForm({ role }: Props) {
<FormItem>
<FormLabel>{t(KEY.role_content_type)}</FormLabel>
<FormControl>
<Dropdown options={contentTypeOptions} {...field} />
<Dropdown options={contentTypeOptions} disabled={isLoading || isPending} {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -143,7 +165,7 @@ export function RoleForm({ role }: Props) {
/>

<div className={styles.action_row}>
<Button type="submit" theme="green">
<Button type="submit" theme="green" disabled={isLoading || isPending}>
{t(KEY.common_save)}
</Button>
</div>
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,19 @@ export async function getGang(id: string | number): Promise<GangDto> {
return response.data;
}

export async function createRole(data: Partial<RoleDto>): Promise<RoleDto> {
const url = BACKEND_DOMAIN + reverse({ pattern: ROUTES.backend.samfundet__role_list });
const response = await axios.post<RoleDto>(url, data, { withCredentials: true });
return response.data;
}

export async function editRole(data: RoleDto): Promise<RoleDto> {
const url = BACKEND_DOMAIN + reverse({ pattern: ROUTES.backend.samfundet__role_detail, urlParams: { pk: data.id } });
const response = await axios.put<RoleDto>(url, data, { withCredentials: true });

return response.data;
}

export async function getRoles(): Promise<RoleDto[]> {
const url = BACKEND_DOMAIN + reverse({ pattern: ROUTES.backend.samfundet__role_list });
const response = await axios.get<RoleDto[]>(url, { withCredentials: true });
Expand Down
1 change: 1 addition & 0 deletions frontend/src/router/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ export const router = createBrowserRouter(
}}
/>
<Route
id="role"
element={<Outlet />}
loader={roleLoader}
handle={{
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/schema/role.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { z } from 'zod';

const contentTypes = ['', 'Organization', 'Gang', 'Section'] as const;
export const ROLE_NAME = z.string().min(1);

const contentTypes = ['', 'organization', 'gang', 'section'] as const;

export const ROLE_CONTENT_TYPE = z.enum(contentTypes);

0 comments on commit eedfb97

Please sign in to comment.