@stamprally/ui 0.13.0 → 0.15.0

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @stamprally/ui
1
+ # @stamprally/ui v0.15.0
2
2
 
3
3
  Participant-facing React components for `@stamprally/core`.
4
4
 
package/dist/index.cjs CHANGED
@@ -1,11 +1,79 @@
1
+ "use client";
1
2
  'use strict';
2
3
 
3
4
  var core = require('@stamprally/core');
4
5
  var react = require('react');
5
6
  var jsxRuntime = require('react/jsx-runtime');
6
7
 
7
- // src/index.tsx
8
- var label = (dictionary, locale, key, fallback) => dictionary?.[locale]?.[key] ?? fallback;
8
+ // src/locales/index.ts
9
+ var DEFAULT_UI_DICTIONARY = {
10
+ en: {
11
+ viewer: "Stamp rally",
12
+ stampSheet: "Stamp sheet",
13
+ progress: "Progress",
14
+ rewards: "Rewards",
15
+ externalReferences: "External references",
16
+ qrValue: "QR value",
17
+ qrPlaceholder: "Paste a QR value",
18
+ qrCamera: "QR camera",
19
+ scanQr: "Scan QR",
20
+ passcode: "Passcode",
21
+ proof: "Proof",
22
+ checkLocation: "Check location",
23
+ readNfc: "Read NFC",
24
+ checkIn: "Check in",
25
+ verifying: "Verifying\u2026",
26
+ verified: "Verified",
27
+ verificationFailed: "Verification failed.",
28
+ prerequisitesNotMet: "Complete the prerequisite spots before checking in.",
29
+ "status.locked": "\u{1F512} LOCKED",
30
+ "status.unclaimed": "UNCLAIMED",
31
+ "status.claimed": "CLAIMED",
32
+ "status.verifying": "VERIFYING",
33
+ "status.available": "AVAILABLE",
34
+ "status.consumed": "CONSUMED",
35
+ "status.expired": "EXPIRED",
36
+ "status.onlyAFewLeft": "Only a few left",
37
+ "reward.lowStock": "Only a few left",
38
+ "reward.remaining": "remaining",
39
+ "reward.sharedRemaining": "Overall remaining",
40
+ "reward.validUntil": "Valid until"
41
+ },
42
+ ja: {
43
+ viewer: "\u30B9\u30BF\u30F3\u30D7\u30E9\u30EA\u30FC",
44
+ stampSheet: "\u30B9\u30BF\u30F3\u30D7\u30B7\u30FC\u30C8",
45
+ progress: "\u9032\u6357",
46
+ rewards: "\u666F\u54C1",
47
+ externalReferences: "\u95A2\u9023\u30EA\u30F3\u30AF",
48
+ qrValue: "QR\u5024",
49
+ qrPlaceholder: "QR\u5024\u3092\u5165\u529B",
50
+ qrCamera: "QR\u30AB\u30E1\u30E9",
51
+ scanQr: "QR\u3092\u8AAD\u307F\u53D6\u308B",
52
+ passcode: "\u30D1\u30B9\u30B3\u30FC\u30C9",
53
+ proof: "\u8A3C\u660E\u60C5\u5831",
54
+ checkLocation: "\u4F4D\u7F6E\u60C5\u5831\u3092\u78BA\u8A8D",
55
+ readNfc: "NFC\u3092\u8AAD\u307F\u53D6\u308B",
56
+ checkIn: "\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3",
57
+ verifying: "\u78BA\u8A8D\u4E2D\u2026",
58
+ verified: "\u78BA\u8A8D\u6E08\u307F",
59
+ verificationFailed: "\u78BA\u8A8D\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002",
60
+ prerequisitesNotMet: "\u524D\u63D0\u30B9\u30DD\u30C3\u30C8\u3092\u30AF\u30EA\u30A2\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
61
+ "status.locked": "\u{1F512} \u30ED\u30C3\u30AF\u4E2D",
62
+ "status.unclaimed": "\u672A\u53D6\u5F97",
63
+ "status.claimed": "\u53D6\u5F97\u6E08\u307F",
64
+ "status.verifying": "\u78BA\u8A8D\u4E2D",
65
+ "status.available": "\u5229\u7528\u53EF\u80FD",
66
+ "status.consumed": "\u4F7F\u7528\u6E08\u307F",
67
+ "status.expired": "\u671F\u9650\u5207\u308C",
68
+ "status.onlyAFewLeft": "\u6B8B\u308A\u308F\u305A\u304B",
69
+ "reward.lowStock": "\u6B8B\u308A\u308F\u305A\u304B",
70
+ "reward.remaining": "\u6B8B\u308A",
71
+ "reward.sharedRemaining": "\u5168\u4F53\u3067\u6B8B\u308A",
72
+ "reward.validUntil": "\u6709\u52B9\u671F\u9650"
73
+ }
74
+ };
75
+ var UI_DICTIONARIES = DEFAULT_UI_DICTIONARY;
76
+ var label = (dictionary, locale, key, fallback) => dictionary?.[locale]?.[key] ?? DEFAULT_UI_DICTIONARY[locale]?.[key] ?? fallback;
9
77
  var join = (...names) => {
10
78
  const value = names.filter((name) => name !== void 0 && name !== "").join(" ");
11
79
  return value === "" ? void 0 : value;
@@ -180,6 +248,7 @@ function DefaultCondition({
180
248
  function DefaultRewardCard({
181
249
  reward,
182
250
  state,
251
+ inventory,
183
252
  locale,
184
253
  dictionary,
185
254
  onClaim,
@@ -187,12 +256,23 @@ function DefaultRewardCard({
187
256
  styles
188
257
  }) {
189
258
  const status = state?.status ?? "LOCKED";
190
- const remaining = reward.stockLimit === void 0 ? void 0 : Math.max(0, reward.stockLimit - (state?.redeemedCount ?? 0));
259
+ const configuredRemaining = inventory?.rewardRemaining?.[reward.id] ?? (reward.stockLimit === void 0 ? void 0 : Math.max(0, reward.stockLimit - (state?.redeemedCount ?? 0)));
260
+ const sharedRemaining = inventory?.sharedRemaining;
261
+ const unavailable = status !== "AVAILABLE" || onClaim === void 0 || sharedRemaining === 0 || configuredRemaining === 0;
191
262
  const expiry = reward.validUntil === void 0 ? void 0 : new Date(reward.validUntil);
192
263
  return /* @__PURE__ */ jsxRuntime.jsxs("article", { className: classNames?.reward, style: styles?.reward, children: [
193
264
  /* @__PURE__ */ jsxRuntime.jsx("h3", { children: core.resolveLocalizedText(reward.title, locale) }),
194
265
  reward.description !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { children: core.resolveLocalizedText(reward.description, locale) }),
195
- remaining !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { children: remaining <= 3 ? label(dictionary, locale, "reward.lowStock", "Only a few left") : `${remaining} ${label(dictionary, locale, "reward.remaining", "remaining")}` }),
266
+ sharedRemaining !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
267
+ label(dictionary, locale, "reward.sharedRemaining", "Overall remaining"),
268
+ ":",
269
+ " ",
270
+ sharedRemaining
271
+ ] }),
272
+ configuredRemaining !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
273
+ configuredRemaining <= 3 && /* @__PURE__ */ jsxRuntime.jsx("span", { children: label(dictionary, locale, "reward.lowStock", "Only a few left") }),
274
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: `${configuredRemaining} ${label(dictionary, locale, "reward.remaining", "remaining")}` })
275
+ ] }),
196
276
  expiry !== void 0 && !Number.isNaN(expiry.getTime()) && /* @__PURE__ */ jsxRuntime.jsxs("time", { dateTime: reward.validUntil, children: [
197
277
  label(dictionary, locale, "reward.validUntil", "Valid until"),
198
278
  ":",
@@ -205,7 +285,7 @@ function DefaultRewardCard({
205
285
  type: "button",
206
286
  className: join(classNames?.reward, classNames?.button),
207
287
  style: styles?.button,
208
- disabled: status !== "AVAILABLE" || onClaim === void 0,
288
+ disabled: unavailable,
209
289
  onClick: () => {
210
290
  if (onClaim !== void 0) void onClaim(reward.id);
211
291
  },
@@ -364,7 +444,7 @@ function RallyViewer({
364
444
  spot.externalReferences.length,
365
445
  ")"
366
446
  ] }),
367
- renderStatusBadge?.({ status }) ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: classNames.badge, style: styles.badge, children: status === "LOCKED" ? "\u{1F512} LOCKED" : status }),
447
+ renderStatusBadge?.({ status }) ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: classNames.badge, style: styles.badge, children: label(dictionary, locale, `status.${status.toLowerCase()}`, status) }),
368
448
  locked && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", children: label(
369
449
  dictionary,
370
450
  locale,
@@ -381,6 +461,7 @@ function RallyViewer({
381
461
  const props = {
382
462
  reward,
383
463
  state: currentState.rewards.find((item) => item.rewardId === reward.id),
464
+ ...currentState.inventory === void 0 ? {} : { inventory: currentState.inventory },
384
465
  locale,
385
466
  ...dictionary === void 0 ? {} : { dictionary },
386
467
  onClaim: claim
@@ -428,14 +509,13 @@ function StampSheet({
428
509
  ] }),
429
510
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: config.spots.map((spot) => {
430
511
  const status = core.evaluateSpotStatus(spot, currentState);
431
- const claimed = status === "CLAIMED";
432
512
  const props = {
433
513
  spot,
434
514
  state: currentState,
435
515
  status,
436
516
  locale,
437
517
  ...dictionary === void 0 ? {} : { dictionary },
438
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: classNames.slot, style: styles.slot, children: status === "LOCKED" ? "\u{1F512}" : claimed ? "\u2713" : "\u25CB" })
518
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: classNames.slot, style: styles.slot, children: status === "LOCKED" ? label(dictionary, locale, "status.locked", "\u{1F512} LOCKED") : status === "CLAIMED" ? label(dictionary, locale, "status.claimed", "CLAIMED") : label(dictionary, locale, "status.unclaimed", "UNCLAIMED") })
439
519
  };
440
520
  return /* @__PURE__ */ jsxRuntime.jsx(
441
521
  "div",
@@ -450,7 +530,7 @@ function StampSheet({
450
530
  " ",
451
531
  spot.description !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("small", { children: core.resolveLocalizedText(spot.description, locale) }),
452
532
  " ",
453
- renderStatusBadge?.({ status }) ?? (status === "LOCKED" ? "\u{1F512}" : claimed ? "\u2713" : "\u25CB")
533
+ renderStatusBadge?.({ status }) ?? label(dictionary, locale, `status.${status.toLowerCase()}`, status)
454
534
  ] })
455
535
  },
456
536
  spot.id
@@ -462,7 +542,9 @@ function StampSheet({
462
542
  );
463
543
  }
464
544
 
545
+ exports.DEFAULT_UI_DICTIONARY = DEFAULT_UI_DICTIONARY;
465
546
  exports.RallyViewer = RallyViewer;
466
547
  exports.StampSheet = StampSheet;
548
+ exports.UI_DICTIONARIES = UI_DICTIONARIES;
467
549
  //# sourceMappingURL=index.cjs.map
