Compare commits

...

16 Commits
master ... main

Author SHA1 Message Date
karimaldeen
15a111d3f7 / 2024-07-27 09:51:53 +03:00
Moaz Dawalibi
c51332ee03 single products swiper 2024-06-22 14:45:28 +03:00
Moaz Dawalibi
949f8de235 fix home style 2024-06-22 12:29:34 +03:00
Moaz Dawalibi
e8ee03dfd3 fix cart button 2024-06-22 12:21:19 +03:00
Moaz Dawalibi
99ab6ede2c remove log 2024-06-22 12:18:00 +03:00
Moaz Dawalibi
5fbbc2e3dc Merge branch 'main' of https://git.point-dev.net/Karimaldeen/dm-website 2024-06-22 12:13:25 +03:00
Moaz Dawalibi
0c709c0dfd single product new design 2024-06-22 12:13:12 +03:00
karimalden
10de972ca9 change logo 2024-06-15 13:44:16 +03:00
karimalden
b1fa853eb6 change color 2024-06-15 13:33:55 +03:00
Moaz Dawalibi
39382fbfdc fix search bar ,logic and add empty search component 2024-06-11 11:49:15 +03:00
Moaz Dawalibi
c9713a6e89 fix bugs 2024-06-10 17:24:05 +03:00
Moaz Dawalibi
f6c9aa9034 check on web res and fix all bugs 2024-06-10 17:23:56 +03:00
karimalden
d5ad2a68ff dix_product_api 2024-06-10 12:16:04 +03:00
karimalden
36ffb8ef19 add_cart_notfound 2024-06-10 12:00:38 +03:00
karimalden
2421bce5f7 first_push 2024-06-10 11:01:05 +03:00
karimalden
996c5389d4 first commit 2024-06-10 11:00:52 +03:00
82 changed files with 807 additions and 494 deletions

0
.gitignore vendored Normal file → Executable file
View File

12
index.html Normal file → Executable file
View File

@ -4,13 +4,13 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<link rel="android-chrome" href="./App/Logo.svg" /> <link rel="android-chrome" href="./App/Logo.png" />
<link rel="android-chrome" href="./App/Logo.svg" /> <link rel="android-chrome" href="./App/Logo.png" />
<link rel="canonical" href="https://karimalden.vercel.app/" /> <link rel="canonical" href="https://karimalden.vercel.app/" />
<link rel="apple-touch-icon" sizes="180x180" href="./App/Logo.svg" /> <link rel="apple-touch-icon" sizes="180x180" href="./App/Logo.png" />
<link rel="icon" type="image/png" sizes="32x32" href="./App/Logo.svg" /> <link rel="icon" type="image/png" sizes="32x32" href="./App/Logo.png" />
<link rel="icon" type="image/png" sizes="16x16" href="./App/Logo.svg" /> <link rel="icon" type="image/png" sizes="16x16" href="./App/Logo.png" />
<link rel="manifest" href="./site.webmanifest" /> <link rel="manifest" href="./site.webmanifest" />
<meta <meta
name="description" name="description"
@ -22,7 +22,7 @@
property="og:description" property="og:description"
content="Landing Page About My Work and Includ My Cv As Front End Developer Use Reactjs In Syria" content="Landing Page About My Work and Includ My Cv As Front End Developer Use Reactjs In Syria"
/> />
<meta property="og:image" content="./App/Logo.svg" /> <meta property="og:image" content="./App/Logo.png" />
<meta property="og:url" content="https://karimalden.vercel.app" /> <meta property="og:url" content="https://karimalden.vercel.app" />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<script type="module" src="/src/index.tsx"></script> <script type="module" src="/src/index.tsx"></script>

View File

@ -13,6 +13,7 @@
"axios": "^1.7.2", "axios": "^1.7.2",
"bootstrap": "^5.3.3", "bootstrap": "^5.3.3",
"chart.js": "^4.4.3", "chart.js": "^4.4.3",
"classnames": "^2.5.1",
"dayjs": "^1.11.11", "dayjs": "^1.11.11",
"firebase": "^10.12.2", "firebase": "^10.12.2",
"formik": "^2.4.6", "formik": "^2.4.6",

BIN
public/About/about_hand.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

BIN
public/About/about_lap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -1,6 +1,6 @@
<svg width="72" height="34" viewBox="0 0 72 34" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="72" height="34" viewBox="0 0 72 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2001_4350)"> <g clip-path="url(#clip0_2001_4350)">
<path d="M34.9514 12.9924C34.4047 16.0388 33.9491 18.929 33.116 21.6629C31.3456 27.5058 27.9089 31.2239 22.7931 32.6143C21.1138 33.0674 19.4215 33.2236 17.7032 33.2236C12.0406 33.2236 6.37794 33.2236 0.71531 33.2392C0.181591 33.2392 -0.0136719 33.1455 -0.0136719 32.4112C0.0123632 26.2091 0.0123632 20.0226 -0.0136719 13.8204C-0.0136719 13.2268 0.103486 13.0393 0.624188 13.0393C2.99338 13.0706 5.34955 13.0706 7.71875 13.0393C8.23945 13.0393 8.40868 13.1643 8.40868 13.8361C8.36962 17.273 8.40868 20.71 8.38264 24.1469C8.38264 24.7562 8.4998 24.9437 9.03352 24.928C12.0276 24.8968 15.0216 24.9437 18.0156 24.8968C20.3848 24.8656 22.5978 24.2407 24.3812 22.1785C25.3835 21.038 25.7871 19.5539 26.1646 18.0229C27.2451 13.5705 28.3255 9.10244 29.432 4.65003C30.3042 1.18183 32.9598 -0.521025 35.7715 0.556928C37.0863 1.05685 37.9715 2.18167 38.6094 3.57207C41.4862 9.75858 44.5454 15.8201 47.1879 22.1629C47.227 22.2566 47.266 22.3347 47.3571 22.5066C47.6045 21.8973 47.8128 21.3505 48.0471 20.8037C50.6246 14.9453 53.3973 9.2118 56.131 3.46271C57.667 0.244478 60.6871 -0.661628 63.1865 1.19745C64.2539 1.9942 64.8788 3.18151 65.2172 4.58753C66.9616 11.8051 68.6799 19.0071 70.4112 26.2247C70.9189 28.3337 71.4136 30.4428 71.9343 32.5362C72.0514 33.0205 72.0775 33.2392 71.5307 33.2392C69.1225 33.1923 66.7142 33.208 64.306 33.2392C63.8894 33.2392 63.7462 33.0517 63.6551 32.6299C62.3794 26.5997 60.8694 20.6475 59.6848 14.6016C59.5936 14.1329 59.5155 13.6642 59.3984 13.0237C59.1771 13.5236 59.0209 13.8673 58.8777 14.2266C56.6907 19.7101 54.2434 25.0218 51.8742 30.3803C50.4293 33.6454 48.3204 34.2703 45.1962 33.3954C44.0897 33.083 43.3347 32.0675 42.814 30.9115C41.33 27.6776 39.8721 24.4125 38.4401 21.1318C37.3206 18.5384 36.11 16.0076 35.1337 13.3205C35.0816 13.258 35.0556 13.1955 34.9514 12.9924Z" fill="red"/> <path d="M34.9514 12.9924C34.4047 16.0388 33.9491 18.929 33.116 21.6629C31.3456 27.5058 27.9089 31.2239 22.7931 32.6143C21.1138 33.0674 19.4215 33.2236 17.7032 33.2236C12.0406 33.2236 6.37794 33.2236 0.71531 33.2392C0.181591 33.2392 -0.0136719 33.1455 -0.0136719 32.4112C0.0123632 26.2091 0.0123632 20.0226 -0.0136719 13.8204C-0.0136719 13.2268 0.103486 13.0393 0.624188 13.0393C2.99338 13.0706 5.34955 13.0706 7.71875 13.0393C8.23945 13.0393 8.40868 13.1643 8.40868 13.8361C8.36962 17.273 8.40868 20.71 8.38264 24.1469C8.38264 24.7562 8.4998 24.9437 9.03352 24.928C12.0276 24.8968 15.0216 24.9437 18.0156 24.8968C20.3848 24.8656 22.5978 24.2407 24.3812 22.1785C25.3835 21.038 25.7871 19.5539 26.1646 18.0229C27.2451 13.5705 28.3255 9.10244 29.432 4.65003C30.3042 1.18183 32.9598 -0.521025 35.7715 0.556928C37.0863 1.05685 37.9715 2.18167 38.6094 3.57207C41.4862 9.75858 44.5454 15.8201 47.1879 22.1629C47.227 22.2566 47.266 22.3347 47.3571 22.5066C47.6045 21.8973 47.8128 21.3505 48.0471 20.8037C50.6246 14.9453 53.3973 9.2118 56.131 3.46271C57.667 0.244478 60.6871 -0.661628 63.1865 1.19745C64.2539 1.9942 64.8788 3.18151 65.2172 4.58753C66.9616 11.8051 68.6799 19.0071 70.4112 26.2247C70.9189 28.3337 71.4136 30.4428 71.9343 32.5362C72.0514 33.0205 72.0775 33.2392 71.5307 33.2392C69.1225 33.1923 66.7142 33.208 64.306 33.2392C63.8894 33.2392 63.7462 33.0517 63.6551 32.6299C62.3794 26.5997 60.8694 20.6475 59.6848 14.6016C59.5936 14.1329 59.5155 13.6642 59.3984 13.0237C59.1771 13.5236 59.0209 13.8673 58.8777 14.2266C56.6907 19.7101 54.2434 25.0218 51.8742 30.3803C50.4293 33.6454 48.3204 34.2703 45.1962 33.3954C44.0897 33.083 43.3347 32.0675 42.814 30.9115C41.33 27.6776 39.8721 24.4125 38.4401 21.1318C37.3206 18.5384 36.11 16.0076 35.1337 13.3205C35.0816 13.258 35.0556 13.1955 34.9514 12.9924Z" fill="#eb671b"/>
<path d="M24.1476 11.8056C22.0778 9.71216 19.6825 9.16537 17.1051 9.181C11.4685 9.22786 5.83188 9.19662 0.078125 9.19662C0.559774 8.43112 0.989353 7.74373 1.41893 7.05634C2.62956 5.13477 3.85321 3.2132 5.05082 1.27601C5.24609 0.963559 5.44135 0.791711 5.79282 0.807334C10.5182 0.869824 15.2436 0.682354 19.9689 0.932314C22.0387 1.04167 24.0434 1.63533 25.983 2.57268C26.3605 2.76015 26.3345 2.94762 26.2434 3.32256C25.5404 6.11899 24.8635 8.89979 24.1476 11.8056Z" fill="#AFB0B6"/> <path d="M24.1476 11.8056C22.0778 9.71216 19.6825 9.16537 17.1051 9.181C11.4685 9.22786 5.83188 9.19662 0.078125 9.19662C0.559774 8.43112 0.989353 7.74373 1.41893 7.05634C2.62956 5.13477 3.85321 3.2132 5.05082 1.27601C5.24609 0.963559 5.44135 0.791711 5.79282 0.807334C10.5182 0.869824 15.2436 0.682354 19.9689 0.932314C22.0387 1.04167 24.0434 1.63533 25.983 2.57268C26.3605 2.76015 26.3345 2.94762 26.2434 3.32256C25.5404 6.11899 24.8635 8.89979 24.1476 11.8056Z" fill="#AFB0B6"/>
</g> </g>
<defs> <defs>

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/Cart/empty_card.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,3 +1,3 @@
<svg width="500" height="695" viewBox="0 0 500 695" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="500" height="695" viewBox="0 0 500 695" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M500 -24H220V-23.9353C194.171 -23.7928 168.277 -10.9011 153.712 17.4919L8.37793 300.812C-2.79264 322.588 -2.79264 348.412 8.37792 370.188L153.712 653.508C168.277 681.901 194.171 694.793 220 694.935V695H500V-24Z" fill="red"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M500 -24H220V-23.9353C194.171 -23.7928 168.277 -10.9011 153.712 17.4919L8.37793 300.812C-2.79264 322.588 -2.79264 348.412 8.37792 370.188L153.712 653.508C168.277 681.901 194.171 694.793 220 694.935V695H500V-24Z" fill="#eb671b"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 381 B

