Skip to content

Commit a4aa9ca

Browse files
committed
refactor: Correct bad import
1 parent 9b48443 commit a4aa9ca

File tree

8 files changed

+93
-166
lines changed

8 files changed

+93
-166
lines changed

src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { RouterProvider } from 'react-router-dom'
44
import { Toaster } from '@/components/ui/toaster';
55
import { ThemeProvider } from '@/hooks/use-theme';
66
import ScrollProgressBar from '@/components/custom/utils/ScrollProgress'
7+
import OfflineAlert from '@/components/custom/utils/OfflineAlert';
78

89

910
const App: React.FC = () => {
@@ -13,6 +14,7 @@ const App: React.FC = () => {
1314
<RouterProvider router={Router} />
1415

1516
<Toaster />
17+
<OfflineAlert />
1618
</ThemeProvider>
1719
)
1820
}

src/api/api.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
export const DEFAULT_URL = 'http://localhost/back-end:4000';
2-
export const TEST_URL = 'https://670fc6caa85f4164ef2bdfb1.mockapi.io/';
1+
export const DEFAULT_URL = 'https://670fc6caa85f4164ef2bdfb1.mockapi.io/api/v1';

src/components/custom/SomeProducts.tsx

Lines changed: 24 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
import React from 'react'
22
import CardProduct from './cards/CardProduct';
33
import CTA2 from './utils/CTA2';
4+
import { useFetch } from '@/hooks/use-fetch';
5+
import { DEFAULT_URL } from '@/api/api';
6+
import type { IProduct } from '@/interface/interface';
47

