Add avatar in top bar
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { mapProp, Update } from "@/hooks/useStore";
|
||||
import { mapProp } from "@/hooks/useStore";
|
||||
import { Update } from "common";
|
||||
import { getMediaTypeForFile } from "common/MediaType";
|
||||
|
||||
export function FileReducer(prev: FileReducer.State, action: FileReducer.Action): FileReducer.State {
|
||||
|
||||
48
packages/frontend/src/components/ui/avatar.tsx
Normal file
48
packages/frontend/src/components/ui/avatar.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
||||
import * as React from "react";
|
||||
|
||||
const Avatar = React.forwardRef<
|
||||
React.ElementRef<typeof AvatarPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<AvatarPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
||||
|
||||
const AvatarImage = React.forwardRef<
|
||||
React.ElementRef<typeof AvatarPrimitive.Image>,
|
||||
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<AvatarPrimitive.Image
|
||||
ref={ref}
|
||||
className={cn("aspect-square h-full w-full", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
||||
|
||||
const AvatarFallback = React.forwardRef<
|
||||
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
||||
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<AvatarPrimitive.Fallback
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-full w-full items-center justify-center rounded-full bg-muted",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
||||
;
|
||||
export { Avatar, AvatarFallback, AvatarImage };
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { API_URL_PREFIX, client } from "@/client";
|
||||
import { Button, buttonVariants } from "@/components/ui/button";
|
||||
import { Avatar, AvatarImage } from "@/components/ui/avatar";
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||
import { setUser, useStore } from "@/hooks/useStore";
|
||||
import { Effect, Option, pipe } from "effect";
|
||||
import { LogOut, Settings, User } from "lucide-react";
|
||||
import { LogOut, Settings } from "lucide-react";
|
||||
import { useEffect } from "react";
|
||||
import { Link, Outlet, useNavigate } from "react-router-dom";
|
||||
|
||||
@@ -46,15 +47,15 @@ export function Root() {
|
||||
|
||||
return (
|
||||
<div className="w-full h-full overflow-hidden flex flex-col items-stretch">
|
||||
<div className="flex p-4 justify-between items-baseline border-b">
|
||||
<div className="flex p-4 justify-between items-center border-b">
|
||||
<Link className={buttonVariants({ variant: "outline" })} to="/">
|
||||
Repozytorium muzyczne
|
||||
</Link>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button type="button" variant="outline">
|
||||
<User />{Option.getOrElse(user.displayName, () => user.userId)}
|
||||
</Button>
|
||||
<Avatar className="shadow">
|
||||
<AvatarImage src={Option.getOrUndefined(user.avatarUrl)} />
|
||||
</Avatar>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem asChild>
|
||||
|
||||
57
pnpm-lock.yaml
generated
57
pnpm-lock.yaml
generated
@@ -12,6 +12,9 @@ catalogs:
|
||||
'@eslint/js':
|
||||
specifier: ^9.37.0
|
||||
version: 9.37.0
|
||||
'@radix-ui/react-avatar':
|
||||
specifier: ^1.1.10
|
||||
version: 1.1.10
|
||||
'@radix-ui/react-dialog':
|
||||
specifier: ^1.1.15
|
||||
version: 1.1.15
|
||||
@@ -169,6 +172,9 @@ importers:
|
||||
|
||||
packages/frontend:
|
||||
dependencies:
|
||||
'@radix-ui/react-avatar':
|
||||
specifier: 'catalog:'
|
||||
version: 1.1.10(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
'@radix-ui/react-dialog':
|
||||
specifier: 'catalog:'
|
||||
version: 1.1.15(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
@@ -718,6 +724,19 @@ packages:
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-avatar@1.1.10':
|
||||
resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-collection@1.1.7':
|
||||
resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==}
|
||||
peerDependencies:
|
||||
@@ -964,6 +983,15 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-use-is-hydrated@0.1.0':
|
||||
resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-use-layout-effect@1.1.1':
|
||||
resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==}
|
||||
peerDependencies:
|
||||
@@ -2502,6 +2530,11 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
use-sync-external-store@1.6.0:
|
||||
resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
@@ -3086,6 +3119,19 @@ snapshots:
|
||||
'@types/react': 19.2.2
|
||||
'@types/react-dom': 19.2.1(@types/react@19.2.2)
|
||||
|
||||
'@radix-ui/react-avatar@1.1.10(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
|
||||
dependencies:
|
||||
'@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0)
|
||||
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0)
|
||||
'@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.2)(react@19.2.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0)
|
||||
react: 19.2.0
|
||||
react-dom: 19.2.0(react@19.2.0)
|
||||
optionalDependencies:
|
||||
'@types/react': 19.2.2
|
||||
'@types/react-dom': 19.2.1(@types/react@19.2.2)
|
||||
|
||||
'@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
|
||||
dependencies:
|
||||
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
|
||||
@@ -3324,6 +3370,13 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/react': 19.2.2
|
||||
|
||||
'@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.2.2)(react@19.2.0)':
|
||||
dependencies:
|
||||
react: 19.2.0
|
||||
use-sync-external-store: 1.6.0(react@19.2.0)
|
||||
optionalDependencies:
|
||||
'@types/react': 19.2.2
|
||||
|
||||
'@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.2)(react@19.2.0)':
|
||||
dependencies:
|
||||
react: 19.2.0
|
||||
@@ -4977,6 +5030,10 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/react': 19.2.2
|
||||
|
||||
use-sync-external-store@1.6.0(react@19.2.0):
|
||||
dependencies:
|
||||
react: 19.2.0
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
vexflow@1.2.93: {}
|
||||
|
||||
@@ -12,6 +12,7 @@ onlyBuiltDependencies:
|
||||
catalog:
|
||||
'@effect/language-service': '^0.21.8'
|
||||
'@eslint/js': '^9.37.0'
|
||||
'@radix-ui/react-avatar': '^1.1.10'
|
||||
'@radix-ui/react-dialog': '^1.1.15'
|
||||
'@radix-ui/react-dropdown-menu': '^2.1.16'
|
||||
'@radix-ui/react-label': '^2.1.7'
|
||||
|
||||
Reference in New Issue
Block a user