468
550
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"names":["useState","useRef","getCurrentGeoContext","readNfcContext","readQrContext","jsxs","Fragment","jsx","isQrSupported","isNfcSupported","resolveLocalizedText","useEffect","useMemo","calculateProgress","useCallback","evaluateSpotStatus","result"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n CheckInOptions,\n CheckInResult,\n ClaimOptions,\n ClaimResult,\n SpotStatus as CoreSpotStatus,\n LocaleDictionary,\n PublicCheckInCondition,\n PublicRallyConfig,\n PublicReward,\n PublicSpotItem,\n RallyConfig,\n RewardState,\n StampRallyClient,\n StampRallyProgress,\n StampRallyState,\n UserRallyState,\n} from \"@stamprally/core\";\nimport {\n calculateProgress,\n evaluateSpotStatus,\n getCurrentGeoContext,\n isNfcSupported,\n isQrSupported,\n readNfcContext,\n readQrContext,\n resolveLocalizedText,\n} from \"@stamprally/core\";\nimport {\n type ComponentType,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport type ViewerClassName =\n | \"root\"\n | \"header\"\n | \"card\"\n | \"condition\"\n | \"slot\"\n | \"badge\"\n | \"modal\"\n | \"button\"\n | \"action\"\n | \"feedback\"\n | \"reward\"\n | \"footer\";\nexport type ViewerStyle = CSSProperties & {\n readonly [key: `--${string}`]: string | number | undefined;\n};\nexport type ViewerStyles = Partial<Record<ViewerClassName, ViewerStyle>>;\nexport type ViewerClassNames = Partial<Record<ViewerClassName, string>>;\nexport type SpotStatus = CoreSpotStatus;\n\nexport interface ConditionRendererProps<TLocale extends string = string> {\n readonly spot: PublicSpotItem<TLocale>;\n readonly condition: PublicCheckInCondition;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly disabled: boolean;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n // biome-ignore lint/suspicious/noConfusingVoidType: custom renderers may fire-and-forget while built-ins await feedback.\n readonly onSubmit: (proof: unknown) => void | Promise<unknown>;\n}\nexport type ConditionRenderer<TLocale extends string = string> = ComponentType<\n ConditionRendererProps<TLocale>\n>;\n\nexport interface SpotCardProps<TLocale extends string = string> {\n readonly spot: PublicSpotItem<TLocale>;\n readonly state: UserRallyState;\n readonly status: SpotStatus;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly children: ReactNode;\n}\nexport interface RewardCardProps<TLocale extends string = string> {\n readonly reward: PublicReward<TLocale>;\n readonly state: RewardState | undefined;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly onClaim:\n | ((rewardId: string, options?: ClaimOptions) => Promise<ClaimResult>)\n | undefined;\n}\nexport interface RallyViewerSlots<TLocale extends string = string> {\n readonly headerSlot?:\n | ReactNode\n | ((props: {\n readonly config: PublicRallyConfig<TLocale>;\n readonly state: UserRallyState;\n }) => ReactNode);\n readonly footerSlot?: ReactNode;\n readonly renderSpotCard?: (props: SpotCardProps<TLocale>) => ReactNode;\n readonly renderRewardCard?: (props: RewardCardProps<TLocale>) => ReactNode;\n readonly renderStatusBadge?: (props: { readonly status: SpotStatus }) => ReactNode;\n readonly renderVerifyingState?: () => ReactNode;\n readonly renderSuccessFeedback?: (result: CheckInResult) => ReactNode;\n readonly renderErrorFeedback?: (error: string) => ReactNode;\n}\n\nexport interface RallyViewerAdapter<TLocale extends string = string> {\n readonly config: PublicRallyConfig<TLocale>;\n readonly onCheckIn: (\n spotId: string,\n proof: unknown,\n options?: CheckInOptions,\n ) => Promise<CheckInResult>;\n readonly onClaimReward?: (rewardId: string, options?: ClaimOptions) => Promise<ClaimResult>;\n}\nexport interface RallyViewerProps<TLocale extends string = string>\n extends RallyViewerSlots<TLocale> {\n readonly config?: PublicRallyConfig<TLocale>;\n readonly client?: StampRallyClient;\n readonly adapter?: RallyViewerAdapter<TLocale>;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n readonly style?: ViewerStyle;\n readonly customConditionRenderers?: Partial<\n Record<PublicCheckInCondition[\"type\"], ConditionRenderer<TLocale>>\n >;\n}\n\nconst label = <TLocale extends string>(\n dictionary: LocaleDictionary<TLocale> | undefined,\n locale: TLocale,\n key: string,\n fallback: string,\n): string => dictionary?.[locale]?.[key] ?? fallback;\nconst join = (...names: ReadonlyArray<string | undefined>): string | undefined => {\n const value = names.filter((name): name is string => name !== undefined && name !== \"\").join(\" \");\n return value === \"\" ? undefined : value;\n};\ntype VerificationStatus = \"idle\" | \"loading\" | \"success\" | \"error\";\n\nfunction DefaultCondition<TLocale extends string>({\n condition,\n dictionary,\n locale,\n disabled,\n classNames,\n styles,\n onSubmit,\n}: ConditionRendererProps<TLocale>): ReactElement {\n const [value, setValue] = useState(\"\");\n const [status, setStatus] = useState<VerificationStatus>(\"idle\");\n const [error, setError] = useState<string | null>(null);\n const videoRef = useRef<HTMLVideoElement>(null);\n const text = (key: string, fallback: string): string => label(dictionary, locale, key, fallback);\n const verify = async (proof: unknown): Promise<void> => {\n setStatus(\"loading\");\n setError(null);\n try {\n const result = await onSubmit(proof);\n if (\n result !== undefined &&\n typeof result === \"object\" &&\n result !== null &&\n \"ok\" in result &&\n result.ok === false\n ) {\n setStatus(\"error\");\n setError(text(\"verificationFailed\", \"Verification failed.\"));\n } else setStatus(\"success\");\n } catch {\n setStatus(\"error\");\n setError(text(\"verificationFailed\", \"Verification failed.\"));\n }\n };\n const readLocation = (): void => {\n setStatus(\"loading\");\n void getCurrentGeoContext().then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n const readNfc = (): void => {\n setStatus(\"loading\");\n void readNfcContext().then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n const scanQr = (): void => {\n if (videoRef.current === null) return;\n setStatus(\"loading\");\n void readQrContext(videoRef.current).then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n return (\n <div>\n {condition.type === \"qr\" && (\n <>\n <label>\n {text(\"qrValue\", \"QR value\")}\n <input\n aria-label={text(\"qrValue\", \"QR value\")}\n placeholder={condition.qrEntryUrl ?? text(\"qrPlaceholder\", \"Paste a QR value\")}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n />\n </label>\n <video\n ref={videoRef}\n aria-label={text(\"qrCamera\", \"QR camera\")}\n hidden={!isQrSupported()}\n >\n <track kind=\"captions\" />\n </video>\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || !isQrSupported()}\n onClick={scanQr}\n >\n {text(\"scanQr\", \"Scan QR\")}\n </button>\n </>\n )}\n {condition.type === \"gps\" && (\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled}\n onClick={readLocation}\n >\n {text(\"checkLocation\", \"Check location\")}\n </button>\n )}\n {condition.type === \"nfc\" && (\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || !isNfcSupported()}\n onClick={readNfc}\n >\n {text(\"readNfc\", \"Read NFC\")}\n </button>\n )}\n {(condition.type === \"passcode\" ||\n condition.type === \"custom\" ||\n condition.type === \"qr\") && (\n <form\n onSubmit={(event) => {\n event.preventDefault();\n void verify(value);\n }}\n >\n <label>\n {text(\n condition.type === \"passcode\" ? \"passcode\" : \"proof\",\n condition.type === \"passcode\" ? \"Passcode\" : \"Proof\",\n )}\n <input\n aria-label={text(\"proof\", \"Proof\")}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n />\n </label>\n <button\n type=\"submit\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || value.trim() === \"\"}\n >\n {text(\"checkIn\", \"Check in\")}\n </button>\n </form>\n )}\n <div\n className={join(\"sry-feedback\", classNames?.feedback)}\n style={styles?.feedback}\n aria-live=\"polite\"\n role={status === \"error\" ? \"alert\" : undefined}\n >\n {status === \"loading\" && text(\"verifying\", \"Verifying…\")}\n {status === \"success\" && text(\"verified\", \"Verified\")}\n {status === \"error\" && (error ?? text(\"verificationFailed\", \"Verification failed.\"))}\n </div>\n </div>\n );\n}\n\nfunction DefaultRewardCard<TLocale extends string>({\n reward,\n state,\n locale,\n dictionary,\n onClaim,\n classNames,\n styles,\n}: RewardCardProps<TLocale> & {\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n}): ReactElement {\n const status = state?.status ?? \"LOCKED\";\n const remaining =\n reward.stockLimit === undefined\n ? undefined\n : Math.max(0, reward.stockLimit - (state?.redeemedCount ?? 0));\n const expiry = reward.validUntil === undefined ? undefined : new Date(reward.validUntil);\n return (\n <article className={classNames?.reward} style={styles?.reward}>\n <h3>{resolveLocalizedText(reward.title, locale)}</h3>\n {reward.description !== undefined && (\n <p>{resolveLocalizedText(reward.description, locale)}</p>\n )}\n {remaining !== undefined && (\n <span>\n {remaining <= 3\n ? label(dictionary, locale, \"reward.lowStock\", \"Only a few left\")\n : `${remaining} ${label(dictionary, locale, \"reward.remaining\", \"remaining\")}`}\n </span>\n )}\n {expiry !== undefined && !Number.isNaN(expiry.getTime()) && (\n <time dateTime={reward.validUntil}>\n {label(dictionary, locale, \"reward.validUntil\", \"Valid until\")}:{\" \"}\n {expiry.toLocaleString(locale)}\n </time>\n )}\n <button\n type=\"button\"\n className={join(classNames?.reward, classNames?.button)}\n style={styles?.button}\n disabled={status !== \"AVAILABLE\" || onClaim === undefined}\n onClick={() => {\n if (onClaim !== undefined) void onClaim(reward.id);\n }}\n >\n {label(dictionary, locale, `status.${status.toLowerCase()}`, status)}\n </button>\n </article>\n );\n}\n\nexport function RallyViewer<TLocale extends string = string>({\n config: providedConfig,\n client,\n adapter,\n locale,\n dictionary,\n classNames = {},\n styles = {},\n style,\n customConditionRenderers = {},\n headerSlot,\n footerSlot,\n renderSpotCard,\n renderRewardCard,\n renderStatusBadge,\n renderVerifyingState,\n renderSuccessFeedback,\n renderErrorFeedback,\n}: RallyViewerProps<TLocale>): ReactElement {\n const config = providedConfig ?? client?.getConfig() ?? adapter?.config;\n const [state, setState] = useState<UserRallyState | null>(() => client?.getState() ?? null);\n const [busy, setBusy] = useState<string | null>(null);\n const [feedback, setFeedback] = useState<CheckInResult | null>(null);\n useEffect(() => {\n if (client === undefined) return;\n const unsubscribe = client.subscribe(setState);\n void client.init().then(setState);\n return unsubscribe;\n }, [client]);\n if (config === undefined) throw new Error(\"RallyViewer requires config, client, or adapter.\");\n const currentState = state ?? {\n rallyId: config.id,\n userId: null,\n records: [],\n rewards: [],\n updatedAt: \"\",\n };\n const progress = useMemo<StampRallyProgress>(\n () => calculateProgress(currentState, config),\n [config, currentState],\n );\n const checkIn =\n adapter?.onCheckIn ??\n (client === undefined\n ? undefined\n : (spotId: string, proof: unknown, options?: CheckInOptions) =>\n client.checkIn(spotId, proof, options));\n const claim =\n adapter?.onClaimReward ??\n (client === undefined\n ? undefined\n : (rewardId: string, options?: ClaimOptions) => client.claimReward(rewardId, options));\n const submit = useCallback(\n async (spotId: string, proof: unknown): Promise<CheckInResult | undefined> => {\n if (checkIn === undefined) return undefined;\n const target = config.spots.find((spot) => spot.id === spotId);\n if (target !== undefined && evaluateSpotStatus(target, currentState) === \"LOCKED\") {\n const result: CheckInResult = {\n ok: false,\n error: {\n code: \"PREREQUISITES_NOT_MET\",\n spotId,\n message: \"Complete the prerequisite spots before checking in.\",\n },\n };\n setFeedback(result);\n return result;\n }\n setBusy(spotId);\n const result = await checkIn(spotId, proof).finally(() => setBusy(null));\n setFeedback(result);\n return result;\n },\n [checkIn, config.spots, currentState],\n );\n return (\n <section\n className={classNames.root}\n style={styles.root ?? style}\n aria-label={label(dictionary, locale, \"viewer\", \"Stamp rally\")}\n >\n <header className={classNames.header} style={styles.header}>\n {typeof headerSlot === \"function\"\n ? headerSlot({ config, state: currentState })\n : headerSlot}\n {headerSlot === undefined && (\n <h1>{resolveLocalizedText(config.title, locale) || config.id}</h1>\n )}\n <progress\n aria-label={label(dictionary, locale, \"progress\", \"Progress\")}\n max={100}\n value={progress.percentage}\n />\n <span>\n {progress.acquired}/{progress.total}\n </span>\n </header>\n {busy !== null &&\n (renderVerifyingState?.() ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"status\">\n {label(dictionary, locale, \"verifying\", \"Verifying…\")}\n </div>\n ))}\n {feedback?.ok === true &&\n (renderSuccessFeedback?.(feedback) ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"status\">\n {label(dictionary, locale, \"verified\", \"Verified\")}\n </div>\n ))}\n {feedback?.ok === false &&\n (renderErrorFeedback?.(\n \"message\" in feedback.error ? feedback.error.message : feedback.error.code,\n ) ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"alert\">\n {\"message\" in feedback.error ? feedback.error.message : feedback.error.code}\n </div>\n ))}\n <div>\n {config.spots.map((spot) => {\n const status: SpotStatus =\n busy === spot.id ? \"VERIFYING\" : evaluateSpotStatus(spot, currentState);\n const claimed = status === \"CLAIMED\";\n const locked = status === \"LOCKED\";\n const children = spot.conditions.map((condition) => {\n const Renderer = customConditionRenderers[condition.type] ?? DefaultCondition;\n return (\n <div\n className={classNames.condition}\n style={styles.condition}\n key={`${spot.id}-${condition.type}-${JSON.stringify(condition)}`}\n >\n <Renderer\n spot={spot}\n condition={condition}\n locale={locale}\n {...(dictionary === undefined ? {} : { dictionary })}\n disabled={busy !== null || claimed || locked}\n {...(Object.keys(classNames).length === 0 ? {} : { classNames })}\n {...(Object.keys(styles).length === 0 ? {} : { styles })}\n onSubmit={(proof) => submit(spot.id, proof)}\n />\n </div>\n );\n });\n const props: SpotCardProps<TLocale> = {\n spot,\n state: currentState,\n status,\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n children,\n };\n return (\n <div\n key={spot.id}\n className={classNames.card}\n style={styles.card}\n data-status={status}\n aria-disabled={locked}\n >\n {renderSpotCard?.(props) ?? (\n <article>\n {spot.iconUrl !== undefined && (\n <img src={spot.iconUrl} alt=\"\" width={32} height={32} />\n )}\n <h2>{resolveLocalizedText(spot.name, locale)}</h2>\n {spot.imageUrl !== undefined && <img src={spot.imageUrl} alt=\"\" loading=\"lazy\" />}\n {spot.description !== undefined && (\n <p>{resolveLocalizedText(spot.description, locale)}</p>\n )}\n {spot.hint !== undefined && <p>{resolveLocalizedText(spot.hint, locale)}</p>}\n {spot.externalReferences !== undefined && spot.externalReferences.length > 0 && (\n <span className={classNames.badge} style={styles.badge}>\n {label(dictionary, locale, \"externalReferences\", \"External references\")} (\n {spot.externalReferences.length})\n </span>\n )}\n {renderStatusBadge?.({ status }) ?? (\n <span className={classNames.badge} style={styles.badge}>\n {status === \"LOCKED\" ? \"🔒 LOCKED\" : status}\n </span>\n )}\n {locked && (\n <p role=\"status\">\n {label(\n dictionary,\n locale,\n \"prerequisitesNotMet\",\n \"Complete the prerequisite spots before checking in.\",\n )}\n </p>\n )}\n {children}\n </article>\n )}\n </div>\n );\n })}\n </div>\n <section aria-label={label(dictionary, locale, \"rewards\", \"Rewards\")}>\n {config.rewards.map((reward) => {\n const props: RewardCardProps<TLocale> = {\n reward,\n state: currentState.rewards.find((item) => item.rewardId === reward.id),\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n onClaim: claim,\n };\n return (\n <div key={reward.id} className={classNames.reward} style={styles.reward}>\n {renderRewardCard?.(props) ?? (\n <DefaultRewardCard {...props} classNames={classNames} styles={styles} />\n )}\n </div>\n );\n })}\n </section>\n <footer className={classNames.footer} style={styles.footer}>\n {footerSlot}\n </footer>\n </section>\n );\n}\n\nexport interface StampSheetProps<TLocale extends string = string>\n extends RallyViewerSlots<TLocale> {\n readonly config: RallyConfig<TLocale>;\n readonly state?: StampRallyState | null;\n readonly title?: string;\n readonly progress?: StampRallyProgress;\n readonly locale?: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n readonly style?: ViewerStyle;\n}\nexport function StampSheet<TLocale extends string = string>({\n config,\n state,\n title,\n progress,\n locale = \"en\" as TLocale,\n dictionary,\n classNames = {},\n styles = {},\n style,\n headerSlot,\n footerSlot,\n renderSpotCard,\n renderStatusBadge,\n}: StampSheetProps<TLocale>): ReactElement {\n const currentState = state ?? {\n rallyId: config.id,\n userId: null,\n records: [],\n rewards: [],\n updatedAt: \"\",\n };\n const current = progress ?? calculateProgress(currentState, config);\n return (\n <section\n className={classNames.root}\n style={styles.root ?? style}\n aria-label={title ?? label(dictionary, locale, \"stampSheet\", \"Stamp sheet\")}\n >\n <header className={classNames.header} style={styles.header}>\n {typeof headerSlot === \"function\"\n ? headerSlot({ config, state: currentState })\n : (headerSlot ?? <h2>{title ?? resolveLocalizedText(config.title, locale)}</h2>)}\n <progress max={100} value={current.percentage} />\n </header>\n <div>\n {config.spots.map((spot) => {\n const status: SpotStatus = evaluateSpotStatus(spot, currentState);\n const claimed = status === \"CLAIMED\";\n const props: SpotCardProps<TLocale> = {\n spot,\n state: currentState,\n status,\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n children: (\n <span className={classNames.slot} style={styles.slot}>\n {status === \"LOCKED\" ? \"🔒\" : claimed ? \"✓\" : \"○\"}\n </span>\n ),\n };\n return (\n <div\n key={spot.id}\n className={classNames.card}\n style={styles.card}\n data-status={status}\n aria-disabled={status === \"LOCKED\"}\n >\n {renderSpotCard?.(props) ?? (\n <span className={classNames.slot} style={styles.slot}>\n {spot.iconUrl !== undefined && (\n <img src={spot.iconUrl} alt=\"\" width={24} height={24} />\n )}\n {resolveLocalizedText(spot.name, locale)}{\" \"}\n {spot.description !== undefined && (\n <small>{resolveLocalizedText(spot.description, locale)}</small>\n )}{\" \"}\n {renderStatusBadge?.({ status }) ??\n (status === \"LOCKED\" ? \"🔒\" : claimed ? \"✓\" : \"○\")}\n </span>\n )}\n </div>\n );\n })}\n </div>\n <footer className={classNames.footer} style={styles.footer}>\n {footerSlot}\n </footer>\n </section>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/locales/index.ts","../src/index.tsx"],"names":["useState","useRef","getCurrentGeoContext","readNfcContext","readQrContext","jsxs","Fragment","jsx","isQrSupported","isNfcSupported","resolveLocalizedText","useEffect","useMemo","calculateProgress","useCallback","evaluateSpotStatus","result"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { LocaleDictionary } from \"@stamprally/core\";\n\n/** Complete built-in labels for the standard participant components. */\nexport const DEFAULT_UI_DICTIONARY: LocaleDictionary<\"ja\" | \"en\"> = {\n en: {\n viewer: \"Stamp rally\",\n stampSheet: \"Stamp sheet\",\n progress: \"Progress\",\n rewards: \"Rewards\",\n externalReferences: \"External references\",\n qrValue: \"QR value\",\n qrPlaceholder: \"Paste a QR value\",\n qrCamera: \"QR camera\",\n scanQr: \"Scan QR\",\n passcode: \"Passcode\",\n proof: \"Proof\",\n checkLocation: \"Check location\",\n readNfc: \"Read NFC\",\n checkIn: \"Check in\",\n verifying: \"Verifying…\",\n verified: \"Verified\",\n verificationFailed: \"Verification failed.\",\n prerequisitesNotMet: \"Complete the prerequisite spots before checking in.\",\n \"status.locked\": \"🔒 LOCKED\",\n \"status.unclaimed\": \"UNCLAIMED\",\n \"status.claimed\": \"CLAIMED\",\n \"status.verifying\": \"VERIFYING\",\n \"status.available\": \"AVAILABLE\",\n \"status.consumed\": \"CONSUMED\",\n \"status.expired\": \"EXPIRED\",\n \"status.onlyAFewLeft\": \"Only a few left\",\n \"reward.lowStock\": \"Only a few left\",\n \"reward.remaining\": \"remaining\",\n \"reward.sharedRemaining\": \"Overall remaining\",\n \"reward.validUntil\": \"Valid until\",\n },\n ja: {\n viewer: \"スタンプラリー\",\n stampSheet: \"スタンプシート\",\n progress: \"進捗\",\n rewards: \"景品\",\n externalReferences: \"関連リンク\",\n qrValue: \"QR値\",\n qrPlaceholder: \"QR値を入力\",\n qrCamera: \"QRカメラ\",\n scanQr: \"QRを読み取る\",\n passcode: \"パスコード\",\n proof: \"証明情報\",\n checkLocation: \"位置情報を確認\",\n readNfc: \"NFCを読み取る\",\n checkIn: \"チェックイン\",\n verifying: \"確認中…\",\n verified: \"確認済み\",\n verificationFailed: \"確認に失敗しました。\",\n prerequisitesNotMet: \"前提スポットをクリアしてください。\",\n \"status.locked\": \"🔒 ロック中\",\n \"status.unclaimed\": \"未取得\",\n \"status.claimed\": \"取得済み\",\n \"status.verifying\": \"確認中\",\n \"status.available\": \"利用可能\",\n \"status.consumed\": \"使用済み\",\n \"status.expired\": \"期限切れ\",\n \"status.onlyAFewLeft\": \"残りわずか\",\n \"reward.lowStock\": \"残りわずか\",\n \"reward.remaining\": \"残り\",\n \"reward.sharedRemaining\": \"全体で残り\",\n \"reward.validUntil\": \"有効期限\",\n },\n};\n\nexport const UI_DICTIONARIES = DEFAULT_UI_DICTIONARY;\n","\"use client\";\n\nimport type {\n CheckInOptions,\n CheckInResult,\n ClaimOptions,\n ClaimResult,\n SpotStatus as CoreSpotStatus,\n LocaleDictionary,\n PublicCheckInCondition,\n PublicRallyConfig,\n PublicReward,\n PublicSpotItem,\n RallyConfig,\n RallyInventoryState,\n RewardState,\n StampRallyClient,\n StampRallyProgress,\n StampRallyState,\n UserRallyState,\n} from \"@stamprally/core\";\nimport { DEFAULT_UI_DICTIONARY } from \"./locales/index.js\";\n\nexport { DEFAULT_UI_DICTIONARY, UI_DICTIONARIES } from \"./locales/index.js\";\n\nimport {\n calculateProgress,\n evaluateSpotStatus,\n getCurrentGeoContext,\n isNfcSupported,\n isQrSupported,\n readNfcContext,\n readQrContext,\n resolveLocalizedText,\n} from \"@stamprally/core\";\nimport {\n type ComponentType,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport type ViewerClassName =\n | \"root\"\n | \"header\"\n | \"card\"\n | \"condition\"\n | \"slot\"\n | \"badge\"\n | \"modal\"\n | \"button\"\n | \"action\"\n | \"feedback\"\n | \"reward\"\n | \"footer\";\nexport type ViewerStyle = CSSProperties & {\n readonly [key: `--${string}`]: string | number | undefined;\n};\nexport type ViewerStyles = Partial<Record<ViewerClassName, ViewerStyle>>;\nexport type ViewerClassNames = Partial<Record<ViewerClassName, string>>;\nexport type SpotStatus = CoreSpotStatus;\n\nexport interface ConditionRendererProps<TLocale extends string = string> {\n readonly spot: PublicSpotItem<TLocale>;\n readonly condition: PublicCheckInCondition;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly disabled: boolean;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n // biome-ignore lint/suspicious/noConfusingVoidType: custom renderers may fire-and-forget while built-ins await feedback.\n readonly onSubmit: (proof: unknown) => void | Promise<unknown>;\n}\nexport type ConditionRenderer<TLocale extends string = string> = ComponentType<\n ConditionRendererProps<TLocale>\n>;\n\nexport interface SpotCardProps<TLocale extends string = string> {\n readonly spot: PublicSpotItem<TLocale>;\n readonly state: UserRallyState;\n readonly status: SpotStatus;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly children: ReactNode;\n}\nexport interface RewardCardProps<TLocale extends string = string> {\n readonly reward: PublicReward<TLocale>;\n readonly state: RewardState | undefined;\n readonly inventory?: RallyInventoryState;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly onClaim:\n | ((rewardId: string, options?: ClaimOptions) => Promise<ClaimResult>)\n | undefined;\n}\nexport interface RallyViewerSlots<TLocale extends string = string> {\n readonly headerSlot?:\n | ReactNode\n | ((props: {\n readonly config: PublicRallyConfig<TLocale>;\n readonly state: UserRallyState;\n }) => ReactNode);\n readonly footerSlot?: ReactNode;\n readonly renderSpotCard?: (props: SpotCardProps<TLocale>) => ReactNode;\n readonly renderRewardCard?: (props: RewardCardProps<TLocale>) => ReactNode;\n readonly renderStatusBadge?: (props: { readonly status: SpotStatus }) => ReactNode;\n readonly renderVerifyingState?: () => ReactNode;\n readonly renderSuccessFeedback?: (result: CheckInResult) => ReactNode;\n readonly renderErrorFeedback?: (error: string) => ReactNode;\n}\n\nexport interface RallyViewerAdapter<TLocale extends string = string> {\n readonly config: PublicRallyConfig<TLocale>;\n readonly onCheckIn: (\n spotId: string,\n proof: unknown,\n options?: CheckInOptions,\n ) => Promise<CheckInResult>;\n readonly onClaimReward?: (rewardId: string, options?: ClaimOptions) => Promise<ClaimResult>;\n}\nexport interface RallyViewerProps<TLocale extends string = string>\n extends RallyViewerSlots<TLocale> {\n readonly config?: PublicRallyConfig<TLocale>;\n readonly client?: StampRallyClient;\n readonly adapter?: RallyViewerAdapter<TLocale>;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n readonly style?: ViewerStyle;\n readonly customConditionRenderers?: Partial<\n Record<PublicCheckInCondition[\"type\"], ConditionRenderer<TLocale>>\n >;\n}\n\nconst label = <TLocale extends string>(\n dictionary: LocaleDictionary<TLocale> | undefined,\n locale: TLocale,\n key: string,\n fallback: string,\n): string =>\n dictionary?.[locale]?.[key] ?? DEFAULT_UI_DICTIONARY[locale as \"ja\" | \"en\"]?.[key] ?? fallback;\nconst join = (...names: ReadonlyArray<string | undefined>): string | undefined => {\n const value = names.filter((name): name is string => name !== undefined && name !== \"\").join(\" \");\n return value === \"\" ? undefined : value;\n};\ntype VerificationStatus = \"idle\" | \"loading\" | \"success\" | \"error\";\n\nfunction DefaultCondition<TLocale extends string>({\n condition,\n dictionary,\n locale,\n disabled,\n classNames,\n styles,\n onSubmit,\n}: ConditionRendererProps<TLocale>): ReactElement {\n const [value, setValue] = useState(\"\");\n const [status, setStatus] = useState<VerificationStatus>(\"idle\");\n const [error, setError] = useState<string | null>(null);\n const videoRef = useRef<HTMLVideoElement>(null);\n const text = (key: string, fallback: string): string => label(dictionary, locale, key, fallback);\n const verify = async (proof: unknown): Promise<void> => {\n setStatus(\"loading\");\n setError(null);\n try {\n const result = await onSubmit(proof);\n if (\n result !== undefined &&\n typeof result === \"object\" &&\n result !== null &&\n \"ok\" in result &&\n result.ok === false\n ) {\n setStatus(\"error\");\n setError(text(\"verificationFailed\", \"Verification failed.\"));\n } else setStatus(\"success\");\n } catch {\n setStatus(\"error\");\n setError(text(\"verificationFailed\", \"Verification failed.\"));\n }\n };\n const readLocation = (): void => {\n setStatus(\"loading\");\n void getCurrentGeoContext().then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n const readNfc = (): void => {\n setStatus(\"loading\");\n void readNfcContext().then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n const scanQr = (): void => {\n if (videoRef.current === null) return;\n setStatus(\"loading\");\n void readQrContext(videoRef.current).then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n return (\n <div>\n {condition.type === \"qr\" && (\n <>\n <label>\n {text(\"qrValue\", \"QR value\")}\n <input\n aria-label={text(\"qrValue\", \"QR value\")}\n placeholder={condition.qrEntryUrl ?? text(\"qrPlaceholder\", \"Paste a QR value\")}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n />\n </label>\n <video\n ref={videoRef}\n aria-label={text(\"qrCamera\", \"QR camera\")}\n hidden={!isQrSupported()}\n >\n <track kind=\"captions\" />\n </video>\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || !isQrSupported()}\n onClick={scanQr}\n >\n {text(\"scanQr\", \"Scan QR\")}\n </button>\n </>\n )}\n {condition.type === \"gps\" && (\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled}\n onClick={readLocation}\n >\n {text(\"checkLocation\", \"Check location\")}\n </button>\n )}\n {condition.type === \"nfc\" && (\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || !isNfcSupported()}\n onClick={readNfc}\n >\n {text(\"readNfc\", \"Read NFC\")}\n </button>\n )}\n {(condition.type === \"passcode\" ||\n condition.type === \"custom\" ||\n condition.type === \"qr\") && (\n <form\n onSubmit={(event) => {\n event.preventDefault();\n void verify(value);\n }}\n >\n <label>\n {text(\n condition.type === \"passcode\" ? \"passcode\" : \"proof\",\n condition.type === \"passcode\" ? \"Passcode\" : \"Proof\",\n )}\n <input\n aria-label={text(\"proof\", \"Proof\")}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n />\n </label>\n <button\n type=\"submit\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || value.trim() === \"\"}\n >\n {text(\"checkIn\", \"Check in\")}\n </button>\n </form>\n )}\n <div\n className={join(\"sry-feedback\", classNames?.feedback)}\n style={styles?.feedback}\n aria-live=\"polite\"\n role={status === \"error\" ? \"alert\" : undefined}\n >\n {status === \"loading\" && text(\"verifying\", \"Verifying…\")}\n {status === \"success\" && text(\"verified\", \"Verified\")}\n {status === \"error\" && (error ?? text(\"verificationFailed\", \"Verification failed.\"))}\n </div>\n </div>\n );\n}\n\nfunction DefaultRewardCard<TLocale extends string>({\n reward,\n state,\n inventory,\n locale,\n dictionary,\n onClaim,\n classNames,\n styles,\n}: RewardCardProps<TLocale> & {\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n}): ReactElement {\n const status = state?.status ?? \"LOCKED\";\n const configuredRemaining =\n inventory?.rewardRemaining?.[reward.id] ??\n (reward.stockLimit === undefined\n ? undefined\n : Math.max(0, reward.stockLimit - (state?.redeemedCount ?? 0)));\n const sharedRemaining = inventory?.sharedRemaining;\n const unavailable =\n status !== \"AVAILABLE\" ||\n onClaim === undefined ||\n sharedRemaining === 0 ||\n configuredRemaining === 0;\n const expiry = reward.validUntil === undefined ? undefined : new Date(reward.validUntil);\n return (\n <article className={classNames?.reward} style={styles?.reward}>\n <h3>{resolveLocalizedText(reward.title, locale)}</h3>\n {reward.description !== undefined && (\n <p>{resolveLocalizedText(reward.description, locale)}</p>\n )}\n {sharedRemaining !== undefined && (\n <span>\n {label(dictionary, locale, \"reward.sharedRemaining\", \"Overall remaining\")}:{\" \"}\n {sharedRemaining}\n </span>\n )}\n {configuredRemaining !== undefined && (\n <>\n {configuredRemaining <= 3 && (\n <span>{label(dictionary, locale, \"reward.lowStock\", \"Only a few left\")}</span>\n )}\n <span>\n {`${configuredRemaining} ${label(dictionary, locale, \"reward.remaining\", \"remaining\")}`}\n </span>\n </>\n )}\n {expiry !== undefined && !Number.isNaN(expiry.getTime()) && (\n <time dateTime={reward.validUntil}>\n {label(dictionary, locale, \"reward.validUntil\", \"Valid until\")}:{\" \"}\n {expiry.toLocaleString(locale)}\n </time>\n )}\n <button\n type=\"button\"\n className={join(classNames?.reward, classNames?.button)}\n style={styles?.button}\n disabled={unavailable}\n onClick={() => {\n if (onClaim !== undefined) void onClaim(reward.id);\n }}\n >\n {label(dictionary, locale, `status.${status.toLowerCase()}`, status)}\n </button>\n </article>\n );\n}\n\nexport function RallyViewer<TLocale extends string = string>({\n config: providedConfig,\n client,\n adapter,\n locale,\n dictionary,\n classNames = {},\n styles = {},\n style,\n customConditionRenderers = {},\n headerSlot,\n footerSlot,\n renderSpotCard,\n renderRewardCard,\n renderStatusBadge,\n renderVerifyingState,\n renderSuccessFeedback,\n renderErrorFeedback,\n}: RallyViewerProps<TLocale>): ReactElement {\n const config = providedConfig ?? client?.getConfig() ?? adapter?.config;\n const [state, setState] = useState<UserRallyState | null>(() => client?.getState() ?? null);\n const [busy, setBusy] = useState<string | null>(null);\n const [feedback, setFeedback] = useState<CheckInResult | null>(null);\n useEffect(() => {\n if (client === undefined) return;\n const unsubscribe = client.subscribe(setState);\n void client.init().then(setState);\n return unsubscribe;\n }, [client]);\n if (config === undefined) throw new Error(\"RallyViewer requires config, client, or adapter.\");\n const currentState = state ?? {\n rallyId: config.id,\n userId: null,\n records: [],\n rewards: [],\n updatedAt: \"\",\n };\n const progress = useMemo<StampRallyProgress>(\n () => calculateProgress(currentState, config),\n [config, currentState],\n );\n const checkIn =\n adapter?.onCheckIn ??\n (client === undefined\n ? undefined\n : (spotId: string, proof: unknown, options?: CheckInOptions) =>\n client.checkIn(spotId, proof, options));\n const claim =\n adapter?.onClaimReward ??\n (client === undefined\n ? undefined\n : (rewardId: string, options?: ClaimOptions) => client.claimReward(rewardId, options));\n const submit = useCallback(\n async (spotId: string, proof: unknown): Promise<CheckInResult | undefined> => {\n if (checkIn === undefined) return undefined;\n const target = config.spots.find((spot) => spot.id === spotId);\n if (target !== undefined && evaluateSpotStatus(target, currentState) === \"LOCKED\") {\n const result: CheckInResult = {\n ok: false,\n error: {\n code: \"PREREQUISITES_NOT_MET\",\n spotId,\n message: \"Complete the prerequisite spots before checking in.\",\n },\n };\n setFeedback(result);\n return result;\n }\n setBusy(spotId);\n const result = await checkIn(spotId, proof).finally(() => setBusy(null));\n setFeedback(result);\n return result;\n },\n [checkIn, config.spots, currentState],\n );\n return (\n <section\n className={classNames.root}\n style={styles.root ?? style}\n aria-label={label(dictionary, locale, \"viewer\", \"Stamp rally\")}\n >\n <header className={classNames.header} style={styles.header}>\n {typeof headerSlot === \"function\"\n ? headerSlot({ config, state: currentState })\n : headerSlot}\n {headerSlot === undefined && (\n <h1>{resolveLocalizedText(config.title, locale) || config.id}</h1>\n )}\n <progress\n aria-label={label(dictionary, locale, \"progress\", \"Progress\")}\n max={100}\n value={progress.percentage}\n />\n <span>\n {progress.acquired}/{progress.total}\n </span>\n </header>\n {busy !== null &&\n (renderVerifyingState?.() ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"status\">\n {label(dictionary, locale, \"verifying\", \"Verifying…\")}\n </div>\n ))}\n {feedback?.ok === true &&\n (renderSuccessFeedback?.(feedback) ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"status\">\n {label(dictionary, locale, \"verified\", \"Verified\")}\n </div>\n ))}\n {feedback?.ok === false &&\n (renderErrorFeedback?.(\n \"message\" in feedback.error ? feedback.error.message : feedback.error.code,\n ) ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"alert\">\n {\"message\" in feedback.error ? feedback.error.message : feedback.error.code}\n </div>\n ))}\n <div>\n {config.spots.map((spot) => {\n const status: SpotStatus =\n busy === spot.id ? \"VERIFYING\" : evaluateSpotStatus(spot, currentState);\n const claimed = status === \"CLAIMED\";\n const locked = status === \"LOCKED\";\n const children = spot.conditions.map((condition) => {\n const Renderer = customConditionRenderers[condition.type] ?? DefaultCondition;\n return (\n <div\n className={classNames.condition}\n style={styles.condition}\n key={`${spot.id}-${condition.type}-${JSON.stringify(condition)}`}\n >\n <Renderer\n spot={spot}\n condition={condition}\n locale={locale}\n {...(dictionary === undefined ? {} : { dictionary })}\n disabled={busy !== null || claimed || locked}\n {...(Object.keys(classNames).length === 0 ? {} : { classNames })}\n {...(Object.keys(styles).length === 0 ? {} : { styles })}\n onSubmit={(proof) => submit(spot.id, proof)}\n />\n </div>\n );\n });\n const props: SpotCardProps<TLocale> = {\n spot,\n state: currentState,\n status,\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n children,\n };\n return (\n <div\n key={spot.id}\n className={classNames.card}\n style={styles.card}\n data-status={status}\n aria-disabled={locked}\n >\n {renderSpotCard?.(props) ?? (\n <article>\n {spot.iconUrl !== undefined && (\n <img src={spot.iconUrl} alt=\"\" width={32} height={32} />\n )}\n <h2>{resolveLocalizedText(spot.name, locale)}</h2>\n {spot.imageUrl !== undefined && <img src={spot.imageUrl} alt=\"\" loading=\"lazy\" />}\n {spot.description !== undefined && (\n <p>{resolveLocalizedText(spot.description, locale)}</p>\n )}\n {spot.hint !== undefined && <p>{resolveLocalizedText(spot.hint, locale)}</p>}\n {spot.externalReferences !== undefined && spot.externalReferences.length > 0 && (\n <span className={classNames.badge} style={styles.badge}>\n {label(dictionary, locale, \"externalReferences\", \"External references\")} (\n {spot.externalReferences.length})\n </span>\n )}\n {renderStatusBadge?.({ status }) ?? (\n <span className={classNames.badge} style={styles.badge}>\n {label(dictionary, locale, `status.${status.toLowerCase()}`, status)}\n </span>\n )}\n {locked && (\n <p role=\"status\">\n {label(\n dictionary,\n locale,\n \"prerequisitesNotMet\",\n \"Complete the prerequisite spots before checking in.\",\n )}\n </p>\n )}\n {children}\n </article>\n )}\n </div>\n );\n })}\n </div>\n <section aria-label={label(dictionary, locale, \"rewards\", \"Rewards\")}>\n {config.rewards.map((reward) => {\n const props: RewardCardProps<TLocale> = {\n reward,\n state: currentState.rewards.find((item) => item.rewardId === reward.id),\n ...(currentState.inventory === undefined ? {} : { inventory: currentState.inventory }),\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n onClaim: claim,\n };\n return (\n <div key={reward.id} className={classNames.reward} style={styles.reward}>\n {renderRewardCard?.(props) ?? (\n <DefaultRewardCard {...props} classNames={classNames} styles={styles} />\n )}\n </div>\n );\n })}\n </section>\n <footer className={classNames.footer} style={styles.footer}>\n {footerSlot}\n </footer>\n </section>\n );\n}\n\nexport interface StampSheetProps<TLocale extends string = string>\n extends RallyViewerSlots<TLocale> {\n readonly config: RallyConfig<TLocale>;\n readonly state?: StampRallyState | null;\n readonly title?: string;\n readonly progress?: StampRallyProgress;\n readonly locale?: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n readonly style?: ViewerStyle;\n}\nexport function StampSheet<TLocale extends string = string>({\n config,\n state,\n title,\n progress,\n locale = \"en\" as TLocale,\n dictionary,\n classNames = {},\n styles = {},\n style,\n headerSlot,\n footerSlot,\n renderSpotCard,\n renderStatusBadge,\n}: StampSheetProps<TLocale>): ReactElement {\n const currentState = state ?? {\n rallyId: config.id,\n userId: null,\n records: [],\n rewards: [],\n updatedAt: \"\",\n };\n const current = progress ?? calculateProgress(currentState, config);\n return (\n <section\n className={classNames.root}\n style={styles.root ?? style}\n aria-label={title ?? label(dictionary, locale, \"stampSheet\", \"Stamp sheet\")}\n >\n <header className={classNames.header} style={styles.header}>\n {typeof headerSlot === \"function\"\n ? headerSlot({ config, state: currentState })\n : (headerSlot ?? <h2>{title ?? resolveLocalizedText(config.title, locale)}</h2>)}\n <progress max={100} value={current.percentage} />\n </header>\n <div>\n {config.spots.map((spot) => {\n const status: SpotStatus = evaluateSpotStatus(spot, currentState);\n const props: SpotCardProps<TLocale> = {\n spot,\n state: currentState,\n status,\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n children: (\n <span className={classNames.slot} style={styles.slot}>\n {status === \"LOCKED\"\n ? label(dictionary, locale, \"status.locked\", \"🔒 LOCKED\")\n : status === \"CLAIMED\"\n ? label(dictionary, locale, \"status.claimed\", \"CLAIMED\")\n : label(dictionary, locale, \"status.unclaimed\", \"UNCLAIMED\")}\n </span>\n ),\n };\n return (\n <div\n key={spot.id}\n className={classNames.card}\n style={styles.card}\n data-status={status}\n aria-disabled={status === \"LOCKED\"}\n >\n {renderSpotCard?.(props) ?? (\n <span className={classNames.slot} style={styles.slot}>\n {spot.iconUrl !== undefined && (\n <img src={spot.iconUrl} alt=\"\" width={24} height={24} />\n )}\n {resolveLocalizedText(spot.name, locale)}{\" \"}\n {spot.description !== undefined && (\n <small>{resolveLocalizedText(spot.description, locale)}</small>\n )}{\" \"}\n {renderStatusBadge?.({ status }) ??\n label(dictionary, locale, `status.${status.toLowerCase()}`, status)}\n </span>\n )}\n </div>\n );\n })}\n </div>\n <footer className={classNames.footer} style={styles.footer}>\n {footerSlot}\n </footer>\n </section>\n );\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,10 @@
1
- import { PublicSpotItem, PublicCheckInCondition, LocaleDictionary, PublicRallyConfig, UserRallyState, SpotStatus as SpotStatus$1, PublicReward, RewardState, ClaimOptions, ClaimResult, CheckInResult, StampRallyClient, CheckInOptions, RallyConfig, StampRallyState, StampRallyProgress } from '@stamprally/core';
1
+ import { LocaleDictionary, PublicSpotItem, PublicCheckInCondition, PublicRallyConfig, UserRallyState, SpotStatus as SpotStatus$1, PublicReward, RewardState, RallyInventoryState, ClaimOptions, ClaimResult, CheckInResult, StampRallyClient, CheckInOptions, RallyConfig, StampRallyState, StampRallyProgress } from '@stamprally/core';
2
2
  import { ComponentType, CSSProperties, ReactNode, ReactElement } from 'react';
3
3
 
4
+ /** Complete built-in labels for the standard participant components. */
5
+ declare const DEFAULT_UI_DICTIONARY: LocaleDictionary<"ja" | "en">;
6
+ declare const UI_DICTIONARIES: Readonly<Record<"en" | "ja", Readonly<Record<string, string>>>>;
7
+
4
8
  type ViewerClassName = "root" | "header" | "card" | "condition" | "slot" | "badge" | "modal" | "button" | "action" | "feedback" | "reward" | "footer";
5
9
  type ViewerStyle = CSSProperties & {
6
10
  readonly [key: `--${string}`]: string | number | undefined;
@@ -30,6 +34,7 @@ interface SpotCardProps<TLocale extends string = string> {
30
34
  interface RewardCardProps<TLocale extends string = string> {
31
35
  readonly reward: PublicReward<TLocale>;
32
36
  readonly state: RewardState | undefined;
37
+ readonly inventory?: RallyInventoryState;
33
38
  readonly locale: TLocale;
34
39
  readonly dictionary?: LocaleDictionary<TLocale>;
35
40
  readonly onClaim: ((rewardId: string, options?: ClaimOptions) => Promise<ClaimResult>) | undefined;
@@ -79,4 +84,4 @@ interface StampSheetProps<TLocale extends string = string> extends RallyViewerSl
79
84
  }
80
85
  declare function StampSheet<TLocale extends string = string>({ config, state, title, progress, locale, dictionary, classNames, styles, style, headerSlot, footerSlot, renderSpotCard, renderStatusBadge, }: StampSheetProps<TLocale>): ReactElement;
81
86
 
82
- export { type ConditionRenderer, type ConditionRendererProps, RallyViewer, type RallyViewerAdapter, type RallyViewerProps, type RallyViewerSlots, type RewardCardProps, type SpotCardProps, type SpotStatus, StampSheet, type StampSheetProps, type ViewerClassName, type ViewerClassNames, type ViewerStyle, type ViewerStyles };
87
+ export { type ConditionRenderer, type ConditionRendererProps, DEFAULT_UI_DICTIONARY, RallyViewer, type RallyViewerAdapter, type RallyViewerProps, type RallyViewerSlots, type RewardCardProps, type SpotCardProps, type SpotStatus, StampSheet, type StampSheetProps, UI_DICTIONARIES, type ViewerClassName, type ViewerClassNames, type ViewerStyle, type ViewerStyles };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,10 @@
1
- import { PublicSpotItem, PublicCheckInCondition, LocaleDictionary, PublicRallyConfig, UserRallyState, SpotStatus as SpotStatus$1, PublicReward, RewardState, ClaimOptions, ClaimResult, CheckInResult, StampRallyClient, CheckInOptions, RallyConfig, StampRallyState, StampRallyProgress } from '@stamprally/core';
1
+ import { LocaleDictionary, PublicSpotItem, PublicCheckInCondition, PublicRallyConfig, UserRallyState, SpotStatus as SpotStatus$1, PublicReward, RewardState, RallyInventoryState, ClaimOptions, ClaimResult, CheckInResult, StampRallyClient, CheckInOptions, RallyConfig, StampRallyState, StampRallyProgress } from '@stamprally/core';
2
2
  import { ComponentType, CSSProperties, ReactNode, ReactElement } from 'react';
3
3
 
4
+ /** Complete built-in labels for the standard participant components. */
5
+ declare const DEFAULT_UI_DICTIONARY: LocaleDictionary<"ja" | "en">;
6
+ declare const UI_DICTIONARIES: Readonly<Record<"en" | "ja", Readonly<Record<string, string>>>>;
7
+
4
8
  type ViewerClassName = "root" | "header" | "card" | "condition" | "slot" | "badge" | "modal" | "button" | "action" | "feedback" | "reward" | "footer";
5
9
  type ViewerStyle = CSSProperties & {
6
10
  readonly [key: `--${string}`]: string | number | undefined;
@@ -30,6 +34,7 @@ interface SpotCardProps<TLocale extends string = string> {
30
34
  interface RewardCardProps<TLocale extends string = string> {
31
35
  readonly reward: PublicReward<TLocale>;
32
36
  readonly state: RewardState | undefined;
37
+ readonly inventory?: RallyInventoryState;
33
38
  readonly locale: TLocale;
34
39
  readonly dictionary?: LocaleDictionary<TLocale>;
35
40
  readonly onClaim: ((rewardId: string, options?: ClaimOptions) => Promise<ClaimResult>) | undefined;
@@ -79,4 +84,4 @@ interface StampSheetProps<TLocale extends string = string> extends RallyViewerSl
79
84
  }
80
85
  declare function StampSheet<TLocale extends string = string>({ config, state, title, progress, locale, dictionary, classNames, styles, style, headerSlot, footerSlot, renderSpotCard, renderStatusBadge, }: StampSheetProps<TLocale>): ReactElement;
81
86
 
82
- export { type ConditionRenderer, type ConditionRendererProps, RallyViewer, type RallyViewerAdapter, type RallyViewerProps, type RallyViewerSlots, type RewardCardProps, type SpotCardProps, type SpotStatus, StampSheet, type StampSheetProps, type ViewerClassName, type ViewerClassNames, type ViewerStyle, type ViewerStyles };
87
+ export { type ConditionRenderer, type ConditionRendererProps, DEFAULT_UI_DICTIONARY, RallyViewer, type RallyViewerAdapter, type RallyViewerProps, type RallyViewerSlots, type RewardCardProps, type SpotCardProps, type SpotStatus, StampSheet, type StampSheetProps, UI_DICTIONARIES, type ViewerClassName, type ViewerClassNames, type ViewerStyle, type ViewerStyles };
package/dist/index.js CHANGED
@@ -1,9 +1,77 @@
1
+ "use client";
1
2
  import { calculateProgress, evaluateSpotStatus, resolveLocalizedText, isQrSupported, isNfcSupported, readQrContext, getCurrentGeoContext, readNfcContext } from '@stamprally/core';
2
3
  import { useState, useEffect, useMemo, useCallback, useRef } from 'react';
3
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
5
 
5
- // src/index.tsx
6
- var label = (dictionary, locale, key, fallback) => dictionary?.[locale]?.[key] ?? fallback;
6
+ // src/locales/index.ts
7
+ var DEFAULT_UI_DICTIONARY = {
8
+ en: {
9
+ viewer: "Stamp rally",
10
+ stampSheet: "Stamp sheet",
11
+ progress: "Progress",
12
+ rewards: "Rewards",
13
+ externalReferences: "External references",
14
+ qrValue: "QR value",
15
+ qrPlaceholder: "Paste a QR value",
16
+ qrCamera: "QR camera",
17
+ scanQr: "Scan QR",
18
+ passcode: "Passcode",
19
+ proof: "Proof",
20
+ checkLocation: "Check location",
21
+ readNfc: "Read NFC",
22
+ checkIn: "Check in",
23
+ verifying: "Verifying\u2026",
24
+ verified: "Verified",
25
+ verificationFailed: "Verification failed.",
26
+ prerequisitesNotMet: "Complete the prerequisite spots before checking in.",
27
+ "status.locked": "\u{1F512} LOCKED",
28
+ "status.unclaimed": "UNCLAIMED",
29
+ "status.claimed": "CLAIMED",
30
+ "status.verifying": "VERIFYING",
31
+ "status.available": "AVAILABLE",
32
+ "status.consumed": "CONSUMED",
33
+ "status.expired": "EXPIRED",
34
+ "status.onlyAFewLeft": "Only a few left",
35
+ "reward.lowStock": "Only a few left",
36
+ "reward.remaining": "remaining",
37
+ "reward.sharedRemaining": "Overall remaining",
38
+ "reward.validUntil": "Valid until"
39
+ },
40
+ ja: {
41
+ viewer: "\u30B9\u30BF\u30F3\u30D7\u30E9\u30EA\u30FC",
42
+ stampSheet: "\u30B9\u30BF\u30F3\u30D7\u30B7\u30FC\u30C8",
43
+ progress: "\u9032\u6357",
44
+ rewards: "\u666F\u54C1",
45
+ externalReferences: "\u95A2\u9023\u30EA\u30F3\u30AF",
46
+ qrValue: "QR\u5024",
47
+ qrPlaceholder: "QR\u5024\u3092\u5165\u529B",
48
+ qrCamera: "QR\u30AB\u30E1\u30E9",
49
+ scanQr: "QR\u3092\u8AAD\u307F\u53D6\u308B",
50
+ passcode: "\u30D1\u30B9\u30B3\u30FC\u30C9",
51
+ proof: "\u8A3C\u660E\u60C5\u5831",
52
+ checkLocation: "\u4F4D\u7F6E\u60C5\u5831\u3092\u78BA\u8A8D",
53
+ readNfc: "NFC\u3092\u8AAD\u307F\u53D6\u308B",
54
+ checkIn: "\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3",
55
+ verifying: "\u78BA\u8A8D\u4E2D\u2026",
56
+ verified: "\u78BA\u8A8D\u6E08\u307F",
57
+ verificationFailed: "\u78BA\u8A8D\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002",
58
+ prerequisitesNotMet: "\u524D\u63D0\u30B9\u30DD\u30C3\u30C8\u3092\u30AF\u30EA\u30A2\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
59
+ "status.locked": "\u{1F512} \u30ED\u30C3\u30AF\u4E2D",
60
+ "status.unclaimed": "\u672A\u53D6\u5F97",
61
+ "status.claimed": "\u53D6\u5F97\u6E08\u307F",
62
+ "status.verifying": "\u78BA\u8A8D\u4E2D",
63
+ "status.available": "\u5229\u7528\u53EF\u80FD",
64
+ "status.consumed": "\u4F7F\u7528\u6E08\u307F",
65
+ "status.expired": "\u671F\u9650\u5207\u308C",
66
+ "status.onlyAFewLeft": "\u6B8B\u308A\u308F\u305A\u304B",
67
+ "reward.lowStock": "\u6B8B\u308A\u308F\u305A\u304B",
68
+ "reward.remaining": "\u6B8B\u308A",
69
+ "reward.sharedRemaining": "\u5168\u4F53\u3067\u6B8B\u308A",
70
+ "reward.validUntil": "\u6709\u52B9\u671F\u9650"
71
+ }
72
+ };
73
+ var UI_DICTIONARIES = DEFAULT_UI_DICTIONARY;
74
+ var label = (dictionary, locale, key, fallback) => dictionary?.[locale]?.[key] ?? DEFAULT_UI_DICTIONARY[locale]?.[key] ?? fallback;
7
75
  var join = (...names) => {
8
76
  const value = names.filter((name) => name !== void 0 && name !== "").join(" ");
9
77
  return value === "" ? void 0 : value;
@@ -178,6 +246,7 @@ function DefaultCondition({
178
246
  function DefaultRewardCard({
179
247
  reward,
180
248
  state,
249
+ inventory,
181
250
  locale,
182
251
  dictionary,
183
252
  onClaim,
@@ -185,12 +254,23 @@ function DefaultRewardCard({
185
254
  styles
186
255
  }) {
187
256
  const status = state?.status ?? "LOCKED";
188
- const remaining = reward.stockLimit === void 0 ? void 0 : Math.max(0, reward.stockLimit - (state?.redeemedCount ?? 0));
257
+ const configuredRemaining = inventory?.rewardRemaining?.[reward.id] ?? (reward.stockLimit === void 0 ? void 0 : Math.max(0, reward.stockLimit - (state?.redeemedCount ?? 0)));
258
+ const sharedRemaining = inventory?.sharedRemaining;
259
+ const unavailable = status !== "AVAILABLE" || onClaim === void 0 || sharedRemaining === 0 || configuredRemaining === 0;
189
260
  const expiry = reward.validUntil === void 0 ? void 0 : new Date(reward.validUntil);
190
261
  return /* @__PURE__ */ jsxs("article", { className: classNames?.reward, style: styles?.reward, children: [
191
262
  /* @__PURE__ */ jsx("h3", { children: resolveLocalizedText(reward.title, locale) }),
192
263
  reward.description !== void 0 && /* @__PURE__ */ jsx("p", { children: resolveLocalizedText(reward.description, locale) }),
193
- remaining !== void 0 && /* @__PURE__ */ jsx("span", { children: remaining <= 3 ? label(dictionary, locale, "reward.lowStock", "Only a few left") : `${remaining} ${label(dictionary, locale, "reward.remaining", "remaining")}` }),
264
+ sharedRemaining !== void 0 && /* @__PURE__ */ jsxs("span", { children: [
265
+ label(dictionary, locale, "reward.sharedRemaining", "Overall remaining"),
266
+ ":",
267
+ " ",
268
+ sharedRemaining
269
+ ] }),
270
+ configuredRemaining !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
271
+ configuredRemaining <= 3 && /* @__PURE__ */ jsx("span", { children: label(dictionary, locale, "reward.lowStock", "Only a few left") }),
272
+ /* @__PURE__ */ jsx("span", { children: `${configuredRemaining} ${label(dictionary, locale, "reward.remaining", "remaining")}` })
273
+ ] }),
194
274
  expiry !== void 0 && !Number.isNaN(expiry.getTime()) && /* @__PURE__ */ jsxs("time", { dateTime: reward.validUntil, children: [
195
275
  label(dictionary, locale, "reward.validUntil", "Valid until"),
196
276
  ":",
@@ -203,7 +283,7 @@ function DefaultRewardCard({
203
283
  type: "button",
204
284
  className: join(classNames?.reward, classNames?.button),
205
285
  style: styles?.button,
206
- disabled: status !== "AVAILABLE" || onClaim === void 0,
286
+ disabled: unavailable,
207
287
  onClick: () => {
208
288
  if (onClaim !== void 0) void onClaim(reward.id);
209
289
  },
@@ -362,7 +442,7 @@ function RallyViewer({
362
442
  spot.externalReferences.length,
363
443
  ")"
364
444
  ] }),
365
- renderStatusBadge?.({ status }) ?? /* @__PURE__ */ jsx("span", { className: classNames.badge, style: styles.badge, children: status === "LOCKED" ? "\u{1F512} LOCKED" : status }),
445
+ renderStatusBadge?.({ status }) ?? /* @__PURE__ */ jsx("span", { className: classNames.badge, style: styles.badge, children: label(dictionary, locale, `status.${status.toLowerCase()}`, status) }),
366
446
  locked && /* @__PURE__ */ jsx("p", { role: "status", children: label(
367
447
  dictionary,
368
448
  locale,
@@ -379,6 +459,7 @@ function RallyViewer({
379
459
  const props = {
380
460
  reward,
381
461
  state: currentState.rewards.find((item) => item.rewardId === reward.id),
462
+ ...currentState.inventory === void 0 ? {} : { inventory: currentState.inventory },
382
463
  locale,
383
464
  ...dictionary === void 0 ? {} : { dictionary },
384
465
  onClaim: claim
@@ -426,14 +507,13 @@ function StampSheet({
426
507
  ] }),
427
508
  /* @__PURE__ */ jsx("div", { children: config.spots.map((spot) => {
428
509
  const status = evaluateSpotStatus(spot, currentState);
429
- const claimed = status === "CLAIMED";
430
510
  const props = {
431
511
  spot,
432
512
  state: currentState,
433
513
  status,
434
514
  locale,
435
515
  ...dictionary === void 0 ? {} : { dictionary },
436
- children: /* @__PURE__ */ jsx("span", { className: classNames.slot, style: styles.slot, children: status === "LOCKED" ? "\u{1F512}" : claimed ? "\u2713" : "\u25CB" })
516
+ children: /* @__PURE__ */ jsx("span", { className: classNames.slot, style: styles.slot, children: status === "LOCKED" ? label(dictionary, locale, "status.locked", "\u{1F512} LOCKED") : status === "CLAIMED" ? label(dictionary, locale, "status.claimed", "CLAIMED") : label(dictionary, locale, "status.unclaimed", "UNCLAIMED") })
437
517
  };
438
518
  return /* @__PURE__ */ jsx(
439
519
  "div",
@@ -448,7 +528,7 @@ function StampSheet({
448
528
  " ",
449
529
  spot.description !== void 0 && /* @__PURE__ */ jsx("small", { children: resolveLocalizedText(spot.description, locale) }),
450
530
  " ",
451
- renderStatusBadge?.({ status }) ?? (status === "LOCKED" ? "\u{1F512}" : claimed ? "\u2713" : "\u25CB")
531
+ renderStatusBadge?.({ status }) ?? label(dictionary, locale, `status.${status.toLowerCase()}`, status)
452
532
  ] })
453
533
  },
454
534
  spot.id
@@ -460,6 +540,6 @@ function StampSheet({
460
540
  );
461
541
  }
462
542
 
463
- export { RallyViewer, StampSheet };
543
+ export { DEFAULT_UI_DICTIONARY, RallyViewer, StampSheet, UI_DICTIONARIES };
464
544
  //# sourceMappingURL=index.js.map
465
545
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"names":["result"],"mappings":";;;;;AAoIA,IAAM,KAAA,GAAQ,CACZ,UAAA,EACA,MAAA,EACA,GAAA,EACA,aACW,UAAA,GAAa,MAAM,CAAA,GAAI,GAAG,CAAA,IAAK,QAAA;AAC5C,IAAM,IAAA,GAAO,IAAI,KAAA,KAAiE;AAChF,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAyB,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,EAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAChG,EAAA,OAAO,KAAA,KAAU,KAAK,MAAA,GAAY,KAAA;AACpC,CAAA;AAGA,SAAS,gBAAA,CAAyC;AAAA,EAChD,SAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAkD;AAChD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,EAAE,CAAA;AACrC,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAA6B,MAAM,CAAA;AAC/D,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AACtD,EAAA,MAAM,QAAA,GAAW,OAAyB,IAAI,CAAA;AAC9C,EAAA,MAAM,IAAA,GAAO,CAAC,GAAA,EAAa,QAAA,KAA6B,MAAM,UAAA,EAAY,MAAA,EAAQ,KAAK,QAAQ,CAAA;AAC/F,EAAA,MAAM,MAAA,GAAS,OAAO,KAAA,KAAkC;AACtD,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,KAAK,CAAA;AACnC,MAAA,IACE,MAAA,KAAW,KAAA,CAAA,IACX,OAAO,MAAA,KAAW,QAAA,IAClB,MAAA,KAAW,IAAA,IACX,IAAA,IAAQ,MAAA,IACR,MAAA,CAAO,EAAA,KAAO,KAAA,EACd;AACA,QAAA,SAAA,CAAU,OAAO,CAAA;AACjB,QAAA,QAAA,CAAS,IAAA,CAAK,oBAAA,EAAsB,sBAAsB,CAAC,CAAA;AAAA,MAC7D,CAAA,gBAAiB,SAAS,CAAA;AAAA,IAC5B,CAAA,CAAA,MAAQ;AACN,MAAA,SAAA,CAAU,OAAO,CAAA;AACjB,MAAA,QAAA,CAAS,IAAA,CAAK,oBAAA,EAAsB,sBAAsB,CAAC,CAAA;AAAA,IAC7D;AAAA,EACF,CAAA;AACA,EAAA,MAAM,eAAe,MAAY;AAC/B,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,KAAK,oBAAA,EAAqB,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW;AAC3C,MAAA,IAAI,MAAA,CAAO,EAAA,EAAI,KAAK,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,WAClC;AACH,QAAA,SAAA,CAAU,OAAO,CAAA;AACjB,QAAA,QAAA,CAAS,MAAA,CAAO,MAAM,OAAO,CAAA;AAAA,MAC/B;AAAA,IACF,CAAC,CAAA;AAAA,EACH,CAAA;AACA,EAAA,MAAM,UAAU,MAAY;AAC1B,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,KAAK,cAAA,EAAe,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW;AACrC,MAAA,IAAI,MAAA,CAAO,EAAA,EAAI,KAAK,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,WAClC;AACH,QAAA,SAAA,CAAU,OAAO,CAAA;AACjB,QAAA,QAAA,CAAS,MAAA,CAAO,MAAM,OAAO,CAAA;AAAA,MAC/B;AAAA,IACF,CAAC,CAAA;AAAA,EACH,CAAA;AACA,EAAA,MAAM,SAAS,MAAY;AACzB,IAAA,IAAI,QAAA,CAAS,YAAY,IAAA,EAAM;AAC/B,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,KAAK,cAAc,QAAA,CAAS,OAAO,CAAA,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW;AACpD,MAAA,IAAI,MAAA,CAAO,EAAA,EAAI,KAAK,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,WAClC;AACH,QAAA,SAAA,CAAU,OAAO,CAAA;AACjB,QAAA,QAAA,CAAS,MAAA,CAAO,MAAM,OAAO,CAAA;AAAA,MAC/B;AAAA,IACF,CAAC,CAAA;AAAA,EACH,CAAA;AACA,EAAA,4BACG,KAAA,EAAA,EACE,QAAA,EAAA;AAAA,IAAA,SAAA,CAAU,IAAA,KAAS,wBAClB,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,OAAA,EAAA,EACE,QAAA,EAAA;AAAA,QAAA,IAAA,CAAK,WAAW,UAAU,CAAA;AAAA,wBAC3B,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,YAAA,EAAY,IAAA,CAAK,SAAA,EAAW,UAAU,CAAA;AAAA,YACtC,WAAA,EAAa,SAAA,CAAU,UAAA,IAAc,IAAA,CAAK,iBAAiB,kBAAkB,CAAA;AAAA,YAC7E,KAAA;AAAA,YACA,UAAU,CAAC,KAAA,KAAU,QAAA,CAAS,KAAA,CAAM,OAAO,KAAK;AAAA;AAAA;AAClD,OAAA,EACF,CAAA;AAAA,sBACA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,QAAA;AAAA,UACL,YAAA,EAAY,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AAAA,UACxC,MAAA,EAAQ,CAAC,aAAA,EAAc;AAAA,UAEvB,QAAA,kBAAA,GAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,UAAA,EAAW;AAAA;AAAA,OACzB;AAAA,sBACA,GAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,WAAW,IAAA,CAAK,YAAA,EAAc,UAAA,EAAY,MAAA,EAAQ,YAAY,MAAM,CAAA;AAAA,UACpE,KAAA,EAAO,MAAA,EAAQ,MAAA,IAAU,MAAA,EAAQ,MAAA;AAAA,UACjC,QAAA,EAAU,QAAA,IAAY,CAAC,aAAA,EAAc;AAAA,UACrC,OAAA,EAAS,MAAA;AAAA,UAER,QAAA,EAAA,IAAA,CAAK,UAAU,SAAS;AAAA;AAAA;AAC3B,KAAA,EACF,CAAA;AAAA,IAED,SAAA,CAAU,SAAS,KAAA,oBAClB,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,WAAW,IAAA,CAAK,YAAA,EAAc,UAAA,EAAY,MAAA,EAAQ,YAAY,MAAM,CAAA;AAAA,QACpE,KAAA,EAAO,MAAA,EAAQ,MAAA,IAAU,MAAA,EAAQ,MAAA;AAAA,QACjC,QAAA;AAAA,QACA,OAAA,EAAS,YAAA;AAAA,QAER,QAAA,EAAA,IAAA,CAAK,iBAAiB,gBAAgB;AAAA;AAAA,KACzC;AAAA,IAED,SAAA,CAAU,SAAS,KAAA,oBAClB,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,WAAW,IAAA,CAAK,YAAA,EAAc,UAAA,EAAY,MAAA,EAAQ,YAAY,MAAM,CAAA;AAAA,QACpE,KAAA,EAAO,MAAA,EAAQ,MAAA,IAAU,MAAA,EAAQ,MAAA;AAAA,QACjC,QAAA,EAAU,QAAA,IAAY,CAAC,cAAA,EAAe;AAAA,QACtC,OAAA,EAAS,OAAA;AAAA,QAER,QAAA,EAAA,IAAA,CAAK,WAAW,UAAU;AAAA;AAAA,KAC7B;AAAA,IAAA,CAEA,SAAA,CAAU,SAAS,UAAA,IACnB,SAAA,CAAU,SAAS,QAAA,IACnB,SAAA,CAAU,SAAS,IAAA,qBACnB,IAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,UAAA,KAAA,CAAM,cAAA,EAAe;AACrB,UAAA,KAAK,OAAO,KAAK,CAAA;AAAA,QACnB,CAAA;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,OAAA,EAAA,EACE,QAAA,EAAA;AAAA,YAAA,IAAA;AAAA,cACC,SAAA,CAAU,IAAA,KAAS,UAAA,GAAa,UAAA,GAAa,OAAA;AAAA,cAC7C,SAAA,CAAU,IAAA,KAAS,UAAA,GAAa,UAAA,GAAa;AAAA,aAC/C;AAAA,4BACA,GAAA;AAAA,cAAC,OAAA;AAAA,cAAA;AAAA,gBACC,YAAA,EAAY,IAAA,CAAK,OAAA,EAAS,OAAO,CAAA;AAAA,gBACjC,KAAA;AAAA,gBACA,UAAU,CAAC,KAAA,KAAU,QAAA,CAAS,KAAA,CAAM,OAAO,KAAK;AAAA;AAAA;AAClD,WAAA,EACF,CAAA;AAAA,0BACA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,WAAW,IAAA,CAAK,YAAA,EAAc,UAAA,EAAY,MAAA,EAAQ,YAAY,MAAM,CAAA;AAAA,cACpE,KAAA,EAAO,MAAA,EAAQ,MAAA,IAAU,MAAA,EAAQ,MAAA;AAAA,cACjC,QAAA,EAAU,QAAA,IAAY,KAAA,CAAM,IAAA,EAAK,KAAM,EAAA;AAAA,cAEtC,QAAA,EAAA,IAAA,CAAK,WAAW,UAAU;AAAA;AAAA;AAC7B;AAAA;AAAA,KACF;AAAA,oBAEF,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,IAAA,CAAK,cAAA,EAAgB,UAAA,EAAY,QAAQ,CAAA;AAAA,QACpD,OAAO,MAAA,EAAQ,QAAA;AAAA,QACf,WAAA,EAAU,QAAA;AAAA,QACV,IAAA,EAAM,MAAA,KAAW,OAAA,GAAU,OAAA,GAAU,MAAA;AAAA,QAEpC,QAAA,EAAA;AAAA,UAAA,MAAA,KAAW,SAAA,IAAa,IAAA,CAAK,WAAA,EAAa,iBAAY,CAAA;AAAA,UACtD,MAAA,KAAW,SAAA,IAAa,IAAA,CAAK,UAAA,EAAY,UAAU,CAAA;AAAA,UACnD,MAAA,KAAW,OAAA,KAAY,KAAA,IAAS,IAAA,CAAK,sBAAsB,sBAAsB,CAAA;AAAA;AAAA;AAAA;AACpF,GAAA,EACF,CAAA;AAEJ;AAEA,SAAS,iBAAA,CAA0C;AAAA,EACjD,MAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,EAGiB;AACf,EAAA,MAAM,MAAA,GAAS,OAAO,MAAA,IAAU,QAAA;AAChC,EAAA,MAAM,SAAA,GACJ,MAAA,CAAO,UAAA,KAAe,MAAA,GAClB,MAAA,GACA,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAA,CAAO,UAAA,IAAc,KAAA,EAAO,aAAA,IAAiB,CAAA,CAAE,CAAA;AACjE,EAAA,MAAM,MAAA,GAAS,OAAO,UAAA,KAAe,MAAA,GAAY,SAAY,IAAI,IAAA,CAAK,OAAO,UAAU,CAAA;AACvF,EAAA,4BACG,SAAA,EAAA,EAAQ,SAAA,EAAW,YAAY,MAAA,EAAQ,KAAA,EAAO,QAAQ,MAAA,EACrD,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,IAAA,EAAA,EAAI,QAAA,EAAA,oBAAA,CAAqB,MAAA,CAAO,KAAA,EAAO,MAAM,CAAA,EAAE,CAAA;AAAA,IAC/C,MAAA,CAAO,gBAAgB,MAAA,oBACtB,GAAA,CAAC,OAAG,QAAA,EAAA,oBAAA,CAAqB,MAAA,CAAO,WAAA,EAAa,MAAM,CAAA,EAAE,CAAA;AAAA,IAEtD,SAAA,KAAc,0BACb,GAAA,CAAC,MAAA,EAAA,EACE,uBAAa,CAAA,GACV,KAAA,CAAM,YAAY,MAAA,EAAQ,iBAAA,EAAmB,iBAAiB,CAAA,GAC9D,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,KAAA,CAAM,YAAY,MAAA,EAAQ,kBAAA,EAAoB,WAAW,CAAC,CAAA,CAAA,EAChF,CAAA;AAAA,IAED,MAAA,KAAW,MAAA,IAAa,CAAC,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,OAAA,EAAS,CAAA,oBACrD,IAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAU,OAAO,UAAA,EACpB,QAAA,EAAA;AAAA,MAAA,KAAA,CAAM,UAAA,EAAY,MAAA,EAAQ,mBAAA,EAAqB,aAAa,CAAA;AAAA,MAAE,GAAA;AAAA,MAAE,GAAA;AAAA,MAChE,MAAA,CAAO,eAAe,MAAM;AAAA,KAAA,EAC/B,CAAA;AAAA,oBAEF,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAW,IAAA,CAAK,UAAA,EAAY,MAAA,EAAQ,YAAY,MAAM,CAAA;AAAA,QACtD,OAAO,MAAA,EAAQ,MAAA;AAAA,QACf,QAAA,EAAU,MAAA,KAAW,WAAA,IAAe,OAAA,KAAY,MAAA;AAAA,QAChD,SAAS,MAAM;AACb,UAAA,IAAI,OAAA,KAAY,MAAA,EAAW,KAAK,OAAA,CAAQ,OAAO,EAAE,CAAA;AAAA,QACnD,CAAA;AAAA,QAEC,QAAA,EAAA,KAAA,CAAM,YAAY,MAAA,EAAQ,CAAA,OAAA,EAAU,OAAO,WAAA,EAAa,IAAI,MAAM;AAAA;AAAA;AACrE,GAAA,EACF,CAAA;AAEJ;AAEO,SAAS,WAAA,CAA6C;AAAA,EAC3D,MAAA,EAAQ,cAAA;AAAA,EACR,MAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAa,EAAC;AAAA,EACd,SAAS,EAAC;AAAA,EACV,KAAA;AAAA,EACA,2BAA2B,EAAC;AAAA,EAC5B,UAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,iBAAA;AAAA,EACA,oBAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF,CAAA,EAA4C;AAC1C,EAAA,MAAM,MAAA,GAAS,cAAA,IAAkB,MAAA,EAAQ,SAAA,MAAe,OAAA,EAAS,MAAA;AACjE,EAAA,MAAM,CAAC,OAAO,QAAQ,CAAA,GAAI,SAAgC,MAAM,MAAA,EAAQ,QAAA,EAAS,IAAK,IAAI,CAAA;AAC1F,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAwB,IAAI,CAAA;AACpD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAA+B,IAAI,CAAA;AACnE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,WAAW,MAAA,EAAW;AAC1B,IAAA,MAAM,WAAA,GAAc,MAAA,CAAO,SAAA,CAAU,QAAQ,CAAA;AAC7C,IAAA,KAAK,MAAA,CAAO,IAAA,EAAK,CAAE,IAAA,CAAK,QAAQ,CAAA;AAChC,IAAA,OAAO,WAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AACX,EAAA,IAAI,MAAA,KAAW,MAAA,EAAW,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAC5F,EAAA,MAAM,eAAe,KAAA,IAAS;AAAA,IAC5B,SAAS,MAAA,CAAO,EAAA;AAAA,IAChB,MAAA,EAAQ,IAAA;AAAA,IACR,SAAS,EAAC;AAAA,IACV,SAAS,EAAC;AAAA,IACV,SAAA,EAAW;AAAA,GACb;AACA,EAAA,MAAM,QAAA,GAAW,OAAA;AAAA,IACf,MAAM,iBAAA,CAAkB,YAAA,EAAc,MAAM,CAAA;AAAA,IAC5C,CAAC,QAAQ,YAAY;AAAA,GACvB;AACA,EAAA,MAAM,OAAA,GACJ,OAAA,EAAS,SAAA,KACR,MAAA,KAAW,SACR,MAAA,GACA,CAAC,MAAA,EAAgB,KAAA,EAAgB,OAAA,KAC/B,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAQ,OAAO,OAAO,CAAA,CAAA;AAC7C,EAAA,MAAM,KAAA,GACJ,OAAA,EAAS,aAAA,KACR,MAAA,KAAW,MAAA,GACR,MAAA,GACA,CAAC,QAAA,EAAkB,OAAA,KAA2B,MAAA,CAAO,WAAA,CAAY,QAAA,EAAU,OAAO,CAAA,CAAA;AACxF,EAAA,MAAM,MAAA,GAAS,WAAA;AAAA,IACb,OAAO,QAAgB,KAAA,KAAuD;AAC5E,MAAA,IAAI,OAAA,KAAY,QAAW,OAAO,MAAA;AAClC,MAAA,MAAM,MAAA,GAAS,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,OAAO,MAAM,CAAA;AAC7D,MAAA,IAAI,WAAW,MAAA,IAAa,kBAAA,CAAmB,MAAA,EAAQ,YAAY,MAAM,QAAA,EAAU;AACjF,QAAA,MAAMA,OAAAA,GAAwB;AAAA,UAC5B,EAAA,EAAI,KAAA;AAAA,UACJ,KAAA,EAAO;AAAA,YACL,IAAA,EAAM,uBAAA;AAAA,YACN,MAAA;AAAA,YACA,OAAA,EAAS;AAAA;AACX,SACF;AACA,QAAA,WAAA,CAAYA,OAAM,CAAA;AAClB,QAAA,OAAOA,OAAAA;AAAA,MACT;AACA,MAAA,OAAA,CAAQ,MAAM,CAAA;AACd,MAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,MAAA,EAAQ,KAAK,EAAE,OAAA,CAAQ,MAAM,OAAA,CAAQ,IAAI,CAAC,CAAA;AACvE,MAAA,WAAA,CAAY,MAAM,CAAA;AAClB,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA,CAAC,OAAA,EAAS,MAAA,CAAO,KAAA,EAAO,YAAY;AAAA,GACtC;AACA,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,WAAW,UAAA,CAAW,IAAA;AAAA,MACtB,KAAA,EAAO,OAAO,IAAA,IAAQ,KAAA;AAAA,MACtB,YAAA,EAAY,KAAA,CAAM,UAAA,EAAY,MAAA,EAAQ,UAAU,aAAa,CAAA;AAAA,MAE7D,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,YAAO,SAAA,EAAW,UAAA,CAAW,MAAA,EAAQ,KAAA,EAAO,OAAO,MAAA,EACjD,QAAA,EAAA;AAAA,UAAA,OAAO,UAAA,KAAe,aACnB,UAAA,CAAW,EAAE,QAAQ,KAAA,EAAO,YAAA,EAAc,CAAA,GAC1C,UAAA;AAAA,UACH,UAAA,KAAe,MAAA,oBACd,GAAA,CAAC,IAAA,EAAA,EAAI,QAAA,EAAA,oBAAA,CAAqB,OAAO,KAAA,EAAO,MAAM,CAAA,IAAK,MAAA,CAAO,EAAA,EAAG,CAAA;AAAA,0BAE/D,GAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,YAAA,EAAY,KAAA,CAAM,UAAA,EAAY,MAAA,EAAQ,YAAY,UAAU,CAAA;AAAA,cAC5D,GAAA,EAAK,GAAA;AAAA,cACL,OAAO,QAAA,CAAS;AAAA;AAAA,WAClB;AAAA,+BACC,MAAA,EAAA,EACE,QAAA,EAAA;AAAA,YAAA,QAAA,CAAS,QAAA;AAAA,YAAS,GAAA;AAAA,YAAE,QAAA,CAAS;AAAA,WAAA,EAChC;AAAA,SAAA,EACF,CAAA;AAAA,QACC,SAAS,IAAA,KACP,oBAAA,wBACC,GAAA,CAAC,KAAA,EAAA,EAAI,WAAW,UAAA,CAAW,QAAA,EAAU,OAAO,MAAA,CAAO,QAAA,EAAU,MAAK,QAAA,EAC/D,QAAA,EAAA,KAAA,CAAM,YAAY,MAAA,EAAQ,WAAA,EAAa,iBAAY,CAAA,EACtD,CAAA,CAAA;AAAA,QAEH,QAAA,EAAU,OAAO,IAAA,KACf,qBAAA,GAAwB,QAAQ,CAAA,oBAC/B,GAAA,CAAC,SAAI,SAAA,EAAW,UAAA,CAAW,UAAU,KAAA,EAAO,MAAA,CAAO,UAAU,IAAA,EAAK,QAAA,EAC/D,gBAAM,UAAA,EAAY,MAAA,EAAQ,UAAA,EAAY,UAAU,CAAA,EACnD,CAAA,CAAA;AAAA,QAEH,QAAA,EAAU,OAAO,KAAA,KACf,mBAAA;AAAA,UACC,aAAa,QAAA,CAAS,KAAA,GAAQ,SAAS,KAAA,CAAM,OAAA,GAAU,SAAS,KAAA,CAAM;AAAA,6BAEtE,GAAA,CAAC,KAAA,EAAA,EAAI,WAAW,UAAA,CAAW,QAAA,EAAU,OAAO,MAAA,CAAO,QAAA,EAAU,MAAK,OAAA,EAC/D,QAAA,EAAA,SAAA,IAAa,SAAS,KAAA,GAAQ,QAAA,CAAS,MAAM,OAAA,GAAU,QAAA,CAAS,MAAM,IAAA,EACzE,CAAA,CAAA;AAAA,4BAEH,KAAA,EAAA,EACE,QAAA,EAAA,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AAC1B,UAAA,MAAM,SACJ,IAAA,KAAS,IAAA,CAAK,KAAK,WAAA,GAAc,kBAAA,CAAmB,MAAM,YAAY,CAAA;AACxE,UAAA,MAAM,UAAU,MAAA,KAAW,SAAA;AAC3B,UAAA,MAAM,SAAS,MAAA,KAAW,QAAA;AAC1B,UAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,CAAC,SAAA,KAAc;AAClD,YAAA,MAAM,QAAA,GAAW,wBAAA,CAAyB,SAAA,CAAU,IAAI,CAAA,IAAK,gBAAA;AAC7D,YAAA,uBACE,GAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,WAAW,UAAA,CAAW,SAAA;AAAA,gBACtB,OAAO,MAAA,CAAO,SAAA;AAAA,gBAGd,QAAA,kBAAA,GAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,IAAA;AAAA,oBACA,SAAA;AAAA,oBACA,MAAA;AAAA,oBACC,GAAI,UAAA,KAAe,MAAA,GAAY,EAAC,GAAI,EAAE,UAAA,EAAW;AAAA,oBAClD,QAAA,EAAU,IAAA,KAAS,IAAA,IAAQ,OAAA,IAAW,MAAA;AAAA,oBACrC,GAAI,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA,CAAE,WAAW,CAAA,GAAI,EAAC,GAAI,EAAE,UAAA,EAAW;AAAA,oBAC7D,GAAI,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,WAAW,CAAA,GAAI,EAAC,GAAI,EAAE,MAAA,EAAO;AAAA,oBACtD,UAAU,CAAC,KAAA,KAAU,MAAA,CAAO,IAAA,CAAK,IAAI,KAAK;AAAA;AAAA;AAC5C,eAAA;AAAA,cAXK,CAAA,EAAG,IAAA,CAAK,EAAE,CAAA,CAAA,EAAI,SAAA,CAAU,IAAI,CAAA,CAAA,EAAI,IAAA,CAAK,SAAA,CAAU,SAAS,CAAC,CAAA;AAAA,aAYhE;AAAA,UAEJ,CAAC,CAAA;AACD,UAAA,MAAM,KAAA,GAAgC;AAAA,YACpC,IAAA;AAAA,YACA,KAAA,EAAO,YAAA;AAAA,YACP,MAAA;AAAA,YACA,MAAA;AAAA,YACA,GAAI,UAAA,KAAe,MAAA,GAAY,EAAC,GAAI,EAAE,UAAA,EAAW;AAAA,YACjD;AAAA,WACF;AACA,UAAA,uBACE,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cAEC,WAAW,UAAA,CAAW,IAAA;AAAA,cACtB,OAAO,MAAA,CAAO,IAAA;AAAA,cACd,aAAA,EAAa,MAAA;AAAA,cACb,eAAA,EAAe,MAAA;AAAA,cAEd,QAAA,EAAA,cAAA,GAAiB,KAAK,CAAA,oBACrB,IAAA,CAAC,SAAA,EAAA,EACE,QAAA,EAAA;AAAA,gBAAA,IAAA,CAAK,OAAA,KAAY,MAAA,oBAChB,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,IAAA,CAAK,OAAA,EAAS,GAAA,EAAI,EAAA,EAAG,KAAA,EAAO,EAAA,EAAI,MAAA,EAAQ,EAAA,EAAI,CAAA;AAAA,oCAEvD,IAAA,EAAA,EAAI,QAAA,EAAA,oBAAA,CAAqB,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA,EAAE,CAAA;AAAA,gBAC5C,IAAA,CAAK,QAAA,KAAa,MAAA,oBAAa,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,IAAA,CAAK,QAAA,EAAU,GAAA,EAAI,EAAA,EAAG,OAAA,EAAQ,MAAA,EAAO,CAAA;AAAA,gBAC9E,IAAA,CAAK,gBAAgB,MAAA,oBACpB,GAAA,CAAC,OAAG,QAAA,EAAA,oBAAA,CAAqB,IAAA,CAAK,WAAA,EAAa,MAAM,CAAA,EAAE,CAAA;AAAA,gBAEpD,IAAA,CAAK,SAAS,MAAA,oBAAa,GAAA,CAAC,OAAG,QAAA,EAAA,oBAAA,CAAqB,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA,EAAE,CAAA;AAAA,gBACvE,IAAA,CAAK,kBAAA,KAAuB,MAAA,IAAa,IAAA,CAAK,mBAAmB,MAAA,GAAS,CAAA,oBACzE,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,UAAA,CAAW,KAAA,EAAO,KAAA,EAAO,OAAO,KAAA,EAC9C,QAAA,EAAA;AAAA,kBAAA,KAAA,CAAM,UAAA,EAAY,MAAA,EAAQ,oBAAA,EAAsB,qBAAqB,CAAA;AAAA,kBAAE,IAAA;AAAA,kBACvE,KAAK,kBAAA,CAAmB,MAAA;AAAA,kBAAO;AAAA,iBAAA,EAClC,CAAA;AAAA,gBAED,oBAAoB,EAAE,MAAA,EAAQ,CAAA,wBAC5B,MAAA,EAAA,EAAK,SAAA,EAAW,UAAA,CAAW,KAAA,EAAO,OAAO,MAAA,CAAO,KAAA,EAC9C,QAAA,EAAA,MAAA,KAAW,QAAA,GAAW,qBAAc,MAAA,EACvC,CAAA;AAAA,gBAED,MAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAK,QAAA,EACL,QAAA,EAAA,KAAA;AAAA,kBACC,UAAA;AAAA,kBACA,MAAA;AAAA,kBACA,qBAAA;AAAA,kBACA;AAAA,iBACF,EACF,CAAA;AAAA,gBAED;AAAA,eAAA,EACH;AAAA,aAAA;AAAA,YAvCG,IAAA,CAAK;AAAA,WAyCZ;AAAA,QAEJ,CAAC,CAAA,EACH,CAAA;AAAA,wBACA,GAAA,CAAC,SAAA,EAAA,EAAQ,YAAA,EAAY,KAAA,CAAM,UAAA,EAAY,MAAA,EAAQ,SAAA,EAAW,SAAS,CAAA,EAChE,QAAA,EAAA,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,KAAW;AAC9B,UAAA,MAAM,KAAA,GAAkC;AAAA,YACtC,MAAA;AAAA,YACA,KAAA,EAAO,aAAa,OAAA,CAAQ,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,QAAA,KAAa,MAAA,CAAO,EAAE,CAAA;AAAA,YACtE,MAAA;AAAA,YACA,GAAI,UAAA,KAAe,MAAA,GAAY,EAAC,GAAI,EAAE,UAAA,EAAW;AAAA,YACjD,OAAA,EAAS;AAAA,WACX;AACA,UAAA,2BACG,KAAA,EAAA,EAAoB,SAAA,EAAW,WAAW,MAAA,EAAQ,KAAA,EAAO,OAAO,MAAA,EAC9D,QAAA,EAAA,gBAAA,GAAmB,KAAK,CAAA,oBACvB,GAAA,CAAC,qBAAmB,GAAG,KAAA,EAAO,YAAwB,MAAA,EAAgB,CAAA,EAAA,EAFhE,OAAO,EAIjB,CAAA;AAAA,QAEJ,CAAC,CAAA,EACH,CAAA;AAAA,wBACA,GAAA,CAAC,YAAO,SAAA,EAAW,UAAA,CAAW,QAAQ,KAAA,EAAO,MAAA,CAAO,QACjD,QAAA,EAAA,UAAA,EACH;AAAA;AAAA;AAAA,GACF;AAEJ;AAcO,SAAS,UAAA,CAA4C;AAAA,EAC1D,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA,GAAS,IAAA;AAAA,EACT,UAAA;AAAA,EACA,aAAa,EAAC;AAAA,EACd,SAAS,EAAC;AAAA,EACV,KAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,EAA2C;AACzC,EAAA,MAAM,eAAe,KAAA,IAAS;AAAA,IAC5B,SAAS,MAAA,CAAO,EAAA;AAAA,IAChB,MAAA,EAAQ,IAAA;AAAA,IACR,SAAS,EAAC;AAAA,IACV,SAAS,EAAC;AAAA,IACV,SAAA,EAAW;AAAA,GACb;AACA,EAAA,MAAM,OAAA,GAAU,QAAA,IAAY,iBAAA,CAAkB,YAAA,EAAc,MAAM,CAAA;AAClE,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,WAAW,UAAA,CAAW,IAAA;AAAA,MACtB,KAAA,EAAO,OAAO,IAAA,IAAQ,KAAA;AAAA,MACtB,cAAY,KAAA,IAAS,KAAA,CAAM,UAAA,EAAY,MAAA,EAAQ,cAAc,aAAa,CAAA;AAAA,MAE1E,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,YAAO,SAAA,EAAW,UAAA,CAAW,MAAA,EAAQ,KAAA,EAAO,OAAO,MAAA,EACjD,QAAA,EAAA;AAAA,UAAA,OAAO,eAAe,UAAA,GACnB,UAAA,CAAW,EAAE,MAAA,EAAQ,OAAO,YAAA,EAAc,CAAA,GACzC,UAAA,wBAAe,IAAA,EAAA,EAAI,QAAA,EAAA,KAAA,IAAS,qBAAqB,MAAA,CAAO,KAAA,EAAO,MAAM,CAAA,EAAE,CAAA;AAAA,8BAC3E,UAAA,EAAA,EAAS,GAAA,EAAK,GAAA,EAAK,KAAA,EAAO,QAAQ,UAAA,EAAY;AAAA,SAAA,EACjD,CAAA;AAAA,4BACC,KAAA,EAAA,EACE,QAAA,EAAA,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AAC1B,UAAA,MAAM,MAAA,GAAqB,kBAAA,CAAmB,IAAA,EAAM,YAAY,CAAA;AAChE,UAAA,MAAM,UAAU,MAAA,KAAW,SAAA;AAC3B,UAAA,MAAM,KAAA,GAAgC;AAAA,YACpC,IAAA;AAAA,YACA,KAAA,EAAO,YAAA;AAAA,YACP,MAAA;AAAA,YACA,MAAA;AAAA,YACA,GAAI,UAAA,KAAe,MAAA,GAAY,EAAC,GAAI,EAAE,UAAA,EAAW;AAAA,YACjD,QAAA,kBACE,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,WAAW,IAAA,EAAM,KAAA,EAAO,MAAA,CAAO,IAAA,EAC7C,QAAA,EAAA,MAAA,KAAW,QAAA,GAAW,WAAA,GAAO,OAAA,GAAU,WAAM,QAAA,EAChD;AAAA,WAEJ;AACA,UAAA,uBACE,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cAEC,WAAW,UAAA,CAAW,IAAA;AAAA,cACtB,OAAO,MAAA,CAAO,IAAA;AAAA,cACd,aAAA,EAAa,MAAA;AAAA,cACb,iBAAe,MAAA,KAAW,QAAA;AAAA,cAEzB,QAAA,EAAA,cAAA,GAAiB,KAAK,CAAA,oBACrB,IAAA,CAAC,MAAA,EAAA,EAAK,WAAW,UAAA,CAAW,IAAA,EAAM,KAAA,EAAO,MAAA,CAAO,IAAA,EAC7C,QAAA,EAAA;AAAA,gBAAA,IAAA,CAAK,OAAA,KAAY,MAAA,oBAChB,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,IAAA,CAAK,OAAA,EAAS,GAAA,EAAI,EAAA,EAAG,KAAA,EAAO,EAAA,EAAI,MAAA,EAAQ,EAAA,EAAI,CAAA;AAAA,gBAEvD,oBAAA,CAAqB,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA;AAAA,gBAAG,GAAA;AAAA,gBACzC,IAAA,CAAK,gBAAgB,MAAA,oBACpB,GAAA,CAAC,WAAO,QAAA,EAAA,oBAAA,CAAqB,IAAA,CAAK,WAAA,EAAa,MAAM,CAAA,EAAE,CAAA;AAAA,gBACtD,GAAA;AAAA,gBACF,iBAAA,GAAoB,EAAE,MAAA,EAAQ,MAC5B,MAAA,KAAW,QAAA,GAAW,WAAA,GAAO,OAAA,GAAU,QAAA,GAAM,QAAA;AAAA,eAAA,EAClD;AAAA,aAAA;AAAA,YAjBG,IAAA,CAAK;AAAA,WAmBZ;AAAA,QAEJ,CAAC,CAAA,EACH,CAAA;AAAA,wBACA,GAAA,CAAC,YAAO,SAAA,EAAW,UAAA,CAAW,QAAQ,KAAA,EAAO,MAAA,CAAO,QACjD,QAAA,EAAA,UAAA,EACH;AAAA;AAAA;AAAA,GACF;AAEJ","file":"index.js","sourcesContent":["import type {\n CheckInOptions,\n CheckInResult,\n ClaimOptions,\n ClaimResult,\n SpotStatus as CoreSpotStatus,\n LocaleDictionary,\n PublicCheckInCondition,\n PublicRallyConfig,\n PublicReward,\n PublicSpotItem,\n RallyConfig,\n RewardState,\n StampRallyClient,\n StampRallyProgress,\n StampRallyState,\n UserRallyState,\n} from \"@stamprally/core\";\nimport {\n calculateProgress,\n evaluateSpotStatus,\n getCurrentGeoContext,\n isNfcSupported,\n isQrSupported,\n readNfcContext,\n readQrContext,\n resolveLocalizedText,\n} from \"@stamprally/core\";\nimport {\n type ComponentType,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport type ViewerClassName =\n | \"root\"\n | \"header\"\n | \"card\"\n | \"condition\"\n | \"slot\"\n | \"badge\"\n | \"modal\"\n | \"button\"\n | \"action\"\n | \"feedback\"\n | \"reward\"\n | \"footer\";\nexport type ViewerStyle = CSSProperties & {\n readonly [key: `--${string}`]: string | number | undefined;\n};\nexport type ViewerStyles = Partial<Record<ViewerClassName, ViewerStyle>>;\nexport type ViewerClassNames = Partial<Record<ViewerClassName, string>>;\nexport type SpotStatus = CoreSpotStatus;\n\nexport interface ConditionRendererProps<TLocale extends string = string> {\n readonly spot: PublicSpotItem<TLocale>;\n readonly condition: PublicCheckInCondition;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly disabled: boolean;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n // biome-ignore lint/suspicious/noConfusingVoidType: custom renderers may fire-and-forget while built-ins await feedback.\n readonly onSubmit: (proof: unknown) => void | Promise<unknown>;\n}\nexport type ConditionRenderer<TLocale extends string = string> = ComponentType<\n ConditionRendererProps<TLocale>\n>;\n\nexport interface SpotCardProps<TLocale extends string = string> {\n readonly spot: PublicSpotItem<TLocale>;\n readonly state: UserRallyState;\n readonly status: SpotStatus;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly children: ReactNode;\n}\nexport interface RewardCardProps<TLocale extends string = string> {\n readonly reward: PublicReward<TLocale>;\n readonly state: RewardState | undefined;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly onClaim:\n | ((rewardId: string, options?: ClaimOptions) => Promise<ClaimResult>)\n | undefined;\n}\nexport interface RallyViewerSlots<TLocale extends string = string> {\n readonly headerSlot?:\n | ReactNode\n | ((props: {\n readonly config: PublicRallyConfig<TLocale>;\n readonly state: UserRallyState;\n }) => ReactNode);\n readonly footerSlot?: ReactNode;\n readonly renderSpotCard?: (props: SpotCardProps<TLocale>) => ReactNode;\n readonly renderRewardCard?: (props: RewardCardProps<TLocale>) => ReactNode;\n readonly renderStatusBadge?: (props: { readonly status: SpotStatus }) => ReactNode;\n readonly renderVerifyingState?: () => ReactNode;\n readonly renderSuccessFeedback?: (result: CheckInResult) => ReactNode;\n readonly renderErrorFeedback?: (error: string) => ReactNode;\n}\n\nexport interface RallyViewerAdapter<TLocale extends string = string> {\n readonly config: PublicRallyConfig<TLocale>;\n readonly onCheckIn: (\n spotId: string,\n proof: unknown,\n options?: CheckInOptions,\n ) => Promise<CheckInResult>;\n readonly onClaimReward?: (rewardId: string, options?: ClaimOptions) => Promise<ClaimResult>;\n}\nexport interface RallyViewerProps<TLocale extends string = string>\n extends RallyViewerSlots<TLocale> {\n readonly config?: PublicRallyConfig<TLocale>;\n readonly client?: StampRallyClient;\n readonly adapter?: RallyViewerAdapter<TLocale>;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n readonly style?: ViewerStyle;\n readonly customConditionRenderers?: Partial<\n Record<PublicCheckInCondition[\"type\"], ConditionRenderer<TLocale>>\n >;\n}\n\nconst label = <TLocale extends string>(\n dictionary: LocaleDictionary<TLocale> | undefined,\n locale: TLocale,\n key: string,\n fallback: string,\n): string => dictionary?.[locale]?.[key] ?? fallback;\nconst join = (...names: ReadonlyArray<string | undefined>): string | undefined => {\n const value = names.filter((name): name is string => name !== undefined && name !== \"\").join(\" \");\n return value === \"\" ? undefined : value;\n};\ntype VerificationStatus = \"idle\" | \"loading\" | \"success\" | \"error\";\n\nfunction DefaultCondition<TLocale extends string>({\n condition,\n dictionary,\n locale,\n disabled,\n classNames,\n styles,\n onSubmit,\n}: ConditionRendererProps<TLocale>): ReactElement {\n const [value, setValue] = useState(\"\");\n const [status, setStatus] = useState<VerificationStatus>(\"idle\");\n const [error, setError] = useState<string | null>(null);\n const videoRef = useRef<HTMLVideoElement>(null);\n const text = (key: string, fallback: string): string => label(dictionary, locale, key, fallback);\n const verify = async (proof: unknown): Promise<void> => {\n setStatus(\"loading\");\n setError(null);\n try {\n const result = await onSubmit(proof);\n if (\n result !== undefined &&\n typeof result === \"object\" &&\n result !== null &&\n \"ok\" in result &&\n result.ok === false\n ) {\n setStatus(\"error\");\n setError(text(\"verificationFailed\", \"Verification failed.\"));\n } else setStatus(\"success\");\n } catch {\n setStatus(\"error\");\n setError(text(\"verificationFailed\", \"Verification failed.\"));\n }\n };\n const readLocation = (): void => {\n setStatus(\"loading\");\n void getCurrentGeoContext().then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n const readNfc = (): void => {\n setStatus(\"loading\");\n void readNfcContext().then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n const scanQr = (): void => {\n if (videoRef.current === null) return;\n setStatus(\"loading\");\n void readQrContext(videoRef.current).then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n return (\n <div>\n {condition.type === \"qr\" && (\n <>\n <label>\n {text(\"qrValue\", \"QR value\")}\n <input\n aria-label={text(\"qrValue\", \"QR value\")}\n placeholder={condition.qrEntryUrl ?? text(\"qrPlaceholder\", \"Paste a QR value\")}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n />\n </label>\n <video\n ref={videoRef}\n aria-label={text(\"qrCamera\", \"QR camera\")}\n hidden={!isQrSupported()}\n >\n <track kind=\"captions\" />\n </video>\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || !isQrSupported()}\n onClick={scanQr}\n >\n {text(\"scanQr\", \"Scan QR\")}\n </button>\n </>\n )}\n {condition.type === \"gps\" && (\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled}\n onClick={readLocation}\n >\n {text(\"checkLocation\", \"Check location\")}\n </button>\n )}\n {condition.type === \"nfc\" && (\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || !isNfcSupported()}\n onClick={readNfc}\n >\n {text(\"readNfc\", \"Read NFC\")}\n </button>\n )}\n {(condition.type === \"passcode\" ||\n condition.type === \"custom\" ||\n condition.type === \"qr\") && (\n <form\n onSubmit={(event) => {\n event.preventDefault();\n void verify(value);\n }}\n >\n <label>\n {text(\n condition.type === \"passcode\" ? \"passcode\" : \"proof\",\n condition.type === \"passcode\" ? \"Passcode\" : \"Proof\",\n )}\n <input\n aria-label={text(\"proof\", \"Proof\")}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n />\n </label>\n <button\n type=\"submit\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || value.trim() === \"\"}\n >\n {text(\"checkIn\", \"Check in\")}\n </button>\n </form>\n )}\n <div\n className={join(\"sry-feedback\", classNames?.feedback)}\n style={styles?.feedback}\n aria-live=\"polite\"\n role={status === \"error\" ? \"alert\" : undefined}\n >\n {status === \"loading\" && text(\"verifying\", \"Verifying…\")}\n {status === \"success\" && text(\"verified\", \"Verified\")}\n {status === \"error\" && (error ?? text(\"verificationFailed\", \"Verification failed.\"))}\n </div>\n </div>\n );\n}\n\nfunction DefaultRewardCard<TLocale extends string>({\n reward,\n state,\n locale,\n dictionary,\n onClaim,\n classNames,\n styles,\n}: RewardCardProps<TLocale> & {\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n}): ReactElement {\n const status = state?.status ?? \"LOCKED\";\n const remaining =\n reward.stockLimit === undefined\n ? undefined\n : Math.max(0, reward.stockLimit - (state?.redeemedCount ?? 0));\n const expiry = reward.validUntil === undefined ? undefined : new Date(reward.validUntil);\n return (\n <article className={classNames?.reward} style={styles?.reward}>\n <h3>{resolveLocalizedText(reward.title, locale)}</h3>\n {reward.description !== undefined && (\n <p>{resolveLocalizedText(reward.description, locale)}</p>\n )}\n {remaining !== undefined && (\n <span>\n {remaining <= 3\n ? label(dictionary, locale, \"reward.lowStock\", \"Only a few left\")\n : `${remaining} ${label(dictionary, locale, \"reward.remaining\", \"remaining\")}`}\n </span>\n )}\n {expiry !== undefined && !Number.isNaN(expiry.getTime()) && (\n <time dateTime={reward.validUntil}>\n {label(dictionary, locale, \"reward.validUntil\", \"Valid until\")}:{\" \"}\n {expiry.toLocaleString(locale)}\n </time>\n )}\n <button\n type=\"button\"\n className={join(classNames?.reward, classNames?.button)}\n style={styles?.button}\n disabled={status !== \"AVAILABLE\" || onClaim === undefined}\n onClick={() => {\n if (onClaim !== undefined) void onClaim(reward.id);\n }}\n >\n {label(dictionary, locale, `status.${status.toLowerCase()}`, status)}\n </button>\n </article>\n );\n}\n\nexport function RallyViewer<TLocale extends string = string>({\n config: providedConfig,\n client,\n adapter,\n locale,\n dictionary,\n classNames = {},\n styles = {},\n style,\n customConditionRenderers = {},\n headerSlot,\n footerSlot,\n renderSpotCard,\n renderRewardCard,\n renderStatusBadge,\n renderVerifyingState,\n renderSuccessFeedback,\n renderErrorFeedback,\n}: RallyViewerProps<TLocale>): ReactElement {\n const config = providedConfig ?? client?.getConfig() ?? adapter?.config;\n const [state, setState] = useState<UserRallyState | null>(() => client?.getState() ?? null);\n const [busy, setBusy] = useState<string | null>(null);\n const [feedback, setFeedback] = useState<CheckInResult | null>(null);\n useEffect(() => {\n if (client === undefined) return;\n const unsubscribe = client.subscribe(setState);\n void client.init().then(setState);\n return unsubscribe;\n }, [client]);\n if (config === undefined) throw new Error(\"RallyViewer requires config, client, or adapter.\");\n const currentState = state ?? {\n rallyId: config.id,\n userId: null,\n records: [],\n rewards: [],\n updatedAt: \"\",\n };\n const progress = useMemo<StampRallyProgress>(\n () => calculateProgress(currentState, config),\n [config, currentState],\n );\n const checkIn =\n adapter?.onCheckIn ??\n (client === undefined\n ? undefined\n : (spotId: string, proof: unknown, options?: CheckInOptions) =>\n client.checkIn(spotId, proof, options));\n const claim =\n adapter?.onClaimReward ??\n (client === undefined\n ? undefined\n : (rewardId: string, options?: ClaimOptions) => client.claimReward(rewardId, options));\n const submit = useCallback(\n async (spotId: string, proof: unknown): Promise<CheckInResult | undefined> => {\n if (checkIn === undefined) return undefined;\n const target = config.spots.find((spot) => spot.id === spotId);\n if (target !== undefined && evaluateSpotStatus(target, currentState) === \"LOCKED\") {\n const result: CheckInResult = {\n ok: false,\n error: {\n code: \"PREREQUISITES_NOT_MET\",\n spotId,\n message: \"Complete the prerequisite spots before checking in.\",\n },\n };\n setFeedback(result);\n return result;\n }\n setBusy(spotId);\n const result = await checkIn(spotId, proof).finally(() => setBusy(null));\n setFeedback(result);\n return result;\n },\n [checkIn, config.spots, currentState],\n );\n return (\n <section\n className={classNames.root}\n style={styles.root ?? style}\n aria-label={label(dictionary, locale, \"viewer\", \"Stamp rally\")}\n >\n <header className={classNames.header} style={styles.header}>\n {typeof headerSlot === \"function\"\n ? headerSlot({ config, state: currentState })\n : headerSlot}\n {headerSlot === undefined && (\n <h1>{resolveLocalizedText(config.title, locale) || config.id}</h1>\n )}\n <progress\n aria-label={label(dictionary, locale, \"progress\", \"Progress\")}\n max={100}\n value={progress.percentage}\n />\n <span>\n {progress.acquired}/{progress.total}\n </span>\n </header>\n {busy !== null &&\n (renderVerifyingState?.() ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"status\">\n {label(dictionary, locale, \"verifying\", \"Verifying…\")}\n </div>\n ))}\n {feedback?.ok === true &&\n (renderSuccessFeedback?.(feedback) ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"status\">\n {label(dictionary, locale, \"verified\", \"Verified\")}\n </div>\n ))}\n {feedback?.ok === false &&\n (renderErrorFeedback?.(\n \"message\" in feedback.error ? feedback.error.message : feedback.error.code,\n ) ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"alert\">\n {\"message\" in feedback.error ? feedback.error.message : feedback.error.code}\n </div>\n ))}\n <div>\n {config.spots.map((spot) => {\n const status: SpotStatus =\n busy === spot.id ? \"VERIFYING\" : evaluateSpotStatus(spot, currentState);\n const claimed = status === \"CLAIMED\";\n const locked = status === \"LOCKED\";\n const children = spot.conditions.map((condition) => {\n const Renderer = customConditionRenderers[condition.type] ?? DefaultCondition;\n return (\n <div\n className={classNames.condition}\n style={styles.condition}\n key={`${spot.id}-${condition.type}-${JSON.stringify(condition)}`}\n >\n <Renderer\n spot={spot}\n condition={condition}\n locale={locale}\n {...(dictionary === undefined ? {} : { dictionary })}\n disabled={busy !== null || claimed || locked}\n {...(Object.keys(classNames).length === 0 ? {} : { classNames })}\n {...(Object.keys(styles).length === 0 ? {} : { styles })}\n onSubmit={(proof) => submit(spot.id, proof)}\n />\n </div>\n );\n });\n const props: SpotCardProps<TLocale> = {\n spot,\n state: currentState,\n status,\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n children,\n };\n return (\n <div\n key={spot.id}\n className={classNames.card}\n style={styles.card}\n data-status={status}\n aria-disabled={locked}\n >\n {renderSpotCard?.(props) ?? (\n <article>\n {spot.iconUrl !== undefined && (\n <img src={spot.iconUrl} alt=\"\" width={32} height={32} />\n )}\n <h2>{resolveLocalizedText(spot.name, locale)}</h2>\n {spot.imageUrl !== undefined && <img src={spot.imageUrl} alt=\"\" loading=\"lazy\" />}\n {spot.description !== undefined && (\n <p>{resolveLocalizedText(spot.description, locale)}</p>\n )}\n {spot.hint !== undefined && <p>{resolveLocalizedText(spot.hint, locale)}</p>}\n {spot.externalReferences !== undefined && spot.externalReferences.length > 0 && (\n <span className={classNames.badge} style={styles.badge}>\n {label(dictionary, locale, \"externalReferences\", \"External references\")} (\n {spot.externalReferences.length})\n </span>\n )}\n {renderStatusBadge?.({ status }) ?? (\n <span className={classNames.badge} style={styles.badge}>\n {status === \"LOCKED\" ? \"🔒 LOCKED\" : status}\n </span>\n )}\n {locked && (\n <p role=\"status\">\n {label(\n dictionary,\n locale,\n \"prerequisitesNotMet\",\n \"Complete the prerequisite spots before checking in.\",\n )}\n </p>\n )}\n {children}\n </article>\n )}\n </div>\n );\n })}\n </div>\n <section aria-label={label(dictionary, locale, \"rewards\", \"Rewards\")}>\n {config.rewards.map((reward) => {\n const props: RewardCardProps<TLocale> = {\n reward,\n state: currentState.rewards.find((item) => item.rewardId === reward.id),\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n onClaim: claim,\n };\n return (\n <div key={reward.id} className={classNames.reward} style={styles.reward}>\n {renderRewardCard?.(props) ?? (\n <DefaultRewardCard {...props} classNames={classNames} styles={styles} />\n )}\n </div>\n );\n })}\n </section>\n <footer className={classNames.footer} style={styles.footer}>\n {footerSlot}\n </footer>\n </section>\n );\n}\n\nexport interface StampSheetProps<TLocale extends string = string>\n extends RallyViewerSlots<TLocale> {\n readonly config: RallyConfig<TLocale>;\n readonly state?: StampRallyState | null;\n readonly title?: string;\n readonly progress?: StampRallyProgress;\n readonly locale?: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n readonly style?: ViewerStyle;\n}\nexport function StampSheet<TLocale extends string = string>({\n config,\n state,\n title,\n progress,\n locale = \"en\" as TLocale,\n dictionary,\n classNames = {},\n styles = {},\n style,\n headerSlot,\n footerSlot,\n renderSpotCard,\n renderStatusBadge,\n}: StampSheetProps<TLocale>): ReactElement {\n const currentState = state ?? {\n rallyId: config.id,\n userId: null,\n records: [],\n rewards: [],\n updatedAt: \"\",\n };\n const current = progress ?? calculateProgress(currentState, config);\n return (\n <section\n className={classNames.root}\n style={styles.root ?? style}\n aria-label={title ?? label(dictionary, locale, \"stampSheet\", \"Stamp sheet\")}\n >\n <header className={classNames.header} style={styles.header}>\n {typeof headerSlot === \"function\"\n ? headerSlot({ config, state: currentState })\n : (headerSlot ?? <h2>{title ?? resolveLocalizedText(config.title, locale)}</h2>)}\n <progress max={100} value={current.percentage} />\n </header>\n <div>\n {config.spots.map((spot) => {\n const status: SpotStatus = evaluateSpotStatus(spot, currentState);\n const claimed = status === \"CLAIMED\";\n const props: SpotCardProps<TLocale> = {\n spot,\n state: currentState,\n status,\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n children: (\n <span className={classNames.slot} style={styles.slot}>\n {status === \"LOCKED\" ? \"🔒\" : claimed ? \"✓\" : \"○\"}\n </span>\n ),\n };\n return (\n <div\n key={spot.id}\n className={classNames.card}\n style={styles.card}\n data-status={status}\n aria-disabled={status === \"LOCKED\"}\n >\n {renderSpotCard?.(props) ?? (\n <span className={classNames.slot} style={styles.slot}>\n {spot.iconUrl !== undefined && (\n <img src={spot.iconUrl} alt=\"\" width={24} height={24} />\n )}\n {resolveLocalizedText(spot.name, locale)}{\" \"}\n {spot.description !== undefined && (\n <small>{resolveLocalizedText(spot.description, locale)}</small>\n )}{\" \"}\n {renderStatusBadge?.({ status }) ??\n (status === \"LOCKED\" ? \"🔒\" : claimed ? \"✓\" : \"○\")}\n </span>\n )}\n </div>\n );\n })}\n </div>\n <footer className={classNames.footer} style={styles.footer}>\n {footerSlot}\n </footer>\n </section>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/locales/index.ts","../src/index.tsx"],"names":["result"],"mappings":"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","file":"index.js","sourcesContent":["import type { LocaleDictionary } from \"@stamprally/core\";\n\n/** Complete built-in labels for the standard participant components. */\nexport const DEFAULT_UI_DICTIONARY: LocaleDictionary<\"ja\" | \"en\"> = {\n en: {\n viewer: \"Stamp rally\",\n stampSheet: \"Stamp sheet\",\n progress: \"Progress\",\n rewards: \"Rewards\",\n externalReferences: \"External references\",\n qrValue: \"QR value\",\n qrPlaceholder: \"Paste a QR value\",\n qrCamera: \"QR camera\",\n scanQr: \"Scan QR\",\n passcode: \"Passcode\",\n proof: \"Proof\",\n checkLocation: \"Check location\",\n readNfc: \"Read NFC\",\n checkIn: \"Check in\",\n verifying: \"Verifying…\",\n verified: \"Verified\",\n verificationFailed: \"Verification failed.\",\n prerequisitesNotMet: \"Complete the prerequisite spots before checking in.\",\n \"status.locked\": \"🔒 LOCKED\",\n \"status.unclaimed\": \"UNCLAIMED\",\n \"status.claimed\": \"CLAIMED\",\n \"status.verifying\": \"VERIFYING\",\n \"status.available\": \"AVAILABLE\",\n \"status.consumed\": \"CONSUMED\",\n \"status.expired\": \"EXPIRED\",\n \"status.onlyAFewLeft\": \"Only a few left\",\n \"reward.lowStock\": \"Only a few left\",\n \"reward.remaining\": \"remaining\",\n \"reward.sharedRemaining\": \"Overall remaining\",\n \"reward.validUntil\": \"Valid until\",\n },\n ja: {\n viewer: \"スタンプラリー\",\n stampSheet: \"スタンプシート\",\n progress: \"進捗\",\n rewards: \"景品\",\n externalReferences: \"関連リンク\",\n qrValue: \"QR値\",\n qrPlaceholder: \"QR値を入力\",\n qrCamera: \"QRカメラ\",\n scanQr: \"QRを読み取る\",\n passcode: \"パスコード\",\n proof: \"証明情報\",\n checkLocation: \"位置情報を確認\",\n readNfc: \"NFCを読み取る\",\n checkIn: \"チェックイン\",\n verifying: \"確認中…\",\n verified: \"確認済み\",\n verificationFailed: \"確認に失敗しました。\",\n prerequisitesNotMet: \"前提スポットをクリアしてください。\",\n \"status.locked\": \"🔒 ロック中\",\n \"status.unclaimed\": \"未取得\",\n \"status.claimed\": \"取得済み\",\n \"status.verifying\": \"確認中\",\n \"status.available\": \"利用可能\",\n \"status.consumed\": \"使用済み\",\n \"status.expired\": \"期限切れ\",\n \"status.onlyAFewLeft\": \"残りわずか\",\n \"reward.lowStock\": \"残りわずか\",\n \"reward.remaining\": \"残り\",\n \"reward.sharedRemaining\": \"全体で残り\",\n \"reward.validUntil\": \"有効期限\",\n },\n};\n\nexport const UI_DICTIONARIES = DEFAULT_UI_DICTIONARY;\n","\"use client\";\n\nimport type {\n CheckInOptions,\n CheckInResult,\n ClaimOptions,\n ClaimResult,\n SpotStatus as CoreSpotStatus,\n LocaleDictionary,\n PublicCheckInCondition,\n PublicRallyConfig,\n PublicReward,\n PublicSpotItem,\n RallyConfig,\n RallyInventoryState,\n RewardState,\n StampRallyClient,\n StampRallyProgress,\n StampRallyState,\n UserRallyState,\n} from \"@stamprally/core\";\nimport { DEFAULT_UI_DICTIONARY } from \"./locales/index.js\";\n\nexport { DEFAULT_UI_DICTIONARY, UI_DICTIONARIES } from \"./locales/index.js\";\n\nimport {\n calculateProgress,\n evaluateSpotStatus,\n getCurrentGeoContext,\n isNfcSupported,\n isQrSupported,\n readNfcContext,\n readQrContext,\n resolveLocalizedText,\n} from \"@stamprally/core\";\nimport {\n type ComponentType,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport type ViewerClassName =\n | \"root\"\n | \"header\"\n | \"card\"\n | \"condition\"\n | \"slot\"\n | \"badge\"\n | \"modal\"\n | \"button\"\n | \"action\"\n | \"feedback\"\n | \"reward\"\n | \"footer\";\nexport type ViewerStyle = CSSProperties & {\n readonly [key: `--${string}`]: string | number | undefined;\n};\nexport type ViewerStyles = Partial<Record<ViewerClassName, ViewerStyle>>;\nexport type ViewerClassNames = Partial<Record<ViewerClassName, string>>;\nexport type SpotStatus = CoreSpotStatus;\n\nexport interface ConditionRendererProps<TLocale extends string = string> {\n readonly spot: PublicSpotItem<TLocale>;\n readonly condition: PublicCheckInCondition;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly disabled: boolean;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n // biome-ignore lint/suspicious/noConfusingVoidType: custom renderers may fire-and-forget while built-ins await feedback.\n readonly onSubmit: (proof: unknown) => void | Promise<unknown>;\n}\nexport type ConditionRenderer<TLocale extends string = string> = ComponentType<\n ConditionRendererProps<TLocale>\n>;\n\nexport interface SpotCardProps<TLocale extends string = string> {\n readonly spot: PublicSpotItem<TLocale>;\n readonly state: UserRallyState;\n readonly status: SpotStatus;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly children: ReactNode;\n}\nexport interface RewardCardProps<TLocale extends string = string> {\n readonly reward: PublicReward<TLocale>;\n readonly state: RewardState | undefined;\n readonly inventory?: RallyInventoryState;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly onClaim:\n | ((rewardId: string, options?: ClaimOptions) => Promise<ClaimResult>)\n | undefined;\n}\nexport interface RallyViewerSlots<TLocale extends string = string> {\n readonly headerSlot?:\n | ReactNode\n | ((props: {\n readonly config: PublicRallyConfig<TLocale>;\n readonly state: UserRallyState;\n }) => ReactNode);\n readonly footerSlot?: ReactNode;\n readonly renderSpotCard?: (props: SpotCardProps<TLocale>) => ReactNode;\n readonly renderRewardCard?: (props: RewardCardProps<TLocale>) => ReactNode;\n readonly renderStatusBadge?: (props: { readonly status: SpotStatus }) => ReactNode;\n readonly renderVerifyingState?: () => ReactNode;\n readonly renderSuccessFeedback?: (result: CheckInResult) => ReactNode;\n readonly renderErrorFeedback?: (error: string) => ReactNode;\n}\n\nexport interface RallyViewerAdapter<TLocale extends string = string> {\n readonly config: PublicRallyConfig<TLocale>;\n readonly onCheckIn: (\n spotId: string,\n proof: unknown,\n options?: CheckInOptions,\n ) => Promise<CheckInResult>;\n readonly onClaimReward?: (rewardId: string, options?: ClaimOptions) => Promise<ClaimResult>;\n}\nexport interface RallyViewerProps<TLocale extends string = string>\n extends RallyViewerSlots<TLocale> {\n readonly config?: PublicRallyConfig<TLocale>;\n readonly client?: StampRallyClient;\n readonly adapter?: RallyViewerAdapter<TLocale>;\n readonly locale: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n readonly style?: ViewerStyle;\n readonly customConditionRenderers?: Partial<\n Record<PublicCheckInCondition[\"type\"], ConditionRenderer<TLocale>>\n >;\n}\n\nconst label = <TLocale extends string>(\n dictionary: LocaleDictionary<TLocale> | undefined,\n locale: TLocale,\n key: string,\n fallback: string,\n): string =>\n dictionary?.[locale]?.[key] ?? DEFAULT_UI_DICTIONARY[locale as \"ja\" | \"en\"]?.[key] ?? fallback;\nconst join = (...names: ReadonlyArray<string | undefined>): string | undefined => {\n const value = names.filter((name): name is string => name !== undefined && name !== \"\").join(\" \");\n return value === \"\" ? undefined : value;\n};\ntype VerificationStatus = \"idle\" | \"loading\" | \"success\" | \"error\";\n\nfunction DefaultCondition<TLocale extends string>({\n condition,\n dictionary,\n locale,\n disabled,\n classNames,\n styles,\n onSubmit,\n}: ConditionRendererProps<TLocale>): ReactElement {\n const [value, setValue] = useState(\"\");\n const [status, setStatus] = useState<VerificationStatus>(\"idle\");\n const [error, setError] = useState<string | null>(null);\n const videoRef = useRef<HTMLVideoElement>(null);\n const text = (key: string, fallback: string): string => label(dictionary, locale, key, fallback);\n const verify = async (proof: unknown): Promise<void> => {\n setStatus(\"loading\");\n setError(null);\n try {\n const result = await onSubmit(proof);\n if (\n result !== undefined &&\n typeof result === \"object\" &&\n result !== null &&\n \"ok\" in result &&\n result.ok === false\n ) {\n setStatus(\"error\");\n setError(text(\"verificationFailed\", \"Verification failed.\"));\n } else setStatus(\"success\");\n } catch {\n setStatus(\"error\");\n setError(text(\"verificationFailed\", \"Verification failed.\"));\n }\n };\n const readLocation = (): void => {\n setStatus(\"loading\");\n void getCurrentGeoContext().then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n const readNfc = (): void => {\n setStatus(\"loading\");\n void readNfcContext().then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n const scanQr = (): void => {\n if (videoRef.current === null) return;\n setStatus(\"loading\");\n void readQrContext(videoRef.current).then((result) => {\n if (result.ok) void verify(result.value);\n else {\n setStatus(\"error\");\n setError(result.error.message);\n }\n });\n };\n return (\n <div>\n {condition.type === \"qr\" && (\n <>\n <label>\n {text(\"qrValue\", \"QR value\")}\n <input\n aria-label={text(\"qrValue\", \"QR value\")}\n placeholder={condition.qrEntryUrl ?? text(\"qrPlaceholder\", \"Paste a QR value\")}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n />\n </label>\n <video\n ref={videoRef}\n aria-label={text(\"qrCamera\", \"QR camera\")}\n hidden={!isQrSupported()}\n >\n <track kind=\"captions\" />\n </video>\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || !isQrSupported()}\n onClick={scanQr}\n >\n {text(\"scanQr\", \"Scan QR\")}\n </button>\n </>\n )}\n {condition.type === \"gps\" && (\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled}\n onClick={readLocation}\n >\n {text(\"checkLocation\", \"Check location\")}\n </button>\n )}\n {condition.type === \"nfc\" && (\n <button\n type=\"button\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || !isNfcSupported()}\n onClick={readNfc}\n >\n {text(\"readNfc\", \"Read NFC\")}\n </button>\n )}\n {(condition.type === \"passcode\" ||\n condition.type === \"custom\" ||\n condition.type === \"qr\") && (\n <form\n onSubmit={(event) => {\n event.preventDefault();\n void verify(value);\n }}\n >\n <label>\n {text(\n condition.type === \"passcode\" ? \"passcode\" : \"proof\",\n condition.type === \"passcode\" ? \"Passcode\" : \"Proof\",\n )}\n <input\n aria-label={text(\"proof\", \"Proof\")}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n />\n </label>\n <button\n type=\"submit\"\n className={join(\"sry-action\", classNames?.action, classNames?.button)}\n style={styles?.button ?? styles?.action}\n disabled={disabled || value.trim() === \"\"}\n >\n {text(\"checkIn\", \"Check in\")}\n </button>\n </form>\n )}\n <div\n className={join(\"sry-feedback\", classNames?.feedback)}\n style={styles?.feedback}\n aria-live=\"polite\"\n role={status === \"error\" ? \"alert\" : undefined}\n >\n {status === \"loading\" && text(\"verifying\", \"Verifying…\")}\n {status === \"success\" && text(\"verified\", \"Verified\")}\n {status === \"error\" && (error ?? text(\"verificationFailed\", \"Verification failed.\"))}\n </div>\n </div>\n );\n}\n\nfunction DefaultRewardCard<TLocale extends string>({\n reward,\n state,\n inventory,\n locale,\n dictionary,\n onClaim,\n classNames,\n styles,\n}: RewardCardProps<TLocale> & {\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n}): ReactElement {\n const status = state?.status ?? \"LOCKED\";\n const configuredRemaining =\n inventory?.rewardRemaining?.[reward.id] ??\n (reward.stockLimit === undefined\n ? undefined\n : Math.max(0, reward.stockLimit - (state?.redeemedCount ?? 0)));\n const sharedRemaining = inventory?.sharedRemaining;\n const unavailable =\n status !== \"AVAILABLE\" ||\n onClaim === undefined ||\n sharedRemaining === 0 ||\n configuredRemaining === 0;\n const expiry = reward.validUntil === undefined ? undefined : new Date(reward.validUntil);\n return (\n <article className={classNames?.reward} style={styles?.reward}>\n <h3>{resolveLocalizedText(reward.title, locale)}</h3>\n {reward.description !== undefined && (\n <p>{resolveLocalizedText(reward.description, locale)}</p>\n )}\n {sharedRemaining !== undefined && (\n <span>\n {label(dictionary, locale, \"reward.sharedRemaining\", \"Overall remaining\")}:{\" \"}\n {sharedRemaining}\n </span>\n )}\n {configuredRemaining !== undefined && (\n <>\n {configuredRemaining <= 3 && (\n <span>{label(dictionary, locale, \"reward.lowStock\", \"Only a few left\")}</span>\n )}\n <span>\n {`${configuredRemaining} ${label(dictionary, locale, \"reward.remaining\", \"remaining\")}`}\n </span>\n </>\n )}\n {expiry !== undefined && !Number.isNaN(expiry.getTime()) && (\n <time dateTime={reward.validUntil}>\n {label(dictionary, locale, \"reward.validUntil\", \"Valid until\")}:{\" \"}\n {expiry.toLocaleString(locale)}\n </time>\n )}\n <button\n type=\"button\"\n className={join(classNames?.reward, classNames?.button)}\n style={styles?.button}\n disabled={unavailable}\n onClick={() => {\n if (onClaim !== undefined) void onClaim(reward.id);\n }}\n >\n {label(dictionary, locale, `status.${status.toLowerCase()}`, status)}\n </button>\n </article>\n );\n}\n\nexport function RallyViewer<TLocale extends string = string>({\n config: providedConfig,\n client,\n adapter,\n locale,\n dictionary,\n classNames = {},\n styles = {},\n style,\n customConditionRenderers = {},\n headerSlot,\n footerSlot,\n renderSpotCard,\n renderRewardCard,\n renderStatusBadge,\n renderVerifyingState,\n renderSuccessFeedback,\n renderErrorFeedback,\n}: RallyViewerProps<TLocale>): ReactElement {\n const config = providedConfig ?? client?.getConfig() ?? adapter?.config;\n const [state, setState] = useState<UserRallyState | null>(() => client?.getState() ?? null);\n const [busy, setBusy] = useState<string | null>(null);\n const [feedback, setFeedback] = useState<CheckInResult | null>(null);\n useEffect(() => {\n if (client === undefined) return;\n const unsubscribe = client.subscribe(setState);\n void client.init().then(setState);\n return unsubscribe;\n }, [client]);\n if (config === undefined) throw new Error(\"RallyViewer requires config, client, or adapter.\");\n const currentState = state ?? {\n rallyId: config.id,\n userId: null,\n records: [],\n rewards: [],\n updatedAt: \"\",\n };\n const progress = useMemo<StampRallyProgress>(\n () => calculateProgress(currentState, config),\n [config, currentState],\n );\n const checkIn =\n adapter?.onCheckIn ??\n (client === undefined\n ? undefined\n : (spotId: string, proof: unknown, options?: CheckInOptions) =>\n client.checkIn(spotId, proof, options));\n const claim =\n adapter?.onClaimReward ??\n (client === undefined\n ? undefined\n : (rewardId: string, options?: ClaimOptions) => client.claimReward(rewardId, options));\n const submit = useCallback(\n async (spotId: string, proof: unknown): Promise<CheckInResult | undefined> => {\n if (checkIn === undefined) return undefined;\n const target = config.spots.find((spot) => spot.id === spotId);\n if (target !== undefined && evaluateSpotStatus(target, currentState) === \"LOCKED\") {\n const result: CheckInResult = {\n ok: false,\n error: {\n code: \"PREREQUISITES_NOT_MET\",\n spotId,\n message: \"Complete the prerequisite spots before checking in.\",\n },\n };\n setFeedback(result);\n return result;\n }\n setBusy(spotId);\n const result = await checkIn(spotId, proof).finally(() => setBusy(null));\n setFeedback(result);\n return result;\n },\n [checkIn, config.spots, currentState],\n );\n return (\n <section\n className={classNames.root}\n style={styles.root ?? style}\n aria-label={label(dictionary, locale, \"viewer\", \"Stamp rally\")}\n >\n <header className={classNames.header} style={styles.header}>\n {typeof headerSlot === \"function\"\n ? headerSlot({ config, state: currentState })\n : headerSlot}\n {headerSlot === undefined && (\n <h1>{resolveLocalizedText(config.title, locale) || config.id}</h1>\n )}\n <progress\n aria-label={label(dictionary, locale, \"progress\", \"Progress\")}\n max={100}\n value={progress.percentage}\n />\n <span>\n {progress.acquired}/{progress.total}\n </span>\n </header>\n {busy !== null &&\n (renderVerifyingState?.() ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"status\">\n {label(dictionary, locale, \"verifying\", \"Verifying…\")}\n </div>\n ))}\n {feedback?.ok === true &&\n (renderSuccessFeedback?.(feedback) ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"status\">\n {label(dictionary, locale, \"verified\", \"Verified\")}\n </div>\n ))}\n {feedback?.ok === false &&\n (renderErrorFeedback?.(\n \"message\" in feedback.error ? feedback.error.message : feedback.error.code,\n ) ?? (\n <div className={classNames.feedback} style={styles.feedback} role=\"alert\">\n {\"message\" in feedback.error ? feedback.error.message : feedback.error.code}\n </div>\n ))}\n <div>\n {config.spots.map((spot) => {\n const status: SpotStatus =\n busy === spot.id ? \"VERIFYING\" : evaluateSpotStatus(spot, currentState);\n const claimed = status === \"CLAIMED\";\n const locked = status === \"LOCKED\";\n const children = spot.conditions.map((condition) => {\n const Renderer = customConditionRenderers[condition.type] ?? DefaultCondition;\n return (\n <div\n className={classNames.condition}\n style={styles.condition}\n key={`${spot.id}-${condition.type}-${JSON.stringify(condition)}`}\n >\n <Renderer\n spot={spot}\n condition={condition}\n locale={locale}\n {...(dictionary === undefined ? {} : { dictionary })}\n disabled={busy !== null || claimed || locked}\n {...(Object.keys(classNames).length === 0 ? {} : { classNames })}\n {...(Object.keys(styles).length === 0 ? {} : { styles })}\n onSubmit={(proof) => submit(spot.id, proof)}\n />\n </div>\n );\n });\n const props: SpotCardProps<TLocale> = {\n spot,\n state: currentState,\n status,\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n children,\n };\n return (\n <div\n key={spot.id}\n className={classNames.card}\n style={styles.card}\n data-status={status}\n aria-disabled={locked}\n >\n {renderSpotCard?.(props) ?? (\n <article>\n {spot.iconUrl !== undefined && (\n <img src={spot.iconUrl} alt=\"\" width={32} height={32} />\n )}\n <h2>{resolveLocalizedText(spot.name, locale)}</h2>\n {spot.imageUrl !== undefined && <img src={spot.imageUrl} alt=\"\" loading=\"lazy\" />}\n {spot.description !== undefined && (\n <p>{resolveLocalizedText(spot.description, locale)}</p>\n )}\n {spot.hint !== undefined && <p>{resolveLocalizedText(spot.hint, locale)}</p>}\n {spot.externalReferences !== undefined && spot.externalReferences.length > 0 && (\n <span className={classNames.badge} style={styles.badge}>\n {label(dictionary, locale, \"externalReferences\", \"External references\")} (\n {spot.externalReferences.length})\n </span>\n )}\n {renderStatusBadge?.({ status }) ?? (\n <span className={classNames.badge} style={styles.badge}>\n {label(dictionary, locale, `status.${status.toLowerCase()}`, status)}\n </span>\n )}\n {locked && (\n <p role=\"status\">\n {label(\n dictionary,\n locale,\n \"prerequisitesNotMet\",\n \"Complete the prerequisite spots before checking in.\",\n )}\n </p>\n )}\n {children}\n </article>\n )}\n </div>\n );\n })}\n </div>\n <section aria-label={label(dictionary, locale, \"rewards\", \"Rewards\")}>\n {config.rewards.map((reward) => {\n const props: RewardCardProps<TLocale> = {\n reward,\n state: currentState.rewards.find((item) => item.rewardId === reward.id),\n ...(currentState.inventory === undefined ? {} : { inventory: currentState.inventory }),\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n onClaim: claim,\n };\n return (\n <div key={reward.id} className={classNames.reward} style={styles.reward}>\n {renderRewardCard?.(props) ?? (\n <DefaultRewardCard {...props} classNames={classNames} styles={styles} />\n )}\n </div>\n );\n })}\n </section>\n <footer className={classNames.footer} style={styles.footer}>\n {footerSlot}\n </footer>\n </section>\n );\n}\n\nexport interface StampSheetProps<TLocale extends string = string>\n extends RallyViewerSlots<TLocale> {\n readonly config: RallyConfig<TLocale>;\n readonly state?: StampRallyState | null;\n readonly title?: string;\n readonly progress?: StampRallyProgress;\n readonly locale?: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly classNames?: ViewerClassNames;\n readonly styles?: ViewerStyles;\n readonly style?: ViewerStyle;\n}\nexport function StampSheet<TLocale extends string = string>({\n config,\n state,\n title,\n progress,\n locale = \"en\" as TLocale,\n dictionary,\n classNames = {},\n styles = {},\n style,\n headerSlot,\n footerSlot,\n renderSpotCard,\n renderStatusBadge,\n}: StampSheetProps<TLocale>): ReactElement {\n const currentState = state ?? {\n rallyId: config.id,\n userId: null,\n records: [],\n rewards: [],\n updatedAt: \"\",\n };\n const current = progress ?? calculateProgress(currentState, config);\n return (\n <section\n className={classNames.root}\n style={styles.root ?? style}\n aria-label={title ?? label(dictionary, locale, \"stampSheet\", \"Stamp sheet\")}\n >\n <header className={classNames.header} style={styles.header}>\n {typeof headerSlot === \"function\"\n ? headerSlot({ config, state: currentState })\n : (headerSlot ?? <h2>{title ?? resolveLocalizedText(config.title, locale)}</h2>)}\n <progress max={100} value={current.percentage} />\n </header>\n <div>\n {config.spots.map((spot) => {\n const status: SpotStatus = evaluateSpotStatus(spot, currentState);\n const props: SpotCardProps<TLocale> = {\n spot,\n state: currentState,\n status,\n locale,\n ...(dictionary === undefined ? {} : { dictionary }),\n children: (\n <span className={classNames.slot} style={styles.slot}>\n {status === \"LOCKED\"\n ? label(dictionary, locale, \"status.locked\", \"🔒 LOCKED\")\n : status === \"CLAIMED\"\n ? label(dictionary, locale, \"status.claimed\", \"CLAIMED\")\n : label(dictionary, locale, \"status.unclaimed\", \"UNCLAIMED\")}\n </span>\n ),\n };\n return (\n <div\n key={spot.id}\n className={classNames.card}\n style={styles.card}\n data-status={status}\n aria-disabled={status === \"LOCKED\"}\n >\n {renderSpotCard?.(props) ?? (\n <span className={classNames.slot} style={styles.slot}>\n {spot.iconUrl !== undefined && (\n <img src={spot.iconUrl} alt=\"\" width={24} height={24} />\n )}\n {resolveLocalizedText(spot.name, locale)}{\" \"}\n {spot.description !== undefined && (\n <small>{resolveLocalizedText(spot.description, locale)}</small>\n )}{\" \"}\n {renderStatusBadge?.({ status }) ??\n label(dictionary, locale, `status.${status.toLowerCase()}`, status)}\n </span>\n )}\n </div>\n );\n })}\n </div>\n <footer className={classNames.footer} style={styles.footer}>\n {footerSlot}\n </footer>\n </section>\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stamprally/ui",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "Accessible participant UI components for stamp rallies.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -13,6 +13,9 @@
13
13
  },
14
14
  "homepage": "https://github.com/nitta-a/stamprally-core-app#readme",
15
15
  "type": "module",
16
+ "engines": {
17
+ "node": ">=22.0.0"
18
+ },
16
19
  "sideEffects": false,
17
20
  "files": [
18
21
  "dist"
@@ -29,8 +32,8 @@
29
32
  "./styles.css": "./dist/index.css"
30
33
  },
31
34
  "dependencies": {
32
- "@stamprally/core": "0.13.0",
33
- "@stamprally/react": "0.13.0"
35
+ "@stamprally/core": "0.15.0",
36
+ "@stamprally/react": "0.15.0"
34
37
  },
35
38
  "peerDependencies": {
36
39
  "react": "^18.0.0 || ^19.0.0",
@@ -47,7 +50,7 @@
47
50
  "vitest": "^4.1.11"
48
51
  },
49
52
  "scripts": {
50
- "build": "tsup && node ../../scripts/copy-package-css.mjs packages/ui",
53
+ "build": "tsup && node ../../scripts/copy-package-css.mjs packages/ui && node ../../scripts/ensure-client-directive.mjs .",
51
54
  "dev": "tsup --watch",
52
55
  "test": "vitest run",
53
56
  "typecheck": "tsc -p tsconfig.json"