Skip to content

Commit c512d1b

Browse files
Merge pull request #17 from Santiago13dev/feature/dark-mode
feat: implementar dark mode completo
2 parents 60e583e + 2aeb893 commit c512d1b

File tree

4 files changed

+120
-5
lines changed

4 files changed

+120
-5
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react';
2+
import { useTheme } from '../contexts/ThemeContext';
3+
4+
const ThemeToggle: React.FC = () => {
5+
const { theme, toggleTheme } = useTheme();
6+
7+
return (
8+
<button
9+
onClick={toggleTheme}
10+
className="p-2 rounded-lg bg-gray-200 dark:bg-gray-800 hover:bg-gray-300 dark:hover:bg-gray-700 transition-colors"
11+
aria-label="Toggle theme"
12+
>
13+
{theme === 'light' ? (
14+
<svg className="w-6 h-6 text-gray-800" fill="none" stroke="currentColor" viewBox="0 0 24 24">
15+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
16+
</svg>
17+
) : (
18+
<svg className="w-6 h-6 text-yellow-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
19+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
20+
</svg>
21+
)}
22+
</button>
23+
);
24+
};
25+
26+
export default ThemeToggle;

frontend/contexts/ThemeContext.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, { createContext, useContext, useState, useEffect } from 'react';
2+
3+
type Theme = 'light' | 'dark';
4+
5+
interface ThemeContextType {
6+
theme: Theme;
7+
toggleTheme: () => void;
8+
}
9+
10+
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
11+
12+
export const useTheme = () => {
13+
const context = useContext(ThemeContext);
14+
if (!context) {
15+
throw new Error('useTheme must be used within a ThemeProvider');
16+
}
17+
return context;
18+
};
19+
20+
export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
21+
const [theme, setTheme] = useState<Theme>('light');
22+
23+
useEffect(() => {
24+
const savedTheme = localStorage.getItem('theme') as Theme | null;
25+
if (savedTheme) {
26+
setTheme(savedTheme);
27+
document.documentElement.classList.toggle('dark', savedTheme === 'dark');
28+
}
29+
}, []);
30+
31+
const toggleTheme = () => {
32+
const newTheme = theme === 'light' ? 'dark' : 'light';
33+
setTheme(newTheme);
34+
localStorage.setItem('theme', newTheme);
35+
document.documentElement.classList.toggle('dark', newTheme === 'dark');
36+
};
37+
38+
return (
39+
<ThemeContext.Provider value={{ theme, toggleTheme }}>
40+
{children}
41+
</ThemeContext.Provider>
42+
);
43+
};

frontend/styles/themes.css

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* Light theme variables */
2+
:root {
3+
--bg-primary: #ffffff;
4+
--bg-secondary: #f3f4f6;
5+
--text-primary: #111827;
6+
--text-secondary: #6b7280;
7+
--border-color: #e5e7eb;
8+
--accent-color: #3b82f6;
9+
}
10+
11+
/* Dark theme variables */
12+
.dark {
13+
--bg-primary: #111827;
14+
--bg-secondary: #1f2937;
15+
--text-primary: #f9fafb;
16+
--text-secondary: #9ca3af;
17+
--border-color: #374151;
18+
--accent-color: #60a5fa;
19+
}
20+
21+
/* Apply theme variables */
22+
body {
23+
background-color: var(--bg-primary);
24+
color: var(--text-primary);
25+
transition: background-color 0.3s ease, color 0.3s ease;
26+
}

frontend/tailwind.config.cjs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
11
/** @type {import('tailwindcss').Config} */
22
module.exports = {
33
content: [
4-
"./app/**/*.{js,ts,jsx,tsx}",
5-
"./components/**/*.{js,ts,jsx,tsx}",
6-
"./src/**/*.{js,ts,jsx,tsx}",
4+
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
5+
'./components/**/*.{js,ts,jsx,tsx,mdx}',
6+
'./app/**/*.{js,ts,jsx,tsx,mdx}',
7+
'./src/**/*.{js,ts,jsx,tsx,mdx}',
78
],
8-
theme: { extend: {} },
9+
darkMode: 'class',
10+
theme: {
11+
extend: {
12+
colors: {
13+
primary: {
14+
50: '#eff6ff',
15+
500: '#3b82f6',
16+
600: '#2563eb',
17+
700: '#1d4ed8',
18+
},
19+
gray: {
20+
850: '#18202F',
21+
950: '#0b0f19',
22+
}
23+
},
24+
animation: {
25+
'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
26+
}
27+
},
28+
},
929
plugins: [],
10-
};
30+
}

0 commit comments

Comments
 (0)