feat(app): public witnessing - #5297
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Locations and arrangements tables follow the established vertical slice: definition types with the _deleted/updatedAt data-blob pattern, Dexie v13 schema, soft-delete services flagging metadata send_local, jotai db atoms wired through the IndexedDb wrapper, and a publisher route with a Ministry dashboard entry (reusing the existing tr_PW locale key). Arrangements are one record per booking action (author in created_by) so concurrent offline bookings merge without conflicts; day-view shifts are derived from the location's per-weekday schedule and never stored.
Two-column page: locations sidebar (settings_tab from the settings redesign, PR sws2apps#5224) and a details card with badges and description. Admin actions gated by usePermissions (app admin + service overseer): add/edit dialog with General information and Schedule tabs (approved days + per-day shift ranges), delete confirmation (soft delete), and drag reorder persisting sort_index. Shift time rows memoize their Date values in a dedicated ShiftRow — the shared TimePicker resets its in-progress edit whenever the value prop identity changes. Locale keys reuse the existing tr_PW*/general strings; only genuinely new labels were added.
Shifts card composes day navigation (arrows + jump-to-today, matching the field-service-meetings calendar pattern) with the segmented TabSwitcher from the clicker PR (week/month disabled for now). Day slots are derived at render time from the location's weekday schedule merged with booked arrangements — nothing is materialized per date. Cell states follow the design spec: available (accent border + chip), partner needed (orange, stays open until the requested partners join), fully occupied (dashed) and past. Cells are interactive only for bookable states, the arrangement author, or admins. The confirm-the-arrangement dialog covers all flows: partner needed with a wanted-count, I-have-a-partner with a freeSolo persons autocomplete (non-app partners stay name-only), admin for-myself / for-others tabs, joining a seeker (creates the joiner's own record — derived state keeps records conflict-free), edit and cancel, and an add-to-calendar ICS prompt after booking.
Schedule tab now matches the design measurements: fixed 240px approved days column, vertical divider with 32px gaps, 16px shifts-column spacing, 48px day rows, and a 16px dash between the start/end time fields. Tab content renders through the Tabs component's own panels, removing the double gap the empty tabpanels used to add (same fix in the arrangement dialog). Header actions reordered to Reorder / Edit / Add with Add as the main button, and the max publishers badge shortened to "Max. publishers".
Shift cells now behave like buttons: outlined states fill with accent-100 on hover instead of casting a shadow, and publisher names use the smaller text style. The day header drops the year from its label and paints the jump-to-today icon black; the no-shifts state uses the standard info-icon message row. IconReorder's center dot was a separate circle element that CSS recoloring (svg g path selectors) never reached — merged into the arrows path so the glyph is one shape. The cart badge icon gets an explicit accent-dark color for the same reason: its paths sit directly under the svg root with a hardcoded default fill. Location dialog: badges use the small size, the storage field label is now "Stored at", "Every day" shows an indeterminate state when only some days are approved, Add shift uses the small button variant, shift delete buttons sit in the 48px rounded container used by the circuit overseer week rows, and an unselected schedule shows a select-a-day hint with no divider.
The shift-row trash button cancels the IconButton edge-start negative margin that was eating its left spacing, and the day checkboxes drop the FormControlLabel offset so the row's 8px inner padding matches the design. The location delete action moves from a full-width button at the dialog bottom to a small red button beside the Edit location title. Max. publishers per shift is now optional: the field may stay empty, the badge hides when unset, and shift capacity falls back to the default of 3.
Mobile now mirrors the app's subpage pattern: the page shows only the locations list, and tapping a location opens its details as a subpage using the SubpageNavbar from the clicker PR (location name with the parent page underneath, animated back arrow returning to the list). The day navigation adopts the field service meetings calendar layout: single row on tablet+ with the toggle right-aligned, stacked on mobile with the arrows pushed to the card edges; the jump-to-today control always reserves its slot so the label never shifts, the label gets a 180px centered slot with ellipsis, and min-width guards keep the switcher and header clipped inside the card.
On mobile the schedule tab no longer stacks a detached shifts panel under the day list — the editor expands inline right under the tapped day, with expand/collapse chevrons on the far right of approved days and tap-to-toggle behavior. Desktop keeps the two-column layout. Small buttons (Add shift, Add person, the title Delete) now pass disableAutoStretch so they stay compact instead of stretching to the global full-width mobile button default.
The mobile detail view was rendering its own SubpageNavbar below the app navbar, so the screen showed two headers. The app navbar already renders a back arrow with a title and secondary title, so the detail is now a real route (/public-witnessing/:locationId) that drives it through PageTitle: one header, and the navbar back arrow returns to the list on its own. The cherry-picked SubpageNavbar is dropped — it exists for fullscreen overlays that cover the navbar, not for this. Also: the empty locations state uses the InfoNote card variant, the locations list keeps its chevron visible on touch devices (hover never fires there), the dashboard entry uses the cart icon, and a day's shifts only open once the day is approved — tapping an unapproved row approves it, unchecking closes its shifts again.
db293df to
10a7ee3
Compare
|



Description
Implements the Public Witnessing MVP (frontend + local-first data layer), following the Figma "Public witnessing MVP" section: a locations list with details, and a day view where publishers book witnessing shifts.
Since the app is a local-first PWA, this includes the IndexedDB model, state and mutation services — only the congregation sync endpoint remains for a later PR.
What's included
Data layer. Two Dexie tables (
public_witnessing_locations,public_witnessing_arrangements) registered as schema v13, following the established vertical slice:definitiontypes using the_deleted/updatedAtdata-blob pattern, soft-delete services that flagmetadata.send_localfor auto-sync, jotai atoms wired through the IndexedDb wrapper.Two decisions worth reviewing:
created_by), so two publishers booking the same slot offline merge without conflicts. Joining a partner-seeker creates the joiner's own record and never mutates the seeker's; the orange "partner needed" state is derived.Locations management (admin: app admin + service overseer, via
usePermissions).Two-column page — sidebar (reusing
settings_tabfrom the settings redesign, #5224) and a details card with badges and description. Add/edit dialog with General information and Schedule tabs (approved days + per-day shift ranges), delete confirmation (soft delete), and drag reorder persistingsort_index.Day view + booking (all users).
Day navigation with jump-to-today, plus the segmented
TabSwitcherfrom #5291 (week/month rendered but disabled — post-MVP). Shift cells follow the design's states: available, partner needed (orange), fully occupied (dashed) and past. Cells are interactive only for bookable states, the arrangement's author, or admins.The "Confirm the arrangement" dialog covers every flow in the Figma: partner needed with a wanted-count, "I have a partner" with a persons autocomplete that also accepts free-text (partners who aren't app users), the admin For myself / For others tabs, joining a seeker, editing/cancelling, and the add-to-calendar ICS prompt after booking.
Mobile. The page shows only the locations list; a location opens as a subpage via its own route (
/public-witnessing/:locationId), so the app navbar renders it as a subpage with a working back arrow. In the schedule tab, a day's shifts expand inline under it.Notes for reviewers
tr_PW*family,tr_startTime/tr_endTime, weekday names); only a handful of genuinely new keys were added. Figma labels were mapped onto existing wording rather than adding synonyms (e.g. Figma's "From/To" → the existing Start/End).IconReorderfix: its center dot was a separate<circle>, which the app's icon recoloring (svg g pathselectors) never reached, so the dot kept a hardcoded fill. Merged into the arrows path — this affects every existing usage of the icon, and is a drive-by fix.Type of change
Checklist: