@burdenoff/microfe-hookmovies 2026.706.2 → 2026.706.4
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.
- package/dist/hookmovies/HookMoviesRoutes.js +54 -6
- package/dist/hookmovies/HookMoviesRoutes.js.map +1 -1
- package/dist/hookmovies/components/index.js +1 -1
- package/dist/hookmovies/context/HookMoviesContext.js +64 -40
- package/dist/hookmovies/context/HookMoviesContext.js.map +1 -1
- package/dist/hookmovies/hooks/useHookMoviesApi.js +592 -134
- package/dist/hookmovies/hooks/useHookMoviesApi.js.map +1 -1
- package/dist/hookmovies/pages/HomePage.js +211 -139
- package/dist/hookmovies/pages/HomePage.js.map +1 -1
- package/dist/hookmovies/pages/ai/ConciergePage.js +330 -0
- package/dist/hookmovies/pages/ai/ConciergePage.js.map +1 -0
- package/dist/hookmovies/pages/analytics/AnalyticsPage.js +450 -0
- package/dist/hookmovies/pages/analytics/AnalyticsPage.js.map +1 -0
- package/dist/hookmovies/pages/analytics/PayoutsPage.js +499 -0
- package/dist/hookmovies/pages/analytics/PayoutsPage.js.map +1 -0
- package/dist/hookmovies/pages/auditions/AuditionDetailPage.js +223 -140
- package/dist/hookmovies/pages/auditions/AuditionDetailPage.js.map +1 -1
- package/dist/hookmovies/pages/auditions/AuditionsPage.js +161 -83
- package/dist/hookmovies/pages/auditions/AuditionsPage.js.map +1 -1
- package/dist/hookmovies/pages/catalog/PeoplePage.js +177 -103
- package/dist/hookmovies/pages/catalog/PeoplePage.js.map +1 -1
- package/dist/hookmovies/pages/catalog/StudiosPage.js +191 -108
- package/dist/hookmovies/pages/catalog/StudiosPage.js.map +1 -1
- package/dist/hookmovies/pages/catalog/TitleDetailPage.js +744 -622
- package/dist/hookmovies/pages/catalog/TitleDetailPage.js.map +1 -1
- package/dist/hookmovies/pages/catalog/TitlesPage.js +218 -138
- package/dist/hookmovies/pages/catalog/TitlesPage.js.map +1 -1
- package/dist/hookmovies/pages/commerce/CheckoutPage.js +430 -0
- package/dist/hookmovies/pages/commerce/CheckoutPage.js.map +1 -0
- package/dist/hookmovies/pages/consumer/DiscoveryPage.js +21 -21
- package/dist/hookmovies/pages/consumer/HooksPage.js +5 -5
- package/dist/hookmovies/pages/consumer/TitleViewPage.js +32 -32
- package/dist/hookmovies/pages/consumer/TitleViewPage.js.map +1 -1
- package/dist/hookmovies/pages/developer/DevPortalPage.js +815 -0
- package/dist/hookmovies/pages/developer/DevPortalPage.js.map +1 -0
- package/dist/hookmovies/pages/distribution/RightsWindowsPage.js +235 -162
- package/dist/hookmovies/pages/distribution/RightsWindowsPage.js.map +1 -1
- package/dist/hookmovies/pages/engagement/ReviewsPage.js +201 -143
- package/dist/hookmovies/pages/engagement/ReviewsPage.js.map +1 -1
- package/dist/hookmovies/pages/library/EntitlementsPage.js +447 -221
- package/dist/hookmovies/pages/library/EntitlementsPage.js.map +1 -1
- package/dist/hookmovies/pages/library/ListsPage.js +243 -167
- package/dist/hookmovies/pages/library/ListsPage.js.map +1 -1
- package/dist/hookmovies/pages/live/LivePage.js +608 -0
- package/dist/hookmovies/pages/live/LivePage.js.map +1 -0
- package/dist/hookmovies/pages/localization/LocalizationPage.js +656 -0
- package/dist/hookmovies/pages/localization/LocalizationPage.js.map +1 -0
- package/dist/hookmovies/pages/onboarding/OnboardingPage.js +366 -0
- package/dist/hookmovies/pages/onboarding/OnboardingPage.js.map +1 -0
- package/dist/hookmovies/pages/productions/ProductionDetailPage.js +265 -179
- package/dist/hookmovies/pages/productions/ProductionDetailPage.js.map +1 -1
- package/dist/hookmovies/pages/productions/ProductionsPage.js +264 -71
- package/dist/hookmovies/pages/productions/ProductionsPage.js.map +1 -1
- package/dist/hookmovies/pages/social/ProfilesPage.js +701 -0
- package/dist/hookmovies/pages/social/ProfilesPage.js.map +1 -0
- package/dist/hookmovies/pages/social/WatchPartyListPage.js +281 -0
- package/dist/hookmovies/pages/social/WatchPartyListPage.js.map +1 -0
- package/dist/hookmovies/pages/social/WatchPartyRoomPage.js +567 -0
- package/dist/hookmovies/pages/social/WatchPartyRoomPage.js.map +1 -0
- package/dist/hookmovies/pages/trust/ModerationPage.js +320 -0
- package/dist/hookmovies/pages/trust/ModerationPage.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
import { useHookMovies as e } from "../../context/HookMoviesContext.js";
|
|
2
|
+
import { cn as t } from "../../utils/cn.js";
|
|
3
|
+
import { useCreateProfile as n, useDeleteProfile as r, useMyProfiles as i, useUpdateProfile as a } from "../../hooks/useHookMoviesApi.js";
|
|
4
|
+
import { uploadFileToFiles as o, useFileUrl as s } from "../../hooks/useFiles.js";
|
|
5
|
+
import { EmptyState as c } from "../../components/EmptyState.js";
|
|
6
|
+
import { ErrorState as l, LoadingState as u } from "../../components/StateViews.js";
|
|
7
|
+
import "../../components/index.js";
|
|
8
|
+
import { useCallback as d, useEffect as f, useMemo as p, useState as m } from "react";
|
|
9
|
+
import { AlertCircle as h, Baby as g, Camera as _, Check as v, Loader2 as y, Lock as b, Pencil as x, Plus as S, ShieldCheck as C, Trash2 as w, X as T } from "lucide-react";
|
|
10
|
+
import { Fragment as E, jsx as D, jsxs as O } from "react/jsx-runtime";
|
|
11
|
+
import { GlassCard as k, Switch as A } from "@burdenoff/fe-libs/ui";
|
|
12
|
+
//#region src/hookmovies/pages/social/ProfilesPage.tsx
|
|
13
|
+
var j = "/HookMovies/Avatars", M = [
|
|
14
|
+
{
|
|
15
|
+
code: "en",
|
|
16
|
+
label: "English"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
code: "es",
|
|
20
|
+
label: "Spanish"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
code: "hi",
|
|
24
|
+
label: "Hindi"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
code: "ta",
|
|
28
|
+
label: "Tamil"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
code: "fr",
|
|
32
|
+
label: "French"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
code: "de",
|
|
36
|
+
label: "German"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
code: "pt",
|
|
40
|
+
label: "Portuguese"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
code: "ja",
|
|
44
|
+
label: "Japanese"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
code: "ko",
|
|
48
|
+
label: "Korean"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
code: "zh",
|
|
52
|
+
label: "Chinese"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
code: "ar",
|
|
56
|
+
label: "Arabic"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
code: "ru",
|
|
60
|
+
label: "Russian"
|
|
61
|
+
}
|
|
62
|
+
], N = [
|
|
63
|
+
{
|
|
64
|
+
value: "",
|
|
65
|
+
label: "No limit — all ratings"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
value: "G",
|
|
69
|
+
label: "G — General audiences"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
value: "PG",
|
|
73
|
+
label: "PG — Parental guidance"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
value: "PG-13",
|
|
77
|
+
label: "PG-13 — Teens"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
value: "R",
|
|
81
|
+
label: "R — Restricted"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
value: "NC-17",
|
|
85
|
+
label: "NC-17 — Adults only"
|
|
86
|
+
}
|
|
87
|
+
], P = "PG", F = 5, I = "block text-sm font-medium text-text-primary", L = "w-full rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-muted transition-colors focus:border-border-strong focus:outline-none focus-visible:ring-2 focus-visible:ring-border-focus", R = "inline-flex items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-semibold text-action-primary-text transition-opacity hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus-visible:ring-2 focus-visible:ring-border-focus", z = "inline-flex items-center justify-center gap-2 rounded-lg border border-border-seam bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:border-border-strong hover:bg-bg-sunken focus:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
|
|
88
|
+
function B(e) {
|
|
89
|
+
let t = e.trim().split(/\s+/).filter(Boolean);
|
|
90
|
+
return t.length === 0 ? "?" : t.length === 1 ? t[0].slice(0, 2).toUpperCase() : (t[0][0] + t[t.length - 1][0]).toUpperCase();
|
|
91
|
+
}
|
|
92
|
+
var V = ({ fileId: e, overrideUrl: n, name: r, className: i }) => {
|
|
93
|
+
let { data: a, isLoading: o } = s(n ? void 0 : e), c = n ?? a ?? null;
|
|
94
|
+
return /* @__PURE__ */ D("div", {
|
|
95
|
+
className: t("relative flex aspect-square w-full items-center justify-center overflow-hidden rounded-2xl border border-border-seam bg-bg-sunken", i),
|
|
96
|
+
children: c ? /* @__PURE__ */ D("img", {
|
|
97
|
+
src: c,
|
|
98
|
+
alt: "",
|
|
99
|
+
className: "h-full w-full object-cover"
|
|
100
|
+
}) : o && e ? /* @__PURE__ */ D(y, {
|
|
101
|
+
className: "h-6 w-6 animate-spin text-text-muted",
|
|
102
|
+
"aria-hidden": "true"
|
|
103
|
+
}) : /* @__PURE__ */ D("span", {
|
|
104
|
+
className: "text-2xl font-semibold text-text-secondary sm:text-3xl",
|
|
105
|
+
children: B(r)
|
|
106
|
+
})
|
|
107
|
+
});
|
|
108
|
+
}, H = ({ profile: e, isActive: n, manageMode: r, onSelect: i, onEdit: a }) => {
|
|
109
|
+
let o = r ? `Edit ${e.name}'s profile` : `Switch to ${e.name}'s profile`;
|
|
110
|
+
return /* @__PURE__ */ O("button", {
|
|
111
|
+
type: "button",
|
|
112
|
+
onClick: r ? a : i,
|
|
113
|
+
"aria-label": o,
|
|
114
|
+
"aria-pressed": !r && n,
|
|
115
|
+
className: t("group flex w-full flex-col items-center gap-3 rounded-2xl p-2 text-center transition-transform", "focus:outline-none focus-visible:ring-2 focus-visible:ring-border-focus", "hover:-translate-y-0.5 motion-reduce:transform-none"),
|
|
116
|
+
children: [/* @__PURE__ */ O("div", {
|
|
117
|
+
className: "relative w-full",
|
|
118
|
+
children: [
|
|
119
|
+
/* @__PURE__ */ D(k, {
|
|
120
|
+
treatment: n ? "insight" : "glass",
|
|
121
|
+
glow: n,
|
|
122
|
+
className: t("overflow-hidden !p-0", n && "ring-2 ring-action-primary-bg"),
|
|
123
|
+
children: /* @__PURE__ */ D(V, {
|
|
124
|
+
fileId: e.avatarFileId,
|
|
125
|
+
name: e.name
|
|
126
|
+
})
|
|
127
|
+
}),
|
|
128
|
+
e.isKids && /* @__PURE__ */ O("span", {
|
|
129
|
+
className: "absolute left-2 top-2 inline-flex items-center gap-1 rounded-full border border-border-seam bg-bg-surface/80 px-2 py-0.5 text-[0.65rem] font-semibold text-status-info-text backdrop-blur",
|
|
130
|
+
title: "Kids profile",
|
|
131
|
+
children: [/* @__PURE__ */ D(g, {
|
|
132
|
+
className: "h-3 w-3",
|
|
133
|
+
"aria-hidden": "true"
|
|
134
|
+
}), "Kids"]
|
|
135
|
+
}),
|
|
136
|
+
e.hasPin && /* @__PURE__ */ D("span", {
|
|
137
|
+
className: "absolute right-2 top-2 inline-flex h-6 w-6 items-center justify-center rounded-full border border-border-seam bg-bg-surface/80 text-text-secondary backdrop-blur",
|
|
138
|
+
title: "PIN protected",
|
|
139
|
+
children: /* @__PURE__ */ D(b, {
|
|
140
|
+
className: "h-3 w-3",
|
|
141
|
+
"aria-hidden": "true"
|
|
142
|
+
})
|
|
143
|
+
}),
|
|
144
|
+
r && /* @__PURE__ */ D("span", {
|
|
145
|
+
"aria-hidden": "true",
|
|
146
|
+
className: "pointer-events-none absolute inset-0 flex items-center justify-center rounded-2xl bg-bg-overlay/50 opacity-0 transition-opacity group-hover:opacity-100 group-focus-visible:opacity-100",
|
|
147
|
+
children: /* @__PURE__ */ D("span", {
|
|
148
|
+
className: "inline-flex h-10 w-10 items-center justify-center rounded-full border border-border-seam bg-bg-surface text-text-primary",
|
|
149
|
+
children: /* @__PURE__ */ D(x, { className: "h-4 w-4" })
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
]
|
|
153
|
+
}), /* @__PURE__ */ O("div", {
|
|
154
|
+
className: "min-w-0",
|
|
155
|
+
children: [/* @__PURE__ */ D("p", {
|
|
156
|
+
className: t("truncate text-sm font-medium", n ? "text-text-primary" : "text-text-secondary group-hover:text-text-primary"),
|
|
157
|
+
children: e.name
|
|
158
|
+
}), n && !r && /* @__PURE__ */ D("p", {
|
|
159
|
+
className: "mt-0.5 text-[0.7rem] font-medium text-action-primary-bg",
|
|
160
|
+
children: "Watching now"
|
|
161
|
+
})]
|
|
162
|
+
})]
|
|
163
|
+
});
|
|
164
|
+
}, U = ({ onClick: e }) => /* @__PURE__ */ O("button", {
|
|
165
|
+
type: "button",
|
|
166
|
+
onClick: e,
|
|
167
|
+
"aria-label": "Add a profile",
|
|
168
|
+
className: t("group flex w-full flex-col items-center gap-3 rounded-2xl p-2 text-center transition-transform", "focus:outline-none focus-visible:ring-2 focus-visible:ring-border-focus", "hover:-translate-y-0.5 motion-reduce:transform-none"),
|
|
169
|
+
children: [/* @__PURE__ */ D("div", {
|
|
170
|
+
className: "flex aspect-square w-full items-center justify-center rounded-2xl border border-dashed border-border-strong bg-bg-surface/40 text-text-muted transition-colors group-hover:border-action-primary-bg group-hover:text-action-primary-bg",
|
|
171
|
+
children: /* @__PURE__ */ D(S, {
|
|
172
|
+
className: "h-8 w-8",
|
|
173
|
+
"aria-hidden": "true"
|
|
174
|
+
})
|
|
175
|
+
}), /* @__PURE__ */ D("p", {
|
|
176
|
+
className: "text-sm font-medium text-text-secondary group-hover:text-text-primary",
|
|
177
|
+
children: "Add profile"
|
|
178
|
+
})]
|
|
179
|
+
}), W = ({ profile: e, onClose: r, onDelete: i, isDeleting: s = !1 }) => {
|
|
180
|
+
let c = e !== null, l = n(), u = a(), [p, x] = m(() => ({
|
|
181
|
+
name: e?.name ?? "",
|
|
182
|
+
isKids: e?.isKids ?? !1,
|
|
183
|
+
maturityLimit: e?.maturityLimit ?? "",
|
|
184
|
+
languages: e?.languages ?? [],
|
|
185
|
+
pin: "",
|
|
186
|
+
avatarFileId: e?.avatarFileId ?? null
|
|
187
|
+
})), [S, E] = m(null), [k, F] = m(!1), [B, H] = m(null), U = l.isPending || u.isPending, W = U || k || s;
|
|
188
|
+
f(() => {
|
|
189
|
+
let e = (e) => {
|
|
190
|
+
e.key === "Escape" && !W && r();
|
|
191
|
+
};
|
|
192
|
+
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
193
|
+
}, [W, r]);
|
|
194
|
+
let G = d((e, t) => {
|
|
195
|
+
x((n) => ({
|
|
196
|
+
...n,
|
|
197
|
+
[e]: t
|
|
198
|
+
}));
|
|
199
|
+
}, []), K = d((e) => {
|
|
200
|
+
x((t) => ({
|
|
201
|
+
...t,
|
|
202
|
+
languages: t.languages.includes(e) ? t.languages.filter((t) => t !== e) : [...t.languages, e]
|
|
203
|
+
}));
|
|
204
|
+
}, []), q = d((e) => {
|
|
205
|
+
x((t) => {
|
|
206
|
+
let n = e && (t.maturityLimit === "" || t.maturityLimit === "R" || t.maturityLimit === "NC-17") ? P : t.maturityLimit;
|
|
207
|
+
return {
|
|
208
|
+
...t,
|
|
209
|
+
isKids: e,
|
|
210
|
+
maturityLimit: n
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
}, []), J = d(async (e) => {
|
|
214
|
+
let t = e.target.files?.[0];
|
|
215
|
+
if (e.target.value = "", t) {
|
|
216
|
+
if (!t.type.startsWith("image/")) {
|
|
217
|
+
H("Please choose an image file for the avatar.");
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
H(null), F(!0);
|
|
221
|
+
try {
|
|
222
|
+
let e = await o(t, j);
|
|
223
|
+
x((t) => ({
|
|
224
|
+
...t,
|
|
225
|
+
avatarFileId: e.id
|
|
226
|
+
})), E(e.url || null);
|
|
227
|
+
} catch (e) {
|
|
228
|
+
H(e instanceof Error ? e.message : "The avatar upload failed. Please try again.");
|
|
229
|
+
} finally {
|
|
230
|
+
F(!1);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}, []), Y = d(async (t) => {
|
|
234
|
+
t.preventDefault();
|
|
235
|
+
let n = p.name.trim();
|
|
236
|
+
if (!n) {
|
|
237
|
+
H("A profile name is required.");
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
let i = p.pin.trim();
|
|
241
|
+
if (i && !/^\d{4}$/.test(i)) {
|
|
242
|
+
H("The PIN must be exactly 4 digits.");
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
H(null);
|
|
246
|
+
let a = p.maturityLimit || void 0;
|
|
247
|
+
try {
|
|
248
|
+
if (c && e) {
|
|
249
|
+
let t = {
|
|
250
|
+
name: n,
|
|
251
|
+
isKids: p.isKids,
|
|
252
|
+
languages: p.languages,
|
|
253
|
+
maturityLimit: a,
|
|
254
|
+
avatarFileId: p.avatarFileId ?? void 0
|
|
255
|
+
};
|
|
256
|
+
i && (t.pin = i), await u.mutateAsync({
|
|
257
|
+
id: e.id,
|
|
258
|
+
input: t
|
|
259
|
+
});
|
|
260
|
+
} else {
|
|
261
|
+
let e = {
|
|
262
|
+
name: n,
|
|
263
|
+
isKids: p.isKids,
|
|
264
|
+
languages: p.languages,
|
|
265
|
+
maturityLimit: a,
|
|
266
|
+
avatarFileId: p.avatarFileId ?? void 0
|
|
267
|
+
};
|
|
268
|
+
i && (e.pin = i), await l.mutateAsync(e);
|
|
269
|
+
}
|
|
270
|
+
r();
|
|
271
|
+
} catch (e) {
|
|
272
|
+
H(e instanceof Error ? e.message : "Could not save the profile. Please try again.");
|
|
273
|
+
}
|
|
274
|
+
}, [
|
|
275
|
+
p,
|
|
276
|
+
c,
|
|
277
|
+
e,
|
|
278
|
+
u,
|
|
279
|
+
l,
|
|
280
|
+
r
|
|
281
|
+
]), X = "hok-profile-modal-title";
|
|
282
|
+
return /* @__PURE__ */ D("div", {
|
|
283
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-canvas/90 p-4 backdrop-blur-sm",
|
|
284
|
+
role: "dialog",
|
|
285
|
+
"aria-modal": "true",
|
|
286
|
+
"aria-labelledby": X,
|
|
287
|
+
onClick: () => {
|
|
288
|
+
W || r();
|
|
289
|
+
},
|
|
290
|
+
children: /* @__PURE__ */ O("div", {
|
|
291
|
+
className: "relative flex max-h-[90vh] w-full max-w-lg flex-col overflow-hidden rounded-2xl border border-border-seam bg-bg-surface shadow-2xl",
|
|
292
|
+
onClick: (e) => e.stopPropagation(),
|
|
293
|
+
children: [/* @__PURE__ */ O("div", {
|
|
294
|
+
className: "flex items-center justify-between gap-4 border-b border-border-seam px-5 py-4",
|
|
295
|
+
children: [/* @__PURE__ */ D("h2", {
|
|
296
|
+
id: X,
|
|
297
|
+
className: "text-lg font-semibold text-text-primary",
|
|
298
|
+
children: c ? "Edit profile" : "Add a profile"
|
|
299
|
+
}), /* @__PURE__ */ D("button", {
|
|
300
|
+
type: "button",
|
|
301
|
+
onClick: r,
|
|
302
|
+
disabled: W,
|
|
303
|
+
"aria-label": "Close",
|
|
304
|
+
className: "flex size-9 items-center justify-center rounded-full text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:opacity-50",
|
|
305
|
+
children: /* @__PURE__ */ D(T, { className: "h-5 w-5" })
|
|
306
|
+
})]
|
|
307
|
+
}), /* @__PURE__ */ O("form", {
|
|
308
|
+
onSubmit: Y,
|
|
309
|
+
className: "flex min-h-0 flex-1 flex-col",
|
|
310
|
+
children: [/* @__PURE__ */ O("div", {
|
|
311
|
+
className: "flex-1 space-y-5 overflow-y-auto px-5 py-5",
|
|
312
|
+
children: [
|
|
313
|
+
/* @__PURE__ */ O("div", {
|
|
314
|
+
className: "flex items-start gap-4",
|
|
315
|
+
children: [/* @__PURE__ */ O("div", {
|
|
316
|
+
className: "relative w-24 shrink-0",
|
|
317
|
+
children: [/* @__PURE__ */ D(V, {
|
|
318
|
+
fileId: p.avatarFileId,
|
|
319
|
+
overrideUrl: S,
|
|
320
|
+
name: p.name || "New profile"
|
|
321
|
+
}), /* @__PURE__ */ O("label", {
|
|
322
|
+
className: t("absolute -bottom-2 -right-2 flex size-9 cursor-pointer items-center justify-center rounded-full", "border border-border-seam bg-bg-surface text-text-primary shadow-sm transition-colors", "hover:border-border-strong hover:bg-bg-sunken focus-within:ring-2 focus-within:ring-border-focus", k && "pointer-events-none opacity-70"),
|
|
323
|
+
title: "Upload avatar",
|
|
324
|
+
children: [
|
|
325
|
+
k ? /* @__PURE__ */ D(y, {
|
|
326
|
+
className: "h-4 w-4 animate-spin",
|
|
327
|
+
"aria-hidden": "true"
|
|
328
|
+
}) : /* @__PURE__ */ D(_, {
|
|
329
|
+
className: "h-4 w-4",
|
|
330
|
+
"aria-hidden": "true"
|
|
331
|
+
}),
|
|
332
|
+
/* @__PURE__ */ D("span", {
|
|
333
|
+
className: "sr-only",
|
|
334
|
+
children: "Upload avatar image"
|
|
335
|
+
}),
|
|
336
|
+
/* @__PURE__ */ D("input", {
|
|
337
|
+
type: "file",
|
|
338
|
+
accept: "image/*",
|
|
339
|
+
className: "sr-only",
|
|
340
|
+
onChange: J,
|
|
341
|
+
disabled: k
|
|
342
|
+
})
|
|
343
|
+
]
|
|
344
|
+
})]
|
|
345
|
+
}), /* @__PURE__ */ O("div", {
|
|
346
|
+
className: "min-w-0 flex-1 space-y-1.5",
|
|
347
|
+
children: [
|
|
348
|
+
/* @__PURE__ */ D("label", {
|
|
349
|
+
htmlFor: "hok-profile-name",
|
|
350
|
+
className: I,
|
|
351
|
+
children: "Name"
|
|
352
|
+
}),
|
|
353
|
+
/* @__PURE__ */ D("input", {
|
|
354
|
+
id: "hok-profile-name",
|
|
355
|
+
type: "text",
|
|
356
|
+
value: p.name,
|
|
357
|
+
onChange: (e) => G("name", e.target.value),
|
|
358
|
+
placeholder: "e.g. Alex",
|
|
359
|
+
maxLength: 60,
|
|
360
|
+
autoFocus: !0,
|
|
361
|
+
required: !0,
|
|
362
|
+
className: L
|
|
363
|
+
}),
|
|
364
|
+
/* @__PURE__ */ D("p", {
|
|
365
|
+
className: "text-xs text-text-muted",
|
|
366
|
+
children: "Shown on the “Who’s watching?” screen and personalises recommendations."
|
|
367
|
+
})
|
|
368
|
+
]
|
|
369
|
+
})]
|
|
370
|
+
}),
|
|
371
|
+
/* @__PURE__ */ O("div", {
|
|
372
|
+
className: "flex items-center justify-between gap-4 rounded-lg border border-border-seam bg-bg-sunken px-4 py-3",
|
|
373
|
+
children: [/* @__PURE__ */ O("div", {
|
|
374
|
+
className: "flex items-start gap-3",
|
|
375
|
+
children: [/* @__PURE__ */ D(g, {
|
|
376
|
+
className: "mt-0.5 h-5 w-5 text-status-info-text",
|
|
377
|
+
"aria-hidden": "true"
|
|
378
|
+
}), /* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("p", {
|
|
379
|
+
className: "text-sm font-medium text-text-primary",
|
|
380
|
+
children: "Kids profile"
|
|
381
|
+
}), /* @__PURE__ */ D("p", {
|
|
382
|
+
className: "text-xs text-text-muted",
|
|
383
|
+
children: "A simpler experience limited to age-appropriate titles."
|
|
384
|
+
})] })]
|
|
385
|
+
}), /* @__PURE__ */ D(A, {
|
|
386
|
+
checked: p.isKids,
|
|
387
|
+
onCheckedChange: q,
|
|
388
|
+
"aria-label": "Kids profile"
|
|
389
|
+
})]
|
|
390
|
+
}),
|
|
391
|
+
/* @__PURE__ */ O("div", {
|
|
392
|
+
className: "space-y-1.5",
|
|
393
|
+
children: [
|
|
394
|
+
/* @__PURE__ */ D("label", {
|
|
395
|
+
htmlFor: "hok-profile-maturity",
|
|
396
|
+
className: I,
|
|
397
|
+
children: "Maturity ceiling"
|
|
398
|
+
}),
|
|
399
|
+
/* @__PURE__ */ D("select", {
|
|
400
|
+
id: "hok-profile-maturity",
|
|
401
|
+
value: p.maturityLimit,
|
|
402
|
+
onChange: (e) => G("maturityLimit", e.target.value),
|
|
403
|
+
className: t(L, "appearance-none"),
|
|
404
|
+
children: N.map((e) => /* @__PURE__ */ D("option", {
|
|
405
|
+
value: e.value,
|
|
406
|
+
children: e.label
|
|
407
|
+
}, e.value || "none"))
|
|
408
|
+
}),
|
|
409
|
+
/* @__PURE__ */ D("p", {
|
|
410
|
+
className: "text-xs text-text-muted",
|
|
411
|
+
children: "Hides titles rated above this level from this profile."
|
|
412
|
+
})
|
|
413
|
+
]
|
|
414
|
+
}),
|
|
415
|
+
/* @__PURE__ */ O("fieldset", {
|
|
416
|
+
className: "space-y-2",
|
|
417
|
+
children: [
|
|
418
|
+
/* @__PURE__ */ D("legend", {
|
|
419
|
+
className: I,
|
|
420
|
+
children: "Preferred languages"
|
|
421
|
+
}),
|
|
422
|
+
/* @__PURE__ */ D("div", {
|
|
423
|
+
className: "flex flex-wrap gap-2",
|
|
424
|
+
children: M.map((e) => {
|
|
425
|
+
let n = p.languages.includes(e.code);
|
|
426
|
+
return /* @__PURE__ */ O("button", {
|
|
427
|
+
type: "button",
|
|
428
|
+
"aria-pressed": n,
|
|
429
|
+
onClick: () => K(e.code),
|
|
430
|
+
className: t("inline-flex items-center gap-1.5 rounded-full border px-3 py-1.5 text-sm transition-colors", "focus:outline-none focus-visible:ring-2 focus-visible:ring-border-focus", n ? "border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg" : "border-border-seam bg-bg-surface text-text-secondary hover:border-border-strong hover:text-text-primary"),
|
|
431
|
+
children: [n && /* @__PURE__ */ D(v, {
|
|
432
|
+
className: "h-3.5 w-3.5",
|
|
433
|
+
"aria-hidden": "true"
|
|
434
|
+
}), e.label]
|
|
435
|
+
}, e.code);
|
|
436
|
+
})
|
|
437
|
+
}),
|
|
438
|
+
/* @__PURE__ */ D("p", {
|
|
439
|
+
className: "text-xs text-text-muted",
|
|
440
|
+
children: "Prioritises audio & subtitle tracks in these languages."
|
|
441
|
+
})
|
|
442
|
+
]
|
|
443
|
+
}),
|
|
444
|
+
/* @__PURE__ */ O("div", {
|
|
445
|
+
className: "space-y-1.5",
|
|
446
|
+
children: [
|
|
447
|
+
/* @__PURE__ */ O("label", {
|
|
448
|
+
htmlFor: "hok-profile-pin",
|
|
449
|
+
className: I,
|
|
450
|
+
children: [
|
|
451
|
+
"Profile PIN",
|
|
452
|
+
" ",
|
|
453
|
+
/* @__PURE__ */ D("span", {
|
|
454
|
+
className: "font-normal text-text-muted",
|
|
455
|
+
children: "(optional, 4 digits)"
|
|
456
|
+
})
|
|
457
|
+
]
|
|
458
|
+
}),
|
|
459
|
+
/* @__PURE__ */ O("div", {
|
|
460
|
+
className: "relative",
|
|
461
|
+
children: [/* @__PURE__ */ D(b, {
|
|
462
|
+
className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-muted",
|
|
463
|
+
"aria-hidden": "true"
|
|
464
|
+
}), /* @__PURE__ */ D("input", {
|
|
465
|
+
id: "hok-profile-pin",
|
|
466
|
+
type: "password",
|
|
467
|
+
inputMode: "numeric",
|
|
468
|
+
autoComplete: "off",
|
|
469
|
+
pattern: "\\d{4}",
|
|
470
|
+
maxLength: 4,
|
|
471
|
+
value: p.pin,
|
|
472
|
+
onChange: (e) => G("pin", e.target.value.replace(/\D/g, "").slice(0, 4)),
|
|
473
|
+
placeholder: e?.hasPin ? "•••• (set — leave blank to keep)" : "Set a PIN",
|
|
474
|
+
className: t(L, "pl-9 tracking-[0.4em]")
|
|
475
|
+
})]
|
|
476
|
+
}),
|
|
477
|
+
e?.hasPin && /* @__PURE__ */ O("p", {
|
|
478
|
+
className: "inline-flex items-center gap-1.5 text-xs text-status-success-text",
|
|
479
|
+
children: [/* @__PURE__ */ D(C, {
|
|
480
|
+
className: "h-3.5 w-3.5",
|
|
481
|
+
"aria-hidden": "true"
|
|
482
|
+
}), "This profile is PIN protected. Leave blank to keep the current PIN."]
|
|
483
|
+
})
|
|
484
|
+
]
|
|
485
|
+
}),
|
|
486
|
+
B && /* @__PURE__ */ O("p", {
|
|
487
|
+
role: "alert",
|
|
488
|
+
className: "flex items-start gap-2 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
|
|
489
|
+
children: [/* @__PURE__ */ D(h, {
|
|
490
|
+
className: "mt-0.5 h-4 w-4 shrink-0",
|
|
491
|
+
"aria-hidden": "true"
|
|
492
|
+
}), B]
|
|
493
|
+
})
|
|
494
|
+
]
|
|
495
|
+
}), /* @__PURE__ */ O("div", {
|
|
496
|
+
className: "flex items-center justify-between gap-3 border-t border-border-seam px-5 py-4",
|
|
497
|
+
children: [c && e && i ? /* @__PURE__ */ O("button", {
|
|
498
|
+
type: "button",
|
|
499
|
+
onClick: () => i(e),
|
|
500
|
+
disabled: W,
|
|
501
|
+
className: "inline-flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle focus:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:opacity-50",
|
|
502
|
+
children: [s ? /* @__PURE__ */ D(y, {
|
|
503
|
+
className: "h-4 w-4 animate-spin",
|
|
504
|
+
"aria-hidden": "true"
|
|
505
|
+
}) : /* @__PURE__ */ D(w, {
|
|
506
|
+
className: "h-4 w-4",
|
|
507
|
+
"aria-hidden": "true"
|
|
508
|
+
}), "Delete"]
|
|
509
|
+
}) : /* @__PURE__ */ D("span", {}), /* @__PURE__ */ O("div", {
|
|
510
|
+
className: "flex items-center gap-3",
|
|
511
|
+
children: [/* @__PURE__ */ D("button", {
|
|
512
|
+
type: "button",
|
|
513
|
+
onClick: r,
|
|
514
|
+
disabled: W,
|
|
515
|
+
className: z,
|
|
516
|
+
children: "Cancel"
|
|
517
|
+
}), /* @__PURE__ */ O("button", {
|
|
518
|
+
type: "submit",
|
|
519
|
+
disabled: W,
|
|
520
|
+
className: R,
|
|
521
|
+
children: [U && /* @__PURE__ */ D(y, {
|
|
522
|
+
className: "h-4 w-4 animate-spin",
|
|
523
|
+
"aria-hidden": "true"
|
|
524
|
+
}), c ? "Save changes" : "Create profile"]
|
|
525
|
+
})]
|
|
526
|
+
})]
|
|
527
|
+
})]
|
|
528
|
+
})]
|
|
529
|
+
})
|
|
530
|
+
});
|
|
531
|
+
}, G = ({ profile: e, onCancel: t, onConfirm: n, isDeleting: r }) => (f(() => {
|
|
532
|
+
let e = (e) => {
|
|
533
|
+
e.key === "Escape" && !r && t();
|
|
534
|
+
};
|
|
535
|
+
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
536
|
+
}, [r, t]), /* @__PURE__ */ D("div", {
|
|
537
|
+
className: "fixed inset-0 z-[60] flex items-center justify-center bg-bg-canvas/90 p-4 backdrop-blur-sm",
|
|
538
|
+
role: "alertdialog",
|
|
539
|
+
"aria-modal": "true",
|
|
540
|
+
"aria-label": `Delete ${e.name}'s profile`,
|
|
541
|
+
onClick: () => {
|
|
542
|
+
r || t();
|
|
543
|
+
},
|
|
544
|
+
children: /* @__PURE__ */ O("div", {
|
|
545
|
+
className: "w-full max-w-sm rounded-2xl border border-border-seam bg-bg-surface p-6 shadow-2xl",
|
|
546
|
+
onClick: (e) => e.stopPropagation(),
|
|
547
|
+
children: [/* @__PURE__ */ O("div", {
|
|
548
|
+
className: "flex items-start gap-3",
|
|
549
|
+
children: [/* @__PURE__ */ D("span", {
|
|
550
|
+
className: "flex size-10 shrink-0 items-center justify-center rounded-full bg-status-error-bg-subtle text-status-error-text",
|
|
551
|
+
children: /* @__PURE__ */ D(w, {
|
|
552
|
+
className: "h-5 w-5",
|
|
553
|
+
"aria-hidden": "true"
|
|
554
|
+
})
|
|
555
|
+
}), /* @__PURE__ */ O("div", {
|
|
556
|
+
className: "min-w-0",
|
|
557
|
+
children: [/* @__PURE__ */ D("h2", {
|
|
558
|
+
className: "text-base font-semibold text-text-primary",
|
|
559
|
+
children: "Delete this profile?"
|
|
560
|
+
}), /* @__PURE__ */ O("p", {
|
|
561
|
+
className: "mt-1 text-sm text-text-secondary",
|
|
562
|
+
children: [/* @__PURE__ */ D("span", {
|
|
563
|
+
className: "font-medium text-text-primary",
|
|
564
|
+
children: e.name
|
|
565
|
+
}), "'s viewing history and preferences will be permanently removed. This can't be undone."]
|
|
566
|
+
})]
|
|
567
|
+
})]
|
|
568
|
+
}), /* @__PURE__ */ O("div", {
|
|
569
|
+
className: "mt-6 flex items-center justify-end gap-3",
|
|
570
|
+
children: [/* @__PURE__ */ D("button", {
|
|
571
|
+
type: "button",
|
|
572
|
+
onClick: t,
|
|
573
|
+
disabled: r,
|
|
574
|
+
className: z,
|
|
575
|
+
children: "Cancel"
|
|
576
|
+
}), /* @__PURE__ */ O("button", {
|
|
577
|
+
type: "button",
|
|
578
|
+
onClick: n,
|
|
579
|
+
disabled: r,
|
|
580
|
+
className: "inline-flex items-center justify-center gap-2 rounded-lg bg-status-error-text px-4 py-2 text-sm font-semibold text-bg-surface transition-opacity hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:opacity-50",
|
|
581
|
+
children: [r && /* @__PURE__ */ D(y, {
|
|
582
|
+
className: "h-4 w-4 animate-spin",
|
|
583
|
+
"aria-hidden": "true"
|
|
584
|
+
}), "Delete profile"]
|
|
585
|
+
})]
|
|
586
|
+
})]
|
|
587
|
+
})
|
|
588
|
+
})), K = () => {
|
|
589
|
+
let { activeProfileId: t, setActiveProfile: n, navigateTo: a } = e(), { data: o, isLoading: s, isError: f, refetch: h } = i(), g = r(), [_, y] = m(!1), [b, C] = m(null), w = p(() => o ?? [], [o]), T = w.length < F, k = d((e) => {
|
|
590
|
+
n(e.id), a("browse");
|
|
591
|
+
}, [n, a]), A = d(async (e) => {
|
|
592
|
+
try {
|
|
593
|
+
await g.mutateAsync(e.id), t === e.id && n(null), C(null);
|
|
594
|
+
} catch {
|
|
595
|
+
C({
|
|
596
|
+
kind: "edit",
|
|
597
|
+
profile: e
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
}, [
|
|
601
|
+
g,
|
|
602
|
+
t,
|
|
603
|
+
n
|
|
604
|
+
]), j;
|
|
605
|
+
return j = s ? /* @__PURE__ */ D(u, {
|
|
606
|
+
label: "Loading profiles…",
|
|
607
|
+
className: "min-h-[60vh]"
|
|
608
|
+
}) : f ? /* @__PURE__ */ D(l, {
|
|
609
|
+
title: "Couldn't load profiles",
|
|
610
|
+
message: "We couldn't reach your account profiles. Check your connection and try again.",
|
|
611
|
+
onRetry: () => void h(),
|
|
612
|
+
className: "min-h-[60vh]"
|
|
613
|
+
}) : w.length === 0 ? /* @__PURE__ */ D("div", {
|
|
614
|
+
className: "flex min-h-[50vh] items-center justify-center",
|
|
615
|
+
children: /* @__PURE__ */ D(c, {
|
|
616
|
+
illustration: "empty-data",
|
|
617
|
+
title: "No profiles yet",
|
|
618
|
+
description: "Create a profile for each person who shares this account — each gets its own recommendations, languages and parental controls.",
|
|
619
|
+
action: /* @__PURE__ */ O("button", {
|
|
620
|
+
type: "button",
|
|
621
|
+
onClick: () => C({ kind: "create" }),
|
|
622
|
+
className: R,
|
|
623
|
+
children: [/* @__PURE__ */ D(S, {
|
|
624
|
+
className: "h-4 w-4",
|
|
625
|
+
"aria-hidden": "true"
|
|
626
|
+
}), "Add your first profile"]
|
|
627
|
+
})
|
|
628
|
+
})
|
|
629
|
+
}) : /* @__PURE__ */ O("div", {
|
|
630
|
+
className: "mx-auto grid w-full max-w-4xl grid-cols-2 gap-4 sm:grid-cols-3 sm:gap-6 md:grid-cols-4 lg:grid-cols-5",
|
|
631
|
+
children: [w.map((e) => /* @__PURE__ */ D(H, {
|
|
632
|
+
profile: e,
|
|
633
|
+
isActive: t === e.id,
|
|
634
|
+
manageMode: _,
|
|
635
|
+
onSelect: () => k(e),
|
|
636
|
+
onEdit: () => C({
|
|
637
|
+
kind: "edit",
|
|
638
|
+
profile: e
|
|
639
|
+
})
|
|
640
|
+
}, e.id)), T && /* @__PURE__ */ D(U, { onClick: () => C({ kind: "create" }) })]
|
|
641
|
+
}), /* @__PURE__ */ O("div", {
|
|
642
|
+
className: "flex min-h-full w-full flex-col items-center bg-bg-canvas px-4 py-10 sm:py-16",
|
|
643
|
+
children: [
|
|
644
|
+
/* @__PURE__ */ O("div", {
|
|
645
|
+
className: "mb-8 text-center sm:mb-12",
|
|
646
|
+
children: [/* @__PURE__ */ D("h1", {
|
|
647
|
+
className: "text-2xl font-semibold tracking-tight text-text-primary sm:text-4xl",
|
|
648
|
+
children: _ ? "Manage profiles" : "Who's watching?"
|
|
649
|
+
}), /* @__PURE__ */ D("p", {
|
|
650
|
+
className: "mt-2 text-sm text-text-secondary",
|
|
651
|
+
children: _ ? "Select a profile to edit its details and parental controls." : "Pick a profile to personalise your HookMovies experience."
|
|
652
|
+
})]
|
|
653
|
+
}),
|
|
654
|
+
/* @__PURE__ */ D("div", {
|
|
655
|
+
className: "w-full",
|
|
656
|
+
children: j
|
|
657
|
+
}),
|
|
658
|
+
!s && !f && w.length > 0 && /* @__PURE__ */ D("div", {
|
|
659
|
+
className: "mt-10 sm:mt-14",
|
|
660
|
+
children: /* @__PURE__ */ D("button", {
|
|
661
|
+
type: "button",
|
|
662
|
+
onClick: () => y((e) => !e),
|
|
663
|
+
className: _ ? R : z,
|
|
664
|
+
children: _ ? /* @__PURE__ */ O(E, { children: [/* @__PURE__ */ D(v, {
|
|
665
|
+
className: "h-4 w-4",
|
|
666
|
+
"aria-hidden": "true"
|
|
667
|
+
}), "Done"] }) : /* @__PURE__ */ O(E, { children: [/* @__PURE__ */ D(x, {
|
|
668
|
+
className: "h-4 w-4",
|
|
669
|
+
"aria-hidden": "true"
|
|
670
|
+
}), "Manage profiles"] })
|
|
671
|
+
})
|
|
672
|
+
}),
|
|
673
|
+
b?.kind === "create" && /* @__PURE__ */ D(W, {
|
|
674
|
+
profile: null,
|
|
675
|
+
onClose: () => C(null)
|
|
676
|
+
}),
|
|
677
|
+
b?.kind === "edit" && /* @__PURE__ */ D(W, {
|
|
678
|
+
profile: b.profile,
|
|
679
|
+
onClose: () => C(null),
|
|
680
|
+
onDelete: (e) => C({
|
|
681
|
+
kind: "delete",
|
|
682
|
+
profile: e
|
|
683
|
+
}),
|
|
684
|
+
isDeleting: g.isPending
|
|
685
|
+
}),
|
|
686
|
+
b?.kind === "delete" && /* @__PURE__ */ D(G, {
|
|
687
|
+
profile: b.profile,
|
|
688
|
+
isDeleting: g.isPending,
|
|
689
|
+
onCancel: () => C({
|
|
690
|
+
kind: "edit",
|
|
691
|
+
profile: b.profile
|
|
692
|
+
}),
|
|
693
|
+
onConfirm: () => void A(b.profile)
|
|
694
|
+
})
|
|
695
|
+
]
|
|
696
|
+
});
|
|
697
|
+
};
|
|
698
|
+
//#endregion
|
|
699
|
+
export { K as ProfilesPage };
|
|
700
|
+
|
|
701
|
+
//# sourceMappingURL=ProfilesPage.js.map
|