Skip to content

Commit

Permalink
add user container in sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
zmh-program committed Oct 25, 2023
1 parent e32fa87 commit bf56062
Show file tree
Hide file tree
Showing 9 changed files with 456 additions and 338 deletions.
38 changes: 38 additions & 0 deletions app/src/assets/home.less
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions app/src/assets/main.less
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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;
}

* {
Expand Down
4 changes: 2 additions & 2 deletions app/src/assets/ui.less
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions app/src/components/SelectGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Badge } from "./ui/badge.tsx";
export type SelectItemBadgeProps = {
variant: "default" | "gold";
name: string;
}
};

export type SelectItemProps = {
name: string;
Expand All @@ -32,12 +32,11 @@ function GroupSelectItem(props: SelectItemProps) {
return (
<>
{props.value}
{
props.badge &&
{props.badge && (
<Badge className={`badge ml-1 badge-${props.badge.variant}`}>
{props.badge.name}
</Badge>
}
)}
</>
);
}
Expand Down
86 changes: 86 additions & 0 deletions app/src/components/app/MenuBar.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<DropdownMenu>
<DropdownMenuTrigger asChild>{children}</DropdownMenuTrigger>
<DropdownMenuContent className={className} align={`end`}>
<DropdownMenuLabel className={`username`}>{username}</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => dispatch(openQuotaDialog())}>
<Cloud className={`h-4 w-4 mr-1`} />
{quota}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openQuotaDialog())}>
<BadgeCent className={`h-4 w-4 mr-1`} />
{t("quota")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openSub())}>
<CalendarPlus className={`h-4 w-4 mr-1`} />
{t("sub.title")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openPackageDialog())}>
<Boxes className={`h-4 w-4 mr-1`} />
{t("pkg.title")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openSharingDialog())}>
<ListStart className={`h-4 w-4 mr-1`} />
{t("share.manage")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openApiDialog())}>
<Plug className={`h-4 w-4 mr-1`} />
{t("api.title")}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Button
size={`sm`}
className={`action-button`}
onClick={() => dispatch(logout())}
>
{t("logout")}
</Button>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}

export default MenuBar;
87 changes: 9 additions & 78 deletions app/src/components/app/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,100 +2,31 @@ 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";
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 (
<div className={`avatar`}>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant={`ghost`} size={`icon`}>
<img src={`https://api.deeptrain.net/avatar/${username}`} alt="" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align={`end`}>
<DropdownMenuLabel className={`username`}>
{username}
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => dispatch(openQuotaDialog())}>
<Cloud className={`h-4 w-4 mr-1`} />
{quota}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openQuotaDialog())}>
<BadgeCent className={`h-4 w-4 mr-1`} />
{t("quota")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openSub())}>
<CalendarPlus className={`h-4 w-4 mr-1`} />
{t("sub.title")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openPackageDialog())}>
<Boxes className={`h-4 w-4 mr-1`} />
{t("pkg.title")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openSharingDialog())}>
<ListStart className={`h-4 w-4 mr-1`} />
{t("share.manage")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openApiDialog())}>
<Plug className={`h-4 w-4 mr-1`} />
{t("api.title")}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Button
size={`sm`}
className={`action-button`}
onClick={() => dispatch(logout())}
>
{t("logout")}
</Button>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<MenuBar>
<Button variant={`ghost`} size={`icon`}>
<img src={`https://api.deeptrain.net/avatar/${username}`} alt="" />
</Button>
</MenuBar>
</div>
);
}
Expand Down Expand Up @@ -129,7 +60,7 @@ function NavBar() {
<ModeToggle />
<I18nProvider />
{auth ? (
<MenuBar />
<NavMenu />
) : (
<Button size={`sm`} onClick={login}>
{t("login")}
Expand Down
13 changes: 8 additions & 5 deletions app/src/components/home/ModelSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useToast } from "../ui/use-toast.ts";
import { useEffect } from "react";
import { Model } from "../../conversation/types.ts";
import { modelEvent } from "../../events/model.ts";
import {isSubscribedSelector} from "../../store/subscription.ts";
import { isSubscribedSelector } from "../../store/subscription.ts";

function GetModel(name: string): Model {
return supportModels.find((model) => model.id === name) as Model;
Expand Down Expand Up @@ -39,10 +39,13 @@ function ModelSelector() {
(model: Model): SelectItemProps => ({
name: model.id,
value: model.name,
badge: (model.free || (subscription && model.id === "gpt-4")) ? {
variant: model.free ? "default" : "gold",
name: model.free ? "free" : "plus",
} : undefined,
badge:
model.free || (subscription && model.id === "gpt-4")
? {
variant: model.free ? "default" : "gold",
name: model.free ? "free" : "plus",
}
: undefined,
}),
);

Expand Down
Loading

0 comments on commit bf56062

Please sign in to comment.