Skip to content

Commit 409209e

Browse files
committed
Initial Commit
1 parent 30bd73e commit 409209e

11 files changed

Lines changed: 154 additions & 27 deletions

File tree

index.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
<!doctype html>
22
<html lang="en">
33
<head>
4+
<link rel="preconnect" href="https://fonts.googleapis.com" />
5+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
6+
<link
7+
href="https://fonts.googleapis.com/css2?family=Asap:ital,wght@0,100..900;1,100..900&display=swap"
8+
rel="stylesheet"
9+
/>
410
<meta charset="UTF-8" />
511
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
612
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

src/App.tsx

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { BrowserRouter, Route, Routes } from 'react-router-dom';
2+
import { ThemeProvider } from './contexts/ThemeContext';
23
import AppLayout from './components/AppLayout.tsx';
34
import Home from './pages/Home.tsx';
45
import Register from './pages/Register.tsx';
@@ -13,21 +14,23 @@ import Settings from './pages/Settings.tsx';
1314
function App() {
1415
return (
1516
<>
16-
<BrowserRouter>
17-
<Routes>
18-
<Route path="/" element={<Home />} />
19-
<Route path="/register" element={<Register />} />
20-
<Route element={<AppLayout />}>
21-
<Route path="/dashboard" element={<Dashboard />} />
22-
<Route path="/events" element={<Events />} />
23-
<Route path="/calendar" element={<Calendar />} />
24-
<Route path="/roster" element={<Roster />} />
25-
<Route path="/notifications" element={<Notifications />} />
26-
<Route path="/profile" element={<Profile />} />
27-
<Route path="/settings" element={<Settings />} />
28-
</Route>
29-
</Routes>
30-
</BrowserRouter>
17+
<ThemeProvider>
18+
<BrowserRouter>
19+
<Routes>
20+
<Route path="/" element={<Home />} />
21+
<Route path="/register" element={<Register />} />
22+
<Route element={<AppLayout />}>
23+
<Route path="/dashboard" element={<Dashboard />} />
24+
<Route path="/events" element={<Events />} />
25+
<Route path="/calendar" element={<Calendar />} />
26+
<Route path="/roster" element={<Roster />} />
27+
<Route path="/notifications" element={<Notifications />} />
28+
<Route path="/profile" element={<Profile />} />
29+
<Route path="/settings" element={<Settings />} />
30+
</Route>
31+
</Routes>
32+
</BrowserRouter>
33+
</ThemeProvider>
3134
</>
3235
);
3336
}

src/components/.gitkeep

Whitespace-only changes.

src/components/DarkModeToggle.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { useTheme } from '../contexts/ThemeContext';
2+
3+
export function DarkModeToggle() {
4+
const { theme, toggleTheme } = useTheme();
5+
6+
return (
7+
<input
8+
type="checkbox"
9+
checked={theme === 'dark'}
10+
onChange={toggleTheme}
11+
style={{ height: '20px', width: '20px' }}
12+
/>
13+
);
14+
}

src/components/Header.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import '../css/header.css';
22
import { useNavigate } from 'react-router-dom';
3+
import { DarkModeToggle } from './DarkModeToggle.tsx';
34

