admin/src/pages/permissions/permission-form/PermissionFormPage.tsx

165 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
import { usePermission, useCreatePermission, useUpdatePermission } from '../core/_hooks';
import { PermissionFormData } from '../core/_models';
import { Button } from "@/components/ui/Button";
import { Input } from "@/components/ui/Input";
import { ArrowRight } from "lucide-react";
import { FormHeader, PageContainer, Label } from '../../../components/ui/Typography';
const permissionSchema = yup.object({
title: yup.string().required('عنوان الزامی است').min(3, 'عنوان باید حداقل 3 کاراکتر باشد'),
description: yup.string().required('توضیحات الزامی است').min(10, 'توضیحات باید حداقل 10 کاراکتر باشد'),
});
const PermissionFormPage = () => {
const navigate = useNavigate();
const { id } = useParams<{ id: string }>();
const isEdit = !!id;
const { data: permission, isLoading: isLoadingPermission } = usePermission(id || '', isEdit);
const { mutate: createPermission, isPending: isCreating } = useCreatePermission();
const { mutate: updatePermission, isPending: isUpdating } = useUpdatePermission();
const isLoading = isCreating || isUpdating;
const {
register,
handleSubmit,
formState: { errors, isValid },
setValue
} = useForm<PermissionFormData>({
resolver: yupResolver(permissionSchema),
mode: 'onChange',
defaultValues: {
title: '',
description: ''
}
});
// Populate form when editing
useEffect(() => {
if (isEdit && permission) {
setValue('title', permission.title);
setValue('description', permission.description);
}
}, [isEdit, permission, setValue]);
const onSubmit = (data: PermissionFormData) => {
if (isEdit && id) {
updatePermission({
id,
permissionData: {
id: parseInt(id),
title: data.title,
description: data.description
}
}, {
onSuccess: () => {
navigate('/permissions');
}
});
} else {
createPermission({
title: data.title,
description: data.description
}, {
onSuccess: () => {
navigate('/permissions');
}
});
}
};
const handleBack = () => {
navigate('/permissions');
};
if (isEdit && isLoadingPermission) {
return (
<PageContainer>
<div className="space-y-6 animate-pulse">
<div className="h-8 bg-gray-200 dark:bg-gray-700 rounded w-48"></div>
<div className="card p-6 space-y-6">
{[...Array(4)].map((_, i) => (
<div key={i}>
<div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-32 mb-2"></div>
<div className="h-10 bg-gray-200 dark:bg-gray-700 rounded"></div>
</div>
))}
</div>
</div>
</PageContainer>
);
}
return (
<PageContainer>
{/* Header */}
<FormHeader
title={isEdit ? 'ویرایش دسترسی' : 'ایجاد دسترسی جدید'}
subtitle={isEdit ? 'ویرایش اطلاعات دسترسی' : 'اطلاعات دسترسی جدید را وارد کنید'}
backButton={
<Button
variant="secondary"
onClick={handleBack}
className="flex items-center gap-2"
>
<ArrowRight className="h-4 w-4" />
بازگشت
</Button>
}
/>
{/* Form */}
<div className="bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700 rounded-lg p-6">
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
<Input
label="عنوان دسترسی"
{...register('title')}
error={errors.title?.message}
placeholder="مثال: CREATE_USER, DELETE_POST, MANAGE_ADMIN"
/>
<div>
<Label htmlFor="description">
توضیحات
</Label>
<textarea
{...register('description')}
rows={4}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-1 focus:ring-primary-500 dark:bg-gray-700 dark:text-gray-100"
placeholder="توضیح کاملی از این دسترسی ارائه دهید..."
/>
{errors.description && (
<p className="text-red-500 text-sm mt-1">{errors.description.message}</p>
)}
</div>
<div className="flex justify-end space-x-4 space-x-reverse pt-6 border-t border-gray-200 dark:border-gray-600">
<Button
type="button"
variant="secondary"
onClick={handleBack}
disabled={isLoading}
>
انصراف
</Button>
<Button
type="submit"
loading={isLoading}
disabled={!isValid}
>
{isEdit ? 'به‌روزرسانی' : 'ایجاد'}
</Button>
</div>
</form>
</div>
</PageContainer>
);
};
export default PermissionFormPage;