aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/views/admin
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2023-08-02 02:52:07 +0800
committercrupest <crupest@outlook.com>2023-08-02 02:52:07 +0800
commit645a88e7e35d15cec6106709c42b071bec045e0d (patch)
tree8c34d8ac3ba177f725e31b55bdf689a303cfee9a /FrontEnd/src/views/admin
parent0c5c9d51c51d07aecb6f4a01586c81c824141cb2 (diff)
downloadtimeline-645a88e7e35d15cec6106709c42b071bec045e0d.tar.gz
timeline-645a88e7e35d15cec6106709c42b071bec045e0d.tar.bz2
timeline-645a88e7e35d15cec6106709c42b071bec045e0d.zip
...
Diffstat (limited to 'FrontEnd/src/views/admin')
-rw-r--r--FrontEnd/src/views/admin/Admin.tsx27
-rw-r--r--FrontEnd/src/views/admin/AdminNav.tsx29
-rw-r--r--FrontEnd/src/views/admin/MoreAdmin.tsx7
-rw-r--r--FrontEnd/src/views/admin/UserAdmin.tsx304
-rw-r--r--FrontEnd/src/views/admin/index.css33
-rw-r--r--FrontEnd/src/views/admin/index.tsx7
6 files changed, 0 insertions, 407 deletions
diff --git a/FrontEnd/src/views/admin/Admin.tsx b/FrontEnd/src/views/admin/Admin.tsx
deleted file mode 100644
index 986c36b4..00000000
--- a/FrontEnd/src/views/admin/Admin.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Route, Routes } from "react-router-dom";
-import { useTranslation } from "react-i18next";
-
-import AdminNav from "./AdminNav";
-import UserAdmin from "./UserAdmin";
-import MoreAdmin from "./MoreAdmin";
-
-import "./index.css";
-
-const Admin: React.FC = () => {
- useTranslation("admin");
-
- return (
- <>
- <div className="container">
- <AdminNav className="mt-2" />
- <Routes>
- <Route index element={<UserAdmin />} />
- <Route path="user" element={<UserAdmin />} />
- <Route path="more" element={<MoreAdmin />} />
- </Routes>
- </div>
- </>
- );
-};
-
-export default Admin;
diff --git a/FrontEnd/src/views/admin/AdminNav.tsx b/FrontEnd/src/views/admin/AdminNav.tsx
deleted file mode 100644
index b7385e5c..00000000
--- a/FrontEnd/src/views/admin/AdminNav.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { useLocation } from "react-router-dom";
-
-import Tabs from "../common/tab/Tabs";
-
-export function AdminNav({ className }: { className?: string }) {
- const location = useLocation();
- const name = location.pathname.split("/")[2] ?? "user";
-
- return (
- <Tabs
- className={className}
- activeTabName={name}
- tabs={[
- {
- name: "user",
- text: "admin:nav.users",
- link: "/admin/user",
- },
- {
- name: "more",
- text: "admin:nav.more",
- link: "/admin/more",
- },
- ]}
- />
- );
-}
-
-export default AdminNav;
diff --git a/FrontEnd/src/views/admin/MoreAdmin.tsx b/FrontEnd/src/views/admin/MoreAdmin.tsx
deleted file mode 100644
index d49d211f..00000000
--- a/FrontEnd/src/views/admin/MoreAdmin.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import * as React from "react";
-
-const MoreAdmin: React.FC = () => {
- return <>More...</>;
-};
-
-export default MoreAdmin;
diff --git a/FrontEnd/src/views/admin/UserAdmin.tsx b/FrontEnd/src/views/admin/UserAdmin.tsx
deleted file mode 100644
index d5179bf5..00000000
--- a/FrontEnd/src/views/admin/UserAdmin.tsx
+++ /dev/null
@@ -1,304 +0,0 @@
-import { useState, useEffect } from "react";
-import * as React from "react";
-import { Trans, useTranslation } from "react-i18next";
-import classnames from "classnames";
-
-import { getHttpUserClient, HttpUser, kUserPermissionList } from "@/http/user";
-
-import OperationDialog, {
- OperationDialogBoolInput,
-} from "../common/dialog/OperationDialog";
-import Button from "../common/button/Button";
-import Spinner from "../common/Spinner";
-import FlatButton from "../common/button/FlatButton";
-import IconButton from "../common/button/IconButton";
-
-const CreateUserDialog: React.FC<{
- open: boolean;
- close: () => void;
- onSuccess: (user: HttpUser) => void;
-}> = ({ open, close, onSuccess }) => {
- return (
- <OperationDialog
- title="admin:user.dialog.create.title"
- themeColor="success"
- inputPrompt="admin:user.dialog.create.prompt"
- inputScheme={
- [
- { type: "text", label: "admin:user.username" },
- { type: "text", label: "admin:user.password" },
- ] as const
- }
- onProcess={([username, password]) =>
- getHttpUserClient().post({
- username,
- password,
- })
- }
- onClose={close}
- open={open}
- onSuccessAndClose={onSuccess}
- />
- );
-};
-
-const UsernameLabel: React.FC<{ children: React.ReactNode }> = (props) => {
- return <span style={{ color: "blue" }}>{props.children}</span>;
-};
-
-const UserDeleteDialog: React.FC<{
- open: boolean;
- close: () => void;
- user: HttpUser;
- onSuccess: () => void;
-}> = ({ open, close, user, onSuccess }) => {
- return (
- <OperationDialog
- open={open}
- onClose={close}
- title="admin:user.dialog.delete.title"
- themeColor="danger"
- inputPrompt={() => (
- <Trans i18nKey="user.dialog.delete.prompt" ns="admin">
- 0<UsernameLabel>{user.username}</UsernameLabel>2
- </Trans>
- )}
- onProcess={() => getHttpUserClient().delete(user.username)}
- onSuccessAndClose={onSuccess}
- />
- );
-};
-
-const UserModifyDialog: React.FC<{
- open: boolean;
- close: () => void;
- user: HttpUser;
- onSuccess: () => void;
-}> = ({ open, close, user, onSuccess }) => {
- return (
- <OperationDialog
- open={open}
- onClose={close}
- title="admin:user.dialog.modify.title"
- themeColor="danger"
- inputPrompt={() => (
- <Trans i18nKey="admin:user.dialog.modify.prompt">
- 0<UsernameLabel>{user.username}</UsernameLabel>2
- </Trans>
- )}
- inputScheme={
- [
- {
- type: "text",
- label: "admin:user.username",
- initValue: user.username,
- },
- { type: "text", label: "admin:user.password" },
- {
- type: "text",
- label: "admin:user.nickname",
- initValue: user.nickname,
- },
- ] as const
- }
- onProcess={([username, password, nickname]) =>
- getHttpUserClient().patch(user.username, {
- username: username !== user.username ? username : undefined,
- password: password !== "" ? password : undefined,
- nickname: nickname !== user.nickname ? nickname : undefined,
- })
- }
- onSuccessAndClose={onSuccess}
- />
- );
-};
-
-const UserPermissionModifyDialog: React.FC<{
- open: boolean;
- close: () => void;
- user: HttpUser;
- onSuccess: () => void;
-}> = ({ open, close, user, onSuccess }) => {
- const oldPermissionBoolList: boolean[] = kUserPermissionList.map(
- (permission) => user.permissions.includes(permission)
- );
-
- return (
- <OperationDialog
- open={open}
- onClose={close}
- title="admin:user.dialog.modifyPermissions.title"
- themeColor="danger"
- inputPrompt={() => (
- <Trans i18nKey="admin:user.dialog.modifyPermissions.prompt">
- 0<UsernameLabel>{user.username}</UsernameLabel>2
- </Trans>
- )}
- inputScheme={kUserPermissionList.map<OperationDialogBoolInput>(
- (permission, index) => ({
- type: "bool",
- label: { type: "custom", value: permission },
- initValue: oldPermissionBoolList[index],
- })
- )}
- onProcess={async (newPermissionBoolList): Promise<boolean[]> => {
- for (let index = 0; index < kUserPermissionList.length; index++) {
- const oldValue = oldPermissionBoolList[index];
- const newValue = newPermissionBoolList[index];
- const permission = kUserPermissionList[index];
- if (oldValue === newValue) continue;
- if (newValue) {
- await getHttpUserClient().putUserPermission(
- user.username,
- permission
- );
- } else {
- await getHttpUserClient().deleteUserPermission(
- user.username,
- permission
- );
- }
- }
- return newPermissionBoolList;
- }}
- onSuccessAndClose={onSuccess}
- />
- );
-};
-
-interface UserItemProps {
- user: HttpUser;
- onChange: () => void;
-}
-
-const UserItem: React.FC<UserItemProps> = ({ user, onChange }) => {
- const { t } = useTranslation();
-
- const [dialog, setDialog] = useState<
- "delete" | "modify" | "permission" | null
- >(null);
-
- const [editMaskVisible, setEditMaskVisible] = React.useState<boolean>(false);
-
- return (
- <>
- <div className="admin-user-item">
- <IconButton
- icon="pencil-square"
- className="cru-float-right"
- onClick={() => setEditMaskVisible(true)}
- />
- <h5 className="cru-color-primary">{user.username}</h5>
- <small className="d-block cru-color-secondary">
- {t("admin:user.nickname")}
- {user.nickname}
- </small>
- <small className="d-block cru-color-secondary">
- {t("admin:user.uniqueId")}
- {user.uniqueId}
- </small>
- <small className="d-block cru-color-secondary">
- {t("admin:user.permissions")}
- {user.permissions.map((permission) => {
- return (
- <span key={permission} className="cru-color-danger">
- {permission}
- </span>
- );
- })}
- </small>
- <div
- className={classnames("edit-mask", !editMaskVisible && "d-none")}
- onClick={() => setEditMaskVisible(false)}
- >
- <FlatButton
- text="admin:user.modify"
- onClick={() => setDialog("modify")}
- />
- <FlatButton
- text="admin:user.modifyPermissions"
- onClick={() => setDialog("permission")}
- />
- <FlatButton
- text="admin:user.delete"
- color="danger"
- onClick={() => setDialog("delete")}
- />
- </div>
- </div>
- <UserDeleteDialog
- open={dialog === "delete"}
- close={() => setDialog(null)}
- user={user}
- onSuccess={onChange}
- />
- <UserModifyDialog
- open={dialog === "modify"}
- close={() => setDialog(null)}
- user={user}
- onSuccess={onChange}
- />
- <UserPermissionModifyDialog
- open={dialog === "permission"}
- close={() => setDialog(null)}
- user={user}
- onSuccess={onChange}
- />
- </>
- );
-};
-
-const UserAdmin: React.FC = () => {
- const [users, setUsers] = useState<HttpUser[] | null>(null);
- const [dialog, setDialog] = useState<"create" | null>(null);
- const [usersVersion, setUsersVersion] = useState<number>(0);
- const updateUsers = (): void => {
- setUsersVersion(usersVersion + 1);
- };
-
- useEffect(() => {
- let subscribe = true;
- void getHttpUserClient()
- .list()
- .then((us) => {
- if (subscribe) {
- setUsers(us.items);
- }
- });
- return () => {
- subscribe = false;
- };
- }, [usersVersion]);
-
- if (users) {
- const userComponents = users.map((user) => {
- return (
- <UserItem key={user.username} user={user} onChange={updateUsers} />
- );
- });
-
- return (
- <>
- <div className="row justify-content-end my-2">
- <div className="col col-auto">
- <Button
- text="admin:create"
- color="success"
- onClick={() => setDialog("create")}
- />
- </div>
- </div>
- {userComponents}
- <CreateUserDialog
- open={dialog === "create"}
- close={() => setDialog(null)}
- onSuccess={updateUsers}
- />
- </>
- );
- } else {
- return <Spinner />;
- }
-};
-
-export default UserAdmin;
diff --git a/FrontEnd/src/views/admin/index.css b/FrontEnd/src/views/admin/index.css
deleted file mode 100644
index 17e24586..00000000
--- a/FrontEnd/src/views/admin/index.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.admin-user-item {
- position: relative;
- border: var(--cru-primary-color) solid;
- border-width: 1px 1px 0;
- padding: 1em;
-}
-
-.admin-user-item:last-of-type {
- border-bottom-width: 1px;
-}
-
-.admin-user-item .edit-mask {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- background: rgba(255, 255, 255, 0.9);
- position: absolute;
- display: flex;
- justify-content: space-around;
- align-items: center;
-}
-
-@media (max-width: 576px) {
- .admin-user-item .edit-mask {
- flex-direction: column;
- }
-}
-
-.admin-user-item .edit-mask button {
- margin: 0.5em 2em;
-}
diff --git a/FrontEnd/src/views/admin/index.tsx b/FrontEnd/src/views/admin/index.tsx
deleted file mode 100644
index 0467711d..00000000
--- a/FrontEnd/src/views/admin/index.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import { lazy } from "react";
-
-const Admin = lazy(
- () => import(/* webpackChunkName: "admin" */ "./Admin")
-);
-
-export default Admin;