191 lines
9.5 KiB
TypeScript
191 lines
9.5 KiB
TypeScript
|
||
import { FC, useState } from 'react'
|
||
import { useTranslation } from 'react-i18next'
|
||
import Input from '../../components/Input'
|
||
import Td from '../../components/Td'
|
||
import SwitchComponent from '../../components/Switch'
|
||
import { TickCircle, Trash } from 'iconsax-react'
|
||
import "quill/dist/quill.snow.css";
|
||
import Button from '../../components/Button'
|
||
import { useCreateBlogCategory, useDeleteBlogCategory, useGetBlogCategories } from './hooks/useBlogData'
|
||
import { BlogCategoryType, CreateBlogCategoryType } from './types/BlogTypes'
|
||
import moment from 'moment-jalaali'
|
||
import { useFormik } from 'formik'
|
||
import * as Yup from 'yup'
|
||
import Textarea from '../../components/Textarea'
|
||
import UploadBoxDraggble from '../../components/UploadBoxDraggble'
|
||
import { useSingleUpload } from '../service/hooks/useServiceData'
|
||
import { toast } from '../../components/Toast';
|
||
import UpdateCategory from './components/UpdateCategory'
|
||
import { usePermissions } from '../../hooks/usePermissions'
|
||
const BlogCategory: FC = () => {
|
||
|
||
const { t } = useTranslation('global')
|
||
const getBlogCategories = useGetBlogCategories()
|
||
const [file, setFile] = useState<File>()
|
||
const singleUpload = useSingleUpload()
|
||
const createBlogCategory = useCreateBlogCategory()
|
||
const deleteBlogCategory = useDeleteBlogCategory()
|
||
const { canCreate, canUpdate, canDelete } = usePermissions()
|
||
const formik = useFormik<CreateBlogCategoryType>({
|
||
initialValues: {
|
||
title: '',
|
||
description: '',
|
||
iconUrl: '',
|
||
isActive: true
|
||
},
|
||
validationSchema: Yup.object({
|
||
title: Yup.string().required(t('errors.required')),
|
||
description: Yup.string().required(t('errors.required')),
|
||
}),
|
||
onSubmit: async (values) => {
|
||
if (!file) {
|
||
toast('فایل را انتخاب کنید', 'error')
|
||
return
|
||
}
|
||
const formData = new FormData()
|
||
formData.append('file', file)
|
||
await singleUpload.mutateAsync(formData, {
|
||
onSuccess: (data) => {
|
||
values.iconUrl = data.data.url
|
||
}
|
||
})
|
||
|
||
createBlogCategory.mutateAsync(values, {
|
||
onSuccess: () => {
|
||
toast('دسته بندی با موفقیت ثبت شد', 'success')
|
||
setFile(undefined)
|
||
formik.resetForm()
|
||
getBlogCategories.refetch()
|
||
}
|
||
})
|
||
}
|
||
})
|
||
return (
|
||
<div className='mt-4'>
|
||
<div className='flex justify-start items-center'>
|
||
<div>
|
||
{t('blog.blog_category')}
|
||
</div>
|
||
</div>
|
||
<div className='flex gap-6 xl:mt-8 mt-4'>
|
||
<div className='flex-1'>
|
||
<div className='bg-white min-h-[calc(100vh-245px)] mt-4 rounded-3xl'>
|
||
<div className='relative overflow-x-auto rounded-3xl w-full'>
|
||
<table className='w-full text-sm '>
|
||
<thead className='thead'>
|
||
<tr>
|
||
<Td text={''} />
|
||
<Td text={t('blog.blog_title')} />
|
||
<Td text={'توضیحات'} />
|
||
<Td text={t('blog.category')} />
|
||
<Td text={t('blog.shareDate')} />
|
||
<Td text={t('')} />
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{
|
||
getBlogCategories.data?.data?.categories?.map((item: BlogCategoryType) => {
|
||
return (
|
||
<tr key={item.id} className='tr'>
|
||
<td>
|
||
<div className='flex justify-center'>
|
||
<img src={item.iconUrl} className='w-10' />
|
||
</div>
|
||
</td>
|
||
<Td text={item.title} />
|
||
<Td text={item.description} />
|
||
<Td text={t('')}>
|
||
<SwitchComponent
|
||
active={true}
|
||
onChange={() => { }}
|
||
/>
|
||
</Td>
|
||
<Td text={moment(item.createdAt).format('jYYYY/jMM/jDD')} />
|
||
<Td text={t('')}>
|
||
<div className='flex gap-2 items-center'>
|
||
{canUpdate('blog_categories') && (
|
||
<UpdateCategory id={item.id} />
|
||
)}
|
||
{canDelete('blog_categories') && (
|
||
<Trash size={20} color='red' onClick={() => {
|
||
deleteBlogCategory.mutateAsync(item.id, {
|
||
onSuccess: () => {
|
||
toast('دسته بندی با موفقیت حذف شد', 'success')
|
||
getBlogCategories.refetch()
|
||
}
|
||
})
|
||
}} />
|
||
)}
|
||
</div>
|
||
</Td>
|
||
</tr>
|
||
)
|
||
})
|
||
}
|
||
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{canCreate('blog_categories') && (
|
||
<div className='relative bg-white min-h-[calc(100vh-185px)] w-sidebar xl:block hidden py-10 px-5 h-fit rounded-3xl'>
|
||
<p className='text-md'>{t('blog.add_category')}</p>
|
||
<div className='text-sm flex items-center justify-between mt-4'>
|
||
<p>
|
||
{t('blog.category_status')}
|
||
</p>
|
||
<div className='flex gap-1 text-xs items-center text-description'>
|
||
<div>
|
||
{t('ads.deactive')}
|
||
</div>
|
||
<SwitchComponent
|
||
active={formik.values.isActive}
|
||
onChange={(value) => formik.setFieldValue('isActive', value)}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className='mt-6'>
|
||
<Input
|
||
label='عنوان'
|
||
{...formik.getFieldProps('title')}
|
||
error_text={formik.touched.title && formik.errors.title ? formik.errors.title : undefined}
|
||
/>
|
||
</div>
|
||
|
||
<div className='mt-6'>
|
||
<Textarea
|
||
label='توضیحات'
|
||
{...formik.getFieldProps('description')}
|
||
error_text={formik.touched.description && formik.errors.description ? formik.errors.description : undefined}
|
||
/>
|
||
</div>
|
||
|
||
<div className='mt-6'>
|
||
<UploadBoxDraggble
|
||
label='آپلود آیکون'
|
||
onChange={(file) => setFile(file[0])}
|
||
/>
|
||
</div>
|
||
|
||
<Button
|
||
className='w-[172px] absolute bottom-4 left-4'
|
||
onClick={() => formik.handleSubmit()}
|
||
isLoading={createBlogCategory.isPending || singleUpload.isPending}
|
||
>
|
||
<div className='flex gap-2 items-center'>
|
||
<TickCircle size={20} color='white' />
|
||
<div>
|
||
ذخیره
|
||
</div>
|
||
</div>
|
||
</Button>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
export default BlogCategory |