Spaces:
Sleeping
Sleeping
Merge pull request #2 from jasonkneen/feature/3-theme-colors
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",
|