From e86b8f8eb04145c0806865c89a78d88f960900ef Mon Sep 17 00:00:00 2001 From: Anushka Wagh Date: Mon, 29 Jun 2026 16:05:55 +0530 Subject: [PATCH] feat(theme): add light mode --- app/api/events/route.ts | 8 +- app/create-event/page.tsx | 4 +- app/error.tsx | 6 +- app/events/page.tsx | 2 +- app/globals.css | 106 ++++++++----- app/layout.tsx | 32 ++-- app/my-bookings/page.tsx | 225 +++++++++++++--------------- app/not-found.tsx | 6 +- app/page.tsx | 7 +- app/watchlist/page.tsx | 65 ++++---- components/BookEvent.tsx | 2 +- components/CreateNewEvent.tsx | 23 ++- components/EventCard.tsx | 114 ++++---------- components/EventDetails.tsx | 6 +- components/EventDetailsSkeleton.tsx | 14 +- components/ExploreBtn.tsx | 5 +- components/Footer.tsx | 10 +- components/LightRays.tsx | 24 ++- components/NavLinks.tsx | 29 ++-- components/Navbar.tsx | 6 +- components/SearchFilters.tsx | 132 +++++++--------- components/ThemeToggle.tsx | 25 ++++ lib/actions/booking.actions.ts | 4 +- lib/actions/create-event.actions.ts | 11 +- lib/actions/event.actions.ts | 148 +++++++++++++++--- lib/mongodb.ts | 15 +- lib/use-bookmarks.ts | 41 +++++ package-lock.json | 142 +++++++----------- package.json | 2 +- tsconfig.json | 2 +- 30 files changed, 662 insertions(+), 554 deletions(-) create mode 100644 components/ThemeToggle.tsx create mode 100644 lib/use-bookmarks.ts diff --git a/app/api/events/route.ts b/app/api/events/route.ts index d272832..e4b39e1 100644 --- a/app/api/events/route.ts +++ b/app/api/events/route.ts @@ -14,7 +14,7 @@ export async function POST(req: NextRequest) { try { event = Object.fromEntries(formData.entries()); - } catch (e) { + } catch { return NextResponse.json({ message: 'Invalid JSON data format' }, { status: 400 }) } @@ -46,8 +46,8 @@ export async function POST(req: NextRequest) { const tagsStr = formData.get('tags') as string; const agendaStr = formData.get('agenda') as string; - let tags = safeParseJsonArray(tagsStr); - let agenda = safeParseJsonArray(agendaStr); + const tags = safeParseJsonArray(tagsStr); + const agenda = safeParseJsonArray(agendaStr); const arrayBuffer = await file.arrayBuffer(); const buffer = Buffer.from(arrayBuffer); @@ -148,4 +148,4 @@ export async function GET(req: NextRequest) { } catch (e) { return NextResponse.json({ message: 'Event fetching failed', error: e }, { status: 500 }); } -} \ No newline at end of file +} diff --git a/app/create-event/page.tsx b/app/create-event/page.tsx index c5aa1ad..4f54591 100644 --- a/app/create-event/page.tsx +++ b/app/create-event/page.tsx @@ -11,7 +11,7 @@ const CreateEventPage = () => { Create New Event -

+

Submit your hackathon, meetup, or conference.

@@ -23,4 +23,4 @@ const CreateEventPage = () => { ); }; -export default CreateEventPage; \ No newline at end of file +export default CreateEventPage; diff --git a/app/error.tsx b/app/error.tsx index d408138..9694b5d 100644 --- a/app/error.tsx +++ b/app/error.tsx @@ -17,11 +17,11 @@ export default function ErrorPage({ }, [error]); return ( -
+

Something went wrong

-

+

An unexpected error occurred. Please try again.

@@ -33,7 +33,7 @@ export default function ErrorPage({ Go home diff --git a/app/events/page.tsx b/app/events/page.tsx index 2f7a12e..f239be7 100644 --- a/app/events/page.tsx +++ b/app/events/page.tsx @@ -103,7 +103,7 @@ export default async function Page({ searchParams }: PageProps) {
{/* SearchFilters uses useSearchParams — must be inside Suspense */} - }> + }> diff --git a/app/globals.css b/app/globals.css index 92580d6..f43c0ca 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,39 +1,37 @@ @import "tailwindcss"; @import "tw-animate-css"; -@custom-variant dark (&:is(.dark *)); - -input[type="date"]::-webkit-calendar-picker-indicator, -input[type="time"]::-webkit-calendar-picker-indicator { - filter: invert(1); -} +@custom-variant dark (&:where(.dark, .dark *)); :root { - --color-blue: #94eaff; - --color-light-100: #e7f2ff; - --color-light-200: #bdbdbd; - --color-border-dark: #151024; - --color-dark-100: #0d161a; - --color-dark-200: #182830; + color-scheme: light; + --font-sans-brand: "Segoe UI", Inter, system-ui, -apple-system, BlinkMacSystemFont, sans-serif; + --font-mono-brand: "Cascadia Code", "SFMono-Regular", Consolas, monospace; + --color-blue: #087f91; + --color-light-100: #17262d; + --color-light-200: #52666f; + --color-border-dark: #d8e2e6; + --color-dark-100: #ffffff; + --color-dark-200: #eef4f6; --radius: 0.625rem; - --background: #030708; - --foreground: #ffffff; - --card: oklch(1 0 0); - --card-foreground: oklch(0.145 0 0); - --popover: oklch(1 0 0); - --popover-foreground: oklch(0.145 0 0); - --primary: #59deca; - --primary-foreground: oklch(0.985 0 0); - --secondary: oklch(0.97 0 0); - --secondary-foreground: oklch(0.205 0 0); - --muted: oklch(0.97 0 0); - --muted-foreground: oklch(0.556 0 0); - --accent: oklch(0.97 0 0); - --accent-foreground: oklch(0.205 0 0); + --background: #f6fafb; + --foreground: #102027; + --card: #ffffff; + --card-foreground: #102027; + --popover: #ffffff; + --popover-foreground: #102027; + --primary: #0f9f91; + --primary-foreground: #ffffff; + --secondary: #e7f1f3; + --secondary-foreground: #183038; + --muted: #eaf1f3; + --muted-foreground: #52666f; + --accent: #dff5f1; + --accent-foreground: #075e57; --destructive: oklch(0.577 0.245 27.325); - --border: oklch(0.922 0 0); - --input: oklch(0.922 0 0); - --ring: oklch(0.708 0 0); + --border: #d8e2e6; + --input: #cad8dd; + --ring: #0f9f91; --chart-1: oklch(0.646 0.222 41.116); --chart-2: oklch(0.6 0.118 184.704); --chart-3: oklch(0.398 0.07 227.392); @@ -58,8 +56,8 @@ input[type="time"]::-webkit-calendar-picker-indicator { --color-border-dark: var(--color-border-dark); --color-dark-100: var(--color-dark-100); --color-dark-200: var(--color-dark-200); - --font-schibsted-grotesk: var(--font-schibsted-grotesk); - --font-martian-mono: var(--font-martian-mono); + --font-schibsted-grotesk: var(--font-sans-brand); + --font-martian-mono: var(--font-mono-brand); --color-sidebar-ring: var(--sidebar-ring); --color-sidebar-border: var(--sidebar-border); --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); @@ -100,11 +98,11 @@ input[type="time"]::-webkit-calendar-picker-indicator { } @utility text-gradient { - @apply to-blue bg-gradient-to-b from-white via-white bg-clip-text font-semibold text-transparent; + @apply to-blue bg-gradient-to-b from-foreground via-foreground bg-clip-text font-semibold text-transparent; } @utility glass { - @apply bg-[#12121280]/50 rounded-md bg-clip-padding backdrop-filter backdrop-blur-xl border-b border-border-dark; + @apply bg-background/85 rounded-md bg-clip-padding backdrop-filter backdrop-blur-xl border-b border-border-dark; } @utility card-shadow { @@ -117,7 +115,9 @@ input[type="time"]::-webkit-calendar-picker-indicator { } body { - @apply bg-background text-foreground; + @apply min-h-screen bg-background text-foreground antialiased transition-colors duration-300; + font-family: var(--font-sans-brand); + background-image: radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--primary) 8%, transparent), transparent 34rem); } main { @@ -227,7 +227,7 @@ input[type="time"]::-webkit-calendar-picker-indicator { } .booking { - @apply flex-1 w-full p-4 border-l border-gray-700; + @apply flex-1 w-full p-4 border-l border-border; .signup-card { @apply bg-dark-100 border-dark-200 card-shadow flex w-full flex-col gap-6 rounded-[10px] border px-5 py-6; @@ -277,4 +277,38 @@ input[type="time"]::-webkit-calendar-picker-indicator { } } } -} \ No newline at end of file +} + +.dark { + color-scheme: dark; + --color-blue: #94eaff; + --color-light-100: #e7f2ff; + --color-light-200: #bdbdbd; + --color-border-dark: #21323a; + --color-dark-100: #0d161a; + --color-dark-200: #182830; + --background: #030708; + --foreground: #ffffff; + --card: #0d161a; + --card-foreground: #f4fbff; + --popover: #0d161a; + --popover-foreground: #f4fbff; + --primary: #59deca; + --primary-foreground: #031310; + --secondary: #182830; + --secondary-foreground: #f4fbff; + --muted: #182830; + --muted-foreground: #bdbdbd; + --accent: #163139; + --accent-foreground: #dffcff; + --border: #21323a; + --input: #2b3e47; + --ring: #59deca; + --sidebar: #0d161a; + --sidebar-foreground: #f4fbff; +} + +.dark input[type="date"]::-webkit-calendar-picker-indicator, +.dark input[type="time"]::-webkit-calendar-picker-indicator { + filter: invert(1); +} diff --git a/app/layout.tsx b/app/layout.tsx index 8c37c80..8b3d9b0 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,4 @@ import type { Metadata } from "next"; -import { Schibsted_Grotesk, Martian_Mono } from "next/font/google"; import { Suspense } from "react"; import "./globals.css"; import LightRays from "../components/LightRays"; @@ -8,17 +7,17 @@ import { PostHogProvider } from "./providers"; import { Toaster } from "sonner"; import BackToTop from '../components/BackToTop'; - -const SchibstedGrotesk = Schibsted_Grotesk({ - variable: "--font-schibsted-grotesk", - subsets: ["latin"], -}); - -const MartianMono = Martian_Mono({ - variable: "--font-martian-mono", - subsets: ["latin"], -}); - +const themeScript = ` + try { + const savedTheme = localStorage.getItem('devevent-theme'); + const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + const theme = savedTheme === 'light' || savedTheme === 'dark' + ? savedTheme + : (prefersDark ? 'dark' : 'light'); + document.documentElement.classList.toggle('dark', theme === 'dark'); + document.documentElement.dataset.theme = theme; + } catch (_) {} +`; export const metadata: Metadata = { title: "DevEvent", description: "The Hub for Every Dev Event that you Mustn't Miss", @@ -31,9 +30,10 @@ export default function RootLayout({ }>) { return ( - + +