@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 +1 -1
- package/dist/index.cjs +101 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -4
- package/dist/index.d.ts +24 -4
- package/dist/index.js +101 -21
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
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
|
|
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(
|
|
149
|
+
setError(text2("verificationFailed", "Verification failed."));
|
|
103
150
|
} else setStatus("success");
|
|
104
151
|
} catch {
|
|
105
152
|
setStatus("error");
|
|
106
|
-
setError(
|
|
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
|
-
|
|
190
|
+
text2("qrValue", "QR value"),
|
|
144
191
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
145
192
|
"input",
|
|
146
193
|
{
|
|
147
|
-
"aria-label":
|
|
148
|
-
placeholder: condition.qrEntryUrl ??
|
|
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":
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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":
|
|
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:
|
|
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" &&
|
|
241
|
-
status === "success" &&
|
|
242
|
-
status === "error" && (error ??
|
|
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
|
package/dist/index.cjs.map
CHANGED
|
@@ -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 {
|
|
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 {
|
|
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
|
|
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(
|
|
147
|
+
setError(text2("verificationFailed", "Verification failed."));
|
|
101
148
|
} else setStatus("success");
|
|
102
149
|
} catch {
|
|
103
150
|
setStatus("error");
|
|
104
|
-
setError(
|
|
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
|
-
|
|
188
|
+
text2("qrValue", "QR value"),
|
|
142
189
|
/* @__PURE__ */ jsx(
|
|
143
190
|
"input",
|
|
144
191
|
{
|
|
145
|
-
"aria-label":
|
|
146
|
-
placeholder: condition.qrEntryUrl ??
|
|
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":
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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":
|
|
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:
|
|
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" &&
|
|
239
|
-
status === "success" &&
|
|
240
|
-
status === "error" && (error ??
|
|
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.
|
|
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.
|
|
36
|
-
"@stamprally/react": "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",
|