fix dark theme

This commit is contained in:
AI Christianson 2025-03-13 19:53:00 -04:00
parent 9f24c6bef9
commit d5d250b215
5 changed files with 150 additions and 33 deletions

View File

@ -6,7 +6,7 @@
"tailwind": { "tailwind": {
"config": "frontend/common/tailwind.config.js", "config": "frontend/common/tailwind.config.js",
"css": "frontend/common/src/styles/global.css", "css": "frontend/common/src/styles/global.css",
"baseColor": "slate", "baseColor": "zinc",
"cssVariables": true "cssVariables": true
}, },
"aliases": { "aliases": {

View File

@ -531,6 +531,30 @@ video {
--radius: 0.5rem; --radius: 0.5rem;
} }
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
--radius: 0.5rem;
}
* { * {
border-color: hsl(var(--border)); border-color: hsl(var(--border));
} }

View File

@ -37,33 +37,25 @@
} }
.dark { .dark {
--background: 240 10% 3.9%; --background: 222.2 84% 4.9%;
--foreground: 0 0% 98%; --foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card: 240 10% 3.9%; --card-foreground: 210 40% 98%;
--card-foreground: 0 0% 98%; --popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--popover: 240 10% 3.9%; --primary: 210 40% 98%;
--popover-foreground: 0 0% 98%; --primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--primary: 0 0% 98%; --secondary-foreground: 210 40% 98%;
--primary-foreground: 240 5.9% 10%; --muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--secondary: 240 3.7% 15.9%; --accent: 217.2 32.6% 17.5%;
--secondary-foreground: 0 0% 98%; --accent-foreground: 210 40% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%; --destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%; --destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--border: 240 3.7% 15.9%; --input: 217.2 32.6% 17.5%;
--input: 240 3.7% 15.9%; --ring: 212.7 26.8% 83.9%;
--ring: 240 4.9% 83.9%;
--radius: 0.5rem; --radius: 0.5rem;
} }

View File

@ -4,6 +4,7 @@ module.exports = {
content: [ content: [
'./src/**/*.{js,jsx,ts,tsx}', './src/**/*.{js,jsx,ts,tsx}',
], ],
safelist: ['dark'],
theme: { theme: {
extend: {}, extend: {},
}, },

View File

@ -10,6 +10,27 @@ import {
} from '@ra-aid/common'; } from '@ra-aid/common';
// The CSS import happens through the common package's index.ts // The CSS import happens through the common package's index.ts
// Theme management helper function
const setupTheme = () => {
// Check if theme preference is stored in localStorage
const storedTheme = localStorage.getItem('theme');
// Default to dark mode unless explicitly set to light
const isDark = storedTheme ? storedTheme === 'dark' : true;
// Apply theme class to document element (html) for better CSS specificity
if (isDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
// Store the current theme preference
localStorage.setItem('theme', isDark ? 'dark' : 'light');
return isDark;
};
const App = () => { const App = () => {
// State for drawer open/close // State for drawer open/close
const [isDrawerOpen, setIsDrawerOpen] = useState(false); const [isDrawerOpen, setIsDrawerOpen] = useState(false);
@ -17,10 +38,19 @@ const App = () => {
// State for selected session // State for selected session
const [selectedSessionId, setSelectedSessionId] = useState<string | null>(null); const [selectedSessionId, setSelectedSessionId] = useState<string | null>(null);
// State for theme (dark is default)
const [isDarkTheme, setIsDarkTheme] = useState(true);
// Get sample data // Get sample data
const sessions = getSampleAgentSessions(); const sessions = getSampleAgentSessions();
const allSteps = getSampleAgentSteps(); const allSteps = getSampleAgentSteps();
// Set up theme on component mount
useEffect(() => {
const isDark = setupTheme();
setIsDarkTheme(isDark);
}, []);
// Set initial selected session if none selected // Set initial selected session if none selected
useEffect(() => { useEffect(() => {
if (!selectedSessionId && sessions.length > 0) { if (!selectedSessionId && sessions.length > 0) {
@ -39,8 +69,24 @@ const App = () => {
setIsDrawerOpen(false); // Close drawer on selection (mobile) setIsDrawerOpen(false); // Close drawer on selection (mobile)
}; };
// Toggle theme function
const toggleTheme = () => {
const newIsDark = !isDarkTheme;
setIsDarkTheme(newIsDark);
// Update document element class
if (newIsDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
// Save to localStorage
localStorage.setItem('theme', newIsDark ? 'dark' : 'light');
};
return ( return (
<div className="min-h-screen bg-background text-foreground flex flex-col dark"> <div className="min-h-screen bg-background text-foreground flex flex-col">
{/* Header */} {/* Header */}
<header className="border-b border-border py-4 px-4 sticky top-0 z-10 bg-background"> <header className="border-b border-border py-4 px-4 sticky top-0 z-10 bg-background">
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
@ -48,16 +94,67 @@ const App = () => {
RA-Aid RA-Aid
</h1> </h1>
{/* Mobile drawer toggle - show only on small screens */} <div className="flex items-center gap-2">
<div className="md:hidden"> {/* Theme toggle button */}
<Button <Button
variant="ghost" variant="ghost"
size="icon" size="icon"
onClick={() => setIsDrawerOpen(true)} onClick={toggleTheme}
aria-label="Open menu" aria-label={isDarkTheme ? "Switch to light mode" : "Switch to dark mode"}
className="mr-2"
> >
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-menu"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg> {isDarkTheme ? (
// Sun icon for light mode toggle
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx="12" cy="12" r="5" />
<line x1="12" y1="1" x2="12" y2="3" />
<line x1="12" y1="21" x2="12" y2="23" />
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
<line x1="1" y1="12" x2="3" y2="12" />
<line x1="21" y1="12" x2="23" y2="12" />
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
</svg>
) : (
// Moon icon for dark mode toggle
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
</svg>
)}
</Button> </Button>
{/* Mobile drawer toggle - show only on small screens */}
<div className="md:hidden">
<Button
variant="ghost"
size="icon"
onClick={() => setIsDrawerOpen(true)}
aria-label="Open menu"
>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-menu"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
</Button>
</div>
</div> </div>
</div> </div>
</header> </header>
@ -106,6 +203,9 @@ const App = () => {
); );
}; };
// Initialize theme before rendering the app
setupTheme();
const root = ReactDOM.createRoot(document.getElementById('root')!); const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render( root.render(
<React.StrictMode> <React.StrictMode>