Workspaces in Workspaces all around
This commit is contained in:
@@ -5,7 +5,7 @@ export const ColorPicker = (props: ColorPickerProps) => {
|
||||
const { value = '#000000', name, label } = props;
|
||||
return (
|
||||
<div style={{ borderWidth: '1px' }} className="relative w-full rounded">
|
||||
{label && <span className="text-muted-foreground absolute z-10 -mt-2 ml-5 bg-white px-2 text-xs">{label}</span>}
|
||||
{label && <span className="text-muted-foreground absolute z-10 -mt-2 ml-5 bg-background px-2 text-xs">{label}</span>}
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="h-12 overflow-hidden rounded-full p-0">
|
||||
<Input
|
||||
|
||||
@@ -21,7 +21,7 @@ export const PaginationBar = <T,>(props: PaginationBarProps<T>) => {
|
||||
};
|
||||
|
||||
const buttonClass =
|
||||
'h-8 w-8 p-0 hover:bg-white text-muted-foreground disabled:opacity-100 disabled:pointer-events-none';
|
||||
'h-8 w-8 p-0 hover:bg-background text-muted-foreground disabled:opacity-100 disabled:pointer-events-none';
|
||||
|
||||
return (
|
||||
<div className="bg-muted/50 flex w-full items-center justify-between border-t p-4">
|
||||
@@ -44,7 +44,7 @@ export const PaginationBar = <T,>(props: PaginationBarProps<T>) => {
|
||||
justify-between
|
||||
bg-transparent
|
||||
text-muted-foreground
|
||||
hover:bg-white
|
||||
hover:bg-background
|
||||
data-[state=open]:bg-muted
|
||||
"
|
||||
aria-label="Rows per page"
|
||||
|
||||
@@ -69,7 +69,7 @@ export function MarkdownEditor({
|
||||
) : (
|
||||
<div className="w-full h-full overflow-auto bg-slate-50 dark:bg-slate-900 p-4">
|
||||
{/* Email wrapper simulation */}
|
||||
<div className="mx-auto max-w-2xl rounded-lg bg-white dark:bg-slate-800 p-8 shadow-lg">
|
||||
<div className="mx-auto max-w-2xl rounded-lg bg-background p-8 shadow-lg">
|
||||
{/* Logo */}
|
||||
<div className="mb-8 text-center">
|
||||
<img src="https://app.pertento.ai/logo.png" alt="Pertento" className="h-16 mx-auto" />
|
||||
|
||||
@@ -14,7 +14,7 @@ export const AppPicker = ({ registry, onSelect }: AppPickerProps) => {
|
||||
<button
|
||||
key={key}
|
||||
type="button"
|
||||
className="flex flex-col items-center gap-1.5 rounded-lg border border-duck-teal/25 bg-white/80 backdrop-blur-sm px-3 py-3 text-duck-teal hover:border-duck-teal/40 hover:bg-white/90 transition-colors cursor-pointer"
|
||||
className="flex flex-col items-center gap-1.5 rounded-lg border border-duck-teal/25 bg-background/80 backdrop-blur-sm px-3 py-3 text-duck-teal hover:border-duck-teal/40 hover:bg-background/90 transition-colors cursor-pointer"
|
||||
onClick={() => onSelect(key)}
|
||||
>
|
||||
<entry.icon className="h-5 w-5" />
|
||||
|
||||
@@ -20,6 +20,8 @@ export type WorkspaceDefinition = {
|
||||
id: string;
|
||||
name: string;
|
||||
cwd: string;
|
||||
description?: string;
|
||||
templateIdx?: number;
|
||||
};
|
||||
|
||||
export type AppRegistryEntry = {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user