@stamprally/ui 0.17.0 → 0.18.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 v0.17.0
1
+ # @stamprally/ui v0.18.0
2
2
 
3
3
  Participant-facing React components for `@stamprally/core`.
4
4
 
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
+ var jsxRuntime = require('react/jsx-runtime');
4
5
  var core = require('@stamprally/core');
5
6
  var react = require('react');
6
- var jsxRuntime = require('react/jsx-runtime');
7
7
 
8
8
  // src/locales/index.ts
9
9
  var DEFAULT_UI_DICTIONARY = {
@@ -37,7 +37,11 @@ var DEFAULT_UI_DICTIONARY = {
37
37
  "reward.lowStock": "Only a few left",
38
38
  "reward.remaining": "remaining",
39
39
  "reward.sharedRemaining": "Overall remaining",
40
- "reward.validUntil": "Valid until"
40
+ "reward.validUntil": "Valid until",
41
+ "sync.syncing": "Sending unsynced operations to the server...",
42
+ "sync.offline": "Recording offline",
43
+ "sync.unsynced": "unsynced",
44
+ "sync.rollback": "Some check-ins were rolled back by the server"
41
45
  },
42
46
  ja: {
43
47
  viewer: "\u30B9\u30BF\u30F3\u30D7\u30E9\u30EA\u30FC",
@@ -69,10 +73,53 @@ var DEFAULT_UI_DICTIONARY = {
69
73
  "reward.lowStock": "\u6B8B\u308A\u308F\u305A\u304B",
70
74
  "reward.remaining": "\u6B8B\u308A",
71
75
  "reward.sharedRemaining": "\u5168\u4F53\u3067\u6B8B\u308A",
72
- "reward.validUntil": "\u6709\u52B9\u671F\u9650"
76
+ "reward.validUntil": "\u6709\u52B9\u671F\u9650",
77
+ "sync.syncing": "\u672A\u540C\u671F\u306E\u64CD\u4F5C\u3092\u30B5\u30FC\u30D0\u30FC\u3078\u9001\u4FE1\u4E2D...",
78
+ "sync.offline": "\u30AA\u30D5\u30E9\u30A4\u30F3\u3067\u8A18\u9332\u4E2D",
79
+ "sync.unsynced": "\u672A\u540C\u671F",
80
+ "sync.rollback": "\u4E00\u90E8\u306E\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3\u304C\u30B5\u30FC\u30D0\u30FC\u306B\u3088\u308A\u53D6\u308A\u6D88\u3055\u308C\u307E\u3057\u305F"
73
81
  }
74
82
  };
75
83
  var UI_DICTIONARIES = DEFAULT_UI_DICTIONARY;
84
+ function text(dictionary, locale, key, fallback) {
85
+ return dictionary?.[locale]?.[key] ?? DEFAULT_UI_DICTIONARY[locale]?.[key] ?? fallback;
86
+ }
87
+ function SyncStatusBanner({
88
+ status,
89
+ locale = "en",
90
+ dictionary,
91
+ className,
92
+ style
93
+ }) {
94
+ if (status.isSyncing)
95
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style, role: "status", "aria-live": "polite", children: [
96
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\u27F3" }),
97
+ " ",
98
+ text(dictionary, locale, "sync.syncing", "\u672A\u540C\u671F\u306E\u64CD\u4F5C\u3092\u30B5\u30FC\u30D0\u30FC\u3078\u9001\u4FE1\u4E2D...")
99
+ ] });
100
+ if (status.rejectedHistory.length > 0) {
101
+ const detail = status.rejectedHistory[status.rejectedHistory.length - 1]?.reason.message;
102
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style, role: "alert", "aria-live": "assertive", children: [
103
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: text(
104
+ dictionary,
105
+ locale,
106
+ "sync.rollback",
107
+ "\u4E00\u90E8\u306E\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3\u304C\u30B5\u30FC\u30D0\u30FC\u306B\u3088\u308A\u53D6\u308A\u6D88\u3055\u308C\u307E\u3057\u305F"
108
+ ) }),
109
+ detail === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx("span", { children: detail })
110
+ ] });
111
+ }
112
+ if (status.pendingCount > 0)
113
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style, role: "status", "aria-live": "polite", children: [
114
+ text(dictionary, locale, "sync.offline", "\u30AA\u30D5\u30E9\u30A4\u30F3\u3067\u8A18\u9332\u4E2D"),
115
+ " (",
116
+ text(dictionary, locale, "sync.unsynced", "\u672A\u540C\u671F"),
117
+ ": ",
118
+ status.pendingCount,
119
+ "\u4EF6)"
120
+ ] });
121
+ return null;
122
+ }
76
123
  var label = (dictionary, locale, key, fallback) => dictionary?.[locale]?.[key] ?? DEFAULT_UI_DICTIONARY[locale]?.[key] ?? fallback;
