diff --git a/app/src/assets/home.less b/app/src/assets/home.less
index 4ffc3ce5..ab8ef1d6 100644
--- a/app/src/assets/home.less
+++ b/app/src/assets/home.less
@@ -53,6 +53,44 @@
opacity: 1;
}
+ .sidebar-menu {
+ height: max-content;
+ width: 100%;
+
+ .sidebar-wrapper {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ height: max-content;
+ width: calc(100% - 0.5rem);
+ margin: 0.25rem;
+
+ img {
+ width: 2.5rem;
+ height: 2.5rem;
+ padding: 0.2rem;
+ border-radius: .5rem;
+ transform: translateY(0.05rem);
+ flex-shrink: 0;
+ }
+
+ .username {
+ margin: 0 auto 0 8px;
+ color: hsl(var(--text));
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-size: 14px;
+ font-family: var(--font-family-normal);
+ }
+
+ svg {
+ color: hsl(var(--text-secondary));
+ }
+ }
+ }
+
.conversation-list {
position: relative;
display: flex;
diff --git a/app/src/assets/main.less b/app/src/assets/main.less
index 4ac19bb9..96de0ac4 100644
--- a/app/src/assets/main.less
+++ b/app/src/assets/main.less
@@ -1,5 +1,6 @@
@import "ui";
@font-family: Andika,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
+@font-family-normal: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
@line-height: 1.5;
@font-weight: 400;
@@ -35,6 +36,7 @@ html, body {
-moz-osx-font-smoothing: @-moz-osx-font-smoothing;
-webkit-text-size-adjust: @-webkit-text-size-adjust;
--font-family: @font-family;
+ --font-family-normal: @font-family-normal;
}
* {
diff --git a/app/src/assets/ui.less b/app/src/assets/ui.less
index 59c7aa4e..ea4ea1af 100644
--- a/app/src/assets/ui.less
+++ b/app/src/assets/ui.less
@@ -65,8 +65,8 @@
}
&.badge-gold {
- color: rgb(146, 114, 1) !important;
- background: rgb(250, 230, 158) !important;
+ color: rgb(164, 128, 0) !important;
+ background: rgb(255, 231, 145) !important;
}
}
}
diff --git a/app/src/components/SelectGroup.tsx b/app/src/components/SelectGroup.tsx
index ebcd432a..bf5a6e2b 100644
--- a/app/src/components/SelectGroup.tsx
+++ b/app/src/components/SelectGroup.tsx
@@ -12,7 +12,7 @@ import { Badge } from "./ui/badge.tsx";
export type SelectItemBadgeProps = {
variant: "default" | "gold";
name: string;
-}
+};
export type SelectItemProps = {
name: string;
@@ -32,12 +32,11 @@ function GroupSelectItem(props: SelectItemProps) {
return (
<>
{props.value}
- {
- props.badge &&
+ {props.badge && (
{props.badge.name}
- }
+ )}
>
);
}
diff --git a/app/src/components/app/MenuBar.tsx b/app/src/components/app/MenuBar.tsx
new file mode 100644
index 00000000..dbf43196
--- /dev/null
+++ b/app/src/components/app/MenuBar.tsx
@@ -0,0 +1,86 @@
+import { useTranslation } from "react-i18next";
+import { useDispatch, useSelector } from "react-redux";
+import { logout, selectUsername } from "../../store/auth.ts";
+import {
+ openDialog as openQuotaDialog,
+ quotaSelector,
+} from "../../store/quota.ts";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from "../ui/dropdown-menu.tsx";
+import { Button } from "../ui/button.tsx";
+import {
+ BadgeCent,
+ Boxes,
+ CalendarPlus,
+ Cloud,
+ ListStart,
+ Plug,
+} from "lucide-react";
+import { openDialog as openSub } from "../../store/subscription.ts";
+import { openDialog as openPackageDialog } from "../../store/package.ts";
+import { openDialog as openSharingDialog } from "../../store/sharing.ts";
+import { openDialog as openApiDialog } from "../../store/api.ts";
+
+type MenuBarProps = {
+ children: React.ReactNode;
+ className?: string;
+};
+
+function MenuBar({ children, className }: MenuBarProps) {
+ const { t } = useTranslation();
+ const dispatch = useDispatch();
+ const username = useSelector(selectUsername);
+ const quota = useSelector(quotaSelector);
+
+ return (
+
+ {children}
+
+ {username}
+
+ dispatch(openQuotaDialog())}>
+
+ {quota}
+
+ dispatch(openQuotaDialog())}>
+
+ {t("quota")}
+
+ dispatch(openSub())}>
+
+ {t("sub.title")}
+
+ dispatch(openPackageDialog())}>
+
+ {t("pkg.title")}
+
+ dispatch(openSharingDialog())}>
+
+ {t("share.manage")}
+
+ dispatch(openApiDialog())}>
+
+ {t("api.title")}
+
+
+
+
+
+
+
+ );
+}
+
+export default MenuBar;
diff --git a/app/src/components/app/NavBar.tsx b/app/src/components/app/NavBar.tsx
index 6e04c679..a817bfae 100644
--- a/app/src/components/app/NavBar.tsx
+++ b/app/src/components/app/NavBar.tsx
@@ -2,37 +2,12 @@ import "@/assets/navbar.less";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import {
- logout,
selectAuthenticated,
selectUsername,
validateToken,
} from "../../store/auth.ts";
-import {
- openDialog as openQuotaDialog,
- quotaSelector,
-} from "../../store/quota.ts";
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuTrigger,
-} from "../ui/dropdown-menu.tsx";
import { Button } from "../ui/button.tsx";
-import {
- BadgeCent,
- Boxes,
- CalendarPlus,
- Cloud,
- ListStart,
- Menu,
- Plug,
-} from "lucide-react";
-import { openDialog as openSub } from "../../store/subscription.ts";
-import { openDialog as openPackageDialog } from "../../store/package.ts";
-import { openDialog as openSharingDialog } from "../../store/sharing.ts";
-import { openDialog as openApiDialog } from "../../store/api.ts";
+import { Menu } from "lucide-react";
import { useEffect } from "react";
import { login, tokenField } from "../../conf.ts";
import { toggleMenu } from "../../store/menu.ts";
@@ -40,62 +15,18 @@ import ProjectLink from "../ProjectLink.tsx";
import ModeToggle from "../ThemeProvider.tsx";
import I18nProvider from "../I18nProvider.tsx";
import router from "../../router.tsx";
+import MenuBar from "./MenuBar.tsx";
-function MenuBar() {
- const { t } = useTranslation();
- const dispatch = useDispatch();
+function NavMenu() {
const username = useSelector(selectUsername);
- const quota = useSelector(quotaSelector);
return (
-
-
-
-
-
-
- {username}
-
-
- dispatch(openQuotaDialog())}>
-
- {quota}
-
- dispatch(openQuotaDialog())}>
-
- {t("quota")}
-
- dispatch(openSub())}>
-
- {t("sub.title")}
-
- dispatch(openPackageDialog())}>
-
- {t("pkg.title")}
-
- dispatch(openSharingDialog())}>
-
- {t("share.manage")}
-
- dispatch(openApiDialog())}>
-
- {t("api.title")}
-
-
-
-
-
-
-
+
+
+
);
}
@@ -129,7 +60,7 @@ function NavBar() {
{auth ? (
-
+
) : (