used daisyUI for dark mode
This commit is contained in:
parent
b8b6fe24bc
commit
3afd5fef6e
|
@ -8,6 +8,7 @@ import ProfilePhoto from "./ProfilePhoto";
|
|||
import { faCalendarDays } from "@fortawesome/free-regular-svg-icons";
|
||||
import useModalStore from "@/store/modals";
|
||||
import usePermissions from "@/hooks/usePermissions";
|
||||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
|
||||
type Props = {
|
||||
collection: CollectionIncludingMembersAndLinkCount;
|
||||
|
@ -23,6 +24,7 @@ type DropdownTrigger =
|
|||
|
||||
export default function CollectionCard({ collection, className }: Props) {
|
||||
const { setModal } = useModalStore();
|
||||
const { settings } = useLocalSettingsStore();
|
||||
|
||||
const formattedDate = new Date(collection.createdAt as string).toLocaleString(
|
||||
"en-US",
|
||||
|
@ -42,8 +44,8 @@ export default function CollectionCard({ collection, className }: Props) {
|
|||
<div
|
||||
style={{
|
||||
backgroundImage: `linear-gradient(45deg, ${collection.color}30 10%, ${
|
||||
"dark" ? "#262626" : "#f3f4f6"
|
||||
} 50%, ${"dark" ? "#262626" : "#f9fafb"} 100%)`,
|
||||
settings.theme === "dark" ? "#262626" : "#f3f4f6"
|
||||
} 50%, ${settings.theme === "dark" ? "#262626" : "#f9fafb"} 100%)`,
|
||||
}}
|
||||
className={`border border-solid border-sky-100 dark:border-neutral-700 self-stretch min-h-[12rem] rounded-2xl shadow duration-100 hover:shadow-none hover:opacity-80 group relative ${
|
||||
className || ""
|
||||
|
|
|
@ -12,10 +12,13 @@ import ProfilePhoto from "@/components/ProfilePhoto";
|
|||
import useModalStore from "@/store/modals";
|
||||
import useWindowDimensions from "@/hooks/useWindowDimensions";
|
||||
import ToggleDarkMode from "./ToggleDarkMode";
|
||||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
|
||||
export default function Navbar() {
|
||||
const { setModal } = useModalStore();
|
||||
|
||||
const { settings, updateSettings } = useLocalSettingsStore();
|
||||
|
||||
const { account } = useAccountStore();
|
||||
|
||||
const [profileDropdown, setProfileDropdown] = useState(false);
|
||||
|
@ -26,6 +29,14 @@ export default function Navbar() {
|
|||
|
||||
const { width } = useWindowDimensions();
|
||||
|
||||
const handleToggle = () => {
|
||||
if (settings.theme === "dark") {
|
||||
updateSettings({ theme: "light" });
|
||||
} else {
|
||||
updateSettings({ theme: "dark" });
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setSidebar(false);
|
||||
}, [width]);
|
||||
|
@ -95,9 +106,12 @@ export default function Navbar() {
|
|||
href: "/settings/account",
|
||||
},
|
||||
{
|
||||
name: `Switch to ${"light" ? "Dark" : "Light"}`,
|
||||
name: `Switch to ${
|
||||
settings.theme === "light" ? "Dark" : "Light"
|
||||
}`,
|
||||
onClick: () => {
|
||||
setProfileDropdown(!profileDropdown);
|
||||
handleToggle();
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
type Props = {
|
||||
|
@ -5,9 +6,9 @@ type Props = {
|
|||
};
|
||||
|
||||
export default function ToggleDarkMode({ className }: Props) {
|
||||
const [theme, setTheme] = useState(
|
||||
localStorage.getItem("theme") ? localStorage.getItem("theme") : "light"
|
||||
);
|
||||
const { updateSettings } = useLocalSettingsStore();
|
||||
|
||||
const [theme, setTheme] = useState(localStorage.getItem("theme"));
|
||||
|
||||
const handleToggle = (e: any) => {
|
||||
if (e.target.checked) {
|
||||
|
@ -18,11 +19,7 @@ export default function ToggleDarkMode({ className }: Props) {
|
|||
};
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem("theme", theme || "");
|
||||
const localTheme = localStorage.getItem("theme");
|
||||
document
|
||||
.querySelector("html")
|
||||
?.setAttribute("data-theme", localTheme || "");
|
||||
updateSettings({ theme: theme as string });
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
|
@ -31,7 +28,7 @@ export default function ToggleDarkMode({ className }: Props) {
|
|||
type="checkbox"
|
||||
onChange={handleToggle}
|
||||
className="theme-controller"
|
||||
checked={theme === "light" ? false : true}
|
||||
checked={localStorage.getItem("theme") === "light" ? false : true}
|
||||
/>
|
||||
|
||||
{/* sun icon */}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import React, { ReactNode } from "react";
|
||||
|
@ -8,19 +9,22 @@ interface Props {
|
|||
}
|
||||
|
||||
export default function CenteredForm({ text, children }: Props) {
|
||||
const { settings } = useLocalSettingsStore();
|
||||
return (
|
||||
<div className="absolute top-0 bottom-0 left-0 right-0 flex justify-center items-center p-5">
|
||||
<div className="m-auto flex flex-col gap-2 w-full">
|
||||
{true ? (
|
||||
<Image
|
||||
src={`/linkwarden_${"dark" ? "dark" : "light"}.png`}
|
||||
src={`/linkwarden_${
|
||||
settings.theme === "dark" ? "dark" : "light"
|
||||
}.png`}
|
||||
width={640}
|
||||
height={136}
|
||||
alt="Linkwarden"
|
||||
className="h-12 w-fit mx-auto"
|
||||
/>
|
||||
) : undefined}
|
||||
{/* {theme === "dark" ? (
|
||||
{/* {settings.theme === "dark" ? (
|
||||
<Image
|
||||
src="/linkwarden_dark.png"
|
||||
width={640}
|
||||
|
|
|
@ -6,6 +6,7 @@ import Head from "next/head";
|
|||
import AuthRedirect from "@/layouts/AuthRedirect";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import { Session } from "next-auth";
|
||||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
|
||||
export default function App({
|
||||
Component,
|
||||
|
@ -13,20 +14,10 @@ export default function App({
|
|||
}: AppProps<{
|
||||
session: Session;
|
||||
}>) {
|
||||
const [theme, setTheme] = useState("");
|
||||
const { setSettings } = useLocalSettingsStore();
|
||||
|
||||
useEffect(() => {
|
||||
setTheme(
|
||||
localStorage.getItem("theme")
|
||||
? (localStorage.getItem("theme") as string)
|
||||
: "light"
|
||||
);
|
||||
|
||||
if (theme) localStorage.setItem("theme", theme as string);
|
||||
const localTheme = localStorage.getItem("theme");
|
||||
document
|
||||
.querySelector("html")
|
||||
?.setAttribute("data-theme", localTheme || "");
|
||||
setSettings();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
|
|
@ -18,10 +18,13 @@ import useModalStore from "@/store/modals";
|
|||
import useLinks from "@/hooks/useLinks";
|
||||
import usePermissions from "@/hooks/usePermissions";
|
||||
import NoLinksFound from "@/components/NoLinksFound";
|
||||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
|
||||
export default function Index() {
|
||||
const { setModal } = useModalStore();
|
||||
|
||||
const { settings } = useLocalSettingsStore();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const { links } = useLinkStore();
|
||||
|
@ -51,9 +54,9 @@ export default function Index() {
|
|||
style={{
|
||||
backgroundImage: `linear-gradient(-45deg, ${
|
||||
activeCollection?.color
|
||||
}30 10%, ${"dark" ? "#262626" : "#f3f4f6"} 50%, ${
|
||||
"dark" ? "#262626" : "#f9fafb"
|
||||
} 100%)`,
|
||||
}30 10%, ${
|
||||
settings.theme === "dark" ? "#262626" : "#f3f4f6"
|
||||
} 50%, ${settings.theme === "dark" ? "#262626" : "#f9fafb"} 100%)`,
|
||||
}}
|
||||
className="border border-solid border-sky-100 dark:border-neutral-700 rounded-2xl shadow min-h-[10rem] p-5 flex gap-5 flex-col justify-between"
|
||||
>
|
||||
|
|
|
@ -106,8 +106,6 @@ export default function Dashboard() {
|
|||
|
||||
return (
|
||||
<MainLayout>
|
||||
<button className="btn btn-primary">Primary</button>
|
||||
<button className=" dark:bg-red-500">Primary</button>
|
||||
<div style={{ flex: "1 1 auto" }} className="p-5 flex flex-col gap-5">
|
||||
<div className="flex items-center gap-3">
|
||||
<FontAwesomeIcon
|
||||
|
|
|
@ -16,6 +16,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||
import { faBoxesStacked, faFolder } from "@fortawesome/free-solid-svg-icons";
|
||||
import useModalStore from "@/store/modals";
|
||||
import { useSession } from "next-auth/react";
|
||||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
|
||||
type LinkContent = {
|
||||
title: string;
|
||||
|
@ -33,6 +34,8 @@ export default function Index() {
|
|||
const { links, getLink } = useLinkStore();
|
||||
const { setModal } = useModalStore();
|
||||
|
||||
const { settings } = useLocalSettingsStore();
|
||||
|
||||
const session = useSession();
|
||||
const userId = session.data?.user.id;
|
||||
|
||||
|
@ -144,7 +147,7 @@ export default function Index() {
|
|||
<LinkLayout>
|
||||
<div
|
||||
className={`flex flex-col max-w-screen-md h-full ${
|
||||
"dark" ? "banner-dark-mode" : "banner-light-mode"
|
||||
settings.theme === "dark" ? "banner-dark-mode" : "banner-light-mode"
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
|
|
|
@ -20,6 +20,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||
import { faFilter, faSort } from "@fortawesome/free-solid-svg-icons";
|
||||
import FilterSearchDropdown from "@/components/FilterSearchDropdown";
|
||||
import SortDropdown from "@/components/SortDropdown";
|
||||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
|
||||
const cardVariants: Variants = {
|
||||
offscreen: {
|
||||
|
@ -39,6 +40,8 @@ export default function PublicCollections() {
|
|||
const { links } = useLinkStore();
|
||||
const { modal, setModal } = useModalStore();
|
||||
|
||||
const { settings } = useLocalSettingsStore();
|
||||
|
||||
useEffect(() => {
|
||||
modal
|
||||
? (document.body.style.overflow = "hidden")
|
||||
|
@ -103,8 +106,8 @@ export default function PublicCollections() {
|
|||
className="h-screen"
|
||||
style={{
|
||||
backgroundImage: `linear-gradient(${collection?.color}30 10%, ${
|
||||
"dark" ? "#262626" : "#f3f4f6"
|
||||
} 50%, ${"dark" ? "#171717" : "#ffffff"} 100%)`,
|
||||
settings.theme === "dark" ? "#262626" : "#f3f4f6"
|
||||
} 50%, ${settings.theme === "dark" ? "#171717" : "#ffffff"} 100%)`,
|
||||
}}
|
||||
>
|
||||
<ModalManagement />
|
||||
|
|
|
@ -16,6 +16,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||
import { faBoxesStacked, faFolder } from "@fortawesome/free-solid-svg-icons";
|
||||
import useModalStore from "@/store/modals";
|
||||
import { useSession } from "next-auth/react";
|
||||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
|
||||
type LinkContent = {
|
||||
title: string;
|
||||
|
@ -33,6 +34,8 @@ export default function Index() {
|
|||
const { links, getLink } = useLinkStore();
|
||||
const { setModal } = useModalStore();
|
||||
|
||||
const { settings } = useLocalSettingsStore();
|
||||
|
||||
const session = useSession();
|
||||
const userId = session.data?.user.id;
|
||||
|
||||
|
@ -144,7 +147,7 @@ export default function Index() {
|
|||
<LinkLayout>
|
||||
<div
|
||||
className={`flex flex-col max-w-screen-md h-full ${
|
||||
"dark" ? "banner-dark-mode" : "banner-light-mode"
|
||||
settings.theme === "dark" ? "banner-dark-mode" : "banner-light-mode"
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
|
|
|
@ -13,8 +13,10 @@ import SubmitButton from "@/components/SubmitButton";
|
|||
import React from "react";
|
||||
import Checkbox from "@/components/Checkbox";
|
||||
import LinkPreview from "@/components/LinkPreview";
|
||||
import useLocalSettingsStore from "@/store/localSettings";
|
||||
|
||||
export default function Appearance() {
|
||||
const { settings, updateSettings } = useLocalSettingsStore();
|
||||
const submit = async () => {
|
||||
setSubmitLoader(true);
|
||||
|
||||
|
@ -75,8 +77,11 @@ export default function Appearance() {
|
|||
<div className="flex gap-3 w-full">
|
||||
<div
|
||||
className={`w-full text-center outline-solid outline-sky-100 outline dark:outline-neutral-700 h-40 duration-100 rounded-md flex items-center justify-center cursor-pointer select-none bg-black ${
|
||||
"dark" ? "dark:outline-sky-500 text-sky-500" : "text-white"
|
||||
localStorage.getItem("theme") === "dark"
|
||||
? "dark:outline-sky-500 text-sky-500"
|
||||
: "text-white"
|
||||
}`}
|
||||
onClick={() => updateSettings({ theme: "dark" })}
|
||||
>
|
||||
<FontAwesomeIcon icon={faMoon} className="w-1/2 h-1/2" />
|
||||
<p className="text-2xl">Dark Theme</p>
|
||||
|
@ -85,8 +90,11 @@ export default function Appearance() {
|
|||
</div>
|
||||
<div
|
||||
className={`w-full text-center outline-solid outline-sky-100 outline dark:outline-neutral-700 h-40 duration-100 rounded-md flex items-center justify-center cursor-pointer select-none bg-white ${
|
||||
"light" ? "outline-sky-500 text-sky-500" : "text-black"
|
||||
localStorage.getItem("theme") === "light"
|
||||
? "outline-sky-500 text-sky-500"
|
||||
: "text-black"
|
||||
}`}
|
||||
onClick={() => updateSettings({ theme: "light" })}
|
||||
>
|
||||
<FontAwesomeIcon icon={faSun} className="w-1/2 h-1/2" />
|
||||
<p className="text-2xl">Light Theme</p>
|
||||
|
|
|
@ -1,23 +1,45 @@
|
|||
import { create } from "zustand";
|
||||
|
||||
type LocalSettings = {
|
||||
darkMode: boolean;
|
||||
theme: string;
|
||||
};
|
||||
|
||||
type LocalSettingsStore = {
|
||||
settings: LocalSettings;
|
||||
updateSettings: (settings: LocalSettings) => void;
|
||||
setSettings: () => void;
|
||||
};
|
||||
|
||||
const useLocalSettingsStore = create<LocalSettingsStore>((set) => ({
|
||||
settings: {
|
||||
darkMode: false,
|
||||
theme: "",
|
||||
},
|
||||
updateSettings: async (newSettings) => {
|
||||
if (
|
||||
newSettings.theme &&
|
||||
newSettings.theme !== localStorage.getItem("theme")
|
||||
) {
|
||||
localStorage.setItem("theme", newSettings.theme);
|
||||
|
||||
const localTheme = localStorage.getItem("theme");
|
||||
|
||||
document
|
||||
.querySelector("html")
|
||||
?.setAttribute("data-theme", localTheme || "");
|
||||
}
|
||||
|
||||
set((state) => ({ settings: { ...state.settings, ...newSettings } }));
|
||||
},
|
||||
setSettings: async () => {
|
||||
if (!localStorage.getItem("theme")) {
|
||||
localStorage.setItem("theme", "dark");
|
||||
}
|
||||
|
||||
const localTheme = localStorage.getItem("theme");
|
||||
document
|
||||
.querySelector("html")
|
||||
?.setAttribute("data-theme", localTheme || "");
|
||||
},
|
||||
}));
|
||||
|
||||
export default useLocalSettingsStore;
|
||||
|
||||
// TODO: Add Dark mode.
|
||||
|
|
|
@ -2,8 +2,22 @@
|
|||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--my-color: #fff;
|
||||
/* or any other variables/style */
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
--my-color: #000;
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
--my-color: #ffabc8;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
color-scheme: dark;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
|
@ -140,11 +154,6 @@ body {
|
|||
}
|
||||
|
||||
/* Theme */
|
||||
@layer base {
|
||||
body {
|
||||
@apply dark:bg-neutral-900 bg-white text-black dark:text-white;
|
||||
}
|
||||
}
|
||||
|
||||
/* react-select */
|
||||
@layer components {
|
||||
|
|
|
@ -10,7 +10,7 @@ module.exports = {
|
|||
secondary: "#22d3ee",
|
||||
accent: "#4f46e5",
|
||||
neutral: "#6b7280",
|
||||
"base-100": "#f5f5f4",
|
||||
"base-100": "#ffffff",
|
||||
info: "#a5f3fc",
|
||||
success: "#22c55e",
|
||||
warning: "#facc15",
|
||||
|
@ -23,7 +23,7 @@ module.exports = {
|
|||
secondary: "#0284c7",
|
||||
accent: "#818cf8",
|
||||
neutral: "#1f2937",
|
||||
"base-100": "#fcfcfc",
|
||||
"base-100": "#171717",
|
||||
info: "#009ee4",
|
||||
success: "#00b17d",
|
||||
warning: "#eac700",
|
||||
|
|
Ŝarĝante…
Reference in New Issue