diff --git a/app/(pages)/explorer/viewer/page.tsx b/app/(pages)/explorer/viewer/page.tsx index b5ff066..9ddb40b 100644 --- a/app/(pages)/explorer/viewer/page.tsx +++ b/app/(pages)/explorer/viewer/page.tsx @@ -8,6 +8,7 @@ import { concatPath } from "@/lib/utils"; import { diskStorageKey } from "@/lib/global"; import { storage } from "@/lib/storage"; import { getViewer } from "@/lib/viewers"; +import { useDetectCookie } from "@/hooks/useDetectCookie"; export default function Page({ searchParams }: { searchParams: { @@ -27,6 +28,8 @@ export default function Page({ searchParams }: { explorer.setCurrentViewing(file); }, []); + useDetectCookie(); + if(!ViewerComponent) { toast.error("暂不支持打开此类型的文件"); diff --git a/app/(pages)/settings/page.tsx b/app/(pages)/settings/page.tsx index c083561..53a8608 100644 --- a/app/(pages)/settings/page.tsx +++ b/app/(pages)/settings/page.tsx @@ -1,15 +1,117 @@ "use client"; import { useEffect } from "react"; +import { useRouter } from "next/navigation"; +import { cn } from "@nextui-org/theme"; +import { Button } from "@nextui-org/button"; +import { Switch } from "@nextui-org/switch"; +import { Select, SelectItem } from "@nextui-org/select"; +import Cookies from "js-cookie"; +import { toast } from "react-toastify"; +import { List, LayoutGrid, LogOut } from "lucide-react"; import { useDetectCookie } from "@/hooks/useDetectCookie"; +import SettingsSection from "@/components/settings/settings-section"; +import SettingsItem from "@/components/settings/settings-item"; +import ThemeSwitch from "@/components/theme-switch"; +import { tokenStorageKey } from "@/lib/global"; +import { scrollbarStyle } from "@/lib/style"; export default function Page() { + const router = useRouter(); + + const handleLogout = () => { + Cookies.remove(tokenStorageKey); + toast.success("登出成功"); + router.refresh(); + }; + useEffect(() => { document.title = "Ferrum - 设置"; }, []); useDetectCookie(); - return <>; + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); } diff --git a/components/nav.tsx b/components/nav.tsx index 664fffd..d27bb36 100644 --- a/components/nav.tsx +++ b/components/nav.tsx @@ -1,7 +1,6 @@ "use client"; import React, { useState } from "react"; -import Cookies from "js-cookie"; import { Navbar, NavbarBrand, @@ -9,20 +8,15 @@ import { NavbarItem } from "@nextui-org/navbar"; import { Image } from "@nextui-org/image"; -import { Button } from "@nextui-org/button"; import Link from "next/link"; -import { LogOut, Gauge, Folders, Settings2 } from "lucide-react"; -import { usePathname, useRouter } from "next/navigation"; -import { toast } from "react-toastify"; +import { Gauge, Folders, Settings2 } from "lucide-react"; +import { usePathname } from "next/navigation"; import ThemeSwitch from "./theme-switch"; -import { tokenStorageKey } from "@/lib/global"; - type NavPage = "dashboard" | "explorer" | "settings"; const Nav: React.FC = () => { - const router = useRouter(); const pathname = usePathname(); const [page, setPage] = useState(() => { switch(pathname) { @@ -38,12 +32,6 @@ const Nav: React.FC = () => { } }); - const handleLogout = () => { - Cookies.remove(tokenStorageKey); - toast.success("登出成功"); - router.refresh(); - }; - return ( { - - - - + {page !== "settings" && } diff --git a/components/settings/settings-item.tsx b/components/settings/settings-item.tsx new file mode 100644 index 0000000..ab2f025 --- /dev/null +++ b/components/settings/settings-item.tsx @@ -0,0 +1,23 @@ +"use client"; + +import React, { type PropsWithChildren } from "react"; + +interface SettingsItemProps extends PropsWithChildren { + label: string + description?: string +} + +const SettingsItem: React.FC = (props) => { + return ( +
+
+ {props.label} + {props.description && {props.description}} +
+ + {props.children} +
+ ); +} + +export default SettingsItem; diff --git a/components/settings/settings-section.tsx b/components/settings/settings-section.tsx new file mode 100644 index 0000000..5d5a9bf --- /dev/null +++ b/components/settings/settings-section.tsx @@ -0,0 +1,22 @@ +"use client"; + +import React, { type PropsWithChildren } from "react"; +import { Card } from "@nextui-org/card"; + +interface SettingsSectionProps extends PropsWithChildren { + title: string +} + +const SettingsSection: React.FC = (props) => { + return ( +
+

{props.title}

+ + + {props.children} + +
+ ); +} + +export default SettingsSection; diff --git a/components/theme-switch.tsx b/components/theme-switch.tsx index ba8d551..6f523f0 100644 --- a/components/theme-switch.tsx +++ b/components/theme-switch.tsx @@ -14,9 +14,7 @@ const ThemeSwitch: React.FC = ({ size }) => { const [mouted, setMouted] = useState(false); const handleSwitchTheme = (value: boolean) => { - value - ? setTheme("light") - : setTheme("dark"); + setTheme(value ? "light" : "dark"); }; useEffect(() => { diff --git a/package-lock.json b/package-lock.json index e99c782..cca3762 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "@nextui-org/navbar": "2.0.33", "@nextui-org/progress": "^2.0.33", "@nextui-org/scroll-shadow": "^2.1.19", + "@nextui-org/select": "^2.2.5", "@nextui-org/skeleton": "^2.0.29", "@nextui-org/snippet": "2.0.38", "@nextui-org/switch": "2.0.31", @@ -1743,6 +1744,174 @@ "react-dom": ">=18" } }, + "node_modules/@nextui-org/select": { + "version": "2.2.5", + "resolved": "https://registry.npmmirror.com/@nextui-org/select/-/select-2.2.5.tgz", + "integrity": "sha512-Il1eigjSXOBgJ745nhn6TDPD1jj1avrnvk9WV/DCjOsFRwfstRnDzsS1aNpZKHqJgHhFRQZ1ivz8hA4x3Zgasg==", + "dependencies": { + "@nextui-org/aria-utils": "2.0.24", + "@nextui-org/listbox": "2.1.25", + "@nextui-org/popover": "2.1.27", + "@nextui-org/react-utils": "2.0.16", + "@nextui-org/scroll-shadow": "2.1.19", + "@nextui-org/shared-icons": "2.0.9", + "@nextui-org/shared-utils": "2.0.7", + "@nextui-org/spinner": "2.0.33", + "@nextui-org/use-aria-button": "2.0.10", + "@nextui-org/use-aria-multiselect": "2.2.3", + "@nextui-org/use-safe-layout-effect": "2.0.6", + "@react-aria/focus": "3.17.1", + "@react-aria/form": "3.0.5", + "@react-aria/interactions": "3.21.3", + "@react-aria/utils": "3.24.1", + "@react-aria/visually-hidden": "3.8.12", + "@react-types/shared": "3.23.1" + }, + "peerDependencies": { + "@nextui-org/system": ">=2.0.0", + "@nextui-org/theme": ">=2.1.0", + "framer-motion": ">=10.17.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@nextui-org/select/node_modules/@nextui-org/listbox": { + "version": "2.1.25", + "resolved": "https://registry.npmmirror.com/@nextui-org/listbox/-/listbox-2.1.25.tgz", + "integrity": "sha512-WJqxhzPxADLIsenREaaoQ44bs3gQx5yqOvK86Jkiv/m9nXr0YuxZOJEsVa5GenkmyJBrEd6LkBV5cZ1TGNzbJw==", + "dependencies": { + "@nextui-org/aria-utils": "2.0.24", + "@nextui-org/divider": "2.0.31", + "@nextui-org/react-utils": "2.0.16", + "@nextui-org/shared-utils": "2.0.7", + "@nextui-org/use-is-mobile": "2.0.9", + "@react-aria/focus": "3.17.1", + "@react-aria/interactions": "3.21.3", + "@react-aria/listbox": "3.12.1", + "@react-aria/utils": "3.24.1", + "@react-stately/list": "3.10.5", + "@react-types/menu": "3.9.9", + "@react-types/shared": "3.23.1" + }, + "peerDependencies": { + "@nextui-org/system": ">=2.0.0", + "@nextui-org/theme": ">=2.1.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@nextui-org/select/node_modules/@nextui-org/spinner": { + "version": "2.0.33", + "resolved": "https://registry.npmmirror.com/@nextui-org/spinner/-/spinner-2.0.33.tgz", + "integrity": "sha512-c1wW4YEbzdn0t1MJAXhJ2W0PuNxrxtZg2DVqJeqh3180y4iQPYDzEy7oFoU0FpK53LcBPxjfsKHNL6v1pn+60A==", + "dependencies": { + "@nextui-org/react-utils": "2.0.16", + "@nextui-org/shared-utils": "2.0.7", + "@nextui-org/system-rsc": "2.1.5" + }, + "peerDependencies": { + "@nextui-org/theme": ">=2.1.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@nextui-org/select/node_modules/@nextui-org/system-rsc": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nextui-org/system-rsc/-/system-rsc-2.1.5.tgz", + "integrity": "sha512-tkJLAyJu34Rr5KUMMqoB7cZjOVXB+7a/7N4ushZfuiLdoYijgmcXFMzLxjm+tbt9zA5AV+ivsfbHvscg77dJ6w==", + "dependencies": { + "@react-types/shared": "3.23.1", + "clsx": "^1.2.1" + }, + "peerDependencies": { + "@nextui-org/theme": ">=2.1.0", + "react": ">=18" + } + }, + "node_modules/@nextui-org/select/node_modules/@nextui-org/use-aria-button": { + "version": "2.0.10", + "resolved": "https://registry.npmmirror.com/@nextui-org/use-aria-button/-/use-aria-button-2.0.10.tgz", + "integrity": "sha512-tUpp4QMr1zugKPevyToeRHIufTuc/g+67/r/oQLRTG0mMo3yGVmggykQuYn22fqqZPpW6nHcB9VYc+XtZZ27TQ==", + "dependencies": { + "@react-aria/focus": "3.17.1", + "@react-aria/interactions": "3.21.3", + "@react-aria/utils": "3.24.1", + "@react-types/button": "3.9.4", + "@react-types/shared": "3.23.1" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@nextui-org/select/node_modules/@nextui-org/use-is-mobile": { + "version": "2.0.9", + "resolved": "https://registry.npmmirror.com/@nextui-org/use-is-mobile/-/use-is-mobile-2.0.9.tgz", + "integrity": "sha512-u5pRmPV0wacdpOcAkQnWwE30yNBl2uk1WvbWkrSELxIVRN22+fTIYn8ynnHK0JbJFTA6/5zh7uIfETQu3L6KjA==", + "dependencies": { + "@react-aria/ssr": "3.9.4" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@nextui-org/select/node_modules/@react-aria/form": { + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/@react-aria/form/-/form-3.0.5.tgz", + "integrity": "sha512-n290jRwrrRXO3fS82MyWR+OKN7yznVesy5Q10IclSTVYHHI3VI53xtAPr/WzNjJR1um8aLhOcDNFKwnNIUUCsQ==", + "dependencies": { + "@react-aria/interactions": "^3.21.3", + "@react-aria/utils": "^3.24.1", + "@react-stately/form": "^3.0.3", + "@react-types/shared": "^3.23.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@nextui-org/select/node_modules/@react-aria/listbox": { + "version": "3.12.1", + "resolved": "https://registry.npmmirror.com/@react-aria/listbox/-/listbox-3.12.1.tgz", + "integrity": "sha512-7JiUp0NGykbv/HgSpmTY1wqhuf/RmjFxs1HZcNaTv8A+DlzgJYc7yQqFjP3ZA/z5RvJFuuIxggIYmgIFjaRYdA==", + "dependencies": { + "@react-aria/interactions": "^3.21.3", + "@react-aria/label": "^3.7.8", + "@react-aria/selection": "^3.18.1", + "@react-aria/utils": "^3.24.1", + "@react-stately/collections": "^3.10.7", + "@react-stately/list": "^3.10.5", + "@react-types/listbox": "^3.4.9", + "@react-types/shared": "^3.23.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@nextui-org/select/node_modules/@react-stately/list": { + "version": "3.10.5", + "resolved": "https://registry.npmmirror.com/@react-stately/list/-/list-3.10.5.tgz", + "integrity": "sha512-fV9plO+6QDHiewsYIhboxcDhF17GO95xepC5ki0bKXo44gr14g/LSo/BMmsaMnV+1BuGdBunB05bO4QOIaigXA==", + "dependencies": { + "@react-stately/collections": "^3.10.7", + "@react-stately/selection": "^3.15.1", + "@react-stately/utils": "^3.10.1", + "@react-types/shared": "^3.23.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@nextui-org/select/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, "node_modules/@nextui-org/shared-icons": { "version": "2.0.9", "resolved": "https://registry.npmmirror.com/@nextui-org/shared-icons/-/shared-icons-2.0.9.tgz", @@ -2281,6 +2450,91 @@ "react-dom": ">=18" } }, + "node_modules/@nextui-org/use-aria-multiselect": { + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/@nextui-org/use-aria-multiselect/-/use-aria-multiselect-2.2.3.tgz", + "integrity": "sha512-VeRoyyUUVgJ7DrdfzU6onjohHxJfG7bmwpIfQyurMzvTZcmcVUGTnddAnRPVEoOro68tTAj4IuPs/4xkf1aXxg==", + "dependencies": { + "@react-aria/i18n": "3.11.1", + "@react-aria/interactions": "3.21.3", + "@react-aria/label": "3.7.8", + "@react-aria/listbox": "3.12.1", + "@react-aria/menu": "3.14.1", + "@react-aria/selection": "3.18.1", + "@react-aria/utils": "3.24.1", + "@react-stately/form": "3.0.3", + "@react-stately/list": "3.10.5", + "@react-stately/menu": "3.7.1", + "@react-types/button": "3.9.4", + "@react-types/overlays": "3.8.7", + "@react-types/select": "3.9.4", + "@react-types/shared": "3.23.1" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@nextui-org/use-aria-multiselect/node_modules/@react-aria/label": { + "version": "3.7.8", + "resolved": "https://registry.npmmirror.com/@react-aria/label/-/label-3.7.8.tgz", + "integrity": "sha512-MzgTm5+suPA3KX7Ug6ZBK2NX9cin/RFLsv1BdafJ6CZpmUSpWnGE/yQfYUB7csN7j31OsZrD3/P56eShYWAQfg==", + "dependencies": { + "@react-aria/utils": "^3.24.1", + "@react-types/shared": "^3.23.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@nextui-org/use-aria-multiselect/node_modules/@react-aria/listbox": { + "version": "3.12.1", + "resolved": "https://registry.npmmirror.com/@react-aria/listbox/-/listbox-3.12.1.tgz", + "integrity": "sha512-7JiUp0NGykbv/HgSpmTY1wqhuf/RmjFxs1HZcNaTv8A+DlzgJYc7yQqFjP3ZA/z5RvJFuuIxggIYmgIFjaRYdA==", + "dependencies": { + "@react-aria/interactions": "^3.21.3", + "@react-aria/label": "^3.7.8", + "@react-aria/selection": "^3.18.1", + "@react-aria/utils": "^3.24.1", + "@react-stately/collections": "^3.10.7", + "@react-stately/list": "^3.10.5", + "@react-types/listbox": "^3.4.9", + "@react-types/shared": "^3.23.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@nextui-org/use-aria-multiselect/node_modules/@react-stately/form": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/@react-stately/form/-/form-3.0.3.tgz", + "integrity": "sha512-92YYBvlHEWUGUpXgIaQ48J50jU9XrxfjYIN8BTvvhBHdD63oWgm8DzQnyT/NIAMzdLnhkg7vP+fjG8LjHeyIAg==", + "dependencies": { + "@react-types/shared": "^3.23.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@nextui-org/use-aria-multiselect/node_modules/@react-stately/list": { + "version": "3.10.5", + "resolved": "https://registry.npmmirror.com/@react-stately/list/-/list-3.10.5.tgz", + "integrity": "sha512-fV9plO+6QDHiewsYIhboxcDhF17GO95xepC5ki0bKXo44gr14g/LSo/BMmsaMnV+1BuGdBunB05bO4QOIaigXA==", + "dependencies": { + "@react-stately/collections": "^3.10.7", + "@react-stately/selection": "^3.15.1", + "@react-stately/utils": "^3.10.1", + "@react-types/shared": "^3.23.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, "node_modules/@nextui-org/use-aria-toggle-button": { "version": "2.0.9", "resolved": "https://registry.npmmirror.com/@nextui-org/use-aria-toggle-button/-/use-aria-toggle-button-2.0.9.tgz", @@ -3341,6 +3595,17 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, + "node_modules/@react-types/select": { + "version": "3.9.4", + "resolved": "https://registry.npmmirror.com/@react-types/select/-/select-3.9.4.tgz", + "integrity": "sha512-xI7dnOW2st91fPPcv6hdtrTdcfetYiqZuuVPZ5TRobY7Q10/Zqqe/KqtOw1zFKUj9xqNJe4Ov3xP5GSdcO60Eg==", + "dependencies": { + "@react-types/shared": "^3.23.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, "node_modules/@react-types/shared": { "version": "3.23.1", "resolved": "https://registry.npmmirror.com/@react-types/shared/-/shared-3.23.1.tgz", diff --git a/package.json b/package.json index 8711f75..6a5936a 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@nextui-org/navbar": "2.0.33", "@nextui-org/progress": "^2.0.33", "@nextui-org/scroll-shadow": "^2.1.19", + "@nextui-org/select": "^2.2.5", "@nextui-org/skeleton": "^2.0.29", "@nextui-org/snippet": "2.0.38", "@nextui-org/switch": "2.0.31",