This commit is contained in:
Moaz Dawalibi 2024-08-03 15:20:02 +03:00
parent fc8f495815
commit 69fd134af4
263 changed files with 58323 additions and 0 deletions

23
.gitignore vendored Normal file
View 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
View File

@ -0,0 +1,13 @@
{
"cSpell.words": [
"aldeen",
"currentlanguage",
"Datepicker",
"formik",
"Karim",
"queryqlent",
"setstyle",
"szhsin",
"Viewelement"
]
}

48
db.json Normal file
View 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
View 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

File diff suppressed because it is too large Load Diff

104
package.json Normal file
View 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

File diff suppressed because it is too large Load Diff

BIN
public/About/About.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 485 KiB

104
public/About/about.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 MiB

BIN
public/App/BigGmap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 KiB

BIN
public/App/CheckMark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

BIN
public/App/product.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
public/Home/Gmap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
public/Home/heroImage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

BIN
public/Home/settingIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

1
public/Layout/Ar.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

1
public/Layout/En.svg Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 KiB

1
public/Layout/dark.svg Normal file
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

108
public/MainPartnerr.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 87 KiB

BIN
public/Partner/partner1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
public/Service/Services.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

136
public/Service/service.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 106 KiB

BIN
public/Team/team1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

25
public/manifest.json Normal file
View 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
View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

34
src/App.tsx Normal file
View 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;

View 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

View 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

View 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

View 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;

View 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

View 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

View 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

View 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

View 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. Ş.</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. Ş.</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

View 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

View 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

View 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;

View 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

View 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;

View 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

View 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

View 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;

View 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

View 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

View 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;

View 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}`);
}
};
};

View 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;

View 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

View 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;

View 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

View 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;

View 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;

View 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;

View 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

View 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

View 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;

View 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;

View 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

View 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;

View 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

View 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

View 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

View 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;

View 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;

View 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;

View 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

View 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;

View 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;

View 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',
},
];

View 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;

View 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

View 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

View 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;

View 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%;
}
}
}

View 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

View 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

View 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;
}

View 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

View 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

View 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 };

View 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

View 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

View File

@ -0,0 +1,11 @@
import SearchWithDrawer from '../../HOC/SearchWithDrawer'
const ViewSearch = () => {
return (
<div className='ViewSearch'>
<SearchWithDrawer />
</div>
)
}
export default ViewSearch

View 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;

View 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;
}
}
}
}

View 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;

Some files were not shown because too many files have changed in this diff Show More