admin/queries/consumerKeys.ts
alisaza e1eaf5eff5 feat: initial ghabilee-admin backoffice app
Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js
app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
2026-09-05 13:12:59 +03:30

81 lines
5.6 KiB
TypeScript

/**
* Query-key factory for authenticated consumer data.
* Mutations should invalidate / patch these keys so lists stay fresh.
*
* Note: `following()` is a prefix of `followingCount()` / `isFollowing()`.
* When invalidating the following list only, pass `{ exact: true }`.
*/
export const consumerKeys = {
all: ['consumer'] as const,
me: () => [...consumerKeys.all, 'me'] as const,
wallet: () => [...consumerKeys.all, 'wallet'] as const,
walletTransactions: () => [...consumerKeys.all, 'wallet', 'transactions'] as const,
bankAccounts: () => [...consumerKeys.all, 'wallet', 'bank-accounts'] as const,
withdrawalRequests: () => [...consumerKeys.all, 'wallet', 'withdrawals'] as const,
settlementRequests: () => [...consumerKeys.all, 'wallet', 'settlements'] as const,
myBookings: () => [...consumerKeys.all, 'bookings', 'mine'] as const,
booking: (id: string) => [...consumerKeys.all, 'bookings', id] as const,
bookingPayment: (id: string) => [...consumerKeys.all, 'bookings', id, 'payment'] as const,
bookingEventSummary: (eventId: string) => [...consumerKeys.all, 'bookings', 'event-summary', eventId] as const,
myHostedEvents: () => [...consumerKeys.all, 'events', 'mine'] as const,
/** Prefix for all paginated role/status variants of the unified My Events API. */
myEventsRoot: () => [...consumerKeys.all, 'my-events'] as const,
myEvents: (role: 'guest' | 'host', status: 'upcoming' | 'held' | 'cancelled' | 'pending_review' | 'published' | 'rejected') =>
[...consumerKeys.myEventsRoot(), role, status] as const,
/** `GET /events/:id` is viewer-sensitive because confirmed attendees can receive the exact address. */
eventDetailRoot: (eventId: string) => [...consumerKeys.all, 'events', eventId, 'detail'] as const,
eventDetail: (eventId: string, viewerId: string) => [...consumerKeys.eventDetailRoot(eventId), viewerId] as const,
eventMedia: (eventId: string) => [...consumerKeys.all, 'events', eventId, 'media'] as const,
eventFaqs: (eventId: string) => [...consumerKeys.all, 'events', eventId, 'faqs'] as const,
/** Prefix for every review page of an event — use with `invalidateQueries`. */
eventReviewsRoot: (eventId: string) => [...consumerKeys.all, 'events', eventId, 'reviews'] as const,
eventReviews: (eventId: string) => [...consumerKeys.eventReviewsRoot(eventId)] as const,
eventOwnerInsights: (eventId: string) => [...consumerKeys.all, 'events', eventId, 'owner-insights'] as const,
eventViewerState: (eventId: string, viewerId: string) => [...consumerKeys.all, 'events', eventId, 'viewer-state', viewerId] as const,
publicOrganizer: (organizerId: string) => [...consumerKeys.all, 'organizers', organizerId, 'public'] as const,
myEventReview: (eventId: string) => [...consumerKeys.all, 'reviews', 'mine', eventId] as const,
identityVerification: () => [...consumerKeys.all, 'identity'] as const,
contactLinks: () => [...consumerKeys.all, 'contact-links'] as const,
organizerAttendeeContactLinks: (organizerId: string, viewerId: string) =>
[...consumerKeys.all, 'organizers', organizerId, 'attendee-contact-links', viewerId] as const,
organizerViewerState: (organizerId: string, viewerId: string) =>
[...consumerKeys.all, 'organizers', organizerId, 'viewer-state', viewerId] as const,
eventManagementBootstrap: (eventId: string) => [...consumerKeys.all, 'events', eventId, 'management-bootstrap'] as const,
bookmarks: () => [...consumerKeys.all, 'bookmarks'] as const,
bookmarkStatuses: (eventIdsKey: string) => [...consumerKeys.all, 'bookmark-statuses', eventIdsKey] as const,
bookmarkStatus: (eventId: string) => [...consumerKeys.all, 'bookmark-status', eventId] as const,
following: () => [...consumerKeys.all, 'following'] as const,
followers: () => [...consumerKeys.all, 'followers'] as const,
followingCount: () => [...consumerKeys.all, 'following', 'count'] as const,
isFollowing: (hostId: string) => [...consumerKeys.all, 'following', 'is', hostId] as const,
notifications: () => [...consumerKeys.all, 'notifications'] as const,
unreadCount: () => [...consumerKeys.all, 'notifications', 'unread-count'] as const,
conversationsRoot: () => [...consumerKeys.all, 'chat', 'conversations'] as const,
conversations: (type: 'direct' | 'event_group') => [...consumerKeys.conversationsRoot(), type] as const,
conversation: (id: string) => [...consumerKeys.all, 'chat', 'conversation', id] as const,
conversationMessages: (id: string) => [...consumerKeys.all, 'chat', 'messages', id] as const,
conversationParticipants: (id: string) => [...consumerKeys.all, 'chat', 'participants', id] as const,
blockStatus: (userId: string) => [...consumerKeys.all, 'chat', 'block', userId] as const,
reportReasons: () => [...consumerKeys.all, 'chat', 'report-reasons'] as const,
/** Prefix for every `discoveryEvents(filtersKey)` variant — use with `invalidateQueries`. */
discoveryEventsRoot: () => [...consumerKeys.all, 'discovery', 'events'] as const,
discoveryEvents: (filtersKey: string) => [...consumerKeys.discoveryEventsRoot(), filtersKey] as const,
discoveryHomeFeed: (cityKey: string) => [...consumerKeys.all, 'discovery', 'home-feed', cityKey] as const,
discoveryHomeFeedRoot: () => [...consumerKeys.all, 'discovery', 'home-feed'] as const,
discoveryBootstrap: () => [...consumerKeys.all, 'discovery', 'bootstrap'] as const,
discoveryCategories: () => [...consumerKeys.all, 'discovery', 'categories'] as const,
discoveryCities: () => [...consumerKeys.all, 'discovery', 'cities'] as const,
publicCategories: () => [...consumerKeys.all, 'categories', 'public'] as const,
}
export const DEFAULT_DISCOVERY_FILTERS_KEY = 'city:|cats:|from:|to:'