Spaces:
Running
Running
Jason Kneen
commited on
Commit
·
9ca7165
1
Parent(s):
e87a324
3 theme modes (light, sunset, dark)
Browse files- .gitignore +3 -1
- app/globals.css +98 -1
- app/providers.tsx +2 -1
- components/theme-toggle.tsx +33 -13
- lib/context/mcp-context.tsx +2 -1
- package-lock.json +0 -0
- package.json +1 -0
.gitignore
CHANGED
@@ -38,4 +38,6 @@ yarn-error.log*
|
|
38 |
|
39 |
# typescript
|
40 |
*.tsbuildinfo
|
41 |
-
next-env.d.ts
|
|
|
|
|
|
38 |
|
39 |
# typescript
|
40 |
*.tsbuildinfo
|
41 |
+
next-env.d.ts
|
42 |
+
.env
|
43 |
+
CLAUDE.md
|
app/globals.css
CHANGED
@@ -3,6 +3,8 @@
|
|
3 |
@plugin "tailwindcss-animate";
|
4 |
|
5 |
@custom-variant dark (&:is(.dark *));
|
|
|
|
|
6 |
|
7 |
:root {
|
8 |
--background: oklch(0.99 0.01 56.32);
|
@@ -98,6 +100,100 @@
|
|
98 |
--shadow-2xl: 0px 6px 12px -3px hsl(0 0% 0% / 0.22);
|
99 |
}
|
100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
@theme inline {
|
102 |
--color-background: var(--background);
|
103 |
--color-foreground: var(--foreground);
|
@@ -170,6 +266,7 @@
|
|
170 |
/* Hide scrollbar for IE, Edge and Firefox */
|
171 |
.no-scrollbar {
|
172 |
-ms-overflow-style: none; /* IE and Edge */
|
173 |
-
|
|
|
174 |
}
|
175 |
}
|
|
|
3 |
@plugin "tailwindcss-animate";
|
4 |
|
5 |
@custom-variant dark (&:is(.dark *));
|
6 |
+
@custom-variant sunset (&:is(.sunset *));
|
7 |
+
@custom-variant black (&:is(.black *));
|
8 |
|
9 |
:root {
|
10 |
--background: oklch(0.99 0.01 56.32);
|
|
|
100 |
--shadow-2xl: 0px 6px 12px -3px hsl(0 0% 0% / 0.22);
|
101 |
}
|
102 |
|
103 |
+
.sunset {
|
104 |
+
--background: oklch(0.98 0.03 80.00);
|
105 |
+
--foreground: oklch(0.34 0.01 2.77);
|
106 |
+
--card: oklch(1.00 0 0);
|
107 |
+
--card-foreground: oklch(0.34 0.01 2.77);
|
108 |
+
--popover: oklch(1.00 0 0);
|
109 |
+
--popover-foreground: oklch(0.34 0.01 2.77);
|
110 |
+
--primary: oklch(0.65 0.26 34.00);
|
111 |
+
--primary-foreground: oklch(1.00 0 0);
|
112 |
+
--secondary: oklch(0.96 0.05 60.00);
|
113 |
+
--secondary-foreground: oklch(0.56 0.13 32.74);
|
114 |
+
--muted: oklch(0.97 0.02 39.40);
|
115 |
+
--muted-foreground: oklch(0.49 0.05 26.45);
|
116 |
+
--accent: oklch(0.83 0.22 50.00);
|
117 |
+
--accent-foreground: oklch(0.34 0.01 2.77);
|
118 |
+
--destructive: oklch(0.61 0.21 22.24);
|
119 |
+
--destructive-foreground: oklch(1.00 0 0);
|
120 |
+
--border: oklch(0.93 0.06 60.00);
|
121 |
+
--input: oklch(0.93 0.06 60.00);
|
122 |
+
--ring: oklch(0.65 0.26 34.00);
|
123 |
+
--chart-1: oklch(0.65 0.26 34.00);
|
124 |
+
--chart-2: oklch(0.83 0.22 50.00);
|
125 |
+
--chart-3: oklch(0.88 0.15 54.93);
|
126 |
+
--chart-4: oklch(0.82 0.20 40.89);
|
127 |
+
--chart-5: oklch(0.64 0.18 32.07);
|
128 |
+
--sidebar: oklch(0.97 0.04 70.00);
|
129 |
+
--sidebar-foreground: oklch(0.34 0.01 2.77);
|
130 |
+
--sidebar-primary: oklch(0.65 0.26 34.00);
|
131 |
+
--sidebar-primary-foreground: oklch(1.00 0 0);
|
132 |
+
--sidebar-accent: oklch(0.83 0.22 50.00);
|
133 |
+
--sidebar-accent-foreground: oklch(0.34 0.01 2.77);
|
134 |
+
--sidebar-border: oklch(0.93 0.06 60.00);
|
135 |
+
--sidebar-ring: oklch(0.65 0.26 34.00);
|
136 |
+
--font-sans: Montserrat, sans-serif;
|
137 |
+
--font-serif: Merriweather, serif;
|
138 |
+
--font-mono: Ubuntu Mono, monospace;
|
139 |
+
--radius: 0.625rem;
|
140 |
+
--shadow-2xs: 0px 6px 12px -3px hsl(0 0% 0% / 0.04);
|
141 |
+
--shadow-xs: 0px 6px 12px -3px hsl(0 0% 0% / 0.04);
|
142 |
+
--shadow-sm: 0px 6px 12px -3px hsl(0 0% 0% / 0.09), 0px 1px 2px -4px hsl(0 0% 0% / 0.09);
|
143 |
+
--shadow: 0px 6px 12px -3px hsl(0 0% 0% / 0.09), 0px 1px 2px -4px hsl(0 0% 0% / 0.09);
|
144 |
+
--shadow-md: 0px 6px 12px -3px hsl(0 0% 0% / 0.09), 0px 2px 4px -4px hsl(0 0% 0% / 0.09);
|
145 |
+
--shadow-lg: 0px 6px 12px -3px hsl(0 0% 0% / 0.09), 0px 4px 6px -4px hsl(0 0% 0% / 0.09);
|
146 |
+
--shadow-xl: 0px 6px 12px -3px hsl(0 0% 0% / 0.09), 0px 8px 10px -4px hsl(0 0% 0% / 0.09);
|
147 |
+
--shadow-2xl: 0px 6px 12px -3px hsl(0 0% 0% / 0.22);
|
148 |
+
}
|
149 |
+
|
150 |
+
.black {
|
151 |
+
--background: oklch(0.15 0.01 350.00);
|
152 |
+
--foreground: oklch(0.95 0.01 60.00);
|
153 |
+
--card: oklch(0.20 0.01 340.00);
|
154 |
+
--card-foreground: oklch(0.95 0.01 60.00);
|
155 |
+
--popover: oklch(0.20 0.01 340.00);
|
156 |
+
--popover-foreground: oklch(0.95 0.01 60.00);
|
157 |
+
--primary: oklch(0.45 0.10 35.00);
|
158 |
+
--primary-foreground: oklch(1.00 0 0);
|
159 |
+
--secondary: oklch(0.25 0.01 340.00);
|
160 |
+
--secondary-foreground: oklch(0.95 0.01 60.00);
|
161 |
+
--muted: oklch(0.22 0.01 340.00);
|
162 |
+
--muted-foreground: oklch(0.86 0.01 60.00);
|
163 |
+
--accent: oklch(0.70 0.09 58.00);
|
164 |
+
--accent-foreground: oklch(0.15 0.01 350.00);
|
165 |
+
--destructive: oklch(0.45 0.16 20.00);
|
166 |
+
--destructive-foreground: oklch(1.00 0 0);
|
167 |
+
--border: oklch(0.25 0.01 340.00);
|
168 |
+
--input: oklch(0.25 0.01 340.00);
|
169 |
+
--ring: oklch(0.45 0.10 35.00);
|
170 |
+
--chart-1: oklch(0.45 0.10 35.00);
|
171 |
+
--chart-2: oklch(0.70 0.09 58.00);
|
172 |
+
--chart-3: oklch(0.80 0.06 54.00);
|
173 |
+
--chart-4: oklch(0.75 0.08 40.00);
|
174 |
+
--chart-5: oklch(0.55 0.10 32.00);
|
175 |
+
--sidebar: oklch(0.15 0.01 350.00);
|
176 |
+
--sidebar-foreground: oklch(0.95 0.01 60.00);
|
177 |
+
--sidebar-primary: oklch(0.40 0.06 34.00);
|
178 |
+
--sidebar-primary-foreground: oklch(1.00 0 0);
|
179 |
+
--sidebar-accent: oklch(0.60 0.07 56.00);
|
180 |
+
--sidebar-accent-foreground: oklch(0.15 0.01 350.00);
|
181 |
+
--sidebar-border: oklch(0.25 0.01 340.00);
|
182 |
+
--sidebar-ring: oklch(0.45 0.10 35.00);
|
183 |
+
--font-sans: Montserrat, sans-serif;
|
184 |
+
--font-serif: Merriweather, serif;
|
185 |
+
--font-mono: Ubuntu Mono, monospace;
|
186 |
+
--radius: 0.625rem;
|
187 |
+
--shadow-2xs: 0px 6px 12px -3px hsl(0 0% 0% / 0.04);
|
188 |
+
--shadow-xs: 0px 6px 12px -3px hsl(0 0% 0% / 0.04);
|
189 |
+
--shadow-sm: 0px 6px 12px -3px hsl(0 0% 0% / 0.09), 0px 1px 2px -4px hsl(0 0% 0% / 0.09);
|
190 |
+
--shadow: 0px 6px 12px -3px hsl(0 0% 0% / 0.09), 0px 1px 2px -4px hsl(0 0% 0% / 0.09);
|
191 |
+
--shadow-md: 0px 6px 12px -3px hsl(0 0% 0% / 0.09), 0px 2px 4px -4px hsl(0 0% 0% / 0.09);
|
192 |
+
--shadow-lg: 0px 6px 12px -3px hsl(0 0% 0% / 0.09), 0px 4px 6px -4px hsl(0 0% 0% / 0.09);
|
193 |
+
--shadow-xl: 0px 6px 12px -3px hsl(0 0% 0% / 0.09), 0px 8px 10px -4px hsl(0 0% 0% / 0.09);
|
194 |
+
--shadow-2xl: 0px 6px 12px -3px hsl(0 0% 0% / 0.22);
|
195 |
+
}
|
196 |
+
|
197 |
@theme inline {
|
198 |
--color-background: var(--background);
|
199 |
--color-foreground: var(--foreground);
|
|
|
266 |
/* Hide scrollbar for IE, Edge and Firefox */
|
267 |
.no-scrollbar {
|
268 |
-ms-overflow-style: none; /* IE and Edge */
|
269 |
+
/* Use Firefox-specific scrollbar hiding when supported */
|
270 |
+
scrollbar-width: none;
|
271 |
}
|
272 |
}
|
app/providers.tsx
CHANGED
@@ -30,8 +30,9 @@ export function Providers({ children }: { children: ReactNode }) {
|
|
30 |
<ThemeProvider
|
31 |
attribute="class"
|
32 |
defaultTheme="system"
|
33 |
-
enableSystem
|
34 |
disableTransitionOnChange
|
|
|
35 |
>
|
36 |
<MCPProvider>
|
37 |
<SidebarProvider defaultOpen={sidebarOpen} open={sidebarOpen} onOpenChange={setSidebarOpen}>
|
|
|
30 |
<ThemeProvider
|
31 |
attribute="class"
|
32 |
defaultTheme="system"
|
33 |
+
enableSystem={true}
|
34 |
disableTransitionOnChange
|
35 |
+
themes={["light", "dark", "sunset", "black"]}
|
36 |
>
|
37 |
<MCPProvider>
|
38 |
<SidebarProvider defaultOpen={sidebarOpen} open={sidebarOpen} onOpenChange={setSidebarOpen}>
|
components/theme-toggle.tsx
CHANGED
@@ -1,24 +1,44 @@
|
|
1 |
"use client"
|
2 |
|
3 |
import * as React from "react"
|
4 |
-
import {
|
5 |
import { useTheme } from "next-themes"
|
6 |
import { Button } from "./ui/button"
|
|
|
|
|
7 |
|
8 |
export function ThemeToggle({ className, ...props }: React.ComponentProps<typeof Button>) {
|
9 |
const { theme, setTheme } = useTheme()
|
10 |
|
11 |
return (
|
12 |
-
<
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
)
|
24 |
-
}
|
|
|
1 |
"use client"
|
2 |
|
3 |
import * as React from "react"
|
4 |
+
import { CircleDashed, Flame, Sun } from "lucide-react"
|
5 |
import { useTheme } from "next-themes"
|
6 |
import { Button } from "./ui/button"
|
7 |
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "./ui/dropdown-menu"
|
8 |
+
import { cn } from "@/lib/utils"
|
9 |
|
10 |
export function ThemeToggle({ className, ...props }: React.ComponentProps<typeof Button>) {
|
11 |
const { theme, setTheme } = useTheme()
|
12 |
|
13 |
return (
|
14 |
+
<DropdownMenu>
|
15 |
+
<DropdownMenuTrigger asChild={true}>
|
16 |
+
<Button
|
17 |
+
variant="ghost"
|
18 |
+
size="icon"
|
19 |
+
className={cn(`rounded-md h-8 w-8`, className)}
|
20 |
+
{...props}
|
21 |
+
>
|
22 |
+
<Flame className="h-4 w-4 rotate-0 scale-100 transition-all light:scale-0 light:-rotate-90 black:scale-0 black:-rotate-90 hover:text-sidebar-accent" />
|
23 |
+
<Sun className="absolute h-4 w-4 rotate-90 scale-0 transition-all light:rotate-0 light:scale-100 black:scale-0 black:rotate-0 hover:text-sidebar-accent" />
|
24 |
+
<CircleDashed className="absolute h-4 w-4 rotate-90 scale-0 transition-all black:rotate-0 black:scale-100 light:scale-0 light:rotate-0 hover:text-sidebar-accent" />
|
25 |
+
<span className="sr-only">Toggle theme</span>
|
26 |
+
</Button>
|
27 |
+
</DropdownMenuTrigger>
|
28 |
+
<DropdownMenuContent align="end">
|
29 |
+
<DropdownMenuItem onSelect={() => setTheme("dark")}>
|
30 |
+
<Flame className="mr-2 h-4 w-4" />
|
31 |
+
<span>Sunset</span>
|
32 |
+
</DropdownMenuItem>
|
33 |
+
<DropdownMenuItem onSelect={() => setTheme("light")}>
|
34 |
+
<Sun className="mr-2 h-4 w-4" />
|
35 |
+
<span>Light</span>
|
36 |
+
</DropdownMenuItem>
|
37 |
+
<DropdownMenuItem onSelect={() => setTheme("black")}>
|
38 |
+
<CircleDashed className="mr-2 h-4 w-4" />
|
39 |
+
<span>Dark</span>
|
40 |
+
</DropdownMenuItem>
|
41 |
+
</DropdownMenuContent>
|
42 |
+
</DropdownMenu>
|
43 |
)
|
44 |
+
}
|
lib/context/mcp-context.tsx
CHANGED
@@ -42,7 +42,8 @@ interface MCPContextType {
|
|
42 |
|
43 |
const MCPContext = createContext<MCPContextType | undefined>(undefined);
|
44 |
|
45 |
-
export function MCPProvider(
|
|
|
46 |
const [mcpServers, setMcpServers] = useLocalStorage<MCPServer[]>(
|
47 |
STORAGE_KEYS.MCP_SERVERS,
|
48 |
[]
|
|
|
42 |
|
43 |
const MCPContext = createContext<MCPContextType | undefined>(undefined);
|
44 |
|
45 |
+
export function MCPProvider(props: { children: React.ReactNode }) {
|
46 |
+
const { children } = props;
|
47 |
const [mcpServers, setMcpServers] = useLocalStorage<MCPServer[]>(
|
48 |
STORAGE_KEYS.MCP_SERVERS,
|
49 |
[]
|
package-lock.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
package.json
CHANGED
@@ -53,6 +53,7 @@
|
|
53 |
"next": "^15.3.1",
|
54 |
"next-auth": "^4.24.11",
|
55 |
"next-themes": "^0.4.6",
|
|
|
56 |
"pg": "^8.14.1",
|
57 |
"react": "^19.1.0",
|
58 |
"react-dom": "^19.1.0",
|
|
|
53 |
"next": "^15.3.1",
|
54 |
"next-auth": "^4.24.11",
|
55 |
"next-themes": "^0.4.6",
|
56 |
+
"or": "^0.2.0",
|
57 |
"pg": "^8.14.1",
|
58 |
"react": "^19.1.0",
|
59 |
"react-dom": "^19.1.0",
|