@@ -57,7 +57,7 @@ bun run dev
|
||||
**Tech Related**
|
||||
|
||||
- [ ] Dark Mode
|
||||
- [ ] Dockerize
|
||||
- [x] Dockerize
|
||||
- [ ] Authentication
|
||||
|
||||
### Tech Stack
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"drizzle-orm": "^0.33.0",
|
||||
"lucide-react": "^0.428.0",
|
||||
"next": "14.2.5",
|
||||
"next-themes": "^0.3.0",
|
||||
"pg": "^8.12.0",
|
||||
"qs": "^6.13.0",
|
||||
"react": "^18",
|
||||
|
||||
@@ -7,6 +7,14 @@ import { cn } from "@/lib/utils";
|
||||
import { useRouter } from "next/router";
|
||||
import { Badge } from "../ui/badge";
|
||||
import { ENV } from "@/config/environment";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
import dynamic from "next/dynamic";
|
||||
import Image from "next/image";
|
||||
|
||||
const ThemeSwitcher = dynamic(() => import("@/components/shared/ThemeSwitcher"), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
export default function Sidebar() {
|
||||
const router = useRouter();
|
||||
@@ -15,15 +23,18 @@ export default function Sidebar() {
|
||||
return (
|
||||
<div className="hidden border-r bg-muted/40 md:block max-h-screen min-h-screen">
|
||||
<div className="flex h-full max-h-screen flex-col gap-2">
|
||||
<div className="flex h-14 items-center border-b px-4 lg:h-[60px] lg:px-6">
|
||||
<Link href="/" className="flex items-center gap-2 font-semibold">
|
||||
<img
|
||||
<div className="flex h-14 items-center justify-between border-b px-4 lg:h-[60px] lg:px-6">
|
||||
<Link href="/" className="flex items-center gap-2 font-semibold">
|
||||
<Image
|
||||
src="/favicon.png"
|
||||
width={32}
|
||||
height={32}
|
||||
alt="Immich Power Tools"
|
||||
className="w-8 h-8"
|
||||
/>
|
||||
<span className="">Immich Power Tools</span>
|
||||
</Link>
|
||||
<ThemeSwitcher />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<nav className="grid items-start px-2 text-sm font-medium lg:px-4">
|
||||
@@ -50,20 +61,25 @@ export default function Sidebar() {
|
||||
</nav>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex flex-col gap-1 text-xs text-center py-2">
|
||||
<p className="text-gray-800 font-mono">Connected to</p>
|
||||
<div className="flex flex-col gap-1 text-xs text-center py-2">
|
||||
<p className="text-muted-foreground font-mono">Connected to</p>
|
||||
<Link href={ENV.IMMICH_URL} target="_blank" className="font-mono">
|
||||
{ENV.IMMICH_URL}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="border text-gray-700 text-xs text-center py-2">
|
||||
|
||||
<p>
|
||||
Made with <span className="text-red-500">♥</span> by <Link target="_blank" href="https://x.com/zathvarun" className="text-primary">@zathvarun</Link>
|
||||
</p>
|
||||
<div className="border text-muted-foreground text-xs text-center py-2">
|
||||
<p>
|
||||
Made with <span className="text-red-500">♥</span> by{" "}
|
||||
<Link
|
||||
target="_blank"
|
||||
href="https://x.com/zathvarun"
|
||||
className="text-primary"
|
||||
>
|
||||
@zathvarun
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from "react";
|
||||
import { Button } from "../ui/button";
|
||||
import { useTheme } from "next-themes";
|
||||
import { Moon, Sun } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export default function ThemeSwitcher() {
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
const toggleTheme = () => {
|
||||
setTheme(theme === "light" ? "dark" : "light");
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={toggleTheme}
|
||||
className={cn(
|
||||
"p-1 rounded-md rounded-full transition-all duration-300 border border-primary text-primary",
|
||||
)}
|
||||
>
|
||||
{theme === "light" ? <Moon size={10} /> : <Sun size={10} />}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -14,7 +14,7 @@ const buttonVariants = cva(
|
||||
destructive:
|
||||
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
||||
outline:
|
||||
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
||||
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground dark:bg-secondary dark:border-secondary dark:text-secondary-foreground",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
|
||||
+3
-1
@@ -1,7 +1,9 @@
|
||||
import RootLayout from "@/components/layouts/RootLayout";
|
||||
import "@/styles/globals.scss";
|
||||
import type { AppProps } from "next/app";
|
||||
import { ThemeProvider } from 'next-themes'
|
||||
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
return <RootLayout><Component {...pageProps} /></RootLayout>
|
||||
return <ThemeProvider attribute="class" storageKey = 'theme'><RootLayout><Component {...pageProps} /></RootLayout></ThemeProvider>
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
--chart-3: 197 37% 24%;
|
||||
--chart-4: 43 74% 66%;
|
||||
--chart-5: 27 87% 67%;
|
||||
|
||||
}
|
||||
|
||||
.dark {
|
||||
|
||||
Reference in New Issue
Block a user