Events app
This page covers what Events adds to the Vue side of your app: pages, components, composables and the admin event page's tabs. It is for app developers and module authors. Set up the module first: Overview.
Pages
Each page is opt-in through its option and follows the UX patterns of its area.
| Page | Default path | Who |
|---|---|---|
| Event list | /events | Everyone |
| Event page, with the ticket picker | /events/:slug | Everyone |
| My tickets, each with its QR code | /account/tickets | Signed-in users |
| Event list for staff | /admin/events | Staff, with Admin |
| Event page for staff, with Details, Tickets and Attendees tabs | /admin/events/:id | Staff, with Admin |
- Menus. With Menu, the tickets page joins the
accountmenu and the staff list joins the admin sidebar (admin.nav). - Account layout. The tickets page has no container of its own. The
accountlayout of Account draws the navigation around it. - Deleting. An event with paid tickets cannot be deleted. Archive it instead.
- Locale. Every link to an event goes through
useEventLinks(), so a visitor on/en/eventsstays under/en.
Components
All components are auto-imported.
- Public:
EventCard,EventTicketPickerandEventTicketCard, which shows the QR code. - Staff:
EventFormSlideovercreates an event.EventTicketTypeSlideover,EventAddonGroupSlideoverandEventAddonSlideoverare the catalogue forms, and each closes with{ id }orfalse.EventAdminAddonGroupslists a ticket type's add-on groups and emits onlyrefresh.
Composables
All composables are auto-imported. @frigear-nu/events/composables exports them too.
| Composable | Returns |
|---|---|
useEvents() | { events, grouped, status, refresh }. grouped splits into ongoing, upcoming and past. |
useEvent(slug) | { event, status, error, refresh, purchase(ticketTypeId, addonIds?) }. |
useMyTickets() | { tickets, status, loading, error, refresh, pay(ticketId) }. Await it in pages. It survives navigation. |
useEventLinks() | Locale-aware links: events(), event(slug), tickets(), admin() and adminEvent(id). |
useEventActions() | Staff actions on events: create(), duplicate(event), remove(event) and menu(event, options?). |
useEventCatalogActions(options?) | Staff actions on ticket types, add-on groups and add-ons. See below. |
useEventsLocale() | The current locale from @nuxtjs/i18n, else en. |
useEventsFallbackLocale() | The site's default locale, else en. |
useEventsTranslate() | tr(value): a translated text in the current locale, then the default locale, then en. |
useEventActions().create() opens the slideover, then goes to the new event's page. It resolves with
{ id, slug }, or false when cancelled. menu(event, { extra?, onRemoved? }) builds the row menu.
Catalogue actions
useEventCatalogActions(options?) owns the forms, deletes and row menus of an event's ticket types, add-on groups and
add-ons. Its menus have no Open item, because these records have no page of their own.
| Option | Purpose |
|---|---|
eventId | The event that new ticket types join: a value, ref or getter. Needed only for openTicketType() without a record. |
onChanged | Runs after anything is saved or deleted, for example to refresh the event. |
membership | A getter for the membership plans the ticket type form offers. It is read when the form opens. |
| Returned | Purpose |
|---|---|
openTicketType(ticketType?), openGroup(ticketType, group?), openAddon(ticketType, group, addon?) | Open the create form (no record) or the edit form. Resolve { id } or false. |
removeTicketType(ticketType), removeGroup(group), removeAddon(addon) | Confirm, delete, and resolve true once deleted. |
typeMenu(ticketType), groupMenu(ticketType, group), addonMenu(ticketType, group, addon) | Row menu items: the edits, then the delete in its own red group. |
Utils
@frigear-nu/events/utils is safe in the Vue app and in Nitro. It exports the DTO and hook types, translate,
normalizeMembership, DEFAULT_CURRENCY and id helpers. @frigear-nu/events/api exports eventsApi, the typed
paths of the routes.
Add a tab to the admin event page
The staff event page renders the admin.events tab area of Widget. Events registers
Details, Tickets and Attendees there. Any module can add a tab from its setup():
import { extendTabs } from '@frigear-nu/widget/utils'
extendTabs(nuxt, 'admin.events', { id: 'notes', component: resolver.resolve('./runtime/app/tabs/Notes.vue'), label: 'Notes', order: 30 })
Each tab component receives event as a prop, the response of GET /api/admin/events/:id, and may emit refresh.
Without Widget, the three built-in tabs render stacked.
authorize(event, 'events:manage') too.Next steps
- Reference – the routes and translation keys these pages use.
- Widget – how tab areas and
extendTabswork. - Forms and actions – the slideover and row menu patterns of the admin pages.