feat : add download btn in tutorial page for open vpn
This commit is contained in:
13
package-lock.json
generated
13
package-lock.json
generated
@@ -18,6 +18,7 @@
|
|||||||
"@tsparticles/slim": "^3.4.0",
|
"@tsparticles/slim": "^3.4.0",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"country-flag-icons": "^1.5.11",
|
"country-flag-icons": "^1.5.11",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"framer-motion": "^11.2.9",
|
"framer-motion": "^11.2.9",
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
@@ -35,6 +36,7 @@
|
|||||||
"yup": "^1.4.0"
|
"yup": "^1.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/file-saver": "^2.0.7",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/react": "^18.2.66",
|
"@types/react": "^18.2.66",
|
||||||
"@types/react-dom": "^18.2.22",
|
"@types/react-dom": "^18.2.22",
|
||||||
@@ -2160,6 +2162,12 @@
|
|||||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/file-saver": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/hoist-non-react-statics": {
|
"node_modules/@types/hoist-non-react-statics": {
|
||||||
"version": "3.3.5",
|
"version": "3.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
|
||||||
@@ -3382,6 +3390,11 @@
|
|||||||
"node": "^10.12.0 || >=12.0.0"
|
"node": "^10.12.0 || >=12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/file-saver": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
|
||||||
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
"@tsparticles/slim": "^3.4.0",
|
"@tsparticles/slim": "^3.4.0",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"country-flag-icons": "^1.5.11",
|
"country-flag-icons": "^1.5.11",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"framer-motion": "^11.2.9",
|
"framer-motion": "^11.2.9",
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
@@ -37,6 +38,7 @@
|
|||||||
"yup": "^1.4.0"
|
"yup": "^1.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/file-saver": "^2.0.7",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/react": "^18.2.66",
|
"@types/react": "^18.2.66",
|
||||||
"@types/react-dom": "^18.2.22",
|
"@types/react-dom": "^18.2.22",
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ const Tutorials = () => {
|
|||||||
return axios.get('/home/category/learning')
|
return axios.get('/home/category/learning')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log(data?.data?.result);
|
|
||||||
|
|
||||||
const [activeTutorial, setActiveTutorial] = useState<number>(1);
|
const [activeTutorial, setActiveTutorial] = useState<number>(1);
|
||||||
return (
|
return (
|
||||||
<div className="relative w-full h-full flex flex-col px-4 py-4 text-start">
|
<div className="relative w-full h-full flex flex-col px-4 py-4 text-start">
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { useQuery } from "@tanstack/react-query";
|
|||||||
import useAxios from "../../../../hooks/useAxios";
|
import useAxios from "../../../../hooks/useAxios";
|
||||||
import Alert from "../../../../components/alert/Alert";
|
import Alert from "../../../../components/alert/Alert";
|
||||||
import { MdErrorOutline } from "react-icons/md";
|
import { MdErrorOutline } from "react-icons/md";
|
||||||
|
import Button from "../../../../components/button";
|
||||||
|
import { saveAs } from "file-saver";
|
||||||
|
|
||||||
const Learn = ({ activeTutorial }: LearnProps) => {
|
const Learn = ({ activeTutorial }: LearnProps) => {
|
||||||
const axios = useAxios();
|
const axios = useAxios();
|
||||||
@@ -45,15 +47,37 @@ const Learn = ({ activeTutorial }: LearnProps) => {
|
|||||||
<Alert type="danger" message="خطایی با این موضوع رخ داد: ">
|
<Alert type="danger" message="خطایی با این موضوع رخ داد: ">
|
||||||
{error.message}
|
{error.message}
|
||||||
</Alert>
|
</Alert>
|
||||||
) : data?.data?.result.length === 0 ? (
|
) : data?.data?.result?.learning.length === 0 &&
|
||||||
|
!data?.data?.result?.files ? (
|
||||||
<div className="w-full h-full flex flex-col gap-3 justify-center items-center">
|
<div className="w-full h-full flex flex-col gap-3 justify-center items-center">
|
||||||
<MdErrorOutline className="w-[5rem] h-[5rem]" />
|
<MdErrorOutline className="w-[5rem] h-[5rem]" />
|
||||||
<p className="text-sm md:text-base"> اموزشی وجود ندارد </p>
|
<p className="text-sm md:text-base"> اموزشی وجود ندارد </p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
data?.data?.result.map(
|
<>
|
||||||
(i: { id: string; title: string; medias: string[] }) => {
|
{/* Render files if they exist */}
|
||||||
return (
|
{data?.data?.result?.files &&
|
||||||
|
data?.data?.result?.files.length > 0 && (
|
||||||
|
<div className="w-full h-full p-3 mb-3 flex flex-col justify-center items-center gap-2 bg-gray-900 rounded-md shadow-xl">
|
||||||
|
{data.data.result.files.map(
|
||||||
|
(file: { id: number; title: string; file: string }) => (
|
||||||
|
<div
|
||||||
|
className="w-full h-full flex justify-between gap-4 items-center"
|
||||||
|
key={file.id}
|
||||||
|
>
|
||||||
|
<p className="text-xs md:text-sm">{file.title}</p>
|
||||||
|
<Button extra="!py-1" onClick={() => saveAs(file.file)}>
|
||||||
|
دانلود
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Render learning items */}
|
||||||
|
{data?.data?.result?.learning.map(
|
||||||
|
(i: { id: string; title: string; medias: string[] }) => (
|
||||||
<div
|
<div
|
||||||
key={i.id}
|
key={i.id}
|
||||||
className="relative w-full h-full flex flex-col justify-center items-center"
|
className="relative w-full h-full flex flex-col justify-center items-center"
|
||||||
@@ -62,22 +86,20 @@ const Learn = ({ activeTutorial }: LearnProps) => {
|
|||||||
{i.title}
|
{i.title}
|
||||||
</span>
|
</span>
|
||||||
<div className="relative w-full h-full flex flex-col justify-center items-center">
|
<div className="relative w-full h-full flex flex-col justify-center items-center">
|
||||||
{i.medias.map((medias, index) => {
|
{i.medias.map((media, index) => (
|
||||||
return (
|
|
||||||
<img
|
<img
|
||||||
className="w-full md:w-1/2 mb-3 rounded-lg mx-auto h-full"
|
className="w-full md:w-1/2 mb-3 rounded-lg mx-auto h-full"
|
||||||
src={medias}
|
src={media}
|
||||||
alt="images"
|
alt="images"
|
||||||
key={index}
|
key={index}
|
||||||
/>
|
/>
|
||||||
);
|
))}
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user