165 lines
6.3 KiB
TypeScript
165 lines
6.3 KiB
TypeScript
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;
|