58
const SomeProducts: React.FC = () => {
6-
// const [isActive, setIsActive] = React.useState<boolean>(false);
9+
const { data, loading, error } = useFetch<IProduct[]>(`${DEFAULT_URL}/products`);
10+
11+
const products = data;
12+
// const products = data?.length(8);
713

814
return (
915
<section className="py-8 md:py-10 lg:py-14 space-y-4 md:space-y-6 lg:space-y-8">
@@ -26,106 +32,23 @@ const SomeProducts: React.FC = () => {
2632
{/* Products */}
2733
<div className="flex items-center flex-col gap-10">
2834
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 md:gap-3 lg:gap-4 place-items-center md:place-items-stretch">
29-
<CardProduct
30-
id="product5"
31-
slug='iphone-14'
32-
picture={'src/assets/images/iphone14.svg'}
33-
name="Apple iPhone 14 Pro Max"
34-
caracteristiques="128GB Deep Purple (MQ9T3RX/A)"
35-
price={900}
36-
isWhiteListe={false}
37-
isPromo={true}
38-
promoPercent={20}
39-
statut="New"
40-
/>
41-
<CardProduct
42-
id="product5"
43-
slug='iphone-14'
44-
picture={'src/assets/images/iphone14.svg'}
45-
name="Apple iPhone 14 Pro Max"
46-
caracteristiques="128GB Deep Purple (MQ9T3RX/A)"
47-
price={900}
48-
isWhiteListe={false}
49-
isPromo={false}
50-
promoPercent={20}
51-
statut="New"
52-
/>
53-
54-
<CardProduct
55-
id="product5"
56-
slug='iphone-14'
57-
picture={'src/assets/images/iphone14.svg'}
58-
name="Apple iPhone 14 Pro Max"
59-
caracteristiques="128GB Deep Purple (MQ9T3RX/A)"
60-
price={900}
61-
isWhiteListe={false}
62-
isPromo={true}
63-
promoPercent={20}
64-
statut="New"
65-
/>
66-
67-
<CardProduct
68-
id="product5"
69-
slug='iphone-14'
70-
picture={'src/assets/images/iphone14.svg'}
71-
name="Apple iPhone 14 Pro Max"
72-
price={900}
73-
isWhiteListe={false}
74-
isPromo={false}
75-
promoPercent={20}
76-
statut="New"
77-
/>
78-
79-
<CardProduct
80-
id="product5"
81-
slug='iphone-14'
82-
picture={'src/assets/images/iphone14.svg'}
83-
name="Apple iPhone 14 Pro Max"
84-
price={900}
85-
isWhiteListe={false}
86-
isPromo={true}
87-
promoPercent={20}
88-
statut="New"
89-
/>
90-
91-
<CardProduct
92-
id="product5"
93-
slug='iphone-14'
94-
picture={'src/assets/images/iphone14.svg'}
95-
name="Apple iPhone 14 Pro Max"
96-
caracteristiques="128GB Deep Purple (MQ9T3RX/A)"
97-
price={900}
98-
isWhiteListe={false}
99-
isPromo={true}
100-
promoPercent={20}
101-
statut="New"
102-
/>
103-
104-
<CardProduct
105-
id="product5"
106-
slug='iphone-14'
107-
picture={'src/assets/images/iphone14.svg'}
108-
name="Apple iPhone 14 Pro Max"
109-
caracteristiques="128GB Deep Purple (MQ9T3RX/A)"
110-
price={900}
111-
isWhiteListe={false}
112-
isPromo={true}
113-
promoPercent={20}
114-
statut="New"
115-
/>
116-
117-
<CardProduct
118-
id="product5"
119-
slug='iphone-14'
120-
picture={'src/assets/images/iphone14.svg'}
121-
name="Apple iPhone 14 Pro Max"
122-
caracteristiques="128GB Deep Purple (MQ9T3RX/A)"
123-
price={900}
124-
isWhiteListe={false}
125-
isPromo={true}
126-
promoPercent={20}
127-
statut="New"
128-
/>
35+
{
36+
products && products.slice(0, 8).map((product) => (
37+
<CardProduct
38+
key={product.id}
39+
id={product.id}
40+
slug={product.slug}
41+
picture={product.picture}
42+
name={product.name}
43+
caracteristiques={product.caracteristiques}
44+
price={product.price}
45+
isWhiteListe={product.isWhiteListe}
46+
isPromo={product.isPromo}
47+
promoPercent={product.promoPercent}
48+
statut={product.statut}
49+
/>
50+
))
51+
}
12952
</div>
13053

13154
<CTA2 name="More Products" url='/products' />

src/components/custom/cards/CardProduct.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const CardProduct: React.FC<IProduct> = (props) => {
5050
{/* Picture part */}
5151
<Link
5252
to={`/products/${props.id}`}
53-
className="rounded-sm flex items-center justify-center min-h-32 max-h-60 md:min-h-40 min-w-[80%] text-sm text-destructive"
53+
className="rounded-sm overflow-hidden flex items-center justify-center min-h-32 max-h-60 md:min-h-40 min-w-[80%] text-sm text-destructive"
5454
>
5555
<img
5656
src={props.picture}
Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
1+
import React, { lazy, Suspense } from 'react';
12
import LoaderPage from '@/layouts/loaders/LoaderPage';
2-
import React, { lazy, Suspense } from 'react'
3-
// import type { ReactNode } from 'react'
43

5-
export interface ILazyCompoment {
6-
componentPath: string;
4+
interface DynamicPageLoaderProps {
5+
pageKey: string; // Key representing the page to load dynamically
76
}
87

9-
const LazyComponent: React.FC<ILazyCompoment> = ({ componentPath }) => {
10-
const Component = lazy(() =>
11-
import(`${componentPath}`)
12-
.then((module) => {
13-
if (!module.default) {
14-
throw new Error("Imported compoment don't have a defaut module !");
15-
}
16-
return module;
17-
})
18-
.catch((e) => {
19-
throw new Error("\nFailed to load compoments to path " +componentPath + " \nError: "+ e)
20-
})
21-
);
8+
// Dynamically import pages using import.meta.glob
9+
const pages = import.meta.glob('/src/pages/**/*.tsx');
10+
11+
const DynamicPageLoader: React.FC<DynamicPageLoaderProps> = ({ pageKey }) => {
12+
// Lazy load the page based on the provided pageKey
13+
// @ts-ignore-next-line
14+
const PageComponent = lazy(() => {
15+
const importPage = pages[`/src/pages/${pageKey}.tsx`];
16+
if (!importPage) {
17+
return Promise.reject(new Error(`Page not found: ${pageKey}`));
18+
}
19+
return importPage();
20+
});
2221

2322
return (
24-
<>
25-
<Suspense fallback={<LoaderPage />}>
26-
< Component />
27-
</Suspense>
28-
</>
29-
)
30-
}
23+
<Suspense fallback={<LoaderPage />}>
24+
<PageComponent />
25+
</Suspense>
26+
);
27+
};
3128

32-
export default LazyComponent
29+
export default DynamicPageLoader;
Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,55 @@
1-
// ToastAlert.tsx
2-
import React, { useState, useEffect } from 'react';
3-
import * as Toast from '@radix-ui/react-toast';
4-
import { cn } from "@/lib/utils"; // Utilitaire pour gérer les classes conditionnelles (ShadCN).
1+
import { useState, useEffect } from 'react';
2+
import { useToast } from '@/hooks/use-toast';
3+
import { ToastAction } from '@/components/ui/toast';
54

6-
const ToastAlert: React.FC = () => {
7-
const [isOnline, setIsOnline] = useState(navigator.onLine);
8-
const [open, setOpen] = useState(!isOnline);
5+
const OfflineAlert = () => {
6+
const { toast } = useToast();
7+
const [isOnline, setIsOnline] = useState<boolean>(navigator.onLine);
8+
const [hasNotified, setHasNotified] = useState<boolean>(false);
99

1010
useEffect(() => {
11+
// Gestion de l'événement "en ligne"
1112
const handleOnline = () => {
1213
setIsOnline(true);
13-
setOpen(false);
14+
setHasNotified(false);
15+
toast({
16+
duration: 2000,
17+
variant: "default",
18+
title: "Back Online!",
19+
description: "You are reconnected to the internet.",
20+
});
1421
};
1522

23+
// Gestion de l'événement "hors ligne"
1624
const handleOffline = () => {
1725
setIsOnline(false);
18-
setOpen(true);
26+
if (!hasNotified) {
27+
toast({
28+
duration: 4000,
29+
variant: "destructive",
30+
title: "No Internet Connection",
31+
description:
32+
"You are currently offline. Check your connection to continue.",
33+
action: (
34+
<ToastAction altText="Retry">Retry</ToastAction>
35+
),
36+
});
37+
setHasNotified(true); // Empêche l'affichage répété de l'alerte
38+
}
1939
};
2040

41+
// Ajout des gestionnaires d'événements
2142
window.addEventListener('online', handleOnline);
2243
window.addEventListener('offline', handleOffline);
2344

45+
// Nettoyage des gestionnaires d'événements
2446
return () => {
2547
window.removeEventListener('online', handleOnline);
2648
window.removeEventListener('offline', handleOffline);
2749
};
28-
}, []);
50+
}, [toast, hasNotified, isOnline]);
2951

30-
return (
31-
<Toast.Provider>
32-
<Toast.Root
33-
open={open}
34-
onOpenChange={setOpen}
35-
className={cn(
36-
"fixed bottom-4 left-4 z-50 w-72 rounded-lg bg-red-500 p-4 text-white shadow-lg",
37-
"data-[state=open]:animate-slide-in data-[state=closed]:animate-slide-out"
38-
)}
39-
>
40-
<Toast.Title className="font-bold text-lg">
41-
Pas de connexion Internet
42-
</Toast.Title>
43-
<Toast.Description className="mt-2 text-sm">
44-
Vous êtes actuellement hors ligne. Vérifiez votre connexion pour continuer.
45-
</Toast.Description>
46-
</Toast.Root>
47-
<Toast.Viewport className="fixed bottom-4 left-4 z-50" />
48-
</Toast.Provider>
49-
);
52+
return null;
5053
};
5154

52-
export default ToastAlert;
55+
export default OfflineAlert;

src/core/mocks/mock-products.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// export const Products = [];

src/routes/router.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import Navbar from '@/layouts/navbar/Navbar'
33
import Footer from '@/layouts/footer/Footer'
44
import PageError from '@/pages/error/PageError'
55
import Blog from '@/pages/blog/Blog'
6-
import Products from '@/pages/products/Products'
7-
import ProductDetail from '@/pages/products/ProductDetail'
6+
// import Products from '@/pages/products/Products'
7+
// import ProductDetail from '@/pages/products/ProductDetail'
88
import ProductCategory from '@/pages/products/ProductCategory'
99
import Account from '@/pages/account/Account'
1010
import Order from '@/pages/order/Order'
@@ -24,7 +24,9 @@ import settingsRoute from './routes-config/settingRoutes'
2424
import authRoutes from './routes-config/authRoutes'
2525
import ScrollToTop from '@/components/custom/utils/ScrollToTop'
2626
import PrivateRoute from '@/components/custom/utils/PrivateRoute'
27-
import LazyComponent from '@/components/custom/utils/LazyCompoment'
27+
import DynamicPageLoader from '@/components/custom/utils/LazyCompoment'
28+
29+
2830

2931
const userNameSlug = 'barthez';
3032

@@ -60,7 +62,7 @@ const Router = createBrowserRouter([
6062
children: [
6163
{
6264
path: '/',
63-
element: <LazyComponent componentPath='/src/pages/home/Home'/>
65+
element: <DynamicPageLoader pageKey="home/Home" />
6466
},
6567

6668
{
@@ -86,12 +88,12 @@ const Router = createBrowserRouter([
8688
children: [
8789
{
8890
path: '',
89-
element: <Products />
91+
element: <DynamicPageLoader pageKey="products/Products" />
9092
},
9193

9294
{
9395
path: ':productID',
94-
element: <ProductDetail />
96+
element: <DynamicPageLoader pageKey="products/ProductDetail" />
9597
},
9698

9799
{

0 commit comments

Comments
 (0)