update theme values + delete theme value
This commit is contained in:
@@ -1,18 +1,25 @@
|
|||||||
import { type FC, useState } from 'react'
|
import { type FC, useState } from 'react'
|
||||||
import { useGetThemeValues } from './hooks/useThemeData'
|
import { useDeleteThemeValue, useGetThemeValues } from './hooks/useThemeData'
|
||||||
import { useParams } from 'react-router-dom'
|
import { useParams } from 'react-router-dom'
|
||||||
import PageTitle from '@/components/PageTitle'
|
import PageTitle from '@/components/PageTitle'
|
||||||
import Td from '@/components/Td'
|
import Td from '@/components/Td'
|
||||||
import { Eye, Add } from 'iconsax-react'
|
import { Edit, Add } from 'iconsax-react'
|
||||||
import TrashWithConfrim from '@/components/TrashWithConfrim'
|
import TrashWithConfrim from '@/components/TrashWithConfrim'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import Button from '@/components/Button'
|
import Button from '@/components/Button'
|
||||||
import CreateThemeValueModal from './components/CreateThemeValueModal'
|
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 Values: FC = () => {
|
||||||
|
|
||||||
const { id } = useParams()
|
const { id } = useParams()
|
||||||
|
const { mutate: deleteThemeValue, isPending: isDeletingThemeValue } = useDeleteThemeValue()
|
||||||
const { data, isLoading } = useGetThemeValues(id!)
|
const { data, isLoading } = useGetThemeValues(id!)
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false)
|
const [isModalOpen, setIsModalOpen] = useState(false)
|
||||||
|
const [isUpdateModalOpen, setIsUpdateModalOpen] = useState(false)
|
||||||
|
const [selectedThemeValue, setSelectedThemeValue] = useState<ThemeValueType | null>(null)
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <div className="flex justify-center items-center h-64">در حال بارگذاری...</div>
|
return <div className="flex justify-center items-center h-64">در حال بارگذاری...</div>
|
||||||
@@ -22,7 +29,7 @@ const Values: FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className='flex justify-between items-center'>
|
<div className='flex gap-4 justify-between items-center'>
|
||||||
<PageTitle title1='مقادیر تم' />
|
<PageTitle title1='مقادیر تم' />
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setIsModalOpen(true)}
|
onClick={() => setIsModalOpen(true)}
|
||||||
@@ -69,12 +76,27 @@ const Values: FC = () => {
|
|||||||
<Td text={item.value.toString()} />
|
<Td text={item.value.toString()} />
|
||||||
<Td text=''>
|
<Td text=''>
|
||||||
<div className='flex gap-2'>
|
<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
|
<TrashWithConfrim
|
||||||
onDelete={() => {
|
onDelete={() => {
|
||||||
toast.error('این قابلیت در حال توسعه است')
|
deleteThemeValue(item._id, {
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success('مقدار تم با موفقیت حذف شد')
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error))
|
||||||
|
}
|
||||||
|
})
|
||||||
}}
|
}}
|
||||||
isLoading={false}
|
isLoading={isDeletingThemeValue}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Td>
|
</Td>
|
||||||
@@ -100,6 +122,15 @@ const Values: FC = () => {
|
|||||||
themeId={id}
|
themeId={id}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<UpdateThemeValueModal
|
||||||
|
open={isUpdateModalOpen}
|
||||||
|
close={() => {
|
||||||
|
setIsUpdateModalOpen(false)
|
||||||
|
setSelectedThemeValue(null)
|
||||||
|
}}
|
||||||
|
themeValue={selectedThemeValue}
|
||||||
|
/>
|
||||||
</div>
|
</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
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import * as api from "../service/ThemeService";
|
import * as api from "../service/ThemeService";
|
||||||
import type { CreateThemeType } from "../type/Types";
|
import type { CreateThemeType, UpdateThemeValueType } from "../type/Types";
|
||||||
|
|
||||||
export const useGetThemes = () => {
|
export const useGetThemes = () => {
|
||||||
return useQuery({
|
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"] });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type {
|
|||||||
GetThemeByIdResponseType,
|
GetThemeByIdResponseType,
|
||||||
GetThemeValuesResponseType,
|
GetThemeValuesResponseType,
|
||||||
CreateThemeValueType,
|
CreateThemeValueType,
|
||||||
|
UpdateThemeValueType,
|
||||||
} from "../type/Types";
|
} from "../type/Types";
|
||||||
|
|
||||||
export const getThemes = async (): Promise<GetThemesResponseType> => {
|
export const getThemes = async (): Promise<GetThemesResponseType> => {
|
||||||
@@ -57,18 +58,13 @@ export const createThemeValue = async (params: CreateThemeValueType) => {
|
|||||||
|
|
||||||
export const updateThemeValue = async (
|
export const updateThemeValue = async (
|
||||||
id: string,
|
id: string,
|
||||||
params: CreateThemeValueType
|
params: UpdateThemeValueType
|
||||||
) => {
|
) => {
|
||||||
const { data } = await axios.put(
|
const { data } = await axios.put(`/admin/category/theme-value/${id}`, params);
|
||||||
`/admin/category/theme-value/${id}/value`,
|
|
||||||
params
|
|
||||||
);
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteThemeValue = async (id: string) => {
|
export const deleteThemeValue = async (id: string) => {
|
||||||
const { data } = await axios.delete(
|
const { data } = await axios.delete(`/admin/category/theme-value/${id}`);
|
||||||
`/admin/category/theme-value/${id}/value`
|
|
||||||
);
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ export type CreateThemeValueType = {
|
|||||||
value: string;
|
value: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type UpdateThemeValueType = {
|
||||||
|
name: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type ThemeValueType = {
|
export type ThemeValueType = {
|
||||||
_id: string;
|
_id: string;
|
||||||
theme: ThemeType;
|
theme: ThemeType;
|
||||||
|
|||||||
Reference in New Issue
Block a user