Skip to content

create publisher UI - #23

Merged
Illyriat merged 2 commits into
mainfrom
feature/create-publisher-ui
Sep 7, 2026
Merged

Illyriat merged 2 commits into
mainfrom
feature/create-publisher-ui

Conversation

@Illyriat

@Illyriat Illyriat commented Sep 7, 2026 •

Copy link
Copy Markdown
Owner

Issue Number: Issue #7

Summary

Adds an "Add Publisher" flow to the Publishers page: a button opens a modal form that posts to the new POST /api/publishers backend endpoint, with client-side validation, loading state, error handling, and an automatic list refresh on success.


Context / Motivation

Ticket: Frontend — Create Publisher. The backend now exposes POST /api/publishers (see companion backend PR); this closes the loop by letting a user actually create a Publisher from the UI instead of only viewing/filtering the existing list.


Scope of Changes

  • src/components/AddPublisherModal.tsx (new) — modal component with a Name field. Handles client-side validation (required, ≤200 chars, mirroring the backend's limit), a submitting/loading state that disables the form and prevents duplicate submissions, inline display of both validation errors and API errors, and closes via Cancel button, overlay click, or Escape key (all disabled while a request is in flight).
  • src/pages/PublishersPage.tsx — added an "Add Publisher" button in a new page header row; opens the modal, and on successful creation closes it and refreshes the publisher list.
  • src/hooks/usePublishers.ts — added a refetch() function to the hook's return value so the page can re-trigger the existing list query after a create, without changing any of its filter/pagination state.
  • src/api/client.ts — added createPublisher() (POST helper) and a shared extractErrorMessage() used by both GET and POST calls, which reads the backend's ErrorDto.error field out of a failed response body so API error messages (e.g. the 409 conflict text) are shown to the user instead of a generic "request failed" message.
  • src/api/types.ts — added CreatePublisherRequest and ApiErrorResponse types.
  • src/App.css — styles for the modal overlay/dialog, the new page-header layout, and a .primary button variant, consistent with the app's existing light/dark theme tokens.

Testing Instructions

  • Load the app, go to Publishers page
  • Click "Add Publisher" — modal opens with a Name field, focused
  • Submit with an empty name — inline validation error shown, no network request made
  • Enter a unique name and submit — button shows "Creating...", modal closes on success, and the new publisher appears in the list (count updates)
  • Try creating a publisher with a name that already exists — modal stays open and shows the backend's 409 conflict message
  • While a request is in flight, confirm the Create/Cancel buttons and Escape/overlay-close are disabled (no duplicate submissions possible)
  • Toggle light/dark theme with the modalle in both

Acceptance Criteria

  • Create Publisher UI implemented (modal on Publishers page)
  • All required fields available (Name)
  • Client-side validation implemented
  • API integration implemented (POST /api/publishers)
  • Loading state handled
  • Validation errors displayed
  • API/server errors displayed (including 409 conflict text from backend)
  • Duplicate submissions prevented (submi
  • Successful creation provides user feedback (modal closes, new row visible in refreshed list)
  • Publisher list updated after creation
  • Existing frontend conventions followed CSS variable usage)
  • Functionality manually verified (see testing instructions; verified with Playwright against a live backend during development)

Code Review Notes

  • usePublishers's refetch() is implemented via an internal reload-token counter rather than exposing a way to mutate data directly, so it re-runs the exact same query the page already has configured (same filters/page) rather than needing the caller to know the fetch in
  • usePublishers's refetch() is implemented via an internal reload-token counter rather than exposing a way to mutate data directly, so it re-runs the exact same query the page already has configured (same filters/page) rather
    than needing the caller to know the fetch in
  • No toast/notification system exists elsewhere in the app, so "success feedback" is the modal closing plus the new row appearing in the refreshed list — consistent with the app's current minimal UI conventions. Flagging in case a
    more explicit success message is wanted.

Related Issues / Tickets

@Illyriat
Illyriat merged commit a7678de into main Sep 7, 2026
3 checks passed
@Illyriat
Illyriat deleted the feature/create-publisher-ui branch September 7, 2026 00:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create Publisher UI

1 participant