# Reminders list

> The next events with the caller's reminders on each, to add a reminder at an offset before an event or remove one.

- Block: [reminders](https://bettersupabase.com/blocks/reminders.md)
- Kind: component
- Data: loaded on the server through the block's client
- Page: https://bettersupabase.com/recipes/reminders-list

## Install the block

```bash
npx better-supabase add reminders
```

## Web (Next.js)

Add the shadcn components:

```bash
npx shadcn add card empty skeleton
```

From `apps/examples/nextjs/src/features/calendar/components/reminders-list.tsx` (https://github.com/ScaleDockHQ/better-supabase/blob/main/apps/examples/nextjs/src/features/calendar/components/reminders-list.tsx):

```tsx
/**
 * The next events with the caller's reminders on each. A reminder fires
 * its offset before every occurrence of the event, once per occurrence.
 */
export async function RemindersList() {
  const session = await getSession();

  if (!can(session, "reminders.manage")) {
    return null;
  }

  const [t, format, upcoming] = await Promise.all([
    getExtracted("calendar"),
    getFormatter(),
    settle(loadUpcomingReminders),
    connection(),
  ]);

  if (upcoming.kind === "no-organization") {
    return null;
  }

  const calendars = upcoming.kind === "ok" ? upcoming.data.calendars : [];

  const defaultDate = Temporal.Now.plainDateISO(
    calendars[0]?.tz ?? "UTC",
  ).toString();

  return (
    <Card data-recipe="reminders-list">
      <CardHeader>
        <CardTitle>{t("Upcoming reminders")}</CardTitle>
        <CardDescription>
          {t("Get a notification before the events of the next two weeks.")}
        </CardDescription>
      </CardHeader>
      <CardContent>
        {upcoming.kind === "error" ? (
          <CalendarLoadError title={t("Your reminders didn't load.")} />
        ) : upcoming.data.events.length === 0 ? (
          <Empty className="border">
            <EmptyHeader>
              <EmptyMedia variant="icon">
                <BellIcon />
              </EmptyMedia>
              <EmptyTitle>{t("No events coming up")}</EmptyTitle>
              <EmptyDescription>
                {t("Add an event, then set a reminder for it here.")}
              </EmptyDescription>
            </EmptyHeader>
            {calendars.length > 0 && can(session, "calendar.write") ? (
              <EmptyContent>
                <CreateEventDialog
                  calendars={calendars}
                  defaultDate={defaultDate}
                />
              </EmptyContent>
            ) : null}
          </Empty>
        ) : (
          <ul className="flex flex-col gap-2">
            {upcoming.data.events.map((event) => (
              <EventReminders
                key={event.id}
                eventId={event.id}
                title={event.title}
                when={format.dateTime(
                  new Date(event.startsAt),
                  event.allDay
                    ? { dateStyle: "medium" }
                    : { dateStyle: "medium", timeStyle: "short" },
                )}
                reminders={event.reminders}
              />
            ))}
          </ul>
        )}
      </CardContent>
    </Card>
  );
}
```

## Prompt

Paste this into a coding agent to build the recipe in your app.

### Web

```text
Build "Reminders list" in a React web app that uses shadcn/ui components. The next events with the caller's reminders on each, to add a reminder at an offset before an event or remove one.

It uses the better-supabase `reminders` block (Reminders). It loads its data on the server through the block's client.

Steps:

1. If the app doesn't have the block yet, add the SQL with `npx better-supabase add reminders` and apply the migration.
2. Add the shadcn components the recipe uses: `npx shadcn add card empty skeleton`.
3. The recipe needs no glue: it calls the block's client on the server.
4. Write the component. Load the data on the server with the block's client, starting from the recipe's snippet (`apps/examples/nextjs/src/features/calendar/components/reminders-list.tsx`). Adapt it to the app's existing components, styling and data loading instead of copying it as is.
5. Check the result against the recipe and the block's docs: it typechecks, it reads the same block data, and it handles the loading and empty states the snippet handles.

Read the full code first:

- Recipe: https://bettersupabase.com/recipes/reminders-list.md
- Block docs: https://bettersupabase.com/docs/blocks/reminders
```
