Workspaces in Workspaces all around

This commit is contained in:
2026-02-19 01:49:15 +00:00
parent 72bca6cd42
commit dd8ab84df5
84 changed files with 3047 additions and 749 deletions
+20 -25
View File
@@ -1,45 +1,40 @@
import { createContext, useContext, useEffect, useState } from 'react';
type ColorMode = 'light' | 'dark';
const initialState = {
theme: 'light',
setTheme: (theme: string) => {
theme;
return null;
},
colorMode: 'light' as ColorMode,
setColorMode: (_mode: ColorMode) => {},
};
type ThemeProviderProps = { children: React.ReactNode; defaultTheme?: string; storageKey?: string };
type ColorModeProviderProps = { children: React.ReactNode; defaultMode?: ColorMode; storageKey?: string };
const ThemeProviderContext = createContext(initialState);
const ColorModeContext = createContext(initialState);
export function ThemeProvider(props: ThemeProviderProps) {
const { children, defaultTheme = 'light', storageKey = 'theme' } = props;
const [theme, setTheme] = useState(() => localStorage.getItem(storageKey) || defaultTheme);
export function ColorModeProvider(props: ColorModeProviderProps) {
const { children, defaultMode = 'light', storageKey = 'officer-color-mode' } = props;
const [colorMode, setColorModeState] = useState<ColorMode>(
() => (localStorage.getItem(storageKey) as ColorMode) || defaultMode,
);
useEffect(() => {
const root = window.document.documentElement;
root.classList.remove('light', 'dark');
root.classList.add(colorMode);
}, [colorMode]);
root.classList.add(theme);
}, [theme]);
const value = {
theme,
setTheme: (newTheme: string) => {
localStorage.setItem(storageKey, newTheme);
setTheme(newTheme);
return null;
},
const setColorMode = (mode: ColorMode) => {
localStorage.setItem(storageKey, mode);
setColorModeState(mode);
};
return <ThemeProviderContext.Provider value={value}>{children}</ThemeProviderContext.Provider>;
return <ColorModeContext.Provider value={{ colorMode, setColorMode }}>{children}</ColorModeContext.Provider>;
}
export const useTheme = () => {
const context = useContext(ThemeProviderContext);
export const useColorMode = () => {
const context = useContext(ColorModeContext);
if (context === undefined) throw new Error('useTheme must be used within a ThemeProvider');
if (context === undefined) throw new Error('useColorMode must be used within a ColorModeProvider');
return context;
};
+6 -6
View File
@@ -1,19 +1,19 @@
import { Moon, Sun } from 'lucide-react';
import { cn } from 'helpers/cn';
import { useTheme } from './ThemeProvider';
import { useColorMode } from './ThemeProvider';
type ThemeToggleProps = { colorDark?: boolean; colorLight?: boolean };
export const ThemeToggle = (props: ThemeToggleProps) => {
const { colorDark, colorLight } = props;
const { theme, setTheme } = useTheme();
const { colorMode, setColorMode } = useColorMode();
const changeTheme = () => {
setTheme(theme === 'dark' ? 'light' : 'dark');
const toggle = () => {
setColorMode(colorMode === 'dark' ? 'light' : 'dark');
};
return (
<div className="cursor-pointer" onClick={changeTheme}>
<div className="cursor-pointer" onClick={toggle}>
<Sun
className={cn(
'h-[1.2rem] w-[1.2rem] origin-center rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0',
@@ -26,7 +26,7 @@ export const ThemeToggle = (props: ThemeToggleProps) => {
colorDark && 'text-black',
)}
/>
<span className="sr-only">Toggle theme</span>
<span className="sr-only">Toggle color mode</span>
</div>
);
};
+4 -4
View File
@@ -1,25 +1,25 @@
import * as React from 'react';
import { Moon, Sun } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useTheme } from '@/components/ui/ThemeProvider';
import { useColorMode } from '@/components/ui/ThemeProvider';
import { cn } from 'helpers/cn';
export const ModeToggle = React.forwardRef<React.ElementRef<typeof Button>, React.ComponentProps<typeof Button>>(
({ className, ...props }, ref) => {
const { theme, setTheme } = useTheme();
const { colorMode, setColorMode } = useColorMode();
return (
<Button
ref={ref}
variant="outline"
size="icon"
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
onClick={() => setColorMode(colorMode === 'light' ? 'dark' : 'light')}
className={cn('h-9 w-9', className)}
{...props}
>
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
<span className="sr-only">Toggle color mode</span>
</Button>
);
},