After

Width:  |  Height:  |  Size: 385 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

0
public/Layout/Ar.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/Layout/DMlOGO.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

0
public/Layout/En.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

0
public/Layout/KarimLogo.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -18,7 +18,6 @@ firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging(); const messaging = firebase.messaging();
messaging.onBackgroundMessage(function (payload) { messaging.onBackgroundMessage(function (payload) {
console.log("Received background message ", payload);
const notificationTitle = payload.notification.title; const notificationTitle = payload.notification.title;
const notificationOptions = { const notificationOptions = {

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

12
public/index.html Normal file → Executable file
View File

@ -4,13 +4,13 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<link rel="android-chrome" href="./App/Logo.svg" /> <link rel="android-chrome" href="./App/Logo.png" />
<link rel="android-chrome" href="./App/Logo.svg" /> <link rel="android-chrome" href="./App/Logo.png" />
<link rel="canonical" href="https://karimalden.vercel.app/" /> <link rel="canonical" href="https://karimalden.vercel.app/" />
<link rel="apple-touch-icon" sizes="180x180" href="./App/Logo.svg" /> <link rel="apple-touch-icon" sizes="180x180" href="./App/Logo.png" />
<link rel="icon" type="image/png" sizes="32x32" href="./App/Logo.svg" /> <link rel="icon" type="image/png" sizes="32x32" href="./App/Logo.png" />
<link rel="icon" type="image/png" sizes="16x16" href="./App/Logo.svg" /> <link rel="icon" type="image/png" sizes="16x16" href="./App/Logo.png" />
<link rel="manifest" href="./site.webmanifest" /> <link rel="manifest" href="./site.webmanifest" />
<meta <meta
name="description" name="description"
@ -22,7 +22,7 @@
property="og:description" property="og:description"
content="Landing Page About My Work and Includ My Cv As Front End Developer Use Reactjs In Syria" content="Landing Page About My Work and Includ My Cv As Front End Developer Use Reactjs In Syria"
/> />
<meta property="og:image" content="./App/Logo.svg" /> <meta property="og:image" content="./App/Logo.png" />
<meta property="og:url" content="https://karimalden.vercel.app" /> <meta property="og:url" content="https://karimalden.vercel.app" />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<script type="module" src="/src/index.tsx"></script> <script type="module" src="/src/index.tsx"></script>

0
public/robots.txt Normal file → Executable file
View File

View File

@ -8,17 +8,17 @@
"theme_color": "#000000", "theme_color": "#000000",
"icons": [ "icons": [
{ {
"src": "./App/Logo.svg", "src": "./App/Logo.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image/png" "type": "image/png"
}, },
{ {
"src": "./App/Logo.svg", "src": "./App/Logo.png",
"sizes": "512x512", "sizes": "512x512",
"type": "image/png" "type": "image/png"
}, },
{ {
"src": "./App/Logo.svg", "src": "./App/Logo.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image/png", "type": "image/png",
"purpose": "maskable" "purpose": "maskable"

6
src/App.tsx Normal file → Executable file
View File

@ -19,12 +19,12 @@ const App = () => {
} }
}, [data]); }, [data]);
const randomtoken = Math.random()
useEffect(() => { useEffect(() => {
const fn_firebase = (async () => { const fn_firebase = (async () => {
const token = await requestPermission() // const token = await requestPermission()
if (!Guest) { if (!Guest) {
mutate({ fcm_token: token }); mutate({ fcm_token: randomtoken });
} }
}) })
fn_firebase() fn_firebase()

View File

@ -13,8 +13,6 @@ const BrandFilter = () => {
(Category: Category): CheckboxProps["onChange"] => (Category: Category): CheckboxProps["onChange"] =>
(e) => { (e) => {
const checked = e.target.checked; const checked = e.target.checked;
console.log(Category);
console.log(languageObject(Category?.name));
if (checked) { if (checked) {

View File

@ -19,7 +19,7 @@ const CartWithDrawer = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { Cart, calculateTotalPrice, calculateTotalQuantity, removeCart } = const { Cart, calculateTotalPrice, calculateTotalQuantity, removeCart } =
useCartState(); useCartState();
const { user } = useAuthState(); const { user ,isAuthenticated} = useAuthState();
const { mutate, isLoading, isSuccess } = useAddOrder(); const { mutate, isLoading, isSuccess } = useAddOrder();
const products = Cart?.map((item: any) => ({ const products = Cart?.map((item: any) => ({
quantity: item?.quantity, quantity: item?.quantity,
@ -27,6 +27,10 @@ const CartWithDrawer = () => {
})); }));
const addOrder = () => { const addOrder = () => {
if (!isAuthenticated) {
toast.error("sorry you need to be authenticated");
return;
}
mutate({ mutate({
email: user?.email, email: user?.email,
products: products, products: products,
@ -60,8 +64,8 @@ const CartWithDrawer = () => {
onClose={() => setOpen(false)} onClose={() => setOpen(false)}
open={open} open={open}
key={placement} key={placement}
width={550} width={450}
style={{maxHeight:"90%"}} style={{maxHeight:"60%", minHeight:"500px"}}
> >
<div className="cart_first_section"> <div className="cart_first_section">
<span>{t("Cart")}</span> <span>{t("Cart")}</span>
@ -77,6 +81,7 @@ const CartWithDrawer = () => {
))} ))}
</div> </div>
{Cart?.length > 0 ? ( {Cart?.length > 0 ? (
<div className="ViewCart_Button"> <div className="ViewCart_Button">
<p> <p>
@ -97,7 +102,10 @@ const CartWithDrawer = () => {
</Button> </Button>
</div> </div>
) : ( ) : (
<div></div> <div className="EmptyCard">
{/* <img src="/Cart/empty_card.gif" alt="" />
<p>{t('You have not placed any orders yet')}</p> */}
</div>
)} )}
</div> </div>
</Drawer> </Drawer>

View File

@ -16,7 +16,7 @@ export const ChangeModeComp = ({onClickFunction, src, modeText,icon, isImage = t
const ModeContainer = memo(() => ( const ModeContainer = memo(() => (
<div className="MenuChange" onClick={onClickFunction}> <div className="MenuChange" onClick={onClickFunction}>
{isImage {isImage
? <img alt='ModeImage' src={src} width={20} height={20} /> ? <img className="mode_image" alt='ModeImage' src={src} width={20} height={20} />
: icon : icon
} }
{t(modeText)} {t(modeText)}

View File

@ -1,33 +1,22 @@
import React, { useState, ReactNode } from 'react'; import { useState } from 'react';
import type { DrawerProps } from 'antd'; import type { DrawerProps } from 'antd';
import { Badge, Button, Drawer, Space } from 'antd'; import { Drawer, Space } from 'antd';
import CardItem from '../Cart/CardItem';
import { BsArrowLeft, BsCart, BsSearch } from 'react-icons/bs';
import { Link } from 'react-router-dom';
import { ShoppingCartOutlined } from '@ant-design/icons';
import { useCartData } from '../../Redux/DispatchData';
import { useTranslation } from 'react-i18next';
import { TiDeleteOutline } from "react-icons/ti"; import { TiDeleteOutline } from "react-icons/ti";
import SearchButton from '../Utils/Search/SearchButton'; import SearchButton from '../Utils/Search/SearchButton';
import { GoClock } from "react-icons/go"; import { RiSearchLine } from "react-icons/ri";
import { FiDelete } from "react-icons/fi"; import Empty from '../Utils/Search/Empty';
import { RiSearch2Line, RiSearchLine } from "react-icons/ri";
const SearchWithDrawer = () => { const SearchWithDrawer = () => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [placement, setPlacement] = useState<DrawerProps['placement']>('right'); const [placement, setPlacement] = useState<DrawerProps['placement']>('right');
const { DataCart,count} = useCartData() const [noDataFound, setNoDataFound] = useState(false);
const {t} = useTranslation();
return ( return (
<> <>
<Space> <Space>
<div onClick={()=>setOpen(true)} className="icon_navbar"> <div onClick={() => setOpen(true)} className="icon_navbar">
<RiSearchLine /> <RiSearchLine />
</div> </div>
</Space> </Space>
<Drawer <Drawer
@ -37,20 +26,19 @@ const SearchWithDrawer = () => {
onClose={() => setOpen(false)} onClose={() => setOpen(false)}
open={open} open={open}
key={placement} key={placement}
width ={700} width={720}
style={{maxHeight:"40%"}} style={{ maxHeight: "40%" }}
> >
<div className="search_first_section"> <div className="search_first_section">
<SearchButton/> <SearchButton setOpen={setOpen} setNoDataFound={setNoDataFound} />
<span className='delete_icon' onClick={()=>setOpen(false)}><TiDeleteOutline/></span> <span className='delete_icon' onClick={() => setOpen(false)}><TiDeleteOutline /></span>
</div>
<div className='not_found_section'>
{noDataFound ? <Empty />:"" }
</div> </div>
</Drawer> </Drawer>
</> </>
); );
}; };
export default SearchWithDrawer; export default SearchWithDrawer;

View File

@ -1,6 +1,7 @@
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import ProductSwiper from "./ProductSwiper"; import ProductSwiper from "./ProductSwiper";
import { useGetBaseProduct } from "../../api/baseProduct";
const Products = () => { const Products = () => {
const {t} = useTranslation(); const {t} = useTranslation();
@ -9,6 +10,10 @@ const Products = () => {
const handelSeeAll = () => { const handelSeeAll = () => {
navigate(`/categories?type=best_sale`); navigate(`/categories?type=best_sale`);
}; };
const { data,isLoading } = useGetBaseProduct({
mostOrderd: "asc",
})
return ( return (
<div className="Products"> <div className="Products">
<header> <header>
@ -16,7 +21,7 @@ const Products = () => {
<h5 className="pointer" onClick={handelSeeAll}> {t("View all")} </h5> <h5 className="pointer" onClick={handelSeeAll}> {t("View all")} </h5>
</header> </header>
<main className="ProductCards"> <main className="ProductCards">
<ProductSwiper/> <ProductSwiper data={data} isLoading={isLoading} />
</main> </main>
</div> </div>
); );

View File

@ -1,6 +1,6 @@
import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { GoArrowUpRight } from "react-icons/go"; import { RiArrowRightUpFill } from "react-icons/ri";
import { Link } from "react-router-dom";
const BoseHeadphones = () => { const BoseHeadphones = () => {
const {t} = useTranslation(); const {t} = useTranslation();
@ -10,10 +10,12 @@ const BoseHeadphones = () => {
<div> <div>
<h6>{t("Bose Headphones")}</h6> <h6>{t("Bose Headphones")}</h6>
<h1>{t("Smarter than your average headphones")}</h1> <h1>{t("Smarter than your average headphones")}</h1>
<button className="button"> <Link to="/categories" >
{t("Shop now")} <button className="button">
<GoArrowUpRight /> {t("Shop now")}
</button> <RiArrowRightUpFill />
</button>
</Link>
</div> </div>
</div> </div>
); );

View File

@ -17,10 +17,8 @@ const ProductCard = ({ item }: { item: Product }) => {
const [t] = useTranslation(); const [t] = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
const { isAuthenticated } = useAuthState(); const { isAuthenticated } = useAuthState();
// console.log(item);
const handel_click = (id: number) => { const handel_click = (id: number) => {
console.log(id);
navigate(`/product/${id}`); navigate(`/product/${id}`);
}; };
@ -40,10 +38,10 @@ const ProductCard = ({ item }: { item: Product }) => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const handelChangeFavorite = (item: Product) => { const handelChangeFavorite = (item: Product) => {
if (!isAuthenticated) { // if (!isAuthenticated) {
toast.error("sorry you need to be authenticated"); // toast.error("sorry you need to be authenticated");
return; // return;
} // }
if (item?.favorite) { if (item?.favorite) {
@ -55,6 +53,8 @@ const ProductCard = ({ item }: { item: Product }) => {
id: item?.id, id: item?.id,
}); });
} }
queryClient.invalidateQueries('mainProduct');
}; };
useEffect(() => { useEffect(() => {
@ -71,11 +71,11 @@ const ProductCard = ({ item }: { item: Product }) => {
}, [Delete]); }, [Delete]);
const handelAddToCart = (item: Product) => { const handelAddToCart = (item: Product) => {
if (!isAuthenticated) { // if (!isAuthenticated) {
toast.error("sorry you need to be authenticated"); // toast.error("sorry you need to be authenticated");
return; // return;
} // }
setCart(item); setCart(item);

View File

@ -1,26 +1,21 @@
import React, { useRef, useState } from 'react'; import { useRef, useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react'; import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css'; import 'swiper/css';
import 'swiper/css/free-mode'; import 'swiper/css/free-mode';
import 'swiper/css/pagination'; import 'swiper/css/pagination';
import ProductCard from './ProductCard'; import ProductCard from './ProductCard';
import { Product } from '../../types/item'; import { Product } from '../../types/item';
import { useGetBaseProduct } from '../../api/baseProduct';
import { A11y, Autoplay, Navigation, Pagination, Scrollbar } from 'swiper/modules'; import { A11y, Autoplay, Navigation, Pagination, Scrollbar } from 'swiper/modules';
import { Spin } from 'antd'; import { Spin } from 'antd';
const ProductSwiper = () => { const ProductSwiper = ({data,isLoading}:any) => {
const language = localStorage.getItem('language') ; const language = localStorage.getItem('language') ;
console.log(language);
const [swiperDirection, setSwiperDirection] = useState(language === "ar" ? "rtl" : "ltr"); const [swiperDirection, setSwiperDirection] = useState(language === "ar" ? "rtl" : "ltr");
const swiperRef = useRef<any>(null); const swiperRef = useRef<any>(null);
const { data, isLoading } = useGetBaseProduct({
mostOrderd: "asc",
});
const BaseProducts = (data?.products as Product[]) || ([] as []); const BaseProducts = (data?.products as Product[]) || ([] as []);
return ( return (
@ -31,7 +26,7 @@ const ProductSwiper = () => {
spaceBetween={50} spaceBetween={50}
breakpoints={{ breakpoints={{
0: { slidesPerView: 1 }, 0: { slidesPerView: 1 },
400: { slidesPerView: 2 }, 400: { slidesPerView: 1 },
600: { slidesPerView: 2 }, 600: { slidesPerView: 2 },
900: { slidesPerView: 4 }, 900: { slidesPerView: 4 },
1200: { slidesPerView: 4 }, 1200: { slidesPerView: 4 },

View File

@ -1,6 +1,7 @@
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import ProductSwiper from "./ProductSwiper"; import ProductSwiper from "./ProductSwiper";
import { useGetBaseProduct } from "../../api/baseProduct";
const Products = () => { const Products = () => {
const {t} = useTranslation(); const {t} = useTranslation();
@ -10,6 +11,11 @@ const Products = () => {
navigate(`/categories?type=new_product`); navigate(`/categories?type=new_product`);
}; };
const { data,isLoading } = useGetBaseProduct({
lastProducts:"asc"
});
return ( return (
<div className="Products"> <div className="Products">
<header> <header>
@ -17,7 +23,7 @@ const Products = () => {
<h5 className="pointer" onClick={handelSeeAll}> {t("View all")} </h5> <h5 className="pointer" onClick={handelSeeAll}> {t("View all")} </h5>
</header> </header>
<main className="ProductCards"> <main className="ProductCards">
<ProductSwiper/> <ProductSwiper data={data} isLoading={isLoading} />
</main> </main>
</div> </div>
); );

View File

@ -0,0 +1,27 @@
import { useTranslation } from 'react-i18next';
import { languageObject } from '../../utils/languageObject';
const ProductAdditionalInfo = (data:any) => {
const ProductAdditionalInfo = data?.data;
const { t } = useTranslation();
const infoEntries = ProductAdditionalInfo?.info ? Object.entries(ProductAdditionalInfo.info) : [];
return (
<div className='product_additional_info'>
<h4>{t("Additional Info")}</h4>
{infoEntries.length > 0 ? (
infoEntries.map(([key, value]: [any, any]) => (
<span key={key}>
<h6>{languageObject(key)}</h6>
<h5>{languageObject(value)}</h5>
</span>
))
) : (
<p>{t("Product info is empty")}</p>
)}
</div>
);
};
export default ProductAdditionalInfo;

View File

@ -0,0 +1,14 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
const ProductDescription = ({data}:any) => {
const {t} = useTranslation();
return (
<div className='product_description'>
<h4>{t("Description")}</h4>
<p>{data?.description}</p>
</div>
)
}
export default ProductDescription

View File

@ -0,0 +1,31 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import { languageObject } from '../../utils/languageObject';
const ProductInfo = (data:any) => {
const productInfo = data?.data
const {t} = useTranslation();
return (
<div className='Product_info'>
<h4>{t("Info")}</h4>
<div>
<span>
<h6>{t("name")}</h6> <h5>{languageObject(productInfo?.name)}</h5>
</span>
<span>
<h6>{t("Category")}</h6> <h5>{languageObject(productInfo?.category?.name)}</h5>
</span>
<span>
<h6>{t("Price")}</h6> <h5>{productInfo?.price}</h5>
</span>
<span>
<h6>{t("Description")}</h6> <h5>{languageObject(productInfo?.description)}</h5>
</span>
</div>
</div>
)
}
export default ProductInfo

View File

@ -0,0 +1,42 @@
// import Swiper core and required modules
import { Navigation, A11y } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";
// Import Swiper styles
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
import "swiper/css/scrollbar";
import CustomImage from "../../ui/CustomImage";
const ProductSlider = (data:any) => {
const handelImage = (item: any) => {
// setMainImage(item);
};
return (
<div className="product_images_swiper">
<Swiper
modules={[Navigation, A11y]}
spaceBetween={10}
slidesPerView={4}
navigation
>
{data?.images?.map(({item,index}:any)=>{
return (
<SwiperSlide key={index}>
<span key={index} onClick={() => handelImage(item?.path)} >
<CustomImage
className="product_multi_image"
src={item?.path}
alt=""
/>
</span>
</SwiperSlide>
)
})}
</Swiper>
</div>
);
};
export default ProductSlider;

View File

@ -0,0 +1,36 @@
import React from 'react';
import { Tabs } from 'antd';
import type { TabsProps } from 'antd';
import { useTranslation } from 'react-i18next';
import ProductDescription from './ProductDescription';
import ProductInfo from './ProductInfo';
import ProductAdditionalInfo from './ProductAdditionalInfo';
const ProductTabs = ({data}:any) => {
const {t} = useTranslation();
const items: TabsProps['items'] = [
{
key: '1',
label: t('product_info'),
children: <ProductInfo data={data}/>,
},
{
key: '2',
label: t('description'),
children: <ProductDescription data={data}/>,
},
{
key: '3',
label: t('additional information'),
children: <ProductAdditionalInfo data={data}/>,
},
];
return (
<Tabs className='product_tabs' defaultActiveKey="1" items={items} />
)
}
export default ProductTabs

View File

@ -13,20 +13,20 @@ const ContactTab = ({className=""}: {className?: string }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const {mutate,isSuccess,isLoading} = useAddSupportMessage() const {mutate,isSuccess,isLoading} = useAddSupportMessage()
const SoicalInfo: { icon: any; text: string }[] = [ const SoicalInfo: { icon: any; text: string }[] = [
{ {
icon: <IoMailOutline/>, icon: <IoMailOutline/>,
text: "info@yourdomain.com", text: "info@yourdomain.com",
}, },
{ {
icon: <FiPhone/> , icon: <FiPhone/> ,
text: "+1 (378) 400-1234", text: "+1 (378) 400-1234",
}, },
{ {
icon: <IoEarthOutline/>, icon: <IoEarthOutline/>,
text: "www.yourdomain.com", text: "www.yourdomain.com",
}, },
]; ];
const SoicalIcons: { icon: any; }[] = [ const SoicalIcons: { icon: any; }[] = [
{ {

0
src/Components/Utils/Loading/Loading.scss Normal file → Executable file
View File

0
src/Components/Utils/Loading/Loading.tsx Normal file → Executable file
View File

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

@ -1,53 +1,70 @@
import React, { useState } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { Select, Spin } from 'antd'; import { Select, Spin } from 'antd';
import { useNavigate, useSearchParams } from 'react-router-dom'; import { useNavigate, useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { LuSearch } from 'react-icons/lu'; import { LuSearch } from 'react-icons/lu';
import { useGetBaseProduct } from '../../../api/baseProduct'; import { useGetBaseProduct } from '../../../api/baseProduct';
import { Product } from '../../../types/item'; import { Product } from '../../../types/item';
import _ from 'lodash';
const SearchButton: React.FC = () => { interface SearchButtonProps {
setOpen: (open: boolean) => void;
setNoDataFound: (noData: boolean) => void;
}
const SearchButton: React.FC<SearchButtonProps> = ({ setOpen, setNoDataFound }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const { t } = useTranslation(); const { t } = useTranslation();
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const [query, setQuery] = useState<string | null>(searchParams.get('search')); const [query, setQuery] = useState<string | null>(searchParams.get('search'));
const { data, isLoading } = useGetBaseProduct({ const { data, isLoading } = useGetBaseProduct({
name: query, search: query,
}); });
const BaseProducts = (data?.products as Product[]) || []; const BaseProducts = (data?.products as Product[]) || [];
useEffect(() => {
setNoDataFound(!isLoading && BaseProducts.length < 1);
}, [isLoading, BaseProducts, setNoDataFound]);
const options = BaseProducts.map((product: any) => ({ const options = BaseProducts.map((product: any) => ({
value: product.base_product_id, value: product.base_product_id,
label: product?.name as string, // Ensuring the label is a string label: product?.name as string,
})); }));
const debouncedSearchChange = useCallback(
_.debounce((value: string) => {
setQuery(value);
navigate(`${window.location.pathname}?search=${value}`, {
replace: true,
});
}, 500), // Adjust the debounce delay (in milliseconds) as needed
[]
);
const handleSearchChange = (value: string) => { const handleSearchChange = (value: string) => {
setQuery(value); debouncedSearchChange(value);
navigate(`${window.location.pathname}?search=${value}`, {
replace: true,
});
}; };
const handleSelectChange = (value: number) => { const handleSelectChange = (value: number) => {
const selectedProduct = BaseProducts.find(product => product.base_product_id === value); const selectedProduct = BaseProducts.find(product => product.base_product_id === value);
if (selectedProduct) { if (selectedProduct) {
setOpen(false);
navigate(`/product/${selectedProduct.base_product_id}`); navigate(`/product/${selectedProduct.base_product_id}`);
} }
}; };
const filterOption = (input: string, option?: { label: string }) => { const filterOption = (input: string, option?: { label: string }) => {
if (!option) return false; if (!option) return false;
const filteredData = option?.label.toLowerCase().includes(input.toLowerCase()); return option?.label.toLowerCase().includes(input.toLowerCase());
return filteredData;
}; };
return ( return (
<Select <Select
className='InputAutoComplete' className='InputAutoComplete'
suffixIcon={<LuSearch />} suffixIcon={<LuSearch />}
placeholder={t('Search Product Name') as string} // Ensuring the placeholder is a string placeholder={t('Search Product Name') as string}
allowClear allowClear
showSearch showSearch
loading={isLoading} loading={isLoading}
@ -56,9 +73,7 @@ const SearchButton: React.FC = () => {
options={options} options={options}
optionFilterProp="label" optionFilterProp="label"
filterOption={filterOption} filterOption={filterOption}
notFoundContent={ notFoundContent={isLoading ? <Spin /> : null}
isLoading ? <Spin/> : "not found data"
}
/> />
); );
}; };

45
src/Components/Utils/SearchBar/SearchBar.scss Normal file → Executable file
View File

@ -35,7 +35,7 @@
.InputAutoComplete{ .InputAutoComplete{
width: 78%; width: 78%;
height: 48px; height: 48px;
margin-top: 0px;margin-bottom: 38px; margin-top: 12px;margin-bottom: 38px;
.ant-select-arrow{ .ant-select-arrow{
font-size: 32px; font-size: 32px;
color: var(--DarkGray) !important; color: var(--DarkGray) !important;
@ -95,13 +95,38 @@
} }
} }
} }
.not_found_section{
.ViewSearch{ @include Flex;
.ant-drawer .ant-drawer-content { .Empty{
height: 50% !important ;width: 100% ; @include Flex; flex-direction: column;
min-height: 50% !important; p,h1{
display: flex; flex-direction: column; font-size: 20px;
border-radius: 5px 0 0 5px;
}
} }
}
}
.ViewSearch{
.ant-drawer .ant-drawer-content {
height: 50% !important ;width: 100% ;
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:600px) {
.not_found_section{
.Empty{
h1 , p{
text-align: center;
font-size: 12px !important;
}
}
}
}

0
src/Components/Utils/SearchBar/SearchBar.tsx Normal file → Executable file
View File

0
src/Components/Utils/Translate.tsx Normal file → Executable file
View File

View File

@ -13,11 +13,11 @@ import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
const Footer = () => { const Footer = () => {
const {t} = useTranslation(); const { t } = useTranslation();
return ( return (
<div className="Footer"> <div className="Footer">
<div className="footer_first_section"> <div className="footer_first_section">
<img src="/App/Logo.svg" alt="" /> <img src="/App/Logo.png" alt="" />
<p> <p>
{t("DM is the one of the worlds largest online shops that providing over 1500 headphones for its costumers from over 80 countries")} {t("DM is the one of the worlds largest online shops that providing over 1500 headphones for its costumers from over 80 countries")}
</p> </p>

0
src/Layout/Ui/Layout.tsx Normal file → Executable file
View File

6
src/Layout/Ui/NavBar.tsx Normal file → Executable file
View File

@ -39,7 +39,7 @@ const NavBar = () => {
return ( return (
<div className="navbar"> <div className="navbar">
<Link to={'/'}><img src="/App/Logo.svg" alt="Logo" /></Link> <Link to={'/'}><img src="/App/Logo.png" alt="Logo" /></Link>
<div className="navbar_links"> <div className="navbar_links">
{Links?.map((item: item, index: number) => { {Links?.map((item: item, index: number) => {
if (item?.href === "help") { if (item?.href === "help") {
@ -69,12 +69,12 @@ const NavBar = () => {
<article> <article>
<div className='icon_navbar search_icon'><ViewSearch /></div> <div className='icon_navbar search_icon'><ViewSearch /></div>
<div className='cart_container icon_navbar'><ViewCart /></div> <div className='cart_container icon_navbar'><ViewCart /></div>
<Translate/> <Translate />
<Auth /> <Auth />
</article> </article>
<div className="menu"> <div className="menu">
<GiHamburgerMenu onClick={showDrawer} /> <GiHamburgerMenu onClick={showDrawer} />
<Drawer width={200} onClose={onClose} open={open} extra={<img src="/App/Logo.svg" alt="Logo" width={40}/>}> <Drawer width={200} onClose={onClose} open={open} extra={<img src="/App/Logo.png" alt="Logo" width={40} />}>
<div className="menu_navbar_links"> <div className="menu_navbar_links">
{Links?.map((item: item, index: number) => { {Links?.map((item: item, index: number) => {

0
src/Layout/Ui/SideBar.tsx Normal file → Executable file
View File

2
src/Layout/app/Const.tsx Normal file → Executable file

File diff suppressed because one or more lines are too long

View File

@ -7,11 +7,11 @@ const Page = () => {
const [t] = useTranslation(); const [t] = useTranslation();
return ( return (
<div className="About"> <div className="About">
<HeaderLink text='About'/> <HeaderLink text='about'/>
<div className="About_Laptop"> <div className="About_Laptop">
<img src="/About/Laptop.png" alt="" /> <img src="/About/about_lap.png" alt="" />
</div> </div>
<div className="Dm_Group"> <div className="Dm_Group">
@ -47,7 +47,7 @@ const Page = () => {
</div> </div>
</div> </div>
<div className="Hands"> <div className="Hands">
<img src="/About/Hands.png" alt="" /> <img src="/About/about_hand.png" alt="" />
</div> </div>
<img src="/About/line.svg" alt="" /> <img src="/About/line.svg" alt="" />

3
src/Pages/Auth/LoginForm.tsx Normal file → Executable file
View File

@ -18,6 +18,7 @@ const LoginForm = ({ setOpen }: any) => {
const { mutate, isLoading, isSuccess, data } = useLogin(); const { mutate, isLoading, isSuccess, data } = useLogin();
const { login } = useAuthState(); const { login } = useAuthState();
const FCM = localStorage.getItem(FCM_TOKEN_KEY) const FCM = localStorage.getItem(FCM_TOKEN_KEY)
const random_token = Math.random()
const handelSubmit = (values: any) => { const handelSubmit = (values: any) => {
if (!values.email || !values.password) { if (!values.email || !values.password) {
@ -25,7 +26,7 @@ const LoginForm = ({ setOpen }: any) => {
return; return;
} }
mutate({ ...values, fcm_token: FCM }); mutate({ ...values, fcm_token: random_token });
}; };
useEffect(() => { useEffect(() => {

View File

@ -19,7 +19,6 @@ const Page = () => {
const [type, setType] = useState(type_param); const [type, setType] = useState(type_param);
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const [totalItems, setTotalItems] = useState(0); const [totalItems, setTotalItems] = useState(0);
console.log(totalItems);
useEffect(() => { useEffect(() => {
@ -63,7 +62,6 @@ const Page = () => {
}; };
const categories = Filter?.filter((item:any)=> item.select !== true)?.map((item:any)=> item?.id) const categories = Filter?.filter((item:any)=> item.select !== true)?.map((item:any)=> item?.id)
console.log(categories,"categories");
const { data , isLoading } = useGetBaseProduct({ const { data , isLoading } = useGetBaseProduct({

View File

@ -1,16 +1,10 @@
import React, { useRef, useState } from 'react' import React, { useState } from 'react'
import { FaChevronRight, FaInstagram, FaLinkedinIn, FaTwitter } from "react-icons/fa6";
import { Button, Form } from 'react-bootstrap';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { IoMailOutline,IoEarthOutline } from "react-icons/io5";
import { FiPhone } from "react-icons/fi";
import { FaFacebookF } from "react-icons/fa";
import ContactTab from '../../Components/Setting/Tabs/ContactTab'; import ContactTab from '../../Components/Setting/Tabs/ContactTab';
import HeaderLink from '../../Components/Ui/HeaderLink'; import HeaderLink from '../../Components/Ui/HeaderLink';
const Contact = () => { const Contact = () => {
const form = useRef<any>(null);
const { t } = useTranslation(); const { t } = useTranslation();
const sendEmail = (e: React.FormEvent<HTMLFormElement>) => { const sendEmail = (e: React.FormEvent<HTMLFormElement>) => {
@ -35,35 +29,6 @@ const Contact = () => {
const [Message , setMessage] = useState('') const [Message , setMessage] = useState('')
const SoicalInfo: { icon: any; text: string }[] = [
{
icon: <IoMailOutline/>,
text: "info@yourdomain.com",
},
{
icon: <FiPhone/> ,
text: "+1 (378) 400-1234",
},
{
icon: <IoEarthOutline/>,
text: "www.yourdomain.com",
},
];
const SoicalIcons: { icon: any; }[] = [
{
icon: <FaFacebookF/>,
},
{
icon: <FaTwitter /> ,
},
{
icon: <FaLinkedinIn />,
},
{
icon: <FaInstagram />,
},
];
return ( return (
<div className='contact_container'> <div className='contact_container'>

View File

@ -1,11 +1,20 @@
import type { CollapseProps } from "antd"; import type { CollapseProps } from "antd";
import { Collapse } from "antd"; import { Collapse } from "antd";
import React from 'react' import React, { useState } from 'react';
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import classNames from 'classnames';
const CollapseGroup = () => { const CollapseGroup = () => {
const {t} = useTranslation(); 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"] = [ const items: CollapseProps["items"] = [
{ {
@ -22,7 +31,7 @@ const CollapseGroup = () => {
label: t("How can I engage with the magazine content on DM?"), label: t("How can I engage with the magazine content on DM?"),
children: ( children: (
<p> <p>
{t("You can actively engage with the magazine content by leaving comments and participating in the question-and-answer section. Feel free to share your thoughts, ask questions, and interact with enthusiastsin the community")}. {t("You can actively engage with the magazine content by leaving comments and participating in the question-and-answer section. Feel free to share your thoughts, ask questions, and interact with enthusiasts in the community")}.
</p> </p>
), ),
}, },
@ -49,7 +58,7 @@ const CollapseGroup = () => {
label: t("How can I get assistance with my purchase or any other inquiries?"), label: t("How can I get assistance with my purchase or any other inquiries?"),
children: ( children: (
<p> <p>
{t("If you need assistance with your purchase or have any questions, our dicated customer is here to help. You out to us through the contact page on our website, and we'll be happy to assist you promptly")}. {t("If you need assistance with your purchase or have any questions, our dedicated customer support is here to help. You can reach out to us through the contact page on our website, and we'll be happy to assist you promptly")}.
</p> </p>
), ),
}, },
@ -57,12 +66,26 @@ const CollapseGroup = () => {
return ( return (
<Collapse <Collapse
className="faqs_collaps"
defaultActiveKey={["1"]} defaultActiveKey={["1"]}
expandIconPosition="right" expandIconPosition="right"
bordered={false} bordered={false}
items={items} 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 CollapseGroup export default CollapseGroup;

View File

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { IoIosArrowForward } from "react-icons/io"; import { IoIosArrowForward } from "react-icons/io";
import { Currency } from "../../Layout/app/Const"; import { Currency } from "../../Layout/app/Const";
@ -12,11 +12,25 @@ import { languageObject } from "../../utils/languageObject";
import { jsonObjectToArray } from "../../utils/jsonObjectToArray"; import { jsonObjectToArray } from "../../utils/jsonObjectToArray";
import HeaderLink from "../../Components/Ui/HeaderLink"; import HeaderLink from "../../Components/Ui/HeaderLink";
import { BaseURL } from "../../api/utils/config"; import { BaseURL } from "../../api/utils/config";
import ProductTabs from "../../Components/Products/ProductsTabs";
import { IoHeartOutline } from "react-icons/io5";
import { useAddFavorite, useDeleteFavorite } from "../../api/Favorite";
import { useQueryClient } from "react-query";
import { toast } from "react-toastify";
import { FaCartPlus } from "react-icons/fa";
import { useCartState } from "../../state/CartState";
import useAuthState from "../../state/AuthState";
import ProductSlider from "../../Components/Products/ProductSlider";
const Page = () => { const Page = () => {
const [t] = useTranslation(); const [t] = useTranslation();
const {product_id} = useParams() const {product_id} = useParams()
const { Cart, setCart } = useCartState();
const { isAuthenticated } = useAuthState();
const { mutate: addToFavorite, isSuccess: Add } = useAddFavorite();
const { mutate: deleteToFavorite, isSuccess: Delete } = useDeleteFavorite();
const {data,isLoading} = useGetSingleBaseProduct({ const {data,isLoading} = useGetSingleBaseProduct({
show:product_id show:product_id
}) })
@ -28,7 +42,50 @@ const Page = () => {
const handelImage = (item: any) => { const handelImage = (item: any) => {
// setMainImage(item); // setMainImage(item);
}; };
console.log(product?.images);
const queryClient = useQueryClient();
const handelChangeFavorite = (item: Product) => {
if (!isAuthenticated) {
toast.error("sorry you need to be authenticated");
return;
}
if (item?.favorite) {
deleteToFavorite({
id: item?.id,
});
} else {
addToFavorite({
id: item?.id,
});
}
queryClient.invalidateQueries('mainProduct');
};
useEffect(() => {
if (Add) {
toast.success("added to favorite successfully");
queryClient.invalidateQueries("mainProduct");
}
}, [Add]);
useEffect(() => {
if (Delete) {
toast.success("removed from favorite successfully");
queryClient.invalidateQueries("mainProduct");
}
}, [Delete]);
const handelAddToCart = (item: Product) => {
if (!isAuthenticated) {
toast.error("sorry you need to be authenticated");
return;
}
setCart(item);
toast.success(`${languageObject(item?.name)}` + " added to cart");
};
const info = jsonObjectToArray(product?.info) const info = jsonObjectToArray(product?.info)
@ -42,59 +99,34 @@ const Page = () => {
</header> </header>
<main> <main>
<div className="Product_left"> <div className="Product_left">
<span> <span className="Product_left_container">
<div className="fav_icon">
<IoHeartOutline
onClick={() => handelChangeFavorite(product)}
className={product?.favorite ? "" : "not_favorite"}
/>
<FaCartPlus
onClick={() => handelAddToCart(product)}
/>
</div>
<CustomImage src={MainImage ?? product?.main_photo} alt="" /> <CustomImage src={MainImage ?? product?.main_photo} alt="" />
<div className="gallery_product"> <div className="gallery_product">
{product?.images?.map((item,index)=>{ <ProductSlider data={product}/>
return ( {/* <span>
<span key={index} onClick={() => handelImage(item?.path)} >
<CustomImage
src={item?.path}
alt=""
/>
</span>
)
})}
<span>
<img <img
onClick={() => handelImage('/Home/p1.png')} onClick={() => handelImage('/Home/p1.png')}
// src={}
alt="" alt=""
/> />
</span> </span> */}
</div> </div>
</span> </span>
</div> </div>
<div className="Product_Right"> <div className="Product_Right">
<h1> {languageObject(product?.name)} </h1> <ProductTabs data={product}/>
<div> </div>
<span>
<h6>category</h6> <h5>{languageObject(product?.category?.name)}</h5>
</span>
<span>
<h6>price</h6> <h5>{product?.price}</h5>
</span>
<span>
<h6>brand</h6> <h5>SAMSUNG</h5>
</span>
{info?.map((item:any)=>{
return (
<span>
<h6>item</h6> <h5>SAMSUNG</h5>
</span>
)
})}
<span>
<h6>description</h6> <h5>{languageObject(product?.description)}</h5>
</span>
</div>
</div>
</main> </main>
<Similar/> <Similar category_id={product?.category?.id} />
</div> </div>
); );
}; };

View File

@ -1,16 +1,20 @@
import { useTranslation } from "react-i18next";
import { useGetBaseProduct } from "../../api/baseProduct"; import { useGetBaseProduct } from "../../api/baseProduct";
import ProductSwiper from "../../Components/Home/ProductSwiper"; import ProductSwiper from "../../Components/Home/ProductSwiper";
const Similar = () => { const Similar = ({category_id}:any) => {
const { data } = useGetBaseProduct(); const { data,isLoading } = useGetBaseProduct({
category_id:[category_id]
});
const {t} = useTranslation();
return ( return (
<div className="Products"> <div className="Products">
<header> <header>
<h1>Similar Products</h1> <h1>{t("Similar Products")}</h1>
</header> </header>
<main className="ProductCards"> <main className="ProductCards">
<ProductSwiper/> <ProductSwiper data={data} isLoading={isLoading} />
</main> </main>
</div> </div>
); );

View File

@ -14,11 +14,11 @@ function ProviderContainer({ children }: Tchildren) {
<ConfigProvider <ConfigProvider
theme={{ theme={{
token:{ token:{
colorPrimary:"red" colorPrimary:"#eb671b"
}, },
components: { components: {
Pagination: { Pagination: {
itemActiveBg: "red", itemActiveBg: "#eb671b",
}, },
}, },
}} }}

View File

@ -57,3 +57,6 @@ svg {
} }
} }
} }
//

View File

@ -112,16 +112,17 @@
} }
} }
@mixin Scrollbar($color) { @mixin Scrollbar() {
scroll-behavior: smooth; scroll-behavior: smooth;
scroll-padding: 10rem; scroll-padding: 10rem;
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 8px; width: 8px;
height: 5px;
} }
/* Handle */ /* Handle */
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background-color: $color; background-color: var(--primary);
border-radius: 3px; /* Adjust border-radius as needed */ border-radius: 3px; /* Adjust border-radius as needed */
} }

View File

@ -1,14 +1,15 @@
:root { :root {
--primary: red; --primary: #eb671b;
--secondary: rgb(255, 255, 255); --secondary: rgb(255, 255, 255);
--text: black; --text: black;
--DarkPrimary: rgb(168, 22, 22); --DarkPrimary: #e2571c;
--bg: white; --bg: white;
--bg2: #dcdcdc; --bg2: #dcdcdc;
--white: white; --white: white;
--whiteOpacity: #f6f6f6;
--shadow: rgba(0, 0, 0, 0.15); --shadow: rgba(0, 0, 0, 0.15);
--gray: rgb(207, 210, 214); --gray: rgb(207, 210, 214);
--whiteGray: #717171; --whiteGray: #717171;

View File

@ -29,8 +29,8 @@
justify-content: center; justify-content: center;
gap: 15px; gap: 15px;
padding-inline: 2vw; padding-inline: 2vw;
font-size: 1vw; font-size: 1.2vw;
font-weight: bold; font-weight: 500;
} }
@media screen and (max-width: 1000px) { @media screen and (max-width: 1000px) {

View File

@ -5,8 +5,8 @@
border-radius: var(--border-radius); border-radius: var(--border-radius);
width: fit-content; width: fit-content;
white-space: nowrap; white-space: nowrap;
background: var(--primary); background: var(--white);
color: var(--white); color: var(--primary);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -16,12 +16,12 @@
&:hover{ &:hover{
background: var(--DarkPrimary) !important; background: var(--DarkPrimary) !important;
} }
} }
}
.ant-drawer .ant-drawer-content {
display: flex; flex-direction: column;
border-radius: 5px 0 0 5px;
} }
.ant-drawer .ant-drawer-content {
display: flex; flex-direction: column;
border-radius: 5px 0 0 5px;
}
.auth_first_section{ .auth_first_section{
width: 100%; width: 100%;
display: flex;justify-content: end;align-items: end; display: flex;justify-content: end;align-items: end;

4
src/Styles/Layout/Layout.scss Normal file → Executable file
View File

@ -68,7 +68,9 @@ a:hover{
.pointer{ .pointer{
cursor: pointer; cursor: pointer;
} }
.mode_image{
margin-inline: 5px;
}
@media screen and (max-width:600px) { @media screen and (max-width:600px) {
.header_link{ .header_link{
font-size: 12px; font-size: 12px;

21
src/Styles/Layout/NavBar.scss Normal file → Executable file
View File

@ -2,7 +2,6 @@
.navbar{ .navbar{
position: absolute; position: absolute;
border: none; border: none;
} }
} }
@ -11,38 +10,28 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
color: var(--secondary); color: var(--text);
padding-inline: 5.5vw; padding-inline: 5.5vw;
height: var(--navbar-height); height: var(--navbar-height);
width: 100%; width: 100%;
z-index: 999; z-index: 999;
border-bottom: .8px solid var(--primary); border-bottom: .8px solid var(--primary);
img{
width: 45px;
>img{
width: 4.7vw;
} }
.navbar_links{ .navbar_links{
display: flex; display: flex;
gap: 3vw; gap: 3vw;
.navbar_link{ .navbar_link{
color: var(--text); color: var(--text);
opacity: .5; // opacity: .5;
// font-weight: bold;
cursor: pointer; cursor: pointer;
&:hover{ &:hover{
opacity: 1; opacity: 1;
} }
} }
.active{ .active{
opacity: 1; opacity: 1;
// border-bottom: .1vw solid var(--primary);
color: var(--primary); color: var(--primary);
} }
} }
@ -61,7 +50,6 @@
align-items: center; align-items: center;
>.icon_navbar{ >.icon_navbar{
padding: 10px; padding: 10px;
// background: var(--primary);
@include Flex; @include Flex;
border-radius: 50%; border-radius: 50%;
width: 30px; width: 30px;
@ -91,6 +79,7 @@
} }
.menu{ .menu{
display: inline; display: inline;
margin-inline: 10px;
svg{ svg{
color: var(--text); color: var(--text);
} }

0
src/Styles/Layout/SideBar.scss Normal file → Executable file
View File

View File

@ -68,6 +68,9 @@
color: var(--primary); color: var(--primary);
font-size: 4vw; font-size: 4vw;
} }
h6{
font-weight: 400 !important;
}
p { p {
color: var(--secondary); color: var(--secondary);
font-size: 2vw; font-size: 2vw;

View File

@ -46,9 +46,9 @@
@include Flex; @include Flex;
} }
.ViewCart_Button{ .ViewCart_Button{
width: 100%; width: 100%;
margin-top: 20px; display: flex;justify-content: space-between;
display: flex;justify-content: space-between; margin-top: 20px;
p{ p{
text-align: center; text-align: center;
font-size: 1\6px; font-size: 1\6px;
@ -69,7 +69,10 @@
} }
} }
.Drawer_Body{
height: 70vh;
display: flex; flex-direction: column; justify-content: space-between;align-items: center;
}
.ar{ .ar{
.cart_first_section{ .cart_first_section{
display: flex;justify-content: space-between; display: flex;justify-content: space-between;
@ -95,8 +98,27 @@
p{ p{
font-size: 12px; font-size: 12px;
} }
.cart_checkout_button{
font-size: 15px;
padding: 20px 10px;
}
}
}
.EmptyCard{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 5%;
gap: 20px;
img{
width: 40%;
}
p{
font-size: max(1.5vw,15px);
}
.cart_checkout_button{ .cart_checkout_button{
font-size: 15px; font-size: 15px;
} }
} }
}

View File

@ -18,18 +18,15 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: var(--bg); background: var(--bg);
// gap: 20px;
padding: 10px; padding: 10px;
> header { > header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
// height: 40px;
padding-inline: 16px; padding-inline: 16px;
// margin-inline: auto;
h4 { h4 {
font-size: 1.4vw; font-size: 1.4vw;
font-weight: bold; font-weight: 500;
color: var(--text); color: var(--text);
} }
h6 { h6 {
@ -57,7 +54,7 @@
} }
.ant-collapse-item{ .ant-collapse-item{
font-weight: 500 !important;
} }
} }
} }
@ -109,7 +106,6 @@
} }
> main { > main {
display: flex; display: flex;
// justify-content: center;
flex-wrap: wrap; flex-wrap: wrap;
gap: 40px; gap: 40px;
} }
@ -129,7 +125,16 @@
.show_on_responsive { .show_on_responsive {
display: none; display: none;
} }
.ant-collapse-header-text{
font-weight: 500 !important;
}
.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector{
padding: 0px 28px ;
}
.ant-pagination .ant-pagination-item a{
color: var(--white);
}
@media screen and (max-width: 1000px) { @media screen and (max-width: 1000px) {
.show_on_responsive { .show_on_responsive {
display: inline; display: inline;
@ -161,7 +166,7 @@
height: 40px; height: 40px;
h4 { h4 {
font-size: 1.7vw; font-size: 1.7vw;
font-weight: bold; font-weight: 500;
color: var(--text); color: var(--text);
} }
h6 { h6 {

View File

@ -1,122 +1,83 @@
.faqs_container{ .faqs_container {
display: flex;flex-direction: column; display: flex;
flex-direction: column;
width: 90vw; width: 90vw;
margin-inline: auto; margin-inline: auto;
.faqs_image_section{ .faqs_image_section {
width: 100%;
margin-top: 50px;
position: relative;
z-index: 0;
img {
width: 100%; width: 100%;
margin-top: 50px; border-radius: 10px;
position: relative; }
z-index: 0;
img{ h6 {
width: 100%; position: absolute;
border-radius: 10px; top: 43%;
} left: 50px;
h6{ color: #021736;
position: absolute; font-size: 3vw;
top: 43%; }
left: 50px;
color: #021736;
font-size: 3vw;
}
} }
.faqs_body{ .faqs_body {
width: 100%; width: 100%;
display: flex;justify-content: space-between; display: flex;
margin-block:40px; justify-content: space-between;
.left{ margin-block: 40px;
width: 20%;
h1{ .left {
font-size: 27px; width: 20%;
color: #0C0C0C;
margin-bottom: 20px; h1 {
font-size: 18px;
color: #0c0c0c;
margin-bottom: 20px;
}
p {
color: #0c0c0c;
font-size: 16px;
&:nth-child(2) {
color: var(--primary) !important;
} }
p{
color: #0C0C0C;
font-size: 20px;
&:nth-child(2) {
color: var(--primary) !important;
}
}
}
.right{
width: 80%;
} }
}
.right {
width: 80%;
}
} }
} }
.ant-collapse [class^="ant-collapse"],
.ant-collapse [class*=" ant-collapse"] {
.ant-collapse [class^="ant-collapse"], .ant-collapse [class*=" ant-collapse"]{
background: #fff; background: #fff;
} }
.ant-collapse>.ant-collapse-item >.ant-collapse-header .ant-collapse-header-text{ .ant-collapse > .ant-collapse-item > .ant-collapse-header .ant-collapse-header-text {
font-size: 1.8vw; font-size: max(20px,1.8vw);
font-weight: 500; font-weight: 500;
} }
.ant-collapse>.ant-collapse-item >.ant-collapse-header .ant-collapse-arrow svg{ .ant-collapse > .ant-collapse-item > .ant-collapse-header .ant-collapse-arrow svg {
font-size: 1.7vw; font-size: 1.7vw;
} }
.ant-collapse .ant-collapse-content{ .ant-collapse .ant-collapse-content {
p{ p {
font-size: 1.4vw; font-size: 1.4vw;
color: var(--primary); color: var(--text);
margin-bottom: 0; margin-bottom: 0;
} }
} }
@media screen and (max-width:800px) { .label-active {
.faqs_container{ color: var(--primary);
.faqs_image_section{ transition: ease-in-out .4s;
margin-top: 30px;
h6{
width: 50%;
left: 20px;
font-size: 3.5vw;
}
}
.faqs_body{
@include Flex; flex-direction: column;
width: 100%;
.left{
text-align: center;
width: 90%;
h1{
font-size: 22px;
margin-bottom: 12px;
}
p{
font-size: 18px;
}
}
.right{
width: 95%;
}
}
}
.ant-collapse>.ant-collapse-item >.ant-collapse-header .ant-collapse-header-text{
font-size: 20px;
}
.ant-collapse>.ant-collapse-item >.ant-collapse-header .ant-collapse-arrow svg{
font-size: 15px;
}
.ant-collapse .ant-collapse-content{
p{
font-size: 16px;
}
}
} }

View File

@ -10,8 +10,8 @@
&::after { &::after {
position: absolute; position: absolute;
content: ""; content: "";
right: 0;
top: 0; top: 0;
right: 0;
background: url("../../../public/Home/HeroShape.svg"); background: url("../../../public/Home/HeroShape.svg");
background-size: cover; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
@ -27,7 +27,7 @@
gap: 20px; gap: 20px;
h1 { h1 {
font-size: 4vw; font-size: 4.4vw;
font-weight: bold; font-weight: bold;
} }
@ -256,26 +256,25 @@
.BatteryLife, .BatteryLife,
.PerfectSound { .PerfectSound {
width: 100%;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
justify-content: center; img{
width: 54%;
> div { }
width: 40%; div {
width: 46%;
h1 { h1 {
font-size: 5vw; font-size: 5vw;
font-weight: bold; font-weight: 500;
} }
p { p {
font-size: 1vw; font-size: 1.24vw;
} }
} }
> img {
}
} }
.PerfectSound { .PerfectSound {
@ -289,6 +288,13 @@
} }
} }
} }
.BatteryLife{
width: 84%;
margin-inline: auto;
p{
font-size: 1.38vw !important;
}
}
} }
@media screen and (max-width: 1000px) { @media screen and (max-width: 1000px) {
@ -335,15 +341,15 @@
> div { > div {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 30px; gap: 10px;
display: none; // display: none;
h3 { h3 {
font-weight: bold; font-weight: bold;
} }
button { button {
font-size: 30px; font-size: 20px;
padding-inline: 10%; padding-inline: 10%;
border-radius: 2vw; border-radius: 2vw;
} }
@ -352,7 +358,7 @@
> span { > span {
img { img {
width: 50vw; width: 50VW;
} }
} }
} }
@ -497,7 +503,9 @@
max-width: 100vw; max-width: 100vw;
flex-wrap: wrap; flex-wrap: wrap;
text-align: center; text-align: center;
img{
width: 100%;
}
> div { > div {
width: 80%; width: 80%;
@ -537,59 +545,27 @@
.home_page{ .home_page{
.HeroSection { .HeroSection {
display: flex; &::after{
padding: 10% 6%; scale: -1;
position: relative; right: auto;
width: 100%; left: 0 !important;
z-index: 99; }
min-height: 100vh;
&::after {
position: absolute;
content: "";
right: auto;
scale: -1;
left: 0;
top: 0;
background: url("../../../public/Home/HeroShape.svg");
background-size: cover;
background-repeat: no-repeat;
width: 40%;
height: 100%;
z-index: -1;
}
> div { > div {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 45%; width: 60%;
gap: 20px;
h1 { h1 {
font-size: 4vw; font-size: 6vw;
font-weight: bold; font-weight: bold;
} }
> div { > div {
display: flex; display: flex;
gap: 30px; gap: 30px
h3 {
font-weight: bold;
}
button {
padding-inline: 10%;
border-radius: 2vw;
}
} }
} }
> span {
img {
width: 25vw;
}
}
} }
} }

View File

@ -21,7 +21,18 @@
.Product_left { .Product_left {
display: flex; display: flex;
width: 45%; width: 45%;
> span { .fav_icon{
svg{
font-size: 25px;
transition: ease-in-out .3s;
margin-inline: 5px;
&:hover{
color: var(--primary);
}
}
}
.Product_left_container {
width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 20px; gap: 20px;
@ -33,51 +44,108 @@
display: flex; display: flex;
gap: 20px; gap: 20px;
overflow-x: scroll; overflow-x: scroll;
// max-width: 40vw;
&::-webkit-scrollbar { &::-webkit-scrollbar {
display: none; display: none;
} }
span {
padding: 10px 15px;
border: 2px solid rgba(128, 128, 128, 0.1);
width: 100%;
> img {
width: 100%;
cursor: pointer;
}
}
} }
} }
} }
.Product_info {
.Product_Right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 20px; gap: 5px;
align-items: flex-start; align-items: flex-start;
padding-top: 2%;
h1 { h1 {
font-size: 4vw; font-size: 4vw;
} }
> div { > div {
width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 20px; gap: 10px;
> span { > span {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
gap: 20px; gap: 20px;
width: 80%; width: 100%;
padding: 10px 15px 0px 15px;
&:nth-child(odd){
background: var(--whiteOpacity) !important;
}
h6 { h6 {
color: gray; color: var(--whiteGray);
position: relative; position: relative;
min-width: 80px; width: 50%;
font-size: 12px;
}
h5{
height: 100%;
color: var(--text);
font-size: 12px;
} }
} }
} }
} }
}
.product_images_swiper{
width: 100%;
.swiper-button-prev:after, .swiper-button-next:after{
color: var(--text);
font-size: 25px;
background: #fff;
padding: 4px;
border-radius: 4px;
}
.swiper-backface-hidden .swiper-slide{
padding-inline: 20px;
min-width: 50px !important;
}
> span{
width: 50px;
}
.product_multi_image{
width: 50px !important;
}
}
}
.Product_Right{
width: 50%;
}
.product_tab{
width: 100%;
}
.product_description{
width: 100%;
p{
padding-inline: 15px;
width: 95%;
background: var(--whiteOpacity);
}
}
.product_additional_info{
> span {
display: flex;
align-items: flex-start;
gap: 20px;
width: 100%;
padding: 10px 15px 0px 15px;
&:nth-child(even){
background: var(--whiteOpacity) !important;
}
h6 {
color: var(--text);
position: relative;
width: 50%;
font-size: 10px;
}
h5{
color: var(--text);
font-size: 10px;
}
}
}
.Products { .Products {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -89,23 +157,25 @@
> header { > header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
h1{
font-size: 20px;
}
} }
.ProductCards { .ProductCards {
max-width: 90vw; max-width: 90vw;
margin-inline: auto; margin-inline: auto;
display: flex; display: flex;
// gap: 40px;
// overflow-x: scroll;
// &::-webkit-scrollbar {
// display: none;
// }
} }
} }
@media screen and (max-width:850px) {
@media screen and (max-width:700px) { .ant-tabs .ant-tabs-tab-btn{
font-size: 14px !important;
}
.ant-tabs >.ant-tabs-nav .ant-tabs-nav-wrap,.ant-tabs >div>.ant-tabs-nav .ant-tabs-nav-wrap{
justify-content: center !important;align-items: center !important;
}
.Product { .Product {
display: flex; display: flex;
min-height: 100vh; min-height: 100vh;
@ -121,24 +191,20 @@
gap: 10%; gap: 10%;
} }
.Product_left { .Product_left {
display: flex; display: flex;justify-content: center;align-items: center;
width: 90%; width: 100%;
margin-inline: auto; margin-inline: auto;
> span { > span {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 20px; gap: 20px;
> img { > img {
width: 60%; width: 50%;
margin-inline: auto; margin-inline: auto;
} }
.gallery_product { .gallery_product {
display: flex; display: flex;
gap: 20px; gap: 20px;
// overflow-x: scroll;
// &::-webkit-scrollbar {
// display: none;
// }
span { span {
padding: 10px 10px; padding: 10px 10px;
border: 2px solid rgba(128, 128, 128, 0.1); border: 2px solid rgba(128, 128, 128, 0.1);
@ -181,3 +247,9 @@
} }
} }
} }
@media screen and (max-width:450px) {
.ant-tabs >.ant-tabs-nav .ant-tabs-nav-wrap,.ant-tabs >div>.ant-tabs-nav .ant-tabs-nav-wrap{
justify-content: flex-start !important;align-items: flex-start !important;
}
}

View File

@ -26,7 +26,7 @@
width: 100%; width: 100%;
.ant-tabs .ant-tabs-tab{ .ant-tabs .ant-tabs-tab{
justify-content: start;align-items: start; justify-content: start;align-items: start;
font-size: 24px; font-size: 20px;
width: 100% !important; width: 100% !important;
color: #717171; color: #717171;
@ -36,7 +36,7 @@
justify-content: space-around !important; justify-content: space-around !important;
margin-bottom: 50px; margin-bottom: 50px;
.left{ .left{
width: 36%;height: 500px !important; width: 36%;height: 400px !important;
.social_info{ .social_info{
.Single_info{ .Single_info{
span{ span{
@ -80,7 +80,7 @@
} }
.personl_data_form_button{ .personl_data_form_button{
width: 20% !important; width: 20% !important;
padding: 12px 0 !important; padding: 10px 0 !important;
background: var(--primary); background: var(--primary);
color: var(--white); color: var(--white);
font-size: 20px; font-size: 20px;
@ -101,11 +101,11 @@
} }
} }
.personl_data_form_button{ .personl_data_form_button{
width: 20% !important; width: 16% !important;
padding: 12px 0 !important; padding: 5px 0 !important;
background: var(--primary); background: var(--primary);
color: var(--white); color: var(--white);
font-size: 20px; font-size: 16px;
border: none; border: none;
&:hover{ &:hover{
background: var(--DarkPrimary); background: var(--DarkPrimary);
@ -241,12 +241,6 @@
display: flex;flex-direction: row-reverse;align-items: center; display: flex;flex-direction: row-reverse;align-items: center;
} }
} }
.personl_data_form{
span{
// display: flex;align-items: end;justify-content: end;
// text-align: end;
}
}
} }
@media screen and (max-width:1100px) { @media screen and (max-width:1100px) {

View File

@ -5,20 +5,20 @@
align-items: center; align-items: center;
border-radius: 7px; border-radius: 7px;
.ant-card-body { .ant-card-body {
@include Flex; display: flex;justify-content: space-between;align-items: center;
padding: 10px 5px; padding: 10px 5px;
width: 100%; width: 100%;
box-shadow: 10px 10px 20px 15px rgba(0, 0, 0, 0.1); box-shadow: 10px 10px 20px 15px rgba(0, 0, 0, 0.1);
border-radius: 7px; border-radius: 7px;
} }
.Card_Img { .Card_Img {
width: 40%; width: 20%;
img { img {
width: 40%; width: 80%;
} }
} }
.Card_Info { .Card_Info {
width: 50%; width: 70%;
h5 { h5 {
font-size: 14px; font-size: 14px;
text-wrap: nowrap; text-wrap: nowrap;
@ -72,7 +72,7 @@
@media screen and (max-width: 650px) { @media screen and (max-width: 650px) {
.CardItem { .CardItem {
.ant-card-body { .ant-card-body {
@include Flex; // @include Flex;
padding: 10px 0px; padding: 10px 0px;
width: 100%; width: 100%;
box-shadow: 10px 10px 20px 15px rgba(0, 0, 0, 0.1); box-shadow: 10px 10px 20px 15px rgba(0, 0, 0, 0.1);

View File

@ -15,3 +15,14 @@
}.ant-collapse>.ant-collapse-item:last-child,.ant-collapse>.ant-collapse-item:last-child>.ant-collapse-header{ }.ant-collapse>.ant-collapse-item:last-child,.ant-collapse>.ant-collapse-item:last-child>.ant-collapse-header{
border-radius: 0; border-radius: 0;
} }
.setting_container .ant-tabs > .ant-tabs-nav .ant-tabs-nav-list, .setting_container .ant-tabs > div > .ant-tabs-nav .ant-tabs-nav-list{
overflow-x: auto ;
@include Scrollbar;
}
.ant-tabs-tab.ant-tabs-tab-active.ant-tabs-tab-disabled{
}

View File

@ -34,6 +34,7 @@ function useGetQuery(
return response?.data ?? []; return response?.data ?? [];
}, },
options, options,
); );
} }

0
src/index.tsx Normal file → Executable file
View File

8
src/lib/ReactQueryProvider.tsx Normal file → Executable file
View File

@ -2,7 +2,13 @@ import React from "react";
import { QueryClient, QueryClientProvider } from "react-query"; import { QueryClient, QueryClientProvider } from "react-query";
function QueryProvider({ children }: any) { function QueryProvider({ children }: any) {
const queryClient = new QueryClient(); const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus:false,
},
},
});
return ( return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider> <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>

14
src/translate/ar.json Normal file → Executable file
View File

@ -380,13 +380,25 @@
"Verify": "تحقق", "Verify": "تحقق",
"Create Your Account": "أنشئ حسابك", "Create Your Account": "أنشئ حسابك",
"Log In To DM": "تسجيل الدخول إلى DM", "Log In To DM": "تسجيل الدخول إلى DM",
"Login / Sign Up": "تسجيل الدخول / الاشتراك",
"Verify Your Account": "تحقق من حسابك", "Verify Your Account": "تحقق من حسابك",
"E-mail": "البريد الإلكتروني", "E-mail": "البريد الإلكتروني",
"Full Name": "الاسم الكامل", "Full Name": "الاسم الكامل",
"verify code": "تحقق من الرمز", "verify code": "تحقق من الرمز",
"verify": "تحقق", "verify": "تحقق",
"sub_categories": "الفئات الفرعية", "sub_categories": "الفئات الفرعية",
"Clear_All": "مسح الكل" "Clear_All": "مسح الكل",
"Track, return or purchase items":"تتبع أو إرجاع أو شراء العناصر",
"Order History":"تاريخ الطلب",
"Please try using other keywords to find the product name":"يرجى محاولة استخدام كلمات رئيسية أخرى للعثور على اسم المنتج",
"There are no suitable products":"لا توجد منتجات مناسبة",
"product_info":"معلومات المنتج",
"additional information":"معلومات إضافية",
"description":"الوصف",
"Info":"معلومات",
"Additional Info":"معلومات إضافية",
"Product info is empty":"معلومات المنتج فارغة",
"":""
} }

View File

@ -367,10 +367,23 @@
"Create Your Account": "创建您的账户", "Create Your Account": "创建您的账户",
"Log In To DM": "登录到 DM", "Log In To DM": "登录到 DM",
"Verify Your Account": "验证您的账户", "Verify Your Account": "验证您的账户",
"Login / Sign Up": "登录 / 注册",
"E-mail": "电子邮件", "E-mail": "电子邮件",
"Full Name": "全名", "Full Name": "全名",
"verify code": "验证代码", "verify code": "验证代码",
"verify": "验证", "verify": "验证",
"sub_categories": "子类别", "sub_categories": "子类别",
"Clear_All": "清除所有" "Clear_All": "清除所有",
"Track, return or purchase items":"跟踪、退货或购买物品",
"Order History":"订单历史",
"Please try using other keywords to find the product name":"请尝试使用其他关键字来查找产品名称",
"There are no suitable products":"没有合适的产品",
"product_info":"产品信息",
"additional information":"附加信息",
"description":"描述",
"Info":"信息",
"Additional Info":"附加信息",
"Product info is empty":"产品信息为空",
"":""
} }

16
src/translate/en.json Normal file → Executable file
View File

@ -371,8 +371,7 @@
"Security settings":"Security settings", "Security settings":"Security settings",
"See your favorites list here":"See your favorites list here", "See your favorites list here":"See your favorites list here",
"Change Password":"Change Password", "Change Password":"Change Password",
"Quite Comfort 35 wireless headphones II":"Quite Comfort 35 wireless headphones II", "Quite Comfort 35 wireless headphones II":"QuiteComfort 35 wireless headphones II",
"Verify":"Verify", "Verify":"Verify",
"Create Your Account":"Create Your Account", "Create Your Account":"Create Your Account",
@ -384,7 +383,18 @@
"verify":"Verify", "verify":"Verify",
"Login / Sign Up":"Login / Sign Up", "Login / Sign Up":"Login / Sign Up",
"sub_categories": "sub categories", "sub_categories": "sub categories",
"Clear_All": "Clear All" "Clear_All": "Clear All",
"Track, return or purchase items":"Track, return or purchase items",
"Order History":"Order History",
"Please try using other keywords to find the product name":"Please try using other keywords to find the product name",
"There are no suitable products":"There are no suitable products",
"product_info":"Product info",
"additional information":"Additional information",
"description":"Description",
"Info":"Info",
"Additional Info":"Additional Info",
"Product info is empty":"Product info is empty"
} }

View File

@ -77,7 +77,6 @@ export const requestPermissionWithLogout = async (logout: () => void): Promise<v
localStorage.setItem(KEY_NOTIFICATION_PERMISSION, 'yes'); localStorage.setItem(KEY_NOTIFICATION_PERMISSION, 'yes');
localStorage.setItem(FCM_TOKEN_KEY, currentToken || ''); localStorage.setItem(FCM_TOKEN_KEY, currentToken || '');
toast.success("Notifications enabled successfully."); toast.success("Notifications enabled successfully.");
console.log('FCM Token:', currentToken);
logout(); logout();
} else { } else {
localStorage.setItem(KEY_NOTIFICATION_PERMISSION, 'no'); localStorage.setItem(KEY_NOTIFICATION_PERMISSION, 'no');

0
tsconfig.json Normal file → Executable file
View File