Skip to content

Commit

Permalink
feat: Settings page ui
Browse files Browse the repository at this point in the history
  • Loading branch information
NriotHrreion committed Aug 7, 2024
1 parent 9430af2 commit c12da4f
Show file tree
Hide file tree
Showing 8 changed files with 421 additions and 25 deletions.
3 changes: 3 additions & 0 deletions app/(pages)/explorer/viewer/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -27,6 +28,8 @@ export default function Page({ searchParams }: {
explorer.setCurrentViewing(file);
}, []);

useDetectCookie();

if(!ViewerComponent) {
toast.error("暂不支持打开此类型的文件");

Expand Down
104 changes: 103 additions & 1 deletion app/(pages)/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className={cn("w-[800px] min-h-0 mx-auto mb-9 px-5 py-5 overflow-y-auto flex flex-col gap-10", scrollbarStyle)}>
<SettingsSection title="通用">
<SettingsItem label="文件批量上传数量上限">
<Select
className="w-48"
selectionMode="single"
defaultSelectedKeys={["infinite"]}
aria-label="文件批量上传数量上限">
<SelectItem key="infinite" aria-label="无限">无限</SelectItem>
{
new Array(6).fill(0).map((_value, index) => {
const n = (5 * (index + 1)).toString()

return (
<SelectItem key={n} aria-label={n}>{n}</SelectItem>
);
}) as any
}
</Select>
</SettingsItem>
<SettingsItem label="Ace Editor 自动换行" description="文本编辑器自动换行">
<Switch />
</SettingsItem>
<SettingsItem label="Ace Editor 代码提示" description="文本编辑器代码提示与自动填充">
<Switch />
</SettingsItem>
<SettingsItem label="Ace Editor 代码高亮(暂不支持)" description="文本编辑器自动识别代码语言并高亮代码">
<Switch isDisabled/>
</SettingsItem>
</SettingsSection>

<SettingsSection title="视图">
<SettingsItem label="文件管理器默认视图">
<Select
className="w-48"
selectionMode="single"
defaultSelectedKeys={["list"]}
aria-label="文件管理器默认视图">
<SelectItem
key="list"
startContent={<List size={17}/>}
aria-label="列表视图">列表视图</SelectItem>
<SelectItem
key="grid"
startContent={<LayoutGrid size={17}/>}
aria-label="网格视图">网格视图</SelectItem>
</Select>
</SettingsItem>
<SettingsItem label="网格图片瀑布流" description="在网格视图下,开启图片文件缩略图预览(可能消耗性能)">
<Switch />
</SettingsItem>
</SettingsSection>

<SettingsSection title="外观">
<SettingsItem label="深色 / 浅色模式">
<ThemeSwitch />
</SettingsItem>
<SettingsItem label="Ace Editor 主题" description="文本编辑器外观主题">
<Select
className="w-48"
selectionMode="single"
defaultSelectedKeys={["ambiance"]}
aria-label="Ace Editor 主题">
<SelectItem key="ambiance" aria-label="ambiance">Ambiance</SelectItem>
</Select>
</SettingsItem>
</SettingsSection>

<SettingsSection title="安全">
<SettingsItem label="设置访问密码">
<Button color="primary">开始设置</Button>
</SettingsItem>
<SettingsItem label="登出 Ferrum" description="退出Ferrum 并清除token信息">
<Button color="danger" onClick={() => handleLogout()}>
登出
<LogOut size={15}/>
</Button>
</SettingsItem>
</SettingsSection>
</div>
);
}
24 changes: 3 additions & 21 deletions components/nav.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
"use client";

import React, { useState } from "react";
import Cookies from "js-cookie";
import {
Navbar,
NavbarBrand,
NavbarContent,
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<NavPage | null>(() => {
switch(pathname) {
Expand All @@ -38,12 +32,6 @@ const Nav: React.FC = () => {
}
});

const handleLogout = () => {
Cookies.remove(tokenStorageKey);
toast.success("登出成功");
router.refresh();
};

return (
<Navbar
classNames={{
Expand Down Expand Up @@ -90,13 +78,7 @@ const Nav: React.FC = () => {
</NavbarContent>
<NavbarContent justify="end">
<NavbarItem>
<ThemeSwitch />
</NavbarItem>
<NavbarItem>
<Button color="primary" size="sm" onClick={() => handleLogout()}>
登出
<LogOut size={15}/>
</Button>
{page !== "settings" && <ThemeSwitch />}
</NavbarItem>
</NavbarContent>
</Navbar>
Expand Down
23 changes: 23 additions & 0 deletions components/settings/settings-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use client";

import React, { type PropsWithChildren } from "react";

interface SettingsItemProps extends PropsWithChildren {
label: string
description?: string
}

const SettingsItem: React.FC<SettingsItemProps> = (props) => {
return (
<div className="flex justify-between items-center">
<div className="flex flex-col gap-1" aria-label={props.label}>
<span>{props.label}</span>
{props.description && <span className="text-sm text-default-500" aria-label={props.description}>{props.description}</span>}
</div>

{props.children}
</div>
);
}

export default SettingsItem;
22 changes: 22 additions & 0 deletions components/settings/settings-section.tsx
Original file line number Diff line number Diff line change
@@ -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<SettingsSectionProps> = (props) => {
return (
<section className="flex flex-col gap-4">
<h2 className="px-3 text-2xl font-bold">{props.title}</h2>

<Card className="px-6 py-4 flex flex-col gap-5 dark:bg-[#111]">
{props.children}
</Card>
</section>
);
}

export default SettingsSection;
4 changes: 1 addition & 3 deletions components/theme-switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ const ThemeSwitch: React.FC<ThemeSwitchProps> = ({ size }) => {
const [mouted, setMouted] = useState<boolean>(false);

const handleSwitchTheme = (value: boolean) => {
value
? setTheme("light")
: setTheme("dark");
setTheme(value ? "light" : "dark");
};

useEffect(() => {
Expand Down
Loading

0 comments on commit c12da4f

Please sign in to comment.