update theme values + delete theme value

This commit is contained in:
hamid zarghami
2025-11-29 11:08:31 +03:30
parent 04ba8f3203
commit b999a764a6
5 changed files with 200 additions and 15 deletions
+37 -6
View File
@@ -1,18 +1,25 @@
import { type FC, useState } from 'react'
import { useGetThemeValues } from './hooks/useThemeData'
import { useDeleteThemeValue, useGetThemeValues } from './hooks/useThemeData'
import { useParams } from 'react-router-dom'
import PageTitle from '@/components/PageTitle'
import Td from '@/components/Td'
import { Eye, Add } from 'iconsax-react'
import { Edit, Add } from 'iconsax-react'
import TrashWithConfrim from '@/components/TrashWithConfrim'
import { toast } from 'react-toastify'
import Button from '@/components/Button'
import CreateThemeValueModal from './components/CreateThemeValueModal'
import UpdateThemeValueModal from './components/UpdateThemeValueModal'
import type { ThemeValueType } from './type/Types'
import { extractErrorMessage } from '@/helpers/utils'
const Values: FC = () => {
const { id } = useParams()
const { mutate: deleteThemeValue, isPending: isDeletingThemeValue } = useDeleteThemeValue()
const { data, isLoading } = useGetThemeValues(id!)
const [isModalOpen, setIsModalOpen] = useState(false)
const [isUpdateModalOpen, setIsUpdateModalOpen] = useState(false)
const [selectedThemeValue, setSelectedThemeValue] = useState<ThemeValueType | null>(null)
if (isLoading) {
return <div className="flex justify-center items-center h-64">در حال بارگذاری...</div>
@@ -22,7 +29,7 @@ const Values: FC = () => {
return (
<div>
<div className='flex justify-between items-center'>
<div className='flex gap-4 justify-between items-center'>
<PageTitle title1='مقادیر تم' />
<Button
onClick={() => setIsModalOpen(true)}
@@ -69,12 +76,27 @@ const Values: FC = () => {
<Td text={item.value.toString()} />
<Td text=''>
<div className='flex gap-2'>
<Eye size={16} color='#8C90A3' />
<button
onClick={() => {
setSelectedThemeValue(item)
setIsUpdateModalOpen(true)
}}
className='cursor-pointer hover:opacity-70 transition-opacity'
>
<Edit size={16} color='#8C90A3' />
</button>
<TrashWithConfrim
onDelete={() => {
toast.error('این قابلیت در حال توسعه است')
deleteThemeValue(item._id, {
onSuccess: () => {
toast.success('مقدار تم با موفقیت حذف شد')
},
onError: (error) => {
toast.error(extractErrorMessage(error))
}
})
}}
isLoading={false}
isLoading={isDeletingThemeValue}
/>
</div>
</Td>
@@ -100,6 +122,15 @@ const Values: FC = () => {
themeId={id}
/>
)}
<UpdateThemeValueModal
open={isUpdateModalOpen}
close={() => {
setIsUpdateModalOpen(false)
setSelectedThemeValue(null)
}}
themeValue={selectedThemeValue}
/>
</div>
)
}
@@ -0,0 +1,127 @@
import { type FC, useEffect } from 'react'
import { useFormik } from 'formik'
import * as Yup from 'yup'
import DefaulModal from '@/components/DefaulModal'
import Input from '@/components/Input'
import Button from '@/components/Button'
import { useUpdateThemeValue } from '../hooks/useThemeData'
import { extractErrorMessage } from '@/helpers/utils'
import { toast } from 'react-toastify'
import { TickCircle } from 'iconsax-react'
import type { UpdateThemeValueType, ThemeValueType } from '../type/Types'
interface Props {
open: boolean
close: () => void
themeValue: ThemeValueType | null
}
const UpdateThemeValueModal: FC<Props> = ({ open, close, themeValue }) => {
const { mutate: updateThemeValue, isPending } = useUpdateThemeValue()
const formik = useFormik<UpdateThemeValueType>({
initialValues: {
name: '',
value: '',
},
validationSchema: Yup.object({
name: Yup.string().required('نام الزامی است'),
value: Yup.string().required('مقدار الزامی است'),
}),
onSubmit: (values) => {
if (!themeValue?._id) return
updateThemeValue(
{
id: themeValue._id,
params: {
name: values.name,
value: values.value,
},
},
{
onSuccess: () => {
toast.success('مقدار تم با موفقیت به‌روزرسانی شد')
formik.resetForm()
close()
},
onError: (error) => {
toast.error(extractErrorMessage(error))
},
}
)
},
})
useEffect(() => {
if (themeValue && open) {
formik.setValues({
name: themeValue.name,
value: themeValue.value.toString(),
})
}
}, [themeValue, open])
const handleClose = () => {
formik.resetForm()
close()
}
return (
<DefaulModal
open={open}
close={handleClose}
isHeader
title_header="ویرایش مقدار تم"
>
<div className="mt-5 space-y-5 w-[400px]">
<Input
label="نام"
placeholder="نام را وارد کنید"
{...formik.getFieldProps('name')}
error_text={
formik.touched.name && formik.errors.name
? formik.errors.name
: ''
}
/>
<Input
label="مقدار"
placeholder="مقدار را وارد کنید"
{...formik.getFieldProps('value')}
error_text={
formik.touched.value && formik.errors.value
? formik.errors.value
: ''
}
/>
<div className="flex gap-3 pt-3">
<Button
variant="outline"
onClick={handleClose}
disabled={isPending}
className="w-fit"
>
انصراف
</Button>
<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>
</DefaulModal>
)
}
export default UpdateThemeValueModal
+27 -1
View File
@@ -1,6 +1,6 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import * as api from "../service/ThemeService";
import type { CreateThemeType } from "../type/Types";
import type { CreateThemeType, UpdateThemeValueType } from "../type/Types";
export const useGetThemes = () => {
return useQuery({
@@ -66,3 +66,29 @@ export const useCreateThemeValue = () => {
},
});
};
export const useUpdateThemeValue = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({
id,
params,
}: {
id: string;
params: UpdateThemeValueType;
}) => api.updateThemeValue(id, params),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["theme-values"] });
},
});
};
export const useDeleteThemeValue = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: api.deleteThemeValue,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["theme-values"] });
},
});
};
+4 -8
View File
@@ -5,6 +5,7 @@ import type {
GetThemeByIdResponseType,
GetThemeValuesResponseType,
CreateThemeValueType,
UpdateThemeValueType,
} from "../type/Types";
export const getThemes = async (): Promise<GetThemesResponseType> => {
@@ -57,18 +58,13 @@ export const createThemeValue = async (params: CreateThemeValueType) => {
export const updateThemeValue = async (
id: string,
params: CreateThemeValueType
params: UpdateThemeValueType
) => {
const { data } = await axios.put(
`/admin/category/theme-value/${id}/value`,
params
);
const { data } = await axios.put(`/admin/category/theme-value/${id}`, params);
return data;
};
export const deleteThemeValue = async (id: string) => {
const { data } = await axios.delete(
`/admin/category/theme-value/${id}/value`
);
const { data } = await axios.delete(`/admin/category/theme-value/${id}`);
return data;
};
+5
View File
@@ -35,6 +35,11 @@ export type CreateThemeValueType = {
value: string;
};
export type UpdateThemeValueType = {
name: string;
value: string;
};
export type ThemeValueType = {
_id: string;
theme: ThemeType;