diff options
author | crupest <crupest@outlook.com> | 2023-07-15 23:54:25 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2023-07-15 23:54:25 +0800 |
commit | 2514e709c3ad0a5b7fc62b67462c8ba668f89d2c (patch) | |
tree | a74511641a553774c7ca3dad38890b73956ca5fc /FrontEnd/src/views | |
parent | 85659d977ac501a13886c1c7098763935af416e2 (diff) | |
download | timeline-2514e709c3ad0a5b7fc62b67462c8ba668f89d2c.tar.gz timeline-2514e709c3ad0a5b7fc62b67462c8ba668f89d2c.tar.bz2 timeline-2514e709c3ad0a5b7fc62b67462c8ba668f89d2c.zip |
...
Diffstat (limited to 'FrontEnd/src/views')
-rw-r--r-- | FrontEnd/src/views/common/AppBar.css | 53 | ||||
-rw-r--r-- | FrontEnd/src/views/common/AppBar.tsx | 73 | ||||
-rw-r--r-- | FrontEnd/src/views/common/breakpoints.ts | 3 | ||||
-rw-r--r-- | FrontEnd/src/views/common/common.ts | 3 | ||||
-rw-r--r-- | FrontEnd/src/views/common/hooks.ts | 14 | ||||
-rw-r--r-- | FrontEnd/src/views/common/index.css | 9 |
6 files changed, 117 insertions, 38 deletions
diff --git a/FrontEnd/src/views/common/AppBar.css b/FrontEnd/src/views/common/AppBar.css index 272a99ad..67fd9516 100644 --- a/FrontEnd/src/views/common/AppBar.css +++ b/FrontEnd/src/views/common/AppBar.css @@ -1,6 +1,4 @@ .app-bar {
- display: flex;
- align-items: center;
height: 56px;
position: fixed;
z-index: 1030;
@@ -8,52 +6,53 @@ left: 0;
right: 0;
background-color: var(--cru-primary-color);
- transition: background-color 1s;
}
-.app-bar .cru-avatar {
- background-color: white;
+.app-bar.desktop {
+ display: flex;
}
-.app-bar a {
- color: var(--cru-primary-on-color);
- text-decoration: none;
- margin: 0 1em;
- transition: color 1s;
+.app-bar.desktop .app-bar-brand {
+ display: flex;
+ align-items: center;
}
-.app-bar a:hover {
- color: var(--cru-primary-on-color);
+.app-bar.desktop .app-bar-brand-icon {
+ height: 2em;
}
-.app-bar a.active {
- color: var(--cru-primary-on-color);
+.app-bar.desktop .app-bar-main-area {
+ display: flex;
+ flex-grow: 1;
}
-.app-bar-brand {
+.app-bar.desktop .app-bar-link-area {
+ display: flex;
+}
+
+.app-bar.desktop a {
+ background-color: var(--cru-primary-color);
+ color: var(--cru-primary-on-color);
+ text-decoration: none;
display: flex;
align-items: center;
+ padding: 0 1em;
}
-.app-bar-brand-icon {
- height: 2em;
+.app-bar.desktop a:hover {
+ filter: brightness(var(--cru-hover-brightness));
}
-.app-bar-main-area {
- display: flex;
- flex-grow: 1;
+.app-bar.desktop a:focus {
+ filter: brightness(var(--cru-focus-brightness));
}
-.app-bar-link-area {
- display: flex;
- align-items: center;
- flex-shrink: 0;
+.app-bar.desktop a:active {
+ filter: brightness(var(--cru-press-brightness));
}
-.app-bar-user-area {
+.app-bar.desktop .app-bar-user-area {
display: flex;
- align-items: center;
- flex-shrink: 0;
margin-left: auto;
}
diff --git a/FrontEnd/src/views/common/AppBar.tsx b/FrontEnd/src/views/common/AppBar.tsx index 444d903e..180d0db6 100644 --- a/FrontEnd/src/views/common/AppBar.tsx +++ b/FrontEnd/src/views/common/AppBar.tsx @@ -3,7 +3,7 @@ import classnames from "classnames"; import { Link, NavLink } from "react-router-dom"; import { useMediaQuery } from "react-responsive"; -import { useC } from "./common"; +import { I18nText, useC, useMobile } from "./common"; import { useUser } from "@/services/user"; import TimelineLogo from "./TimelineLogo"; @@ -11,7 +11,71 @@ import UserAvatar from "./user/UserAvatar"; import "./AppBar.css"; -export default function AppBar() { +function AppBarNavLink({ + link, + className, + label, + children, +}: { + link: string; + className?: string; + label?: I18nText; + children?: React.ReactNode; +}) { + if (label != null && children != null) { + throw new Error("AppBarNavLink: label and children cannot be both set"); + } + + const c = useC(); + + return ( + <NavLink + to={link} + className={({ isActive }) => classnames(className, isActive && "active")} + > + {children != null ? children : c(label)} + </NavLink> + ); +} + +function DesktopAppBar() { + const user = useUser(); + const hasAdministrationPermission = user && user.hasAdministrationPermission; + + return ( + <nav className="desktop app-bar"> + <Link to="/" className="app-bar-brand active"> + <TimelineLogo className="app-bar-brand-icon" /> + Timeline + </Link> + <div className="app-bar-main-area"> + <div className="app-bar-link-area"> + <AppBarNavLink link="/settings" label="nav.settings" /> + <AppBarNavLink link="/about" label="nav.about" /> + {hasAdministrationPermission && ( + <AppBarNavLink link="/admin" label="nav.administration" /> + )} + </div> + + <div className="app-bar-user-area"> + {user != null ? ( + <AppBarNavLink link="/" className="app-bar-avatar"> + <UserAvatar + username={user.username} + className="cru-avatar small cru-round cursor-pointer ml-auto" + /> + </AppBarNavLink> + ) : ( + <AppBarNavLink link="/login" label="nav.login" /> + )} + </div> + </div> + </nav> + ); +} + +// TODO: Go make this! +function MobileAppBar() { const c = useC(); const user = useUser(); @@ -77,3 +141,8 @@ export default function AppBar() { </nav> ); } + +export default function AppBar() { + const isMobile = useMobile(); + return isMobile ? <MobileAppBar /> : <DesktopAppBar />; +} diff --git a/FrontEnd/src/views/common/breakpoints.ts b/FrontEnd/src/views/common/breakpoints.ts new file mode 100644 index 00000000..fb281610 --- /dev/null +++ b/FrontEnd/src/views/common/breakpoints.ts @@ -0,0 +1,3 @@ +export const breakpoints = { + sm: 576, +} as const; diff --git a/FrontEnd/src/views/common/common.ts b/FrontEnd/src/views/common/common.ts index e3a5a2a2..d3db9f93 100644 --- a/FrontEnd/src/views/common/common.ts +++ b/FrontEnd/src/views/common/common.ts @@ -10,3 +10,6 @@ export const themeColors = [ ] as const; export type ThemeColor = (typeof themeColors)[number]; + +export { breakpoints } from "./breakpoints"; +export { useMobile } from "./hooks"; diff --git a/FrontEnd/src/views/common/hooks.ts b/FrontEnd/src/views/common/hooks.ts new file mode 100644 index 00000000..c1fa5774 --- /dev/null +++ b/FrontEnd/src/views/common/hooks.ts @@ -0,0 +1,14 @@ +// TODO: Migrate hooks + +export { + useIsSmallScreen, + useClickOutside, + useScrollToBottom, +} from "@/utilities/hooks"; + +import { useMediaQuery } from "react-responsive"; +import { breakpoints } from "./breakpoints"; + +export function useMobile(): boolean { + return useMediaQuery({ maxWidth: breakpoints.sm }); +} diff --git a/FrontEnd/src/views/common/index.css b/FrontEnd/src/views/common/index.css index bd556a81..f87fdfd2 100644 --- a/FrontEnd/src/views/common/index.css +++ b/FrontEnd/src/views/common/index.css @@ -6,21 +6,12 @@ margin-block: 0;
}
-*::before {
- box-sizing: border-box;
-}
-
-*::after {
- box-sizing: border-box;
-}
-
body {
font-family: var(--cru-default-font-family);
background: var(--cru-surface-color);
color: var(--cru-surface-on-color);
}
-
.cru-text-center {
text-align: center;
}
|