Welcome to the World of Mozimo Magic
diff --git a/src/app/layout.tsx b/src/app/(static)/layout.tsx
similarity index 93%
rename from src/app/layout.tsx
rename to src/app/(static)/layout.tsx
index b2a077c..e0ce217 100644
--- a/src/app/layout.tsx
+++ b/src/app/(static)/layout.tsx
@@ -1,4 +1,4 @@
-import './globals.css';
+import '../globals.css';
// import './globalicons.css';
import { ReactNode } from 'react';
diff --git a/src/app/page.tsx b/src/app/(static)/page.tsx
similarity index 100%
rename from src/app/page.tsx
rename to src/app/(static)/page.tsx
diff --git a/src/app/privacy-policy/page.tsx b/src/app/(static)/privacy-policy/page.tsx
similarity index 100%
rename from src/app/privacy-policy/page.tsx
rename to src/app/(static)/privacy-policy/page.tsx
diff --git a/src/app/terms/page.tsx b/src/app/(static)/terms/page.tsx
similarity index 100%
rename from src/app/terms/page.tsx
rename to src/app/(static)/terms/page.tsx
diff --git a/src/app/(storefront)/cart/page.tsx.exclude b/src/app/(storefront)/cart/page.tsx.exclude
new file mode 100644
index 0000000..a3d4985
--- /dev/null
+++ b/src/app/(storefront)/cart/page.tsx.exclude
@@ -0,0 +1,87 @@
+'use client';
+
+import { useCart, useUpdateLineItem, useDeleteLineItem } from 'medusa-react';
+import { useRouter } from 'next/navigation';
+
+export default function CartPage() {
+ const { cart } = useCart();
+ const router = useRouter();
+
+ // Ensure cart is loaded
+ if (!cart?.id) {
+ return
Loading cart...
;
+ }
+
+ // Hook for updating a cart line item
+ const {
+ mutate: updateLineItem,
+ isLoading: isUpdating,
+ error: updateError,
+ } = useUpdateLineItem(cart.id);
+ // Hook for deleting a cart line item
+ const {
+ mutate: deleteLineItem,
+ isLoading: isDeleting,
+ error: deleteError,
+ } = useDeleteLineItem(cart?.id);
+
+ if (!cart) return
Loading cart...
;
+
+ const handleUpdateItem = (lineId: string, quantity: number) => {
+ updateLineItem(
+ { lineId, quantity },
+ {
+ onSuccess: () => {
+ // Optionally refetch cart or show a success message
+ },
+ },
+ );
+ };
+
+ const handleRemoveItem = (lineId: string) => {
+ deleteLineItem(
+ { lineId },
+ {
+ onSuccess: () => {
+ // Optionally refetch cart or show a success message
+ },
+ },
+ );
+ };
+
+ const proceedToCheckout = () => {
+ router.push('/checkout');
+ };
+
+ return (
+
+
Your Cart
+ {cart.items?.length ? (
+ cart.items.map((item) => (
+
+
{item.title}
+
Quantity: {item.quantity}
+
+
+ {updateError &&
Error updating item: {updateError.message}
}
+ {deleteError &&
Error removing item: {deleteError.message}
}
+
+ ))
+ ) : (
+
Your cart is empty.
+ )}
+
Total: {cart.total ? `$${(cart.total / 100).toFixed(2)}` : '$0.00'}
+
+
+ );
+}
diff --git a/src/app/(storefront)/layout.tsx b/src/app/(storefront)/layout.tsx
new file mode 100644
index 0000000..ea4dddf
--- /dev/null
+++ b/src/app/(storefront)/layout.tsx
@@ -0,0 +1,21 @@
+import '../globals.css';
+import { ReactNode } from 'react';
+import { Providers } from '../providers';
+import { Footer } from '@/components/footer';
+import { Navbar } from '@/components/navbar';
+
+interface RootLayoutProps {
+ children: ReactNode;
+}
+
+export default function RootLayout({ children }: RootLayoutProps) {
+ return (
+
+
+
+
{children}
+
+
+
+ );
+}
diff --git a/src/app/(storefront)/products/[handle]/ProductDetails.tsx b/src/app/(storefront)/products/[handle]/ProductDetails.tsx
new file mode 100644
index 0000000..383c2e3
--- /dev/null
+++ b/src/app/(storefront)/products/[handle]/ProductDetails.tsx
@@ -0,0 +1,79 @@
+'use client';
+
+import { FC } from 'react';
+import { useEffect, useState } from 'react';
+import { getProductByHandle } from '@/lib/product-by-handle';
+import { PricedProduct } from '@medusajs/medusa/dist/types/pricing';
+
+interface ProductDetailsProps {
+ handle: string;
+}
+
+const ProductDetails: FC
= ({ handle }) => {
+ const [product, setProduct] = useState(null);
+ const [isLoading, setIsLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ const fetchProduct = async () => {
+ try {
+ const { product } = await getProductByHandle(handle);
+ console.log(product);
+ if (!product) {
+ setProduct(null);
+ } else {
+ setProduct(product);
+ }
+ } catch (err) {
+ setError(err);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ fetchProduct();
+ }, [handle]);
+
+ if (isLoading) {
+ return Loading...
;
+ }
+
+ if (error) {
+ return Something went wrong: {error.message}
;
+ }
+
+ if (!product) {
+ return Product not found.
;
+ }
+
+ return (
+
+
{product.title}
+
+ {/* Product Images */}
+
+ {product?.images?.length > 0 && (
+
+ )}
+
+
+ {/* Product Info */}
+
+
+ Price: ${product.variants[0].prices[0].amount / 100}
+
+
{product.description}
+
+
+
+
+ );
+};
+
+export default ProductDetails;
diff --git a/src/app/(storefront)/products/[handle]/page.tsx b/src/app/(storefront)/products/[handle]/page.tsx
new file mode 100644
index 0000000..a2f945c
--- /dev/null
+++ b/src/app/(storefront)/products/[handle]/page.tsx
@@ -0,0 +1,37 @@
+import { FC } from 'react';
+import { getProductsList } from '@/lib/product';
+import ProductDetails from './ProductDetails';
+
+interface ProductPageProps {
+ params: {
+ handle: string;
+ };
+}
+
+export async function generateStaticParams() {
+ // Fetch the list of products
+ const products = await getProductsList({}).then(
+ ({ response }) => response.products,
+ );
+
+ if (!products) {
+ return [];
+ }
+
+ // Generate static params based on product handles
+ const staticParams = products.map((product) => ({
+ handle: product.handle,
+ }));
+ return staticParams;
+}
+
+const ProductPage: FC = ({ params }) => {
+ const { handle } = params; // Extract the handle from the params
+
+ return (
+ // Render the client component and pass necessary props
+
+ );
+};
+
+export default ProductPage;
diff --git a/src/app/(storefront)/products/page.tsx b/src/app/(storefront)/products/page.tsx
new file mode 100644
index 0000000..1b94bbf
--- /dev/null
+++ b/src/app/(storefront)/products/page.tsx
@@ -0,0 +1,40 @@
+'use client';
+
+import { useProducts } from 'medusa-react';
+import Image from 'next/image';
+import Link from 'next/link';
+
+export default function ProductsPage() {
+ const { products, isLoading, error } = useProducts();
+
+ if (isLoading) {
+ return Loading...
;
+ }
+ if (error) return Error: {error.message}
;
+
+ return (
+
+
Handbags Collection
+
+ {products?.map((product) => (
+
+
+
+
{product.title}
+
{product.description}
+
+ ${product.variants[0]?.prices[0].amount / 100}
+
+
+
+ ))}
+
+
+ );
+}
diff --git a/src/app/providers.tsx b/src/app/providers.tsx
new file mode 100644
index 0000000..ed075bc
--- /dev/null
+++ b/src/app/providers.tsx
@@ -0,0 +1,23 @@
+// src/app/providers.tsx
+'use client';
+
+import { ReactNode, useState } from 'react';
+import { MedusaProvider, CartProvider } from 'medusa-react';
+import { QueryClient } from '@tanstack/react-query';
+
+interface ProvidersProps {
+ children: ReactNode;
+}
+
+export function Providers({ children }: ProvidersProps) {
+ const [queryClient] = useState(() => new QueryClient());
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/components/footer.tsx b/src/components/footer.tsx
index 465a581..77eedb5 100644
--- a/src/components/footer.tsx
+++ b/src/components/footer.tsx
@@ -7,19 +7,14 @@ import {
FaLinkedin,
} from 'react-icons/fa';
import Image from 'next/image';
+import logoPic from '/public/images/logo-puce-red.svg';
export function Footer() {
return (