Implement host poster feature - #170
Conversation
|
Visit the preview URL for this PR (updated for commit 0f0f69a): https://sunday-service-vr--pr170-host-poster-support-mt8waoac.web.app (expires Sun, 11 Jan 2026 18:29:29 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: 58385af7bd5a89154351e3a6f5764ea3ef89db5c |
There was a problem hiding this comment.
Pull request overview
This PR implements a comprehensive host poster management feature that allows admins and hosts to create, manage, and display host entities with associated poster images. The feature extends the existing event management system by adding host references to events and providing a new club settings interface.
Key changes include:
- Introduction of Host and Club types with poster image support
- New store modules for host CRUD operations and club settings management
- Host caching integrated into the event/DJ cache system with reconciliation
- Complete UI for managing hosts, including creation, editing, and poster upload
- Firebase storage and Firestore security rules for host-posters and club settings
Reviewed changes
Copilot reviewed 21 out of 23 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| webapp/src/util/types.ts | Adds Host and Club types, extends Event with host_ref and reconciled fields |
| webapp/src/store/host.ts | Implements CRUD operations for hosts collection |
| webapp/src/store/clubSettings.ts | Manages club-wide settings including default poster |
| webapp/src/store/converters.ts | Adds docToHost converter for Firestore documents |
| webapp/src/hooks/useEventStore/useEventStore.tsx | Integrates host cache into event reconciliation |
| webapp/src/hooks/useEventStore/eventReconciliation.ts | Adds host reconciliation logic for events |
| webapp/src/contexts/useEventDjCache/useEventDjData.ts | Implements host caching parallel to DJ caching |
| webapp/src/contexts/useEventDjCache/types.ts | Adds HostCache type definition |
| webapp/src/contexts/useEventDjCache/eventDjDataContext.tsx | Exposes host cache and reload functions |
| webapp/src/features/host/HostSearchSelect.tsx | Dropdown component for selecting/creating hosts |
| webapp/src/features/host/HostForm.tsx | Form component for host details and poster upload |
| webapp/src/features/host/CreateHostModal.tsx | Modal for creating new hosts with poster support |
| webapp/src/features/event/basic/EventBasicDetailsForm.tsx | Integrates host selection into event creation |
| webapp/src/features/clubSettings/HostList.tsx | Management interface for viewing/editing hosts |
| webapp/src/features/clubSettings/DefaultPosterSettings.tsx | Interface for setting default host poster |
| webapp/src/features/clubSettings/ClubSettings.tsx | Main club settings page with tabbed interface |
| webapp/src/features/layout/Layout.tsx | Adds Club Settings navigation link |
| webapp/src/App.tsx | Adds club settings route with role-based access |
| storage.rules | Adds security rules for host-posters and default-poster paths |
| firestore.rules | Adds security rules for hosts and club collections |
| functions/package.json | Updates firebase-tools dependency |
| webapp/package-lock.json | Updates various dependencies including babel and vitest |
Files not reviewed (1)
- webapp/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /** | ||
| * Converts a firebase doc to a host | ||
| * | ||
| * @param doc | ||
| * @returns | ||
| */ |
There was a problem hiding this comment.
| // If a poster was uploaded, upload it and update the host | ||
| if (hostPosterFile && hostRef.id) { | ||
| const safeFileName = hostPosterFile.name.replace(/[^a-zA-Z0-9.\-_]/g, "_"); | ||
| const storagePath = `host-posters/${hostRef.id}/${Date.now()}_${safeFileName}`; | ||
| const storageRef = ref(storage, storagePath); | ||
|
|
||
| await uploadBytes(storageRef, hostPosterFile); | ||
| const downloadUrl = await getDownloadURL(storageRef); | ||
|
|
||
| host.host_poster_path = storagePath; | ||
| host.host_poster_url = downloadUrl; | ||
| } |
There was a problem hiding this comment.
After uploading a new poster file, the host document should be updated in Firestore with the new poster path and URL. Currently, the host object is modified locally but not persisted back to the database, which means the poster information will be lost.
| } | ||
|
|
||
| const EventBasicDetailsForm = ({ event: eventScratchpad, onEventChange: proposeEventChange, onLineupPosterFileChange }: Props) => { | ||
|
|
There was a problem hiding this comment.
The unused underscore parameter suggests the Host object is not being used in this handler. Consider removing it from the signature or using it if it's needed for future functionality. If it must remain for API compatibility, add a comment explaining why.
| // Note: The Host argument is intentionally unused here; it remains in the | |
| // signature to stay compatible with the HostSearchSelect callback API. |
| // Only admins/hosts can upload or modify lineup posters | ||
| allow write: if request.auth != null && | ||
| (("admin" in request.auth.token.roles) || ("host" in request.auth.token.roles)); | ||
| request.auth.token.roles.hasAny(['admin', 'host']); |
There was a problem hiding this comment.
The storage rules use different syntax patterns inconsistently. Line 21 uses the newer hasAny() method with an array literal, while lines 9 and 16 in firestore.rules use the older 'in' operator. Consider standardizing on the hasAny() method for consistency and better readability across both rule files.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@copilot open a new pull request to apply changes based on the comments in this thread |
* Initial plan * Address review comments: fix JSDoc, typo, add Firestore update, and standardize rules Co-authored-by: lebull <3135984+lebull@users.noreply.github.com> * Fix syntax error in clubSettings.ts - add missing closing brace Co-authored-by: lebull <3135984+lebull@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lebull <3135984+lebull@users.noreply.github.com>
…eVR/sunday-service-vr into host-poster-support
No description provided.