This commit is contained in:
Benjamin Toby 2026-03-11 05:46:53 +00:00
parent 78adca7091
commit dd2e32007d
6 changed files with 87 additions and 21 deletions

View File

@ -16,7 +16,7 @@ export default function AdminHero({ title, ctas, description }: Props) {
const { pageProps } = useContext(AppContext); const { pageProps } = useContext(AppContext);
return ( return (
<Row className="w-full grid-cell-content justify-between"> <Row className="w-full grid-cell-content justify-between flex-nowrap items-start">
<Stack className="gap-2"> <Stack className="gap-2">
<H1 className="admin-h1">{title}</H1> <H1 className="admin-h1">{title}</H1>
{description ? ( {description ? (

View File

@ -0,0 +1,32 @@
import useStatus from "@/twui/components/hooks/useStatus";
import Img from "@/twui/components/layout/Img";
import { twMerge } from "tailwind-merge";
type Props = {
image_url?: string | null;
image_size?: number;
title?: string;
};
export default function Avatar({ image_url, image_size = 35, title }: Props) {
const { loading, setLoading } = useStatus();
if (!image_url) {
return (
<div
className={twMerge(
`bg-slate-100 dark:bg-white/10 rounded-full`,
``,
)}
style={{
width: `${image_size}px`,
height: `${image_size}px`,
}}
/>
);
}
return (
<Img circle size={image_size} src={image_url} alt={title || `Avatar`} />
);
}

View File

@ -0,0 +1,38 @@
import Avatar from "@/src/components/general/avatar";
import { AppContext } from "@/src/pages/_app";
import Tag from "@/twui/components/elements/Tag";
import Row from "@/twui/components/layout/Row";
import Span from "@/twui/components/layout/Span";
import Stack from "@/twui/components/layout/Stack";
import { useContext } from "react";
export default function UsersList() {
const { pageProps } = useContext(AppContext);
const { deployment_users } = pageProps;
return (
<Stack className="grid-cell-content">
{deployment_users?.map((dep_usr, index) => {
const is_super_admin = Boolean(dep_usr.is_super_admin);
return (
<Row key={index} className="w-full justify-between">
<Row>
<Avatar
image_url={dep_usr.image}
title={`${dep_usr.first_name} Image`}
image_size={40}
/>
<Span>
{dep_usr.first_name} {dep_usr.last_name}
</Span>
</Row>
<Row>
{is_super_admin ? <Tag>Super Admin</Tag> : null}
</Row>
</Row>
);
})}
</Stack>
);
}

View File

@ -2,6 +2,8 @@ import { Fragment, useContext } from "react";
import { AppContext } from "@/src/pages/_app"; import { AppContext } from "@/src/pages/_app";
import Divider from "@/twui/components/layout/Divider"; import Divider from "@/twui/components/layout/Divider";
import AdminHero from "@/src/components/general/admin/hero"; import AdminHero from "@/src/components/general/admin/hero";
import Button from "@/twui/components/layout/Button";
import UsersList from "./(sections)/users-list";
export default function Main() { export default function Main() {
const { pageProps } = useContext(AppContext); const { pageProps } = useContext(AppContext);
@ -11,8 +13,16 @@ export default function Main() {
<AdminHero <AdminHero
title={`Users`} title={`Users`}
description={<>All Users in this deployment</>} description={<>All Users in this deployment</>}
ctas={
<>
<Button title="Add User" href={`/admin/users/add-user`}>
Add User
</Button>
</>
}
/> />
<Divider /> <Divider />
<UsersList />
</Fragment> </Fragment>
); );
} }

View File

@ -1,40 +1,26 @@
import Avatar from "@/src/components/general/avatar";
import { AppContext } from "@/src/pages/_app"; import { AppContext } from "@/src/pages/_app";
import Dropdown from "@/twui/components/elements/Dropdown"; import Dropdown from "@/twui/components/elements/Dropdown";
import LinkList from "@/twui/components/elements/LinkList"; import LinkList from "@/twui/components/elements/LinkList";
import LucideIcon from "@/twui/components/elements/lucide-icon"; import LucideIcon from "@/twui/components/elements/lucide-icon";
import Paper from "@/twui/components/elements/Paper"; import Paper from "@/twui/components/elements/Paper";
import Divider from "@/twui/components/layout/Divider"; import Divider from "@/twui/components/layout/Divider";
import Img from "@/twui/components/layout/Img";
import Row from "@/twui/components/layout/Row"; import Row from "@/twui/components/layout/Row";
import Span from "@/twui/components/layout/Span"; import Span from "@/twui/components/layout/Span";
import { useContext } from "react"; import { useContext } from "react";
import { twMerge } from "tailwind-merge";
export default function HeaderUser() { export default function HeaderUser() {
const { pageProps } = useContext(AppContext); const { pageProps } = useContext(AppContext);
const { user } = pageProps; const { user } = pageProps;
const ICON_SIZE = 35;
return ( return (
<Dropdown <Dropdown
target={ target={
<Row className="-my-2"> <Row className="-my-2">
{user.image_thumbnail ? ( <Avatar
<Img image_url={user.image_thumbnail}
circle title={`${user.first_name} Image`}
size={ICON_SIZE}
src={user.image_thumbnail}
alt={`${user.first_name} Image`}
/> />
) : (
<div
className={twMerge(
`bg-slate-100 dark:bg-white/10 rounded-full w-[35px] h-[35px]`,
``,
)}
/>
)}
<Span>{user.first_name}</Span> <Span>{user.first_name}</Span>
<LucideIcon name="ChevronDown" size={17} /> <LucideIcon name="ChevronDown" size={17} />
</Row> </Row>

View File

@ -77,7 +77,7 @@
} }
.twui-button-primary * { .twui-button-primary * {
@apply text-primary-text; @apply text-primary-text font-semibold;
} }
.twui-h1, .twui-h1,