learning
This commit is contained in:
@@ -202,5 +202,7 @@ export const Pages = {
|
||||
requestCreateProduct: "/sellers/request-create-product",
|
||||
learningCategory: "/sellers/learning-category",
|
||||
learning: "/sellers/learning",
|
||||
learningCreate: "/sellers/learning/create",
|
||||
learningUpdate: "/sellers/learning/update/",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
import { type FC, useState } from 'react'
|
||||
import { useFormik } from 'formik'
|
||||
import { type CreateLearningType } from './types/Types'
|
||||
import * as Yup from 'yup'
|
||||
import { useCreateLearning, useGetLearningCategory } from './hooks/useSellerData'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import Input from '../../components/Input'
|
||||
import Select from '../../components/Select'
|
||||
import Textarea from '../../components/Textarea'
|
||||
import Button from '../../components/Button'
|
||||
import { TickCircle } from 'iconsax-react'
|
||||
import { useUploadSingle } from '../uploader/hooks/useUploaderData'
|
||||
import UploadBoxDraggble from '@/components/UploadBoxDraggble'
|
||||
import { toast } from 'react-toastify'
|
||||
import { extractErrorMessage } from '@/helpers/utils'
|
||||
import { Pages } from '@/config/Pages'
|
||||
|
||||
const CreateLearning: FC = () => {
|
||||
const navigate = useNavigate()
|
||||
const { data: categoriesData } = useGetLearningCategory()
|
||||
const uploadSingle = useUploadSingle()
|
||||
const createLearningMutation = useCreateLearning()
|
||||
|
||||
const [videoFile, setVideoFile] = useState<File[]>([])
|
||||
const [coverFile, setCoverFile] = useState<File[]>([])
|
||||
|
||||
const formik = useFormik<CreateLearningType>({
|
||||
initialValues: {
|
||||
title: '',
|
||||
description: '',
|
||||
videoUrl: '',
|
||||
cover: '',
|
||||
category: ''
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
title: Yup.string().required('عنوان یادگیری الزامی است'),
|
||||
description: Yup.string().required('توضیحات یادگیری الزامی است'),
|
||||
category: Yup.string().required('دستهبندی یادگیری الزامی است')
|
||||
}),
|
||||
onSubmit: async (values) => {
|
||||
let videoUrl = values.videoUrl
|
||||
let coverUrl = values.cover
|
||||
|
||||
if (videoFile.length > 0) {
|
||||
const videoResponse = await uploadSingle.mutateAsync(videoFile[0])
|
||||
videoUrl = videoResponse.results?.url?.url || ''
|
||||
}
|
||||
|
||||
if (coverFile.length > 0) {
|
||||
const coverResponse = await uploadSingle.mutateAsync(coverFile[0])
|
||||
coverUrl = coverResponse.results?.url?.url || ''
|
||||
}
|
||||
|
||||
const submitData = {
|
||||
...values,
|
||||
videoUrl,
|
||||
cover: coverUrl
|
||||
}
|
||||
|
||||
createLearningMutation.mutate(submitData, {
|
||||
onSuccess: () => {
|
||||
toast.success('یادگیری با موفقیت ایجاد شد')
|
||||
navigate(Pages.sellers.learning)
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(extractErrorMessage(error))
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
const categories = categoriesData?.results?.learningCategory || []
|
||||
const categoryOptions = categories.map(category => ({
|
||||
value: category._id,
|
||||
label: category.title
|
||||
}))
|
||||
|
||||
console.log(formik.errors);
|
||||
|
||||
|
||||
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={createLearningMutation.isPending || uploadSingle.isPending}
|
||||
disabled={!formik.isValid || createLearningMutation.isPending || uploadSingle.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 : ''}
|
||||
/>
|
||||
|
||||
<Textarea
|
||||
label="توضیحات یادگیری"
|
||||
placeholder="توضیحات یادگیری را وارد کنید"
|
||||
{...formik.getFieldProps('description')}
|
||||
error_text={formik.touched.description && formik.errors.description ? formik.errors.description : ''}
|
||||
/>
|
||||
|
||||
<Select
|
||||
label="دستهبندی"
|
||||
placeholder="دستهبندی را انتخاب کنید"
|
||||
items={categoryOptions}
|
||||
value={formik.values.category}
|
||||
onChange={(e) => formik.setFieldValue('category', e.target.value)}
|
||||
error_text={formik.touched.category && formik.errors.category ? formik.errors.category : ''}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* فایلها */}
|
||||
<div className='w-80 space-y-6'>
|
||||
<div className='text-sm bg-white py-8 px-6 rounded-3xl'>
|
||||
<h2 className='text-lg font-medium mb-6'>فایلها</h2>
|
||||
|
||||
<div className='space-y-6'>
|
||||
<div>
|
||||
<UploadBoxDraggble
|
||||
label='ویدیو یادگیری'
|
||||
isMultiple={false}
|
||||
onChange={(files) => setVideoFile(files)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<UploadBoxDraggble
|
||||
label='تصویر کاور'
|
||||
isMultiple={false}
|
||||
onChange={(files) => setCoverFile(files)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CreateLearning
|
||||
@@ -0,0 +1,90 @@
|
||||
import { type FC } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useGetLearning } from './hooks/useSellerData'
|
||||
import type { Learning as LearningType } from './types/Types'
|
||||
import PageLoading from '../../components/PageLoading'
|
||||
import Error from '../../components/Error'
|
||||
import Td from '../../components/Td'
|
||||
import Button from '@/components/Button'
|
||||
import LearningTableRow from './components/LearningTableRow'
|
||||
import { Pages } from '@/config/Pages'
|
||||
|
||||
const Learning: FC = () => {
|
||||
const navigate = useNavigate()
|
||||
|
||||
const { data: learningData, isLoading, error } = useGetLearning()
|
||||
|
||||
const handleEditLearning = (learning: LearningType) => {
|
||||
navigate(`${Pages.sellers.learningUpdate}${learning._id}`)
|
||||
}
|
||||
|
||||
const handleCreateLearning = () => {
|
||||
navigate(Pages.sellers.learningCreate)
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex justify-center items-center min-h-[400px]">
|
||||
<PageLoading />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="flex justify-center items-center min-h-[400px]">
|
||||
<Error errorText="خطا در بارگذاری یادگیریها" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const learnings = learningData?.results?.learning || []
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='flex justify-end mt-5'>
|
||||
<Button
|
||||
label="ایجاد یادگیری جدید"
|
||||
onClick={handleCreateLearning}
|
||||
className="w-auto"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='relative overflow-x-auto rounded-3xl mt-5 w-full'>
|
||||
<table className='w-full text-sm'>
|
||||
<thead className='thead'>
|
||||
<tr>
|
||||
<Td text={'کاور'} />
|
||||
<Td text={'عنوان و توضیحات'} />
|
||||
<Td text={'ویدیو'} />
|
||||
<Td text={'دستهبندی'} />
|
||||
<Td text={'وضعیت'} />
|
||||
<Td text={'تاریخ ایجاد'} />
|
||||
<Td text={'عملیات'} />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{learnings.length === 0 ? (
|
||||
<tr className='tr'>
|
||||
<td colSpan={7} className="text-center py-8 text-gray-500">
|
||||
هیچ یادگیری یافت نشد
|
||||
</td>
|
||||
</tr>
|
||||
) : (
|
||||
learnings.map((learning: LearningType) => (
|
||||
<LearningTableRow
|
||||
key={learning._id}
|
||||
learning={learning}
|
||||
onEdit={handleEditLearning}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Learning
|
||||
@@ -0,0 +1,188 @@
|
||||
import { type FC, useState, useEffect } from 'react'
|
||||
import { useParams, useNavigate } from 'react-router-dom'
|
||||
import { useFormik } from 'formik'
|
||||
import { type CreateLearningType } from './types/Types'
|
||||
import * as Yup from 'yup'
|
||||
import { useUpdateLearning, useGetLearningById, useGetLearningCategory } from './hooks/useSellerData'
|
||||
import Input from '../../components/Input'
|
||||
import Select from '../../components/Select'
|
||||
import Textarea from '../../components/Textarea'
|
||||
import Button from '../../components/Button'
|
||||
import { TickCircle } from 'iconsax-react'
|
||||
import { useUploadSingle } from '../uploader/hooks/useUploaderData'
|
||||
import UploadBoxDraggble from '@/components/UploadBoxDraggble'
|
||||
import { toast } from 'react-toastify'
|
||||
import { extractErrorMessage } from '@/helpers/utils'
|
||||
import { Pages } from '@/config/Pages'
|
||||
import PageLoading from '@/components/PageLoading'
|
||||
|
||||
const UpdateLearning: FC = () => {
|
||||
const navigate = useNavigate()
|
||||
const { id } = useParams<{ id: string }>()
|
||||
const { data: categoriesData } = useGetLearningCategory()
|
||||
const { data: learningDetail, isLoading: learningDetailLoading } = useGetLearningById(id!)
|
||||
const uploadSingle = useUploadSingle()
|
||||
const updateLearningMutation = useUpdateLearning()
|
||||
|
||||
const [videoFile, setVideoFile] = useState<File[]>([])
|
||||
const [coverFile, setCoverFile] = useState<File[]>([])
|
||||
|
||||
const formik = useFormik<CreateLearningType>({
|
||||
initialValues: {
|
||||
title: '',
|
||||
description: '',
|
||||
videoUrl: '',
|
||||
cover: '',
|
||||
category: ''
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
title: Yup.string().required('عنوان یادگیری الزامی است'),
|
||||
description: Yup.string().required('توضیحات یادگیری الزامی است'),
|
||||
category: Yup.string().required('دستهبندی یادگیری الزامی است')
|
||||
}),
|
||||
onSubmit: async (values) => {
|
||||
let videoUrl = values.videoUrl
|
||||
let coverUrl = values.cover
|
||||
|
||||
if (videoFile.length > 0) {
|
||||
const videoResponse = await uploadSingle.mutateAsync(videoFile[0])
|
||||
videoUrl = videoResponse.results?.url?.url || ''
|
||||
}
|
||||
|
||||
if (coverFile.length > 0) {
|
||||
const coverResponse = await uploadSingle.mutateAsync(coverFile[0])
|
||||
coverUrl = coverResponse.results?.url?.url || ''
|
||||
}
|
||||
|
||||
const submitData = {
|
||||
...values,
|
||||
videoUrl,
|
||||
cover: coverUrl
|
||||
}
|
||||
|
||||
updateLearningMutation.mutate({
|
||||
id: id!,
|
||||
params: submitData
|
||||
}, {
|
||||
onSuccess: () => {
|
||||
toast.success('یادگیری با موفقیت بروزرسانی شد')
|
||||
navigate(Pages.sellers.learning)
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(extractErrorMessage(error))
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (learningDetail?.results?.learning) {
|
||||
const learning = learningDetail.results.learning
|
||||
formik.setValues({
|
||||
title: learning.title,
|
||||
description: learning.description,
|
||||
videoUrl: learning.videoUrl,
|
||||
cover: learning.cover,
|
||||
category: learning.category._id
|
||||
})
|
||||
}
|
||||
}, [learningDetail])
|
||||
|
||||
const categories = categoriesData?.results?.learningCategory || []
|
||||
const categoryOptions = categories.map(category => ({
|
||||
value: category._id,
|
||||
label: category.title
|
||||
}))
|
||||
|
||||
console.log(formik.errors);
|
||||
|
||||
if (learningDetailLoading) {
|
||||
return (
|
||||
<div className="flex justify-center items-center min-h-[400px]">
|
||||
<PageLoading />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
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={updateLearningMutation.isPending || uploadSingle.isPending}
|
||||
disabled={!formik.isValid || updateLearningMutation.isPending || uploadSingle.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 : ''}
|
||||
/>
|
||||
|
||||
<Textarea
|
||||
label="توضیحات یادگیری"
|
||||
placeholder="توضیحات یادگیری را وارد کنید"
|
||||
{...formik.getFieldProps('description')}
|
||||
error_text={formik.touched.description && formik.errors.description ? formik.errors.description : ''}
|
||||
/>
|
||||
|
||||
<Select
|
||||
label="دستهبندی"
|
||||
placeholder="دستهبندی را انتخاب کنید"
|
||||
items={categoryOptions}
|
||||
value={formik.values.category}
|
||||
onChange={(e) => formik.setFieldValue('category', e.target.value)}
|
||||
error_text={formik.touched.category && formik.errors.category ? formik.errors.category : ''}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* فایلها */}
|
||||
<div className='w-80 space-y-6'>
|
||||
<div className='text-sm bg-white py-8 px-6 rounded-3xl'>
|
||||
<h2 className='text-lg font-medium mb-6'>فایلها</h2>
|
||||
|
||||
<div className='space-y-6'>
|
||||
<div>
|
||||
<UploadBoxDraggble
|
||||
label='ویدیو یادگیری'
|
||||
isMultiple={false}
|
||||
onChange={(files) => setVideoFile(files)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<UploadBoxDraggble
|
||||
label='تصویر کاور'
|
||||
isMultiple={false}
|
||||
onChange={(files) => setCoverFile(files)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default UpdateLearning
|
||||
@@ -0,0 +1,88 @@
|
||||
import { type FC } from 'react'
|
||||
import Td from '../../../components/Td'
|
||||
import { Calendar, Edit, Play } from 'iconsax-react'
|
||||
import StatusWithText from '../../../components/StatusWithText'
|
||||
import type { Learning as LearningType } from '../types/Types'
|
||||
import { useDeleteLearning } from '../hooks/useSellerData'
|
||||
import TrashWithConfrim from '@/components/TrashWithConfrim'
|
||||
|
||||
interface Props {
|
||||
learning: LearningType
|
||||
onEdit: (learning: LearningType) => void
|
||||
}
|
||||
|
||||
const LearningTableRow: FC<Props> = ({ learning, onEdit }) => {
|
||||
const { mutate: deleteLearningMutation, isPending } = useDeleteLearning()
|
||||
const formatDate = (dateString: string) => {
|
||||
return new Date(dateString).toLocaleDateString('fa-IR', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<tr className='tr'>
|
||||
<Td text="">
|
||||
<div className="w-12 h-12 rounded-lg overflow-hidden">
|
||||
<img
|
||||
src={learning.cover || '/placeholder-image.png'}
|
||||
alt={learning.title}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</Td>
|
||||
<Td text="">
|
||||
<div className="max-w-xs">
|
||||
<div className="font-medium text-gray-900 truncate">
|
||||
{learning.title}
|
||||
</div>
|
||||
<div className="text-gray-500 text-xs truncate max-w-xs">
|
||||
{learning.description}
|
||||
</div>
|
||||
</div>
|
||||
</Td>
|
||||
<Td text="">
|
||||
<div className="flex items-center gap-1">
|
||||
<Play size={16} color="#8C90A3" />
|
||||
<span className="text-gray-600 text-sm">
|
||||
ویدیو
|
||||
</span>
|
||||
</div>
|
||||
</Td>
|
||||
<Td text={learning.category.title} />
|
||||
<Td text="">
|
||||
<StatusWithText
|
||||
variant={learning.deleted ? 'error' : 'success'}
|
||||
text={learning.deleted ? 'غیرفعال' : 'فعال'}
|
||||
/>
|
||||
</Td>
|
||||
<Td text="">
|
||||
<div className="flex items-center gap-2">
|
||||
<Calendar size={16} color="#8C90A3" />
|
||||
<span className="text-gray-600 text-sm">
|
||||
{formatDate(learning.createdAt)}
|
||||
</span>
|
||||
</div>
|
||||
</Td>
|
||||
<Td text="">
|
||||
<div className="flex gap-2 items-center">
|
||||
<Edit
|
||||
onClick={() => onEdit(learning)}
|
||||
color="#8C90A3"
|
||||
size={18}
|
||||
className="cursor-pointer hover:text-blue-500"
|
||||
/>
|
||||
<TrashWithConfrim
|
||||
onDelete={() => deleteLearningMutation(learning._id)}
|
||||
isLoading={isPending}
|
||||
/>
|
||||
</div>
|
||||
</Td>
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
|
||||
export default LearningTableRow
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as api from "../service/SellerService";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import type {
|
||||
CreateCategoryLearning,
|
||||
CreateLearningType,
|
||||
@@ -115,3 +115,21 @@ export const useUpdateLearning = () => {
|
||||
api.updateLearning(id, params),
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetLearningById = (id: string, enabled: boolean = true) => {
|
||||
return useQuery({
|
||||
queryKey: ["learning", id],
|
||||
queryFn: () => api.getLearningById(id),
|
||||
enabled: enabled && !!id,
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteLearning = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: api.deleteLearning,
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["learning"] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ import type {
|
||||
GetRequestCreateProductResponse,
|
||||
CreateCategoryLearning,
|
||||
GetLearningCategoryResponse,
|
||||
GetLearningResponse,
|
||||
CreateLearningType,
|
||||
} from "../types/Types";
|
||||
|
||||
@@ -116,7 +117,7 @@ export const updateLearningCategory = async (
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getLearning = async () => {
|
||||
export const getLearning = async (): Promise<GetLearningResponse> => {
|
||||
const { data } = await axios.get(`/learning`);
|
||||
return data;
|
||||
};
|
||||
@@ -133,3 +134,13 @@ export const updateLearning = async (
|
||||
const { data } = await axios.patch(`/admin/learning/${id}/update`, params);
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getLearningById = async (id: string) => {
|
||||
const { data } = await axios.get(`/learning/${id}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
export const deleteLearning = async (id: string) => {
|
||||
const { data } = await axios.delete(`/admin/learning/${id}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -335,6 +335,26 @@ export interface GetRequestCreateProductResponse {
|
||||
};
|
||||
}
|
||||
|
||||
export interface Learning {
|
||||
_id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
videoUrl: string;
|
||||
cover: string;
|
||||
category: LearningCategory;
|
||||
deleted: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface GetLearningResponse {
|
||||
status: number;
|
||||
success: boolean;
|
||||
results: {
|
||||
learning: Learning[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface CreateLearningType {
|
||||
title: string;
|
||||
description: string;
|
||||
|
||||
+6
-1
@@ -68,6 +68,9 @@ import WithdrawalRequestPage from '@/pages/seller/WithdrawalRequest'
|
||||
import Annoncement from '@/pages/seller/Annoncement'
|
||||
import RequestCreateProduct from '@/pages/seller/RequestCreateProduct'
|
||||
import CategoryLearning from '@/pages/seller/CategoryLearning'
|
||||
import Learning from '@/pages/seller/Learning'
|
||||
import CreateLearning from '@/pages/seller/CreateLearning'
|
||||
import UpdateLearning from '@/pages/seller/UpdateLearning'
|
||||
const MainRouter: FC = () => {
|
||||
|
||||
const { hasSubMenu } = useSharedStore()
|
||||
@@ -169,7 +172,9 @@ const MainRouter: FC = () => {
|
||||
<Route path={Pages.sellers.announcement} element={<Annoncement />} />
|
||||
<Route path={Pages.sellers.requestCreateProduct} element={<RequestCreateProduct />} />
|
||||
<Route path={Pages.sellers.learningCategory} element={<CategoryLearning />} />
|
||||
{/* <Route path={Pages.sellers.learning} element={<Learning />} /> */}
|
||||
<Route path={Pages.sellers.learning} element={<Learning />} />
|
||||
<Route path={Pages.sellers.learningCreate} element={<CreateLearning />} />
|
||||
<Route path={`${Pages.sellers.learningUpdate}:id`} element={<UpdateLearning />} />
|
||||
</Routes>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user