update category theme

This commit is contained in:
hamid zarghami
2025-11-29 10:00:15 +03:30
parent 4e8068071f
commit a4aaf21803
6 changed files with 171 additions and 2 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ const ThemeList: FC = () => {
<Td text={item.inputType} />
<Td text=''>
<div className='flex gap-2'>
<Link to={`${Pages.products.theme.update}/${item._id}`}>
<Link to={`${Pages.products.theme.update}${item._id}`}>
<Eye size={16} color='#8C90A3' />
</Link>
<TrashWithConfrim
+102
View File
@@ -0,0 +1,102 @@
import { useEffect, type FC } from 'react'
import { useParams } from 'react-router-dom'
import { useGetThemeById, useUpdateTheme } from './hooks/useThemeData'
import PageTitle from '@/components/PageTitle'
import Button from '@/components/Button'
import { TickCircle } from 'iconsax-react'
import Input from '@/components/Input'
import { useFormik } from 'formik'
import * as Yup from 'yup'
import type { CreateThemeType } from './type/Types'
import { toast } from 'react-toastify'
import { extractErrorMessage } from '@/helpers/utils'
import { Pages } from '@/config/Pages'
import { ThemeInputType } from './enum/Enum'
import { useNavigate } from 'react-router-dom'
import Select from '@/components/Select'
const UpdateTheme: FC = () => {
const { id } = useParams<{ id: string }>()
const navigate = useNavigate()
const { data } = useGetThemeById(id!)
const { mutate: updateTheme, isPending } = useUpdateTheme()
const formik = useFormik<CreateThemeType>({
initialValues: {
title: '',
inputType: ThemeInputType.Color,
},
validationSchema: Yup.object({
title: Yup.string().required('عنوان تم الزامی است'),
inputType: Yup.string().required('نوع ورودی تم الزامی است'),
}),
onSubmit: (values) => {
updateTheme({ id: id!, params: values }, {
onSuccess: () => {
toast.success('تم با موفقیت ویرایش شد')
navigate(Pages.products.theme.list)
},
onError: (error) => {
toast.error(extractErrorMessage(error))
}
})
},
})
useEffect(() => {
if (data?.results?.data) {
formik.setValues({
title: data?.results?.data?.title,
inputType: data?.results?.data?.inputType,
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data])
return (
<div>
<PageTitle title1='ویرایش تم' />
<div className='bg-white p-8 rounded-4xl'>
<div>
<Input
label='عنوان تم'
placeholder='عنوان تم را وارد کنید'
{...formik.getFieldProps('title')}
error_text={formik.touched.title && formik.errors.title ? formik.errors.title : ''}
/>
</div>
<div className='mt-5'>
<Select
label='نوع ورودی تم'
placeholder='انتخاب نوع ورودی تم'
value={formik.values.inputType}
onChange={(e) => formik.setFieldValue('inputType', e.target.value)}
items={[
{ value: ThemeInputType.Color, label: 'رنگ' },
{ value: ThemeInputType.Text, label: 'متن' },
]}
error_text={formik.touched.inputType && formik.errors.inputType ? formik.errors.inputType : ''}
/>
</div>
<div className='mt-5 flex justify-end'>
<Button
onClick={() => formik.handleSubmit()}
isLoading={isPending}
disabled={!formik.isValid || isPending}
className='w-fit'
>
<div className='flex gap-2 items-center'>
<TickCircle size={16} color='#fff' />
<div>ذخیره</div>
</div>
</Button>
</div>
</div>
</div>
)
}
export default UpdateTheme
+31
View File
@@ -1,5 +1,6 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import * as api from "../service/ThemeService";
import type { CreateThemeType } from "../type/Types";
export const useGetThemes = () => {
return useQuery({
@@ -17,3 +18,33 @@ export const useCreateTheme = () => {
},
});
};
export const useGetThemeById = (id: string) => {
return useQuery({
queryKey: ["theme", id],
queryFn: () => api.getThemeById(id),
enabled: !!id,
});
};
export const useUpdateTheme = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, params }: { id: string; params: CreateThemeType }) =>
api.updateTheme(id, params),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["theme"] });
queryClient.invalidateQueries({ queryKey: ["themes"] });
},
});
};
export const useDeleteTheme = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: api.deleteTheme,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["themes"] });
},
});
};
+27 -1
View File
@@ -1,5 +1,9 @@
import axios from "@/config/axios";
import type { CreateThemeType, GetThemesResponseType } from "../type/Types";
import type {
CreateThemeType,
GetThemesResponseType,
GetThemeByIdResponseType,
} from "../type/Types";
export const getThemes = async (): Promise<GetThemesResponseType> => {
const { data } = await axios.get<GetThemesResponseType>(
@@ -12,3 +16,25 @@ export const createTheme = async (params: CreateThemeType) => {
const { data } = await axios.post("/admin/category/theme", params);
return data;
};
export const getThemeById = async (
id: string
): Promise<GetThemeByIdResponseType> => {
const { data } = await axios.get<GetThemeByIdResponseType>(
`/admin/category/theme/${id}`
);
return data;
};
export const updateTheme = async (id: string, params: CreateThemeType) => {
const { data } = await axios.put(`/admin/category/theme`, {
themeId: id,
...params,
});
return data;
};
export const deleteTheme = async (id: string) => {
const { data } = await axios.delete(`/admin/category/theme/${id}`);
return data;
};
+8
View File
@@ -20,3 +20,11 @@ export type GetThemesResponseType = {
data: ThemeType[];
};
};
export type GetThemeByIdResponseType = {
status: number;
success: boolean;
results: {
data: ThemeType;
};
};
+2
View File
@@ -85,6 +85,7 @@ import ReturnDetails from '@/pages/orders/ReturnDetails'
import Cancels from '@/pages/orders/Cancels'
import ThemeList from '@/pages/theme/List'
import CreateTheme from '@/pages/theme/Create'
import UpdateTheme from '@/pages/theme/Update'
const MainRouter: FC = () => {
const { hasSubMenu } = useSharedStore()
@@ -208,6 +209,7 @@ const MainRouter: FC = () => {
<Route path={Pages.products.theme.list} element={<ThemeList />} />
<Route path={Pages.products.theme.create} element={<CreateTheme />} />
<Route path={`${Pages.products.theme.update}:id`} element={<UpdateTheme />} />
</Routes>
</div>
</div>