From 654f6f77ea640e4e4cffe1d17eecd872b6f1e81e Mon Sep 17 00:00:00 2001 From: thomasabishop Date: Mon, 28 Jul 2025 18:05:37 +0100 Subject: [PATCH] feat: add dark theme and toggle --- package-lock.json | 115 ++++++++++++++ package.json | 2 + src/components/EntriesListSidebar.tsx | 118 +++++++------- src/components/TagListSidebar.tsx | 2 +- src/components/ThemeToggle.tsx | 28 ++++ src/components/ui/label.tsx | 22 +++ src/components/ui/switch.tsx | 29 ++++ src/containers/AppSidebar.tsx | 12 +- src/containers/RecentEdits.tsx | 104 ++++++------ src/containers/Settings.tsx | 8 + src/context/ThemeProvider.tsx | 72 +++++++++ src/index.css | 218 +++++++++++++------------- src/pages/Settings.tsx | 6 + src/pages/home.tsx | 112 ++++++------- src/templates/Entry.tsx | 1 - src/templates/Main.tsx | 5 +- src/templates/Page.tsx | 2 +- 17 files changed, 575 insertions(+), 281 deletions(-) create mode 100644 src/components/ThemeToggle.tsx create mode 100644 src/components/ui/label.tsx create mode 100644 src/components/ui/switch.tsx create mode 100644 src/containers/Settings.tsx create mode 100644 src/context/ThemeProvider.tsx create mode 100644 src/pages/Settings.tsx diff --git a/package-lock.json b/package-lock.json index e5110f0..3bbcef1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,10 @@ "@radix-ui/react-collapsible": "^1.1.7", "@radix-ui/react-dialog": "^1.1.10", "@radix-ui/react-hover-card": "^1.1.14", + "@radix-ui/react-label": "^2.1.7", "@radix-ui/react-separator": "^1.1.4", "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.5", "@radix-ui/react-tooltip": "^1.2.3", "@tailwindcss/vite": "^4.1.4", "@tanstack/react-query": "^5.83.0", @@ -1426,6 +1428,52 @@ } } }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.4.tgz", @@ -1584,6 +1632,58 @@ } } }, + "node_modules/@radix-ui/react-switch": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.5.tgz", + "integrity": "sha512-5ijLkak6ZMylXsaImpZ8u4Rlf5grRmoc0p0QeX9VJtlrM4f5m3nCTX8tWga/zOA8PZYIR/t0p2Mnvd7InrJ6yQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-tooltip": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.3.tgz", @@ -1715,6 +1815,21 @@ } } }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-rect": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", diff --git a/package.json b/package.json index 89568a3..941f7da 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,10 @@ "@radix-ui/react-collapsible": "^1.1.7", "@radix-ui/react-dialog": "^1.1.10", "@radix-ui/react-hover-card": "^1.1.14", + "@radix-ui/react-label": "^2.1.7", "@radix-ui/react-separator": "^1.1.4", "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.5", "@radix-ui/react-tooltip": "^1.2.3", "@tailwindcss/vite": "^4.1.4", "@tanstack/react-query": "^5.83.0", diff --git a/src/components/EntriesListSidebar.tsx b/src/components/EntriesListSidebar.tsx index 79ec828..7e10e7d 100644 --- a/src/components/EntriesListSidebar.tsx +++ b/src/components/EntriesListSidebar.tsx @@ -10,68 +10,68 @@ import { Link } from "react-router" import { useState, useRef, useEffect } from "react" export default function EntriesListSidebar() { - const scrollRef = useRef(null) - const [isOpen, setIsOpen] = useState(() => { - if (typeof window !== "undefined") { - const saved = sessionStorage.getItem("entries_list_sidebar_open") - return saved ? JSON.parse(saved) : false - } - return false - }) + const scrollRef = useRef(null) + const [isOpen, setIsOpen] = useState(() => { + if (typeof window !== "undefined") { + const saved = sessionStorage.getItem("entries_list_sidebar_open") + return saved ? JSON.parse(saved) : false + } + return false + }) - const { data: entries, isLoading } = useQuery({ - queryKey: ["entries_list"], - queryFn: () => api.get("/entries").then((res) => res.data), - }) + const { data: entries, isLoading } = useQuery({ + queryKey: ["entries_list"], + queryFn: () => api.get("/entries").then((res) => res.data), + }) - useEffect(() => { - sessionStorage.setItem("entries_list_sidebar_open", JSON.stringify(isOpen)) - }, [isOpen]) + useEffect(() => { + sessionStorage.setItem("entries_list_sidebar_open", JSON.stringify(isOpen)) + }, [isOpen]) - useEffect(() => { - const savedScroll = sessionStorage.getItem("entries_list_sidebar_scroll_position") - if (savedScroll && scrollRef.current) { - scrollRef.current.scrollTop = parseInt(savedScroll) - } - }, [entries]) + useEffect(() => { + const savedScroll = sessionStorage.getItem("entries_list_sidebar_scroll_position") + if (savedScroll && scrollRef.current) { + scrollRef.current.scrollTop = parseInt(savedScroll) + } + }, [entries]) - const handleScroll = () => { - if (scrollRef.current) { - sessionStorage.setItem("entries_list_sidebar_scroll_position", scrollRef.current.scrollTop) - } - } + const handleScroll = () => { + if (scrollRef.current) { + sessionStorage.setItem("entries_list_sidebar_scroll_position", scrollRef.current.scrollTop) + } + } - return ( - - - - - - - Entries - - {entries?.count} - - - - - - -
- - {entries?.data.map((item, i) => ( - - - - {item.title.replace(/_/g, " ")} - - - - ))} - -
-
-
-
- ) + return ( + + + + + + + Entries + + {entries?.count} + + + + + + +
+ + {entries?.data.map((item, i) => ( + + + + {item.title.replace(/_/g, " ")} + + + + ))} + +
+
+
+
+ ) } diff --git a/src/components/TagListSidebar.tsx b/src/components/TagListSidebar.tsx index c0c5384..d4c2b7d 100644 --- a/src/components/TagListSidebar.tsx +++ b/src/components/TagListSidebar.tsx @@ -62,7 +62,7 @@ export default function TagListSidebar() { {tags?.data.map((item, i) => ( - + {item} diff --git a/src/components/ThemeToggle.tsx b/src/components/ThemeToggle.tsx new file mode 100644 index 0000000..1d7a766 --- /dev/null +++ b/src/components/ThemeToggle.tsx @@ -0,0 +1,28 @@ +import { useState } from "react" +import { Label } from "@/components/ui/label" +import { Switch } from "@/components/ui/switch" +import { useTheme } from "@/context/ThemeProvider" + +export default function ThemeToggle() { + const { theme, setTheme } = useTheme() + + const [darkMode, setDarkMode] = useState(false) + const handleToggle = (checked) => { + setTheme(theme === "dark" ? "light" : "dark") + } + + console.log(darkMode) + return ( +
+

Theme

+ +

+ The theme is set automatically to your system default. You can change this below. +

+
+ + +
+
+ ) +} diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx new file mode 100644 index 0000000..ef7133a --- /dev/null +++ b/src/components/ui/label.tsx @@ -0,0 +1,22 @@ +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" + +import { cn } from "@/lib/utils" + +function Label({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Label } diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch.tsx new file mode 100644 index 0000000..b0363e3 --- /dev/null +++ b/src/components/ui/switch.tsx @@ -0,0 +1,29 @@ +import * as React from "react" +import * as SwitchPrimitive from "@radix-ui/react-switch" + +import { cn } from "@/lib/utils" + +function Switch({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +export { Switch } diff --git a/src/containers/AppSidebar.tsx b/src/containers/AppSidebar.tsx index cdc96f2..88c1731 100644 --- a/src/containers/AppSidebar.tsx +++ b/src/containers/AppSidebar.tsx @@ -24,7 +24,7 @@ const footerMenu = [ { title: "Settings", - url: "#", + url: "/settings", icon: Settings, }, ] @@ -75,10 +75,18 @@ export function AppSidebar() { {footerMenu.map((item) => ( - + + + {item.title} + + + {/* + {item.title} + +*/} ))} diff --git a/src/containers/RecentEdits.tsx b/src/containers/RecentEdits.tsx index 9039244..1d68faa 100644 --- a/src/containers/RecentEdits.tsx +++ b/src/containers/RecentEdits.tsx @@ -4,61 +4,61 @@ import api from "../api/eolas-api" import { Link } from "react-router" const columns = [ - { - accessorKey: "title", - header: "Title", - cell: ({ cell, row }) => { - return ( - - - {row.original.title} - - - ) - }, - }, - { - accessorKey: "date", - header: "Date", - }, - { - accessorKey: "time", - header: "Time", - }, + { + accessorKey: "title", + header: "Title", + cell: ({ cell, row }) => { + return ( + + + {row.original.title} + + + ) + }, + }, + { + accessorKey: "date", + header: "Date", + }, + { + accessorKey: "time", + header: "Time", + }, ] export default function RecentEdits() { - const { data, isLoading } = useQuery({ - queryKey: ["entries_recent"], - queryFn: () => api.get("/entries?limit=20&sort=date").then((res) => res.data), - }) + const { data, isLoading } = useQuery({ + queryKey: ["entries_recent"], + queryFn: () => api.get("/entries?limit=20&sort=date").then((res) => res.data), + }) - console.log(data) - const parsed = data?.data?.map((entry) => { - const [date, time] = entry?.last_modified?.split(" ") - return { - title: entry.title.replace(/_/g, " "), - date: new Date(date).toLocaleString("en-GB", { - day: "numeric", - month: "long", - year: "numeric", - }), - time: time, - } - }) + console.log(data) + const parsed = data?.data?.map((entry) => { + const [date, time] = entry?.last_modified?.split(" ") + return { + title: entry.title.replace(/_/g, " "), + date: new Date(date).toLocaleString("en-GB", { + day: "numeric", + month: "long", + year: "numeric", + }), + time: time, + } + }) - return ( - <> -
-
-

Recent edits

-
-
-
- -
-
-
- - ) + return ( + <> +
+
+

Recent edits

+
+
+
+ +
+
+
+ + ) } diff --git a/src/containers/Settings.tsx b/src/containers/Settings.tsx new file mode 100644 index 0000000..594e431 --- /dev/null +++ b/src/containers/Settings.tsx @@ -0,0 +1,8 @@ +import ThemeToggle from "@/components/ThemeToggle" +export default function Settings() { + return ( +
+ +
+ ) +} diff --git a/src/context/ThemeProvider.tsx b/src/context/ThemeProvider.tsx new file mode 100644 index 0000000..a491d79 --- /dev/null +++ b/src/context/ThemeProvider.tsx @@ -0,0 +1,72 @@ +import * as React from "react" +import { createContext, useContext, useEffect, useState } from "react" + +type Theme = "dark" | "light" | "system" + +type ThemeProviderProps = { + children: React.ReactNode + defaultTheme?: Theme + storageKey?: string +} + +type ThemeProviderState = { + theme: Theme + setTheme: (theme: Theme) => void +} + +const initialState: ThemeProviderState = { + theme: "system", + setTheme: () => null, +} + +const ThemeProviderContext = createContext(initialState) + +export function ThemeProvider({ + children, + defaultTheme = "system", + storageKey = "vite-ui-theme", + ...props +}: ThemeProviderProps) { + const [theme, setTheme] = useState( + () => (localStorage.getItem(storageKey) as Theme) || defaultTheme, + ) + + useEffect(() => { + const root = window.document.documentElement + + root.classList.remove("light", "dark") + + if (theme === "system") { + const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches + ? "dark" + : "light" + + root.classList.add(systemTheme) + return + } + + root.classList.add(theme) + }, [theme]) + + const value = { + theme, + setTheme: (theme: Theme) => { + localStorage.setItem(storageKey, theme) + setTheme(theme) + }, + } + + return ( + + {children} + + ) +} + +export const useTheme = () => { + const context = useContext(ThemeProviderContext) + + if (context === undefined) throw new Error("useTheme must be used within a ThemeProvider") + + return context +} diff --git a/src/index.css b/src/index.css index 3c0b1a9..6618ff7 100644 --- a/src/index.css +++ b/src/index.css @@ -4,120 +4,124 @@ @custom-variant dark (&:is(.dark *)); @theme inline { - --radius-sm: calc(var(--radius) - 4px); - --radius-md: calc(var(--radius) - 2px); - --radius-lg: var(--radius); - --radius-xl: calc(var(--radius) + 4px); - --color-background: var(--background); - --color-foreground: var(--foreground); - --color-card: var(--card); - --color-card-foreground: var(--card-foreground); - --color-popover: var(--popover); - --color-popover-foreground: var(--popover-foreground); - --color-primary: var(--primary); - --color-primary-foreground: var(--primary-foreground); - --color-secondary: var(--secondary); - --color-secondary-foreground: var(--secondary-foreground); - --color-muted: var(--muted); - --color-muted-foreground: var(--muted-foreground); - --color-accent: var(--accent); - --color-accent-foreground: var(--accent-foreground); - --color-destructive: var(--destructive); - --color-border: var(--border); - --color-input: var(--input); - --color-ring: var(--ring); - --color-chart-1: var(--chart-1); - --color-chart-2: var(--chart-2); - --color-chart-3: var(--chart-3); - --color-chart-4: var(--chart-4); - --color-chart-5: var(--chart-5); - --color-sidebar: var(--sidebar); - --color-sidebar-foreground: var(--sidebar-foreground); - --color-sidebar-primary: var(--sidebar-primary); - --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); - --color-sidebar-accent: var(--sidebar-accent); - --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); - --color-sidebar-border: var(--sidebar-border); - --color-sidebar-ring: var(--sidebar-ring); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); } :root { - --radius: 0.625rem; - --background: oklch(1 0 0); - --foreground: oklch(0.145 0 0); - --card: oklch(1 0 0); - --card-foreground: oklch(0.145 0 0); - --popover: oklch(1 0 0); - --popover-foreground: oklch(0.145 0 0); - --primary: oklch(0.205 0 0); - --primary-foreground: oklch(0.985 0 0); - --secondary: oklch(0.97 0 0); - --secondary-foreground: oklch(0.205 0 0); - --muted: oklch(0.97 0 0); - --muted-foreground: oklch(0.556 0 0); - --accent: oklch(0.97 0 0); - --accent-foreground: oklch(0.205 0 0); - --destructive: oklch(0.577 0.245 27.325); - --border: oklch(0.922 0 0); - --input: oklch(0.922 0 0); - --ring: oklch(0.708 0 0); - --chart-1: oklch(0.646 0.222 41.116); - --chart-2: oklch(0.6 0.118 184.704); - --chart-3: oklch(0.398 0.07 227.392); - --chart-4: oklch(0.828 0.189 84.429); - --chart-5: oklch(0.769 0.188 70.08); - --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.145 0 0); - --sidebar-primary: oklch(0.205 0 0); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.97 0 0); - --sidebar-accent-foreground: oklch(0.205 0 0); - --sidebar-border: oklch(0.922 0 0); - --sidebar-ring: oklch(0.708 0 0); + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); + color-scheme: light; } .dark { - --background: oklch(0.145 0 0); - --foreground: oklch(0.985 0 0); - --card: oklch(0.205 0 0); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.205 0 0); - --popover-foreground: oklch(0.985 0 0); - --primary: oklch(0.922 0 0); - --primary-foreground: oklch(0.205 0 0); - --secondary: oklch(0.269 0 0); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.269 0 0); - --muted-foreground: oklch(0.708 0 0); - --accent: oklch(0.269 0 0); - --accent-foreground: oklch(0.985 0 0); - --destructive: oklch(0.704 0.191 22.216); - --border: oklch(1 0 0 / 10%); - --input: oklch(1 0 0 / 15%); - --ring: oklch(0.556 0 0); - --chart-1: oklch(0.488 0.243 264.376); - --chart-2: oklch(0.696 0.17 162.48); - --chart-3: oklch(0.769 0.188 70.08); - --chart-4: oklch(0.627 0.265 303.9); - --chart-5: oklch(0.645 0.246 16.439); - --sidebar: oklch(0.205 0 0); - --sidebar-foreground: oklch(0.985 0 0); - --sidebar-primary: oklch(0.488 0.243 264.376); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.269 0 0); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(1 0 0 / 10%); - --sidebar-ring: oklch(0.556 0 0); + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.205 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.205 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.556 0 0); + color-scheme: dark; } @layer base { - * { - @apply border-border outline-ring/50; - } - html { - font-family: "Inter", sans-serif; - } - body { - @apply bg-background text-foreground; - } + * { + @apply border-border outline-ring/50; + } + + html { + font-family: "Inter", sans-serif; + } + + body { + @apply bg-background text-foreground; + } } diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx new file mode 100644 index 0000000..f1cd341 --- /dev/null +++ b/src/pages/Settings.tsx @@ -0,0 +1,6 @@ +import Page from "@/templates/Page" +import { default as SettingsContainer } from "@/containers/Settings" + +export default function Settings() { + return } /> +} diff --git a/src/pages/home.tsx b/src/pages/home.tsx index dbdcba0..3314108 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -4,55 +4,55 @@ import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/h import { Button } from "@/components/ui/button" export default function Home() { - return ( - <> -
-
-
-
-
-
-

Welcome

-
-
-

- - - - - -

-
-

🇮🇪

-

- Irish for "knowledge", especially knowledge gained - through practical experience. -

-
-
- - - is{" "} - - my - {" "} - technical knowledge management system, or "second-brain", comprising - notes from the study of software engineering and computer science. -

-
-
-
+ return ( + <> +
+
+
+
+
+
+

Welcome

+
+
+

+ + + + + +

+
+

🇮🇪

+

+ Irish for "knowledge", especially knowledge gained + through practical experience. +

+
+
+ + + is{" "} + + my + {" "} + technical knowledge management system, or "second-brain", comprising + notes from the study of software engineering and computer science. +

+
+
+
- {/* + {/*

@@ -74,12 +74,12 @@ I'm */} -

- -
-
-
-
- - ) +
+ +
+
+
+
+ + ) } diff --git a/src/templates/Entry.tsx b/src/templates/Entry.tsx index bd70fd8..0943dab 100644 --- a/src/templates/Entry.tsx +++ b/src/templates/Entry.tsx @@ -1,4 +1,3 @@ -import Main from "@/templates/Main" import { useParams } from "react-router" import Page from "./Page" export default function Entry() { diff --git a/src/templates/Main.tsx b/src/templates/Main.tsx index 407efdf..6919fbf 100644 --- a/src/templates/Main.tsx +++ b/src/templates/Main.tsx @@ -1,10 +1,11 @@ import AppHeader from "@/components/AppHeader" import { AppSidebar } from "@/containers/AppSidebar" import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar" +import { ThemeProvider } from "@/context/ThemeProvider" export default function Main({ children, pageTitle }) { return ( - <> + @@ -12,6 +13,6 @@ export default function Main({ children, pageTitle }) {
{children}
- +
) } diff --git a/src/templates/Page.tsx b/src/templates/Page.tsx index 7f4bc02..f084b6a 100644 --- a/src/templates/Page.tsx +++ b/src/templates/Page.tsx @@ -6,7 +6,7 @@ export default function Page({ pageTitle = null, pageBody = null, titleComponent
-
+

{titleComponent ? titleComponent : {pageTitle}}