77
124
  var join = (...names) => {
78
125
  const value = names.filter((name) => name !== void 0 && name !== "").join(" ");
@@ -91,7 +138,7 @@ function DefaultCondition({
91
138
  const [status, setStatus] = react.useState("idle");
92
139
  const [error, setError] = react.useState(null);
93
140
  const videoRef = react.useRef(null);
94
- const text = (key, fallback) => label(dictionary, locale, key, fallback);
141
+ const text2 = (key, fallback) => label(dictionary, locale, key, fallback);
95
142
  const verify = async (proof) => {
96
143
  setStatus("loading");
97
144
  setError(null);
@@ -99,11 +146,11 @@ function DefaultCondition({
99
146
  const result = await onSubmit(proof);
100
147
  if (result !== void 0 && typeof result === "object" && result !== null && "ok" in result && result.ok === false) {
101
148
  setStatus("error");
102
- setError(text("verificationFailed", "Verification failed."));
149
+ setError(text2("verificationFailed", "Verification failed."));
103
150
  } else setStatus("success");
104
151
  } catch {
105
152
  setStatus("error");
106
- setError(text("verificationFailed", "Verification failed."));
153
+ setError(text2("verificationFailed", "Verification failed."));
107
154
  }
108
155
  };
109
156
  const readLocation = () => {
@@ -140,12 +187,12 @@ function DefaultCondition({
140
187
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
141
188
  condition.type === "qr" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
142
189
  /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
143
- text("qrValue", "QR value"),
190
+ text2("qrValue", "QR value"),
144
191
  /* @__PURE__ */ jsxRuntime.jsx(
145
192
  "input",
146
193
  {
147
- "aria-label": text("qrValue", "QR value"),
148
- placeholder: condition.qrEntryUrl ?? text("qrPlaceholder", "Paste a QR value"),
194
+ "aria-label": text2("qrValue", "QR value"),
195
+ placeholder: condition.qrEntryUrl ?? text2("qrPlaceholder", "Paste a QR value"),
149
196
  value,
150
197
  onChange: (event) => setValue(event.target.value)
151
198
  }
@@ -155,7 +202,7 @@ function DefaultCondition({
155
202
  "video",
156
203
  {
157
204
  ref: videoRef,
158
- "aria-label": text("qrCamera", "QR camera"),
205
+ "aria-label": text2("qrCamera", "QR camera"),
159
206
  hidden: !core.isQrSupported(),
160
207
  children: /* @__PURE__ */ jsxRuntime.jsx("track", { kind: "captions" })
161
208
  }
@@ -168,7 +215,7 @@ function DefaultCondition({
168
215
  style: styles?.button ?? styles?.action,
169
216
  disabled: disabled || !core.isQrSupported(),
170
217
  onClick: scanQr,
171
- children: text("scanQr", "Scan QR")
218
+ children: text2("scanQr", "Scan QR")
172
219
  }
173
220
  )
174
221
  ] }),
@@ -180,7 +227,7 @@ function DefaultCondition({
180
227
  style: styles?.button ?? styles?.action,
181
228
  disabled,
182
229
  onClick: readLocation,
183
- children: text("checkLocation", "Check location")
230
+ children: text2("checkLocation", "Check location")
184
231
  }
185
232
  ),
186
233
  condition.type === "nfc" && /* @__PURE__ */ jsxRuntime.jsx(
@@ -191,7 +238,7 @@ function DefaultCondition({
191
238
  style: styles?.button ?? styles?.action,
192
239
  disabled: disabled || !core.isNfcSupported(),
193
240
  onClick: readNfc,
194
- children: text("readNfc", "Read NFC")
241
+ children: text2("readNfc", "Read NFC")
195
242
  }
196
243
  ),
197
244
  (condition.type === "passcode" || condition.type === "custom" || condition.type === "qr") && /* @__PURE__ */ jsxRuntime.jsxs(
@@ -203,14 +250,14 @@ function DefaultCondition({
203
250
  },
204
251
  children: [
205
252
  /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
206
- text(
253
+ text2(
207
254
  condition.type === "passcode" ? "passcode" : "proof",
208
255
  condition.type === "passcode" ? "Passcode" : "Proof"
209
256
  ),
210
257
  /* @__PURE__ */ jsxRuntime.jsx(
211
258
  "input",
212
259
  {
213
- "aria-label": text("proof", "Proof"),
260
+ "aria-label": text2("proof", "Proof"),
214
261
  value,
215
262
  onChange: (event) => setValue(event.target.value)
216
263
  }
@@ -223,7 +270,7 @@ function DefaultCondition({
223
270
  className: join("sry-action", classNames?.action, classNames?.button),
224
271
  style: styles?.button ?? styles?.action,
225
272
  disabled: disabled || value.trim() === "",
226
- children: text("checkIn", "Check in")
273
+ children: text2("checkIn", "Check in")
227
274
  }
228
275
  )
229
276
  ]
@@ -237,9 +284,9 @@ function DefaultCondition({
237
284
  "aria-live": "polite",
238
285
  role: status === "error" ? "alert" : void 0,
239
286
  children: [
240
- status === "loading" && text("verifying", "Verifying\u2026"),
241
- status === "success" && text("verified", "Verified"),
242
- status === "error" && (error ?? text("verificationFailed", "Verification failed."))
287
+ status === "loading" && text2("verifying", "Verifying\u2026"),
288
+ status === "success" && text2("verified", "Verified"),
289
+ status === "error" && (error ?? text2("verificationFailed", "Verification failed."))
243
290
  ]
244
291
  }
245
292
  )
@@ -312,12 +359,22 @@ function RallyViewer({
312
359
  renderStatusBadge,
313
360
  renderVerifyingState,
314
361
  renderSuccessFeedback,
315
- renderErrorFeedback
362
+ renderErrorFeedback,
363
+ renderSyncStatus,
364
+ showSyncStatus = true
316
365
  }) {
317
366
  const config = providedConfig ?? client?.getConfig() ?? adapter?.config;
318
367
  const [state, setState] = react.useState(() => client?.getState() ?? null);
319
368
  const [busy, setBusy] = react.useState(null);
320
369
  const [feedback, setFeedback] = react.useState(null);
370
+ const [syncStatus, setSyncStatus] = react.useState(() => ({
371
+ syncState: client?.syncState ?? "idle",
372
+ isSyncing: client?.syncState === "syncing",
373
+ pendingCount: client?.pendingCount ?? 0,
374
+ rejectedHistory: client?.rejectedHistory ?? [],
375
+ storageCapability: client?.storageCapability ?? "custom",
376
+ isStoragePersistent: client?.isStoragePersistent ?? true
377
+ }));
321
378
  react.useEffect(() => {
322
379
  if (client === void 0) return;
323
380
  const unsubscribe = client.subscribe(setState);
@@ -328,6 +385,19 @@ function RallyViewer({
328
385
  if (client === void 0 || onSyncEvent === void 0) return;
329
386
  return client.subscribeSyncEvents(onSyncEvent);
330
387
  }, [client, onSyncEvent]);
388
+ react.useEffect(() => {
389
+ if (client === void 0) return;
390
+ const update = () => setSyncStatus({
391
+ syncState: client.syncState,
392
+ isSyncing: client.syncState === "syncing",
393
+ pendingCount: client.pendingCount,
394
+ rejectedHistory: client.rejectedHistory,
395
+ storageCapability: client.storageCapability,
396
+ isStoragePersistent: client.isStoragePersistent
397
+ });
398
+ update();
399
+ return client.subscribeSyncState(update);
400
+ }, [client]);
331
401
  if (config === void 0) throw new Error("RallyViewer requires config, client, or adapter.");
332
402
  const currentState = state ?? {
333
403
  rallyId: config.id,
@@ -394,6 +464,16 @@ function RallyViewer({
394
464
  feedback?.ok === false && (renderErrorFeedback?.(
395
465
  "message" in feedback.error ? feedback.error.message : feedback.error.code
396
466
  ) ?? /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames.feedback, style: styles.feedback, role: "alert", children: "message" in feedback.error ? feedback.error.message : feedback.error.code })),
467
+ showSyncStatus && (renderSyncStatus?.(syncStatus) ?? /* @__PURE__ */ jsxRuntime.jsx(
468
+ SyncStatusBanner,
469
+ {
470
+ status: syncStatus,
471
+ locale,
472
+ ...dictionary === void 0 ? {} : { dictionary },
473
+ ...classNames.feedback === void 0 ? {} : { className: classNames.feedback },
474
+ ...styles.feedback === void 0 ? {} : { style: styles.feedback }
475
+ }
476
+ )),
397
477
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: config.spots.map((spot) => {
398
478
  const status = busy === spot.id ? "VERIFYING" : core.evaluateSpotStatus(spot, currentState);
399
479
  const claimed = status === "CLAIMED";
@@ -550,6 +630,7 @@ function StampSheet({
550
630
  exports.DEFAULT_UI_DICTIONARY = DEFAULT_UI_DICTIONARY;
551
631
  exports.RallyViewer = RallyViewer;
552
632
  exports.StampSheet = StampSheet;
633
+ exports.SyncStatusBanner = SyncStatusBanner;
553
634
  exports.UI_DICTIONARIES = UI_DICTIONARIES;
554
635
  //# sourceMappingURL=index.cjs.map
555
636
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
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 SyncEventListener,\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 readonly onSyncEvent?: SyncEventListener;\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 onSyncEvent,\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 useEffect(() => {\n if (client === undefined || onSyncEvent === undefined) return;\n return client.subscribeSyncEvents(onSyncEvent);\n }, [client, onSyncEvent]);\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"]}
1
+ {"version":3,"sources":["../src/locales/index.ts","../src/components/SyncStatusBanner.tsx","../src/index.tsx"],"names":["jsx","useState","useRef","text","getCurrentGeoContext","readNfcContext","readQrContext","jsxs","Fragment","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 \"sync.syncing\": \"Sending unsynced operations to the server...\",\n \"sync.offline\": \"Recording offline\",\n \"sync.unsynced\": \"unsynced\",\n \"sync.rollback\": \"Some check-ins were rolled back by the server\",\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 \"sync.syncing\": \"未同期の操作をサーバーへ送信中...\",\n \"sync.offline\": \"オフラインで記録中\",\n \"sync.unsynced\": \"未同期\",\n \"sync.rollback\": \"一部のチェックインがサーバーにより取り消されました\",\n },\n};\n\nexport const UI_DICTIONARIES = DEFAULT_UI_DICTIONARY;\n","import type {\n LocaleDictionary,\n OfflineStorageCapability,\n RejectedOperationHistoryEntry,\n SyncState,\n} from \"@stamprally/core\";\nimport type { CSSProperties, ReactElement } from \"react\";\nimport { DEFAULT_UI_DICTIONARY } from \"../locales/index.js\";\n\nexport interface SyncStateContext {\n readonly syncState: SyncState;\n readonly isSyncing: boolean;\n readonly pendingCount: number;\n readonly rejectedHistory: ReadonlyArray<RejectedOperationHistoryEntry>;\n readonly storageCapability: OfflineStorageCapability;\n readonly isStoragePersistent: boolean;\n}\n\nexport interface SyncStatusBannerProps<TLocale extends string = string> {\n readonly status: SyncStateContext;\n readonly locale?: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly className?: string;\n readonly style?: CSSProperties;\n}\n\nfunction text<TLocale extends string>(\n dictionary: LocaleDictionary<TLocale> | undefined,\n locale: TLocale,\n key: string,\n fallback: string,\n): string {\n return (\n dictionary?.[locale]?.[key] ?? DEFAULT_UI_DICTIONARY[locale as \"ja\" | \"en\"]?.[key] ?? fallback\n );\n}\n\nexport function SyncStatusBanner<TLocale extends string = \"en\">({\n status,\n locale = \"en\" as TLocale,\n dictionary,\n className,\n style,\n}: SyncStatusBannerProps<TLocale>): ReactElement | null {\n if (status.isSyncing)\n return (\n <div className={className} style={style} role=\"status\" aria-live=\"polite\">\n <span aria-hidden=\"true\">⟳</span>{\" \"}\n {text(dictionary, locale, \"sync.syncing\", \"未同期の操作をサーバーへ送信中...\")}\n </div>\n );\n if (status.rejectedHistory.length > 0) {\n const detail = status.rejectedHistory[status.rejectedHistory.length - 1]?.reason.message;\n return (\n <div className={className} style={style} role=\"alert\" aria-live=\"assertive\">\n <strong>\n {text(\n dictionary,\n locale,\n \"sync.rollback\",\n \"一部のチェックインがサーバーにより取り消されました\",\n )}\n </strong>\n {detail === undefined ? null : <span>{detail}</span>}\n </div>\n );\n }\n if (status.pendingCount > 0)\n return (\n <div className={className} style={style} role=\"status\" aria-live=\"polite\">\n {text(dictionary, locale, \"sync.offline\", \"オフラインで記録中\")} (\n {text(dictionary, locale, \"sync.unsynced\", \"未同期\")}: {status.pendingCount}件)\n </div>\n );\n return null;\n}\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 SyncEventListener,\n UserRallyState,\n} from \"@stamprally/core\";\nimport { type SyncStateContext, SyncStatusBanner } from \"./components/SyncStatusBanner.js\";\nimport { DEFAULT_UI_DICTIONARY } from \"./locales/index.js\";\n\nexport type { SyncStateContext, SyncStatusBannerProps } from \"./components/SyncStatusBanner.js\";\nexport { SyncStatusBanner } from \"./components/SyncStatusBanner.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\";\n\nexport type ViewerSyncStateContext = SyncStateContext;\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 renderSyncStatus?: (status: SyncStateContext) => 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 readonly onSyncEvent?: SyncEventListener;\n readonly showSyncStatus?: boolean;\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 onSyncEvent,\n headerSlot,\n footerSlot,\n renderSpotCard,\n renderRewardCard,\n renderStatusBadge,\n renderVerifyingState,\n renderSuccessFeedback,\n renderErrorFeedback,\n renderSyncStatus,\n showSyncStatus = true,\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 const [syncStatus, setSyncStatus] = useState<SyncStateContext>(() => ({\n syncState: client?.syncState ?? \"idle\",\n isSyncing: client?.syncState === \"syncing\",\n pendingCount: client?.pendingCount ?? 0,\n rejectedHistory: client?.rejectedHistory ?? [],\n storageCapability: client?.storageCapability ?? \"custom\",\n isStoragePersistent: client?.isStoragePersistent ?? true,\n }));\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 useEffect(() => {\n if (client === undefined || onSyncEvent === undefined) return;\n return client.subscribeSyncEvents(onSyncEvent);\n }, [client, onSyncEvent]);\n useEffect(() => {\n if (client === undefined) return;\n const update = (): void =>\n setSyncStatus({\n syncState: client.syncState,\n isSyncing: client.syncState === \"syncing\",\n pendingCount: client.pendingCount,\n rejectedHistory: client.rejectedHistory,\n storageCapability: client.storageCapability,\n isStoragePersistent: client.isStoragePersistent,\n });\n update();\n return client.subscribeSyncState(update);\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 {showSyncStatus &&\n (renderSyncStatus?.(syncStatus) ?? (\n <SyncStatusBanner\n status={syncStatus}\n locale={locale}\n {...(dictionary === undefined ? {} : { dictionary })}\n {...(classNames.feedback === undefined ? {} : { className: classNames.feedback })}\n {...(styles.feedback === undefined ? {} : { style: styles.feedback })}\n />\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,11 +1,29 @@
1
- import { LocaleDictionary, PublicSpotItem, PublicCheckInCondition, PublicRallyConfig, UserRallyState, SpotStatus as SpotStatus$1, PublicReward, RewardState, RallyInventoryState, ClaimOptions, ClaimResult, CheckInResult, StampRallyClient, CheckInOptions, SyncEventListener, RallyConfig, StampRallyState, StampRallyProgress } from '@stamprally/core';
2
- import { ComponentType, CSSProperties, ReactNode, ReactElement } from 'react';
1
+ import { SyncState, RejectedOperationHistoryEntry, OfflineStorageCapability, LocaleDictionary, PublicSpotItem, PublicCheckInCondition, PublicRallyConfig, UserRallyState, SpotStatus as SpotStatus$1, PublicReward, RewardState, RallyInventoryState, ClaimOptions, ClaimResult, CheckInResult, StampRallyClient, CheckInOptions, SyncEventListener, RallyConfig, StampRallyState, StampRallyProgress } from '@stamprally/core';
2
+ import { CSSProperties, ReactElement, ComponentType, ReactNode } from 'react';
3
+
4
+ interface SyncStateContext {
5
+ readonly syncState: SyncState;
6
+ readonly isSyncing: boolean;
7
+ readonly pendingCount: number;
8
+ readonly rejectedHistory: ReadonlyArray<RejectedOperationHistoryEntry>;
9
+ readonly storageCapability: OfflineStorageCapability;
10
+ readonly isStoragePersistent: boolean;
11
+ }
12
+ interface SyncStatusBannerProps<TLocale extends string = string> {
13
+ readonly status: SyncStateContext;
14
+ readonly locale?: TLocale;
15
+ readonly dictionary?: LocaleDictionary<TLocale>;
16
+ readonly className?: string;
17
+ readonly style?: CSSProperties;
18
+ }
19
+ declare function SyncStatusBanner<TLocale extends string = "en">({ status, locale, dictionary, className, style, }: SyncStatusBannerProps<TLocale>): ReactElement | null;
3
20
 
4
21
  /** Complete built-in labels for the standard participant components. */
5
22
  declare const DEFAULT_UI_DICTIONARY: LocaleDictionary<"ja" | "en">;
6
23
  declare const UI_DICTIONARIES: Readonly<Record<"en" | "ja", Readonly<Record<string, string>>>>;
7
24
 
8
25
  type ViewerClassName = "root" | "header" | "card" | "condition" | "slot" | "badge" | "modal" | "button" | "action" | "feedback" | "reward" | "footer";
26
+ type ViewerSyncStateContext = SyncStateContext;
9
27
  type ViewerStyle = CSSProperties & {
10
28
  readonly [key: `--${string}`]: string | number | undefined;
11
29
  };
@@ -45,6 +63,7 @@ interface RallyViewerSlots<TLocale extends string = string> {
45
63
  readonly state: UserRallyState;
46
64
  }) => ReactNode);
47
65
  readonly footerSlot?: ReactNode;
66
+ readonly renderSyncStatus?: (status: SyncStateContext) => ReactNode;
48
67
  readonly renderSpotCard?: (props: SpotCardProps<TLocale>) => ReactNode;
49
68
  readonly renderRewardCard?: (props: RewardCardProps<TLocale>) => ReactNode;
50
69
  readonly renderStatusBadge?: (props: {
@@ -70,8 +89,9 @@ interface RallyViewerProps<TLocale extends string = string> extends RallyViewerS
70
89
  readonly style?: ViewerStyle;
71
90
  readonly customConditionRenderers?: Partial<Record<PublicCheckInCondition["type"], ConditionRenderer<TLocale>>>;
72
91
  readonly onSyncEvent?: SyncEventListener;
92
+ readonly showSyncStatus?: boolean;
73
93
  }
74
- declare function RallyViewer<TLocale extends string = string>({ config: providedConfig, client, adapter, locale, dictionary, classNames, styles, style, customConditionRenderers, onSyncEvent, headerSlot, footerSlot, renderSpotCard, renderRewardCard, renderStatusBadge, renderVerifyingState, renderSuccessFeedback, renderErrorFeedback, }: RallyViewerProps<TLocale>): ReactElement;
94
+ declare function RallyViewer<TLocale extends string = string>({ config: providedConfig, client, adapter, locale, dictionary, classNames, styles, style, customConditionRenderers, onSyncEvent, headerSlot, footerSlot, renderSpotCard, renderRewardCard, renderStatusBadge, renderVerifyingState, renderSuccessFeedback, renderErrorFeedback, renderSyncStatus, showSyncStatus, }: RallyViewerProps<TLocale>): ReactElement;
75
95
  interface StampSheetProps<TLocale extends string = string> extends RallyViewerSlots<TLocale> {
76
96
  readonly config: RallyConfig<TLocale>;
77
97
  readonly state?: StampRallyState | null;
@@ -85,4 +105,4 @@ interface StampSheetProps<TLocale extends string = string> extends RallyViewerSl
85
105
  }
86
106
  declare function StampSheet<TLocale extends string = string>({ config, state, title, progress, locale, dictionary, classNames, styles, style, headerSlot, footerSlot, renderSpotCard, renderStatusBadge, }: StampSheetProps<TLocale>): ReactElement;
87
107
 
88
- 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 };
108
+ export { type ConditionRenderer, type ConditionRendererProps, DEFAULT_UI_DICTIONARY, RallyViewer, type RallyViewerAdapter, type RallyViewerProps, type RallyViewerSlots, type RewardCardProps, type SpotCardProps, type SpotStatus, StampSheet, type StampSheetProps, type SyncStateContext, SyncStatusBanner, type SyncStatusBannerProps, UI_DICTIONARIES, type ViewerClassName, type ViewerClassNames, type ViewerStyle, type ViewerStyles, type ViewerSyncStateContext };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,29 @@
1
- import { LocaleDictionary, PublicSpotItem, PublicCheckInCondition, PublicRallyConfig, UserRallyState, SpotStatus as SpotStatus$1, PublicReward, RewardState, RallyInventoryState, ClaimOptions, ClaimResult, CheckInResult, StampRallyClient, CheckInOptions, SyncEventListener, RallyConfig, StampRallyState, StampRallyProgress } from '@stamprally/core';
2
- import { ComponentType, CSSProperties, ReactNode, ReactElement } from 'react';
1
+ import { SyncState, RejectedOperationHistoryEntry, OfflineStorageCapability, LocaleDictionary, PublicSpotItem, PublicCheckInCondition, PublicRallyConfig, UserRallyState, SpotStatus as SpotStatus$1, PublicReward, RewardState, RallyInventoryState, ClaimOptions, ClaimResult, CheckInResult, StampRallyClient, CheckInOptions, SyncEventListener, RallyConfig, StampRallyState, StampRallyProgress } from '@stamprally/core';
2
+ import { CSSProperties, ReactElement, ComponentType, ReactNode } from 'react';
3
+
4
+ interface SyncStateContext {
5
+ readonly syncState: SyncState;
6
+ readonly isSyncing: boolean;
7
+ readonly pendingCount: number;
8
+ readonly rejectedHistory: ReadonlyArray<RejectedOperationHistoryEntry>;
9
+ readonly storageCapability: OfflineStorageCapability;
10
+ readonly isStoragePersistent: boolean;
11
+ }
12
+ interface SyncStatusBannerProps<TLocale extends string = string> {
13
+ readonly status: SyncStateContext;
14
+ readonly locale?: TLocale;
15
+ readonly dictionary?: LocaleDictionary<TLocale>;
16
+ readonly className?: string;
17
+ readonly style?: CSSProperties;
18
+ }
19
+ declare function SyncStatusBanner<TLocale extends string = "en">({ status, locale, dictionary, className, style, }: SyncStatusBannerProps<TLocale>): ReactElement | null;
3
20
 
4
21
  /** Complete built-in labels for the standard participant components. */
5
22
  declare const DEFAULT_UI_DICTIONARY: LocaleDictionary<"ja" | "en">;
6
23
  declare const UI_DICTIONARIES: Readonly<Record<"en" | "ja", Readonly<Record<string, string>>>>;
7
24
 
8
25
  type ViewerClassName = "root" | "header" | "card" | "condition" | "slot" | "badge" | "modal" | "button" | "action" | "feedback" | "reward" | "footer";
26
+ type ViewerSyncStateContext = SyncStateContext;
9
27
  type ViewerStyle = CSSProperties & {
10
28
  readonly [key: `--${string}`]: string | number | undefined;
11
29
  };
@@ -45,6 +63,7 @@ interface RallyViewerSlots<TLocale extends string = string> {
45
63
  readonly state: UserRallyState;
46
64
  }) => ReactNode);
47
65
  readonly footerSlot?: ReactNode;
66
+ readonly renderSyncStatus?: (status: SyncStateContext) => ReactNode;
48
67
  readonly renderSpotCard?: (props: SpotCardProps<TLocale>) => ReactNode;
49
68
  readonly renderRewardCard?: (props: RewardCardProps<TLocale>) => ReactNode;
50
69
  readonly renderStatusBadge?: (props: {
@@ -70,8 +89,9 @@ interface RallyViewerProps<TLocale extends string = string> extends RallyViewerS
70
89
  readonly style?: ViewerStyle;
71
90
  readonly customConditionRenderers?: Partial<Record<PublicCheckInCondition["type"], ConditionRenderer<TLocale>>>;
72
91
  readonly onSyncEvent?: SyncEventListener;
92
+ readonly showSyncStatus?: boolean;
73
93
  }
74
- declare function RallyViewer<TLocale extends string = string>({ config: providedConfig, client, adapter, locale, dictionary, classNames, styles, style, customConditionRenderers, onSyncEvent, headerSlot, footerSlot, renderSpotCard, renderRewardCard, renderStatusBadge, renderVerifyingState, renderSuccessFeedback, renderErrorFeedback, }: RallyViewerProps<TLocale>): ReactElement;
94
+ declare function RallyViewer<TLocale extends string = string>({ config: providedConfig, client, adapter, locale, dictionary, classNames, styles, style, customConditionRenderers, onSyncEvent, headerSlot, footerSlot, renderSpotCard, renderRewardCard, renderStatusBadge, renderVerifyingState, renderSuccessFeedback, renderErrorFeedback, renderSyncStatus, showSyncStatus, }: RallyViewerProps<TLocale>): ReactElement;
75
95
  interface StampSheetProps<TLocale extends string = string> extends RallyViewerSlots<TLocale> {
76
96
  readonly config: RallyConfig<TLocale>;
77
97
  readonly state?: StampRallyState | null;
@@ -85,4 +105,4 @@ interface StampSheetProps<TLocale extends string = string> extends RallyViewerSl
85
105
  }
86
106
  declare function StampSheet<TLocale extends string = string>({ config, state, title, progress, locale, dictionary, classNames, styles, style, headerSlot, footerSlot, renderSpotCard, renderStatusBadge, }: StampSheetProps<TLocale>): ReactElement;
87
107
 
88
- 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 };
108
+ export { type ConditionRenderer, type ConditionRendererProps, DEFAULT_UI_DICTIONARY, RallyViewer, type RallyViewerAdapter, type RallyViewerProps, type RallyViewerSlots, type RewardCardProps, type SpotCardProps, type SpotStatus, StampSheet, type StampSheetProps, type SyncStateContext, SyncStatusBanner, type SyncStatusBannerProps, UI_DICTIONARIES, type ViewerClassName, type ViewerClassNames, type ViewerStyle, type ViewerStyles, type ViewerSyncStateContext };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
3
  import { calculateProgress, evaluateSpotStatus, resolveLocalizedText, isQrSupported, isNfcSupported, readQrContext, getCurrentGeoContext, readNfcContext } from '@stamprally/core';
3
4
  import { useState, useEffect, useMemo, useCallback, useRef } from 'react';
4
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
 
6
6
  // src/locales/index.ts
7
7
  var DEFAULT_UI_DICTIONARY = {
@@ -35,7 +35,11 @@ var DEFAULT_UI_DICTIONARY = {
35
35
  "reward.lowStock": "Only a few left",
36
36
  "reward.remaining": "remaining",
37
37
  "reward.sharedRemaining": "Overall remaining",
38
- "reward.validUntil": "Valid until"
38
+ "reward.validUntil": "Valid until",
39
+ "sync.syncing": "Sending unsynced operations to the server...",
40
+ "sync.offline": "Recording offline",
41
+ "sync.unsynced": "unsynced",
42
+ "sync.rollback": "Some check-ins were rolled back by the server"
39
43
  },
40
44
  ja: {
41
45
  viewer: "\u30B9\u30BF\u30F3\u30D7\u30E9\u30EA\u30FC",
@@ -67,10 +71,53 @@ var DEFAULT_UI_DICTIONARY = {
67
71
  "reward.lowStock": "\u6B8B\u308A\u308F\u305A\u304B",
68
72
  "reward.remaining": "\u6B8B\u308A",
69
73
  "reward.sharedRemaining": "\u5168\u4F53\u3067\u6B8B\u308A",
70
- "reward.validUntil": "\u6709\u52B9\u671F\u9650"
74
+ "reward.validUntil": "\u6709\u52B9\u671F\u9650",
75
+ "sync.syncing": "\u672A\u540C\u671F\u306E\u64CD\u4F5C\u3092\u30B5\u30FC\u30D0\u30FC\u3078\u9001\u4FE1\u4E2D...",
76
+ "sync.offline": "\u30AA\u30D5\u30E9\u30A4\u30F3\u3067\u8A18\u9332\u4E2D",
77
+ "sync.unsynced": "\u672A\u540C\u671F",
78
+ "sync.rollback": "\u4E00\u90E8\u306E\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3\u304C\u30B5\u30FC\u30D0\u30FC\u306B\u3088\u308A\u53D6\u308A\u6D88\u3055\u308C\u307E\u3057\u305F"
71
79
  }
72
80
  };
73
81
  var UI_DICTIONARIES = DEFAULT_UI_DICTIONARY;
82
+ function text(dictionary, locale, key, fallback) {
83
+ return dictionary?.[locale]?.[key] ?? DEFAULT_UI_DICTIONARY[locale]?.[key] ?? fallback;
84
+ }
85
+ function SyncStatusBanner({
86
+ status,
87
+ locale = "en",
88
+ dictionary,
89
+ className,
90
+ style
91
+ }) {
92
+ if (status.isSyncing)
93
+ return /* @__PURE__ */ jsxs("div", { className, style, role: "status", "aria-live": "polite", children: [
94
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u27F3" }),
95
+ " ",
96
+ text(dictionary, locale, "sync.syncing", "\u672A\u540C\u671F\u306E\u64CD\u4F5C\u3092\u30B5\u30FC\u30D0\u30FC\u3078\u9001\u4FE1\u4E2D...")
97
+ ] });
98
+ if (status.rejectedHistory.length > 0) {
99
+ const detail = status.rejectedHistory[status.rejectedHistory.length - 1]?.reason.message;
100
+ return /* @__PURE__ */ jsxs("div", { className, style, role: "alert", "aria-live": "assertive", children: [
101
+ /* @__PURE__ */ jsx("strong", { children: text(
102
+ dictionary,
103
+ locale,
104
+ "sync.rollback",
105
+ "\u4E00\u90E8\u306E\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3\u304C\u30B5\u30FC\u30D0\u30FC\u306B\u3088\u308A\u53D6\u308A\u6D88\u3055\u308C\u307E\u3057\u305F"
106
+ ) }),
107
+ detail === void 0 ? null : /* @__PURE__ */ jsx("span", { children: detail })
108
+ ] });
109
+ }
110
+ if (status.pendingCount > 0)
111
+ return /* @__PURE__ */ jsxs("div", { className, style, role: "status", "aria-live": "polite", children: [
112
+ text(dictionary, locale, "sync.offline", "\u30AA\u30D5\u30E9\u30A4\u30F3\u3067\u8A18\u9332\u4E2D"),
113
+ " (",
114
+ text(dictionary, locale, "sync.unsynced", "\u672A\u540C\u671F"),
115
+ ": ",
116
+ status.pendingCount,
117
+ "\u4EF6)"
118
+ ] });
119
+ return null;
120
+ }
74
121
  var label = (dictionary, locale, key, fallback) => dictionary?.[locale]?.[key] ?? DEFAULT_UI_DICTIONARY[locale]?.[key] ?? fallback;
75
122
  var join = (...names) => {
76
123
  const value = names.filter((name) => name !== void 0 && name !== "").join(" ");
@@ -89,7 +136,7 @@ function DefaultCondition({
89
136
  const [status, setStatus] = useState("idle");
90
137
  const [error, setError] = useState(null);
91
138
  const videoRef = useRef(null);
92
- const text = (key, fallback) => label(dictionary, locale, key, fallback);
139
+ const text2 = (key, fallback) => label(dictionary, locale, key, fallback);
93
140
  const verify = async (proof) => {
94
141
  setStatus("loading");
95
142
  setError(null);
@@ -97,11 +144,11 @@ function DefaultCondition({
97
144
  const result = await onSubmit(proof);
98
145
  if (result !== void 0 && typeof result === "object" && result !== null && "ok" in result && result.ok === false) {
99
146
  setStatus("error");
100
- setError(text("verificationFailed", "Verification failed."));
147
+ setError(text2("verificationFailed", "Verification failed."));
101
148
  } else setStatus("success");
102
149
  } catch {
103
150
  setStatus("error");
104
- setError(text("verificationFailed", "Verification failed."));
151
+ setError(text2("verificationFailed", "Verification failed."));
105
152
  }
106
153
  };
107
154
  const readLocation = () => {
@@ -138,12 +185,12 @@ function DefaultCondition({
138
185
  return /* @__PURE__ */ jsxs("div", { children: [
139
186
  condition.type === "qr" && /* @__PURE__ */ jsxs(Fragment, { children: [
140
187
  /* @__PURE__ */ jsxs("label", { children: [
141
- text("qrValue", "QR value"),
188
+ text2("qrValue", "QR value"),
142
189
  /* @__PURE__ */ jsx(
143
190
  "input",
144
191
  {
145
- "aria-label": text("qrValue", "QR value"),
146
- placeholder: condition.qrEntryUrl ?? text("qrPlaceholder", "Paste a QR value"),
192
+ "aria-label": text2("qrValue", "QR value"),
193
+ placeholder: condition.qrEntryUrl ?? text2("qrPlaceholder", "Paste a QR value"),
147
194
  value,
148
195
  onChange: (event) => setValue(event.target.value)
149
196
  }
@@ -153,7 +200,7 @@ function DefaultCondition({
153
200
  "video",
154
201
  {
155
202
  ref: videoRef,
156
- "aria-label": text("qrCamera", "QR camera"),
203
+ "aria-label": text2("qrCamera", "QR camera"),
157
204
  hidden: !isQrSupported(),
158
205
  children: /* @__PURE__ */ jsx("track", { kind: "captions" })
159
206
  }
@@ -166,7 +213,7 @@ function DefaultCondition({
166
213
  style: styles?.button ?? styles?.action,
167
214
  disabled: disabled || !isQrSupported(),
168
215
  onClick: scanQr,
169
- children: text("scanQr", "Scan QR")
216
+ children: text2("scanQr", "Scan QR")
170
217
  }
171
218
  )
172
219
  ] }),
@@ -178,7 +225,7 @@ function DefaultCondition({
178
225
  style: styles?.button ?? styles?.action,
179
226
  disabled,
180
227
  onClick: readLocation,
181
- children: text("checkLocation", "Check location")
228
+ children: text2("checkLocation", "Check location")
182
229
  }
183
230
  ),
184
231
  condition.type === "nfc" && /* @__PURE__ */ jsx(
@@ -189,7 +236,7 @@ function DefaultCondition({
189
236
  style: styles?.button ?? styles?.action,
190
237
  disabled: disabled || !isNfcSupported(),
191
238
  onClick: readNfc,
192
- children: text("readNfc", "Read NFC")
239
+ children: text2("readNfc", "Read NFC")
193
240
  }
194
241
  ),
195
242
  (condition.type === "passcode" || condition.type === "custom" || condition.type === "qr") && /* @__PURE__ */ jsxs(
@@ -201,14 +248,14 @@ function DefaultCondition({
201
248
  },
202
249
  children: [
203
250
  /* @__PURE__ */ jsxs("label", { children: [
204
- text(
251
+ text2(
205
252
  condition.type === "passcode" ? "passcode" : "proof",
206
253
  condition.type === "passcode" ? "Passcode" : "Proof"
207
254
  ),
208
255
  /* @__PURE__ */ jsx(
209
256
  "input",
210
257
  {
211
- "aria-label": text("proof", "Proof"),
258
+ "aria-label": text2("proof", "Proof"),
212
259
  value,
213
260
  onChange: (event) => setValue(event.target.value)
214
261
  }
@@ -221,7 +268,7 @@ function DefaultCondition({
221
268
  className: join("sry-action", classNames?.action, classNames?.button),
222
269
  style: styles?.button ?? styles?.action,
223
270
  disabled: disabled || value.trim() === "",
224
- children: text("checkIn", "Check in")
271
+ children: text2("checkIn", "Check in")
225
272
  }
226
273
  )
227
274
  ]
@@ -235,9 +282,9 @@ function DefaultCondition({
235
282
  "aria-live": "polite",
236
283
  role: status === "error" ? "alert" : void 0,
237
284
  children: [
238
- status === "loading" && text("verifying", "Verifying\u2026"),
239
- status === "success" && text("verified", "Verified"),
240
- status === "error" && (error ?? text("verificationFailed", "Verification failed."))
285
+ status === "loading" && text2("verifying", "Verifying\u2026"),
286
+ status === "success" && text2("verified", "Verified"),
287
+ status === "error" && (error ?? text2("verificationFailed", "Verification failed."))
241
288
  ]
242
289
  }
243
290
  )
@@ -310,12 +357,22 @@ function RallyViewer({
310
357
  renderStatusBadge,
311
358
  renderVerifyingState,
312
359
  renderSuccessFeedback,
313
- renderErrorFeedback
360
+ renderErrorFeedback,
361
+ renderSyncStatus,
362
+ showSyncStatus = true
314
363
  }) {
315
364
  const config = providedConfig ?? client?.getConfig() ?? adapter?.config;
316
365
  const [state, setState] = useState(() => client?.getState() ?? null);
317
366
  const [busy, setBusy] = useState(null);
318
367
  const [feedback, setFeedback] = useState(null);
368
+ const [syncStatus, setSyncStatus] = useState(() => ({
369
+ syncState: client?.syncState ?? "idle",
370
+ isSyncing: client?.syncState === "syncing",
371
+ pendingCount: client?.pendingCount ?? 0,
372
+ rejectedHistory: client?.rejectedHistory ?? [],
373
+ storageCapability: client?.storageCapability ?? "custom",
374
+ isStoragePersistent: client?.isStoragePersistent ?? true
375
+ }));
319
376
  useEffect(() => {
320
377
  if (client === void 0) return;
321
378
  const unsubscribe = client.subscribe(setState);
@@ -326,6 +383,19 @@ function RallyViewer({
326
383
  if (client === void 0 || onSyncEvent === void 0) return;
327
384
  return client.subscribeSyncEvents(onSyncEvent);
328
385
  }, [client, onSyncEvent]);
386
+ useEffect(() => {
387
+ if (client === void 0) return;
388
+ const update = () => setSyncStatus({
389
+ syncState: client.syncState,
390
+ isSyncing: client.syncState === "syncing",
391
+ pendingCount: client.pendingCount,
392
+ rejectedHistory: client.rejectedHistory,
393
+ storageCapability: client.storageCapability,
394
+ isStoragePersistent: client.isStoragePersistent
395
+ });
396
+ update();
397
+ return client.subscribeSyncState(update);
398
+ }, [client]);
329
399
  if (config === void 0) throw new Error("RallyViewer requires config, client, or adapter.");
330
400
  const currentState = state ?? {
331
401
  rallyId: config.id,
@@ -392,6 +462,16 @@ function RallyViewer({
392
462
  feedback?.ok === false && (renderErrorFeedback?.(
393
463
  "message" in feedback.error ? feedback.error.message : feedback.error.code
394
464
  ) ?? /* @__PURE__ */ jsx("div", { className: classNames.feedback, style: styles.feedback, role: "alert", children: "message" in feedback.error ? feedback.error.message : feedback.error.code })),
465
+ showSyncStatus && (renderSyncStatus?.(syncStatus) ?? /* @__PURE__ */ jsx(
466
+ SyncStatusBanner,
467
+ {
468
+ status: syncStatus,
469
+ locale,
470
+ ...dictionary === void 0 ? {} : { dictionary },
471
+ ...classNames.feedback === void 0 ? {} : { className: classNames.feedback },
472
+ ...styles.feedback === void 0 ? {} : { style: styles.feedback }
473
+ }
474
+ )),
395
475
  /* @__PURE__ */ jsx("div", { children: config.spots.map((spot) => {
396
476
  const status = busy === spot.id ? "VERIFYING" : evaluateSpotStatus(spot, currentState);
397
477
  const claimed = status === "CLAIMED";
@@ -545,6 +625,6 @@ function StampSheet({
545
625
  );
546
626
  }
547
627
 
548
- export { DEFAULT_UI_DICTIONARY, RallyViewer, StampSheet, UI_DICTIONARIES };
628
+ export { DEFAULT_UI_DICTIONARY, RallyViewer, StampSheet, SyncStatusBanner, UI_DICTIONARIES };
549
629
  //# sourceMappingURL=index.js.map
550
630
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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 SyncEventListener,\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 readonly onSyncEvent?: SyncEventListener;\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 onSyncEvent,\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 useEffect(() => {\n if (client === undefined || onSyncEvent === undefined) return;\n return client.subscribeSyncEvents(onSyncEvent);\n }, [client, onSyncEvent]);\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"]}
1
+ {"version":3,"sources":["../src/locales/index.ts","../src/components/SyncStatusBanner.tsx","../src/index.tsx"],"names":["text","jsxs","jsx","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 \"sync.syncing\": \"Sending unsynced operations to the server...\",\n \"sync.offline\": \"Recording offline\",\n \"sync.unsynced\": \"unsynced\",\n \"sync.rollback\": \"Some check-ins were rolled back by the server\",\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 \"sync.syncing\": \"未同期の操作をサーバーへ送信中...\",\n \"sync.offline\": \"オフラインで記録中\",\n \"sync.unsynced\": \"未同期\",\n \"sync.rollback\": \"一部のチェックインがサーバーにより取り消されました\",\n },\n};\n\nexport const UI_DICTIONARIES = DEFAULT_UI_DICTIONARY;\n","import type {\n LocaleDictionary,\n OfflineStorageCapability,\n RejectedOperationHistoryEntry,\n SyncState,\n} from \"@stamprally/core\";\nimport type { CSSProperties, ReactElement } from \"react\";\nimport { DEFAULT_UI_DICTIONARY } from \"../locales/index.js\";\n\nexport interface SyncStateContext {\n readonly syncState: SyncState;\n readonly isSyncing: boolean;\n readonly pendingCount: number;\n readonly rejectedHistory: ReadonlyArray<RejectedOperationHistoryEntry>;\n readonly storageCapability: OfflineStorageCapability;\n readonly isStoragePersistent: boolean;\n}\n\nexport interface SyncStatusBannerProps<TLocale extends string = string> {\n readonly status: SyncStateContext;\n readonly locale?: TLocale;\n readonly dictionary?: LocaleDictionary<TLocale>;\n readonly className?: string;\n readonly style?: CSSProperties;\n}\n\nfunction text<TLocale extends string>(\n dictionary: LocaleDictionary<TLocale> | undefined,\n locale: TLocale,\n key: string,\n fallback: string,\n): string {\n return (\n dictionary?.[locale]?.[key] ?? DEFAULT_UI_DICTIONARY[locale as \"ja\" | \"en\"]?.[key] ?? fallback\n );\n}\n\nexport function SyncStatusBanner<TLocale extends string = \"en\">({\n status,\n locale = \"en\" as TLocale,\n dictionary,\n className,\n style,\n}: SyncStatusBannerProps<TLocale>): ReactElement | null {\n if (status.isSyncing)\n return (\n <div className={className} style={style} role=\"status\" aria-live=\"polite\">\n <span aria-hidden=\"true\">⟳</span>{\" \"}\n {text(dictionary, locale, \"sync.syncing\", \"未同期の操作をサーバーへ送信中...\")}\n </div>\n );\n if (status.rejectedHistory.length > 0) {\n const detail = status.rejectedHistory[status.rejectedHistory.length - 1]?.reason.message;\n return (\n <div className={className} style={style} role=\"alert\" aria-live=\"assertive\">\n <strong>\n {text(\n dictionary,\n locale,\n \"sync.rollback\",\n \"一部のチェックインがサーバーにより取り消されました\",\n )}\n </strong>\n {detail === undefined ? null : <span>{detail}</span>}\n </div>\n );\n }\n if (status.pendingCount > 0)\n return (\n <div className={className} style={style} role=\"status\" aria-live=\"polite\">\n {text(dictionary, locale, \"sync.offline\", \"オフラインで記録中\")} (\n {text(dictionary, locale, \"sync.unsynced\", \"未同期\")}: {status.pendingCount}件)\n </div>\n );\n return null;\n}\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 SyncEventListener,\n UserRallyState,\n} from \"@stamprally/core\";\nimport { type SyncStateContext, SyncStatusBanner } from \"./components/SyncStatusBanner.js\";\nimport { DEFAULT_UI_DICTIONARY } from \"./locales/index.js\";\n\nexport type { SyncStateContext, SyncStatusBannerProps } from \"./components/SyncStatusBanner.js\";\nexport { SyncStatusBanner } from \"./components/SyncStatusBanner.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\";\n\nexport type ViewerSyncStateContext = SyncStateContext;\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 renderSyncStatus?: (status: SyncStateContext) => 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 readonly onSyncEvent?: SyncEventListener;\n readonly showSyncStatus?: boolean;\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 onSyncEvent,\n headerSlot,\n footerSlot,\n renderSpotCard,\n renderRewardCard,\n renderStatusBadge,\n renderVerifyingState,\n renderSuccessFeedback,\n renderErrorFeedback,\n renderSyncStatus,\n showSyncStatus = true,\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 const [syncStatus, setSyncStatus] = useState<SyncStateContext>(() => ({\n syncState: client?.syncState ?? \"idle\",\n isSyncing: client?.syncState === \"syncing\",\n pendingCount: client?.pendingCount ?? 0,\n rejectedHistory: client?.rejectedHistory ?? [],\n storageCapability: client?.storageCapability ?? \"custom\",\n isStoragePersistent: client?.isStoragePersistent ?? true,\n }));\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 useEffect(() => {\n if (client === undefined || onSyncEvent === undefined) return;\n return client.subscribeSyncEvents(onSyncEvent);\n }, [client, onSyncEvent]);\n useEffect(() => {\n if (client === undefined) return;\n const update = (): void =>\n setSyncStatus({\n syncState: client.syncState,\n isSyncing: client.syncState === \"syncing\",\n pendingCount: client.pendingCount,\n rejectedHistory: client.rejectedHistory,\n storageCapability: client.storageCapability,\n isStoragePersistent: client.isStoragePersistent,\n });\n update();\n return client.subscribeSyncState(update);\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 {showSyncStatus &&\n (renderSyncStatus?.(syncStatus) ?? (\n <SyncStatusBanner\n status={syncStatus}\n locale={locale}\n {...(dictionary === undefined ? {} : { dictionary })}\n {...(classNames.feedback === undefined ? {} : { className: classNames.feedback })}\n {...(styles.feedback === undefined ? {} : { style: styles.feedback })}\n />\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.17.0",
3
+ "version": "0.18.0",
4
4
  "description": "Accessible participant UI components for stamp rallies.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -32,8 +32,8 @@
32
32
  "./styles.css": "./dist/index.css"
33
33
  },
34
34
  "dependencies": {
35
- "@stamprally/core": "0.17.0",
36
- "@stamprally/react": "0.17.0"
35
+ "@stamprally/core": "0.18.0",
36
+ "@stamprally/react": "0.18.0"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "react": "^18.0.0 || ^19.0.0",