@burdenoff/microfe-hookmovies 2026.705.2 → 2026.706.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/hookmovies/HookMoviesRoutes.js +26 -6
  2. package/dist/hookmovies/HookMoviesRoutes.js.map +1 -1
  3. package/dist/hookmovies/components/index.js +7 -0
  4. package/dist/hookmovies/hooks/index.js +1 -0
  5. package/dist/hookmovies/hooks/useFiles.js +97 -0
  6. package/dist/hookmovies/hooks/useFiles.js.map +1 -0
  7. package/dist/hookmovies/hooks/useHookMoviesApi.js +204 -52
  8. package/dist/hookmovies/hooks/useHookMoviesApi.js.map +1 -1
  9. package/dist/hookmovies/pages/HomePage.js +2 -2
  10. package/dist/hookmovies/pages/HomePage.js.map +1 -1
  11. package/dist/hookmovies/pages/auditions/AuditionDetailPage.js +100 -45
  12. package/dist/hookmovies/pages/auditions/AuditionDetailPage.js.map +1 -1
  13. package/dist/hookmovies/pages/catalog/TitleDetailPage.js +1340 -266
  14. package/dist/hookmovies/pages/catalog/TitleDetailPage.js.map +1 -1
  15. package/dist/hookmovies/pages/catalog/TitlesPage.js +95 -74
  16. package/dist/hookmovies/pages/catalog/TitlesPage.js.map +1 -1
  17. package/dist/hookmovies/pages/consumer/DiscoveryPage.js +422 -0
  18. package/dist/hookmovies/pages/consumer/DiscoveryPage.js.map +1 -0
  19. package/dist/hookmovies/pages/consumer/HooksPage.js +252 -0
  20. package/dist/hookmovies/pages/consumer/HooksPage.js.map +1 -0
  21. package/dist/hookmovies/pages/consumer/PlayerPage.js +542 -0
  22. package/dist/hookmovies/pages/consumer/PlayerPage.js.map +1 -0
  23. package/dist/hookmovies/pages/consumer/TitleViewPage.js +424 -0
  24. package/dist/hookmovies/pages/consumer/TitleViewPage.js.map +1 -0
  25. package/dist/hookmovies/pages/distribution/RightsWindowsPage.js +1 -1
  26. package/dist/hookmovies/pages/distribution/RightsWindowsPage.js.map +1 -1
  27. package/dist/hookmovies/pages/library/EntitlementsPage.js +273 -75
  28. package/dist/hookmovies/pages/library/EntitlementsPage.js.map +1 -1
  29. package/dist/hookmovies/pages/library/ListsPage.js +186 -106
  30. package/dist/hookmovies/pages/library/ListsPage.js.map +1 -1
  31. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useHookMoviesApi.js","names":[],"sources":["../../../src/hookmovies/hooks/useHookMoviesApi.ts"],"sourcesContent":["/**\n * HookMovies API hooks\n * @module hookmovies/hooks\n *\n * Real data layer for the HookMovies workspace subgraph (`hookmovies` Hive\n * service / `wspace-hookmovies-svc`). Every hook talks to the live workspace\n * GraphQL gateway via {@link graphqlFetch} with inline operations whose fields\n * mirror `.hive-schema.graphql` exactly. No mocks.\n *\n * Conventions (mirrors microfe-kadaikodi):\n * - `hookmoviesQuery` wraps graphqlFetch({ gateway: 'workspace', workspaceToken: true })\n * and throws on GraphQL errors / missing data.\n * - One react-query `useQuery` per read op and `useMutation` per write op.\n * - Strict hand-written result interfaces — no `any`.\n * - Pagination uses the subgraph's `PaginationInput` (limit/offset/cursor) and\n * `Hok*Connection { items, pageInfo { cursor hasMore } }` shapes verbatim.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useHookMovies } from '../context';\n\n// ============================================================================\n// Low-level query runner\n// ============================================================================\n\nconst hookmoviesQuery = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'GraphQL request failed');\n }\n\n if (!response.data) {\n throw new Error('GraphQL response did not include data');\n }\n\n // This MFE bypasses Apollo, so fe-libs' short-lived graphqlFetch read cache\n // (~15s) would otherwise serve pre-write data to the very next refetch issued\n // by a mutation's onSuccess invalidation. Clear it after any successful\n // mutation so every downstream read is fresh (fleet-wide stale-read-after-\n // write fix).\n if (query.trimStart().startsWith('mutation')) {\n clearGraphqlFetchResponseCache();\n }\n\n return response.data;\n};\n\nconst QK = 'hookmovies' as const;\n\n// ============================================================================\n// Shared scalar / enum types (mirror .hive-schema.graphql)\n// ============================================================================\n\nexport interface HokPaginationInput {\n cursor?: string | null;\n limit?: number | null;\n offset?: number | null;\n}\n\nexport interface HokPageInfo {\n cursor: string | null;\n hasMore: boolean;\n}\n\nexport type HokTitleType =\n | 'MOVIE'\n | 'SERIES'\n | 'SHORT_FILM'\n | 'DOCUMENTARY'\n | 'ANIME'\n | 'SHORT_FORM'\n | 'LONG_FORM'\n | 'LIVE_EVENT'\n | 'TRAILER'\n | 'COLLECTION'\n | 'FAST_CHANNEL';\n\nexport type HokTitleStatus =\n | 'DRAFT'\n | 'IN_REVIEW'\n | 'SCHEDULED'\n | 'PUBLISHED'\n | 'UNPUBLISHED'\n | 'ARCHIVED';\n\nexport type HokProductionStatus =\n | 'DEVELOPMENT'\n | 'GREENLIT'\n | 'IN_PRODUCTION'\n | 'POST_PRODUCTION'\n | 'RELEASED'\n | 'SHELVED';\n\nexport type HokAuditionStatus = 'OPEN' | 'REVIEWING' | 'CALLBACKS' | 'CLOSED' | 'CANCELLED';\n\nexport type HokApplicationStatus =\n | 'SUBMITTED'\n | 'SHORTLISTED'\n | 'CALLBACK'\n | 'OFFERED'\n | 'REJECTED'\n | 'WITHDRAWN';\n\nexport type HokCreditRole =\n | 'ACTOR'\n | 'DIRECTOR'\n | 'WRITER'\n | 'PRODUCER'\n | 'CINEMATOGRAPHER'\n | 'EDITOR'\n | 'COMPOSER'\n | 'VOICE_ACTOR'\n | 'CREW';\n\nexport type HokReviewStatus = 'PENDING' | 'PUBLISHED' | 'HIDDEN' | 'REMOVED';\n\nexport type HokRightsWindowStatus = 'DRAFT' | 'PENDING' | 'ACTIVE' | 'EXPIRED' | 'REVOKED';\n\nexport type HokMonetizationMode = 'FREE_AVOD' | 'SVOD' | 'TVOD_RENT' | 'TVOD_BUY' | 'PPV' | 'FAST';\n\nexport type HokEntitlementSource = 'SUBSCRIPTION' | 'PURCHASE' | 'RENTAL' | 'PROMO' | 'FREE';\n\nexport type HokEntitlementStatus = 'ACTIVE' | 'EXPIRED' | 'REVOKED';\n\nexport type HokListKind = 'WATCHLIST' | 'PLAYLIST';\n\nexport type HokListVisibility = 'PRIVATE' | 'UNLISTED' | 'PUBLIC';\n\n// ============================================================================\n// Domain object types\n// ============================================================================\n\nexport interface HokStudio {\n id: string;\n name: string;\n slug: string | null;\n description: string | null;\n country: string | null;\n websiteUrl: string | null;\n isVerified: boolean;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokPerson {\n id: string;\n name: string;\n biography: string | null;\n knownFor: string | null;\n primaryLanguage: string | null;\n portfolioRef: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokCredit {\n id: string;\n personId: string;\n titleId: string;\n role: HokCreditRole;\n characterName: string | null;\n billingOrder: number;\n person: Pick<HokPerson, 'id' | 'name' | 'knownFor'> | null;\n}\n\nexport interface HokEpisodeSummary {\n id: string;\n name: string;\n number: number;\n seasonId: string | null;\n synopsis: string | null;\n runtimeMinutes: number | null;\n airDate: string | null;\n}\n\nexport interface HokSeasonSummary {\n id: string;\n name: string | null;\n number: number;\n synopsis: string | null;\n}\n\nexport interface HokTitle {\n id: string;\n title: string;\n slug: string | null;\n type: HokTitleType;\n status: HokTitleStatus;\n synopsis: string | null;\n genres: string[];\n tags: string[];\n originalLanguage: string | null;\n originCountry: string | null;\n releaseYear: number | null;\n releaseDate: string | null;\n runtimeMinutes: number | null;\n certification: string | null;\n aiDisclosure: boolean;\n studioId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokTitleDetail extends HokTitle {\n studio: Pick<HokStudio, 'id' | 'name'> | null;\n credits: HokCredit[];\n seasons: HokSeasonSummary[];\n episodes: HokEpisodeSummary[];\n}\n\nexport interface HokProduction {\n id: string;\n title: string;\n logline: string | null;\n synopsis: string | null;\n status: HokProductionStatus;\n currency: string;\n budgetMinorUnits: string;\n studioId: string | null;\n producerId: string | null;\n resultingTitleId: string | null;\n artistrybaseProjectRef: string | null;\n tags: string[];\n startDate: string | null;\n endDate: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokAuditionSummary {\n id: string;\n roleName: string;\n status: HokAuditionStatus;\n isMinorRole: boolean;\n payMinorUnits: string;\n currency: string;\n location: string | null;\n language: string | null;\n submissionDeadline: string | null;\n}\n\nexport interface HokProductionDetail extends HokProduction {\n auditions: HokAuditionSummary[];\n}\n\nexport interface HokAudition {\n id: string;\n productionId: string;\n roleName: string;\n description: string | null;\n status: HokAuditionStatus;\n isMinorRole: boolean;\n payMinorUnits: string;\n currency: string;\n location: string | null;\n language: string | null;\n submissionDeadline: string | null;\n createdAt: string;\n updatedAt: string;\n production: Pick<HokProduction, 'id' | 'title'> | null;\n}\n\nexport interface HokApplication {\n id: string;\n auditionId: string;\n applicantId: string;\n coverNote: string | null;\n score: number | null;\n status: HokApplicationStatus;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokReview {\n id: string;\n titleId: string;\n authorId: string;\n score: number;\n body: string | null;\n hasSpoilers: boolean;\n helpfulCount: number;\n verifiedWatch: boolean;\n status: HokReviewStatus;\n createdAt: string;\n updatedAt: string;\n title: Pick<HokTitle, 'id' | 'title'> | null;\n}\n\nexport interface HokRightsWindow {\n id: string;\n titleId: string;\n status: HokRightsWindowStatus;\n modes: HokMonetizationMode[];\n territories: string[];\n exclusive: boolean;\n currency: string;\n licenseeId: string | null;\n startsAt: string | null;\n endsAt: string | null;\n createdAt: string;\n updatedAt: string;\n title: Pick<HokTitle, 'id' | 'title'> | null;\n}\n\nexport interface HokEntitlement {\n id: string;\n titleId: string;\n userId: string;\n mode: HokMonetizationMode;\n source: HokEntitlementSource;\n status: HokEntitlementStatus;\n territory: string | null;\n expiresAt: string | null;\n createdAt: string;\n updatedAt: string;\n title: Pick<HokTitle, 'id' | 'title'> | null;\n}\n\nexport interface HokList {\n id: string;\n name: string;\n description: string | null;\n kind: HokListKind;\n visibility: HokListVisibility;\n ownerId: string;\n itemCount: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokWatchProgress {\n id: string;\n titleId: string;\n episodeId: string | null;\n positionSeconds: number;\n completed: boolean;\n lastDevice: string | null;\n updatedAt: string;\n title: Pick<HokTitle, 'id' | 'title' | 'type'> | null;\n}\n\n// ============================================================================\n// Connection wrappers\n// ============================================================================\n\ninterface HokConnection<TItem> {\n items: TItem[];\n pageInfo: HokPageInfo;\n}\n\n// ============================================================================\n// Inline field selections (reused across ops)\n// ============================================================================\n\nconst TITLE_FIELDS = `\n id title slug type status synopsis genres tags originalLanguage originCountry\n releaseYear releaseDate runtimeMinutes certification aiDisclosure studioId\n createdAt updatedAt\n`;\n\nconst STUDIO_FIELDS = `\n id name slug description country websiteUrl isVerified tags createdAt updatedAt\n`;\n\nconst PERSON_FIELDS = `\n id name biography knownFor primaryLanguage portfolioRef tags createdAt updatedAt\n`;\n\nconst PRODUCTION_FIELDS = `\n id title logline synopsis status currency budgetMinorUnits studioId producerId\n resultingTitleId artistrybaseProjectRef tags startDate endDate createdAt updatedAt\n`;\n\nconst AUDITION_FIELDS = `\n id productionId roleName description status isMinorRole payMinorUnits currency\n location language submissionDeadline createdAt updatedAt\n`;\n\nconst REVIEW_FIELDS = `\n id titleId authorId score body hasSpoilers helpfulCount verifiedWatch status\n createdAt updatedAt\n`;\n\nconst RIGHTS_FIELDS = `\n id titleId status modes territories exclusive currency licenseeId startsAt endsAt\n createdAt updatedAt\n`;\n\nconst LIST_FIELDS = `\n id name description kind visibility ownerId itemCount createdAt updatedAt\n`;\n\nconst PAGE_INFO = `pageInfo { cursor hasMore }`;\n\n// ============================================================================\n// Titles\n// ============================================================================\n\nexport interface HokTitleFilters {\n status?: HokTitleStatus;\n type?: HokTitleType;\n studioId?: string;\n}\n\nexport const useTitles = (\n filters: HokTitleFilters = {},\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'titles', filters, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListTitles: HokConnection<HokTitle> }>(\n `query HokTitles($pagination: PaginationInput, $status: HokTitleStatus, $type: HokTitleType, $studioId: ID) {\n hokListTitles(pagination: $pagination, status: $status, type: $type, studioId: $studioId) {\n items { ${TITLE_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n {\n pagination,\n status: filters.status,\n type: filters.type,\n studioId: filters.studioId,\n },\n apiGatewayUrl\n );\n return result.hokListTitles;\n },\n });\n};\n\nexport const useTitle = (id: string | undefined) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'title', id],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokTitle: HokTitleDetail | null }>(\n `query HokTitle($id: ID!) {\n hokTitle(id: $id) {\n ${TITLE_FIELDS}\n studio { id name }\n credits {\n id personId titleId role characterName billingOrder\n person { id name knownFor }\n }\n seasons { id name number synopsis }\n episodes { id name number seasonId synopsis runtimeMinutes airDate }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.hokTitle;\n },\n enabled: Boolean(id),\n });\n};\n\nexport interface CreateTitleInput {\n title: string;\n type?: HokTitleType;\n synopsis?: string;\n genres?: string[];\n tags?: string[];\n originalLanguage?: string;\n originCountry?: string;\n releaseYear?: number;\n runtimeMinutes?: number;\n certification?: string;\n slug?: string;\n studioId?: string;\n aiDisclosure?: boolean;\n}\n\nexport const useCreateTitle = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateTitleInput) => {\n const result = await hookmoviesQuery<{ hokCreateTitle: HokTitle }>(\n `mutation HokCreateTitle($input: HokCreateTitleInput!) {\n hokCreateTitle(input: $input) { ${TITLE_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateTitle;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'titles'] });\n },\n });\n};\n\nexport interface UpdateTitleInput {\n title?: string;\n type?: HokTitleType;\n synopsis?: string;\n genres?: string[];\n tags?: string[];\n originalLanguage?: string;\n originCountry?: string;\n releaseYear?: number;\n runtimeMinutes?: number;\n certification?: string;\n slug?: string;\n studioId?: string;\n aiDisclosure?: boolean;\n}\n\nexport const useUpdateTitle = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: UpdateTitleInput }) => {\n const result = await hookmoviesQuery<{ hokUpdateTitle: HokTitle }>(\n `mutation HokUpdateTitle($id: ID!, $input: HokUpdateTitleInput!) {\n hokUpdateTitle(id: $id, input: $input) { ${TITLE_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.hokUpdateTitle;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'titles'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'title', data.id] });\n },\n });\n};\n\nexport const useTransitionTitle = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: HokTitleStatus }) => {\n const result = await hookmoviesQuery<{ hokTransitionTitle: HokTitle }>(\n `mutation HokTransitionTitle($id: ID!, $status: HokTitleStatus!) {\n hokTransitionTitle(id: $id, status: $status) { ${TITLE_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.hokTransitionTitle;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'titles'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'title', data.id] });\n },\n });\n};\n\nexport const useArchiveTitle = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await hookmoviesQuery<{ hokArchiveTitle: boolean }>(\n `mutation HokArchiveTitle($id: ID!) { hokArchiveTitle(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.hokArchiveTitle;\n },\n onSuccess: (_data, id) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'titles'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'title', id] });\n },\n });\n};\n\n// ============================================================================\n// Studios\n// ============================================================================\n\nexport const useStudios = (pagination: HokPaginationInput = { limit: 50, offset: 0 }) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'studios', pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListStudios: HokConnection<HokStudio> }>(\n `query HokStudios($pagination: PaginationInput) {\n hokListStudios(pagination: $pagination) {\n items { ${STUDIO_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n { pagination },\n apiGatewayUrl\n );\n return result.hokListStudios;\n },\n });\n};\n\nexport interface CreateStudioInput {\n name: string;\n slug?: string;\n description?: string;\n country?: string;\n websiteUrl?: string;\n tags?: string[];\n}\n\nexport const useCreateStudio = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateStudioInput) => {\n const result = await hookmoviesQuery<{ hokCreateStudio: HokStudio }>(\n `mutation HokCreateStudio($input: HokCreateStudioInput!) {\n hokCreateStudio(input: $input) { ${STUDIO_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateStudio;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'studios'] });\n },\n });\n};\n\n// ============================================================================\n// People\n// ============================================================================\n\nexport const usePeople = (pagination: HokPaginationInput = { limit: 50, offset: 0 }) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'people', pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListPeople: HokConnection<HokPerson> }>(\n `query HokPeople($pagination: PaginationInput) {\n hokListPeople(pagination: $pagination) {\n items { ${PERSON_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n { pagination },\n apiGatewayUrl\n );\n return result.hokListPeople;\n },\n });\n};\n\nexport interface CreatePersonInput {\n name: string;\n biography?: string;\n knownFor?: string;\n primaryLanguage?: string;\n portfolioRef?: string;\n tags?: string[];\n}\n\nexport const useCreatePerson = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreatePersonInput) => {\n const result = await hookmoviesQuery<{ hokCreatePerson: HokPerson }>(\n `mutation HokCreatePerson($input: HokCreatePersonInput!) {\n hokCreatePerson(input: $input) { ${PERSON_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreatePerson;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'people'] });\n },\n });\n};\n\n// ============================================================================\n// Productions\n// ============================================================================\n\nexport interface HokProductionFilters {\n status?: HokProductionStatus;\n studioId?: string;\n}\n\nexport const useProductions = (\n filters: HokProductionFilters = {},\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'productions', filters, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListProductions: HokConnection<HokProduction> }>(\n `query HokProductions($pagination: PaginationInput, $status: HokProductionStatus, $studioId: ID) {\n hokListProductions(pagination: $pagination, status: $status, studioId: $studioId) {\n items { ${PRODUCTION_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n { pagination, status: filters.status, studioId: filters.studioId },\n apiGatewayUrl\n );\n return result.hokListProductions;\n },\n });\n};\n\nexport const useProduction = (id: string | undefined) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'production', id],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokProduction: HokProductionDetail | null }>(\n `query HokProduction($id: ID!) {\n hokProduction(id: $id) {\n ${PRODUCTION_FIELDS}\n auditions {\n id roleName status isMinorRole payMinorUnits currency location language submissionDeadline\n }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.hokProduction;\n },\n enabled: Boolean(id),\n });\n};\n\nexport interface CreateProductionInput {\n title: string;\n logline?: string;\n synopsis?: string;\n currency?: string;\n budgetMinorUnits?: string;\n studioId?: string;\n producerId?: string;\n artistrybaseProjectRef?: string;\n tags?: string[];\n startDate?: string;\n endDate?: string;\n}\n\nexport const useCreateProduction = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateProductionInput) => {\n const result = await hookmoviesQuery<{ hokCreateProduction: HokProduction }>(\n `mutation HokCreateProduction($input: HokCreateProductionInput!) {\n hokCreateProduction(input: $input) { ${PRODUCTION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateProduction;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'productions'] });\n },\n });\n};\n\nexport const useTransitionProduction = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: HokProductionStatus }) => {\n const result = await hookmoviesQuery<{ hokTransitionProduction: HokProduction }>(\n `mutation HokTransitionProduction($id: ID!, $status: HokProductionStatus!) {\n hokTransitionProduction(id: $id, status: $status) { ${PRODUCTION_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.hokTransitionProduction;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'productions'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'production', data.id] });\n },\n });\n};\n\n// ============================================================================\n// Auditions & Applications\n// ============================================================================\n\nexport interface HokAuditionFilters {\n status?: HokAuditionStatus;\n productionId?: string;\n}\n\nexport const useAuditions = (\n filters: HokAuditionFilters = {},\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'auditions', filters, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListAuditions: HokConnection<HokAudition> }>(\n `query HokAuditions($pagination: PaginationInput, $status: HokAuditionStatus, $productionId: ID) {\n hokListAuditions(pagination: $pagination, status: $status, productionId: $productionId) {\n items {\n ${AUDITION_FIELDS}\n production { id title }\n }\n ${PAGE_INFO}\n }\n }`,\n { pagination, status: filters.status, productionId: filters.productionId },\n apiGatewayUrl\n );\n return result.hokListAuditions;\n },\n });\n};\n\n/**\n * Resolve a single audition by id. The subgraph exposes no `hokAudition(id)`\n * root field, so we read the (workspace-scoped) audition list and pick the row.\n * Fetched with a generous page size since auditions are workspace-bounded.\n */\nexport const useAuditionById = (id: string | undefined) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'audition-by-id', id],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListAuditions: HokConnection<HokAudition> }>(\n `query HokAuditionLookup($pagination: PaginationInput) {\n hokListAuditions(pagination: $pagination) {\n items {\n ${AUDITION_FIELDS}\n production { id title }\n }\n ${PAGE_INFO}\n }\n }`,\n { pagination: { limit: 200, offset: 0 } },\n apiGatewayUrl\n );\n return result.hokListAuditions.items.find((a) => a.id === id) ?? null;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useAuditionApplications = (auditionId: string | undefined) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'applications', auditionId],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListApplications: HokApplication[] }>(\n `query HokApplications($auditionId: ID!) {\n hokListApplications(auditionId: $auditionId) {\n id auditionId applicantId coverNote score status createdAt updatedAt\n }\n }`,\n { auditionId },\n apiGatewayUrl\n );\n return result.hokListApplications;\n },\n enabled: Boolean(auditionId),\n });\n};\n\nexport interface CreateAuditionInput {\n productionId: string;\n roleName: string;\n description?: string;\n payMinorUnits?: string;\n currency?: string;\n location?: string;\n language?: string;\n isMinorRole?: boolean;\n submissionDeadline?: string;\n}\n\nexport const useCreateAudition = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateAuditionInput) => {\n const result = await hookmoviesQuery<{ hokCreateAudition: HokAudition }>(\n `mutation HokCreateAudition($input: HokCreateAuditionInput!) {\n hokCreateAudition(input: $input) { ${AUDITION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateAudition;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'auditions'] });\n },\n });\n};\n\nexport const useCloseAudition = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await hookmoviesQuery<{ hokCloseAudition: HokAudition }>(\n `mutation HokCloseAudition($id: ID!) {\n hokCloseAudition(id: $id) { ${AUDITION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.hokCloseAudition;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'auditions'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'audition-by-id', data.id] });\n },\n });\n};\n\nexport interface ApplyToAuditionInput {\n auditionId: string;\n coverNote?: string;\n selfTapeFileId?: string;\n}\n\nexport const useApplyToAudition = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: ApplyToAuditionInput) => {\n const result = await hookmoviesQuery<{ hokApplyToAudition: HokApplication }>(\n `mutation HokApplyToAudition($input: HokApplyToAuditionInput!) {\n hokApplyToAudition(input: $input) {\n id auditionId applicantId coverNote score status createdAt updatedAt\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokApplyToAudition;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'applications', data.auditionId] });\n },\n });\n};\n\nexport const useScoreApplication = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, score }: { id: string; score: number }) => {\n const result = await hookmoviesQuery<{ hokScoreApplication: HokApplication }>(\n `mutation HokScoreApplication($id: ID!, $score: Int!) {\n hokScoreApplication(id: $id, score: $score) {\n id auditionId applicantId coverNote score status createdAt updatedAt\n }\n }`,\n { id, score },\n apiGatewayUrl\n );\n return result.hokScoreApplication;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'applications', data.auditionId] });\n },\n });\n};\n\n// ============================================================================\n// Reviews\n// ============================================================================\n\nexport interface HokReviewFilters {\n status?: HokReviewStatus;\n titleId?: string;\n}\n\nexport const useReviews = (\n filters: HokReviewFilters = {},\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'reviews', filters, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListReviews: HokConnection<HokReview> }>(\n `query HokReviews($pagination: PaginationInput, $status: HokReviewStatus, $titleId: ID) {\n hokListReviews(pagination: $pagination, status: $status, titleId: $titleId) {\n items {\n ${REVIEW_FIELDS}\n title { id title }\n }\n ${PAGE_INFO}\n }\n }`,\n { pagination, status: filters.status, titleId: filters.titleId },\n apiGatewayUrl\n );\n return result.hokListReviews;\n },\n });\n};\n\nexport interface CreateReviewInput {\n titleId: string;\n score: number;\n body?: string;\n hasSpoilers?: boolean;\n aspectScores?: Record<string, unknown>;\n}\n\nexport const useCreateReview = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateReviewInput) => {\n const result = await hookmoviesQuery<{ hokCreateReview: HokReview }>(\n `mutation HokCreateReview($input: HokCreateReviewInput!) {\n hokCreateReview(input: $input) { ${REVIEW_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateReview;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'reviews'] });\n },\n });\n};\n\nexport const useDeleteReview = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await hookmoviesQuery<{ hokDeleteReview: boolean }>(\n `mutation HokDeleteReview($id: ID!) { hokDeleteReview(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.hokDeleteReview;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'reviews'] });\n },\n });\n};\n\n// ============================================================================\n// Rights Windows\n// ============================================================================\n\nexport interface HokRightsFilters {\n status?: HokRightsWindowStatus;\n titleId?: string;\n}\n\nexport const useRightsWindows = (\n filters: HokRightsFilters = {},\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'rights', filters, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{\n hokListRightsWindows: HokConnection<HokRightsWindow>;\n }>(\n `query HokRightsWindows($pagination: PaginationInput, $status: HokRightsWindowStatus, $titleId: ID) {\n hokListRightsWindows(pagination: $pagination, status: $status, titleId: $titleId) {\n items {\n ${RIGHTS_FIELDS}\n title { id title }\n }\n ${PAGE_INFO}\n }\n }`,\n { pagination, status: filters.status, titleId: filters.titleId },\n apiGatewayUrl\n );\n return result.hokListRightsWindows;\n },\n });\n};\n\nexport interface CreateRightsWindowInput {\n titleId: string;\n modes: HokMonetizationMode[];\n territories?: string[];\n exclusive?: boolean;\n currency?: string;\n licenseeId?: string;\n startsAt?: string;\n endsAt?: string;\n contractFileId?: string;\n priceMinorUnits?: Record<string, unknown>;\n}\n\nexport const useCreateRightsWindow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateRightsWindowInput) => {\n const result = await hookmoviesQuery<{ hokCreateRightsWindow: HokRightsWindow }>(\n `mutation HokCreateRightsWindow($input: HokCreateRightsWindowInput!) {\n hokCreateRightsWindow(input: $input) { ${RIGHTS_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateRightsWindow;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'rights'] });\n },\n });\n};\n\nexport const useTransitionRightsWindow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: HokRightsWindowStatus }) => {\n const result = await hookmoviesQuery<{ hokTransitionRightsWindow: HokRightsWindow }>(\n `mutation HokTransitionRightsWindow($id: ID!, $status: HokRightsWindowStatus!) {\n hokTransitionRightsWindow(id: $id, status: $status) { ${RIGHTS_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.hokTransitionRightsWindow;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'rights'] });\n },\n });\n};\n\nexport const useRevokeEntitlement = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await hookmoviesQuery<{ hokRevokeEntitlement: boolean }>(\n `mutation HokRevokeEntitlement($id: ID!) { hokRevokeEntitlement(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.hokRevokeEntitlement;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-entitlements'] });\n },\n });\n};\n\n// ============================================================================\n// Entitlements (self-scoped)\n// ============================================================================\n\nexport const useMyEntitlements = (titleId?: string) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'my-entitlements', titleId],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokMyEntitlements: HokEntitlement[] }>(\n `query HokMyEntitlements($titleId: ID) {\n hokMyEntitlements(titleId: $titleId) {\n id titleId userId mode source status territory expiresAt createdAt updatedAt\n title { id title }\n }\n }`,\n { titleId },\n apiGatewayUrl\n );\n return result.hokMyEntitlements;\n },\n });\n};\n\n// ============================================================================\n// Lists / Watchlists (self-scoped)\n// ============================================================================\n\nexport const useMyLists = (\n kind?: HokListKind,\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'my-lists', kind, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokMyLists: HokConnection<HokList> }>(\n `query HokMyLists($kind: HokListKind, $pagination: PaginationInput) {\n hokMyLists(kind: $kind, pagination: $pagination) {\n items { ${LIST_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n { kind, pagination },\n apiGatewayUrl\n );\n return result.hokMyLists;\n },\n });\n};\n\nexport interface CreateListInput {\n name: string;\n description?: string;\n kind?: HokListKind;\n visibility?: HokListVisibility;\n items?: Record<string, unknown>;\n}\n\nexport const useCreateList = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateListInput) => {\n const result = await hookmoviesQuery<{ hokCreateList: HokList }>(\n `mutation HokCreateList($input: HokCreateListInput!) {\n hokCreateList(input: $input) { ${LIST_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateList;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-lists'] });\n },\n });\n};\n\nexport const useDeleteList = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await hookmoviesQuery<{ hokDeleteList: boolean }>(\n `mutation HokDeleteList($id: ID!) { hokDeleteList(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.hokDeleteList;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-lists'] });\n },\n });\n};\n\n// ============================================================================\n// Watch progress / Continue Watching (self-scoped)\n// ============================================================================\n\nexport const useMyWatchProgress = (titleId?: string) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'my-watch-progress', titleId],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokMyWatchProgress: HokWatchProgress[] }>(\n `query HokMyWatchProgress($titleId: ID) {\n hokMyWatchProgress(titleId: $titleId) {\n id titleId episodeId positionSeconds completed lastDevice updatedAt\n title { id title type }\n }\n }`,\n { titleId },\n apiGatewayUrl\n );\n return result.hokMyWatchProgress;\n },\n });\n};\n\n// ============================================================================\n// Health probe (used by the dashboard service-status card)\n// ============================================================================\n\nexport const useHealth = () => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'health'],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokHealth: string }>(\n `query HokHealth { hokHealth }`,\n {},\n apiGatewayUrl\n );\n return result.hokHealth;\n },\n staleTime: 60 * 1000,\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useHookMoviesApi.js","names":[],"sources":["../../../src/hookmovies/hooks/useHookMoviesApi.ts"],"sourcesContent":["/**\n * HookMovies API hooks\n * @module hookmovies/hooks\n *\n * Real data layer for the HookMovies workspace subgraph (`hookmovies` Hive\n * service / `wspace-hookmovies-svc`). Every hook talks to the live workspace\n * GraphQL gateway via {@link graphqlFetch} with inline operations whose fields\n * mirror `.hive-schema.graphql` exactly. No mocks.\n *\n * Conventions (mirrors microfe-kadaikodi):\n * - `hookmoviesQuery` wraps graphqlFetch({ gateway: 'workspace', workspaceToken: true })\n * and throws on GraphQL errors / missing data.\n * - One react-query `useQuery` per read op and `useMutation` per write op.\n * - Strict hand-written result interfaces — no `any`.\n * - Pagination uses the subgraph's `PaginationInput` (limit/offset/cursor) and\n * `Hok*Connection { items, pageInfo { cursor hasMore } }` shapes verbatim.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useHookMovies } from '../context';\n\n// ============================================================================\n// Low-level query runner\n// ============================================================================\n\nconst hookmoviesQuery = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'GraphQL request failed');\n }\n\n if (!response.data) {\n throw new Error('GraphQL response did not include data');\n }\n\n // This MFE bypasses Apollo, so fe-libs' short-lived graphqlFetch read cache\n // (~15s) would otherwise serve pre-write data to the very next refetch issued\n // by a mutation's onSuccess invalidation. Clear it after any successful\n // mutation so every downstream read is fresh (fleet-wide stale-read-after-\n // write fix).\n if (query.trimStart().startsWith('mutation')) {\n clearGraphqlFetchResponseCache();\n }\n\n return response.data;\n};\n\nconst QK = 'hookmovies' as const;\n\n// ============================================================================\n// Shared scalar / enum types (mirror .hive-schema.graphql)\n// ============================================================================\n\nexport interface HokPaginationInput {\n cursor?: string | null;\n limit?: number | null;\n offset?: number | null;\n}\n\nexport interface HokPageInfo {\n cursor: string | null;\n hasMore: boolean;\n}\n\nexport type HokTitleType =\n | 'MOVIE'\n | 'SERIES'\n | 'SHORT_FILM'\n | 'DOCUMENTARY'\n | 'ANIME'\n | 'SHORT_FORM'\n | 'LONG_FORM'\n | 'LIVE_EVENT'\n | 'TRAILER'\n | 'COLLECTION'\n | 'FAST_CHANNEL';\n\nexport type HokTitleStatus =\n | 'DRAFT'\n | 'IN_REVIEW'\n | 'SCHEDULED'\n | 'PUBLISHED'\n | 'UNPUBLISHED'\n | 'ARCHIVED';\n\nexport type HokProductionStatus =\n | 'DEVELOPMENT'\n | 'GREENLIT'\n | 'IN_PRODUCTION'\n | 'POST_PRODUCTION'\n | 'RELEASED'\n | 'SHELVED';\n\nexport type HokAuditionStatus = 'OPEN' | 'REVIEWING' | 'CALLBACKS' | 'CLOSED' | 'CANCELLED';\n\nexport type HokApplicationStatus =\n | 'SUBMITTED'\n | 'SHORTLISTED'\n | 'CALLBACK'\n | 'OFFERED'\n | 'REJECTED'\n | 'WITHDRAWN';\n\nexport type HokCreditRole =\n | 'ACTOR'\n | 'DIRECTOR'\n | 'WRITER'\n | 'PRODUCER'\n | 'CINEMATOGRAPHER'\n | 'EDITOR'\n | 'COMPOSER'\n | 'VOICE_ACTOR'\n | 'CREW';\n\nexport type HokReviewStatus = 'PENDING' | 'PUBLISHED' | 'HIDDEN' | 'REMOVED';\n\nexport type HokRightsWindowStatus = 'DRAFT' | 'PENDING' | 'ACTIVE' | 'EXPIRED' | 'REVOKED';\n\nexport type HokMonetizationMode = 'FREE_AVOD' | 'SVOD' | 'TVOD_RENT' | 'TVOD_BUY' | 'PPV' | 'FAST';\n\nexport type HokEntitlementSource = 'SUBSCRIPTION' | 'PURCHASE' | 'RENTAL' | 'PROMO' | 'FREE';\n\nexport type HokEntitlementStatus = 'ACTIVE' | 'EXPIRED' | 'REVOKED';\n\nexport type HokListKind = 'WATCHLIST' | 'PLAYLIST';\n\nexport type HokListVisibility = 'PRIVATE' | 'UNLISTED' | 'PUBLIC';\n\n// ============================================================================\n// Domain object types\n// ============================================================================\n\nexport interface HokStudio {\n id: string;\n name: string;\n slug: string | null;\n description: string | null;\n country: string | null;\n websiteUrl: string | null;\n isVerified: boolean;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokPerson {\n id: string;\n name: string;\n biography: string | null;\n knownFor: string | null;\n primaryLanguage: string | null;\n portfolioRef: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokCredit {\n id: string;\n personId: string;\n titleId: string;\n role: HokCreditRole;\n characterName: string | null;\n billingOrder: number;\n person: Pick<HokPerson, 'id' | 'name' | 'knownFor'> | null;\n}\n\nexport interface HokEpisodeSummary {\n id: string;\n name: string;\n number: number;\n seasonId: string | null;\n synopsis: string | null;\n runtimeMinutes: number | null;\n airDate: string | null;\n}\n\nexport interface HokSeasonSummary {\n id: string;\n name: string | null;\n number: number;\n synopsis: string | null;\n}\n\nexport interface HokTitle {\n id: string;\n title: string;\n slug: string | null;\n type: HokTitleType;\n status: HokTitleStatus;\n synopsis: string | null;\n genres: string[];\n tags: string[];\n originalLanguage: string | null;\n originCountry: string | null;\n releaseYear: number | null;\n releaseDate: string | null;\n runtimeMinutes: number | null;\n certification: string | null;\n aiDisclosure: boolean;\n studioId: string | null;\n posterFileId: string | null;\n backdropFileId: string | null;\n trailerFileId: string | null;\n videoFileId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokTitleDetail extends HokTitle {\n studio: Pick<HokStudio, 'id' | 'name'> | null;\n credits: HokCredit[];\n seasons: HokSeasonSummary[];\n episodes: HokEpisodeSummary[];\n}\n\nexport interface HokProduction {\n id: string;\n title: string;\n logline: string | null;\n synopsis: string | null;\n status: HokProductionStatus;\n currency: string;\n budgetMinorUnits: string;\n studioId: string | null;\n producerId: string | null;\n resultingTitleId: string | null;\n artistrybaseProjectRef: string | null;\n tags: string[];\n startDate: string | null;\n endDate: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokAuditionSummary {\n id: string;\n roleName: string;\n status: HokAuditionStatus;\n isMinorRole: boolean;\n payMinorUnits: string;\n currency: string;\n location: string | null;\n language: string | null;\n submissionDeadline: string | null;\n}\n\nexport interface HokProductionDetail extends HokProduction {\n auditions: HokAuditionSummary[];\n}\n\nexport interface HokAudition {\n id: string;\n productionId: string;\n roleName: string;\n description: string | null;\n status: HokAuditionStatus;\n isMinorRole: boolean;\n payMinorUnits: string;\n currency: string;\n location: string | null;\n language: string | null;\n submissionDeadline: string | null;\n createdAt: string;\n updatedAt: string;\n production: Pick<HokProduction, 'id' | 'title'> | null;\n}\n\nexport interface HokApplication {\n id: string;\n auditionId: string;\n applicantId: string;\n coverNote: string | null;\n score: number | null;\n status: HokApplicationStatus;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokReview {\n id: string;\n titleId: string;\n authorId: string;\n score: number;\n body: string | null;\n hasSpoilers: boolean;\n helpfulCount: number;\n verifiedWatch: boolean;\n status: HokReviewStatus;\n createdAt: string;\n updatedAt: string;\n title: Pick<HokTitle, 'id' | 'title'> | null;\n}\n\nexport interface HokRightsWindow {\n id: string;\n titleId: string;\n status: HokRightsWindowStatus;\n modes: HokMonetizationMode[];\n territories: string[];\n exclusive: boolean;\n currency: string;\n licenseeId: string | null;\n startsAt: string | null;\n endsAt: string | null;\n createdAt: string;\n updatedAt: string;\n title: Pick<HokTitle, 'id' | 'title'> | null;\n}\n\nexport interface HokEntitlement {\n id: string;\n titleId: string;\n userId: string;\n mode: HokMonetizationMode;\n source: HokEntitlementSource;\n status: HokEntitlementStatus;\n territory: string | null;\n expiresAt: string | null;\n createdAt: string;\n updatedAt: string;\n title: Pick<HokTitle, 'id' | 'title'> | null;\n}\n\nexport interface HokList {\n id: string;\n name: string;\n description: string | null;\n kind: HokListKind;\n visibility: HokListVisibility;\n ownerId: string;\n itemCount: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface HokWatchProgress {\n id: string;\n titleId: string;\n episodeId: string | null;\n positionSeconds: number;\n completed: boolean;\n lastDevice: string | null;\n updatedAt: string;\n title: Pick<HokTitle, 'id' | 'title' | 'type'> | null;\n}\n\n// ============================================================================\n// Connection wrappers\n// ============================================================================\n\ninterface HokConnection<TItem> {\n items: TItem[];\n pageInfo: HokPageInfo;\n /** Total rows matching the current filters, across all pages. */\n totalCount: number;\n}\n\n// ============================================================================\n// Inline field selections (reused across ops)\n// ============================================================================\n\nconst TITLE_FIELDS = `\n id title slug type status synopsis genres tags originalLanguage originCountry\n releaseYear releaseDate runtimeMinutes certification aiDisclosure studioId\n posterFileId backdropFileId trailerFileId videoFileId\n createdAt updatedAt\n`;\n\nconst STUDIO_FIELDS = `\n id name slug description country websiteUrl isVerified tags createdAt updatedAt\n`;\n\nconst PERSON_FIELDS = `\n id name biography knownFor primaryLanguage portfolioRef tags createdAt updatedAt\n`;\n\nconst PRODUCTION_FIELDS = `\n id title logline synopsis status currency budgetMinorUnits studioId producerId\n resultingTitleId artistrybaseProjectRef tags startDate endDate createdAt updatedAt\n`;\n\nconst AUDITION_FIELDS = `\n id productionId roleName description status isMinorRole payMinorUnits currency\n location language submissionDeadline createdAt updatedAt\n`;\n\nconst REVIEW_FIELDS = `\n id titleId authorId score body hasSpoilers helpfulCount verifiedWatch status\n createdAt updatedAt\n`;\n\nconst RIGHTS_FIELDS = `\n id titleId status modes territories exclusive currency licenseeId startsAt endsAt\n createdAt updatedAt\n`;\n\nconst LIST_FIELDS = `\n id name description kind visibility ownerId itemCount createdAt updatedAt\n`;\n\nconst PAGE_INFO = `pageInfo { cursor hasMore }\n totalCount`;\n\n// ============================================================================\n// Titles\n// ============================================================================\n\nexport interface HokTitleFilters {\n status?: HokTitleStatus;\n type?: HokTitleType;\n studioId?: string;\n}\n\nexport const useTitles = (\n filters: HokTitleFilters = {},\n pagination: HokPaginationInput = { limit: 50, offset: 0 },\n search?: string\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'titles', filters, pagination, search ?? ''],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListTitles: HokConnection<HokTitle> }>(\n `query HokTitles($pagination: PaginationInput, $search: String, $status: HokTitleStatus, $type: HokTitleType, $studioId: ID) {\n hokListTitles(pagination: $pagination, search: $search, status: $status, type: $type, studioId: $studioId) {\n items { ${TITLE_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n {\n pagination,\n search: search?.trim() ? search.trim() : undefined,\n status: filters.status,\n type: filters.type,\n studioId: filters.studioId,\n },\n apiGatewayUrl\n );\n return result.hokListTitles;\n },\n });\n};\n\nexport const useTitle = (id: string | undefined) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'title', id],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokTitle: HokTitleDetail | null }>(\n `query HokTitle($id: ID!) {\n hokTitle(id: $id) {\n ${TITLE_FIELDS}\n studio { id name }\n credits {\n id personId titleId role characterName billingOrder\n person { id name knownFor }\n }\n seasons { id name number synopsis }\n episodes { id name number seasonId synopsis runtimeMinutes airDate }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.hokTitle;\n },\n enabled: Boolean(id),\n });\n};\n\nexport interface CreateTitleInput {\n title: string;\n type?: HokTitleType;\n synopsis?: string;\n genres?: string[];\n tags?: string[];\n originalLanguage?: string;\n originCountry?: string;\n releaseYear?: number;\n runtimeMinutes?: number;\n certification?: string;\n slug?: string;\n studioId?: string;\n aiDisclosure?: boolean;\n}\n\nexport const useCreateTitle = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateTitleInput) => {\n const result = await hookmoviesQuery<{ hokCreateTitle: HokTitle }>(\n `mutation HokCreateTitle($input: HokCreateTitleInput!) {\n hokCreateTitle(input: $input) { ${TITLE_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateTitle;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'titles'] });\n },\n });\n};\n\nexport interface UpdateTitleInput {\n title?: string;\n type?: HokTitleType;\n synopsis?: string;\n genres?: string[];\n tags?: string[];\n originalLanguage?: string;\n originCountry?: string;\n releaseYear?: number;\n runtimeMinutes?: number;\n certification?: string;\n slug?: string;\n studioId?: string;\n aiDisclosure?: boolean;\n posterFileId?: string;\n backdropFileId?: string;\n trailerFileId?: string;\n videoFileId?: string;\n}\n\nexport const useUpdateTitle = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: UpdateTitleInput }) => {\n const result = await hookmoviesQuery<{ hokUpdateTitle: HokTitle }>(\n `mutation HokUpdateTitle($id: ID!, $input: HokUpdateTitleInput!) {\n hokUpdateTitle(id: $id, input: $input) { ${TITLE_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.hokUpdateTitle;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'titles'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'title', data.id] });\n },\n });\n};\n\nexport const useTransitionTitle = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: HokTitleStatus }) => {\n const result = await hookmoviesQuery<{ hokTransitionTitle: HokTitle }>(\n `mutation HokTransitionTitle($id: ID!, $status: HokTitleStatus!) {\n hokTransitionTitle(id: $id, status: $status) { ${TITLE_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.hokTransitionTitle;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'titles'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'title', data.id] });\n },\n });\n};\n\nexport const useArchiveTitle = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await hookmoviesQuery<{ hokArchiveTitle: boolean }>(\n `mutation HokArchiveTitle($id: ID!) { hokArchiveTitle(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.hokArchiveTitle;\n },\n onSuccess: (_data, id) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'titles'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'title', id] });\n },\n });\n};\n\n// ============================================================================\n// Studios\n// ============================================================================\n\nexport const useStudios = (\n pagination: HokPaginationInput = { limit: 50, offset: 0 },\n search?: string\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'studios', pagination, search ?? ''],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListStudios: HokConnection<HokStudio> }>(\n `query HokStudios($pagination: PaginationInput, $search: String) {\n hokListStudios(pagination: $pagination, search: $search) {\n items { ${STUDIO_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n { pagination, search: search?.trim() ? search.trim() : undefined },\n apiGatewayUrl\n );\n return result.hokListStudios;\n },\n });\n};\n\nexport interface CreateStudioInput {\n name: string;\n slug?: string;\n description?: string;\n country?: string;\n websiteUrl?: string;\n tags?: string[];\n}\n\nexport const useCreateStudio = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateStudioInput) => {\n const result = await hookmoviesQuery<{ hokCreateStudio: HokStudio }>(\n `mutation HokCreateStudio($input: HokCreateStudioInput!) {\n hokCreateStudio(input: $input) { ${STUDIO_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateStudio;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'studios'] });\n },\n });\n};\n\n// ============================================================================\n// People\n// ============================================================================\n\nexport const usePeople = (\n pagination: HokPaginationInput = { limit: 50, offset: 0 },\n search?: string\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'people', pagination, search ?? ''],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListPeople: HokConnection<HokPerson> }>(\n `query HokPeople($pagination: PaginationInput, $search: String) {\n hokListPeople(pagination: $pagination, search: $search) {\n items { ${PERSON_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n { pagination, search: search?.trim() ? search.trim() : undefined },\n apiGatewayUrl\n );\n return result.hokListPeople;\n },\n });\n};\n\nexport interface CreatePersonInput {\n name: string;\n biography?: string;\n knownFor?: string;\n primaryLanguage?: string;\n portfolioRef?: string;\n tags?: string[];\n}\n\nexport const useCreatePerson = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreatePersonInput) => {\n const result = await hookmoviesQuery<{ hokCreatePerson: HokPerson }>(\n `mutation HokCreatePerson($input: HokCreatePersonInput!) {\n hokCreatePerson(input: $input) { ${PERSON_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreatePerson;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'people'] });\n },\n });\n};\n\n// ============================================================================\n// Productions\n// ============================================================================\n\nexport interface HokProductionFilters {\n status?: HokProductionStatus;\n studioId?: string;\n}\n\nexport const useProductions = (\n filters: HokProductionFilters = {},\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'productions', filters, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListProductions: HokConnection<HokProduction> }>(\n `query HokProductions($pagination: PaginationInput, $status: HokProductionStatus, $studioId: ID) {\n hokListProductions(pagination: $pagination, status: $status, studioId: $studioId) {\n items { ${PRODUCTION_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n { pagination, status: filters.status, studioId: filters.studioId },\n apiGatewayUrl\n );\n return result.hokListProductions;\n },\n });\n};\n\nexport const useProduction = (id: string | undefined) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'production', id],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokProduction: HokProductionDetail | null }>(\n `query HokProduction($id: ID!) {\n hokProduction(id: $id) {\n ${PRODUCTION_FIELDS}\n auditions {\n id roleName status isMinorRole payMinorUnits currency location language submissionDeadline\n }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.hokProduction;\n },\n enabled: Boolean(id),\n });\n};\n\nexport interface CreateProductionInput {\n title: string;\n logline?: string;\n synopsis?: string;\n currency?: string;\n budgetMinorUnits?: string;\n studioId?: string;\n producerId?: string;\n artistrybaseProjectRef?: string;\n tags?: string[];\n startDate?: string;\n endDate?: string;\n}\n\nexport const useCreateProduction = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateProductionInput) => {\n const result = await hookmoviesQuery<{ hokCreateProduction: HokProduction }>(\n `mutation HokCreateProduction($input: HokCreateProductionInput!) {\n hokCreateProduction(input: $input) { ${PRODUCTION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateProduction;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'productions'] });\n },\n });\n};\n\nexport const useTransitionProduction = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: HokProductionStatus }) => {\n const result = await hookmoviesQuery<{ hokTransitionProduction: HokProduction }>(\n `mutation HokTransitionProduction($id: ID!, $status: HokProductionStatus!) {\n hokTransitionProduction(id: $id, status: $status) { ${PRODUCTION_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.hokTransitionProduction;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'productions'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'production', data.id] });\n },\n });\n};\n\n// ============================================================================\n// Auditions & Applications\n// ============================================================================\n\nexport interface HokAuditionFilters {\n status?: HokAuditionStatus;\n productionId?: string;\n}\n\nexport const useAuditions = (\n filters: HokAuditionFilters = {},\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'auditions', filters, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListAuditions: HokConnection<HokAudition> }>(\n `query HokAuditions($pagination: PaginationInput, $status: HokAuditionStatus, $productionId: ID) {\n hokListAuditions(pagination: $pagination, status: $status, productionId: $productionId) {\n items {\n ${AUDITION_FIELDS}\n production { id title }\n }\n ${PAGE_INFO}\n }\n }`,\n { pagination, status: filters.status, productionId: filters.productionId },\n apiGatewayUrl\n );\n return result.hokListAuditions;\n },\n });\n};\n\n/**\n * Resolve a single audition by id. The subgraph exposes no `hokAudition(id)`\n * root field, so we read the (workspace-scoped) audition list and pick the row.\n * Fetched with a generous page size since auditions are workspace-bounded.\n */\nexport const useAuditionById = (id: string | undefined) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'audition-by-id', id],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListAuditions: HokConnection<HokAudition> }>(\n `query HokAuditionLookup($pagination: PaginationInput) {\n hokListAuditions(pagination: $pagination) {\n items {\n ${AUDITION_FIELDS}\n production { id title }\n }\n ${PAGE_INFO}\n }\n }`,\n { pagination: { limit: 200, offset: 0 } },\n apiGatewayUrl\n );\n return result.hokListAuditions.items.find((a) => a.id === id) ?? null;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useAuditionApplications = (auditionId: string | undefined) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'applications', auditionId],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListApplications: HokApplication[] }>(\n `query HokApplications($auditionId: ID!) {\n hokListApplications(auditionId: $auditionId) {\n id auditionId applicantId coverNote score status createdAt updatedAt\n }\n }`,\n { auditionId },\n apiGatewayUrl\n );\n return result.hokListApplications;\n },\n enabled: Boolean(auditionId),\n });\n};\n\nexport interface CreateAuditionInput {\n productionId: string;\n roleName: string;\n description?: string;\n payMinorUnits?: string;\n currency?: string;\n location?: string;\n language?: string;\n isMinorRole?: boolean;\n submissionDeadline?: string;\n}\n\nexport const useCreateAudition = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateAuditionInput) => {\n const result = await hookmoviesQuery<{ hokCreateAudition: HokAudition }>(\n `mutation HokCreateAudition($input: HokCreateAuditionInput!) {\n hokCreateAudition(input: $input) { ${AUDITION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateAudition;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'auditions'] });\n },\n });\n};\n\nexport const useCloseAudition = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await hookmoviesQuery<{ hokCloseAudition: HokAudition }>(\n `mutation HokCloseAudition($id: ID!) {\n hokCloseAudition(id: $id) { ${AUDITION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.hokCloseAudition;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'auditions'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'audition-by-id', data.id] });\n },\n });\n};\n\nexport interface ApplyToAuditionInput {\n auditionId: string;\n coverNote?: string;\n selfTapeFileId?: string;\n}\n\nexport const useApplyToAudition = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: ApplyToAuditionInput) => {\n const result = await hookmoviesQuery<{ hokApplyToAudition: HokApplication }>(\n `mutation HokApplyToAudition($input: HokApplyToAuditionInput!) {\n hokApplyToAudition(input: $input) {\n id auditionId applicantId coverNote score status createdAt updatedAt\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokApplyToAudition;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'applications', data.auditionId] });\n },\n });\n};\n\nexport const useScoreApplication = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, score }: { id: string; score: number }) => {\n const result = await hookmoviesQuery<{ hokScoreApplication: HokApplication }>(\n `mutation HokScoreApplication($id: ID!, $score: Int!) {\n hokScoreApplication(id: $id, score: $score) {\n id auditionId applicantId coverNote score status createdAt updatedAt\n }\n }`,\n { id, score },\n apiGatewayUrl\n );\n return result.hokScoreApplication;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'applications', data.auditionId] });\n },\n });\n};\n\n// ============================================================================\n// Reviews\n// ============================================================================\n\nexport interface HokReviewFilters {\n status?: HokReviewStatus;\n titleId?: string;\n}\n\nexport const useReviews = (\n filters: HokReviewFilters = {},\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'reviews', filters, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListReviews: HokConnection<HokReview> }>(\n `query HokReviews($pagination: PaginationInput, $status: HokReviewStatus, $titleId: ID) {\n hokListReviews(pagination: $pagination, status: $status, titleId: $titleId) {\n items {\n ${REVIEW_FIELDS}\n title { id title }\n }\n ${PAGE_INFO}\n }\n }`,\n { pagination, status: filters.status, titleId: filters.titleId },\n apiGatewayUrl\n );\n return result.hokListReviews;\n },\n });\n};\n\nexport interface CreateReviewInput {\n titleId: string;\n score: number;\n body?: string;\n hasSpoilers?: boolean;\n aspectScores?: Record<string, unknown>;\n}\n\nexport const useCreateReview = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateReviewInput) => {\n const result = await hookmoviesQuery<{ hokCreateReview: HokReview }>(\n `mutation HokCreateReview($input: HokCreateReviewInput!) {\n hokCreateReview(input: $input) { ${REVIEW_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateReview;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'reviews'] });\n },\n });\n};\n\nexport const useDeleteReview = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await hookmoviesQuery<{ hokDeleteReview: boolean }>(\n `mutation HokDeleteReview($id: ID!) { hokDeleteReview(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.hokDeleteReview;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'reviews'] });\n },\n });\n};\n\n// ============================================================================\n// Rights Windows\n// ============================================================================\n\nexport interface HokRightsFilters {\n status?: HokRightsWindowStatus;\n titleId?: string;\n}\n\nexport const useRightsWindows = (\n filters: HokRightsFilters = {},\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'rights', filters, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{\n hokListRightsWindows: HokConnection<HokRightsWindow>;\n }>(\n `query HokRightsWindows($pagination: PaginationInput, $status: HokRightsWindowStatus, $titleId: ID) {\n hokListRightsWindows(pagination: $pagination, status: $status, titleId: $titleId) {\n items {\n ${RIGHTS_FIELDS}\n title { id title }\n }\n ${PAGE_INFO}\n }\n }`,\n { pagination, status: filters.status, titleId: filters.titleId },\n apiGatewayUrl\n );\n return result.hokListRightsWindows;\n },\n });\n};\n\nexport interface CreateRightsWindowInput {\n titleId: string;\n modes: HokMonetizationMode[];\n territories?: string[];\n exclusive?: boolean;\n currency?: string;\n licenseeId?: string;\n startsAt?: string;\n endsAt?: string;\n contractFileId?: string;\n priceMinorUnits?: Record<string, unknown>;\n}\n\nexport const useCreateRightsWindow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateRightsWindowInput) => {\n const result = await hookmoviesQuery<{ hokCreateRightsWindow: HokRightsWindow }>(\n `mutation HokCreateRightsWindow($input: HokCreateRightsWindowInput!) {\n hokCreateRightsWindow(input: $input) { ${RIGHTS_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateRightsWindow;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'rights'] });\n },\n });\n};\n\nexport const useTransitionRightsWindow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: HokRightsWindowStatus }) => {\n const result = await hookmoviesQuery<{ hokTransitionRightsWindow: HokRightsWindow }>(\n `mutation HokTransitionRightsWindow($id: ID!, $status: HokRightsWindowStatus!) {\n hokTransitionRightsWindow(id: $id, status: $status) { ${RIGHTS_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.hokTransitionRightsWindow;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'rights'] });\n },\n });\n};\n\nexport const useRevokeEntitlement = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await hookmoviesQuery<{ hokRevokeEntitlement: boolean }>(\n `mutation HokRevokeEntitlement($id: ID!) { hokRevokeEntitlement(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.hokRevokeEntitlement;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-entitlements'] });\n },\n });\n};\n\n// ============================================================================\n// Entitlements (self-scoped)\n// ============================================================================\n\nexport const useMyEntitlements = (titleId?: string) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'my-entitlements', titleId],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokMyEntitlements: HokEntitlement[] }>(\n `query HokMyEntitlements($titleId: ID) {\n hokMyEntitlements(titleId: $titleId) {\n id titleId userId mode source status territory expiresAt createdAt updatedAt\n title { id title }\n }\n }`,\n { titleId },\n apiGatewayUrl\n );\n return result.hokMyEntitlements;\n },\n });\n};\n\n// ============================================================================\n// Lists / Watchlists (self-scoped)\n// ============================================================================\n\nexport const useMyLists = (\n kind?: HokListKind,\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'my-lists', kind, pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokMyLists: HokConnection<HokList> }>(\n `query HokMyLists($kind: HokListKind, $pagination: PaginationInput) {\n hokMyLists(kind: $kind, pagination: $pagination) {\n items { ${LIST_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n { kind, pagination },\n apiGatewayUrl\n );\n return result.hokMyLists;\n },\n });\n};\n\nexport interface CreateListInput {\n name: string;\n description?: string;\n kind?: HokListKind;\n visibility?: HokListVisibility;\n items?: Record<string, unknown>;\n}\n\nexport const useCreateList = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: CreateListInput) => {\n const result = await hookmoviesQuery<{ hokCreateList: HokList }>(\n `mutation HokCreateList($input: HokCreateListInput!) {\n hokCreateList(input: $input) { ${LIST_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateList;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-lists'] });\n },\n });\n};\n\nexport const useDeleteList = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await hookmoviesQuery<{ hokDeleteList: boolean }>(\n `mutation HokDeleteList($id: ID!) { hokDeleteList(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.hokDeleteList;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-lists'] });\n },\n });\n};\n\n// ============================================================================\n// Watch progress / Continue Watching (self-scoped)\n// ============================================================================\n\nexport const useMyWatchProgress = (titleId?: string) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'my-watch-progress', titleId],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokMyWatchProgress: HokWatchProgress[] }>(\n `query HokMyWatchProgress($titleId: ID) {\n hokMyWatchProgress(titleId: $titleId) {\n id titleId episodeId positionSeconds completed lastDevice updatedAt\n title { id title type }\n }\n }`,\n { titleId },\n apiGatewayUrl\n );\n return result.hokMyWatchProgress;\n },\n });\n};\n\n// ============================================================================\n// Credits (cast & crew on a title)\n// ============================================================================\n\nexport interface HokCreateCreditInput {\n personId: string;\n titleId: string;\n role?: HokCreditRole;\n characterName?: string;\n billingOrder?: number;\n}\n\n/**\n * Attach a person to a title as cast/crew. Invalidates the affected title's\n * detail query (`[QK,'title',titleId]`) — credits are read as part of that\n * detail selection, so refetching it surfaces the new credit.\n */\nexport const useAddCredit = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: HokCreateCreditInput) => {\n const result = await hookmoviesQuery<{ hokAddCredit: HokCredit }>(\n `mutation HokAddCredit($input: HokCreateCreditInput!) {\n hokAddCredit(input: $input) {\n id personId titleId role characterName billingOrder\n person { id name knownFor }\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokAddCredit;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'title', data.titleId] });\n },\n });\n};\n\n// ============================================================================\n// Seasons & Episodes (series structure under a title)\n// ============================================================================\n\nexport interface HokSeason {\n id: string;\n titleId: string;\n number: number;\n name: string | null;\n synopsis: string | null;\n airDate: string | null;\n}\n\nexport interface HokEpisode {\n id: string;\n titleId: string;\n seasonId: string | null;\n number: number;\n name: string;\n synopsis: string | null;\n runtimeMinutes: number | null;\n airDate: string | null;\n}\n\nexport interface HokCreateSeasonInput {\n titleId: string;\n number: number;\n name?: string;\n synopsis?: string;\n airDate?: string;\n}\n\n/** Add a season to a series title; refetches the title detail (seasons live there). */\nexport const useCreateSeason = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: HokCreateSeasonInput) => {\n const result = await hookmoviesQuery<{ hokCreateSeason: HokSeason }>(\n `mutation HokCreateSeason($input: HokCreateSeasonInput!) {\n hokCreateSeason(input: $input) {\n id titleId number name synopsis airDate\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateSeason;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'title', data.titleId] });\n },\n });\n};\n\nexport interface HokCreateEpisodeInput {\n titleId: string;\n number: number;\n name: string;\n seasonId?: string;\n synopsis?: string;\n runtimeMinutes?: number;\n airDate?: string;\n fileId?: string;\n}\n\n/** Add an episode to a title; refetches the title detail (episodes live there). */\nexport const useCreateEpisode = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: HokCreateEpisodeInput) => {\n const result = await hookmoviesQuery<{ hokCreateEpisode: HokEpisode }>(\n `mutation HokCreateEpisode($input: HokCreateEpisodeInput!) {\n hokCreateEpisode(input: $input) {\n id titleId seasonId number name synopsis runtimeMinutes airDate\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateEpisode;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'title', data.titleId] });\n },\n });\n};\n\n// ============================================================================\n// Watch progress mutation (self-scoped)\n// ============================================================================\n\nexport interface HokRecordProgressInput {\n titleId: string;\n positionSeconds: number;\n completed?: boolean;\n episodeId?: string;\n lastDevice?: string;\n}\n\n/** Record playback position for the calling user; invalidates continue-watching. */\nexport const useRecordProgress = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: HokRecordProgressInput) => {\n const result = await hookmoviesQuery<{ hokRecordProgress: HokWatchProgress }>(\n `mutation HokRecordProgress($input: HokRecordProgressInput!) {\n hokRecordProgress(input: $input) {\n id titleId episodeId positionSeconds completed lastDevice updatedAt\n title { id title type }\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokRecordProgress;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-watch-progress'] });\n },\n });\n};\n\n// ============================================================================\n// Entitlements — check (self) & grant (wspace)\n// ============================================================================\n\nexport interface HokEntitlementCheck {\n entitled: boolean;\n modes: HokMonetizationMode[];\n}\n\n/** Whether the calling user may watch a title, and under which monetization modes. */\nexport const useCheckEntitlement = (titleId?: string) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'check-entitlement', titleId],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokCheckEntitlement: HokEntitlementCheck }>(\n `query HokCheckEntitlement($titleId: ID!) {\n hokCheckEntitlement(titleId: $titleId) { entitled modes }\n }`,\n { titleId },\n apiGatewayUrl\n );\n return result.hokCheckEntitlement;\n },\n enabled: Boolean(titleId),\n });\n};\n\nexport interface HokGrantEntitlementInput {\n titleId: string;\n userId: string;\n mode: HokMonetizationMode;\n source?: HokEntitlementSource;\n territory?: string;\n expiresAt?: string;\n}\n\n/** Grant a user access to a title; invalidates the caller's entitlements list. */\nexport const useGrantEntitlement = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: HokGrantEntitlementInput) => {\n const result = await hookmoviesQuery<{ hokGrantEntitlement: HokEntitlement }>(\n `mutation HokGrantEntitlement($input: HokGrantEntitlementInput!) {\n hokGrantEntitlement(input: $input) {\n id titleId userId mode source status territory expiresAt createdAt updatedAt\n title { id title }\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokGrantEntitlement;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-entitlements'] });\n },\n });\n};\n\n// ============================================================================\n// List updates (self-scoped)\n// ============================================================================\n\nexport interface HokUpdateListInput {\n name?: string;\n description?: string;\n visibility?: HokListVisibility;\n items?: Record<string, unknown>;\n}\n\n/** Rename / re-scope / re-order a list's items; invalidates the caller's lists. */\nexport const useUpdateList = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: HokUpdateListInput }) => {\n const result = await hookmoviesQuery<{ hokUpdateList: HokList }>(\n `mutation HokUpdateList($id: ID!, $input: HokUpdateListInput!) {\n hokUpdateList(id: $id, input: $input) { ${LIST_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.hokUpdateList;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-lists'] });\n },\n });\n};\n\n// ============================================================================\n// Clips (short-form promos / bonus content attached to a title)\n// ============================================================================\n\nexport type HokClipStatus = 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';\n\nexport interface HokClip {\n id: string;\n titleId: string;\n videoFileId: string;\n posterFileId: string | null;\n caption: string | null;\n durationSeconds: number | null;\n language: string | null;\n}\n\nconst CLIP_FIELDS = `\n id titleId videoFileId posterFileId caption durationSeconds language\n`;\n\n/** Clips for a title (optionally filtered by language). */\nexport const useClips = (\n titleId?: string,\n language?: string,\n pagination: HokPaginationInput = { limit: 50, offset: 0 }\n) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'clips', titleId ?? '', language ?? '', pagination],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListClips: HokConnection<HokClip> }>(\n `query HokClips($pagination: PaginationInput, $titleId: ID, $language: String) {\n hokListClips(pagination: $pagination, titleId: $titleId, language: $language) {\n items { ${CLIP_FIELDS} }\n ${PAGE_INFO}\n }\n }`,\n {\n pagination,\n titleId,\n language: language?.trim() ? language.trim() : undefined,\n },\n apiGatewayUrl\n );\n return result.hokListClips;\n },\n enabled: Boolean(titleId),\n });\n};\n\nexport interface HokCreateClipInput {\n titleId: string;\n videoFileId: string;\n posterFileId?: string;\n caption?: string;\n durationSeconds?: number;\n language?: string;\n order?: number;\n}\n\n/** Attach a clip (video file ref) to a title; invalidates that title's clip list. */\nexport const useCreateClip = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async (input: HokCreateClipInput) => {\n const result = await hookmoviesQuery<{ hokCreateClip: HokClip }>(\n `mutation HokCreateClip($input: HokCreateClipInput!) {\n hokCreateClip(input: $input) { ${CLIP_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.hokCreateClip;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'clips', data.titleId] });\n },\n });\n};\n\n/**\n * Delete a clip. `hokDeleteClip` takes only the clip id, so the caller passes\n * the owning `titleId` too — used purely to invalidate the right clip list.\n */\nexport const useDeleteClip = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useHookMovies();\n return useMutation({\n mutationFn: async ({ id }: { id: string; titleId: string }) => {\n const result = await hookmoviesQuery<{ hokDeleteClip: boolean }>(\n `mutation HokDeleteClip($id: ID!) { hokDeleteClip(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.hokDeleteClip;\n },\n onSuccess: (_data, { titleId }) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'clips', titleId] });\n },\n });\n};\n\n// ============================================================================\n// Localizations (subtitle / caption / dub tracks — for player track menus)\n// ============================================================================\n\nexport type HokLocalizationKind = 'SUBTITLE' | 'CAPTION' | 'DUB';\n\nexport interface HokLocalization {\n id: string;\n language: string;\n kind: HokLocalizationKind;\n fileId: string;\n isDefault: boolean;\n}\n\n/**\n * Localization tracks for a title (and optionally a specific episode). Used by\n * the player to build its subtitle / caption / dub track menu.\n */\nexport const useLocalizations = (titleId?: string, episodeId?: string) => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'localizations', titleId ?? '', episodeId ?? ''],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokListLocalizations: HokLocalization[] }>(\n `query HokLocalizations($titleId: ID, $episodeId: ID) {\n hokListLocalizations(titleId: $titleId, episodeId: $episodeId) {\n id language kind fileId isDefault\n }\n }`,\n { titleId, episodeId },\n apiGatewayUrl\n );\n return result.hokListLocalizations;\n },\n enabled: Boolean(titleId) || Boolean(episodeId),\n });\n};\n\n// ============================================================================\n// Health probe (used by the dashboard service-status card)\n// ============================================================================\n\nexport const useHealth = () => {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: [QK, 'health'],\n queryFn: async () => {\n const result = await hookmoviesQuery<{ hokHealth: string }>(\n `query HokHealth { hokHealth }`,\n {},\n apiGatewayUrl\n );\n return result.hokHealth;\n },\n staleTime: 60 * 1000,\n });\n};\n"],"mappings":"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"}
