Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@
--radius: 0.5rem;
}

* { @apply border-border; }
body { @apply bg-background text-foreground; }
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 7%;
--card-foreground: 210 40% 98%;
--primary: 142.1 70% 45%;
--primary-foreground: 144.9 80.4% 10%;
--secondary: 217.2 91.2% 59.8%;
--muted: 222.2 47% 11%;
--muted-foreground: 215 20.2% 65.1%;
--border: 217.2 32.6% 17.5%;
}

* {
@apply border-border;
}

body {
@apply bg-background text-foreground;
}
}
18 changes: 6 additions & 12 deletions src/components/providers.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
"use client";

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState } from "react";
import { ThemeProvider } from "@/components/ui/theme-provider";

export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(
() => new QueryClient({
defaultOptions: {
queries: { staleTime: 30_000, retry: 2 },
},
})
);
const queryClient = new QueryClient();

export function Providers({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</ThemeProvider>
);
}
14 changes: 9 additions & 5 deletions src/components/ui/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
LayoutDashboard, Users, CreditCard, Vote, Landmark, BarChart3, Settings,
} from "lucide-react";
import { clsx } from "clsx";
import { ThemeToggle } from "@/components/ui/theme-toggle";

const navItems = [
{ href: "/dashboard", label: "Dashboard", icon: LayoutDashboard },
Expand Down Expand Up @@ -57,11 +58,14 @@ export function Sidebar() {
})}
</nav>

{/* Stellar indicator */}
<div className="px-4 py-3 border-t border-gray-100">
<div className="flex items-center gap-2 text-xs text-gray-400">
<span className="w-2 h-2 rounded-full bg-green-400 animate-pulse" />
<span>Stellar Testnet</span>
{/* Stellar indicator + Theme toggle */}
<div className="px-4 py-3 border-t border-gray-100 dark:border-gray-800">
<div className="flex items-center justify-between text-xs text-gray-400 dark:text-gray-500">
<div className="flex items-center gap-2">
<span className="w-2 h-2 rounded-full bg-green-400 animate-pulse" />
<span>Stellar Testnet</span>
</div>
<ThemeToggle />
</div>
</div>
</aside>
Expand Down
8 changes: 8 additions & 0 deletions src/components/ui/theme-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"use client";

import { ThemeProvider as NextThemesProvider } from "next-themes";
import type { ThemeProviderProps } from "next-themes/dist/types";

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}
43 changes: 43 additions & 0 deletions src/components/ui/theme-toggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"use client";

import * as React from "react";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes";

export function ThemeToggle() {
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = React.useState(false);

React.useEffect(() => {
setMounted(true);
}, []);

if (!mounted) {
return (
<button className="w-8 h-8 flex items-center justify-center rounded-md opacity-0" aria-label="Toggle theme">
<Sun className="w-4 h-4" />
</button>
);
}

const isDark = theme === "dark";

return (
<button
onClick={() => setTheme(isDark ? "light" : "dark")}
className="w-8 h-8 flex items-center justify-center rounded-md hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
aria-label="Toggle theme"
>
<Sun
className={`w-4 h-4 transition-all duration-300 ${
isDark ? "rotate-90 scale-0 opacity-0" : "rotate-0 scale-100 opacity-100"
} absolute`}
/>
<Moon
className={`w-4 h-4 transition-all duration-300 ${
isDark ? "rotate-0 scale-100 opacity-100" : "-rotate-90 scale-0 opacity-0"
} absolute`}
/>
</button>
);
}