@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":"EntitlementsPage.js","names":[],"sources":["../../../../src/hookmovies/pages/library/EntitlementsPage.tsx"],"sourcesContent":["/**\n * My Entitlements (Library — self-scoped)\n * @module hookmovies/pages/library\n *\n * The caller's own watch entitlements via `hokMyEntitlements` (self-scoped to\n * the user). Active entitlements can be revoked with `hokRevokeEntitlement`.\n */\n\nimport { type FC } from 'react';\nimport { Ticket, PlayCircle, XCircle } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingState, ErrorState } from '../../components/StateViews';\nimport { useHookMovies } from '../../context/HookMoviesContext';\nimport { useMyEntitlements, useRevokeEntitlement } from '../../hooks/useHookMoviesApi';\nimport { formatDate, formatEnumLabel } from '../../utils/formatters';\n\nexport const EntitlementsPage: FC = () => {\n const { navigateTo } = useHookMovies();\n const { data, isLoading, isError, refetch } = useMyEntitlements();\n const revoke = useRevokeEntitlement();\n\n const items = data ?? [];\n\n return (\n <PageLayout\n title=\"My Entitlements\"\n description=\"What you can watch right now\"\n purpose=\"Your computed right to watch each title — from subscriptions, purchases, rentals, or promos. Entitlements derive from plan and rights windows.\"\n >\n {isLoading ? (\n <LoadingState label=\"Loading entitlements…\" />\n ) : isError ? (\n <ErrorState onRetry={() => void refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<Ticket className=\"h-12 w-12\" />}\n title=\"No entitlements yet\"\n description=\"You don't have any active watch rights. Browse the catalog to find something to watch.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('catalog/titles')}\n className=\"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 Browse Catalog\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {items.map((ent) => (\n <GlassCard\n key={ent.id}\n treatment=\"metric\"\n className=\"flex flex-col border-border-seam p-4\"\n >\n <div className=\"flex items-start justify-between gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo(`catalog/titles/${ent.titleId}`)}\n className=\"line-clamp-2 text-left text-sm font-semibold text-text-primary hover:text-action-primary-bg transition-colors\"\n >\n {ent.title?.title ?? 'Title'}\n </button>\n <StatusBadge status={ent.status} />\n </div>\n <div className=\"mt-2 flex flex-wrap items-center gap-1.5 text-xs text-text-secondary\">\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5\">\n {formatEnumLabel(ent.mode)}\n </span>\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5\">\n {formatEnumLabel(ent.source)}\n </span>\n {ent.territory && (\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5\">{ent.territory}</span>\n )}\n </div>\n {ent.expiresAt && (\n <p className=\"mt-2 text-xs text-text-secondary\">\n Expires {formatDate(ent.expiresAt, { hour: undefined, minute: undefined })}\n </p>\n )}\n <div className=\"mt-auto flex items-center gap-2 pt-3\">\n <button\n type=\"button\"\n onClick={() => navigateTo(`catalog/titles/${ent.titleId}`)}\n className=\"inline-flex flex-1 items-center justify-center gap-1 rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text hover:opacity-90 transition-opacity\"\n >\n <PlayCircle className=\"h-3.5 w-3.5\" />\n Watch\n </button>\n {ent.status === 'ACTIVE' && (\n <button\n type=\"button\"\n disabled={revoke.isPending}\n onClick={() => void revoke.mutateAsync(ent.id)}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-seam px-3 py-1.5 text-xs font-medium text-text-secondary hover:text-status-error-text disabled:opacity-50 transition-colors\"\n >\n <XCircle className=\"h-3.5 w-3.5\" />\n Revoke\n </button>\n )}\n </div>\n </GlassCard>\n ))}\n </div>\n )}\n </PageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;AAmBA,IAAa,UAA6B;CACxC,IAAM,EAAE,kBAAe,GAAe,EAChC,EAAE,SAAM,cAAW,YAAS,eAAY,GAAmB,EAC3D,IAAS,GAAsB,EAE/B,IAAQ,KAAQ,EAAE;AAExB,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAQ;YAEP,IACC,kBAAC,GAAD,EAAc,OAAM,yBAA0B,CAAA,GAC5C,IACF,kBAAC,GAAD,EAAY,eAAe,KAAK,GAAS,EAAI,CAAA,GAC3C,EAAM,WAAW,IACnB,kBAAC,GAAD;GACE,MAAM,kBAAC,GAAD,EAAQ,WAAU,aAAc,CAAA;GACtC,OAAM;GACN,aAAY;GACZ,QACE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAW,iBAAiB;IAC3C,WAAU;cACX;IAEQ,CAAA;GAEX,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAM,KAAK,MACV,kBAAC,GAAD;IAEE,WAAU;IACV,WAAU;cAHZ;KAKE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAW,kBAAkB,EAAI,UAAU;OAC1D,WAAU;iBAET,EAAI,OAAO,SAAS;OACd,CAAA,EACT,kBAAC,GAAD,EAAa,QAAQ,EAAI,QAAU,CAAA,CAC/B;;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAgB,EAAI,KAAK;QACrB,CAAA;OACP,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAgB,EAAI,OAAO;QACvB,CAAA;OACN,EAAI,aACH,kBAAC,QAAD;QAAM,WAAU;kBAAyC,EAAI;QAAiB,CAAA;OAE5E;;KACL,EAAI,aACH,kBAAC,KAAD;MAAG,WAAU;gBAAb,CAAgD,YACrC,EAAW,EAAI,WAAW;OAAE,MAAM,KAAA;OAAW,QAAQ,KAAA;OAAW,CAAC,CACxE;;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAW,kBAAkB,EAAI,UAAU;OAC1D,WAAU;iBAHZ,CAKE,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA,EAAA,QAE/B;UACR,EAAI,WAAW,YACd,kBAAC,UAAD;OACE,MAAK;OACL,UAAU,EAAO;OACjB,eAAe,KAAK,EAAO,YAAY,EAAI,GAAG;OAC9C,WAAU;iBAJZ,CAME,kBAAC,GAAD,EAAS,WAAU,eAAgB,CAAA,EAAA,SAE5B;SAEP;;KACI;MAnDL,EAAI,GAmDC,CACZ;GACE,CAAA;EAEG,CAAA"}
1
+ {"version":3,"file":"EntitlementsPage.js","names":[],"sources":["../../../../src/hookmovies/pages/library/EntitlementsPage.tsx"],"sourcesContent":["/**\n * My Entitlements (Library — self-scoped)\n * @module hookmovies/pages/library\n *\n * The caller's own watch entitlements via `hokMyEntitlements` (self-scoped to\n * the user). Active entitlements can be revoked with `hokRevokeEntitlement`, and\n * new entitlements granted (to self or another user) with `hokGrantEntitlement`.\n */\n\nimport { type FC, type FormEvent, useState } from 'react';\nimport { Ticket, PlayCircle, XCircle, Plus, X } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingState, ErrorState } from '../../components/StateViews';\nimport { useHookMovies } from '../../context/HookMoviesContext';\nimport {\n useMyEntitlements,\n useRevokeEntitlement,\n useGrantEntitlement,\n useTitles,\n type HokMonetizationMode,\n type HokEntitlementSource,\n type HokGrantEntitlementInput,\n} from '../../hooks/useHookMoviesApi';\nimport { formatDate, formatEnumLabel } from '../../utils/formatters';\n\nconst MODE_OPTIONS: HokMonetizationMode[] = [\n 'FREE_AVOD',\n 'SVOD',\n 'TVOD_RENT',\n 'TVOD_BUY',\n 'PPV',\n 'FAST',\n];\n\nconst SOURCE_OPTIONS: HokEntitlementSource[] = [\n 'SUBSCRIPTION',\n 'PURCHASE',\n 'RENTAL',\n 'PROMO',\n 'FREE',\n];\n\nconst fieldClass =\n 'w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\nconst labelClass = 'mb-1.5 block text-xs font-medium text-text-secondary';\n\nexport const EntitlementsPage: FC = () => {\n const { navigateTo, currentUser } = useHookMovies();\n const { data, isLoading, isError, refetch } = useMyEntitlements();\n const revoke = useRevokeEntitlement();\n const grant = useGrantEntitlement();\n\n const [showGrant, setShowGrant] = useState(false);\n const [titleSearch, setTitleSearch] = useState('');\n const titles = useTitles({}, { limit: 200, offset: 0 }, titleSearch);\n\n const [titleId, setTitleId] = useState('');\n const [userId, setUserId] = useState(currentUser?.id ?? '');\n const [mode, setMode] = useState<HokMonetizationMode>('SVOD');\n const [source, setSource] = useState<HokEntitlementSource>('SUBSCRIPTION');\n const [territory, setTerritory] = useState('');\n const [expiresAt, setExpiresAt] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n\n const items = data ?? [];\n\n const resetForm = () => {\n setTitleId('');\n setUserId(currentUser?.id ?? '');\n setMode('SVOD');\n setSource('SUBSCRIPTION');\n setTerritory('');\n setExpiresAt('');\n setTitleSearch('');\n setError(null);\n };\n\n const handleGrant = async (e: FormEvent) => {\n e.preventDefault();\n setError(null);\n if (!titleId) {\n setError('Select a title.');\n return;\n }\n if (!userId.trim()) {\n setError('A user id is required.');\n return;\n }\n const input: HokGrantEntitlementInput = {\n titleId,\n userId: userId.trim(),\n mode,\n source,\n territory: territory.trim() ? territory.trim().toUpperCase() : undefined,\n expiresAt: expiresAt ? new Date(expiresAt).toISOString() : undefined,\n };\n try {\n await grant.mutateAsync(input);\n resetForm();\n setShowGrant(false);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to grant entitlement');\n }\n };\n\n const handleRevoke = async (id: string) => {\n setActionError(null);\n try {\n await revoke.mutateAsync(id);\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to revoke entitlement');\n }\n };\n\n return (\n <PageLayout\n title=\"My Entitlements\"\n description=\"What you can watch right now\"\n purpose=\"Your computed right to watch each title — from subscriptions, purchases, rentals, or promos. Entitlements derive from plan and rights windows.\"\n actions={\n <button\n type=\"button\"\n onClick={() => setShowGrant((v) => !v)}\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 Grant Entitlement\n </button>\n }\n >\n {actionError && (\n <div className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {actionError}\n </div>\n )}\n\n {showGrant && (\n <GlassCard treatment=\"glass\" className=\"mb-6 border-border-seam p-5\">\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-sm font-semibold text-text-primary\">Grant Entitlement</h2>\n <button\n type=\"button\"\n onClick={() => setShowGrant(false)}\n aria-label=\"Close grant form\"\n className=\"rounded-md p-1 text-text-secondary hover:text-text-primary\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n <form onSubmit={handleGrant} className=\"space-y-4\">\n {error && (\n <div className=\"rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {error}\n </div>\n )}\n\n <div>\n <label htmlFor=\"grant-title-search\" className={labelClass}>\n Search titles\n </label>\n <input\n id=\"grant-title-search\"\n type=\"text\"\n value={titleSearch}\n onChange={(e) => setTitleSearch(e.target.value)}\n placeholder=\"Filter titles by name…\"\n className={fieldClass}\n />\n </div>\n\n <div>\n <label htmlFor=\"grant-title\" className={labelClass}>\n Title *\n </label>\n <select\n id=\"grant-title\"\n value={titleId}\n onChange={(e) => setTitleId(e.target.value)}\n className={fieldClass}\n required\n >\n <option value=\"\">{titles.isLoading ? 'Loading titles…' : 'Select a title…'}</option>\n {(titles.data?.items ?? []).map((t) => (\n <option key={t.id} value={t.id}>\n {t.title}\n </option>\n ))}\n </select>\n </div>\n\n <div>\n <label htmlFor=\"grant-user\" className={labelClass}>\n User ID *\n </label>\n <input\n id=\"grant-user\"\n type=\"text\"\n value={userId}\n onChange={(e) => setUserId(e.target.value)}\n placeholder=\"User id to grant access to\"\n className={fieldClass}\n required\n />\n <p className=\"mt-1 text-[11px] text-text-secondary\">\n Defaults to your own id. Change it to grant access to another user.\n </p>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"grant-mode\" className={labelClass}>\n Monetization Mode *\n </label>\n <select\n id=\"grant-mode\"\n value={mode}\n onChange={(e) => setMode(e.target.value as HokMonetizationMode)}\n className={fieldClass}\n required\n >\n {MODE_OPTIONS.map((m) => (\n <option key={m} value={m}>\n {formatEnumLabel(m)}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"grant-source\" className={labelClass}>\n Source\n </label>\n <select\n id=\"grant-source\"\n value={source}\n onChange={(e) => setSource(e.target.value as HokEntitlementSource)}\n className={fieldClass}\n >\n {SOURCE_OPTIONS.map((s) => (\n <option key={s} value={s}>\n {formatEnumLabel(s)}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"grant-territory\" className={labelClass}>\n Territory (ISO code, optional)\n </label>\n <input\n id=\"grant-territory\"\n type=\"text\"\n value={territory}\n onChange={(e) => setTerritory(e.target.value)}\n placeholder=\"US\"\n className={fieldClass}\n />\n </div>\n <div>\n <label htmlFor=\"grant-expires\" className={labelClass}>\n Expires At (optional)\n </label>\n <input\n id=\"grant-expires\"\n type=\"date\"\n value={expiresAt}\n onChange={(e) => setExpiresAt(e.target.value)}\n className={fieldClass}\n />\n </div>\n </div>\n\n <button\n type=\"submit\"\n disabled={grant.isPending}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n {grant.isPending ? 'Granting…' : 'Grant Entitlement'}\n </button>\n </form>\n </GlassCard>\n )}\n\n {isLoading ? (\n <LoadingState label=\"Loading entitlements…\" />\n ) : isError ? (\n <ErrorState onRetry={() => void refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<Ticket className=\"h-12 w-12\" />}\n title=\"No entitlements yet\"\n description=\"You don't have any active watch rights. Grant an entitlement above, or browse the catalog to find something to watch.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('catalog/titles')}\n className=\"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 Browse Catalog\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {items.map((ent) => (\n <GlassCard\n key={ent.id}\n treatment=\"metric\"\n className=\"flex flex-col border-border-seam p-4\"\n >\n <div className=\"flex items-start justify-between gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo(`catalog/titles/${ent.titleId}`)}\n className=\"line-clamp-2 text-left text-sm font-semibold text-text-primary hover:text-action-primary-bg transition-colors\"\n >\n {ent.title?.title ?? 'Title'}\n </button>\n <StatusBadge status={ent.status} />\n </div>\n <div className=\"mt-2 flex flex-wrap items-center gap-1.5 text-xs text-text-secondary\">\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5\">\n {formatEnumLabel(ent.mode)}\n </span>\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5\">\n {formatEnumLabel(ent.source)}\n </span>\n {ent.territory && (\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5\">{ent.territory}</span>\n )}\n </div>\n {ent.expiresAt && (\n <p className=\"mt-2 text-xs text-text-secondary\">\n Expires {formatDate(ent.expiresAt, { hour: undefined, minute: undefined })}\n </p>\n )}\n <div className=\"mt-auto flex items-center gap-2 pt-3\">\n <button\n type=\"button\"\n onClick={() => navigateTo(`catalog/titles/${ent.titleId}`)}\n className=\"inline-flex flex-1 items-center justify-center gap-1 rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text hover:opacity-90 transition-opacity\"\n >\n <PlayCircle className=\"h-3.5 w-3.5\" />\n Watch\n </button>\n {ent.status === 'ACTIVE' && (\n <button\n type=\"button\"\n disabled={revoke.isPending}\n onClick={() => void handleRevoke(ent.id)}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-seam px-3 py-1.5 text-xs font-medium text-text-secondary hover:text-status-error-text disabled:opacity-50 transition-colors\"\n >\n <XCircle className=\"h-3.5 w-3.5\" />\n Revoke\n </button>\n )}\n </div>\n </GlassCard>\n ))}\n </div>\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -1,213 +1,293 @@
1
1
  import { PageLayout as e } from "../../components/PageLayout.js";
2
- import { useCreateList as t, useDeleteList as n, useMyLists as r } from "../../hooks/useHookMoviesApi.js";
3
- import { formatRelativeTime as i } from "../../utils/formatters.js";
4
- import { ErrorState as a, LoadingState as o } from "../../components/StateViews.js";
5
- import { EmptyState as s } from "../../components/EmptyState.js";
6
- import { useState as c } from "react";
7
- import { Globe as l, Link as u, ListVideo as d, Lock as f, Plus as p, Trash2 as m, X as h } from "lucide-react";
8
- import { jsx as g, jsxs as _ } from "react/jsx-runtime";
9
- import { GlassCard as v } from "@burdenoff/fe-libs/ui";
2
+ import { useCreateList as t, useDeleteList as n, useMyLists as r, useUpdateList as i } from "../../hooks/useHookMoviesApi.js";
3
+ import { formatRelativeTime as a } from "../../utils/formatters.js";
4
+ import { ErrorState as o, LoadingState as s } from "../../components/StateViews.js";
5
+ import { EmptyState as c } from "../../components/EmptyState.js";
6
+ import { useState as l } from "react";
7
+ import { Globe as u, Link as d, ListVideo as ee, Lock as f, Pencil as p, Plus as m, Trash2 as h, X as te } from "lucide-react";
8
+ import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
9
+ import { GlassCard as y } from "@burdenoff/fe-libs/ui";
10
10
  //#region src/hookmovies/pages/library/ListsPage.tsx
11
- var y = ["WATCHLIST", "PLAYLIST"], b = [
11
+ var b = ["WATCHLIST", "PLAYLIST"], x = [
12
12
  "PRIVATE",
13
13
  "UNLISTED",
14
14
  "PUBLIC"
15
- ], x = "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]", S = "mb-1.5 block text-xs font-medium text-text-secondary", C = {
15
+ ], S = "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]", C = "mb-1.5 block text-xs font-medium text-text-secondary", w = {
16
16
  PRIVATE: f,
17
- UNLISTED: u,
18
- PUBLIC: l
19
- }, w = () => {
20
- let [l, u] = c(""), [f, w] = c(!1), { data: T, isLoading: E, isError: D, refetch: O } = r(l || void 0, {
17
+ UNLISTED: d,
18
+ PUBLIC: u
19
+ }, T = () => {
20
+ let [u, d] = l(""), [f, T] = l(!1), { data: E, isLoading: D, isError: O, refetch: k } = r(u || void 0, {
21
21
  limit: 100,
22
22
  offset: 0
23
- }), k = t(), A = n(), [j, M] = c(""), [N, P] = c(""), [F, I] = c("WATCHLIST"), [L, R] = c("PRIVATE"), [z, B] = c(null), [V, H] = c(null), U = async (e) => {
24
- H(null);
23
+ }), A = t(), j = n(), M = i(), [N, P] = l(""), [F, I] = l(""), [L, R] = l("WATCHLIST"), [z, B] = l("PRIVATE"), [V, H] = l(null), [U, W] = l(null), [G, K] = l(null), [q, J] = l(""), [Y, X] = l("PRIVATE"), [Z, Q] = l(null), ne = (e) => {
24
+ Q(null), K(e.id), J(e.name), X(e.visibility);
25
+ }, re = () => {
26
+ K(null), Q(null);
27
+ }, ie = async (e, t) => {
28
+ if (e.preventDefault(), Q(null), !q.trim()) {
29
+ Q("Name is required.");
30
+ return;
31
+ }
32
+ try {
33
+ await M.mutateAsync({
34
+ id: t,
35
+ input: {
36
+ name: q.trim(),
37
+ visibility: Y
38
+ }
39
+ }), K(null);
40
+ } catch (e) {
41
+ Q(e instanceof Error ? e.message : "Failed to update list (you can only edit your own)");
42
+ }
43
+ }, ae = async (e) => {
44
+ W(null);
25
45
  try {
26
- await A.mutateAsync(e);
46
+ await j.mutateAsync(e);
27
47
  } catch (e) {
28
- H(e instanceof Error ? e.message : "Failed to delete list (you can only delete your own)");
48
+ W(e instanceof Error ? e.message : "Failed to delete list (you can only delete your own)");
29
49
  }
30
- }, W = async (e) => {
31
- if (e.preventDefault(), B(null), !j.trim()) {
32
- B("Name is required.");
50
+ }, oe = async (e) => {
51
+ if (e.preventDefault(), H(null), !N.trim()) {
52
+ H("Name is required.");
33
53
  return;
34
54
  }
35
55
  let t = {
36
- name: j.trim(),
37
- description: N.trim() || void 0,
38
- kind: F,
39
- visibility: L
56
+ name: N.trim(),
57
+ description: F.trim() || void 0,
58
+ kind: L,
59
+ visibility: z
40
60
  };
41
61
  try {
42
- await k.mutateAsync(t), M(""), P(""), I("WATCHLIST"), R("PRIVATE"), w(!1);
62
+ await A.mutateAsync(t), P(""), I(""), R("WATCHLIST"), B("PRIVATE"), T(!1);
43
63
  } catch (e) {
44
- B(e instanceof Error ? e.message : "Failed to create list");
64
+ H(e instanceof Error ? e.message : "Failed to create list");
45
65
  }
46
- }, G = T?.items ?? [];
47
- return /* @__PURE__ */ _(e, {
66
+ }, $ = E?.items ?? [];
67
+ return /* @__PURE__ */ v(e, {
48
68
  title: "My Library",
49
69
  description: "Watchlists & playlists",
50
70
  purpose: "Your personal collections — a watchlist of what to watch next and curated playlists you can keep private, unlisted, or public.",
51
- actions: /* @__PURE__ */ _("button", {
71
+ actions: /* @__PURE__ */ v("button", {
52
72
  type: "button",
53
- onClick: () => w((e) => !e),
73
+ onClick: () => T((e) => !e),
54
74
  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",
55
- children: [/* @__PURE__ */ g(p, { className: "h-4 w-4" }), "New List"]
75
+ children: [/* @__PURE__ */ _(m, { className: "h-4 w-4" }), "New List"]
56
76
  }),
57
77
  children: [
58
- f && /* @__PURE__ */ _(v, {
78
+ f && /* @__PURE__ */ v(y, {
59
79
  treatment: "glass",
60
80
  className: "mb-6 border-border-seam p-5",
61
- children: [/* @__PURE__ */ _("div", {
81
+ children: [/* @__PURE__ */ v("div", {
62
82
  className: "mb-3 flex items-center justify-between",
63
- children: [/* @__PURE__ */ g("h2", {
83
+ children: [/* @__PURE__ */ _("h2", {
64
84
  className: "text-sm font-semibold text-text-primary",
65
85
  children: "Create List"
66
- }), /* @__PURE__ */ g("button", {
86
+ }), /* @__PURE__ */ _("button", {
67
87
  type: "button",
68
- onClick: () => w(!1),
88
+ onClick: () => T(!1),
69
89
  className: "rounded-md p-1 text-text-secondary hover:text-text-primary",
70
- children: /* @__PURE__ */ g(h, { className: "h-4 w-4" })
90
+ children: /* @__PURE__ */ _(te, { className: "h-4 w-4" })
71
91
  })]
72
- }), /* @__PURE__ */ _("form", {
73
- onSubmit: W,
92
+ }), /* @__PURE__ */ v("form", {
93
+ onSubmit: oe,
74
94
  className: "space-y-4",
75
95
  children: [
76
- z && /* @__PURE__ */ g("div", {
96
+ V && /* @__PURE__ */ _("div", {
77
97
  className: "rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
78
- children: z
98
+ children: V
79
99
  }),
80
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
100
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
81
101
  htmlFor: "list-name",
82
- className: S,
102
+ className: C,
83
103
  children: "Name *"
84
- }), /* @__PURE__ */ g("input", {
104
+ }), /* @__PURE__ */ _("input", {
85
105
  id: "list-name",
86
106
  type: "text",
87
- value: j,
88
- onChange: (e) => M(e.target.value),
107
+ value: N,
108
+ onChange: (e) => P(e.target.value),
89
109
  placeholder: "e.g. Weekend Watch",
90
- className: x,
110
+ className: S,
91
111
  required: !0
92
112
  })] }),
93
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
113
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
94
114
  htmlFor: "list-desc",
95
- className: S,
115
+ className: C,
96
116
  children: "Description"
97
- }), /* @__PURE__ */ g("textarea", {
117
+ }), /* @__PURE__ */ _("textarea", {
98
118
  id: "list-desc",
99
- value: N,
100
- onChange: (e) => P(e.target.value),
119
+ value: F,
120
+ onChange: (e) => I(e.target.value),
101
121
  rows: 2,
102
- className: x
122
+ className: S
103
123
  })] }),
104
- /* @__PURE__ */ _("div", {
124
+ /* @__PURE__ */ v("div", {
105
125
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
106
- children: [/* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
126
+ children: [/* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
107
127
  htmlFor: "list-kind",
108
- className: S,
128
+ className: C,
109
129
  children: "Kind"
110
- }), /* @__PURE__ */ g("select", {
130
+ }), /* @__PURE__ */ _("select", {
111
131
  id: "list-kind",
112
- value: F,
113
- onChange: (e) => I(e.target.value),
114
- className: x,
115
- children: y.map((e) => /* @__PURE__ */ g("option", {
132
+ value: L,
133
+ onChange: (e) => R(e.target.value),
134
+ className: S,
135
+ children: b.map((e) => /* @__PURE__ */ _("option", {
116
136
  value: e,
117
137
  children: e.charAt(0) + e.slice(1).toLowerCase()
118
138
  }, e))
119
- })] }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
139
+ })] }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
120
140
  htmlFor: "list-visibility",
121
- className: S,
141
+ className: C,
122
142
  children: "Visibility"
123
- }), /* @__PURE__ */ g("select", {
143
+ }), /* @__PURE__ */ _("select", {
124
144
  id: "list-visibility",
125
- value: L,
126
- onChange: (e) => R(e.target.value),
127
- className: x,
128
- children: b.map((e) => /* @__PURE__ */ g("option", {
145
+ value: z,
146
+ onChange: (e) => B(e.target.value),
147
+ className: S,
148
+ children: x.map((e) => /* @__PURE__ */ _("option", {
129
149
  value: e,
130
150
  children: e.charAt(0) + e.slice(1).toLowerCase()
131
151
  }, e))
132
152
  })] })]
133
153
  }),
134
- /* @__PURE__ */ g("button", {
154
+ /* @__PURE__ */ _("button", {
135
155
  type: "submit",
136
- disabled: k.isPending,
156
+ disabled: A.isPending,
137
157
  className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 transition-opacity",
138
- children: k.isPending ? "Creating…" : "Create List"
158
+ children: A.isPending ? "Creating…" : "Create List"
139
159
  })
140
160
  ]
141
161
  })]
142
162
  }),
143
- /* @__PURE__ */ g("div", {
163
+ /* @__PURE__ */ _("div", {
144
164
  className: "mb-4 flex flex-wrap items-center gap-3",
145
- children: /* @__PURE__ */ _("select", {
146
- value: l,
147
- onChange: (e) => u(e.target.value),
165
+ children: /* @__PURE__ */ v("select", {
166
+ value: u,
167
+ onChange: (e) => d(e.target.value),
148
168
  className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
149
- children: [/* @__PURE__ */ g("option", {
169
+ children: [/* @__PURE__ */ _("option", {
150
170
  value: "",
151
171
  children: "All Lists"
152
- }), y.map((e) => /* @__PURE__ */ g("option", {
172
+ }), b.map((e) => /* @__PURE__ */ _("option", {
153
173
  value: e,
154
174
  children: e.charAt(0) + e.slice(1).toLowerCase()
155
175
  }, e))]
156
176
  })
157
177
  }),
158
- V && /* @__PURE__ */ g("div", {
178
+ U && /* @__PURE__ */ _("div", {
159
179
  className: "mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text",
160
- children: V
180
+ children: U
161
181
  }),
162
- E ? /* @__PURE__ */ g(o, { label: "Loading your lists…" }) : D ? /* @__PURE__ */ g(a, { onRetry: () => void O() }) : G.length === 0 ? /* @__PURE__ */ g(s, {
163
- icon: /* @__PURE__ */ g(d, { className: "h-12 w-12" }),
182
+ D ? /* @__PURE__ */ _(s, { label: "Loading your lists…" }) : O ? /* @__PURE__ */ _(o, { onRetry: () => void k() }) : $.length === 0 ? /* @__PURE__ */ _(c, {
183
+ icon: /* @__PURE__ */ _(ee, { className: "h-12 w-12" }),
164
184
  title: "No lists yet",
165
185
  description: "Create a watchlist or playlist to organize what you watch."
166
- }) : /* @__PURE__ */ g("div", {
186
+ }) : /* @__PURE__ */ _("div", {
167
187
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
168
- children: G.map((e) => {
169
- let t = C[e.visibility];
170
- return /* @__PURE__ */ _(v, {
188
+ children: $.map((e) => {
189
+ let t = w[e.visibility];
190
+ return /* @__PURE__ */ _(y, {
171
191
  treatment: "metric",
172
192
  className: "flex flex-col border-border-seam p-4",
173
- children: [
174
- /* @__PURE__ */ _("div", {
193
+ children: G === e.id ? /* @__PURE__ */ v("form", {
194
+ onSubmit: (t) => void ie(t, e.id),
195
+ className: "space-y-3",
196
+ children: [
197
+ Z && /* @__PURE__ */ _("div", {
198
+ className: "rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-xs text-status-error-text",
199
+ children: Z
200
+ }),
201
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
202
+ htmlFor: `list-edit-name-${e.id}`,
203
+ className: C,
204
+ children: "Name *"
205
+ }), /* @__PURE__ */ _("input", {
206
+ id: `list-edit-name-${e.id}`,
207
+ type: "text",
208
+ value: q,
209
+ onChange: (e) => J(e.target.value),
210
+ className: S,
211
+ autoFocus: !0,
212
+ required: !0
213
+ })] }),
214
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
215
+ htmlFor: `list-edit-visibility-${e.id}`,
216
+ className: C,
217
+ children: "Visibility"
218
+ }), /* @__PURE__ */ _("select", {
219
+ id: `list-edit-visibility-${e.id}`,
220
+ value: Y,
221
+ onChange: (e) => X(e.target.value),
222
+ className: S,
223
+ children: x.map((e) => /* @__PURE__ */ _("option", {
224
+ value: e,
225
+ children: e.charAt(0) + e.slice(1).toLowerCase()
226
+ }, e))
227
+ })] }),
228
+ /* @__PURE__ */ v("div", {
229
+ className: "flex items-center gap-2",
230
+ children: [/* @__PURE__ */ _("button", {
231
+ type: "submit",
232
+ disabled: M.isPending,
233
+ className: "rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 transition-opacity",
234
+ children: M.isPending ? "Saving…" : "Save"
235
+ }), /* @__PURE__ */ _("button", {
236
+ type: "button",
237
+ onClick: re,
238
+ disabled: M.isPending,
239
+ className: "rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-secondary hover:text-text-primary disabled:opacity-50 transition-colors",
240
+ children: "Cancel"
241
+ })]
242
+ })
243
+ ]
244
+ }) : /* @__PURE__ */ v(g, { children: [
245
+ /* @__PURE__ */ v("div", {
175
246
  className: "flex items-start justify-between gap-2",
176
- children: [/* @__PURE__ */ g("h3", {
247
+ children: [/* @__PURE__ */ _("h3", {
177
248
  className: "line-clamp-1 text-sm font-semibold text-text-primary",
178
249
  children: e.name
179
- }), /* @__PURE__ */ g("button", {
180
- type: "button",
181
- disabled: A.isPending,
182
- onClick: () => void U(e.id),
183
- className: "rounded-md p-1 text-text-secondary hover:text-status-error-text disabled:opacity-50 transition-colors",
184
- "aria-label": "Delete list",
185
- children: /* @__PURE__ */ g(m, { className: "h-4 w-4" })
250
+ }), /* @__PURE__ */ v("div", {
251
+ className: "flex items-center gap-0.5",
252
+ children: [/* @__PURE__ */ _("button", {
253
+ type: "button",
254
+ onClick: () => ne(e),
255
+ className: "rounded-md p-1 text-text-secondary hover:text-text-primary transition-colors",
256
+ "aria-label": `Edit list ${e.name}`,
257
+ children: /* @__PURE__ */ _(p, { className: "h-4 w-4" })
258
+ }), /* @__PURE__ */ _("button", {
259
+ type: "button",
260
+ disabled: j.isPending,
261
+ onClick: () => void ae(e.id),
262
+ className: "rounded-md p-1 text-text-secondary hover:text-status-error-text disabled:opacity-50 transition-colors",
263
+ "aria-label": `Delete list ${e.name}`,
264
+ children: /* @__PURE__ */ _(h, { className: "h-4 w-4" })
265
+ })]
186
266
  })]
187
267
  }),
188
- e.description && /* @__PURE__ */ g("p", {
268
+ e.description && /* @__PURE__ */ _("p", {
189
269
  className: "mt-1 line-clamp-2 text-xs text-text-secondary",
190
270
  children: e.description
191
271
  }),
192
- /* @__PURE__ */ _("div", {
272
+ /* @__PURE__ */ v("div", {
193
273
  className: "mt-3 flex items-center gap-3 text-xs text-text-secondary",
194
274
  children: [
195
- /* @__PURE__ */ g("span", {
275
+ /* @__PURE__ */ _("span", {
196
276
  className: "rounded-full bg-bg-sunken px-2 py-0.5",
197
277
  children: e.kind.charAt(0) + e.kind.slice(1).toLowerCase()
198
278
  }),
199
- /* @__PURE__ */ _("span", {
279
+ /* @__PURE__ */ v("span", {
200
280
  className: "inline-flex items-center gap-1",
201
- children: [/* @__PURE__ */ g(t, { className: "h-3 w-3" }), e.visibility.charAt(0) + e.visibility.slice(1).toLowerCase()]
281
+ children: [/* @__PURE__ */ _(t, { className: "h-3 w-3" }), e.visibility.charAt(0) + e.visibility.slice(1).toLowerCase()]
202
282
  }),
203
- /* @__PURE__ */ _("span", { children: [e.itemCount, " items"] })
283
+ /* @__PURE__ */ v("span", { children: [e.itemCount, " items"] })
204
284
  ]
205
285
  }),
206
- /* @__PURE__ */ _("p", {
286
+ /* @__PURE__ */ v("p", {
207
287
  className: "mt-2 text-[11px] text-text-muted",
208
- children: ["Updated ", i(e.updatedAt)]
288
+ children: ["Updated ", a(e.updatedAt)]
209
289
  })
210
- ]
290
+ ] })
211
291
  }, e.id);
212
292
  })
213
293
  })
@@ -215,6 +295,6 @@ var y = ["WATCHLIST", "PLAYLIST"], b = [
215
295
  });
216
296
  };
217
297
  //#endregion
218
- export { w as ListsPage };
298
+ export { T as ListsPage };
219
299
 
220
300
  //# sourceMappingURL=ListsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ListsPage.js","names":[],"sources":["../../../../src/hookmovies/pages/library/ListsPage.tsx"],"sourcesContent":["/**\n * My Lists (Library — self-scoped)\n * @module hookmovies/pages/library\n *\n * The caller's own watchlists and playlists via `hokMyLists`, created with\n * `hokCreateList` and removed with `hokDeleteList`. All self-scoped to the\n * calling user by the subgraph.\n */\n\nimport { type FC, type FormEvent, useState } from 'react';\nimport { ListVideo, Plus, X, Trash2, Lock, Globe, Link as LinkIcon } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingState, ErrorState } from '../../components/StateViews';\nimport {\n useMyLists,\n useCreateList,\n useDeleteList,\n type HokListKind,\n type HokListVisibility,\n type CreateListInput,\n} from '../../hooks/useHookMoviesApi';\nimport { formatRelativeTime } from '../../utils/formatters';\n\nconst KIND_OPTIONS: HokListKind[] = ['WATCHLIST', 'PLAYLIST'];\nconst VISIBILITY_OPTIONS: HokListVisibility[] = ['PRIVATE', 'UNLISTED', 'PUBLIC'];\nconst fieldClass =\n 'w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\nconst labelClass = 'mb-1.5 block text-xs font-medium text-text-secondary';\n\nconst visibilityIcon: Record<HokListVisibility, typeof Lock> = {\n PRIVATE: Lock,\n UNLISTED: LinkIcon,\n PUBLIC: Globe,\n};\n\nexport const ListsPage: FC = () => {\n const [kindFilter, setKindFilter] = useState<HokListKind | ''>('');\n const [showCreate, setShowCreate] = useState(false);\n\n const { data, isLoading, isError, refetch } = useMyLists(kindFilter || undefined, {\n limit: 100,\n offset: 0,\n });\n const createList = useCreateList();\n const deleteList = useDeleteList();\n\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [kind, setKind] = useState<HokListKind>('WATCHLIST');\n const [visibility, setVisibility] = useState<HokListVisibility>('PRIVATE');\n const [error, setError] = useState<string | null>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n\n const handleDelete = async (id: string) => {\n setActionError(null);\n try {\n await deleteList.mutateAsync(id);\n } catch (err) {\n setActionError(\n err instanceof Error ? err.message : 'Failed to delete list (you can only delete your own)'\n );\n }\n };\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n setError(null);\n if (!name.trim()) {\n setError('Name is required.');\n return;\n }\n const input: CreateListInput = {\n name: name.trim(),\n description: description.trim() || undefined,\n kind,\n visibility,\n };\n try {\n await createList.mutateAsync(input);\n setName('');\n setDescription('');\n setKind('WATCHLIST');\n setVisibility('PRIVATE');\n setShowCreate(false);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to create list');\n }\n };\n\n const items = data?.items ?? [];\n\n return (\n <PageLayout\n title=\"My Library\"\n description=\"Watchlists & playlists\"\n purpose=\"Your personal collections — a watchlist of what to watch next and curated playlists you can keep private, unlisted, or public.\"\n actions={\n <button\n type=\"button\"\n onClick={() => setShowCreate((v) => !v)}\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 List\n </button>\n }\n >\n {showCreate && (\n <GlassCard treatment=\"glass\" className=\"mb-6 border-border-seam p-5\">\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-sm font-semibold text-text-primary\">Create List</h2>\n <button\n type=\"button\"\n onClick={() => setShowCreate(false)}\n className=\"rounded-md p-1 text-text-secondary hover:text-text-primary\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {error && (\n <div className=\"rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {error}\n </div>\n )}\n <div>\n <label htmlFor=\"list-name\" className={labelClass}>\n Name *\n </label>\n <input\n id=\"list-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. Weekend Watch\"\n className={fieldClass}\n required\n />\n </div>\n <div>\n <label htmlFor=\"list-desc\" className={labelClass}>\n Description\n </label>\n <textarea\n id=\"list-desc\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n className={fieldClass}\n />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"list-kind\" className={labelClass}>\n Kind\n </label>\n <select\n id=\"list-kind\"\n value={kind}\n onChange={(e) => setKind(e.target.value as HokListKind)}\n className={fieldClass}\n >\n {KIND_OPTIONS.map((k) => (\n <option key={k} value={k}>\n {k.charAt(0) + k.slice(1).toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"list-visibility\" className={labelClass}>\n Visibility\n </label>\n <select\n id=\"list-visibility\"\n value={visibility}\n onChange={(e) => setVisibility(e.target.value as HokListVisibility)}\n className={fieldClass}\n >\n {VISIBILITY_OPTIONS.map((v) => (\n <option key={v} value={v}>\n {v.charAt(0) + v.slice(1).toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n </div>\n <button\n type=\"submit\"\n disabled={createList.isPending}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n {createList.isPending ? 'Creating…' : 'Create List'}\n </button>\n </form>\n </GlassCard>\n )}\n\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <select\n value={kindFilter}\n onChange={(e) => setKindFilter(e.target.value as HokListKind | '')}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Lists</option>\n {KIND_OPTIONS.map((k) => (\n <option key={k} value={k}>\n {k.charAt(0) + k.slice(1).toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n\n {actionError && (\n <div className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {actionError}\n </div>\n )}\n\n {isLoading ? (\n <LoadingState label=\"Loading your lists…\" />\n ) : isError ? (\n <ErrorState onRetry={() => void refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<ListVideo className=\"h-12 w-12\" />}\n title=\"No lists yet\"\n description=\"Create a watchlist or playlist to organize what you watch.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {items.map((list) => {\n const VisibilityIcon = visibilityIcon[list.visibility];\n return (\n <GlassCard\n key={list.id}\n treatment=\"metric\"\n className=\"flex flex-col border-border-seam p-4\"\n >\n <div className=\"flex items-start justify-between gap-2\">\n <h3 className=\"line-clamp-1 text-sm font-semibold text-text-primary\">\n {list.name}\n </h3>\n <button\n type=\"button\"\n disabled={deleteList.isPending}\n onClick={() => void handleDelete(list.id)}\n className=\"rounded-md p-1 text-text-secondary hover:text-status-error-text disabled:opacity-50 transition-colors\"\n aria-label=\"Delete list\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n {list.description && (\n <p className=\"mt-1 line-clamp-2 text-xs text-text-secondary\">\n {list.description}\n </p>\n )}\n <div className=\"mt-3 flex items-center gap-3 text-xs text-text-secondary\">\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5\">\n {list.kind.charAt(0) + list.kind.slice(1).toLowerCase()}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <VisibilityIcon className=\"h-3 w-3\" />\n {list.visibility.charAt(0) + list.visibility.slice(1).toLowerCase()}\n </span>\n <span>{list.itemCount} items</span>\n </div>\n <p className=\"mt-2 text-[11px] text-text-muted\">\n Updated {formatRelativeTime(list.updatedAt)}\n </p>\n </GlassCard>\n );\n })}\n </div>\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ListsPage.js","names":[],"sources":["../../../../src/hookmovies/pages/library/ListsPage.tsx"],"sourcesContent":["/**\n * My Lists (Library — self-scoped)\n * @module hookmovies/pages/library\n *\n * The caller's own watchlists and playlists via `hokMyLists`, created with\n * `hokCreateList` and removed with `hokDeleteList`. All self-scoped to the\n * calling user by the subgraph.\n */\n\nimport { type FC, type FormEvent, useState } from 'react';\nimport { ListVideo, Plus, X, Trash2, Pencil, Lock, Globe, Link as LinkIcon } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingState, ErrorState } from '../../components/StateViews';\nimport {\n useMyLists,\n useCreateList,\n useDeleteList,\n useUpdateList,\n type HokListKind,\n type HokListVisibility,\n type HokList,\n type CreateListInput,\n} from '../../hooks/useHookMoviesApi';\nimport { formatRelativeTime } from '../../utils/formatters';\n\nconst KIND_OPTIONS: HokListKind[] = ['WATCHLIST', 'PLAYLIST'];\nconst VISIBILITY_OPTIONS: HokListVisibility[] = ['PRIVATE', 'UNLISTED', 'PUBLIC'];\nconst fieldClass =\n 'w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\nconst labelClass = 'mb-1.5 block text-xs font-medium text-text-secondary';\n\nconst visibilityIcon: Record<HokListVisibility, typeof Lock> = {\n PRIVATE: Lock,\n UNLISTED: LinkIcon,\n PUBLIC: Globe,\n};\n\nexport const ListsPage: FC = () => {\n const [kindFilter, setKindFilter] = useState<HokListKind | ''>('');\n const [showCreate, setShowCreate] = useState(false);\n\n const { data, isLoading, isError, refetch } = useMyLists(kindFilter || undefined, {\n limit: 100,\n offset: 0,\n });\n const createList = useCreateList();\n const deleteList = useDeleteList();\n const updateList = useUpdateList();\n\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [kind, setKind] = useState<HokListKind>('WATCHLIST');\n const [visibility, setVisibility] = useState<HokListVisibility>('PRIVATE');\n const [error, setError] = useState<string | null>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n\n // Inline edit (rename / re-scope) state — one row open at a time.\n const [editingId, setEditingId] = useState<string | null>(null);\n const [editName, setEditName] = useState('');\n const [editVisibility, setEditVisibility] = useState<HokListVisibility>('PRIVATE');\n const [editError, setEditError] = useState<string | null>(null);\n\n const startEdit = (list: HokList) => {\n setEditError(null);\n setEditingId(list.id);\n setEditName(list.name);\n setEditVisibility(list.visibility);\n };\n\n const cancelEdit = () => {\n setEditingId(null);\n setEditError(null);\n };\n\n const handleUpdate = async (e: FormEvent, id: string) => {\n e.preventDefault();\n setEditError(null);\n if (!editName.trim()) {\n setEditError('Name is required.');\n return;\n }\n try {\n await updateList.mutateAsync({\n id,\n input: { name: editName.trim(), visibility: editVisibility },\n });\n setEditingId(null);\n } catch (err) {\n setEditError(\n err instanceof Error ? err.message : 'Failed to update list (you can only edit your own)'\n );\n }\n };\n\n const handleDelete = async (id: string) => {\n setActionError(null);\n try {\n await deleteList.mutateAsync(id);\n } catch (err) {\n setActionError(\n err instanceof Error ? err.message : 'Failed to delete list (you can only delete your own)'\n );\n }\n };\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n setError(null);\n if (!name.trim()) {\n setError('Name is required.');\n return;\n }\n const input: CreateListInput = {\n name: name.trim(),\n description: description.trim() || undefined,\n kind,\n visibility,\n };\n try {\n await createList.mutateAsync(input);\n setName('');\n setDescription('');\n setKind('WATCHLIST');\n setVisibility('PRIVATE');\n setShowCreate(false);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to create list');\n }\n };\n\n const items = data?.items ?? [];\n\n return (\n <PageLayout\n title=\"My Library\"\n description=\"Watchlists & playlists\"\n purpose=\"Your personal collections — a watchlist of what to watch next and curated playlists you can keep private, unlisted, or public.\"\n actions={\n <button\n type=\"button\"\n onClick={() => setShowCreate((v) => !v)}\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 List\n </button>\n }\n >\n {showCreate && (\n <GlassCard treatment=\"glass\" className=\"mb-6 border-border-seam p-5\">\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-sm font-semibold text-text-primary\">Create List</h2>\n <button\n type=\"button\"\n onClick={() => setShowCreate(false)}\n className=\"rounded-md p-1 text-text-secondary hover:text-text-primary\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {error && (\n <div className=\"rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {error}\n </div>\n )}\n <div>\n <label htmlFor=\"list-name\" className={labelClass}>\n Name *\n </label>\n <input\n id=\"list-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. Weekend Watch\"\n className={fieldClass}\n required\n />\n </div>\n <div>\n <label htmlFor=\"list-desc\" className={labelClass}>\n Description\n </label>\n <textarea\n id=\"list-desc\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n className={fieldClass}\n />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"list-kind\" className={labelClass}>\n Kind\n </label>\n <select\n id=\"list-kind\"\n value={kind}\n onChange={(e) => setKind(e.target.value as HokListKind)}\n className={fieldClass}\n >\n {KIND_OPTIONS.map((k) => (\n <option key={k} value={k}>\n {k.charAt(0) + k.slice(1).toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"list-visibility\" className={labelClass}>\n Visibility\n </label>\n <select\n id=\"list-visibility\"\n value={visibility}\n onChange={(e) => setVisibility(e.target.value as HokListVisibility)}\n className={fieldClass}\n >\n {VISIBILITY_OPTIONS.map((v) => (\n <option key={v} value={v}>\n {v.charAt(0) + v.slice(1).toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n </div>\n <button\n type=\"submit\"\n disabled={createList.isPending}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n {createList.isPending ? 'Creating…' : 'Create List'}\n </button>\n </form>\n </GlassCard>\n )}\n\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <select\n value={kindFilter}\n onChange={(e) => setKindFilter(e.target.value as HokListKind | '')}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Lists</option>\n {KIND_OPTIONS.map((k) => (\n <option key={k} value={k}>\n {k.charAt(0) + k.slice(1).toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n\n {actionError && (\n <div className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {actionError}\n </div>\n )}\n\n {isLoading ? (\n <LoadingState label=\"Loading your lists…\" />\n ) : isError ? (\n <ErrorState onRetry={() => void refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<ListVideo className=\"h-12 w-12\" />}\n title=\"No lists yet\"\n description=\"Create a watchlist or playlist to organize what you watch.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {items.map((list) => {\n const VisibilityIcon = visibilityIcon[list.visibility];\n const isEditing = editingId === list.id;\n return (\n <GlassCard\n key={list.id}\n treatment=\"metric\"\n className=\"flex flex-col border-border-seam p-4\"\n >\n {isEditing ? (\n <form onSubmit={(e) => void handleUpdate(e, list.id)} className=\"space-y-3\">\n {editError && (\n <div className=\"rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-xs text-status-error-text\">\n {editError}\n </div>\n )}\n <div>\n <label htmlFor={`list-edit-name-${list.id}`} className={labelClass}>\n Name *\n </label>\n <input\n id={`list-edit-name-${list.id}`}\n type=\"text\"\n value={editName}\n onChange={(e) => setEditName(e.target.value)}\n className={fieldClass}\n autoFocus\n required\n />\n </div>\n <div>\n <label htmlFor={`list-edit-visibility-${list.id}`} className={labelClass}>\n Visibility\n </label>\n <select\n id={`list-edit-visibility-${list.id}`}\n value={editVisibility}\n onChange={(e) => setEditVisibility(e.target.value as HokListVisibility)}\n className={fieldClass}\n >\n {VISIBILITY_OPTIONS.map((v) => (\n <option key={v} value={v}>\n {v.charAt(0) + v.slice(1).toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"submit\"\n disabled={updateList.isPending}\n className=\"rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n {updateList.isPending ? 'Saving…' : 'Save'}\n </button>\n <button\n type=\"button\"\n onClick={cancelEdit}\n disabled={updateList.isPending}\n className=\"rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-secondary hover:text-text-primary disabled:opacity-50 transition-colors\"\n >\n Cancel\n </button>\n </div>\n </form>\n ) : (\n <>\n <div className=\"flex items-start justify-between gap-2\">\n <h3 className=\"line-clamp-1 text-sm font-semibold text-text-primary\">\n {list.name}\n </h3>\n <div className=\"flex items-center gap-0.5\">\n <button\n type=\"button\"\n onClick={() => startEdit(list)}\n className=\"rounded-md p-1 text-text-secondary hover:text-text-primary transition-colors\"\n aria-label={`Edit list ${list.name}`}\n >\n <Pencil className=\"h-4 w-4\" />\n </button>\n <button\n type=\"button\"\n disabled={deleteList.isPending}\n onClick={() => void handleDelete(list.id)}\n className=\"rounded-md p-1 text-text-secondary hover:text-status-error-text disabled:opacity-50 transition-colors\"\n aria-label={`Delete list ${list.name}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n {list.description && (\n <p className=\"mt-1 line-clamp-2 text-xs text-text-secondary\">\n {list.description}\n </p>\n )}\n <div className=\"mt-3 flex items-center gap-3 text-xs text-text-secondary\">\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5\">\n {list.kind.charAt(0) + list.kind.slice(1).toLowerCase()}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <VisibilityIcon className=\"h-3 w-3\" />\n {list.visibility.charAt(0) + list.visibility.slice(1).toLowerCase()}\n </span>\n <span>{list.itemCount} items</span>\n </div>\n <p className=\"mt-2 text-[11px] text-text-muted\">\n Updated {formatRelativeTime(list.updatedAt)}\n </p>\n </>\n )}\n </GlassCard>\n );\n })}\n </div>\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-hookmovies",
3
- "version": "2026.705.2",
3
+ "version": "2026.706.2",
4
4
  "description": "Burdenoff HookMovies Microfrontend - Mobile services marketplace platform for connecting service providers with customers",
5
5
  "type": "module",
6
6
  "files": [