product report list + detail report

This commit is contained in:
hamid zarghami
2025-09-29 16:04:57 +03:30
parent 25148282ae
commit 9ec483383e
16 changed files with 580 additions and 10 deletions
+87
View File
@@ -0,0 +1,87 @@
import { useFormik } from 'formik'
import { type FC } from 'react'
import type { CreateFineType } from './types/Types'
import * as Yup from 'yup'
import { useCreateFine } from './hooks/usePaymentData'
import { useNavigate } from 'react-router-dom'
import Input from '../../components/Input'
import Button from '../../components/Button'
import { TickCircle } from 'iconsax-react'
import { toast } from 'react-toastify'
import { extractErrorMessage } from '@/helpers/utils'
import { Pages } from '@/config/Pages'
const CreateFine: FC = () => {
const navigate = useNavigate()
const createFineMutation = useCreateFine()
const formik = useFormik<CreateFineType>({
initialValues: {
fine_percentage: 0,
title: ''
},
validationSchema: Yup.object({
fine_percentage: Yup.number().required('درصد جریمه الزامی است').min(0, 'درصد جریمه نمی‌تواند منفی باشد'),
title: Yup.string().required('عنوان جریمه الزامی است'),
}),
onSubmit: (values) => {
createFineMutation.mutate(values, {
onSuccess: () => {
toast.success('قانون جریمه با موفقیت ایجاد شد')
navigate(Pages.financial.fines)
},
onError: (error) => {
toast.error(extractErrorMessage(error))
}
})
}
})
return (
<div className='mt-4'>
<div className='flex justify-between items-center'>
<div className='flex items-center gap-3'>
<h1>ساخت قانون جریمه جدید</h1>
</div>
<div>
<Button
className='px-6'
onClick={() => formik.handleSubmit()}
isLoading={createFineMutation.isPending}
disabled={!formik.isValid || createFineMutation.isPending}
>
<div className='flex gap-2 items-center'>
<TickCircle size={16} color='#fff' />
<div>ثبت قانون جریمه</div>
</div>
</Button>
</div>
</div>
<div className='flex gap-6 xl:mt-8 mt-6'>
<div className='flex-1 text-sm bg-white py-8 xl:px-10 px-6 rounded-3xl'>
<h2 className='text-lg font-medium mb-6'>اطلاعات قانون جریمه</h2>
<div className='space-y-6'>
<Input
label='عنوان جریمه'
placeholder='مثال: جریمه تأخیر پرداخت'
{...formik.getFieldProps('title')}
error_text={formik.touched.title && formik.errors.title ? formik.errors.title : ''}
/>
<Input
label='درصد جریمه'
type='number'
placeholder='مثال: 5'
{...formik.getFieldProps('fine_percentage')}
error_text={formik.touched.fine_percentage && formik.errors.fine_percentage ? formik.errors.fine_percentage : ''}
/>
</div>
</div>
</div>
</div>
)
}
export default CreateFine
+10
View File
@@ -0,0 +1,10 @@
import { type FC } from 'react'
const Fines: FC = () => {
return (
<div>Fines</div>
)
}
export default Fines
+14 -1
View File
@@ -1,5 +1,5 @@
import * as api from "../service/PaymentService";
import { useQuery } from "@tanstack/react-query";
import { useMutation, useQuery } from "@tanstack/react-query";
export const useGetPayments = (page: number = 1) => {
return useQuery({
@@ -7,3 +7,16 @@ export const useGetPayments = (page: number = 1) => {
queryFn: () => api.getPayments(page),
});
};
export const useCreateFine = () => {
return useMutation({
mutationFn: api.createFine,
});
};
export const useGetFines = () => {
return useQuery({
queryKey: ["fines"],
queryFn: api.getFines,
});
};
+11 -1
View File
@@ -1,5 +1,5 @@
import axios from "../../../config/axios";
import type { PaymentResponse } from "../types/Types";
import type { CreateFineType, PaymentResponse } from "../types/Types";
export const getPayments = async (
page: number = 1
@@ -7,3 +7,13 @@ export const getPayments = async (
const { data } = await axios.get(`/admin/financial/payments?page=${page}`);
return data;
};
export const createFine = async (params: CreateFineType) => {
const { data } = await axios.post(`/admin/fine/rule`, params);
return data;
};
export const getFines = async () => {
const { data } = await axios.get(`/admin/fine/fines`);
return data;
};
+5
View File
@@ -49,3 +49,8 @@ export interface Pager {
prevPage: boolean | null;
nextPage: string | null;
}
export type CreateFineType = {
title: string;
fine_percentage: number;
};