diff --git a/bundle-analysis.html b/bundle-analysis.html new file mode 100644 index 0000000..2cd30d0 --- /dev/null +++ b/bundle-analysis.html @@ -0,0 +1,4842 @@ + + + + + + + + Rollup Visualizer + + + +
+ + + + + diff --git a/data.json b/data.json index 7b2b2ca..d20e4f7 100644 --- a/data.json +++ b/data.json @@ -6,7 +6,8 @@ "link4": "لقطة الشاشة", "link5": "ملاحظة", "link6": "اتصل بنا", - "link7":"الخصوصية" + "link7":"الخصوصية", + "link8":"تحميل" }, "Home": { "title": "احصل على تنزيل مجاني لتطبيق", @@ -183,8 +184,8 @@ "privacy": "© زاكر 2024.جميع الحقوق محفوظة" }, "Links": { - "google_play_link": "/", - "apple_store_link": "/", + "google_play_link": "https://play.google.com/store", + "apple_store_link": "https://apps.apple.com", "facebook": "/", "telegram": "/", "instagram": "/", @@ -205,5 +206,9 @@ "NotFound": { "title":"عذرا الصفخة غير موجودة", "description":"ارجع للصفحة الرئيسية" + }, + "Download": { + "title":"", + "description":"" } } diff --git a/index.html b/index.html index 22c7974..8beb06b 100644 --- a/index.html +++ b/index.html @@ -4,9 +4,9 @@ - + - Website + Zaker diff --git a/package-lock.json b/package-lock.json index 162ebff..2758594 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,8 @@ "react-icons": "^5.3.0", "react-player": "^2.16.0", "react-router-dom": "^6.27.0", - "swiper": "^11.1.14" + "swiper": "^11.1.14", + "zustand": "^5.0.0" }, "devDependencies": { "@types/node": "^22.5.1", @@ -4810,6 +4811,34 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zustand": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.0.tgz", + "integrity": "sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } } }, "dependencies": { @@ -7978,6 +8007,12 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true + }, + "zustand": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.0.tgz", + "integrity": "sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==", + "requires": {} } } } diff --git a/package.json b/package.json index 8694127..1ca9aee 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "react-icons": "^5.3.0", "react-player": "^2.16.0", "react-router-dom": "^6.27.0", - "swiper": "^11.1.14" + "swiper": "^11.1.14", + "zustand": "^5.0.0" }, "devDependencies": { "@types/node": "^22.5.1", diff --git a/src/App.tsx b/src/App.tsx index d482190..9c613a8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,44 +1,32 @@ +import './styles/App/index.scss'; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; -import { lazy, Suspense } from 'react'; +import { Suspense } from 'react'; import { Spin } from 'antd'; import Layout from './components/layout/Layout'; -import './styles/App/index.scss'; -const PrivacyPage = lazy(() => import("./pages/Privacy/Page")); -const Page = lazy(() => import("./pages/Main/Page")); -const NotFoundPage = lazy(() => import("./pages/NotFound/NotFound")); +import { routes } from './Routes'; const App = () => { + return ( - }> - - - - - } - /> - }> - - - - - } - /> - }> - - - } - /> + {routes.map((route:any) => ( + }> + {route.withLayout ? ( + + + + ) : ( + + )} + + } + /> + ))} ); diff --git a/src/Routes.tsx b/src/Routes.tsx index 865b639..87edc9f 100644 --- a/src/Routes.tsx +++ b/src/Routes.tsx @@ -1,8 +1,31 @@ -import './styles/App/index.scss'; -import HomePage from './pages/HomePage'; +import { lazy } from 'react'; +import { RouteConfig } from './types/RoutesType'; -const Routes = () => { - return ; -}; +const DownloadPage = lazy(() => import("./pages/Download/Download")); +const PrivacyPage = lazy(() => import("./pages/Privacy/Page")); +const Page = lazy(() => import("./pages/Main/Page")); +const NotFoundPage = lazy(() => import("./pages/NotFound/NotFound")); + + export const routes: RouteConfig[] = [ + { + path: '/', + Component: Page, + withLayout: true, + }, + { + path: '/privacy', + Component: PrivacyPage, + withLayout: true, + }, + { + path: '/download', + Component: DownloadPage, + withLayout: false, + }, + { + path: '*', + Component: NotFoundPage, + withLayout: false, + }, + ]; -export default Routes; diff --git a/src/components/layout/NavBar.tsx b/src/components/layout/NavBar.tsx index 0f25a1b..73dd11f 100644 --- a/src/components/layout/NavBar.tsx +++ b/src/components/layout/NavBar.tsx @@ -23,6 +23,7 @@ const NavBar: React.FC = () => { { path: RoutesEnums.NOTE, label: navBarData.link5 }, { path: RoutesEnums.CONTACT, label: navBarData.link6 }, { path: RoutesEnums.PRIVACY, label: navBarData.link7 }, + { path: RoutesEnums.DOWNLOAD, label: navBarData.link8 }, ]; const [Open, setOpen] = useState(false); const handleToggle = () => { @@ -57,7 +58,6 @@ const NavBar: React.FC = () => { const handleClick = () => { setActive(link.path); }; - console.log(link); const isActive = Active === '' && link.path === '/#' ? true : Active === link.path; diff --git a/src/enums/RoutesEnums.ts b/src/enums/RoutesEnums.ts index b4ec319..03074ac 100644 --- a/src/enums/RoutesEnums.ts +++ b/src/enums/RoutesEnums.ts @@ -6,4 +6,5 @@ export enum RoutesEnums { NOTE = '/#note', CONTACT = '/#contact_us', PRIVACY = '/privacy', + DOWNLOAD = '/download', } diff --git a/src/pages/Download/Download.tsx b/src/pages/Download/Download.tsx new file mode 100644 index 0000000..35329e0 --- /dev/null +++ b/src/pages/Download/Download.tsx @@ -0,0 +1,34 @@ +import { useEffect } from 'react'; +import { useDetectDeviceType } from '../../states/DeviceTypeState'; +import DownloadPage from '../DownloadPage' +import { detectDeviceType } from '../../utils/DetectDeviceType'; +import { Spin } from 'antd'; +import Layout from '../../components/layout/Layout'; +import { ExternalRedirect } from '../../utils/ExternalRedirect'; + +const Download = () => { + const { DeviceType, setDeviceType }: any = useDetectDeviceType(); + + useEffect(() => { + setDeviceType(detectDeviceType()); + }, [setDeviceType]); + + if (!DeviceType) { + return ; + } + return ( +
+ { + DeviceType === 'desktop' ? ( + + + + ) : ( + + ) + } +
+ ) +} + +export default Download \ No newline at end of file diff --git a/src/states/DeviceTypeState.ts b/src/states/DeviceTypeState.ts new file mode 100644 index 0000000..58033aa --- /dev/null +++ b/src/states/DeviceTypeState.ts @@ -0,0 +1,13 @@ +import { create } from 'zustand'; + + + +interface ModalState { + DeviceType: string; + setDeviceType: (value: string) => void; +} +export const useDetectDeviceType = create((set) => ({ + DeviceType: "", + setDeviceType: (value: string) => set(() => ({ DeviceType: value })), +})); + diff --git a/src/styles/App/classNames.scss b/src/styles/App/classNames.scss index 194f386..bb75ba6 100644 --- a/src/styles/App/classNames.scss +++ b/src/styles/App/classNames.scss @@ -31,7 +31,7 @@ outline: none; border: none; border-radius: 10px; - padding: 3vw 1vw; + padding: 35px 15px; background: var(--secondary); color: var(--white); display: flex; diff --git a/src/styles/pages/HowItWork.scss b/src/styles/pages/HowItWork.scss index 61bc107..2bfaa0d 100644 --- a/src/styles/pages/HowItWork.scss +++ b/src/styles/pages/HowItWork.scss @@ -29,6 +29,7 @@ margin-top: 40px; > img { width: 600px; + height: 500px; } > span { display: flex; @@ -96,6 +97,7 @@ margin-top: 40px; > img { width: 300px; + height: 250px; order: 0; } > span { diff --git a/src/types/RoutesType.ts b/src/types/RoutesType.ts new file mode 100644 index 0000000..7e3e2e1 --- /dev/null +++ b/src/types/RoutesType.ts @@ -0,0 +1,5 @@ +export interface RouteConfig { + path: string; + Component: React.LazyExoticComponent | React.FC; + withLayout: boolean; +} \ No newline at end of file diff --git a/src/utils/DetectDeviceType.ts b/src/utils/DetectDeviceType.ts new file mode 100644 index 0000000..b6f29fb --- /dev/null +++ b/src/utils/DetectDeviceType.ts @@ -0,0 +1,16 @@ +export const detectDeviceType = () => { + const ua = navigator.userAgent; + + // Check if it's an iOS device + const isIOS = /iPad|iPhone|iPod/.test(ua) && !(window as any).MSStream; + + if (/android/i.test(ua)) { + return 'android'; + } else if (isIOS) { + return 'ios'; + } else { + return 'desktop'; + } + }; + + diff --git a/src/utils/ExternalRedirect.ts b/src/utils/ExternalRedirect.ts new file mode 100644 index 0000000..90f7e1e --- /dev/null +++ b/src/utils/ExternalRedirect.ts @@ -0,0 +1,9 @@ +import { useEffect } from "react"; + +export const ExternalRedirect = ({ url }: { url: string }) => { + useEffect(() => { + window.location.href = url; + }, [url]); + + return null; // This component renders nothing + }; \ No newline at end of file