@@ -14,10 +14,10 @@ var O = {
14
14
  limit: 5,
15
15
  offset: 0
16
16
  }, k = {
17
- limit: 50,
17
+ limit: 1,
18
18
  offset: 0
19
19
  }, A = () => {
20
- let { navigateTo: A, currentUser: j } = e(), M = d({}, k), N = c({}, k), P = a({ status: "OPEN" }, k), F = l({}, k), I = u(k), L = s(k), R = d({}, O), z = o(), B = M.data?.items.length ?? 0, V = N.data?.items.length ?? 0, H = P.data?.items.length ?? 0, U = F.data?.items.length ?? 0, W = I.data?.items.length ?? 0, G = L.data?.items.length ?? 0, K = m(() => (z.data ?? []).filter((e) => !e.completed).slice(0, 4), [z.data]), q = [
20
+ let { navigateTo: A, currentUser: j } = e(), M = d({}, k), N = c({}, k), P = a({ status: "OPEN" }, k), F = l({}, k), I = u(k), L = s(k), R = d({}, O), z = o(), B = M.data?.totalCount ?? 0, V = N.data?.totalCount ?? 0, H = P.data?.totalCount ?? 0, U = F.data?.totalCount ?? 0, W = I.data?.totalCount ?? 0, G = L.data?.totalCount ?? 0, K = m(() => (z.data ?? []).filter((e) => !e.completed).slice(0, 4), [z.data]), q = [
21
21
  {
22
22
  id: "catalog",
23
23
  label: "Catalog",
@@ -1 +1 @@
1
- {"version":3,"file":"HomePage.js","names":[],"sources":["../../../src/hookmovies/pages/HomePage.tsx"],"sourcesContent":["/**\n * HookMovies Overview / Dashboard\n * @module hookmovies/pages\n *\n * The MFE's primary landing surface. Summarizes the workspace's catalog,\n * production pipeline, casting activity, and audience engagement using the live\n * HookMovies subgraph (counts derived from the real list ops), plus quick\n * links into each module. No mocks.\n */\n\nimport { type FC, useMemo } from 'react';\nimport {\n Film,\n Clapperboard,\n Megaphone,\n Star,\n Building2,\n Users,\n ScrollText,\n PlayCircle,\n ArrowRight,\n Plus,\n} from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { MetricsCard } from '../components/MetricsCard';\nimport { StatusBadge } from '../components/StatusBadge';\nimport { useHookMovies } from '../context/HookMoviesContext';\nimport {\n useTitles,\n useProductions,\n useAuditions,\n useReviews,\n useStudios,\n usePeople,\n useMyWatchProgress,\n} from '../hooks/useHookMoviesApi';\nimport { cn } from '../utils/cn';\nimport { formatEnumLabel, formatRelativeTime } from '../utils/formatters';\n\nconst SMALL_PAGE = { limit: 5, offset: 0 };\nconst COUNT_PAGE = { limit: 50, offset: 0 };\n\nexport const HomePage: FC = () => {\n const { navigateTo, currentUser } = useHookMovies();\n\n const titles = useTitles({}, COUNT_PAGE);\n const productions = useProductions({}, COUNT_PAGE);\n const openAuditions = useAuditions({ status: 'OPEN' }, COUNT_PAGE);\n const reviews = useReviews({}, COUNT_PAGE);\n const studios = useStudios(COUNT_PAGE);\n const people = usePeople(COUNT_PAGE);\n const recentTitles = useTitles({}, SMALL_PAGE);\n const watchProgress = useMyWatchProgress();\n\n const titleCount = titles.data?.items.length ?? 0;\n const productionCount = productions.data?.items.length ?? 0;\n const auditionCount = openAuditions.data?.items.length ?? 0;\n const reviewCount = reviews.data?.items.length ?? 0;\n const studioCount = studios.data?.items.length ?? 0;\n const personCount = people.data?.items.length ?? 0;\n\n const continueWatching = useMemo(\n () => (watchProgress.data ?? []).filter((p) => !p.completed).slice(0, 4),\n [watchProgress.data]\n );\n\n const modules: Array<{\n id: string;\n label: string;\n description: string;\n icon: typeof Film;\n path: string;\n }> = [\n {\n id: 'catalog',\n label: 'Catalog',\n description: 'Movies, series, anime & more',\n icon: Film,\n path: 'catalog/titles',\n },\n {\n id: 'studios',\n label: 'Studios',\n description: 'Studios, channels & networks',\n icon: Building2,\n path: 'catalog/studios',\n },\n {\n id: 'people',\n label: 'People',\n description: 'Cast & crew directory',\n icon: Users,\n path: 'catalog/people',\n },\n {\n id: 'productions',\n label: 'Productions',\n description: 'Development → release pipeline',\n icon: Clapperboard,\n path: 'productions',\n },\n {\n id: 'auditions',\n label: 'Auditions',\n description: 'Casting & talent marketplace',\n icon: Megaphone,\n path: 'auditions',\n },\n {\n id: 'reviews',\n label: 'Reviews',\n description: 'Ratings & audience reviews',\n icon: Star,\n path: 'engagement/reviews',\n },\n {\n id: 'rights',\n label: 'Rights & Distribution',\n description: 'Licensing windows & territories',\n icon: ScrollText,\n path: 'distribution/rights',\n },\n {\n id: 'library',\n label: 'My Library',\n description: 'Watchlists, playlists & history',\n icon: PlayCircle,\n path: 'library/lists',\n },\n ];\n\n return (\n <PageLayout\n hero\n title=\"HookMovies\"\n description={\n currentUser?.name\n ? `Welcome back, ${currentUser.name}`\n : 'The global creative-media network'\n }\n purpose=\"Discover and stream titles, run productions and casting, and manage rights & distribution — your workspace's whole creative-media operation in one place.\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('catalog/titles/new')}\n className=\"inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 transition-opacity\"\n >\n <Plus className=\"h-4 w-4\" />\n New Title\n </button>\n }\n >\n {/* Key metrics */}\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3 xl:grid-cols-6\">\n <MetricsCard\n featured\n icon={<Film className=\"h-5 w-5\" />}\n value={titleCount}\n label=\"Titles\"\n />\n <MetricsCard\n icon={<Clapperboard className=\"h-5 w-5\" />}\n value={productionCount}\n label=\"Productions\"\n />\n <MetricsCard\n icon={<Megaphone className=\"h-5 w-5\" />}\n value={auditionCount}\n label=\"Open Auditions\"\n />\n <MetricsCard icon={<Star className=\"h-5 w-5\" />} value={reviewCount} label=\"Reviews\" />\n <MetricsCard icon={<Building2 className=\"h-5 w-5\" />} value={studioCount} label=\"Studios\" />\n <MetricsCard icon={<Users className=\"h-5 w-5\" />} value={personCount} label=\"People\" />\n </div>\n\n {/* Continue watching */}\n {continueWatching.length > 0 && (\n <section className=\"mt-8\">\n <h2 className=\"mb-3 text-lg font-semibold text-text-primary\">Continue Watching</h2>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {continueWatching.map((entry) => (\n <button\n key={entry.id}\n type=\"button\"\n onClick={() => entry.title && navigateTo(`catalog/titles/${entry.title.id}`)}\n className=\"text-left\"\n >\n <GlassCard treatment=\"metric\" className=\"h-full border-border-seam p-4\">\n <div className=\"flex items-center gap-2 text-action-primary-bg\">\n <PlayCircle className=\"h-5 w-5\" />\n {entry.title && (\n <span className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {formatEnumLabel(entry.title.type)}\n </span>\n )}\n </div>\n <p className=\"mt-2 line-clamp-1 text-sm font-semibold text-text-primary\">\n {entry.title?.title ?? 'Untitled'}\n </p>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {Math.round(entry.positionSeconds / 60)} min in ·{' '}\n {formatRelativeTime(entry.updatedAt)}\n </p>\n </GlassCard>\n </button>\n ))}\n </div>\n </section>\n )}\n\n {/* Modules */}\n <section className=\"mt-8\">\n <h2 className=\"mb-3 text-lg font-semibold text-text-primary\">Modules</h2>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {modules.map((mod) => {\n const Icon = mod.icon;\n return (\n <button\n key={mod.id}\n type=\"button\"\n onClick={() => navigateTo(mod.path)}\n className=\"group text-left\"\n >\n <GlassCard\n treatment=\"metric\"\n className=\"flex h-full flex-col border-border-seam p-5\"\n >\n <div className=\"flex items-center justify-between\">\n <span className=\"inline-flex h-10 w-10 items-center justify-center rounded-lg bg-bg-sunken text-action-primary-bg\">\n <Icon className=\"h-5 w-5\" />\n </span>\n <ArrowRight className=\"h-4 w-4 text-text-secondary transition-colors group-hover:text-text-primary\" />\n </div>\n <p className=\"mt-3 text-sm font-semibold text-text-primary\">{mod.label}</p>\n <p className=\"mt-1 text-xs text-text-secondary\">{mod.description}</p>\n </GlassCard>\n </button>\n );\n })}\n </div>\n </section>\n\n {/* Recently added titles */}\n <section className=\"mt-8\">\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recently Added</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('catalog/titles')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-action-primary-bg hover:opacity-80\"\n >\n View all\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <ul className=\"divide-y divide-border-seam\">\n {(recentTitles.data?.items ?? []).map((title) => (\n <li key={title.id}>\n <button\n type=\"button\"\n onClick={() => navigateTo(`catalog/titles/${title.id}`)}\n className={cn(\n 'flex w-full items-center justify-between gap-3 px-4 py-3 text-left',\n 'hover:bg-bg-sunken transition-colors'\n )}\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{title.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {formatEnumLabel(title.type)}\n {title.releaseYear ? ` · ${title.releaseYear}` : ''}\n {title.originalLanguage ? ` · ${title.originalLanguage}` : ''}\n </p>\n </div>\n <StatusBadge status={title.status} />\n </button>\n </li>\n ))}\n {recentTitles.data && recentTitles.data.items.length === 0 && (\n <li className=\"px-4 py-6 text-center text-sm text-text-secondary\">\n No titles yet — create your first title to get started.\n </li>\n )}\n </ul>\n </GlassCard>\n </section>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"HomePage.js","names":[],"sources":["../../../src/hookmovies/pages/HomePage.tsx"],"sourcesContent":["/**\n * HookMovies Overview / Dashboard\n * @module hookmovies/pages\n *\n * The MFE's primary landing surface. Summarizes the workspace's catalog,\n * production pipeline, casting activity, and audience engagement using the live\n * HookMovies subgraph (counts derived from the real list ops), plus quick\n * links into each module. No mocks.\n */\n\nimport { type FC, useMemo } from 'react';\nimport {\n Film,\n Clapperboard,\n Megaphone,\n Star,\n Building2,\n Users,\n ScrollText,\n PlayCircle,\n ArrowRight,\n Plus,\n} from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { MetricsCard } from '../components/MetricsCard';\nimport { StatusBadge } from '../components/StatusBadge';\nimport { useHookMovies } from '../context/HookMoviesContext';\nimport {\n useTitles,\n useProductions,\n useAuditions,\n useReviews,\n useStudios,\n usePeople,\n useMyWatchProgress,\n} from '../hooks/useHookMoviesApi';\nimport { cn } from '../utils/cn';\nimport { formatEnumLabel, formatRelativeTime } from '../utils/formatters';\n\nconst SMALL_PAGE = { limit: 5, offset: 0 };\n// Count-only queries: we read `totalCount` off the connection, so fetch a\n// minimal page of rows (the items are discarded here).\nconst COUNT_PAGE = { limit: 1, offset: 0 };\n\nexport const HomePage: FC = () => {\n const { navigateTo, currentUser } = useHookMovies();\n\n const titles = useTitles({}, COUNT_PAGE);\n const productions = useProductions({}, COUNT_PAGE);\n const openAuditions = useAuditions({ status: 'OPEN' }, COUNT_PAGE);\n const reviews = useReviews({}, COUNT_PAGE);\n const studios = useStudios(COUNT_PAGE);\n const people = usePeople(COUNT_PAGE);\n const recentTitles = useTitles({}, SMALL_PAGE);\n const watchProgress = useMyWatchProgress();\n\n const titleCount = titles.data?.totalCount ?? 0;\n const productionCount = productions.data?.totalCount ?? 0;\n const auditionCount = openAuditions.data?.totalCount ?? 0;\n const reviewCount = reviews.data?.totalCount ?? 0;\n const studioCount = studios.data?.totalCount ?? 0;\n const personCount = people.data?.totalCount ?? 0;\n\n const continueWatching = useMemo(\n () => (watchProgress.data ?? []).filter((p) => !p.completed).slice(0, 4),\n [watchProgress.data]\n );\n\n const modules: Array<{\n id: string;\n label: string;\n description: string;\n icon: typeof Film;\n path: string;\n }> = [\n {\n id: 'catalog',\n label: 'Catalog',\n description: 'Movies, series, anime & more',\n icon: Film,\n path: 'catalog/titles',\n },\n {\n id: 'studios',\n label: 'Studios',\n description: 'Studios, channels & networks',\n icon: Building2,\n path: 'catalog/studios',\n },\n {\n id: 'people',\n label: 'People',\n description: 'Cast & crew directory',\n icon: Users,\n path: 'catalog/people',\n },\n {\n id: 'productions',\n label: 'Productions',\n description: 'Development → release pipeline',\n icon: Clapperboard,\n path: 'productions',\n },\n {\n id: 'auditions',\n label: 'Auditions',\n description: 'Casting & talent marketplace',\n icon: Megaphone,\n path: 'auditions',\n },\n {\n id: 'reviews',\n label: 'Reviews',\n description: 'Ratings & audience reviews',\n icon: Star,\n path: 'engagement/reviews',\n },\n {\n id: 'rights',\n label: 'Rights & Distribution',\n description: 'Licensing windows & territories',\n icon: ScrollText,\n path: 'distribution/rights',\n },\n {\n id: 'library',\n label: 'My Library',\n description: 'Watchlists, playlists & history',\n icon: PlayCircle,\n path: 'library/lists',\n },\n ];\n\n return (\n <PageLayout\n hero\n title=\"HookMovies\"\n description={\n currentUser?.name\n ? `Welcome back, ${currentUser.name}`\n : 'The global creative-media network'\n }\n purpose=\"Discover and stream titles, run productions and casting, and manage rights & distribution — your workspace's whole creative-media operation in one place.\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('catalog/titles/new')}\n className=\"inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 transition-opacity\"\n >\n <Plus className=\"h-4 w-4\" />\n New Title\n </button>\n }\n >\n {/* Key metrics */}\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3 xl:grid-cols-6\">\n <MetricsCard\n featured\n icon={<Film className=\"h-5 w-5\" />}\n value={titleCount}\n label=\"Titles\"\n />\n <MetricsCard\n icon={<Clapperboard className=\"h-5 w-5\" />}\n value={productionCount}\n label=\"Productions\"\n />\n <MetricsCard\n icon={<Megaphone className=\"h-5 w-5\" />}\n value={auditionCount}\n label=\"Open Auditions\"\n />\n <MetricsCard icon={<Star className=\"h-5 w-5\" />} value={reviewCount} label=\"Reviews\" />\n <MetricsCard icon={<Building2 className=\"h-5 w-5\" />} value={studioCount} label=\"Studios\" />\n <MetricsCard icon={<Users className=\"h-5 w-5\" />} value={personCount} label=\"People\" />\n </div>\n\n {/* Continue watching */}\n {continueWatching.length > 0 && (\n <section className=\"mt-8\">\n <h2 className=\"mb-3 text-lg font-semibold text-text-primary\">Continue Watching</h2>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {continueWatching.map((entry) => (\n <button\n key={entry.id}\n type=\"button\"\n onClick={() => entry.title && navigateTo(`catalog/titles/${entry.title.id}`)}\n className=\"text-left\"\n >\n <GlassCard treatment=\"metric\" className=\"h-full border-border-seam p-4\">\n <div className=\"flex items-center gap-2 text-action-primary-bg\">\n <PlayCircle className=\"h-5 w-5\" />\n {entry.title && (\n <span className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {formatEnumLabel(entry.title.type)}\n </span>\n )}\n </div>\n <p className=\"mt-2 line-clamp-1 text-sm font-semibold text-text-primary\">\n {entry.title?.title ?? 'Untitled'}\n </p>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {Math.round(entry.positionSeconds / 60)} min in ·{' '}\n {formatRelativeTime(entry.updatedAt)}\n </p>\n </GlassCard>\n </button>\n ))}\n </div>\n </section>\n )}\n\n {/* Modules */}\n <section className=\"mt-8\">\n <h2 className=\"mb-3 text-lg font-semibold text-text-primary\">Modules</h2>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {modules.map((mod) => {\n const Icon = mod.icon;\n return (\n <button\n key={mod.id}\n type=\"button\"\n onClick={() => navigateTo(mod.path)}\n className=\"group text-left\"\n >\n <GlassCard\n treatment=\"metric\"\n className=\"flex h-full flex-col border-border-seam p-5\"\n >\n <div className=\"flex items-center justify-between\">\n <span className=\"inline-flex h-10 w-10 items-center justify-center rounded-lg bg-bg-sunken text-action-primary-bg\">\n <Icon className=\"h-5 w-5\" />\n </span>\n <ArrowRight className=\"h-4 w-4 text-text-secondary transition-colors group-hover:text-text-primary\" />\n </div>\n <p className=\"mt-3 text-sm font-semibold text-text-primary\">{mod.label}</p>\n <p className=\"mt-1 text-xs text-text-secondary\">{mod.description}</p>\n </GlassCard>\n </button>\n );\n })}\n </div>\n </section>\n\n {/* Recently added titles */}\n <section className=\"mt-8\">\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recently Added</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('catalog/titles')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-action-primary-bg hover:opacity-80\"\n >\n View all\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <ul className=\"divide-y divide-border-seam\">\n {(recentTitles.data?.items ?? []).map((title) => (\n <li key={title.id}>\n <button\n type=\"button\"\n onClick={() => navigateTo(`catalog/titles/${title.id}`)}\n className={cn(\n 'flex w-full items-center justify-between gap-3 px-4 py-3 text-left',\n 'hover:bg-bg-sunken transition-colors'\n )}\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{title.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {formatEnumLabel(title.type)}\n {title.releaseYear ? ` · ${title.releaseYear}` : ''}\n {title.originalLanguage ? ` · ${title.originalLanguage}` : ''}\n </p>\n </div>\n <StatusBadge status={title.status} />\n </button>\n </li>\n ))}\n {recentTitles.data && recentTitles.data.items.length === 0 && (\n <li className=\"px-4 py-6 text-center text-sm text-text-secondary\">\n No titles yet — create your first title to get started.\n </li>\n )}\n </ul>\n </GlassCard>\n </section>\n </PageLayout>\n );\n};\n"],"mappings":"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"}