feat: add workspace setting section

This commit is contained in:
Steven 2023-06-23 22:46:35 +08:00
parent 61568840d3
commit afbf935a71
8 changed files with 101 additions and 6 deletions

View File

@ -7,7 +7,7 @@ function App() {
return ( return (
<CssVarsProvider> <CssVarsProvider>
<RouterProvider router={router} /> <RouterProvider router={router} />
<Toaster position="top-right" /> <Toaster position="top-center" />
</CssVarsProvider> </CssVarsProvider>
); );
} }

View File

@ -32,10 +32,10 @@ const Header: React.FC = () => {
actions={ actions={
<> <>
<Link <Link
to="/account" to="/setting"
className="w-full flex flex-row justify-start items-center px-3 leading-10 text-left cursor-pointer rounded whitespace-nowrap hover:bg-gray-100" className="w-full flex flex-row justify-start items-center px-3 leading-10 text-left cursor-pointer rounded whitespace-nowrap hover:bg-gray-100"
> >
<Icon.User className="w-4 h-auto mr-2" /> My Account <Icon.Settings className="w-4 h-auto mr-2" /> Setting
</Link> </Link>
<button <button
className="w-full flex flex-row justify-start items-center px-3 leading-10 text-left cursor-pointer rounded whitespace-nowrap hover:bg-gray-100" className="w-full flex flex-row justify-start items-center px-3 leading-10 text-left cursor-pointer rounded whitespace-nowrap hover:bg-gray-100"

View File

@ -0,0 +1,38 @@
import { Button } from "@mui/joy";
import { useState } from "react";
import { useAppSelector } from "../../stores";
import ChangePasswordDialog from "../ChangePasswordDialog";
import EditUserinfoDialog from "../EditUserinfoDialog";
const AccountSection: React.FC = () => {
const user = useAppSelector((state) => state.user).user as User;
const [showEditUserinfoDialog, setShowEditUserinfoDialog] = useState<boolean>(false);
const [showChangePasswordDialog, setShowChangePasswordDialog] = useState<boolean>(false);
return (
<>
<div className="mx-auto max-w-4xl w-full px-3 py-6 flex flex-col justify-start items-start space-y-4">
<p className="text-gray-400">Account</p>
<p className="text-3xl my-2">{user.nickname}</p>
<p className="leading-8 flex flex-row justify-start items-center">
<span className="mr-3 text-gray-500 font-mono">Email: </span>
{user.email}
</p>
<div className="flex flex-row justify-start items-center gap-2">
<Button variant="outlined" color="neutral" onClick={() => setShowEditUserinfoDialog(true)}>
Edit
</Button>
<Button variant="outlined" color="neutral" onClick={() => setShowChangePasswordDialog(true)}>
Change password
</Button>
</div>
</div>
{showEditUserinfoDialog && <EditUserinfoDialog onClose={() => setShowEditUserinfoDialog(false)} />}
{showChangePasswordDialog && <ChangePasswordDialog onClose={() => setShowChangePasswordDialog(false)} />}
</>
);
};
export default AccountSection;

View File

@ -0,0 +1,32 @@
import { Switch } from "@mui/joy";
import { useEffect, useState } from "react";
import { getSystemStatus, upsertWorkspaceSetting } from "../../helpers/api";
const WorkspaceSection: React.FC = () => {
const [disallowSignUp, setDisallowSignUp] = useState<boolean>(false);
useEffect(() => {
getSystemStatus().then(({ data }) => {
setDisallowSignUp(data.disallowSignUp);
});
}, []);
const handleDisallowSignUpChange = async (value: boolean) => {
await upsertWorkspaceSetting("disallow-signup", JSON.stringify(value));
setDisallowSignUp(value);
};
return (
<>
<div className="mx-auto max-w-4xl w-full px-3 py-6 flex flex-col justify-start items-start space-y-4">
<p className="text-gray-400">Workspace settings</p>
<div className="w-full flex flex-row justify-between items-center">
<span>Allow sign up</span>
<Switch checked={disallowSignUp} onChange={(event) => handleDisallowSignUpChange(event.target.checked)} />
</div>
</div>
</>
);
};
export default WorkspaceSection;

View File

@ -64,3 +64,10 @@ export function patchShortcut(shortcutPatch: ShortcutPatch) {
export function deleteShortcutById(shortcutId: ShortcutId) { export function deleteShortcutById(shortcutId: ShortcutId) {
return axios.delete(`/api/v1/shortcut/${shortcutId}`); return axios.delete(`/api/v1/shortcut/${shortcutId}`);
} }
export function upsertWorkspaceSetting(key: string, value: string) {
return axios.post(`/api/v1/workspace/setting`, {
key,
value,
});
}

17
web/src/pages/Setting.tsx Normal file
View File

@ -0,0 +1,17 @@
import { useAppSelector } from "../stores";
import AccountSection from "../components/setting/AccountSection";
import WorkspaceSection from "../components/setting/WorkspaceSection";
const Setting: React.FC = () => {
const user = useAppSelector((state) => state.user).user as User;
const isAdmin = user.role === "ADMIN";
return (
<div className="mx-auto max-w-4xl w-full px-3 py-6 flex flex-col justify-start items-start space-y-4">
<AccountSection />
{isAdmin && <WorkspaceSection />}
</div>
);
};
export default Setting;

View File

@ -4,7 +4,7 @@ import { userService } from "../services";
import Root from "../layouts/Root"; import Root from "../layouts/Root";
import Auth from "../pages/Auth"; import Auth from "../pages/Auth";
import Home from "../pages/Home"; import Home from "../pages/Home";
import Account from "../pages/Account"; import Setting from "../pages/Setting";
const router = createBrowserRouter([ const router = createBrowserRouter([
{ {
@ -33,8 +33,8 @@ const router = createBrowserRouter([
}, },
}, },
{ {
path: "/account", path: "/setting",
element: <Account />, element: <Setting />,
loader: async () => { loader: async () => {
try { try {
await userService.initialState(); await userService.initialState();

View File

@ -5,4 +5,5 @@ interface Profile {
interface SystemStatus { interface SystemStatus {
profile: Profile; profile: Profile;
disallowSignUp: boolean;
} }