Skip to main content

Submissions Components

The Submissions module enables users to submit new directory items and manage their submissions through a dashboard. It includes the submission form, list views, filtering, statistics, and CRUD modals.

Architecture Overview

Source Files

FileDescription
submissions/index.tsBarrel exports
submissions/submission-list.tsxList container with loading and empty states
submissions/submission-item.tsxSingle submission row with status and actions
submissions/submission-stats-cards.tsxOverview stats cards
submissions/submission-filters.tsxStatus tabs and search input
submissions/delete-submission-dialog.tsxConfirmation dialog for deletion
submissions/edit-submission-modal.tsxEdit form modal
submissions/submission-detail-modal.tsxRead-only detail view modal
submit/submit-form-client.tsxPublic item submission form

Components

SubmitFormClient

The public-facing form for submitting a new item to the directory. Posts to /api/client/items.

import { SubmitFormClient } from "@/components/submit/submit-form-client";

<SubmitFormClient />

Key features:

  • Transforms FormData into a ClientCreateItemRequest object.
  • Integrates with LocationPicker for geo-located submissions.
  • Shows toast notifications for success and error states.
  • Redirects to the user's submissions dashboard on success.

SubmissionStatsCards

Displays four summary statistics cards for the user's submissions.

import { SubmissionStatsCards } from "@/components/submissions";

<SubmissionStatsCards stats={stats} isLoading={false} />

Props:

PropTypeDescription
statsSubmissionStatsObject with total, approved, pending, rejected counts
isLoadingbooleanShow skeleton placeholders

Card colour mapping:

StatColourIcon
TotalBluePackage
ApprovedGreenCheck
PendingYellowClock
RejectedRedX Circle

SubmissionFilters

Renders status filter tabs and a search input for narrowing the submission list.

<SubmissionFilters
currentStatus={status}
onStatusChange={setStatus}
searchTerm={search}
onSearchChange={setSearch}
counts={statusCounts}
/>

Props:

PropTypeDescription
currentStatusstringActive filter tab
onStatusChange(status) => voidFilter change callback
searchTermstringCurrent search text
onSearchChange(term) => voidSearch change callback
countsRecord<string, number>Count per status for badge display

SubmissionList

Renders the list of submissions with loading skeletons and an empty state.

<SubmissionList
items={submissions}
isLoading={isLoading}
onViewDetails={handleView}
onEdit={handleEdit}
onDelete={handleDelete}
/>

Props:

PropTypeDescription
itemsSubmission[]Array of submission objects
isLoadingbooleanShow skeleton loading state
skeletonCountnumberNumber of skeleton rows (default: 5)
onViewDetails(id) => voidView detail callback
onEdit(submission) => voidEdit callback
onDelete(submission) => voidDelete callback

The empty state includes a CTA button linking to the submission form.

SubmissionItem

A single submission row displaying item name, status badge, date, and action buttons.

<SubmissionItem
submission={submission}
onViewDetails={handleView}
onEdit={handleEdit}
onDelete={handleDelete}
/>

Status configuration:

StatusColourIconDescription
approvedGreenCheckCircleItem is live on the directory
pendingYellowClockAwaiting admin review
rejectedRedXCircleSubmission was declined

Action Modals

ComponentPurpose
SubmissionDetailModalRead-only view of submission details
EditSubmissionModalForm for editing a pending submission
DeleteSubmissionDialogConfirmation dialog before permanent deletion

Data Flow

Styling and Theming

  • All status badges use consistent colour coding across the module.
  • Cards use subtle gradient backgrounds with hover shadow transitions.
  • Loading skeletons match the exact dimensions of the real content.
  • Responsive layout: stat cards stack 2x2 on mobile, 4-across on desktop.

Integration Notes

  • The submission form requires authentication; unauthenticated users are redirected.
  • SubmitFormClient depends on LocationPicker from the maps module for geo-input.
  • All user-facing strings are internationalised via next-intl with the client.submissions namespace.
  • The dashboard is typically mounted at /[locale]/client/submissions.
  • Delete operations are soft-deletes by default; the DeleteSubmissionDialog warns the user accordingly.