| 274 | // ── UserFooter ────────────────────────────────────────────────────────── |
| 275 | |
| 276 | function UserFooter(props: Pick<ShellProps, "onSignOut" | "orgMenuSlot">) { |
| 277 | const auth = useAuth(); |
| 278 | if (auth.status !== "authenticated") return null; |
| 279 | |
| 280 | return ( |
| 281 | <div className="shrink-0 border-t border-sidebar-border px-3 py-2.5"> |
| 282 | <DropdownMenu> |
| 283 | <DropdownMenuTrigger asChild> |
| 284 | <Button |
| 285 | type="button" |
| 286 | variant="ghost" |
| 287 | className="flex h-auto w-full items-center justify-start gap-2.5 rounded-md px-1 py-1 text-left hover:bg-sidebar-active/60" |
| 288 | > |
| 289 | <Avatar url={auth.user.avatarUrl} name={auth.user.name} email={auth.user.email} /> |
| 290 | <div className="min-w-0 flex-1"> |
| 291 | <p className="truncate text-xs font-medium text-foreground"> |
| 292 | {auth.user.name ?? auth.user.email} |
| 293 | </p> |
| 294 | {auth.organization && ( |
| 295 | <p className="truncate text-xs text-muted-foreground">{auth.organization.name}</p> |
| 296 | )} |
| 297 | </div> |
| 298 | <svg |
| 299 | viewBox="0 0 16 16" |
| 300 | fill="none" |
| 301 | className="size-3.5 shrink-0 text-muted-foreground" |
| 302 | > |
| 303 | <path |
| 304 | d="M4 6l4 4 4-4" |
| 305 | stroke="currentColor" |
| 306 | strokeWidth="1.3" |
| 307 | strokeLinecap="round" |
| 308 | strokeLinejoin="round" |
| 309 | /> |
| 310 | </svg> |
| 311 | </Button> |
| 312 | </DropdownMenuTrigger> |
| 313 | <DropdownMenuContent align="start" side="top" className="w-64"> |
| 314 | {props.orgMenuSlot} |
| 315 | <DropdownMenuLabel className="text-xs font-normal text-muted-foreground"> |
| 316 | Signed in as |
| 317 | </DropdownMenuLabel> |
| 318 | <DropdownMenuItem disabled className="gap-2 text-xs opacity-100"> |
| 319 | <Avatar url={auth.user.avatarUrl} name={auth.user.name} email={auth.user.email} /> |
| 320 | <div className="min-w-0 flex-1"> |
| 321 | <p className="truncate font-medium text-foreground"> |
| 322 | {auth.user.name ?? auth.user.email} |
| 323 | </p> |
| 324 | {auth.user.name && ( |
| 325 | <p className="truncate text-muted-foreground">{auth.user.email}</p> |
| 326 | )} |
| 327 | </div> |
| 328 | </DropdownMenuItem> |
| 329 | <DropdownMenuItem |
| 330 | className="text-xs text-destructive focus:text-destructive" |
| 331 | onClick={() => void props.onSignOut()} |
| 332 | > |
| 333 | Sign out |