mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-18 21:19:44 +00:00
feat: add workspace setting section
This commit is contained in:
parent
61568840d3
commit
afbf935a71
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
38
web/src/components/setting/AccountSection.tsx
Normal file
38
web/src/components/setting/AccountSection.tsx
Normal 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;
|
32
web/src/components/setting/WorkspaceSection.tsx
Normal file
32
web/src/components/setting/WorkspaceSection.tsx
Normal 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;
|
@ -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
17
web/src/pages/Setting.tsx
Normal 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;
|
@ -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();
|
||||||
|
1
web/src/types/modules/system.d.ts
vendored
1
web/src/types/modules/system.d.ts
vendored
@ -5,4 +5,5 @@ interface Profile {
|
|||||||
|
|
||||||
interface SystemStatus {
|
interface SystemStatus {
|
||||||
profile: Profile;
|
profile: Profile;
|
||||||
|
disallowSignUp: boolean;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user