From cd0d92c4b7d15ab84d028bd5148ad9408df01af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anouk=20R=C3=ADmola?= <77553677+AnoukRImola@users.noreply.github.com> Date: Mon, 23 Dec 2024 21:27:07 -0600 Subject: [PATCH] feat: implement shadcn dark mode (#80) * feat: implement shadcn dark mode * feat: implement shadcn dark mode and merge upstream changes --- frontend/app/components/header/Header.tsx | 207 +- .../components/header/subheader/SubHeader.tsx | 41 +- .../products/ProductDetailModal.tsx | 38 +- .../components/providers/theme-provider.tsx | 9 + .../app/components/ui/add-product-modal.tsx | 168 +- .../components/ui/breadcrumb-navigation.tsx | 2 +- .../ui/delivery-location-button.tsx | 63 +- frontend/app/components/ui/input.tsx | 36 +- frontend/app/components/ui/label.tsx | 36 +- frontend/app/components/ui/select.tsx | 264 +- frontend/app/components/ui/textarea.tsx | 34 +- frontend/app/components/ui/theme-toggle.tsx | 39 + frontend/app/layout.tsx | 77 +- frontend/app/marketplace/page.tsx | 4 +- frontend/app/products/[productId]/page.tsx | 179 +- frontend/app/products/page.tsx | 137 +- frontend/package-lock.json | 9223 +---------------- frontend/package.json | 78 +- 18 files changed, 1172 insertions(+), 9463 deletions(-) create mode 100644 frontend/app/components/providers/theme-provider.tsx create mode 100644 frontend/app/components/ui/theme-toggle.tsx diff --git a/frontend/app/components/header/Header.tsx b/frontend/app/components/header/Header.tsx index 52730d2..1d5de3d 100644 --- a/frontend/app/components/header/Header.tsx +++ b/frontend/app/components/header/Header.tsx @@ -1,135 +1,96 @@ "use client"; -import Link from "next/link"; -import { useEffect, useState } from "react"; import { SafeSwapLogo } from "@/app/components/ui/SafeSwapLogo"; import { Button } from "@/app/components/ui/button"; -import { Input } from "@/app/components/ui/input"; +import DeliveryLocationButton from "@/app/components/ui/delivery-location-button"; import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, } from "@/app/components/ui/dropdown-menu"; - -import DeliveryLocationButton from "@/app/components/ui/delivery-location-button"; -import { MapPin } from 'lucide-react'; - +import { Input } from "@/app/components/ui/input"; +import { ThemeToggle } from "@/app/components/ui/theme-toggle"; import { - Search, - ShoppingCart, - Wallet, - User, - Settings, - List, - History, + History, + List, + Search, + Settings, + ShoppingCart, + User, + Wallet, } from "lucide-react"; -import { IoMoon, IoSunny } from "react-icons/io5"; -import SubHeader from "./subheader/SubHeader"; - +import Link from "next/link"; +import { useState } from "react"; export default function Header() { - const [searchTerm, setSearchTerm] = useState(""); - const [dark, setDark] = useState(false); - - useEffect(() => { - const darkMode = localStorage.getItem("darkMode"); - if (darkMode) { - setDark(JSON.parse(darkMode)); - } - }, []); - - useEffect(() => { - if (typeof window !== "undefined") { - document.documentElement.classList.toggle("dark", dark); - localStorage.setItem("darkMode", JSON.stringify(dark)); - } - }, [dark]); - - const showSearchBar = searchTerm !== undefined && setSearchTerm !== undefined; + const [searchTerm, setSearchTerm] = useState(""); + const showSearchBar = searchTerm !== undefined && setSearchTerm !== undefined; - return ( - <> -
-
- - - -
-
- {showSearchBar ? ( -
- setSearchTerm(e.target.value)} - className="w-full h-8 pr-10" - /> - -
- ) : null} - - -
-
- - - - - - - - - - - Profile - - - - My Listings - - - - Transaction History - - - - Settings - - - - -
-
- - ); + return ( + <> +
+
+ + + +
+ {showSearchBar ? ( +
+ setSearchTerm(e.target.value)} + className="w-full h-8 pr-10" + /> + +
+ ) : null} +
+ + + + + + + + + + + Profile + + + + My Listings + + + + Transaction History + + + + Settings + + + + +
+
+ + ); } diff --git a/frontend/app/components/header/subheader/SubHeader.tsx b/frontend/app/components/header/subheader/SubHeader.tsx index 084612a..d5d8468 100644 --- a/frontend/app/components/header/subheader/SubHeader.tsx +++ b/frontend/app/components/header/subheader/SubHeader.tsx @@ -1,39 +1,36 @@ "use client"; import { Button } from "@radix-ui/themes"; -import BreadcrumbNavigation from "../../ui/breadcrumb-navigation"; import { CirclePlus } from "lucide-react"; import { useState } from "react"; import AddProductModal from "../../ui/add-product-modal"; +import BreadcrumbNavigation from "../../ui/breadcrumb-navigation"; interface SubHeaderProps { - name: string; + name: string; } const SubHeader = ({ name }: SubHeaderProps) => { - const [showModal, setShowModal] = useState(false); + const [showModal, setShowModal] = useState(false); - return ( - <> -
- {/* Breadcrumb Navigation */} - + return ( + <> +
+ {/* Breadcrumb Navigation */} + - -
+ +
- setShowModal(false)} - /> - - ); + setShowModal(false)} /> + + ); }; export default SubHeader; diff --git a/frontend/app/components/products/ProductDetailModal.tsx b/frontend/app/components/products/ProductDetailModal.tsx index 6a8c5d3..891f15d 100644 --- a/frontend/app/components/products/ProductDetailModal.tsx +++ b/frontend/app/components/products/ProductDetailModal.tsx @@ -1,7 +1,7 @@ import { Button } from "@/app/components/ui/button"; +import { ShoppingCart, Star } from "lucide-react"; import ImageCarousel from "../ui/image-carrousel"; -import { ShoppingCart } from "lucide-react"; interface Product { id: number; images: { src: string; alt: string }[]; @@ -10,7 +10,6 @@ interface Product { price: number; category: string; } -import { Star } from "lucide-react"; function ProductDetailModal({ isOpen, @@ -38,34 +37,42 @@ function ProductDetailModal({ return (
+
-

+

{product.name}

-

{product.category}

-

+

+ {product.category} +

+

{product.price ? `$${product.price}` : "Price not available"}

-

{product.description}

+

+ {product.description} +

@@ -80,26 +87,25 @@ function ProductDetailModal({ /> ); } else { - return ; + return ( + + ); } })} - + {rating.toFixed(1)} / 5
-
-
diff --git a/frontend/app/components/providers/theme-provider.tsx b/frontend/app/components/providers/theme-provider.tsx new file mode 100644 index 0000000..0e2a2f1 --- /dev/null +++ b/frontend/app/components/providers/theme-provider.tsx @@ -0,0 +1,9 @@ +"use client"; + +import { ThemeProvider as NextThemesProvider } from "next-themes"; +import { type ThemeProviderProps } from "next-themes"; +import * as React from "react"; + +export function ThemeProvider({ children, ...props }: ThemeProviderProps) { + return {children}; +} diff --git a/frontend/app/components/ui/add-product-modal.tsx b/frontend/app/components/ui/add-product-modal.tsx index 49f0bf0..9a6a356 100644 --- a/frontend/app/components/ui/add-product-modal.tsx +++ b/frontend/app/components/ui/add-product-modal.tsx @@ -2,99 +2,105 @@ import React from "react"; import { Button } from "./button"; import { Input } from "./input"; import { Label } from "./label"; -import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "./select"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "./select"; import { Textarea } from "./textarea"; interface AddProductModalProps { - isOpen: boolean; - onClose: () => void; + isOpen: boolean; + onClose: () => void; } const AddProductModal: React.FC = ({ - isOpen, - onClose, + isOpen, + onClose, }) => { - if (!isOpen) return null; + if (!isOpen) return null; - return ( -
-
-

Add New Product

-
- {/* Product Name */} -
- - -
+ return ( +
+
+

Add New Product

+ + {/* Product Name */} +
+ + +
- {/* Description */} -
- -