feat : add download btn in tutorial page for open vpn

This commit is contained in:
alij
2024-06-24 00:26:55 +04:30
parent 206146fc53
commit cc67bee86a
4 changed files with 55 additions and 20 deletions

13
package-lock.json generated
View File

@@ -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",

View File

@@ -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",

View File

@@ -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">

View File

@@ -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>
); );
}; };