Skip to content

Commit

Permalink
various ui and library refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
xvvvyz committed Jul 2, 2024
1 parent 696717f commit a2dee0c
Show file tree
Hide file tree
Showing 39 changed files with 500 additions and 399 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import PageModalLoading from '@/_components/page-modal-loading';

const Loading = PageModalLoading;

export default Loading;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import PageModalLoading from '@/_components/page-modal-loading';

const Loading = PageModalLoading;

export default Loading;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import PageModalLoading from '@/_components/page-modal-loading';

const Loading = PageModalLoading;

export default Loading;

This file was deleted.

4 changes: 2 additions & 2 deletions app/(pages)/(private)/templates/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Button from '@/_components/button';
import Empty from '@/_components/empty';
import TemplateLinkListItemMenu from '@/_components/template-link-list-item-menu';
import TemplateMenu from '@/_components/template-menu';
import listTemplates from '@/_queries/list-templates';
import InformationCircleIcon from '@heroicons/react/24/outline/ExclamationCircleIcon';

Expand Down Expand Up @@ -32,7 +32,7 @@ const Page = async () => {
>
{template.name}
</Button>
<TemplateLinkListItemMenu templateId={template.id} />
<TemplateMenu templateId={template.id} />
</li>
))}
</ul>
Expand Down
37 changes: 20 additions & 17 deletions app/_components/account-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import Avatar from '@/_components/avatar';
import Menu from '@/_components/menu';
import DropdownMenu from '@/_components/dropdown-menu';
import signOut from '@/_mutations/sign-out';
import ArrowLeftStartOnRectangleIcon from '@heroicons/react/24/outline/ArrowLeftStartOnRectangleIcon';
import Bars3Icon from '@heroicons/react/24/outline/Bars3Icon';
Expand All @@ -17,21 +17,24 @@ const AccountMenu = ({ user }: AccountMenuProps) => {
const [isTransitioning, startTransition] = useTransition();

return (
<Menu className="h-full shrink-0">
<Menu.Button className="gap-2 rounded-sm border border-alpha-3 pl-2 hover:bg-alpha-1">
<Bars3Icon className="w-5" />
<Avatar
className="-m-px"
file={user?.user_metadata?.image_uri}
id={user?.id}
/>
</Menu.Button>
<Menu.Items className="mt-10">
<Menu.Item href="/account/profile" scroll={false}>
<DropdownMenu
trigger={
<div className="flex gap-2 rounded-sm border border-alpha-3 pl-2 transition-colors hover:bg-alpha-1">
<Bars3Icon className="w-5" />
<Avatar
className="-m-px"
file={user?.user_metadata?.image_uri}
id={user?.id}
/>
</div>
}
>
<DropdownMenu.Content className="mt-0.5">
<DropdownMenu.Button href="/account/profile" scroll={false}>
<Cog6ToothIcon className="w-5 text-fg-4" />
Account settings
</Menu.Item>
<Menu.Item
</DropdownMenu.Button>
<DropdownMenu.Button
loading={isTransitioning}
loadingText="Signing out…"
onClick={(e) => {
Expand All @@ -41,9 +44,9 @@ const AccountMenu = ({ user }: AccountMenuProps) => {
>
<ArrowLeftStartOnRectangleIcon className="w-5 text-fg-4" />
Sign out
</Menu.Item>
</Menu.Items>
</Menu>
</DropdownMenu.Button>
</DropdownMenu.Content>
</DropdownMenu>
);
};

Expand Down
119 changes: 119 additions & 0 deletions app/_components/dropdown-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
'use client';

import ButtonPrimitive from '@/_components/button';
import * as Primitive from '@radix-ui/react-dropdown-menu';
import { useToggle } from '@uidotdev/usehooks';
import * as React from 'react';
import { twMerge } from 'tailwind-merge';

const Button = React.forwardRef<
React.ElementRef<typeof Primitive.Item>,
React.ComponentPropsWithoutRef<typeof ButtonPrimitive>
>((props, ref) => (
<Item asChild ref={ref}>
<ButtonPrimitive colorScheme="transparent" {...props} />
</Item>
));

Button.displayName = ButtonPrimitive.displayName;

const Content = React.forwardRef<
React.ElementRef<typeof Primitive.Content>,
React.ComponentPropsWithoutRef<typeof Primitive.Content>
>(({ className, ...props }, ref) => (
<Primitive.Content
align="end"
ref={ref}
sideOffset={4}
className={twMerge(
'z-10 w-60 rounded border border-alpha-1 bg-bg-3 py-1 shadow-lg',
className,
)}
{...props}
/>
));

Content.displayName = Primitive.Content.displayName;

const Item = React.forwardRef<
React.ElementRef<typeof Primitive.Item>,
React.ComponentPropsWithoutRef<typeof Primitive.Item>
>(({ className, ...props }, ref) => (
<Primitive.Item
ref={ref}
className={twMerge(
'h-10 w-full justify-start gap-4 rounded-none border-0 bg-transparent ring-transparent ring-offset-0 focus:bg-alpha-1 focus:text-fg-2',
className,
)}
{...props}
/>
));

Item.displayName = Primitive.Item.displayName;

const Label = React.forwardRef<
React.ElementRef<typeof Primitive.Label>,
React.ComponentPropsWithoutRef<typeof Primitive.Label>
>(({ className, ...props }, ref) => (
<Primitive.Label
ref={ref}
className={twMerge('smallcaps px-2 py-1.5', className)}
{...props}
/>
));

Label.displayName = Primitive.Label.displayName;

const Root = React.forwardRef<
React.ElementRef<typeof Primitive.Trigger>,
React.ComponentPropsWithoutRef<typeof Primitive.Root> & {
trigger: React.ReactNode;
}
>(({ children, trigger, ...props }, ref) => {
const [open, toggleOpen] = useToggle(false);

return (
<Primitive.Root
modal={false}
onOpenChange={toggleOpen}
open={open}
{...props}
>
<Primitive.Trigger
asChild
className="cursor-pointer outline-none"
onClick={() => toggleOpen()}
onPointerDown={(e) => e.preventDefault()}
ref={ref}
>
{trigger}
</Primitive.Trigger>
{children}
</Primitive.Root>
);
});

Root.displayName = Primitive.Root.displayName;

const Separator = React.forwardRef<
React.ElementRef<typeof Primitive.Separator>,
React.ComponentPropsWithoutRef<typeof Primitive.Separator>
>(({ className, ...props }, ref) => (
<Primitive.Separator
ref={ref}
className={twMerge('my-1 h-px bg-alpha-1', className)}
{...props}
/>
));

Separator.displayName = Primitive.Separator.displayName;

export default Object.assign(Root, {
Button,
Content,
Group: Primitive.Group,
Item,
Label,
Portal: Primitive.Portal,
Separator,
});
8 changes: 7 additions & 1 deletion app/_components/event-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface EventCardProps {
isTeamMember?: boolean;
mission?: NonNullable<GetMissionWithSessionsData>;
subjectId: string;
totalModules?: number;
user?: User | null;
}

Expand All @@ -38,6 +39,7 @@ const EventCard = ({
isTeamMember,
mission,
subjectId,
totalModules,
user,
}: EventCardProps) => {
const comments = forceArray(event?.comments);
Expand All @@ -50,7 +52,11 @@ const EventCard = ({
<div className="flex flex-col gap-6 py-7">
{(showModule || event) && (
<div className="smallcaps flex justify-between gap-4 whitespace-nowrap px-4 align-baseline text-fg-4 sm:px-8">
{showModule && <>Module {(eventType.order as number) + 1}</>}
{showModule && (
<>
Module {(eventType.order as number) + 1} / {totalModules}
</>
)}
{event && (
<div className="flex min-w-0 flex-row items-center gap-4">
<span>{mission ? 'Completed' : 'Recorded'} by</span>
Expand Down
25 changes: 15 additions & 10 deletions app/_components/event-comment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Alert from '@/_components/alert';
import Avatar from '@/_components/avatar';
import DateTime from '@/_components/date-time';
import DirtyHtml from '@/_components/dirty-html';
import Menu from '@/_components/menu';
import DropdownMenu from '@/_components/dropdown-menu';
import deleteComment from '@/_mutations/delete-comment';
import { Database } from '@/_types/database';
import EllipsisVerticalIcon from '@heroicons/react/24/outline/EllipsisVerticalIcon';
Expand Down Expand Up @@ -59,17 +59,22 @@ const EventComment = ({
{!isPublic &&
!isArchived &&
(userId === profile.id || isTeamMember) && (
<Menu className="-mr-2 -mt-2.5">
<Menu.Button className="rounded-full p-2 hover:bg-alpha-1">
<EllipsisVerticalIcon className="w-5" />
</Menu.Button>
<Menu.Items>
<Menu.Item onClick={() => toggleDeleteAlert(true)}>
<DropdownMenu
trigger={
<div className="-mr-2 -mt-[0.7rem]">
<div className="rounded-full p-2 text-fg-3 transition-colors hover:bg-alpha-1 hover:text-fg-2">
<EllipsisVerticalIcon className="w-5" />
</div>
</div>
}
>
<DropdownMenu.Content className="-mt-8 mr-1.5">
<DropdownMenu.Button onClick={() => toggleDeleteAlert(true)}>
<TrashIcon className="w-5 text-fg-4" />
Delete comment
</Menu.Item>
</Menu.Items>
</Menu>
</DropdownMenu.Button>
</DropdownMenu.Content>
</DropdownMenu>
)}
</div>
<DirtyHtml className="mt-1">{content}</DirtyHtml>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
'use client';

import Alert from '@/_components/alert';
import Menu from '@/_components/menu';
import DropdownMenu from '@/_components/dropdown-menu';
import deleteEventType from '@/_mutations/delete-event-type';
import DocumentDuplicateIcon from '@heroicons/react/24/outline/DocumentDuplicateIcon';
import EllipsisVerticalIcon from '@heroicons/react/24/outline/EllipsisVerticalIcon';
import PencilIcon from '@heroicons/react/24/outline/PencilIcon';
import TrashIcon from '@heroicons/react/24/outline/TrashIcon';
import { useToggle } from '@uidotdev/usehooks';

interface EventTypeLinkListItemMenuProps {
interface EventTypeMenuProps {
eventTypeId: string;
subjectId: string;
}

const EventTypeLinkListItemMenu = ({
eventTypeId,
subjectId,
}: EventTypeLinkListItemMenuProps) => {
const EventTypeMenu = ({ eventTypeId, subjectId }: EventTypeMenuProps) => {
const [deleteAlert, toggleDeleteAlert] = useToggle(false);

return (
Expand All @@ -29,35 +26,38 @@ const EventTypeLinkListItemMenu = ({
onClose={toggleDeleteAlert}
onConfirm={() => deleteEventType(eventTypeId)}
/>
<Menu className="shrink-0">
<Menu.Button className="group flex h-full items-center justify-center px-2 text-fg-3 hover:text-fg-2">
<div className="rounded-full p-2 group-hover:bg-alpha-1">
<EllipsisVerticalIcon className="w-5" />
<DropdownMenu
trigger={
<div className="group flex items-center justify-center px-2 text-fg-3 hover:text-fg-2">
<div className="rounded-full p-2 group-hover:bg-alpha-1">
<EllipsisVerticalIcon className="w-5" />
</div>
</div>
</Menu.Button>
<Menu.Items className="mr-2 mt-2">
<Menu.Item
}
>
<DropdownMenu.Content className="-mt-12 mr-1.5">
<DropdownMenu.Button
href={`/subjects/${subjectId}/event-types/${eventTypeId}/edit`}
scroll={false}
>
<PencilIcon className="w-5 text-fg-4" />
Edit
</Menu.Item>
<Menu.Item
</DropdownMenu.Button>
<DropdownMenu.Button
href={`/templates/create/from-event-type/${eventTypeId}`}
scroll={false}
>
<DocumentDuplicateIcon className="w-5 text-fg-4" />
Create template
</Menu.Item>
<Menu.Item onClick={() => toggleDeleteAlert(true)}>
</DropdownMenu.Button>
<DropdownMenu.Button onClick={() => toggleDeleteAlert(true)}>
<TrashIcon className="w-5 text-fg-4" />
Delete
</Menu.Item>
</Menu.Items>
</Menu>
</DropdownMenu.Button>
</DropdownMenu.Content>
</DropdownMenu>
</>
);
};

export default EventTypeLinkListItemMenu;
export default EventTypeMenu;
4 changes: 2 additions & 2 deletions app/_components/event-types.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Button from '@/_components/button';
import EventTypeLinkListItemMenu from '@/_components/event-type-link-list-item-menu';
import EventTypeMenu from '@/_components/event-type-menu';
import Tip from '@/_components/tip';
import listSubjectEventTypes from '@/_queries/list-subject-event-types';
import ArrowUpRightIcon from '@heroicons/react/24/outline/ArrowUpRightIcon';
Expand Down Expand Up @@ -58,7 +58,7 @@ const EventTypes = async ({ isTeamMember, subjectId }: EventTypesProps) => {
)}
</Button>
{isTeamMember && (
<EventTypeLinkListItemMenu
<EventTypeMenu
eventTypeId={eventType.id}
subjectId={subjectId}
/>
Expand Down
Loading

0 comments on commit a2dee0c

Please sign in to comment.