Skip to content

Commit

Permalink
List attendees
Browse files Browse the repository at this point in the history
  • Loading branch information
kearfy committed Feb 20, 2024
1 parent 7bd3102 commit 6b7c660
Show file tree
Hide file tree
Showing 8 changed files with 290 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,7 @@ export default function Account() {
<EventTable events={events ?? []} />
</div>
) : (
<EventGrid
organisationSlug={slug}
manageButton
viewButton
events={events ?? []}
/>
<EventGrid manageButton viewButton events={events ?? []} />
)}
</div>
<div className="flex items-center justify-end gap-10 pt-2">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
'use client';

import { AttendsTable } from '@/components/data/attends/table';
import { LoaderOverlay } from '@/components/layout/LoaderOverlay';
import { NotFoundScreen } from '@/components/layout/NotFoundScreen';
import { Pagination, usePagination } from '@/components/logic/Pagination';
import { Button } from '@/components/ui/button';
import { useSurreal } from '@/lib/Surreal';
import { RichAttends } from '@/schema/relations/attends';
import { Event } from '@/schema/resources/event';
import { useQuery } from '@tanstack/react-query';
import { RefreshCw } from 'lucide-react';
import { useTranslations } from 'next-intl';
import React from 'react';
import { z } from 'zod';

export default function EventAttendeesTab({ event }: { event: Event }) {
const pagination = usePagination();

const t = useTranslations('pages.console.organisation.events');
const { isPending, data, refetch, error } = useData({
event: event.id,
pagination,
});
console.log(error);

if (isPending) return <LoaderOverlay />;
if (!data) return <NotFoundScreen text={t('not_found')} />;

const { attendees, count } = data;

return (
<div className="flex flex-grow flex-col gap-6 pt-6">
<div className="flex justify-start gap-4 pb-2">
<Button variant="outline" size="icon" onClick={() => refetch()}>
<RefreshCw size={20} />
</Button>
</div>
<div className="rounded-md border">
<AttendsTable attendees={attendees ?? []} />
</div>
<div className="flex items-center justify-end gap-10 pt-2">
<Pagination pagination={pagination} count={count} />
</div>
</div>
);
}

