diff options
author | crupest <crupest@outlook.com> | 2020-09-03 18:56:40 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-09-03 18:56:40 +0800 |
commit | 880ed701d5ae3f3b21b30d3b9e2db5d98d6b9513 (patch) | |
tree | 15f1fab11da36d9f2257fbc13396ea517ac32840 /Timeline/ClientApp/src | |
parent | 2be72885e2d49a5637c2741e1844dfe92d3e197e (diff) | |
download | timeline-880ed701d5ae3f3b21b30d3b9e2db5d98d6b9513.tar.gz timeline-880ed701d5ae3f3b21b30d3b9e2db5d98d6b9513.tar.bz2 timeline-880ed701d5ae3f3b21b30d3b9e2db5d98d6b9513.zip |
Move AppBar to App .
Diffstat (limited to 'Timeline/ClientApp/src')
-rw-r--r-- | Timeline/ClientApp/src/app/App.tsx | 75 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/views/about/index.tsx | 156 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/views/admin/Admin.tsx | 2 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/views/home/index.tsx | 2 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/views/login/index.tsx | 151 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/views/settings/index.tsx | 170 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/views/timeline-common/TimelinePageTemplateUI.tsx | 7 |
7 files changed, 268 insertions, 295 deletions
diff --git a/Timeline/ClientApp/src/app/App.tsx b/Timeline/ClientApp/src/app/App.tsx index b64414b7..b68eddb6 100644 --- a/Timeline/ClientApp/src/app/App.tsx +++ b/Timeline/ClientApp/src/app/App.tsx @@ -11,6 +11,7 @@ import About from "./views/about"; import User from "./views/user"; import TimelinePage from "./views/timeline"; import AlertHost from "./views/common/alert/AlertHost"; + import { dataStorage } from "./services/common"; import { userService, useRawUser } from "./services/user"; @@ -38,50 +39,46 @@ const App: React.FC = () => { void dataStorage.ready().then(() => setLoading(false)); }, []); - let body; if (user === undefined || loading) { - body = <LoadingPage />; + return <LoadingPage />; } else { - body = ( - <Router> - <Switch> - <Route exact path="/"> - <Home /> - </Route> - <Route exact path="/login"> - <Login /> - </Route> - <Route path="/settings"> - <Settings /> - </Route> - <Route path="/about"> - <About /> - </Route> - <Route path="/timelines/:name"> - <TimelinePage /> - </Route> - <Route path="/users/:username"> - <User /> - </Route> - {user && user.administrator && ( - <Route path="/admin"> - <LazyAdmin user={user} /> + return ( + <React.Suspense fallback={<LoadingPage />}> + <Router> + <AppBar /> + <Switch> + <Route exact path="/"> + <Home /> + </Route> + <Route exact path="/login"> + <Login /> + </Route> + <Route path="/settings"> + <Settings /> + </Route> + <Route path="/about"> + <About /> + </Route> + <Route path="/timelines/:name"> + <TimelinePage /> </Route> - )} - <Route> - <NoMatch /> - </Route> - </Switch> - </Router> + <Route path="/users/:username"> + <User /> + </Route> + {user && user.administrator && ( + <Route path="/admin"> + <LazyAdmin user={user} /> + </Route> + )} + <Route> + <NoMatch /> + </Route> + </Switch> + <AlertHost /> + </Router> + </React.Suspense> ); } - - return ( - <React.Suspense fallback={<LoadingPage />}> - {body} - <AlertHost /> - </React.Suspense> - ); }; export default hot(App); diff --git a/Timeline/ClientApp/src/app/views/about/index.tsx b/Timeline/ClientApp/src/app/views/about/index.tsx index 78cffb5f..e7771cec 100644 --- a/Timeline/ClientApp/src/app/views/about/index.tsx +++ b/Timeline/ClientApp/src/app/views/about/index.tsx @@ -1,8 +1,6 @@ import React from "react"; import { useTranslation, Trans } from "react-i18next"; -import AppBar from "../common/AppBar"; - import authorAvatarUrl from "./author-avatar.png"; import githubLogoUrl from "./github.png"; @@ -75,97 +73,91 @@ const AboutPage: React.FC = () => { const { t } = useTranslation(); return ( - <> - <AppBar /> - <div className="mt-appbar px-2 mb-4"> - <div className="container mt-4 py-3 shadow border border-primary rounded bg-light"> - <h4 id="author-info">{t("about.author.title")}</h4> - <div> - <div className="d-flex"> - <img - src={authorAvatarUrl} - className="align-self-start avatar large rounded-circle" - /> - <div> - <p> - <small>{t("about.author.fullname")}</small> - <span className="text-primary">杨宇千</span> - </p> - <p> - <small>{t("about.author.nickname")}</small> - <span className="text-primary">crupest</span> - </p> - <p> - <small>{t("about.author.introduction")}</small> - {t("about.author.introductionContent")} - </p> - </div> + <div className="mt-appbar px-2 mb-4"> + <div className="container mt-4 py-3 shadow border border-primary rounded bg-light"> + <h4 id="author-info">{t("about.author.title")}</h4> + <div> + <div className="d-flex"> + <img + src={authorAvatarUrl} + className="align-self-start avatar large rounded-circle" + /> + <div> + <p> + <small>{t("about.author.fullname")}</small> + <span className="text-primary">杨宇千</span> + </p> + <p> + <small>{t("about.author.nickname")}</small> + <span className="text-primary">crupest</span> + </p> + <p> + <small>{t("about.author.introduction")}</small> + {t("about.author.introductionContent")} + </p> </div> - <p> - <small>{t("about.author.links")}</small> - <a - href="https://github.com/crupest" - target="_blank" - rel="noopener noreferrer" - > - <img - src={githubLogoUrl} - className="about-link-icon text-body" - /> - </a> - </p> </div> - </div> - <div className="container mt-4 py-3 shadow border border-primary rounded bg-light"> - <h4>{t("about.site.title")}</h4> - <p> - <Trans i18nKey="about.site.content"> - 0<span className="text-primary">1</span>2<b>3</b>4 - <a href="#author-info">5</a>6 - </Trans> - </p> <p> + <small>{t("about.author.links")}</small> <a - href="https://github.com/crupest/Timeline" + href="https://github.com/crupest" target="_blank" rel="noopener noreferrer" > - {t("about.site.repo")} + <img src={githubLogoUrl} className="about-link-icon text-body" /> </a> </p> </div> - <div className="container mt-4 py-3 shadow border border-primary rounded bg-light"> - <h4>{t("about.credits.title")}</h4> - <p>{t("about.credits.content")}</p> - <p>{t("about.credits.frontend")}</p> - <ul> - {frontendCredits.map((item, index) => { - return ( - <li key={index}> - <a href={item.url} target="_blank" rel="noopener noreferrer"> - {item.name} - </a> - </li> - ); - })} - <li>...</li> - </ul> - <p>{t("about.credits.backend")}</p> - <ul> - {backendCredits.map((item, index) => { - return ( - <li key={index}> - <a href={item.url} target="_blank" rel="noopener noreferrer"> - {item.name} - </a> - </li> - ); - })} - <li>...</li> - </ul> - </div> </div> - </> + <div className="container mt-4 py-3 shadow border border-primary rounded bg-light"> + <h4>{t("about.site.title")}</h4> + <p> + <Trans i18nKey="about.site.content"> + 0<span className="text-primary">1</span>2<b>3</b>4 + <a href="#author-info">5</a>6 + </Trans> + </p> + <p> + <a + href="https://github.com/crupest/Timeline" + target="_blank" + rel="noopener noreferrer" + > + {t("about.site.repo")} + </a> + </p> + </div> + <div className="container mt-4 py-3 shadow border border-primary rounded bg-light"> + <h4>{t("about.credits.title")}</h4> + <p>{t("about.credits.content")}</p> + <p>{t("about.credits.frontend")}</p> + <ul> + {frontendCredits.map((item, index) => { + return ( + <li key={index}> + <a href={item.url} target="_blank" rel="noopener noreferrer"> + {item.name} + </a> + </li> + ); + })} + <li>...</li> + </ul> + <p>{t("about.credits.backend")}</p> + <ul> + {backendCredits.map((item, index) => { + return ( + <li key={index}> + <a href={item.url} target="_blank" rel="noopener noreferrer"> + {item.name} + </a> + </li> + ); + })} + <li>...</li> + </ul> + </div> + </div> ); }; diff --git a/Timeline/ClientApp/src/app/views/admin/Admin.tsx b/Timeline/ClientApp/src/app/views/admin/Admin.tsx index e0f59b0f..9c0250e7 100644 --- a/Timeline/ClientApp/src/app/views/admin/Admin.tsx +++ b/Timeline/ClientApp/src/app/views/admin/Admin.tsx @@ -8,7 +8,6 @@ import { } from "react-router"; import { Nav } from "react-bootstrap"; -import AppBar from "../common/AppBar"; import { UserWithToken } from "@/services/user"; import UserAdmin from "./UserAdmin"; @@ -34,7 +33,6 @@ const Admin: React.FC<AdminProps> = (props) => { ): React.ReactNode => { return ( <Route path={`${match.path}/${name}`}> - <AppBar /> <div style={{ height: 56 }} className="flex-fix-length" /> <Nav variant="tabs"> <Nav.Item> diff --git a/Timeline/ClientApp/src/app/views/home/index.tsx b/Timeline/ClientApp/src/app/views/home/index.tsx index e2e3e6f9..11672c10 100644 --- a/Timeline/ClientApp/src/app/views/home/index.tsx +++ b/Timeline/ClientApp/src/app/views/home/index.tsx @@ -4,7 +4,6 @@ import { useTranslation } from "react-i18next"; import { Row, Container, Button, Col } from "react-bootstrap"; import { useUser } from "@/services/user"; -import AppBar from "../common/AppBar"; import SearchInput from "../common/SearchInput"; import BoardWithoutUser from "./BoardWithoutUser"; @@ -34,7 +33,6 @@ const HomePage: React.FC = () => { return ( <> - <AppBar /> <Container fluid> <Row> <Col> diff --git a/Timeline/ClientApp/src/app/views/login/index.tsx b/Timeline/ClientApp/src/app/views/login/index.tsx index 545fc05a..a3071264 100644 --- a/Timeline/ClientApp/src/app/views/login/index.tsx +++ b/Timeline/ClientApp/src/app/views/login/index.tsx @@ -1,7 +1,7 @@ -import React, { Fragment, useState, useEffect } from "react"; +import React from "react"; import { useHistory } from "react-router"; import { useTranslation } from "react-i18next"; -import { Form, Spinner, Button } from "react-bootstrap"; +import { Form } from "react-bootstrap"; import { useUser, userService } from "@/services/user"; @@ -11,17 +11,17 @@ import LoadingButton from "../common/LoadingButton"; const LoginPage: React.FC = (_) => { const { t } = useTranslation(); const history = useHistory(); - const [username, setUsername] = useState<string>(""); - const [usernameDirty, setUsernameDirty] = useState<boolean>(false); - const [password, setPassword] = useState<string>(""); - const [passwordDirty, setPasswordDirty] = useState<boolean>(false); - const [rememberMe, setRememberMe] = useState<boolean>(true); - const [process, setProcess] = useState<boolean>(false); - const [error, setError] = useState<string | null>(null); + const [username, setUsername] = React.useState<string>(""); + const [usernameDirty, setUsernameDirty] = React.useState<boolean>(false); + const [password, setPassword] = React.useState<string>(""); + const [passwordDirty, setPasswordDirty] = React.useState<boolean>(false); + const [rememberMe, setRememberMe] = React.useState<boolean>(true); + const [process, setProcess] = React.useState<boolean>(false); + const [error, setError] = React.useState<string | null>(null); const user = useUser(); - useEffect(() => { + React.useEffect(() => { if (user != null) { const id = setTimeout(() => history.push("/"), 3000); return () => { @@ -72,73 +72,70 @@ const LoginPage: React.FC = (_) => { } return ( - <Fragment> - <AppBar /> - <div className="container login-container mt-appbar"> - <h1>{t("welcome")}</h1> - <Form> - <Form.Group> - <Form.Label htmlFor="username">{t("user.username")}</Form.Label> - <Form.Control - id="username" - disabled={process} - onChange={(e) => { - setUsername(e.target.value); - setUsernameDirty(true); - }} - value={username} - isInvalid={usernameDirty && username === ""} - /> - {usernameDirty && username === "" && ( - <Form.Control.Feedback type="invalid"> - {t("login.emptyUsername")} - </Form.Control.Feedback> - )} - </Form.Group> - <Form.Group> - <Form.Label htmlFor="password">{t("user.password")}</Form.Label> - <Form.Control - id="password" - type="password" - disabled={process} - onChange={(e) => { - setPassword(e.target.value); - setPasswordDirty(true); - }} - value={password} - isInvalid={passwordDirty && password === ""} - /> - {passwordDirty && password === "" && ( - <Form.Control.Feedback type="invalid"> - {t("login.emptyPassword")} - </Form.Control.Feedback> - )} - </Form.Group> - <Form.Group> - <Form.Check<"input"> - id="remember-me" - type="checkbox" - checked={rememberMe} - onChange={(e) => { - setRememberMe(e.target.checked); - }} - label={t("user.rememberMe")} - /> - </Form.Group> - {error ? <p className="text-danger">{t(error)}</p> : null} - <div className="text-right"> - <LoadingButton - loading={process} - variant="primary" - onClick={onSubmit} - disabled={username === "" || password === "" ? true : undefined} - > - {t("user.login")} - </LoadingButton> - </div> - </Form> - </div> - </Fragment> + <div className="container login-container mt-appbar"> + <h1>{t("welcome")}</h1> + <Form> + <Form.Group> + <Form.Label htmlFor="username">{t("user.username")}</Form.Label> + <Form.Control + id="username" + disabled={process} + onChange={(e) => { + setUsername(e.target.value); + setUsernameDirty(true); + }} + value={username} + isInvalid={usernameDirty && username === ""} + /> + {usernameDirty && username === "" && ( + <Form.Control.Feedback type="invalid"> + {t("login.emptyUsername")} + </Form.Control.Feedback> + )} + </Form.Group> + <Form.Group> + <Form.Label htmlFor="password">{t("user.password")}</Form.Label> + <Form.Control + id="password" + type="password" + disabled={process} + onChange={(e) => { + setPassword(e.target.value); + setPasswordDirty(true); + }} + value={password} + isInvalid={passwordDirty && password === ""} + /> + {passwordDirty && password === "" && ( + <Form.Control.Feedback type="invalid"> + {t("login.emptyPassword")} + </Form.Control.Feedback> + )} + </Form.Group> + <Form.Group> + <Form.Check<"input"> + id="remember-me" + type="checkbox" + checked={rememberMe} + onChange={(e) => { + setRememberMe(e.target.checked); + }} + label={t("user.rememberMe")} + /> + </Form.Group> + {error ? <p className="text-danger">{t(error)}</p> : null} + <div className="text-right"> + <LoadingButton + loading={process} + variant="primary" + onClick={onSubmit} + disabled={username === "" || password === "" ? true : undefined} + > + {t("user.login")} + </LoadingButton> + </div> + </Form> + </div> ); }; diff --git a/Timeline/ClientApp/src/app/views/settings/index.tsx b/Timeline/ClientApp/src/app/views/settings/index.tsx index 123e1353..964e7442 100644 --- a/Timeline/ClientApp/src/app/views/settings/index.tsx +++ b/Timeline/ClientApp/src/app/views/settings/index.tsx @@ -4,7 +4,6 @@ import { useTranslation } from "react-i18next"; import { Form, Container, Row, Col, Button, Modal } from "react-bootstrap"; import { useUser, userService } from "@/services/user"; -import AppBar from "../common/AppBar"; import OperationDialog, { OperationInputErrorInfo, } from "../common/OperationDialog"; @@ -121,92 +120,89 @@ const SettingsPage: React.FC = (_) => { const language = i18n.language.slice(0, 2); return ( - <> - <AppBar /> - <Container fluid> - {user ? ( - <> - <Row className="border-bottom p-3 cursor-pointer"> - <Col xs="12"> - <h5 - onClick={() => { - history.push(`/users/${user.username}`); - }} - > - {t("settings.gotoSelf")} - </h5> - </Col> - </Row> - <Row className="border-bottom p-3 cursor-pointer"> - <Col xs="12"> - <h5 - className="text-danger" - onClick={() => setDialog("changepassword")} - > - {t("settings.changePassword")} - </h5> - </Col> - </Row> - <Row className="border-bottom p-3 cursor-pointer"> - <Col xs="12"> - <h5 - className="text-danger" - onClick={() => { - setDialog("logout"); - }} - > - {t("settings.logout")} - </h5> - </Col> - </Row> - </> - ) : null} - <Row className="align-items-center border-bottom p-3"> - <Col xs="12" sm="auto"> - <h5>{t("settings.languagePrimary")}</h5> - <p>{t("settings.languageSecondary")}</p> - </Col> - <Col xs="auto" className="ml-auto"> - <Form.Control - as="select" - value={language} - onChange={(e) => { - void i18n.changeLanguage(e.target.value); - }} - > - <option value="zh">中文</option> - <option value="en">English</option> - </Form.Control> - </Col> - </Row> - {(() => { - switch (dialog) { - case "changepassword": - return ( - <ChangePasswordDialog - open - close={() => { - setDialog(null); - }} - /> - ); - case "logout": - return ( - <ConfirmLogoutDialog - toggle={() => setDialog(null)} - onConfirm={() => { - void userService.logout().then(() => { - history.push("/"); - }); - }} - /> - ); - default: - return null; - } - })()} - </Container> - </> + <Container fluid> + {user ? ( + <> + <Row className="border-bottom p-3 cursor-pointer"> + <Col xs="12"> + <h5 + onClick={() => { + history.push(`/users/${user.username}`); + }} + > + {t("settings.gotoSelf")} + </h5> + </Col> + </Row> + <Row className="border-bottom p-3 cursor-pointer"> + <Col xs="12"> + <h5 + className="text-danger" + onClick={() => setDialog("changepassword")} + > + {t("settings.changePassword")} + </h5> + </Col> + </Row> + <Row className="border-bottom p-3 cursor-pointer"> + <Col xs="12"> + <h5 + className="text-danger" + onClick={() => { + setDialog("logout"); + }} + > + {t("settings.logout")} + </h5> + </Col> + </Row> + </> + ) : null} + <Row className="align-items-center border-bottom p-3"> + <Col xs="12" sm="auto"> + <h5>{t("settings.languagePrimary")}</h5> + <p>{t("settings.languageSecondary")}</p> + </Col> + <Col xs="auto" className="ml-auto"> + <Form.Control + as="select" + value={language} + onChange={(e) => { + void i18n.changeLanguage(e.target.value); + }} + > + <option value="zh">中文</option> + <option value="en">English</option> + </Form.Control> + </Col> + </Row> + {(() => { + switch (dialog) { + case "changepassword": + return ( + <ChangePasswordDialog + open + close={() => { + setDialog(null); + }} + /> + ); + case "logout": + return ( + <ConfirmLogoutDialog + toggle={() => setDialog(null)} + onConfirm={() => { + void userService.logout().then(() => { + history.push("/"); + }); + }} + /> + ); + default: + return null; + } + })()} + </Container> ); }; diff --git a/Timeline/ClientApp/src/app/views/timeline-common/TimelinePageTemplateUI.tsx b/Timeline/ClientApp/src/app/views/timeline-common/TimelinePageTemplateUI.tsx index e25ed962..c33bc0e5 100644 --- a/Timeline/ClientApp/src/app/views/timeline-common/TimelinePageTemplateUI.tsx +++ b/Timeline/ClientApp/src/app/views/timeline-common/TimelinePageTemplateUI.tsx @@ -310,10 +310,5 @@ export default function TimelinePageTemplateUI<TManageItems>( } } - return ( - <> - <AppBar /> - {body} - </> - ); + return body; } |