From 20afb2b76c6ebd3264c45c01d23b1aa5edf41465 Mon Sep 17 00:00:00 2001 From: kimjaehyeon0101 <47347352-kimjaehyeon0101@users.noreply.replit.com> Date: Tue, 30 Sep 2025 00:34:11 +0000 Subject: [PATCH] Enhance auction page with theme options and login functionality Updated the Auctions page to include theme selection (light/dark) via localStorage, language selection, and integrated a login modal. Replaced direct logout navigation with a modal trigger and added a dropdown menu for user actions. Imported additional lucide-react icons and UI components for theme/language dropdowns. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 069d4324-6c40-4355-955e-c714a50de1ea Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/069d4324-6c40-4355-955e-c714a50de1ea/yHCvWBg --- client/src/pages/Auctions.tsx | 243 +++++++++++++++++++++++++++++++--- 1 file changed, 226 insertions(+), 17 deletions(-) diff --git a/client/src/pages/Auctions.tsx b/client/src/pages/Auctions.tsx index 9984ba3..0cd5bd2 100644 --- a/client/src/pages/Auctions.tsx +++ b/client/src/pages/Auctions.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { useQuery, useMutation } from "@tanstack/react-query"; import { queryClient } from "@/lib/queryClient"; import { Button } from "@/components/ui/button"; @@ -12,9 +12,18 @@ import { apiRequest } from "@/lib/queryClient"; import { isUnauthorizedError } from "@/lib/authUtils"; import AuctionCard from "@/components/AuctionCard"; import type { Auction, MediaOutlet } from "@shared/schema"; -import { BookOpen } from "lucide-react"; +import { BookOpen, Settings, User, LogOut, Sun, Moon, Monitor, Globe } from "lucide-react"; import { Link } from "wouter"; import Footer from "@/components/Footer"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import LoginModal from "@/components/LoginModal"; export default function Auctions() { const { user, isAuthenticated } = useAuth(); @@ -25,6 +34,68 @@ export default function Auctions() { amount: "", qualityScore: "" }); + const [isLoginModalOpen, setIsLoginModalOpen] = useState(false); + + const [theme, setTheme] = useState(() => localStorage.getItem('theme') || 'light'); + const [language, setLanguage] = useState(() => localStorage.getItem('language') || 'en'); + + useEffect(() => { + if (theme === 'dark') { + document.documentElement.classList.add('dark'); + } else { + document.documentElement.classList.remove('dark'); + } + localStorage.setItem('theme', theme); + }, [theme]); + + useEffect(() => { + localStorage.setItem('language', language); + }, [language]); + + const handleThemeChange = (newTheme: string) => { + setTheme(newTheme); + }; + + const handleLanguageChange = (newLanguage: string) => { + setLanguage(newLanguage); + }; + + const languages = [ + { code: 'en', name: 'English' }, + { code: 'fr', name: 'Français' }, + { code: 'de', name: 'Deutsch' }, + { code: 'it', name: 'Italiano' }, + { code: 'hi', name: 'हिन्दी' }, + { code: 'ar', name: 'العربية' }, + { code: 'ja', name: '日本語' }, + { code: 'ko', name: '한국어' }, + { code: 'zh-TW', name: '繁體中文' }, + { code: 'zh-CN', name: '简体中文' }, + ]; + + const handleLogout = async () => { + try { + const response = await fetch("/api/logout", { + method: "POST", + credentials: "include", + }); + + if (response.ok) { + toast({ + title: "Logged Out", + description: "You have been successfully logged out.", + }); + + queryClient.invalidateQueries({ queryKey: ["/api/auth/user"] }); + } + } catch (error) { + toast({ + title: "Logout Error", + description: "An error occurred while logging out.", + variant: "destructive", + }); + } + }; const { data: auctions = [], isLoading: auctionsLoading } = useQuery({ queryKey: ["/api/auctions"], @@ -77,9 +148,7 @@ export default function Auctions() { description: "Please log in to place a bid.", variant: "destructive" }); - setTimeout(() => { - window.location.href = "/api/login"; - }, 1000); + setIsLoginModalOpen(true); return; } setSelectedAuction(auction); @@ -186,17 +255,149 @@ export default function Auctions() { {isAuthenticated && user ? ( - + <> + + + + + + Theme + handleThemeChange('light')} + className="cursor-pointer" + data-testid="theme-light" + > + + Light + + handleThemeChange('dark')} + className="cursor-pointer" + data-testid="theme-dark" + > + + Dark + + handleThemeChange('system')} + className="cursor-pointer" + data-testid="theme-system" + > + + System + + + + + Language + {languages.map((lang) => ( + handleLanguageChange(lang.code)} + className="cursor-pointer" + data-testid={`language-${lang.code}`} + > + + {lang.name} + + ))} + + + + + +
+ + + {user.firstName} {user.lastName} + +
+
+ + My Account + + + + Logout + + +
+ ) : ( - + <> + + + + + + Theme + handleThemeChange('light')} + className="cursor-pointer" + data-testid="theme-light" + > + + Light + + handleThemeChange('dark')} + className="cursor-pointer" + data-testid="theme-dark" + > + + Dark + + handleThemeChange('system')} + className="cursor-pointer" + data-testid="theme-system" + > + + System + + + + + Language + {languages.map((lang) => ( + handleLanguageChange(lang.code)} + className="cursor-pointer" + data-testid={`language-${lang.code}`} + > + + {lang.name} + + ))} + + + + + )} @@ -275,7 +476,7 @@ export default function Auctions() {
Quality Score: - {auction.qualityScore || 0}/100 + {auction.qualityScore || 0}/100
Duration: @@ -290,7 +491,7 @@ export default function Auctions() {