function useData({
event,
published,
discoverable,
pagination: { start, limit },
}: {
event: Event['id'];
published?: boolean;
discoverable?: boolean;
pagination: {
start: number;
limit: number;
};
}) {
const surreal = useSurreal();
return useQuery({
queryKey: ['organisation', 'event-attendees', event, { start, limit }],
retry: false,
queryFn: async () => {
console.log(0);
const result = await surreal.query<
[null[], RichAttends[], { count: number }[]]
>(
/* surql */ `
LET $event = <record<event>> $event;
SELECT * FROM $event<-attends
START $start
LIMIT $limit
FETCH in, out, players.*;
SELECT count() FROM $event<-attends
GROUP ALL;
`,
{
event,
published,
discoverable,
start,
limit,
}
);

console.log(1, result);
if (!result?.[1] || !result?.[2]) return null;

return {
count: z.number().parse(result[2][0]?.count ?? 0),
attendees: z.array(RichAttends).parse(result[1]),
};
},
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,10 @@ import { Organisation } from '@/schema/resources/organisation';
import { useQuery } from '@tanstack/react-query';
import { LayoutGrid, List, RefreshCw } from 'lucide-react';
import { useTranslations } from 'next-intl';
import { useParams } from 'next/navigation';
import React, { useState } from 'react';
import { z } from 'zod';

export default function EventEventsTab({ event }: { event: Event }) {
const params = useParams();
const slug = Array.isArray(params.organisation)
? params.organisation[0]
: params.organisation;

const [view, setView] = useState<'table' | 'cards'>('table');
const eventFilters = useEventFilters();
const pagination = usePagination();
Expand Down Expand Up @@ -95,12 +89,7 @@ export default function EventEventsTab({ event }: { event: Event }) {
<EventTable events={events ?? []} />
</div>
) : (
<EventGrid
organisationSlug={slug}
manageButton
viewButton
events={events ?? []}
/>
<EventGrid manageButton viewButton events={events ?? []} />
)}
</div>
<div className="flex items-center justify-end gap-10 pt-2">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { useParams } from 'next/navigation';
import React from 'react';
import { z } from 'zod';
import { TinyOrgName } from '../../../components/TinyOrgName';
import EventAttendeesTab from './attendees';
import EventEventsTab from './events';
import { EventOverviewTab } from './overview';
import { EventSettingsTab } from './settings';
Expand All @@ -41,8 +42,6 @@ export default function Account() {
event_id,
});

console.log(data);

if (isPending) return <LoaderOverlay />;
if (!data?.organisation) return <NotFoundScreen text={t('not_found')} />;

Expand Down Expand Up @@ -107,7 +106,7 @@ export default function Account() {
</Link>
</div>
<Tab value="overview">Overview</Tab>
<Tab value="registrations">Registrations</Tab>
<Tab value="attendees">Attendees</Tab>
<Tab value="events">Events</Tab>
{organisation.can_manage && (
<Tab
Expand All @@ -123,8 +122,8 @@ export default function Account() {
<TabsContent value="overview">
<EventOverviewTab event={event} />
</TabsContent>
<TabsContent value="registrations">
Registrations
<TabsContent value="attendees">
<EventAttendeesTab event={event} />
</TabsContent>
<TabsContent value="events">
<EventEventsTab event={event} />
Expand Down

This file was deleted.

170 changes: 170 additions & 0 deletions src/components/data/attends/table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { Avatar } from '@/components/cards/avatar';
import { Profile } from '@/components/cards/profile';
import { DateTooltip } from '@/components/miscellaneous/DateTooltip';
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import { RichAttends } from '@/schema/relations/attends';
import { Check, FileSearch, X } from 'lucide-react';
import React, { ReactNode } from 'react';

export type AttendsTableColumns = {
in?: boolean;
out?: boolean;
players?: boolean;
confirmed?: boolean;
created?: boolean;
updated?: boolean;
actions?: boolean;
};

export function AttendsTable({
attendees,
columns,
caption,
}: {
attendees: RichAttends[];
columns?: AttendsTableColumns;
caption?: ReactNode;
}) {
const doRenderCol = (col: keyof AttendsTableColumns) =>
columns?.[col] ?? true;

return (
<Table>
<TableHeader>
<TableRow>
{doRenderCol('in') && <TableHead>Registrant</TableHead>}
{doRenderCol('out') && <TableHead>Event</TableHead>}
{doRenderCol('players') && <TableHead>Players</TableHead>}
{doRenderCol('confirmed') && (
<TableHead>Confirmed</TableHead>
)}
{doRenderCol('created') && <TableHead>Created</TableHead>}
{doRenderCol('updated') && <TableHead>Updated</TableHead>}
{doRenderCol('actions') && <TableHead />}
</TableRow>
</TableHeader>
<TableBody>
{attendees?.map((attends) => {
return (
<TableRow key={attends.id}>
{doRenderCol('in') && (
<TableCell>
<Profile
profile={attends.in}
noSub
clickable
size="extra-tiny"
/>
</TableCell>
)}
{doRenderCol('out') && (
<TableCell>
<Profile
profile={attends.out}
noSub
clickable
size="extra-tiny"
renderBadge={false}
/>
</TableCell>
)}
{doRenderCol('players') && (
<TableCell className="flex -space-x-2">
{attends.players
.slice(0, 5)
.map((player) => (
<Avatar
key={player.id}
profile={player}
size="extra-tiny"
/>
))}
</TableCell>
)}
{doRenderCol('confirmed') && (
<TableCell>
{attends.confirmed ? (
<Check size={20} />
) : (
<X size={20} />
)}
</TableCell>
)}
{doRenderCol('created') && (
<TableCell>
<DateTooltip date={attends.created} />
</TableCell>
)}
{doRenderCol('updated') && (
<TableCell>
<DateTooltip date={attends.updated} />
</TableCell>
)}
{doRenderCol('actions') && (
<TableCell className="flex items-center justify-end gap-4">
{/* <Link
href={url('overview')}
className={buttonVariants({
size: 'sm',
})}
>
{t('row.actions.manage')}
<ArrowRight
size={18}
className="ml-2"
/>
</Link>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button size="icon" variant="ghost">
<MoreHorizontal size={20} />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-44">
<DropdownMenuLabel>
{t(
'row.actions.more-options.label'
)}
</DropdownMenuLabel>
<DropdownMenuSeparator />
<Link href={url('settings')}>
<DropdownMenuItem className="hover:cursor-pointer">
<Wrench
size={18}
className="mr-2 h-4 w-4"
/>
{t(
'row.actions.more-options.settings'
)}
</DropdownMenuItem>
</Link>
</DropdownMenuContent>
</DropdownMenu> */}
</TableCell>
)}
</TableRow>
);
})}
</TableBody>
{attendees?.length == 0 ? (
<TableCaption className="my-12">
<div className="flex items-center justify-center gap-1">
<FileSearch className="h-4 w-4" /> No attendees
</div>
</TableCaption>
) : (
caption && (
<TableCaption className="mb-4">{caption}</TableCaption>
)
)}
</Table>
);
}
Loading

0 comments on commit 6b7c660

Please sign in to comment.