Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TooltipProvider } from "@/components/ui/tooltip";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { UserProvider } from "@/contexts/UserContext";
import { ThemeProvider } from "@/contexts/ThemeContext";
import AppRoutes from "./routes";

const queryClient = new QueryClient({
Expand All @@ -20,15 +21,17 @@ const queryClient = new QueryClient({
const App = () => (
<BrowserRouter>
<QueryClientProvider client={queryClient}>
<UserProvider>
<TooltipProvider>
<div className="min-h-screen flex flex-col">
<AppRoutes />
<Toaster />
<Sonner />
</div>
</TooltipProvider>
</UserProvider>
<ThemeProvider>
<UserProvider>
<TooltipProvider>
<div className="min-h-screen flex flex-col">
<AppRoutes />
<Toaster />
<Sonner />
</div>
</TooltipProvider>
</UserProvider>
</ThemeProvider>
</QueryClientProvider>
</BrowserRouter>
);
Expand Down
46 changes: 46 additions & 0 deletions src/components/ThemeToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import { useTheme as useNextTheme } from 'next-themes';
import { Sun, Moon, Monitor } from 'lucide-react';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
import { Theme } from '@/contexts/ThemeContext';

export const ThemeToggle = () => {
const { theme, setTheme } = useNextTheme();

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon" className="w-9 h-9">
{theme === 'light' ? (
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all" />
) : theme === 'dark' ? (
<Moon className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all" />
) : (
<Monitor className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all" />
)}
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme('light')}>
<Sun className="h-4 w-4 mr-2" />
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('dark')}>
<Moon className="h-4 w-4 mr-2" />
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('system')}>
<Monitor className="h-4 w-4 mr-2" />
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
};
6 changes: 4 additions & 2 deletions src/components/TopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { BookFormDialog } from './BookFormDialog';
import { ThemeToggle } from './ThemeToggle';

const TopBar = () => {
const [searchQuery, setSearchQuery] = useState('');
Expand Down Expand Up @@ -46,7 +47,7 @@ const handleSearch = (e: React.FormEvent) => {

return (
<>
<div className="sticky top-0 z-10 w-full bg-white/90 backdrop-blur-sm border-b border-gray-100 py-3">
<div className="sticky top-0 z-10 w-full bg-background/90 backdrop-blur-sm border-b border-border py-3">
<div className="container mx-auto flex items-center justify-between px-4">
<div className="flex-shrink-0">
<a href="/" className="flex items-center gap-2">
Expand Down Expand Up @@ -88,7 +89,8 @@ const handleSearch = (e: React.FormEvent) => {
)}
</div>

<div className="flex items-center">
<div className="flex items-center gap-2">
<ThemeToggle />

<DropdownMenu>
<DropdownMenuTrigger asChild>
Expand Down
26 changes: 26 additions & 0 deletions src/contexts/ThemeContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { createContext, useContext, useEffect, useState } from 'react';
import { ThemeProvider as NextThemesProvider } from 'next-themes';

// Define the theme options
export type Theme = 'light' | 'dark' | 'system';

// Create a context for theme-related functionality
export const ThemeContext = createContext<{

Check warning on line 8 in src/contexts/ThemeContext.tsx

View workflow job for this annotation

GitHub Actions / Run Tests

Fast refresh only works when a file only exports components. Move your React context(s) to a separate file
theme: Theme;
setTheme: (theme: Theme) => void;
}>({
theme: 'system',
setTheme: () => {},
});

// Custom hook to use the theme context
export const useTheme = () => useContext(ThemeContext);

Check warning on line 17 in src/contexts/ThemeContext.tsx

View workflow job for this annotation

GitHub Actions / Run Tests

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components

// Theme provider component
export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
return (
<NextThemesProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</NextThemesProvider>
);
};
Loading