diff --git a/src/config/Paths.tsx b/src/config/Paths.tsx
index ae9c50d..b86071a 100644
--- a/src/config/Paths.tsx
+++ b/src/config/Paths.tsx
@@ -14,7 +14,10 @@ export const Paths = {
detail: '/announcement/',
},
criticisms: '/criticisms',
- learning: '/learning',
+ learning: {
+ list: '/learning/list',
+ detail: '/learning/',
+ },
auth: {
login: '/auth/login',
},
diff --git a/src/pages/criticisms/hooks/useCriticismsData.ts b/src/pages/criticisms/hooks/useCriticismsData.ts
index a4942b9..d5cced2 100644
--- a/src/pages/criticisms/hooks/useCriticismsData.ts
+++ b/src/pages/criticisms/hooks/useCriticismsData.ts
@@ -1,5 +1,5 @@
import { useMutation } from "@tanstack/react-query";
-import { CreateCriticismsTypes } from "../types/CriticismsTypes";
+import { type CreateCriticismsTypes } from "../types/CriticismsTypes";
import * as api from "../service/CriticismsService";
export const useCreateCriticisms = () => {
diff --git a/src/pages/criticisms/service/CriticismsService.ts b/src/pages/criticisms/service/CriticismsService.ts
index e07d021..b228f2f 100644
--- a/src/pages/criticisms/service/CriticismsService.ts
+++ b/src/pages/criticisms/service/CriticismsService.ts
@@ -1,5 +1,5 @@
import axios from "../../../config/axios";
-import { CreateCriticismsTypes } from "../types/CriticismsTypes";
+import { type CreateCriticismsTypes } from "../types/CriticismsTypes";
export const createCriticisms = async (params: CreateCriticismsTypes) => {
const { data } = await axios.post(`/criticisms`, params);
diff --git a/src/pages/learning/Detail.tsx b/src/pages/learning/Detail.tsx
new file mode 100644
index 0000000..b0cdab5
--- /dev/null
+++ b/src/pages/learning/Detail.tsx
@@ -0,0 +1,90 @@
+import { type FC } from 'react'
+import { useParams } from 'react-router-dom'
+import { useGetLearningDetail } from './hooks/useLearningData'
+import PageLoading from '../../components/PageLoading'
+// import DanakLearning from '../home/components/DanakLearning'
+import { Calendar2, Clock, Element3 } from 'iconsax-react'
+import moment from 'moment-jalaali'
+import { Helmet } from 'react-helmet-async'
+import { type LearningItemType } from './types/LearningTypes'
+
+const LearningDetail: FC = () => {
+
+ const { id } = useParams()
+ const getLearningDetail = useGetLearningDetail(id ? id : '')
+
+ return (
+
+
+
+ داناک | آموزش
+
+
+ {
+ getLearningDetail.isPending ?
+
+ :
+
+
+
+
+
+
+
+
+
+ {(getLearningDetail.data as { data: { learning: LearningItemType } })?.data?.learning?.title}
+
+
+
+
+
+
+
+ {(getLearningDetail.data as { data: { learning: LearningItemType } })?.data?.learning?.videoDuration + ' دقیقه'}
+
+
+
+
+
+
+ {(getLearningDetail.data as { data: { learning: LearningItemType } })?.data?.learning?.category?.name}
+
+
+
+
+
+
+ {moment((getLearningDetail.data as { data: { learning: LearningItemType } })?.data?.learning?.createdAt).format('jYYYY-jMM-jDD')}
+
+
+
+
+
+
+
+
+ {(getLearningDetail.data as { data: { learning: LearningItemType } })?.data?.learning?.description}
+
+
+
+
+ {/*
*/}
+
+ }
+
+ )
+}
+
+export default LearningDetail
\ No newline at end of file
diff --git a/src/pages/learning/List.tsx b/src/pages/learning/List.tsx
new file mode 100644
index 0000000..ff26254
--- /dev/null
+++ b/src/pages/learning/List.tsx
@@ -0,0 +1,106 @@
+import { type FC, useState } from 'react'
+// import { useTranslation } from 'react-i18next'
+import BannerImage from '../../assets/images/support1.png'
+import Input from '../../components/Input'
+import { useGetLearnings } from './hooks/useLearningData'
+import PageLoading from '../../components/PageLoading'
+import { type LearningItemType } from './types/LearningTypes'
+import moment from 'moment-jalaali'
+import { Link } from 'react-router-dom'
+// import { Pages } from '../../config/Pages'
+import { Helmet } from 'react-helmet-async'
+
+const LearningList: FC = () => {
+
+ // const { t } = useTranslation('global')
+ const [search, setSearch] = useState('')
+ const getLearnings = useGetLearnings(search)
+
+ return (
+
+
+
+ داناک | آموزش
+
+
+
+
+ آموزش
+
+
+
+
+ setSearch(value)}
+ />
+
+
+ {/*
+
+
*/}
+
+
+ {
+ getLearnings.isPending ?
+
+ :
+
+ {
+ (getLearnings.data as { data: { learnings: LearningItemType[] } })?.data?.learnings?.map((item: LearningItemType) => {
+ return (
+
+

+
+ {item.title}
+
+
+
{item.category.name} ,
+
{item.videoDuration} دقیقه
+
+
+
+ {moment(item.createdAt).format('jYYYY/jMM/jDD')}
+
+
+ )
+ })
+ }
+
+
+
+
+
+ }
+
+
+
+
+

+
+
+
+ سفارش نرمافزار اختصاصی: سرمایهای برای آینده یا فقط هزینهای برای امروز؟
+
+
+
+
+
+ )
+}
+
+export default LearningList
\ No newline at end of file
diff --git a/src/pages/learning/data/staticData.ts b/src/pages/learning/data/staticData.ts
new file mode 100644
index 0000000..e7f5986
--- /dev/null
+++ b/src/pages/learning/data/staticData.ts
@@ -0,0 +1,138 @@
+// import type { LearningItemType } from "../types/LearningTypes";
+
+export const staticLearningsData = {
+ data: {
+ learnings: [
+ {
+ id: "1",
+ title: "آموزش کامل React و TypeScript",
+ description:
+ "در این دوره شما با مفاهیم پایه و پیشرفته React و TypeScript آشنا خواهید شد و پروژههای عملی انجام خواهید داد.",
+ coverUrl: "/src/assets/images/new_order.png",
+ videoUrl:
+ "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_1mb.mp4",
+ videoDuration: "120",
+ createdAt: "2024-01-15T10:30:00Z",
+ updatedAt: "2024-01-15T10:30:00Z",
+ category: {
+ id: "1",
+ name: "Frontend",
+ createdAt: "2024-01-01T00:00:00Z",
+ updatedAt: "2024-01-01T00:00:00Z",
+ },
+ },
+ {
+ id: "2",
+ title: "Node.js و Express.js از صفر تا صد",
+ description:
+ "یادگیری کامل Node.js و Express.js برای توسعه سمت سرور و ایجاد API های قدرتمند.",
+ coverUrl: "/src/assets/images/support1.png",
+ videoUrl:
+ "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_2mb.mp4",
+ videoDuration: "180",
+ createdAt: "2024-01-20T14:15:00Z",
+ updatedAt: "2024-01-20T14:15:00Z",
+ category: {
+ id: "2",
+ name: "Backend",
+ createdAt: "2024-01-01T00:00:00Z",
+ updatedAt: "2024-01-01T00:00:00Z",
+ },
+ },
+ {
+ id: "3",
+ title: "آموزش MongoDB و Mongoose",
+ description:
+ "کار با پایگاه داده NoSQL MongoDB و کتابخانه Mongoose برای مدیریت دادهها.",
+ coverUrl: "/src/assets/images/logo.svg",
+ videoUrl:
+ "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_5mb.mp4",
+ videoDuration: "90",
+ createdAt: "2024-01-25T09:45:00Z",
+ updatedAt: "2024-01-25T09:45:00Z",
+ category: {
+ id: "3",
+ name: "Database",
+ createdAt: "2024-01-01T00:00:00Z",
+ updatedAt: "2024-01-01T00:00:00Z",
+ },
+ },
+ {
+ id: "4",
+ title: "Docker و Containerization",
+ description:
+ "آموزش کامل Docker برای containerization و deployment اپلیکیشنها.",
+ coverUrl: "/src/assets/images/avatar_image.png",
+ videoUrl:
+ "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_10mb.mp4",
+ videoDuration: "150",
+ createdAt: "2024-02-01T16:20:00Z",
+ updatedAt: "2024-02-01T16:20:00Z",
+ category: {
+ id: "4",
+ name: "DevOps",
+ createdAt: "2024-01-01T00:00:00Z",
+ updatedAt: "2024-01-01T00:00:00Z",
+ },
+ },
+ {
+ id: "5",
+ title: "آموزش Git و GitHub",
+ description: "مدیریت نسخهها با Git و همکاری تیمی با GitHub.",
+ coverUrl: "/src/assets/images/new_order.png",
+ videoUrl:
+ "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_1mb.mp4",
+ videoDuration: "75",
+ createdAt: "2024-02-05T11:10:00Z",
+ updatedAt: "2024-02-05T11:10:00Z",
+ category: {
+ id: "5",
+ name: "Tools",
+ createdAt: "2024-01-01T00:00:00Z",
+ updatedAt: "2024-01-01T00:00:00Z",
+ },
+ },
+ {
+ id: "6",
+ title: "آموزش CSS و Tailwind CSS",
+ description:
+ "طراحی و استایلدهی صفحات وب با CSS و فریمورک Tailwind CSS.",
+ coverUrl: "/src/assets/images/support1.png",
+ videoUrl:
+ "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_2mb.mp4",
+ videoDuration: "105",
+ createdAt: "2024-02-10T13:30:00Z",
+ updatedAt: "2024-02-10T13:30:00Z",
+ category: {
+ id: "6",
+ name: "Styling",
+ createdAt: "2024-01-01T00:00:00Z",
+ updatedAt: "2024-01-01T00:00:00Z",
+ },
+ },
+ ],
+ },
+};
+
+export const staticLearningDetailData = {
+ data: {
+ learning: {
+ id: "1",
+ title: "آموزش کامل React و TypeScript",
+ description:
+ "در این دوره شما با مفاهیم پایه و پیشرفته React و TypeScript آشنا خواهید شد و پروژههای عملی انجام خواهید داد. این دوره شامل موارد زیر است:\n\n• نصب و راهاندازی محیط توسعه\n• آشنایی با JSX و Components\n• State و Props در React\n• Hooks و Lifecycle Methods\n• TypeScript و Type Safety\n• Routing و Navigation\n• State Management\n• Testing و Debugging\n• Deployment و Production",
+ coverUrl: "/src/assets/images/new_order.png",
+ videoUrl:
+ "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_1mb.mp4",
+ videoDuration: "120",
+ createdAt: "2024-01-15T10:30:00Z",
+ updatedAt: "2024-01-15T10:30:00Z",
+ category: {
+ id: "1",
+ name: "Frontend",
+ createdAt: "2024-01-01T00:00:00Z",
+ updatedAt: "2024-01-01T00:00:00Z",
+ },
+ },
+ },
+};
diff --git a/src/pages/learning/hooks/useLearningData.ts b/src/pages/learning/hooks/useLearningData.ts
new file mode 100644
index 0000000..f743378
--- /dev/null
+++ b/src/pages/learning/hooks/useLearningData.ts
@@ -0,0 +1,78 @@
+import { useQuery } from "@tanstack/react-query";
+// import * as api from "../service/LearningService";
+import {
+ staticLearningsData,
+ staticLearningDetailData,
+} from "../data/staticData";
+
+export const useGetLearnings = (search: string, limit?: number) => {
+ return useQuery({
+ queryKey: ["learnings", search, limit],
+ // queryFn: () => api.getLearnings(search, limit),
+ queryFn: () => {
+ // شبیهسازی delay سرور
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ let filteredData = staticLearningsData;
+
+ // فیلتر کردن بر اساس جستجو
+ if (search) {
+ filteredData = {
+ data: {
+ learnings: staticLearningsData.data.learnings.filter(
+ (item) =>
+ item.title.toLowerCase().includes(search.toLowerCase()) ||
+ item.description
+ .toLowerCase()
+ .includes(search.toLowerCase()) ||
+ item.category.name
+ .toLowerCase()
+ .includes(search.toLowerCase())
+ ),
+ },
+ };
+ }
+
+ // محدود کردن تعداد نتایج
+ if (limit) {
+ filteredData = {
+ data: {
+ learnings: filteredData.data.learnings.slice(0, limit),
+ },
+ };
+ }
+
+ resolve(filteredData);
+ }, 500);
+ });
+ },
+ });
+};
+
+export const useGetLearningDetail = (id: string) => {
+ return useQuery({
+ queryKey: ["learning", id],
+ // queryFn: () => api.getLearningDetail(id),
+ queryFn: () => {
+ // شبیهسازی delay سرور
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ // پیدا کردن آموزش بر اساس ID
+ const learning = staticLearningsData.data.learnings.find(
+ (item) => item.id === id
+ );
+ if (learning) {
+ resolve({
+ data: {
+ learning: learning,
+ },
+ });
+ } else {
+ resolve(staticLearningDetailData);
+ }
+ }, 300);
+ });
+ },
+ enabled: !!id,
+ });
+};
diff --git a/src/pages/learning/service/LearningService.ts b/src/pages/learning/service/LearningService.ts
new file mode 100644
index 0000000..0fd4221
--- /dev/null
+++ b/src/pages/learning/service/LearningService.ts
@@ -0,0 +1,14 @@
+// import axios from "../../../config/axios";
+
+// Service calls کامنت شده - در حال حاضر از دیتای استاتیک استفاده میشود
+// export const getLearnings = async (search: string, limit?: number) => {
+// const { data } = await axios.get(
+// `/learnings?q=${search}&limit=${limit ? limit : 20}`
+// );
+// return data;
+// };
+
+// export const getLearningDetail = async (id: string) => {
+// const { data } = await axios.get(`/learnings/${id}`);
+// return data;
+// };
diff --git a/src/pages/learning/types/LearningTypes.ts b/src/pages/learning/types/LearningTypes.ts
new file mode 100644
index 0000000..bd2d21d
--- /dev/null
+++ b/src/pages/learning/types/LearningTypes.ts
@@ -0,0 +1,16 @@
+export type LearningItemType = {
+ id: string;
+ title: string;
+ description: string;
+ coverUrl: string;
+ videoUrl: string;
+ videoDuration: string;
+ createdAt: string;
+ updatedAt: string;
+ category: {
+ id: string;
+ name: string;
+ createdAt: string;
+ updatedAt: string;
+ };
+};
diff --git a/src/router/MainRouter.tsx b/src/router/MainRouter.tsx
index ed94f97..6ec09cc 100644
--- a/src/router/MainRouter.tsx
+++ b/src/router/MainRouter.tsx
@@ -14,6 +14,8 @@ import TicketDetail from '@/pages/ticket/Detail'
import AnnouncementList from '@/pages/annoncement/List'
import AnnouncementDetail from '@/pages/annoncement/Detail'
import AddCriticisms from '@/pages/criticisms/Add'
+import LearningList from '@/pages/learning/List'
+import LearningDetail from '@/pages/learning/Detail'
const MainRouter: FC = () => {
return (
@@ -37,6 +39,8 @@ const MainRouter: FC = () => {
} />
} />
} />
+ } />
+ } />
diff --git a/src/shared/Sidebar.tsx b/src/shared/Sidebar.tsx
index ec24bfc..156790d 100644
--- a/src/shared/Sidebar.tsx
+++ b/src/shared/Sidebar.tsx
@@ -96,7 +96,7 @@ const SideBar: FC = () => {
icon={}
title={t('sidebar.learning')}
isActive={isActive('/learning')}
- link={Paths.learning}
+ link={Paths.learning.list}
/>