From aa89b6cce7701a57b0c377d938788b4c940013d6 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 1 Sep 2020 02:32:06 +0800 Subject: ... --- Timeline/ClientApp/src/app/views/about/about.sass | 4 + .../src/app/views/about/author-avatar.png | Bin 0 -> 12038 bytes Timeline/ClientApp/src/app/views/about/github.png | Bin 0 -> 4268 bytes Timeline/ClientApp/src/app/views/about/index.tsx | 172 +++++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 Timeline/ClientApp/src/app/views/about/about.sass create mode 100644 Timeline/ClientApp/src/app/views/about/author-avatar.png create mode 100644 Timeline/ClientApp/src/app/views/about/github.png create mode 100644 Timeline/ClientApp/src/app/views/about/index.tsx (limited to 'Timeline/ClientApp/src/app/views/about') diff --git a/Timeline/ClientApp/src/app/views/about/about.sass b/Timeline/ClientApp/src/app/views/about/about.sass new file mode 100644 index 00000000..3b5840cd --- /dev/null +++ b/Timeline/ClientApp/src/app/views/about/about.sass @@ -0,0 +1,4 @@ +.about-link-icon + @extend .mx-2 + width: 1.2em + height: 1.2em diff --git a/Timeline/ClientApp/src/app/views/about/author-avatar.png b/Timeline/ClientApp/src/app/views/about/author-avatar.png new file mode 100644 index 00000000..d890d8d0 Binary files /dev/null and b/Timeline/ClientApp/src/app/views/about/author-avatar.png differ diff --git a/Timeline/ClientApp/src/app/views/about/github.png b/Timeline/ClientApp/src/app/views/about/github.png new file mode 100644 index 00000000..ea6ff545 Binary files /dev/null and b/Timeline/ClientApp/src/app/views/about/github.png differ diff --git a/Timeline/ClientApp/src/app/views/about/index.tsx b/Timeline/ClientApp/src/app/views/about/index.tsx new file mode 100644 index 00000000..21c487da --- /dev/null +++ b/Timeline/ClientApp/src/app/views/about/index.tsx @@ -0,0 +1,172 @@ +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"; + +const frontendCredits: { + name: string; + url: string; +}[] = [ + { + name: "reactjs", + url: "https://reactjs.org", + }, + { + name: "typescript", + url: "https://www.typescriptlang.org", + }, + { + name: "bootstrap", + url: "https://getbootstrap.com", + }, + { + name: "reactstrap", + url: "https://reactstrap.github.io", + }, + { + name: "babeljs", + url: "https://babeljs.io", + }, + { + name: "webpack", + url: "https://webpack.js.org", + }, + { + name: "sass", + url: "https://sass-lang.com", + }, + { + name: "eslint", + url: "https://eslint.org", + }, + { + name: "prettier", + url: "https://prettier.io", + }, + { + name: "pepjs", + url: "https://github.com/jquery/PEP", + }, + { + name: "react-inlinesvg", + url: "https://github.com/gilbarbara/react-inlinesvg", + }, +]; + +const backendCredits: { + name: string; + url: string; +}[] = [ + { + name: "ASP.NET Core", + url: "https://dotnet.microsoft.com/learn/aspnet/what-is-aspnet-core", + }, + { name: "sqlite", url: "https://sqlite.org" }, + { + name: "ImageSharp", + url: "https://github.com/SixLabors/ImageSharp", + }, +]; + +const AboutPage: React.FC = () => { + const { t } = useTranslation(); + + return ( + <> + +
+
+

{t("about.author.title")}

+
+
+ +
+

+ {t("about.author.fullname")} + 杨宇千 +

+

+ {t("about.author.nickname")} + crupest +

+

+ {t("about.author.introduction")} + {t("about.author.introductionContent")} +

+
+
+

+ {t("about.author.links")} + + + +

+
+
+
+

{t("about.site.title")}

+

+ + 01234 + 56 + +

+

+ + {t("about.site.repo")} + +

+
+
+

{t("about.credits.title")}

+

{t("about.credits.content")}

+

{t("about.credits.frontend")}

