done
23
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
/.pnp
|
||||
.pnp.js
|
||||
;
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
13
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"cSpell.words": [
|
||||
"aldeen",
|
||||
"currentlanguage",
|
||||
"Datepicker",
|
||||
"formik",
|
||||
"Karim",
|
||||
"queryqlent",
|
||||
"setstyle",
|
||||
"szhsin",
|
||||
"Viewelement"
|
||||
]
|
||||
}
|
||||
48
db.json
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
"example":[
|
||||
{
|
||||
"type": "Bernadette O'Reilly",
|
||||
"href": "/Dennis Von",
|
||||
"data": [
|
||||
|
||||
],
|
||||
"count": 48,
|
||||
"id": "10"
|
||||
},
|
||||
{
|
||||
"type": "Jeanette",
|
||||
"href": "/Patsy",
|
||||
"data": [
|
||||
|
||||
],
|
||||
"count": 32613,
|
||||
"id": "12"
|
||||
},
|
||||
{
|
||||
"type": "Marion",
|
||||
"href": "/MissLuis",
|
||||
"data": [
|
||||
|
||||
],
|
||||
"count": 71846,
|
||||
"id": "13"
|
||||
},
|
||||
{
|
||||
"type": "Jean",
|
||||
"href": "/Georgia",
|
||||
"data": [
|
||||
|
||||
],
|
||||
"count": 8268,
|
||||
"id": "14"
|
||||
}
|
||||
],
|
||||
"users": [
|
||||
{
|
||||
"id": 1,
|
||||
"email": "admin@adamin.com",
|
||||
"password": "password",
|
||||
"token": "token"
|
||||
}
|
||||
]
|
||||
}
|
||||
20
index.html
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
|
||||
|
||||
<title>React-ts</title>
|
||||
</head>
|
||||
<script type="module" src="/src/index.tsx"></script>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
34650
package-lock.json
generated
Normal file
104
package.json
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
{
|
||||
"name": "my-app",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
"@emailjs/browser": "^4.3.3",
|
||||
"@reduxjs/toolkit": "^1.9.7",
|
||||
"@szhsin/react-menu": "github:szhsin/react-menu",
|
||||
"@testing-library/jest-dom": "^5.17.0",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^16.18.60",
|
||||
"@types/react": "^18.2.33",
|
||||
"@types/react-dom": "^18.2.14",
|
||||
"@types/react-slick": "^0.23.12",
|
||||
"@wojtekmaj/react-daterange-picker": "^5.4.4",
|
||||
"antd": "^5.11.1",
|
||||
"apexcharts": "^3.44.0",
|
||||
"axios": "^1.6.0",
|
||||
"bootstrap": "^5.3.2",
|
||||
"chart.js": "^4.4.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"formik": "^2.4.5",
|
||||
"i18next": "^23.6.0",
|
||||
"i18next-browser-languagedetector": "^7.1.0",
|
||||
"json-server": "^0.17.4",
|
||||
"mdb-react-ui-kit": "^7.2.0",
|
||||
"react": "^18.2.0",
|
||||
"react-alice-carousel": "^2.8.0",
|
||||
"react-bootstrap": "^2.9.1",
|
||||
"react-bootstrap-sweetalert": "^5.2.0",
|
||||
"react-chartjs-2": "^5.2.0",
|
||||
"react-confirm-alert": "^3.0.6",
|
||||
"react-data-table-component": "^7.5.4",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-feather": "^2.0.10",
|
||||
"react-i18next": "^13.3.1",
|
||||
"react-icons": "^4.11.0",
|
||||
"react-id-swiper": "^4.0.0",
|
||||
"react-multi-carousel": "^2.8.4",
|
||||
"react-player": "^2.16.0",
|
||||
"react-query": "^3.39.3",
|
||||
"react-redux": "^8.1.3",
|
||||
"react-responsive-carousel": "^3.2.23",
|
||||
"react-router-dom": "^6.18.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-select-country-list": "^2.2.3",
|
||||
"react-slick": "^0.29.0",
|
||||
"react-tabs": "^6.0.2",
|
||||
"react-toastify": "^9.1.3",
|
||||
"react-toggle": "^4.1.3",
|
||||
"react-transition-group": "^4.4.5",
|
||||
"react-verification-code-input": "^1.2.9",
|
||||
"reactstrap": "^9.2.0",
|
||||
"sass": "^1.69.5",
|
||||
"slick-carousel": "^1.8.1",
|
||||
"source-map-explorer": "^2.5.3",
|
||||
"styled-components": "5.3.3",
|
||||
"swiper": "^11.0.5",
|
||||
"typescript": "^4.9.5",
|
||||
"web-vitals": "^2.1.4",
|
||||
"yup": "^1.3.2",
|
||||
"zustand": "^4.4.5"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"build": "vite build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"g:api": "node src/Extensions/FileGenerator/generateApi.js",
|
||||
"g:column": "node src/Extensions/FileGenerator/generateColumn.js",
|
||||
"g:formutil": "node src/Extensions/FileGenerator/generateformUtils.js",
|
||||
"g:page": "node src/Extensions/FileGenerator/generatePage.js",
|
||||
"g:dashboard": "node src/Extensions/FileGenerator/generateDashboard.js ",
|
||||
"g:modal:add": "node src/Extensions/FileGenerator/generateEditModal.js ",
|
||||
"g:model:edit": "node src/Extensions/FileGenerator/generateEditModal.js ",
|
||||
"analyze": "source-map-explorer 'build/static/js/*.js'"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-react": "^4.3.0",
|
||||
"unplugin-auto-import": "^0.17.6",
|
||||
"vite": "^5.2.12"
|
||||
}
|
||||
}
|
||||
12898
pnpm-lock.yaml
Normal file
BIN
public/About/About.png
Normal file
|
After Width: | Height: | Size: 485 KiB |
104
public/About/about.svg
Normal file
|
After Width: | Height: | Size: 12 MiB |
BIN
public/App/BigGmap.png
Normal file
|
After Width: | Height: | Size: 435 KiB |
BIN
public/App/CheckMark.png
Normal file
|
After Width: | Height: | Size: 600 B |
BIN
public/App/product.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
public/App/productManual.png
Normal file
|
After Width: | Height: | Size: 556 B |
BIN
public/Document/documentCard.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
public/Home/Gmap.png
Normal file
|
After Width: | Height: | Size: 258 KiB |
BIN
public/Home/checkoutSwiperCard.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
public/Home/heroImage.png
Normal file
|
After Width: | Height: | Size: 971 KiB |
BIN
public/Home/productReview1.png
Normal file
|
After Width: | Height: | Size: 287 KiB |
BIN
public/Home/productReview2.png
Normal file
|
After Width: | Height: | Size: 148 KiB |
BIN
public/Home/productReview3.png
Normal file
|
After Width: | Height: | Size: 182 KiB |
BIN
public/Home/productReview4.png
Normal file
|
After Width: | Height: | Size: 250 KiB |
BIN
public/Home/settingIcon.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
1
public/Layout/Ar.svg
Normal file
|
After Width: | Height: | Size: 10 KiB |
1
public/Layout/En.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="42.67" height="32" viewBox="0 0 640 480"><defs><clipPath id="flagUm4x30"><path fill-opacity=".7" d="M0 0h682.7v512H0z"/></clipPath></defs><g fill-rule="evenodd" clip-path="url(#flagUm4x30)" transform="scale(.9375)"><g stroke-width="1pt"><path fill="#bd3d44" d="M0 0h972.8v39.4H0zm0 78.8h972.8v39.4H0zm0 78.7h972.8V197H0zm0 78.8h972.8v39.4H0zm0 78.8h972.8v39.4H0zm0 78.7h972.8v39.4H0zm0 78.8h972.8V512H0z"/><path fill="#fff" d="M0 39.4h972.8v39.4H0zm0 78.8h972.8v39.3H0zm0 78.7h972.8v39.4H0zm0 78.8h972.8v39.4H0zm0 78.8h972.8v39.4H0zm0 78.7h972.8v39.4H0z"/></g><path fill="#192f5d" d="M0 0h389.1v275.7H0z"/><path fill="#fff" d="M32.4 11.8L36 22.7h11.4l-9.2 6.7l3.5 11l-9.3-6.8l-9.2 6.7l3.5-10.9l-9.3-6.7H29zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.5 11l-9.2-6.8l-9.3 6.7l3.5-10.9l-9.2-6.7h11.4zm64.8 0l3.6 10.9H177l-9.2 6.7l3.5 11l-9.3-6.8l-9.2 6.7l3.5-10.9l-9.3-6.7h11.5zm64.9 0l3.5 10.9H242l-9.3 6.7l3.6 11l-9.3-6.8l-9.3 6.7l3.6-10.9l-9.3-6.7h11.4zm64.8 0l3.6 10.9h11.4l-9.2 6.7l3.5 11l-9.3-6.8l-9.2 6.7l3.5-10.9l-9.2-6.7h11.4zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.6 11l-9.3-6.8l-9.3 6.7l3.6-10.9l-9.3-6.7h11.5zM64.9 39.4l3.5 10.9h11.5L70.6 57L74 67.9l-9-6.7l-9.3 6.7L59 57l-9-6.7h11.4zm64.8 0l3.6 10.9h11.4l-9.3 6.7l3.6 10.9l-9.3-6.7l-9.3 6.7L124 57l-9.3-6.7h11.5zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.5 10.9l-9.2-6.7l-9.3 6.7l3.5-10.9l-9.2-6.7H191zm64.8 0l3.6 10.9h11.4l-9.3 6.7l3.6 10.9l-9.3-6.7l-9.2 6.7l3.5-10.9l-9.3-6.7H256zm64.9 0l3.5 10.9h11.5L330 57l3.5 10.9l-9.2-6.7l-9.3 6.7l3.5-10.9l-9.2-6.7h11.4zM32.4 66.9L36 78h11.4l-9.2 6.7l3.5 10.9l-9.3-6.8l-9.2 6.8l3.5-11l-9.3-6.7H29zm64.9 0l3.5 11h11.5l-9.3 6.7l3.5 10.9l-9.2-6.8l-9.3 6.8l3.5-11l-9.2-6.7h11.4zm64.8 0l3.6 11H177l-9.2 6.7l3.5 10.9l-9.3-6.8l-9.2 6.8l3.5-11l-9.3-6.7h11.5zm64.9 0l3.5 11H242l-9.3 6.7l3.6 10.9l-9.3-6.8l-9.3 6.8l3.6-11l-9.3-6.7h11.4zm64.8 0l3.6 11h11.4l-9.2 6.7l3.5 10.9l-9.3-6.8l-9.2 6.8l3.5-11l-9.2-6.7h11.4zm64.9 0l3.5 11h11.5l-9.3 6.7l3.6 10.9l-9.3-6.8l-9.3 6.8l3.6-11l-9.3-6.7h11.5zM64.9 94.5l3.5 10.9h11.5l-9.3 6.7l3.5 11l-9.2-6.8l-9.3 6.7l3.5-10.9l-9.2-6.7h11.4zm64.8 0l3.6 10.9h11.4l-9.3 6.7l3.6 11l-9.3-6.8l-9.3 6.7l3.6-10.9l-9.3-6.7h11.5zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.5 11l-9.2-6.8l-9.3 6.7l3.5-10.9l-9.2-6.7H191zm64.8 0l3.6 10.9h11.4l-9.2 6.7l3.5 11l-9.3-6.8l-9.2 6.7l3.5-10.9l-9.3-6.7H256zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.5 11l-9.2-6.8l-9.3 6.7l3.5-10.9l-9.2-6.7h11.4zM32.4 122.1L36 133h11.4l-9.2 6.7l3.5 11l-9.3-6.8l-9.2 6.7l3.5-10.9l-9.3-6.7H29zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.5 10.9l-9.2-6.7l-9.3 6.7l3.5-10.9l-9.2-6.7h11.4zm64.8 0l3.6 10.9H177l-9.2 6.7l3.5 11l-9.3-6.8l-9.2 6.7l3.5-10.9l-9.3-6.7h11.5zm64.9 0l3.5 10.9H242l-9.3 6.7l3.6 11l-9.3-6.8l-9.3 6.7l3.6-10.9l-9.3-6.7h11.4zm64.8 0l3.6 10.9h11.4l-9.2 6.7l3.5 11l-9.3-6.8l-9.2 6.7l3.5-10.9l-9.2-6.7h11.4zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.6 11l-9.3-6.8l-9.3 6.7l3.6-10.9l-9.3-6.7h11.5zM64.9 149.7l3.5 10.9h11.5l-9.3 6.7l3.5 10.9l-9.2-6.8l-9.3 6.8l3.5-11l-9.2-6.7h11.4zm64.8 0l3.6 10.9h11.4l-9.3 6.7l3.6 10.9l-9.3-6.8l-9.3 6.8l3.6-11l-9.3-6.7h11.5zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.5 10.9l-9.2-6.8l-9.3 6.8l3.5-11l-9.2-6.7H191zm64.8 0l3.6 10.9h11.4l-9.2 6.7l3.5 10.9l-9.3-6.8l-9.2 6.8l3.5-11l-9.3-6.7H256zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.5 10.9l-9.2-6.8l-9.3 6.8l3.5-11l-9.2-6.7h11.4zM32.4 177.2l3.6 11h11.4l-9.2 6.7l3.5 10.8l-9.3-6.7l-9.2 6.7l3.5-10.9l-9.3-6.7H29zm64.9 0l3.5 11h11.5l-9.3 6.7l3.6 10.8l-9.3-6.7l-9.3 6.7l3.6-10.9l-9.3-6.7h11.4zm64.8 0l3.6 11H177l-9.2 6.7l3.5 10.8l-9.3-6.7l-9.2 6.7l3.5-10.9l-9.3-6.7h11.5zm64.9 0l3.5 11H242l-9.3 6.7l3.6 10.8l-9.3-6.7l-9.3 6.7l3.6-10.9l-9.3-6.7h11.4zm64.8 0l3.6 11h11.4l-9.2 6.7l3.5 10.8l-9.3-6.7l-9.2 6.7l3.5-10.9l-9.2-6.7h11.4zm64.9 0l3.5 11h11.5l-9.3 6.7l3.6 10.8l-9.3-6.7l-9.3 6.7l3.6-10.9l-9.3-6.7h11.5zM64.9 204.8l3.5 10.9h11.5l-9.3 6.7l3.5 11l-9.2-6.8l-9.3 6.7l3.5-10.9l-9.2-6.7h11.4zm64.8 0l3.6 10.9h11.4l-9.3 6.7l3.6 11l-9.3-6.8l-9.3 6.7l3.6-10.9l-9.3-6.7h11.5zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.5 11l-9.2-6.8l-9.3 6.7l3.5-10.9l-9.2-6.7H191zm64.8 0l3.6 10.9h11.4l-9.2 6.7l3.5 11l-9.3-6.8l-9.2 6.7l3.5-10.9l-9.3-6.7H256zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.5 11l-9.2-6.8l-9.3 6.7l3.5-10.9l-9.2-6.7h11.4zM32.4 232.4l3.6 10.9h11.4l-9.2 6.7l3.5 10.9l-9.3-6.7l-9.2 6.7l3.5-11l-9.3-6.7H29zm64.9 0l3.5 10.9h11.5L103 250l3.6 10.9l-9.3-6.7l-9.3 6.7l3.6-11l-9.3-6.7h11.4zm64.8 0l3.6 10.9H177l-9 6.7l3.5 10.9l-9.3-6.7l-9.2 6.7l3.5-11l-9.3-6.7h11.5zm64.9 0l3.5 10.9H242l-9.3 6.7l3.6 10.9l-9.3-6.7l-9.3 6.7l3.6-11l-9.3-6.7h11.4zm64.8 0l3.6 10.9h11.4l-9.2 6.7l3.5 10.9l-9.3-6.7l-9.2 6.7l3.5-11l-9.2-6.7h11.4zm64.9 0l3.5 10.9h11.5l-9.3 6.7l3.6 10.9l-9.3-6.7l-9.3 6.7l3.6-11l-9.3-6.7h11.5z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
BIN
public/Layout/FooterImage.png
Normal file
|
After Width: | Height: | Size: 624 KiB |
1
public/Layout/dark.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 64 64"><path fill="currentColor" d="M43.139 2a29.885 29.885 0 0 1 5.121 16.756c0 16.701-13.686 30.24-30.57 30.24a30.656 30.656 0 0 1-15.689-4.285C7.209 54.963 17.93 62 30.318 62C47.816 62 62 47.969 62 30.66C62 17.867 54.246 6.871 43.139 2z"/></svg>
|
||||
|
After Width: | Height: | Size: 324 B |
1
public/Layout/light.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 512 512"><path fill="currentColor" d="M256 160c-52.9 0-96 43.1-96 96s43.1 96 96 96s96-43.1 96-96s-43.1-96-96-96zm246.4 80.5l-94.7-47.3l33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5l-47.4-94.8c-6.4-12.8-24.6-12.8-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4l-94.7 47.4c-12.8 6.4-12.8 24.6 0 31l94.7 47.3l-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.4-33.5l47.3 94.7c6.4 12.8 24.6 12.8 31 0l47.3-94.7l100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4l94.7-47.3c13-6.5 13-24.7.2-31.1zm-155.9 106c-49.9 49.9-131.1 49.9-181 0c-49.9-49.9-49.9-131.1 0-181c49.9-49.9 131.1-49.9 181 0c49.9 49.9 49.9 131.1 0 181z"/></svg>
|
||||
|
After Width: | Height: | Size: 715 B |
BIN
public/Logo/Logo.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
108
public/MainPartnerr.svg
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
public/Partner/partner1.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
public/Service/Services.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
public/Service/ServicesRes.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
136
public/Service/service.svg
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
public/Service/serviceImage.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
141
public/Service/serviceRes.svg
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
public/Team/team1.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
25
public/manifest.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
3
public/robots.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
34
src/App.tsx
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { lazy, Suspense } from 'react';
|
||||
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
|
||||
import LoadingAntd from './Components/Utils/Loading/LoadingAntd';
|
||||
import { routesArray } from './config/RoutesArray';
|
||||
import Layout from './Layout/Layout';
|
||||
|
||||
const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Suspense fallback={<LoadingAntd />}>
|
||||
<Routes>
|
||||
{routesArray.map(({ path, LayoutClassName, ComponentElement, isLayoutExist }) => (
|
||||
<Route
|
||||
key={path}
|
||||
path={path}
|
||||
element={
|
||||
isLayoutExist ? (
|
||||
<Layout className={LayoutClassName}>
|
||||
<ComponentElement />
|
||||
</Layout>
|
||||
) : (
|
||||
<ComponentElement />
|
||||
)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</Routes>
|
||||
</Suspense>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
15
src/Components/CheckoutOurNew/All.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import BaseSingleTab from './BaseSingleTab'
|
||||
import { checkoutItemsLighting } from '../../data/Checkout'
|
||||
|
||||
const All = () => {
|
||||
return (
|
||||
<BaseSingleTab
|
||||
data={checkoutItemsLighting}
|
||||
title='CHECKOUT OUR NEW'
|
||||
sub_title='Our product groups'
|
||||
text='Products and technologies that transcend the times in industrial automation'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default All
|
||||
16
src/Components/CheckoutOurNew/Automation.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import React from 'react'
|
||||
import { checkoutItemsLighting } from '../../data/Checkout'
|
||||
import BaseSingleTab from './BaseSingleTab'
|
||||
|
||||
const Automation = () => {
|
||||
return (
|
||||
<BaseSingleTab
|
||||
data={checkoutItemsLighting}
|
||||
title='CHECKOUT OUR NEW'
|
||||
sub_title='Industrial Automation Products'
|
||||
text='In the industrial automation sector, which we entered into in 2006, we are among the world-class premium companies that provide energy efficiency.'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default Automation
|
||||
28
src/Components/CheckoutOurNew/BaseSingleTab.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import BaseSwiper from './BaseSwiperForTabs';
|
||||
|
||||
interface BaseSingleTabProps {
|
||||
data:any;
|
||||
title:string,
|
||||
sub_title:string;
|
||||
text:string
|
||||
}
|
||||
|
||||
|
||||
const BaseSingleTab = ({data,title,sub_title,text}:BaseSingleTabProps) => {
|
||||
const {t} = useTranslation();
|
||||
|
||||
|
||||
return (
|
||||
<div className='checkout_single_tab'>
|
||||
<div className="details">
|
||||
<h1>{t(title)}</h1>
|
||||
<h2>{t(sub_title)}</h2>
|
||||
<p>{t(text)}</p>
|
||||
|
||||
</div>
|
||||
<BaseSwiper data={data} isLoading={false}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default BaseSingleTab
|
||||
51
src/Components/CheckoutOurNew/BaseSwiperForTabs.tsx
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import "swiper/css";
|
||||
import 'swiper/css/free-mode';
|
||||
import "swiper/css/navigation";
|
||||
import "swiper/css/pagination";
|
||||
import "swiper/css/scrollbar";import { A11y, Autoplay, Navigation,Scrollbar } from 'swiper/modules';
|
||||
import Spinner from '../Utils/Loading/Spinner';
|
||||
import TeamCard from '../Ui/TeamCard';
|
||||
import CheckoutCard from './CheckoutCard';
|
||||
|
||||
|
||||
|
||||
const BaseSwiper = ({data,isLoading}:{data:any,isLoading:boolean}) => {
|
||||
|
||||
return (
|
||||
<div className='checkout_Swiper'>
|
||||
<Swiper
|
||||
dir={'ltr'}
|
||||
slidesPerView={3}
|
||||
spaceBetween={60}
|
||||
breakpoints={{
|
||||
0: { slidesPerView: 1 },
|
||||
400: { slidesPerView: 1 },
|
||||
600: { slidesPerView: 1 },
|
||||
900: { slidesPerView: 2 },
|
||||
1200: { slidesPerView: 2 },
|
||||
1500: { slidesPerView: 3 },
|
||||
}}
|
||||
navigation
|
||||
autoplay={true}
|
||||
modules={[Navigation, Scrollbar, A11y, Autoplay]}
|
||||
pagination={{ clickable: true }}
|
||||
className="mySwiper"
|
||||
>
|
||||
{
|
||||
isLoading ? <Spinner/> :
|
||||
data?.map((item:any, index:number) => (
|
||||
<SwiperSlide key={index}>
|
||||
<CheckoutCard
|
||||
name={item?.name}
|
||||
src={item?.src}
|
||||
key={index}
|
||||
/>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default BaseSwiper;
|
||||
11
src/Components/CheckoutOurNew/CheckoutCard.tsx
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
const CheckoutCard = ({src,name}:{src:string,name:string}) => {
|
||||
return (
|
||||
<div className='checkout_card'>
|
||||
<img src={src} alt={name} />
|
||||
<h4>{name}</h4>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CheckoutCard
|
||||
27
src/Components/CheckoutOurNew/CheckoutOurNew.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import CheckoutTabs from './CheckoutTabs'
|
||||
import All from './All';
|
||||
import Lighting from './Lighting';
|
||||
import Automation from './Automation';
|
||||
|
||||
const CheckoutOurNew = () => {
|
||||
const [activeButton, setActiveButton] = useState(0);
|
||||
|
||||
return (
|
||||
<div className='checkout_our_new'>
|
||||
<CheckoutTabs
|
||||
activeButton={activeButton}
|
||||
setActiveButton={setActiveButton}
|
||||
/>
|
||||
|
||||
{activeButton === 0 ? (
|
||||
<All />
|
||||
) : activeButton === 1 ? (
|
||||
<Lighting />
|
||||
) : (
|
||||
<Automation />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CheckoutOurNew
|
||||
33
src/Components/CheckoutOurNew/CheckoutTabs.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { useButtonState } from '../../zustand/ButtonState';
|
||||
|
||||
const CheckoutTabs = ({ activeButton, setActiveButton }: any) => {
|
||||
|
||||
const { setActiveTab } = useButtonState((state) => state);
|
||||
|
||||
// Function to handle button click
|
||||
const handleButtonClick = (index: number) => {
|
||||
setActiveButton(index);
|
||||
setActiveTab(index);
|
||||
};
|
||||
const {t} = useTranslation();
|
||||
const buttonLabels = [
|
||||
t("All"),
|
||||
t("lighting"),
|
||||
t("Automation"),
|
||||
];
|
||||
|
||||
return (
|
||||
<div className='checkout_button_tabs'>
|
||||
{buttonLabels.map((label, index) => (
|
||||
<button
|
||||
key={index}
|
||||
className={activeButton === index ? "Activebutton" : "button"}
|
||||
onClick={() => handleButtonClick(index)}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
))}</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CheckoutTabs
|
||||
15
src/Components/CheckoutOurNew/Lighting.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { checkoutItemsLighting } from '../../data/Checkout';
|
||||
import BaseSingleTab from './BaseSingleTab';
|
||||
|
||||
const Lighting = () => {
|
||||
return (
|
||||
<BaseSingleTab
|
||||
data={checkoutItemsLighting}
|
||||
title='CHECKOUT OUR NEW'
|
||||
sub_title='Latest Professional Lighting'
|
||||
text='We provide a wide range of indoor and outdoor lighting products, project design and supervision services in relation to technical and architectural lighting, and lighting control area.'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default Lighting
|
||||
43
src/Components/Distributor/CollapsChildren.tsx
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import React from 'react'
|
||||
import { CiMail } from "react-icons/ci";
|
||||
import { FaPhoneFlip } from "react-icons/fa6";
|
||||
import { SlPrinter } from "react-icons/sl";
|
||||
|
||||
const CollapsChildren = () => {
|
||||
return (
|
||||
<div className='collaps_children'>
|
||||
<h1>EBRU SOFT YAZILIM BİLG. LTD. ŞTİ.</h1>
|
||||
<p>İvedik O.S.B. Melih Gökçek Blv. Eminel İş Mrkz. No:18/46 Yenimahalle/ANKARA</p>
|
||||
|
||||
<FaPhoneFlip/>
|
||||
<p>+90 (216) 314 59 00</p>
|
||||
|
||||
<SlPrinter/>
|
||||
<p>+90 (312) 385 12 76</p>
|
||||
|
||||
<CiMail/>
|
||||
<p>Boutique@Butykotomasion.com</p>
|
||||
|
||||
<CiMail/>
|
||||
<p>Boutique@Butykotomasion.com</p>
|
||||
|
||||
<h1>EBRU SOFT YAZILIM BİLG. LTD. ŞTİ.</h1>
|
||||
<p>İvedik O.S.B. Melih Gökçek Blv. Eminel İş Mrkz. No:18/46 Yenimahalle/ANKARA</p>
|
||||
|
||||
<FaPhoneFlip/>
|
||||
<p>+90 (216) 314 59 00</p>
|
||||
|
||||
<SlPrinter/>
|
||||
<p>+90 (312) 385 12 76</p>
|
||||
|
||||
<CiMail/>
|
||||
<p>Boutique@Butykotomasion.com</p>
|
||||
|
||||
<CiMail/>
|
||||
<p>Boutique@Butykotomasion.com</p>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CollapsChildren
|
||||
37
src/Components/Distributor/Distributor.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import React from 'react'
|
||||
import { DistributorArray, DistributorArray2 } from '../../data/Distributor'
|
||||
import DistributorWord from '../Ui/DistributorWord'
|
||||
import AnimationButton from '../Ui/AnimationButton'
|
||||
|
||||
const Distributor = () => {
|
||||
const {t} = useTranslation()
|
||||
return (
|
||||
<div className='Distributor'>
|
||||
<div className="left">
|
||||
<h1>{t("Our Distributors")}</h1>
|
||||
<h4>{t("Look at our local distributors")}</h4>
|
||||
<div className='word_container'>
|
||||
<div>
|
||||
{DistributorArray.map((e) =>(
|
||||
<DistributorWord title={e.title}/>
|
||||
))}
|
||||
</div>
|
||||
<div>
|
||||
{DistributorArray2.map((e) =>(
|
||||
<DistributorWord title={e.title}/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="button_container">
|
||||
<AnimationButton withAnimation={false} link='/' text='See Details'/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="right">
|
||||
<img src="/Home/Gmap.png" alt="googleMap" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Distributor
|
||||
114
src/Components/Distributor/DistributorCollaps.tsx
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
import type { CollapseProps } from "antd";
|
||||
import { Collapse } from "antd";
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from "react-i18next";
|
||||
import classNames from 'classnames';
|
||||
import CollapsChildren from "./CollapsChildren";
|
||||
|
||||
const DistributorCollaps = () => {
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [activeKey, setActiveKey] = useState<string[]>(["1"]);
|
||||
|
||||
const onChange = (key: string | string[]) => {
|
||||
if (typeof key === 'string') {
|
||||
setActiveKey([key]);
|
||||
} else {
|
||||
setActiveKey(key);
|
||||
}
|
||||
};
|
||||
|
||||
const items: CollapseProps["items"] = [
|
||||
{
|
||||
style:{background:"transparent"},
|
||||
key: "1",
|
||||
label: t("Ankara"),
|
||||
children: (
|
||||
<p>
|
||||
<CollapsChildren/>
|
||||
</p>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "2",
|
||||
label: t("Gaziantep"),
|
||||
children: (
|
||||
<p>
|
||||
<CollapsChildren/>
|
||||
</p>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "3",
|
||||
label: t("İstanbul"),
|
||||
children: (
|
||||
<p>
|
||||
{/* {t("Sakarya")}. */}
|
||||
</p>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "4",
|
||||
label: t("İzmir"),
|
||||
children: (
|
||||
<p>
|
||||
{/* {t("Sakarya")}. */}
|
||||
</p>
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
key: "5",
|
||||
label: t("Kocaeli"),
|
||||
children: (
|
||||
<p>
|
||||
{/* {t("Sakarya")}. */}
|
||||
</p>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "6",
|
||||
label: t("Konya"),
|
||||
children: (
|
||||
<p>
|
||||
{/* {t("Sakarya")}. */}
|
||||
</p>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "7",
|
||||
label: t("Sakarya"),
|
||||
children: (
|
||||
<p>
|
||||
{/* {t("Sakarya")}. */}
|
||||
</p>
|
||||
),
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
return (
|
||||
<Collapse
|
||||
className="distributor_collaps"
|
||||
defaultActiveKey={["1"]}
|
||||
expandIconPosition="right"
|
||||
bordered={false}
|
||||
activeKey={activeKey}
|
||||
onChange={onChange}
|
||||
|
||||
items={items.map(item => ({
|
||||
...item,
|
||||
label: (
|
||||
<span
|
||||
className={classNames({
|
||||
'label-active': activeKey.includes(item.key as string)
|
||||
})}
|
||||
>
|
||||
{item.label}
|
||||
</span>
|
||||
)
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
};
|
||||
export default DistributorCollaps
|
||||
78
src/Components/Document/Document.tsx
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Pagination } from 'antd';
|
||||
import DocumentCard from './DocumentCard';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useWindowResize } from '../../Hooks/useWindowResize';
|
||||
import { useGetCertificate } from '../../api/certificate';
|
||||
|
||||
const Document: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const [isChanging, setIsChanging] = useState(false);
|
||||
const { windowWidth } = useWindowResize();
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [totalItems, setTotalItems] = useState(0);
|
||||
const [perPage, setPerPage] = useState(3);
|
||||
const { data } = useGetCertificate({ page: currentPage, per_page: perPage });
|
||||
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const handlePageChange = (page: number) => {
|
||||
setIsChanging(true);
|
||||
setTimeout(() => {
|
||||
setCurrentPage(page);
|
||||
navigate(`${location.pathname}?page=${page}`);
|
||||
setIsChanging(false);
|
||||
}, 300);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search);
|
||||
const pageParam = params.get('page');
|
||||
const page = pageParam ? parseInt(pageParam, 10) : 1;
|
||||
setCurrentPage(page);
|
||||
}, [location.search]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data?.meta) {
|
||||
setTotalItems(data.meta.total);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
if (windowWidth < 600) {
|
||||
setPerPage(1);
|
||||
} else if (windowWidth < 1300) {
|
||||
setPerPage(2);
|
||||
} else {
|
||||
setPerPage(3);
|
||||
}
|
||||
}, [windowWidth]);
|
||||
|
||||
return (
|
||||
<div className='Document'>
|
||||
<h1>{t("Documents")}</h1>
|
||||
<h2>{t("Quality Certificates")}</h2>
|
||||
|
||||
<Pagination
|
||||
current={currentPage}
|
||||
pageSize={perPage}
|
||||
total={totalItems}
|
||||
onChange={handlePageChange}
|
||||
/>
|
||||
<div className={`document-cards ${isChanging ? 'changing' : ''}`}>
|
||||
{data?.data?.map((item: any) => (
|
||||
<DocumentCard
|
||||
key={item.id}
|
||||
name={item?.name}
|
||||
image={item?.image}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Document;
|
||||
18
src/Components/Document/DocumentCard.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import React from 'react'
|
||||
|
||||
const DocumentCard = ({name,text,image}:any) => {
|
||||
|
||||
|
||||
return (
|
||||
<div className='Document_card'>
|
||||
<div className="image_container">
|
||||
<img src={image} alt="document_card" />
|
||||
</div>
|
||||
|
||||
<h1>{name}</h1>
|
||||
{/* <p>{text}</p> */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DocumentCard
|
||||
44
src/Components/HOC/SearchWithDrawer.tsx
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import { useState } from 'react';
|
||||
import type { DrawerProps } from 'antd';
|
||||
import { Drawer, Space } from 'antd';
|
||||
import { TiDeleteOutline } from "react-icons/ti";
|
||||
import SearchButton from '../Utils/Search/SearchButton';
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
import Empty from '../Utils/Search/Empty';
|
||||
|
||||
const SearchWithDrawer = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [placement, setPlacement] = useState<DrawerProps['placement']>('right');
|
||||
const [noDataFound, setNoDataFound] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Space>
|
||||
<div onClick={() => setOpen(true)} className="icon_navbar">
|
||||
<RiSearchLine />
|
||||
</div>
|
||||
</Space>
|
||||
|
||||
<Drawer
|
||||
title={""}
|
||||
placement={placement}
|
||||
closable={false}
|
||||
onClose={() => setOpen(false)}
|
||||
open={open}
|
||||
key={placement}
|
||||
width={720}
|
||||
style={{ maxHeight: "40%" }}
|
||||
>
|
||||
<div className="search_first_section">
|
||||
<SearchButton setOpen={setOpen} setNoDataFound={setNoDataFound} />
|
||||
<span className='delete_icon' onClick={() => setOpen(false)}><TiDeleteOutline /></span>
|
||||
</div>
|
||||
<div className='not_found_section'>
|
||||
{noDataFound ? <Empty />:"" }
|
||||
</div>
|
||||
</Drawer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchWithDrawer;
|
||||
41
src/Components/Home/ComprehensivePurchase.tsx
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import React from 'react'
|
||||
import { IoIosArrowForward } from "react-icons/io";
|
||||
|
||||
const ComprehensivePurchase = () => {
|
||||
const {t} = useTranslation();
|
||||
return (
|
||||
<div className='comprehensive_purchase'>
|
||||
<h1>{t("products")}</h1>
|
||||
<h4>{t("Comprehensive purchase of all low voltage and lighting products")}</h4>
|
||||
<div className="first">
|
||||
<div>
|
||||
<Link className='products_link' to={'/products'}><img src="/Home/productReview1.png" alt="" /></Link>
|
||||
<h6>{t("measurement")}</h6>
|
||||
<p>{t("Explore")} <IoIosArrowForward/></p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Link className='products_link' to={'/products'}><img src="/Home/productReview2.png" alt="" /></Link>
|
||||
<h6>{t("End")}</h6>
|
||||
<p>{t("Explore")} <IoIosArrowForward/></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="second first">
|
||||
|
||||
<div>
|
||||
<Link className='products_link' to={'/products'}><img src="/Home/productReview3.png" alt="" /></Link>
|
||||
<h6>{t("Power & Control")}</h6>
|
||||
<p>{t("Explore")} <IoIosArrowForward/></p>
|
||||
</div>
|
||||
<div>
|
||||
<Link className='products_link' to={'/products'}><img src="/Home/productReview4.png" alt="" /></Link>
|
||||
<h6>{t("lighting")}</h6>
|
||||
<p>{t("Explore")} <IoIosArrowForward/></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ComprehensivePurchase
|
||||
26
src/Components/Home/HeroSection.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import React from 'react'
|
||||
import HeroSwiper from './HeroSwiper'
|
||||
import AnimationButton from '../Ui/AnimationButton';
|
||||
|
||||
const HeroSection = () => {
|
||||
const {t} = useTranslation();
|
||||
return (
|
||||
<div className='hero_section'>
|
||||
<HeroSwiper />
|
||||
<div className="hero_details">
|
||||
<h1>{t("Industrial Automation")}</h1>
|
||||
<h4>{t("Industrial Automation & Control Solutions")}</h4>
|
||||
<p>{t("MNS automation and control products and solutions cover a wide range of industrial, infrastructure and construction sectors")}</p>
|
||||
<div className="button_container">
|
||||
<AnimationButton
|
||||
link='/'
|
||||
text='Products'
|
||||
withAnimation={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default HeroSection
|
||||
16
src/Components/Home/HeroSwiper.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
import { Carousel } from 'antd';
|
||||
import { heroArray } from '../../data/Home';
|
||||
|
||||
|
||||
const CarouselApp= () => (
|
||||
<Carousel >
|
||||
{heroArray.map((item:any, index:number) => (
|
||||
<div className='hero_Swiper' key={index}>
|
||||
<img src={item.src} alt="hero_image" />
|
||||
</div>
|
||||
))}
|
||||
</Carousel>
|
||||
);
|
||||
|
||||
export default CarouselApp;
|
||||
43
src/Components/Info/Info.tsx
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import HeaderLink from '../Ui/HeaderLink'
|
||||
import { InfoProps } from '../../type/InfoProps';
|
||||
import Spinner from '../Utils/Loading/Spinner';
|
||||
import { PrivacyData, TermsData } from '../../data/Info';
|
||||
|
||||
const Info = ({headerText,title,isLoading,text,isHaveText=false,isPrivacy = false}:InfoProps) => {
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<div className='info'>
|
||||
|
||||
|
||||
|
||||
{isLoading? <Spinner/> :
|
||||
<div className="info_content">
|
||||
<HeaderLink text={headerText}/>
|
||||
<h1>{t(title)}</h1>
|
||||
{isHaveText?
|
||||
<p>{text}</p>
|
||||
:""
|
||||
}
|
||||
{
|
||||
isPrivacy
|
||||
? PrivacyData.map((item) => (
|
||||
<div className='single_info'>
|
||||
<h2>{item.key}</h2>
|
||||
<p>{item.value}</p>
|
||||
</div>
|
||||
))
|
||||
: TermsData.map((item) => (
|
||||
<div className='single_info'>
|
||||
<h2>{item.key}</h2>
|
||||
<p>{item.value}</p>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Info
|
||||
29
src/Components/OurTeam/OurTeam.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import React from 'react'
|
||||
import TeamCard from '../Ui/TeamCard';
|
||||
import TeamSwiper from './TeamSwiper';
|
||||
import { teamMembers } from '../../data/Team';
|
||||
import { useGetTeamMember } from '../../api/TeamMember';
|
||||
|
||||
const OurTeam = () => {
|
||||
const {t} = useTranslation();
|
||||
const {data} = useGetTeamMember();
|
||||
|
||||
return (
|
||||
<div className='our_team'>
|
||||
<h1>{t("Documents")}</h1>
|
||||
<h2>{t("Quality Certificates")}</h2>
|
||||
|
||||
<div className='our_team_cards'>
|
||||
{data?.data.map((member:any)=>(
|
||||
<TeamCard
|
||||
name={member.name}
|
||||
position={member.position}
|
||||
image={member.image}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default OurTeam
|
||||
46
src/Components/OurTeam/TeamSwiper.tsx
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import "swiper/css";
|
||||
import 'swiper/css/free-mode';
|
||||
import "swiper/css/navigation";
|
||||
import "swiper/css/pagination";
|
||||
import "swiper/css/scrollbar";import { A11y, Autoplay, Navigation,Scrollbar } from 'swiper/modules';
|
||||
import Spinner from '../Utils/Loading/Spinner';
|
||||
import TeamCard from '../Ui/TeamCard';
|
||||
|
||||
|
||||
|
||||
const TeamSwiper = ({data,isLoading}:{data:any,isLoading:boolean}) => {
|
||||
|
||||
return (
|
||||
<div className='team_Swiper'>
|
||||
<Swiper
|
||||
dir={'ltr'}
|
||||
slidesPerView={5}
|
||||
spaceBetween={66}
|
||||
breakpoints={{
|
||||
0: { slidesPerView: 1 },
|
||||
400: { slidesPerView: 1 },
|
||||
600: { slidesPerView: 3 },
|
||||
900: { slidesPerView: 4 },
|
||||
1200: { slidesPerView: 5 },
|
||||
1500: { slidesPerView: 5 },
|
||||
}}
|
||||
navigation
|
||||
autoplay={true}
|
||||
modules={[Navigation, Scrollbar, A11y, Autoplay]}
|
||||
pagination={{ clickable: true }}
|
||||
className="mySwiper"
|
||||
>
|
||||
{
|
||||
isLoading ? <Spinner/> :
|
||||
data?.map((item:any, index:number) => (
|
||||
<SwiperSlide key={index}>
|
||||
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TeamSwiper;
|
||||
33
src/Components/Pagination/PaginationOptions.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { TableProps } from "antd";
|
||||
import { useMemo } from "react";
|
||||
import {
|
||||
IoMdArrowDropdown,
|
||||
IoMdArrowDropleft,
|
||||
IoMdArrowDropright,
|
||||
} from "react-icons/io";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export const PaginationOptions = (dataWpagination: any) => {
|
||||
return useMemo(() => {
|
||||
if (!dataWpagination || !dataWpagination.data.pagination) return {};
|
||||
|
||||
return {
|
||||
pageSize: dataWpagination?.data?.pagination.per_page,
|
||||
current: dataWpagination?.data?.pagination.current_page,
|
||||
total: dataWpagination?.data?.pagination.total_items,
|
||||
prevIcon: <IoMdArrowDropright color="#A098AE" size={30} />,
|
||||
nextIcon: <IoMdArrowDropleft color="#A098AE" size={30} />,
|
||||
};
|
||||
}, [dataWpagination]);
|
||||
};
|
||||
|
||||
export const useTableOnChange = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (pagination: any, _filters: any, _sorter: any, _extra: any) => {
|
||||
if (pagination) {
|
||||
// navigate(`?page=${pagination.current}&per_page=${pagination.pageSize}`);
|
||||
navigate(`?page=${pagination.current}`);
|
||||
}
|
||||
};
|
||||
};
|
||||
34
src/Components/Pagination/usePagination.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { PaginationAntd, PaginationMeta } from "../../type/pagination";
|
||||
|
||||
interface Data {
|
||||
meta: PaginationMeta;
|
||||
}
|
||||
|
||||
const usePagination = (data: Data) => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const [pagination, setPagination] = useState<PaginationAntd>({
|
||||
current: data?.meta?.current_page || 1,
|
||||
pageSize: data?.meta?.per_page || 10,
|
||||
total: data?.meta?.total || 0,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setPagination({
|
||||
current: data?.meta?.current_page || 1,
|
||||
pageSize: data?.meta?.per_page || 10,
|
||||
total: data?.meta?.total || 0,
|
||||
});
|
||||
}, [data]);
|
||||
|
||||
const handlePageChange = (page: number) => {
|
||||
navigate(`?page=${page}`);
|
||||
};
|
||||
|
||||
return { pagination, handlePageChange };
|
||||
};
|
||||
|
||||
export default usePagination;
|
||||
21
src/Components/Partner/Partner.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from 'react'
|
||||
import { partnerArray } from '../../data/Partner';
|
||||
|
||||
const Partner = () => {
|
||||
const {t} = useTranslation();
|
||||
return (
|
||||
<div className='partner'>
|
||||
<div className='top'>
|
||||
<img src="/Home/settingIcon.png" alt="setting" />
|
||||
<p>{t("Trusted by 100+ Companies across the globe!")}</p>
|
||||
</div>
|
||||
<div className='image_container'>
|
||||
{partnerArray?.map((item:any)=>(
|
||||
<img src={item.path} alt="logo" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Partner
|
||||
47
src/Components/Products/BrandFilter.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import React from "react";
|
||||
import { Checkbox } from "antd";
|
||||
import type { CheckboxProps } from "antd";
|
||||
import { useFilterStateState } from "../../zustand/Filter";
|
||||
import { languageObject } from "../Utils/languageObject";
|
||||
import { useGetCategory } from "../../api/category";
|
||||
|
||||
const BrandFilter = ({id}:{id:any}) => {
|
||||
const { setFilter, Filter } = useFilterStateState();
|
||||
|
||||
const onChange =
|
||||
(Category: any): CheckboxProps["onChange"] =>
|
||||
(e) => {
|
||||
const checked = e.target.checked;
|
||||
|
||||
if (checked) {
|
||||
setFilter([...Filter, { name:Category?.name,id:Category?.id,type:"category", index: Filter.length }]);
|
||||
} else {
|
||||
const newArray = Filter?.filter((item: any) => item.name !== Category?.name);
|
||||
setFilter(newArray);
|
||||
}
|
||||
};
|
||||
const data = useGetCategory({
|
||||
parent_id:id
|
||||
})
|
||||
const product = data?.data?.data;
|
||||
console.log(product);
|
||||
|
||||
return (
|
||||
<div className="CheckboxFilter">
|
||||
{product?.map((brand:any) => {
|
||||
console.log(brand?.children);
|
||||
|
||||
return (
|
||||
<Checkbox
|
||||
checked={Filter.some((item: any) => item.name === brand?.name)}
|
||||
key={brand?.id}
|
||||
onChange={onChange(brand)}
|
||||
>
|
||||
{languageObject(brand?.name)}
|
||||
</Checkbox>
|
||||
)})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BrandFilter;
|
||||
24
src/Components/Products/ProductCard.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { useNavigate } from 'react-router-dom';
|
||||
import { languageObject } from '../Utils/languageObject';
|
||||
|
||||
const ProductCard = ({data}:any) => {
|
||||
|
||||
const navigate = useNavigate();
|
||||
const productLink = `/product/${data?.id}`
|
||||
console.log(data);
|
||||
|
||||
return (
|
||||
<div className="product_card">
|
||||
<div className="image_container">
|
||||
<img
|
||||
onClick={() => navigate(productLink)}
|
||||
src={data?.file}
|
||||
alt={`product ${data.name}`}
|
||||
/>
|
||||
</div>
|
||||
<p className="truncate-text">{languageObject(data?.name)}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ProductCard
|
||||
39
src/Components/Products/ProductInfo.tsx
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
const ProductInfo = ({ data }:{data:any}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const ProductCollectionArray = data?.collections
|
||||
? data.collections.flatMap((collection:any) => {
|
||||
const { collectionParam, ...rest } = collection;
|
||||
return Object.entries(rest).map(([key, value]) => ({
|
||||
key,
|
||||
value
|
||||
}));
|
||||
})
|
||||
: [];
|
||||
|
||||
const midpoint = Math.ceil(ProductCollectionArray.length / 2);
|
||||
const leftSection = ProductCollectionArray.slice(0, midpoint);
|
||||
const rightSection = ProductCollectionArray.slice(midpoint);
|
||||
|
||||
return (
|
||||
<div className='product_info'>
|
||||
<h1>{t("allocation")}</h1>
|
||||
|
||||
<div className='details'>
|
||||
<div className='left'>
|
||||
{leftSection.map((e:any) => (
|
||||
<span >{t(e.key)} <span>{e.value}</span></span>
|
||||
))}
|
||||
</div>
|
||||
<div className='right'>
|
||||
{rightSection.map((e:any) => (
|
||||
<span >{t(e.key)} <span>{e.value}</span></span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProductInfo;
|
||||
47
src/Components/Products/ProductSwiper.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import "swiper/css";
|
||||
import 'swiper/css/free-mode';
|
||||
import "swiper/css/navigation";
|
||||
import "swiper/css/pagination";
|
||||
import "swiper/css/scrollbar";import { A11y, Autoplay, Navigation,Scrollbar } from 'swiper/modules';
|
||||
import Spinner from '../Utils/Loading/Spinner';
|
||||
import ProductCard from './ProductCard';
|
||||
|
||||
|
||||
|
||||
const ProductSwiper = ({data,isLoading}:{data:any,isLoading:boolean}) => {
|
||||
|
||||
return (
|
||||
<div className='similar_Swiper'>
|
||||
<Swiper
|
||||
dir={'ltr'}
|
||||
slidesPerView={3}
|
||||
spaceBetween={66}
|
||||
breakpoints={{
|
||||
0: { slidesPerView: 1 },
|
||||
400: { slidesPerView: 1 },
|
||||
600: { slidesPerView: 2 },
|
||||
1000: { slidesPerView: 2 },
|
||||
1200: { slidesPerView: 3 },
|
||||
1500: { slidesPerView: 4 },
|
||||
}}
|
||||
navigation
|
||||
modules={[Navigation, Scrollbar, A11y, Autoplay]}
|
||||
pagination={{ clickable: true }}
|
||||
className="mySwiper"
|
||||
>
|
||||
{
|
||||
isLoading ? <Spinner/> :
|
||||
data?.data?.map((item:any, index:number) => (
|
||||
<SwiperSlide key={index}>
|
||||
<ProductCard
|
||||
data={item}
|
||||
/>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProductSwiper;
|
||||
54
src/Components/Products/SingleProductSwiper.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import "swiper/css";
|
||||
import 'swiper/css/free-mode';
|
||||
import "swiper/css/navigation";
|
||||
import "swiper/css/pagination";
|
||||
import "swiper/css/scrollbar";import { A11y, Autoplay, Navigation,Scrollbar } from 'swiper/modules';
|
||||
import Spinner from '../Utils/Loading/Spinner';
|
||||
import ProductCard from './ProductCard';
|
||||
|
||||
|
||||
|
||||
const SingleProductSwiper = ({data,isLoading}:{data:any,isLoading:boolean}) => {
|
||||
const [mainImage, setMainImage] = useState(data?.file);
|
||||
console.log(data?.data?.attachment);
|
||||
|
||||
const handleImageClick = (image:any) => {
|
||||
setMainImage(image);
|
||||
};
|
||||
return (
|
||||
<div className='single_product_Swiper'>
|
||||
<Swiper
|
||||
dir={'ltr'}
|
||||
slidesPerView={3}
|
||||
spaceBetween={66}
|
||||
breakpoints={{
|
||||
0: { slidesPerView: 1 },
|
||||
400: { slidesPerView: 2 },
|
||||
600: { slidesPerView: 2 },
|
||||
1000: { slidesPerView: 3 },
|
||||
1200: { slidesPerView: 4 },
|
||||
1500: { slidesPerView: 4 },
|
||||
}}
|
||||
navigation
|
||||
modules={[Navigation, Scrollbar, A11y, Autoplay]}
|
||||
pagination={{ clickable: true }}
|
||||
className="mySwiper"
|
||||
>
|
||||
{
|
||||
isLoading ? <Spinner/> :
|
||||
data?.data?.attachment?.map(({attachment, id}:{attachment:string,id:number}) => {
|
||||
return(
|
||||
<SwiperSlide key={id}>
|
||||
<div key={id} className="image_container" onClick={() => handleImageClick(attachment)}>
|
||||
<img src={attachment} alt={`product_multi_image_${id}`} className='multi_image' />
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
)
|
||||
})}
|
||||
</Swiper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SingleProductSwiper;
|
||||
35
src/Components/Service/Service.tsx
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import React from 'react'
|
||||
import { ServicesArray } from '../../data/Service';
|
||||
|
||||
const Service = () => {
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<div className='Service'>
|
||||
<h1>{t("OUR SERVICES")}</h1>
|
||||
<h2>{t("What services do we provide?")}</h2>
|
||||
<picture>
|
||||
<source className="service_image" srcSet="/Service/ServicesRes.png" media="(max-width: 600px)" />
|
||||
<img className="service_image" src="/Service/Services.png" alt="MDN" />
|
||||
</picture>
|
||||
{/* <ServiceImage/> */}
|
||||
{/* <picture>
|
||||
<source className="service_image" srcSet="/Service/serviceRes.svg" media="(max-width: 600px)" />
|
||||
<img className="service_image" src="/Service/service.svg" alt="MDN" />
|
||||
<div className='single_services_container'>
|
||||
{
|
||||
ServicesArray.map((e) =>(
|
||||
<div className='single_service'>
|
||||
<h1>{t(e.title)}</h1>
|
||||
<p>{t(e.text)}</p>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</picture> */}
|
||||
{/* <img src="/Service/service.svg" alt="" /> */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Service
|
||||
13
src/Components/Ui/AnimationButton.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
const AnimationButton = ({text,icon,link,withAnimation= true}:AnimationButtonProps) => {
|
||||
|
||||
return (
|
||||
<div className='animation_button'>
|
||||
<Link to={link}><p>{text}</p></Link>
|
||||
{
|
||||
withAnimation ? <span>{icon}</span> : <span style={{display:"none"}}>{icon}</span>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AnimationButton
|
||||
50
src/Components/Ui/CardItem.tsx
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { CloseOutlined, MinusCircleOutlined, PlusCircleFilled } from '@ant-design/icons';
|
||||
import React, { useState } from 'react';
|
||||
import { Card, Skeleton, Button, Tooltip, Popconfirm } from 'antd';
|
||||
import useLoadingState from '../../Hooks/useLoadingState';
|
||||
import { TProduct } from '../../Layout/NavBar/Types';
|
||||
|
||||
interface CartItemProps {
|
||||
data: TProduct;
|
||||
}
|
||||
|
||||
const CardItem: React.FC<CartItemProps> = ({ data }) => {
|
||||
const [loading, resetLoading] = useLoadingState(true, 2000);
|
||||
const [Counter, setCounter] = useState<number>(data?.count);
|
||||
const [Price, setPrice] = useState<number>(data?.price);
|
||||
|
||||
return (
|
||||
<Skeleton loading={loading} active avatar style={{ width: "100%", marginTop: 22 }}>
|
||||
<Card className='CardItem' style={{ width: "100%", marginTop: 16 }} loading={loading}>
|
||||
<span className='Card_Counter'>
|
||||
<Button shape="circle" icon={<PlusCircleFilled />} onClick={() => { setCounter(v => ++v); setPrice(v => 2 * v) }} />
|
||||
<div className='Counter'>{Counter}</div>
|
||||
<Button shape="circle" icon={<MinusCircleOutlined />} onClick={() => { setCounter(v => v > 1 ? --v : v); setPrice(v => Counter > 1 ? v / 2 : v) }} />
|
||||
</span>
|
||||
<span className='Card_Img'>
|
||||
<img alt='' src={data?.img} />
|
||||
</span>
|
||||
<span className='Card_Info'>
|
||||
<h5>{data.name}</h5>
|
||||
<h6>{data.type}</h6>
|
||||
<strong>${Price}.00</strong>
|
||||
</span>
|
||||
<span className='Card_Delete'>
|
||||
<Popconfirm
|
||||
title="Delete the Item"
|
||||
description="Are you sure to delete this Item?"
|
||||
okText="Yes"
|
||||
cancelText="No"
|
||||
>
|
||||
<Tooltip title="Delete" placement="bottom">
|
||||
<Button shape="circle" icon={<CloseOutlined />} danger />
|
||||
</Tooltip>
|
||||
</Popconfirm>
|
||||
</span>
|
||||
</Card>
|
||||
</Skeleton>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export default CardItem;
|
||||
28
src/Components/Ui/Carousel.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import React from 'react';
|
||||
import { Carousel } from 'antd';
|
||||
import { TbannerData } from '../../Layout/NavBar/Types';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { BsArrowUpRight } from 'react-icons/bs';
|
||||
|
||||
type TCarouselApp = {
|
||||
data: TbannerData[]
|
||||
}
|
||||
|
||||
const CarouselApp: React.FC<TCarouselApp> = ({ data }) => (
|
||||
<Carousel >
|
||||
{data.map((item: TbannerData, index: number) => (
|
||||
<div className='banner_Container' key={index}>
|
||||
<img alt='' className='banner1' src={item.imageUrl} />
|
||||
<div className='banner_Info'>
|
||||
<h1 className='underLineText'>{item.title}</h1>
|
||||
<h2>
|
||||
{item.subtitle} <br /> <strong>{item.discount}</strong>
|
||||
</h2>
|
||||
<Link to={item.link}>{item?.btn} <BsArrowUpRight /> </Link>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</Carousel>
|
||||
);
|
||||
|
||||
export default CarouselApp;
|
||||
15
src/Components/Ui/ContactInfo.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import MediaButton from './MediaButton';
|
||||
|
||||
const ContactInfo = ({ title,info}:ContactInfoProps) => {
|
||||
const {t} = useTranslation();
|
||||
return (
|
||||
<div className='single_contact_info'>
|
||||
<div>
|
||||
<h2>{t(title)}</h2>
|
||||
<p>{info}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ContactInfo
|
||||
30
src/Components/Ui/CustomImage.tsx
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { IMAGE_BASE_URL } from "../../api/config";
|
||||
|
||||
interface ImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {
|
||||
src: string;
|
||||
}
|
||||
|
||||
const CustomImage: React.FC<ImageProps> = ({ src, ...props }) => {
|
||||
|
||||
const [imgSrc, setImgSrc] = useState<any>(src);
|
||||
|
||||
useEffect(() => {
|
||||
setImgSrc(src);
|
||||
}, [src,props]);
|
||||
|
||||
|
||||
|
||||
const newImage = (imgSrc?.replace("public", "/storage"))
|
||||
// IMAGE_BASE_URL +
|
||||
|
||||
return (
|
||||
<img
|
||||
src={newImage}
|
||||
{...props}
|
||||
alt="there is no image"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomImage;
|
||||
15
src/Components/Ui/CustomTitle.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { CustomTitleProps } from '../../type/app';
|
||||
|
||||
|
||||
const CustomTitle = ({title}:CustomTitleProps) => {
|
||||
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<div className='Custom_Title'>
|
||||
<p>{t(title)}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CustomTitle
|
||||
13
src/Components/Ui/DistributorWord.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import React from 'react'
|
||||
|
||||
const DistributorWord = ({title}:any) => {
|
||||
const {t} = useTranslation();
|
||||
return (
|
||||
<div className='distributor_word'>
|
||||
<img src="/App/CheckMark.png" alt="check" />
|
||||
<span>{t(title)}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DistributorWord
|
||||
20
src/Components/Ui/DrawerLink.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { NavLink } from 'react-router-dom';
|
||||
|
||||
const DrawerLink = ({href,name,icon,closeDrawer}:HedaerLinksProps) => {
|
||||
|
||||
const {t} = useTranslation();
|
||||
const pathname = window.location.pathname;
|
||||
const is_active = pathname === href;
|
||||
const handleClick = () => {
|
||||
closeDrawer();
|
||||
};
|
||||
|
||||
return (
|
||||
<NavLink to={href} className="nav_link_drawer" onClick={handleClick}>
|
||||
<p className={`drawer_link ${is_active && "active_link" }`}>{icon}{t(name)} </p>
|
||||
</NavLink>
|
||||
)
|
||||
}
|
||||
|
||||
export default DrawerLink
|
||||
39
src/Components/Ui/DropDown.tsx
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import React from 'react';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import { Dropdown, Menu, Space } from 'antd';
|
||||
|
||||
interface MenuItem {
|
||||
key: string;
|
||||
name: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
interface DropDownProps {
|
||||
menuItems: MenuItem[];
|
||||
title: string;
|
||||
}
|
||||
|
||||
const DropDown: React.FC<DropDownProps> = ({ menuItems, title }) => {
|
||||
const renderMenuItems = () => {
|
||||
return menuItems.map((item) => (
|
||||
<Menu.Item key={item.key}>
|
||||
<a target="_blank" rel="noopener noreferrer" href={item.href}>
|
||||
{item.name}
|
||||
</a>
|
||||
</Menu.Item>
|
||||
));
|
||||
};
|
||||
|
||||
const menu = <Menu>{renderMenuItems()}</Menu>;
|
||||
|
||||
return (
|
||||
<Dropdown overlay={menu} placement="bottomLeft">
|
||||
<Space>
|
||||
<span>{title} </span>
|
||||
<DownOutlined />
|
||||
</Space>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default DropDown;
|
||||
87
src/Components/Ui/DropdownMenu.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import React from 'react';
|
||||
import {Dropdown, Button } from 'antd';
|
||||
import { AppstoreOutlined, DownOutlined } from '@ant-design/icons';
|
||||
import MenuItems from './MenuItems';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const DropdownMenu = () => {
|
||||
const {t} = useTranslation();
|
||||
return (
|
||||
<Dropdown overlay={MenuItems} placement="bottomLeft" className='DropdownMenu'trigger={['click']} >
|
||||
<Button>
|
||||
<AppstoreOutlined />
|
||||
{t("Categories")}
|
||||
<DownOutlined />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default DropdownMenu;
|
||||
|
||||
|
||||
//////////// you can use this file when you connect with backend just change the response and api endpoint //////////////////
|
||||
|
||||
// import React from 'react';
|
||||
// import { Dropdown, Button, Menu } from 'antd';
|
||||
// import { AppstoreOutlined, DownOutlined, MailOutlined } from '@ant-design/icons';
|
||||
// import { useGetAllCategories } from '../../api/categories';
|
||||
// import { Link, useNavigate } from 'react-router-dom';
|
||||
// import { useTranslation } from 'react-i18next';
|
||||
// import type { MenuProps } from 'antd';
|
||||
|
||||
// const DropdownMenu = () => {
|
||||
// const { data, isError, isLoading } = useGetAllCategories();
|
||||
// const navigate = useNavigate();
|
||||
// const [t] = useTranslation();
|
||||
|
||||
// if (isLoading) {
|
||||
// return <div>Loading...</div>;
|
||||
// }
|
||||
|
||||
// if (isError || !data?.data?.data) {
|
||||
// return <div>Error loading categories</div>;
|
||||
// }
|
||||
|
||||
|
||||
// const CategoriesArry = data.data.data.map((item: any) => ({
|
||||
// value: item?.category_translations[0]?.name,
|
||||
// label: item?.id,
|
||||
// }));
|
||||
|
||||
|
||||
// const items: any = CategoriesArry?.map((item: any) => ({
|
||||
// key: item.key,
|
||||
// label: (
|
||||
// <Link rel="noopener noreferrer" to={`/Products?category_id=`+item.label}>
|
||||
// {item.value}
|
||||
// </Link>
|
||||
// ),
|
||||
// icon: item.icon, // You can include the icon if available
|
||||
// disabled: item.disabled,
|
||||
// danger: item.danger,
|
||||
// }));
|
||||
|
||||
// const menu: React.ReactNode = (
|
||||
// <Menu>
|
||||
// {items.map((menuItem: any) => (
|
||||
// <Menu.Item key={menuItem.key} disabled={menuItem.disabled} danger={menuItem.danger}>
|
||||
// {menuItem.label}
|
||||
// </Menu.Item>
|
||||
// ))}
|
||||
// </Menu>
|
||||
// );
|
||||
|
||||
|
||||
// return (
|
||||
// <Dropdown menu={{items}} placement="bottomLeft" className="DropdownMenu" trigger={['click']}>
|
||||
// <Button>
|
||||
// <AppstoreOutlined />
|
||||
// {t("Categories")}
|
||||
// <DownOutlined />
|
||||
// </Button>
|
||||
// </Dropdown>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default DropdownMenu;
|
||||
11
src/Components/Ui/FooterTItleWithSeperator.tsx
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
const FooterTItleWithSeparator = ({ title }: { title: string }) => {
|
||||
const {t} = useTranslation()
|
||||
return (
|
||||
<div className='FooterTItleWithSeparator'>
|
||||
<h1>{t(title)}</h1>
|
||||
<hr />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default FooterTItleWithSeparator;
|
||||
27
src/Components/Ui/HeaderLink.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import { SlArrowRight } from "react-icons/sl";
|
||||
import { Link } from 'react-router-dom';
|
||||
import { THeaderLink } from '../../type/app';
|
||||
import { BaseURL } from '../../api/config';
|
||||
|
||||
const HeaderLink = ({text,isMulti,extraText,extraLink}:THeaderLink) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className='header_link'>
|
||||
<Link to={"/"} className='first_link'>{t("Home")}</Link>
|
||||
<SlArrowRight className='header_link_svg'/>
|
||||
{
|
||||
isMulti ?
|
||||
<>
|
||||
<Link to={`${extraLink}`} className='first_link'>{ t(extraText || "")}</Link>
|
||||
<SlArrowRight className='header_link_svg'/>
|
||||
</>
|
||||
: ""
|
||||
}
|
||||
<span className='page_title_link'>{t(text)}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default HeaderLink
|
||||
14
src/Components/Ui/MediaButton.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { IMAGE_BASE_URL } from "../../api/config";
|
||||
|
||||
const MediaButton = ({ img: Image, link, isStatic = true }: any) => {
|
||||
|
||||
return (
|
||||
<Link to={link}>
|
||||
<div className='MediaButton'>
|
||||
<span>{isStatic ? <span>{<Image />}</span> : <img src={IMAGE_BASE_URL + Image} alt="ak" width={14} />}</span>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default MediaButton;
|
||||
37
src/Components/Ui/MenuItems.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import React from 'react';
|
||||
import { Menu } from 'antd';
|
||||
import { MenuItem } from '../../Layout/NavBar/Types';
|
||||
import { menuData } from './MenuItemsData';
|
||||
|
||||
const { SubMenu } = Menu;
|
||||
|
||||
|
||||
|
||||
const generateMenuItems = (items: MenuItem[]): React.ReactNode => {
|
||||
return items.map((item) => {
|
||||
if (item.children) {
|
||||
return (
|
||||
<SubMenu key={item.key} icon={item.icon} title={item.label}>
|
||||
{generateMenuItems(item.children)}
|
||||
</SubMenu>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Menu.Item key={item.key}>
|
||||
<a href={`/${item.key}`}>{item.label}</a>
|
||||
</Menu.Item>
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const MenuItems: React.FC<{ items: MenuItem[] }> = ({ items }) => {
|
||||
return <Menu mode="vertical">{generateMenuItems(items)}</Menu>;
|
||||
};
|
||||
|
||||
|
||||
const App = () => {
|
||||
return <MenuItems items={menuData} />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
169
src/Components/Ui/MenuItemsData.tsx
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
//// fake data ////
|
||||
|
||||
import { MenuItem } from "../../Layout/NavBar/Types";
|
||||
import { AppstoreOutlined, MailOutlined, SettingOutlined } from '@ant-design/icons';
|
||||
export const menuData: MenuItem[] = [
|
||||
{
|
||||
key: 'sub1',
|
||||
label: 'Moaz',
|
||||
icon: <MailOutlined />,
|
||||
children: [
|
||||
{ key: '1', label: 'Option 1' },
|
||||
{ key: '2', label: 'Option 2' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'sub2',
|
||||
label: 'Navigation Two',
|
||||
icon: <AppstoreOutlined />,
|
||||
children: [
|
||||
{ key: '5', label: 'Option 5' },
|
||||
{ key: '6', label: 'Option 6' },
|
||||
{
|
||||
key: 'sub3',
|
||||
label: 'Submenu',
|
||||
children: [
|
||||
{ key: '7', label: 'Option 7' },
|
||||
{
|
||||
key: 'subsub1',
|
||||
label: 'Sub-Submenu 1',
|
||||
children: [
|
||||
{ key: '8', label: 'Option 8' },
|
||||
{ key: '9', label: 'Option 9' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'sub4',
|
||||
label: 'Navigation Three',
|
||||
icon: <SettingOutlined />,
|
||||
children: [
|
||||
{ key: '9', label: 'Option 9' },
|
||||
{ key: '10', label: 'Option 10' },
|
||||
{ key: '11', label: 'Option 11' },
|
||||
{
|
||||
key: 'subsub2',
|
||||
label: 'Sub-Submenu 2',
|
||||
children: [
|
||||
{ key: '12', label: 'Option 12' },
|
||||
{ key: '13', label: 'Option 13' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'subsub3',
|
||||
label: 'Sub-Submenu 3',
|
||||
children: [
|
||||
{ key: '14', label: 'Option 14' },
|
||||
{ key: '15', label: 'Option 15' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'sub5',
|
||||
label: 'Navigation Four',
|
||||
icon: <SettingOutlined />,
|
||||
children: [
|
||||
{ key: '16', label: 'Option 16' },
|
||||
{ key: '17', label: 'Option 17' },
|
||||
{
|
||||
key: 'subsub4',
|
||||
label: 'Sub-Submenu 4',
|
||||
children: [
|
||||
{ key: '18', label: 'Option 18' },
|
||||
{ key: '19', label: 'Option 19' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'subsub5',
|
||||
label: 'Sub-Submenu 5',
|
||||
children: [
|
||||
{ key: '20', label: 'Option 20' },
|
||||
{ key: '21', label: 'Option 21' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'sub6',
|
||||
label: 'Navigation Five',
|
||||
icon: <SettingOutlined />,
|
||||
children: [
|
||||
{ key: '22', label: 'Option 22' },
|
||||
{ key: '23', label: 'Option 23' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'sub7',
|
||||
label: 'Navigation Six',
|
||||
icon: <SettingOutlined />,
|
||||
children: [
|
||||
{ key: '24', label: 'Option 24' },
|
||||
{ key: '25', label: 'Option 25' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'sub8',
|
||||
label: 'Navigation Seven',
|
||||
icon: <SettingOutlined />,
|
||||
children: [
|
||||
{ key: '26', label: 'Option 26' },
|
||||
{ key: '27', label: 'Option 27' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'sub9',
|
||||
label: 'Navigation Eight',
|
||||
icon: <SettingOutlined />,
|
||||
children: [
|
||||
{ key: '28', label: 'Option 28' },
|
||||
{ key: '29', label: 'Option 29' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'sub10',
|
||||
label: 'Navigation Nine',
|
||||
icon: <SettingOutlined />,
|
||||
children: [
|
||||
{ key: '30', label: 'Option 30' },
|
||||
{ key: '31', label: 'Option 31' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
export const menuItems = [
|
||||
{
|
||||
key: '1',
|
||||
name: '1st menu item',
|
||||
href: 'https://www.antgroup.com',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: '2nd menu item',
|
||||
href: 'https://www.example.com',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
name: '1st menu item',
|
||||
href: 'https://www.antgroup.com',
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
name: '2nd menu item',
|
||||
href: 'https://www.example.com',
|
||||
},
|
||||
{
|
||||
key: '5',
|
||||
name: '1st menu item',
|
||||
href: 'https://www.antgroup.com',
|
||||
},
|
||||
{
|
||||
key: '6.NavMenus',
|
||||
name: '2nd menu item',
|
||||
href: 'https://www.example.com',
|
||||
},
|
||||
];
|
||||
13
src/Components/Ui/PreviewButton.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
const PreviewButton = ({ link }: { link: string }) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<div className='preview_button'>
|
||||
<Link to={link}>
|
||||
<p>{t("Preview")}</p>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PreviewButton;
|
||||
11
src/Components/Ui/SettingImage.tsx
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import React from 'react'
|
||||
|
||||
const SettingImage = ({isReverse = false}:{isReverse?:boolean}) => {
|
||||
return (
|
||||
<div className={`Setting_image ${isReverse? "rotate":""}`}>
|
||||
<img src="/Home/settingIcon.png" alt="" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SettingImage
|
||||
13
src/Components/Ui/SingleLink.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
const SingleLink = ({name, href}:FooterLinksProps) => {
|
||||
return (
|
||||
<div className='SingleLink'>
|
||||
<Link to={href} className="link">
|
||||
{/* <div><RiArrowRightDoubleLine/></div> */}
|
||||
<h5>{name}</h5>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SingleLink
|
||||
26
src/Components/Ui/TeamCard.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import React from 'react'
|
||||
import { IMAGE_BASE_URL } from '../../api/config';
|
||||
|
||||
interface TeamCardProps {
|
||||
name: string;
|
||||
position: string;
|
||||
image: string;
|
||||
}
|
||||
|
||||
const TeamCard: React.FC<TeamCardProps> = ({ name, position, image }) => {
|
||||
console.log(image);
|
||||
|
||||
return (
|
||||
<div className='team_card'>
|
||||
<div className='card_image'>
|
||||
<img src={image} alt={`${name}`} />
|
||||
</div>
|
||||
<div className='card_info'>
|
||||
<h3>{name}</h3>
|
||||
<p>{position}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TeamCard;
|
||||
170
src/Components/Utils/BombBtn/BombBtn.scss
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
.BombBtn{
|
||||
.container-button {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
grid-template-areas: "bt-1 bt-2 bt-3"
|
||||
"bt-4 bt-5 bt-6";
|
||||
position: relative;
|
||||
perspective: 800;
|
||||
padding: 0;
|
||||
width: 60px;
|
||||
height: 25px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.container-button:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.hover {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
.bt-1 {
|
||||
grid-area: bt-1;
|
||||
}
|
||||
|
||||
.bt-2 {
|
||||
grid-area: bt-2;
|
||||
}
|
||||
|
||||
.bt-3 {
|
||||
grid-area: bt-3;
|
||||
}
|
||||
|
||||
.bt-4 {
|
||||
grid-area: bt-4;
|
||||
}
|
||||
|
||||
.bt-5 {
|
||||
grid-area: bt-5;
|
||||
}
|
||||
|
||||
.bt-6 {
|
||||
grid-area: bt-6;
|
||||
}
|
||||
|
||||
.bt-1:hover ~ button {
|
||||
transform: rotateX(15deg) rotateY(-15deg) rotateZ(0deg);
|
||||
box-shadow: -2px -2px #18181888;
|
||||
}
|
||||
|
||||
.bt-1:hover ~ button::after {
|
||||
animation: shake 0.5s ease-in-out 0.3s;
|
||||
text-shadow: -2px -2px #18181888;
|
||||
}
|
||||
|
||||
.bt-3:hover ~ button {
|
||||
transform: rotateX(15deg) rotateY(15deg) rotateZ(0deg);
|
||||
box-shadow: 2px -2px #18181888;
|
||||
}
|
||||
|
||||
.bt-3:hover ~ button::after {
|
||||
animation: shake 0.5s ease-in-out 0.3s;
|
||||
text-shadow: 2px -2px #18181888;
|
||||
}
|
||||
|
||||
.bt-4:hover ~ button {
|
||||
transform: rotateX(-15deg) rotateY(-15deg) rotateZ(0deg);
|
||||
box-shadow: -2px 2px #18181888;
|
||||
}
|
||||
|
||||
.bt-4:hover ~ button::after {
|
||||
animation: shake 0.5s ease-in-out 0.3s;
|
||||
text-shadow: -2px 2px #18181888;
|
||||
}
|
||||
|
||||
.bt-6:hover ~ button {
|
||||
transform: rotateX(-15deg) rotateY(15deg) rotateZ(0deg);
|
||||
box-shadow: 2px 2px #18181888;
|
||||
}
|
||||
|
||||
.bt-6:hover ~ button::after {
|
||||
animation: shake 0.5s ease-in-out 0.3s;
|
||||
text-shadow: 2px 2px #18181888;
|
||||
}
|
||||
|
||||
.hover:hover ~ button::before {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.hover:hover ~ button::after {
|
||||
content: attr(data-text);
|
||||
top: -200%;
|
||||
transform: translate(-50%, 0);
|
||||
font-size: 20px;
|
||||
color: var(--secondary);
|
||||
}
|
||||
|
||||
button {
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
width: 60px;
|
||||
height: 25px;
|
||||
background: var(--secondary);
|
||||
font-size: 10px;
|
||||
font-weight: 900;
|
||||
border: 3px solid var(--secondary);
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
button::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 60px;
|
||||
height: 25px;
|
||||
background-color: var(--secondary);
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
button::after {
|
||||
content: attr(data-text);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 60px;
|
||||
height: 25px;
|
||||
background-color: transparent;
|
||||
font-size: 10px;
|
||||
font-weight: 900;
|
||||
line-height: 25px;
|
||||
color: var(--primary);
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0% {
|
||||
left: 45%;
|
||||
}
|
||||
|
||||
25% {
|
||||
left: 54%;
|
||||
}
|
||||
|
||||
50% {
|
||||
left: 48%;
|
||||
}
|
||||
|
||||
75% {
|
||||
left: 52%;
|
||||
}
|
||||
|
||||
100% {
|
||||
left: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/Components/Utils/BombBtn/BombBtn.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from 'react'
|
||||
import './BombBtn.scss'
|
||||
|
||||
const BombBtn = () => {
|
||||
|
||||
return (
|
||||
<div className='BombBtn'>
|
||||
<div className="container-button" >
|
||||
<div className="hover bt-1" />
|
||||
<div className="hover bt-2" />
|
||||
<div className="hover bt-3" />
|
||||
<div className="hover bt-4" />
|
||||
<div className="hover bt-5" />
|
||||
<div className="hover bt-6" />
|
||||
<button data-text={"15% off"} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default BombBtn
|
||||
47
src/Components/Utils/FileInput/File.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { Button, Upload, UploadFile } from 'antd'
|
||||
import { UploadOutlined } from '@ant-design/icons';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const File = ({ label,set }: any) => {
|
||||
const {t} = useTranslation();
|
||||
const imageUrl = '';
|
||||
|
||||
const fileList: UploadFile[] = [
|
||||
{
|
||||
uid: '-1',
|
||||
name: '',
|
||||
status: 'done',
|
||||
url: imageUrl,
|
||||
thumbUrl: imageUrl,
|
||||
}
|
||||
];
|
||||
|
||||
const FilehandleChange = (value:any) => {
|
||||
set(value?.file?.originFileObj)
|
||||
};
|
||||
const customRequest = async ({ onSuccess}: any) => {
|
||||
onSuccess();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="TalabeeField">
|
||||
<label htmlFor={label} className="text" >
|
||||
{(`${label}`)}
|
||||
</label>
|
||||
|
||||
<Upload
|
||||
listType="picture"
|
||||
maxCount={1}
|
||||
className='w-100 upload_file'
|
||||
defaultFileList={[...fileList]}
|
||||
onChange={ FilehandleChange}
|
||||
customRequest={customRequest}
|
||||
>
|
||||
<Button className='w-100 partner_image' icon={<UploadOutlined />}>{t("upload_image")}</Button>
|
||||
</Upload>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default File
|
||||
117
src/Components/Utils/Loading/Loading.scss
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
.Loading{
|
||||
|
||||
.wrapper {
|
||||
width: 200px;
|
||||
height: 60px;
|
||||
position: relative;
|
||||
left: 40%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background-color: var(--fifthly);
|
||||
left: 15%;
|
||||
transform-origin: 50%;
|
||||
animation: circle7124 .5s alternate infinite ease;
|
||||
}
|
||||
|
||||
@keyframes circle7124 {
|
||||
0% {
|
||||
top: 60px;
|
||||
height: 5px;
|
||||
border-radius: 50px 50px 25px 25px;
|
||||
transform: scaleX(1.7);
|
||||
}
|
||||
|
||||
40% {
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 0%;
|
||||
}
|
||||
}
|
||||
|
||||
.circle:nth-child(2) {
|
||||
left: 45%;
|
||||
animation-delay: .2s;
|
||||
}
|
||||
|
||||
.circle:nth-child(3) {
|
||||
left: auto;
|
||||
right: 15%;
|
||||
animation-delay: .3s;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
width: 20px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--fifthly);
|
||||
position: absolute;
|
||||
opacity: .5;
|
||||
top: 62px;
|
||||
transform-origin: 50%;
|
||||
z-index: -1;
|
||||
left: 15%;
|
||||
filter: blur(1px);
|
||||
animation: shadow046 .5s alternate infinite ease;
|
||||
}
|
||||
|
||||
@keyframes shadow046 {
|
||||
0% {
|
||||
transform: scaleX(1.5);
|
||||
}
|
||||
|
||||
40% {
|
||||
transform: scaleX(1);
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scaleX(.2);
|
||||
opacity: .4;
|
||||
}
|
||||
}
|
||||
|
||||
.shadow:nth-child(4) {
|
||||
left: 45%;
|
||||
animation-delay: .2s
|
||||
}
|
||||
|
||||
.shadow:nth-child(5) {
|
||||
left: auto;
|
||||
right: 15%;
|
||||
animation-delay: .3s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.loading_page{
|
||||
width: 100vw !important;height: 50vh !important;
|
||||
display: flex !important;justify-content: space-between !important;align-items: center !important; flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
:where(.css-dev-only-do-not-override-1ae8k9u).ant-spin .ant-spin-dot-item ,:where(.css-1adbn6x).ant-spin .ant-spin-dot-item{
|
||||
background-color: var(--primary);
|
||||
}
|
||||
:where(.css-dev-only-do-not-override-1ae8k9u).ant-spin, :where(.css-1adbn6x).ant-spin .ant-spin-dot-item{
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
|
||||
.spinner{
|
||||
color: var(--primary);
|
||||
padding-block: 30px;
|
||||
}
|
||||
19
src/Components/Utils/Loading/Loading.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import React from 'react'
|
||||
import './Loading.scss'
|
||||
const Loading = () => {
|
||||
|
||||
return (
|
||||
<div className="Loading">
|
||||
<div className="wrapper">
|
||||
<div className="circle"></div>
|
||||
<div className="circle"></div>
|
||||
<div className="circle"></div>
|
||||
<div className="shadow"></div>
|
||||
<div className="shadow"></div>
|
||||
<div className="shadow"></div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Loading
|
||||
13
src/Components/Utils/Loading/LoadingAntd.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { Spin } from 'antd';
|
||||
import './Loading.scss'
|
||||
|
||||
const LoadingAntd = () => {
|
||||
return (
|
||||
<div className='loading_page'>
|
||||
<img src='/Logo/Logo.png' width={100} alt='logo'/>
|
||||
<Spin className='LoadingAntd' size='large' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LoadingAntd
|
||||
15
src/Components/Utils/Loading/LoadingButton.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import React from "react";
|
||||
import { Button, Spinner } from "reactstrap";
|
||||
|
||||
const LoadingButton = ({ className = 'LoadinButton',isLoading = false, ...props }) => {
|
||||
return (
|
||||
<Button className={className} disabled={isLoading} {...props}>
|
||||
{isLoading ? <Spinner style={{ marginRight: "10px" }} size="sm" /> : null}
|
||||
<span >{props.children}</span>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
export { LoadingButton };
|
||||
8
src/Components/Utils/Loading/Spinner.tsx
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import React from 'react'
|
||||
import { Spin } from 'antd';
|
||||
|
||||
const Spinner: React.FC = () =>
|
||||
<>
|
||||
<Spin className='LoadingAntd spinner' size='large'/>
|
||||
</>
|
||||
export default Spinner
|
||||
17
src/Components/Utils/Search/Empty.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const Empty = () => {
|
||||
const [t] = useTranslation()
|
||||
return (
|
||||
<div className='Empty'>
|
||||
<img src="/icon/notfound_search.png" alt="" />
|
||||
<h1>{t("There are no suitable products")}</h1>
|
||||
<p>
|
||||
{t("Please try using other keywords to find the product name")}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Empty
|
||||
11
src/Components/Utils/Search/Search.tsx
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import SearchWithDrawer from '../../HOC/SearchWithDrawer'
|
||||
|
||||
const ViewSearch = () => {
|
||||
return (
|
||||
<div className='ViewSearch'>
|
||||
<SearchWithDrawer />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ViewSearch
|
||||
85
src/Components/Utils/Search/SearchButton.tsx
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { Select, Spin } from 'antd';
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { LuSearch } from 'react-icons/lu';
|
||||
// import { Product } from '../../../types/item';
|
||||
import _ from 'lodash';
|
||||
import { useGetProducts } from '../../../api/products';
|
||||
|
||||
interface SearchButtonProps {
|
||||
setOpen: (open: boolean) => void;
|
||||
setNoDataFound: (noData: boolean) => void;
|
||||
}
|
||||
|
||||
const SearchButton: React.FC<SearchButtonProps> = ({ setOpen, setNoDataFound }) => {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const [searchParams] = useSearchParams();
|
||||
const [query, setQuery] = useState<string | null>(searchParams.get('search'));
|
||||
|
||||
const { data, isLoading } = useGetProducts({
|
||||
name: query,
|
||||
});
|
||||
|
||||
const BaseProducts = (data?.data as Product[]) || [];
|
||||
|
||||
useEffect(() => {
|
||||
setNoDataFound(!isLoading && BaseProducts.length < 1);
|
||||
}, [isLoading, BaseProducts, setNoDataFound]);
|
||||
|
||||
const options = BaseProducts.map((product: any) => ({
|
||||
value: product.id,
|
||||
label: product?.name as string,
|
||||
}));
|
||||
|
||||
const debouncedSearchChange = useCallback(
|
||||
_.debounce((value: string) => {
|
||||
console.log(value);
|
||||
|
||||
setQuery(value);
|
||||
navigate(`${window.location.pathname}?search=${value}`, {
|
||||
replace: true,
|
||||
});
|
||||
}, 500), // Adjust the debounce delay (in milliseconds) as needed
|
||||
[]
|
||||
);
|
||||
|
||||
const handleSearchChange = (value: string) => {
|
||||
debouncedSearchChange(value);
|
||||
};
|
||||
|
||||
const handleSelectChange = (value: number) => {
|
||||
console.log(value);
|
||||
|
||||
const selectedProduct = BaseProducts.find(product => product?.id === value);
|
||||
if (selectedProduct) {
|
||||
setOpen(false);
|
||||
navigate(`/product/${selectedProduct?.id}`);
|
||||
}
|
||||
};
|
||||
|
||||
const filterOption = (input: string, option?: { label: string }) => {
|
||||
if (!option) return false;
|
||||
return option?.label.toLowerCase().includes(input.toLowerCase());
|
||||
};
|
||||
|
||||
return (
|
||||
<Select
|
||||
className='InputAutoComplete'
|
||||
suffixIcon={<LuSearch />}
|
||||
placeholder={t('Search..') as string}
|
||||
allowClear
|
||||
showSearch
|
||||
loading={isLoading}
|
||||
onSearch={handleSearchChange}
|
||||
onChange={handleSelectChange}
|
||||
options={options}
|
||||
optionFilterProp="label"
|
||||
filterOption={filterOption}
|
||||
notFoundContent={isLoading ? <Spin /> : null}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchButton;
|
||||
182
src/Components/Utils/SearchBar/SearchBar.scss
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
.SearchBar {
|
||||
.group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
max-width: 190px;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
padding: 0 1rem;
|
||||
padding-left: 2.5rem;
|
||||
border-radius: 8px;
|
||||
outline: none;
|
||||
font-weight: 500;
|
||||
background: var(--primary);
|
||||
color: var(--bg);
|
||||
border: none;
|
||||
box-shadow: 2px 2px 7px 0 var(--primary);
|
||||
}
|
||||
|
||||
.input::placeholder {
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
.icon {
|
||||
// background: #000;
|
||||
position: absolute;
|
||||
left: 1rem;
|
||||
fill: var(--bg);
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
top: 0 ;
|
||||
}
|
||||
}
|
||||
.InputAutoComplete{
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
border-radius: 30px !important;
|
||||
box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.05);
|
||||
.ant-select-selector{
|
||||
border-radius: 30px !important;
|
||||
border: 1.4px solid var(--white) !important;
|
||||
padding-left: 15px !important;
|
||||
position: relative;
|
||||
span{
|
||||
color: var(--gray) !important;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.ant-select-arrow{
|
||||
@include Flex;
|
||||
font-size: 32px;
|
||||
color: var(--white) !important;
|
||||
background: var(--primary);
|
||||
width: 40px;height: 40px;
|
||||
border-radius: 50%;
|
||||
top: 20%;
|
||||
right: 5px;
|
||||
svg{
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.Drawer_search_Body{
|
||||
width: 90%;
|
||||
margin-inline: auto;
|
||||
.recent_search_text{
|
||||
display: flex; justify-content: space-between;align-items: center;
|
||||
.recent_search_text_container{
|
||||
margin-block: 8px;
|
||||
width: 100%;
|
||||
display: flex; justify-content: space-between;
|
||||
div{
|
||||
display: flex;
|
||||
p{
|
||||
text-transform: capitalize;
|
||||
font-size: 20px;
|
||||
}
|
||||
svg{
|
||||
opacity: .6;
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
svg{
|
||||
font-size: 10px;
|
||||
opacity: .6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search_first_section{
|
||||
width: 91%;
|
||||
margin-inline: auto;
|
||||
display: flex;justify-content: space-between;align-items: center;
|
||||
.delete_icon{
|
||||
height: 75px;
|
||||
cursor: pointer;
|
||||
svg{
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.not_found_section{
|
||||
@include Flex;
|
||||
.Empty{
|
||||
@include Flex; flex-direction: column;
|
||||
p,h1{
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ViewSearch{
|
||||
// background: #000;
|
||||
width: 100%;
|
||||
.ant-drawer .ant-drawer-content {
|
||||
height: 50% !important ;width: 100% !important;
|
||||
min-height: 50% !important;
|
||||
display: flex; flex-direction: column;
|
||||
border-radius: 5px 0 0 5px;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.search_comp{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width:1000px) {
|
||||
// .InputAutoComplete{
|
||||
// width: 85%;
|
||||
// height: 42px;
|
||||
// @include Flex;
|
||||
// margin-inline: auto;
|
||||
// border-radius: 10px !important;
|
||||
// margin-bottom: 10px;
|
||||
// box-shadow: rgba(0, 0, 0, 0);
|
||||
// .ant-select-selector{
|
||||
// background: #000 !important;
|
||||
// background: var(--whiteGray) !important;
|
||||
// border-radius: 10px !important;
|
||||
// border: 1.4px solid var(--whiteGray) !important;
|
||||
// padding-left: 15px !important;
|
||||
// span{
|
||||
// color: var(--gray) !important;
|
||||
// font-size: 15px;
|
||||
// font-weight: 500;
|
||||
// }
|
||||
// }
|
||||
// .ant-select-arrow{
|
||||
// @include Flex;
|
||||
// font-size: 32px;
|
||||
// color: var(--gray) !important;
|
||||
// background: transparent;
|
||||
// width: 40px;height: 40px;
|
||||
// border-radius: 50%;
|
||||
// top: 16%;
|
||||
// right: 5px;
|
||||
// svg{
|
||||
// font-size: 20px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
.not_found_section{
|
||||
.Empty{
|
||||
h1 , p{
|
||||
text-align: center;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/Components/Utils/SearchBar/SearchBar.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import React from "react";
|
||||
import "./SearchBar.scss";
|
||||
const SearchBar = () => {
|
||||
return (
|
||||
<div className="SearchBar">
|
||||
<div className="group">
|
||||
<svg className="icon" viewBox="0 0 24 24">
|
||||
<g>
|
||||
<path d="M21.53 20.47l-3.66-3.66C19.195 15.24 20 13.214 20 11c0-4.97-4.03-9-9-9s-9 4.03-9 9 4.03 9 9 9c2.215 0 4.24-.804 5.808-2.13l3.66 3.66c.147.146.34.22.53.22s.385-.073.53-.22c.295-.293.295-.767.002-1.06zM3.5 11c0-4.135 3.365-7.5 7.5-7.5s7.5 3.365 7.5 7.5-3.365 7.5-7.5 7.5-7.5-3.365-7.5-7.5z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
<input placeholder="Search" type="search" className="input" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchBar;
|
||||