45
export default function Header() {
56
const navigate = useNavigate();
7+
68
return (
79
<div className="header-container">
810
<h1 className="header-title">CAPY Web UI</h1>
@@ -13,6 +15,7 @@ export default function Header() {
1315
<a className="register-btn" onClick={() => navigate('/register')}>
1416
Register
1517
</a>
18+
<DarkModeToggle />
1619
</div>
1720
</div>
1821
);

src/contexts/ThemeContext.tsx

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

src/css/colors.css

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,66 @@
1-
/* All of the Web UI's color variables in one place */
1+
/* colors.css: All of the Web UI's color variables in one place */
2+
3+
/*
4+
5+
PURPOSE: Consistent, easily modifiable color variables
6+
abstracted to a single file.
7+
8+
HOW TO USE: All variables in the CAPY COLOR SUITE should be treated
9+
as constants. These constants should NOT be found in other CSS files.
10+
Instead, create variables in the COLOR VARIABLES section, and use those.
11+
COLOR VARIABLES should be duplicated and properly adjusted in the dark
12+
mode section as well.
13+
14+
*/
215

316
:root {
17+
/* GLOBAL STYLES ============================ */
418
--site-transition: 0.25s;
5-
--site-bg: #f5f5f5;
6-
--header-bg: #fff;
7-
--sidebar-bg: #fff;
8-
--sidebar-link-hover-bg: #f4f4f4;
9-
--sidebar-active-link-bg: #e4e4e4;
10-
--standard-white: #fff;
11-
--standard-black: #000;
12-
--standard-text: #1c1c1c;
19+
--site-font: 'Asap', sans-serif;
20+
21+
/* ========================================== */
22+
23+
/* CAPY COLOR SUITE ========================= */
24+
25+
/* All colors used on the site are found here */
26+
--primary-light: #339b92;
27+
--primary: #007a75;
28+
--primary-dark: #00464d;
29+
--primary-extra-dark: #002633;
30+
--accent: #f1602f;
31+
--off-white: #f9fafa;
32+
--highlight: #f4f8f6;
33+
--off-black: #20201f;
34+
35+
/* ========================================== */
36+
37+
/* COLOR VARIABLES ========================== */
38+
39+
/* Global Styles: backgrounds, text */
40+
--site-bg: var(--off-white);
41+
--standard-white: var(--off-white);
42+
--standard-black: var(--off-black);
43+
--standard-text: var(--primary);
44+
45+
/* Sidebar / Header */
46+
--header-bg: var(--highlight);
47+
--sidebar-bg: var(--highlight);
48+
--sidebar-link-hover-bg: var(--off-white);
49+
--sidebar-active-link-bg: var(--primary-light);
50+
}
51+
52+
[data-theme='dark'] {
53+
/* COLOR VARIABLES ========================== */
54+
55+
/* Global Styles: backgrounds, text */
56+
--site-bg: var(--off-black);
57+
--standard-white: var(--off-black);
58+
--standard-black: var(--off-white);
59+
--standard-text: var(--primary);
60+
61+
/* Sidebar / Header */
62+
--header-bg: var(--primary-extra-dark);
63+
--sidebar-bg: var(--primary-extra-dark);
64+
--sidebar-link-hover-bg: var(--accent);
65+
--sidebar-active-link-bg: var(--accent);
1366
}

src/css/header.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,20 @@
1515
.header-title {
1616
margin: 0;
1717
flex-grow: 1;
18+
font-weight: 500;
1819
}
1920

2021
.header-right-btns {
2122
display: flex;
2223
flex-direction: row;
2324
gap: 1.75rem;
25+
align-items: center;
2426
}
2527

2628
.profile-btn,
2729
.register-btn {
2830
cursor: pointer;
2931
font-size: 1.25rem;
30-
font-weight: bold;
3132
padding: 0.35rem 1rem;
3233
border-radius: 0.7rem;
3334
display: flex;

src/css/index.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
/* ================================================= */
66
:root {
7-
font-family: Helvetica, Arial, sans-serif;
7+
font-family: var(--site-font);
88
line-height: 1.5;
99
font-weight: 400;
1010
color-scheme: light dark;
@@ -32,6 +32,7 @@ body {
3232

3333
h1 {
3434
color: var(--standard-text);
35+
font-weight: 500;
3536
}
3637

3738
/* ================================================= */

src/css/sidebar.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@
9090

9191
.sidebar-link-label {
9292
font-size: 1rem;
93-
font-weight: bold;
9493
max-width: 200px;
9594
overflow: hidden;
9695
white-space: nowrap;

0 commit comments

Comments
 (0)