+
    + {frontendCredits.map((item, index) => { + return ( +
  • + + {item.name} + +
  • + ); + })} +
  • ...
  • +
+

{t("about.credits.backend")}

+
    + {backendCredits.map((item, index) => { + return ( +
  • + + {item.name} + +
  • + ); + })} +
  • ...
  • +
+
+
+ + ); +}; + +export default AboutPage; -- cgit v1.2.3 From ac40d9c18e2ac7b4995dac38d5da04a3ea7f1559 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 3 Sep 2020 18:10:02 +0800 Subject: Migrate to react-bootstrap. --- Timeline/ClientApp/package.json | 2 - Timeline/ClientApp/src/app/service-worker.tsx | 10 ++- Timeline/ClientApp/src/app/views/about/index.tsx | 4 +- Timeline/ClientApp/src/app/views/admin/Admin.tsx | 25 +++--- .../ClientApp/src/app/views/admin/UserAdmin.tsx | 47 +++++------ Timeline/ClientApp/src/app/views/common/AppBar.tsx | 2 +- .../ClientApp/src/app/views/common/FileInput.tsx | 36 --------- .../src/app/views/common/OperationDialog.tsx | 93 ++++++++++------------ .../src/app/views/common/alert/AlertHost.tsx | 9 ++- Timeline/ClientApp/src/app/views/login/index.tsx | 53 ++++++------ .../src/app/views/timeline-common/TimelineItem.tsx | 28 +++---- .../app/views/timeline-common/TimelineMember.tsx | 22 ++--- .../views/timeline-common/TimelinePageTemplate.tsx | 6 +- .../timeline-common/TimelinePageTemplateUI.tsx | 18 ++--- .../app/views/timeline-common/TimelinePostEdit.tsx | 23 +++--- .../app/views/timeline-common/timeline-common.sass | 25 ++++-- .../src/app/views/timeline/TimelineInfoCard.tsx | 46 ++++------- .../ClientApp/src/app/views/timeline/timeline.sass | 14 ---- .../src/app/views/user/ChangeAvatarDialog.tsx | 93 ++++++++++------------ .../ClientApp/src/app/views/user/UserInfoCard.tsx | 48 ++++------- 20 files changed, 247 insertions(+), 357 deletions(-) delete mode 100644 Timeline/ClientApp/src/app/views/common/FileInput.tsx (limited to 'Timeline/ClientApp/src/app/views/about') diff --git a/Timeline/ClientApp/package.json b/Timeline/ClientApp/package.json index 81232c71..5ae6a608 100644 --- a/Timeline/ClientApp/package.json +++ b/Timeline/ClientApp/package.json @@ -27,7 +27,6 @@ "react-router": "^5.2.0", "react-router-bootstrap": "^0.25.0", "react-router-dom": "^5.2.0", - "reactstrap": "^8.5.1", "regenerator-runtime": "^0.13.7", "rxjs": "^6.6.2", "workbox-precaching": "^5.1.3", @@ -75,7 +74,6 @@ "@types/react-router": "^5.1.8", "@types/react-router-bootstrap": "^0.24.5", "@types/react-router-dom": "^5.1.5", - "@types/reactstrap": "^8.5.1", "@types/webpack-env": "^1.15.2", "@types/xregexp": "^4.3.0", "@typescript-eslint/eslint-plugin": "^3.10.1", diff --git a/Timeline/ClientApp/src/app/service-worker.tsx b/Timeline/ClientApp/src/app/service-worker.tsx index e629995a..3be54bc1 100644 --- a/Timeline/ClientApp/src/app/service-worker.tsx +++ b/Timeline/ClientApp/src/app/service-worker.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { Button } from "reactstrap"; import { useTranslation } from "react-i18next"; +import { Button } from "react-bootstrap"; import { pushAlert } from "./services/alert"; @@ -39,7 +39,11 @@ if ("serviceWorker" in navigator) { return ( <> {t("serviceWorker.externalActivatedPrompt")} - @@ -83,7 +87,7 @@ if ("serviceWorker" in navigator) { return ( <> {t("serviceWorker.upgradePrompt")} - diff --git a/Timeline/ClientApp/src/app/views/about/index.tsx b/Timeline/ClientApp/src/app/views/about/index.tsx index 21c487da..78cffb5f 100644 --- a/Timeline/ClientApp/src/app/views/about/index.tsx +++ b/Timeline/ClientApp/src/app/views/about/index.tsx @@ -23,8 +23,8 @@ const frontendCredits: { url: "https://getbootstrap.com", }, { - name: "reactstrap", - url: "https://reactstrap.github.io", + name: "react-bootstrap", + url: "https://react-bootstrap.github.io", }, { name: "babeljs", diff --git a/Timeline/ClientApp/src/app/views/admin/Admin.tsx b/Timeline/ClientApp/src/app/views/admin/Admin.tsx index 51dc5a3c..e0f59b0f 100644 --- a/Timeline/ClientApp/src/app/views/admin/Admin.tsx +++ b/Timeline/ClientApp/src/app/views/admin/Admin.tsx @@ -1,5 +1,4 @@ import React, { Fragment } from "react"; -import { Nav, NavItem, NavLink } from "reactstrap"; import { Redirect, Route, @@ -7,7 +6,7 @@ import { useRouteMatch, useHistory, } from "react-router"; -import classnames from "classnames"; +import { Nav } from "react-bootstrap"; import AppBar from "../common/AppBar"; import { UserWithToken } from "@/services/user"; @@ -37,27 +36,27 @@ const Admin: React.FC = (props) => {
- {body} diff --git a/Timeline/ClientApp/src/app/views/admin/UserAdmin.tsx b/Timeline/ClientApp/src/app/views/admin/UserAdmin.tsx index bde6b3af..18b77ca8 100644 --- a/Timeline/ClientApp/src/app/views/admin/UserAdmin.tsx +++ b/Timeline/ClientApp/src/app/views/admin/UserAdmin.tsx @@ -1,16 +1,13 @@ import React, { useState, useEffect } from "react"; +import axios from "axios"; import { - ListGroupItem, + ListGroup, Row, Col, - UncontrolledDropdown, - DropdownToggle, - DropdownMenu, - DropdownItem, + Dropdown, Spinner, Button, -} from "reactstrap"; -import axios from "axios"; +} from "react-bootstrap"; import OperationDialog from "../common/OperationDialog"; import { User, UserWithToken } from "@/services/user"; @@ -101,7 +98,7 @@ const UserItem: React.FC = (props) => { }; return ( - +

{user.username}

@@ -112,31 +109,31 @@ const UserItem: React.FC = (props) => { - - + + Manage - - - + + + Change Username - - + + Change Password - - + + Change Permission - - + Delete - - - + + +
-
+ ); }; @@ -441,7 +438,7 @@ const UserAdmin: React.FC = (props) => { return ( <> - + ); } else if (step === "process") { body = ( - + {props.processPrompt?.() ?? } - + ); } else { let content: React.ReactNode; @@ -345,12 +332,12 @@ const OperationDialog: React.FC = (props) => { } body = ( <> - {content} - - - + ); } @@ -359,7 +346,7 @@ const OperationDialog: React.FC = (props) => { return ( - = (props) => { } > {title} - + {body} ); diff --git a/Timeline/ClientApp/src/app/views/common/alert/AlertHost.tsx b/Timeline/ClientApp/src/app/views/common/alert/AlertHost.tsx index 31c0fb86..c74f18e2 100644 --- a/Timeline/ClientApp/src/app/views/common/alert/AlertHost.tsx +++ b/Timeline/ClientApp/src/app/views/common/alert/AlertHost.tsx @@ -1,8 +1,8 @@ import React, { useCallback } from "react"; -import { Alert } from "reactstrap"; import without from "lodash/without"; import concat from "lodash/concat"; import { useTranslation } from "react-i18next"; +import { Alert } from "react-bootstrap"; import { alertService, @@ -37,7 +37,12 @@ export const AutoCloseAlert: React.FC = (props) => { }, [dismissTime, props.close]); return ( - + {(() => { const { message } = alert; if (typeof message === "function") { diff --git a/Timeline/ClientApp/src/app/views/login/index.tsx b/Timeline/ClientApp/src/app/views/login/index.tsx index e53d0002..5d1e8f06 100644 --- a/Timeline/ClientApp/src/app/views/login/index.tsx +++ b/Timeline/ClientApp/src/app/views/login/index.tsx @@ -1,15 +1,7 @@ import React, { Fragment, useState, useEffect } from "react"; import { useHistory } from "react-router"; import { useTranslation } from "react-i18next"; -import { - Label, - FormGroup, - Input, - Form, - FormFeedback, - Spinner, - Button, -} from "reactstrap"; +import { Form, Spinner, Button } from "react-bootstrap"; import { useUser, userService } from "@/services/user"; @@ -84,9 +76,9 @@ const LoginPage: React.FC = (_) => {

{t("welcome")}

- - - + {t("user.username")} + { @@ -94,15 +86,17 @@ const LoginPage: React.FC = (_) => { setUsernameDirty(true); }} value={username} - invalid={usernameDirty && username === ""} + isInvalid={usernameDirty && username === ""} /> {usernameDirty && username === "" && ( - {t("login.emptyUsername")} + + {t("login.emptyUsername")} + )} - - - - + + {t("user.password")} + { setPasswordDirty(true); }} value={password} - invalid={passwordDirty && password === ""} + isInvalid={passwordDirty && password === ""} /> {passwordDirty && password === "" && ( - {t("login.emptyPassword")} + + {t("login.emptyPassword")} + )} - - - + + id="remember-me" type="checkbox" checked={rememberMe} onChange={(e) => { - const v = (e.target as HTMLInputElement).checked; - setRememberMe(v); + setRememberMe(e.target.checked); }} + label={t("user.rememberMe")} /> - - + {error ?

{t(error)}

: null}
{process ? ( - + ) : ( - )} diff --git a/Timeline/ClientApp/src/app/views/timeline-common/TimelineItem.tsx b/Timeline/ClientApp/src/app/views/timeline-common/TimelineItem.tsx index f2441612..ce371015 100644 --- a/Timeline/ClientApp/src/app/views/timeline-common/TimelineItem.tsx +++ b/Timeline/ClientApp/src/app/views/timeline-common/TimelineItem.tsx @@ -1,19 +1,11 @@ import React from "react"; import clsx from "clsx"; -import { - Row, - Col, - Modal, - ModalHeader, - ModalBody, - ModalFooter, - Button, -} from "reactstrap"; import { Link } from "react-router-dom"; import { useTranslation } from "react-i18next"; import Svg from "react-inlinesvg"; import chevronDownIcon from "bootstrap-icons/icons/chevron-down.svg"; import trashIcon from "bootstrap-icons/icons/trash.svg"; +import { Row, Col, Modal, Button } from "react-bootstrap"; import { useAvatar } from "@/services/user"; import { TimelinePostInfo } from "@/services/timeline"; @@ -28,16 +20,18 @@ const TimelinePostDeleteConfirmDialog: React.FC<{ return ( - - {t("timeline.post.deleteDialog.title")} - - {t("timeline.post.deleteDialog.prompt")} - - - + ); }; diff --git a/Timeline/ClientApp/src/app/views/timeline-common/TimelineMember.tsx b/Timeline/ClientApp/src/app/views/timeline-common/TimelineMember.tsx index 99605922..67a8543a 100644 --- a/Timeline/ClientApp/src/app/views/timeline-common/TimelineMember.tsx +++ b/Timeline/ClientApp/src/app/views/timeline-common/TimelineMember.tsx @@ -1,14 +1,6 @@ import React, { useState } from "react"; import { useTranslation } from "react-i18next"; -import { - Container, - ListGroup, - ListGroupItem, - Modal, - Row, - Col, - Button, -} from "reactstrap"; +import { Container, ListGroup, Modal, Row, Col, Button } from "react-bootstrap"; import { User, useAvatar } from "@/services/user"; @@ -25,9 +17,9 @@ const TimelineMemberItem: React.FC<{ const avatar = useAvatar(user.username); return ( - + - + @@ -46,7 +38,7 @@ const TimelineMemberItem: React.FC<{ return (