@indietabletop/appkit 6.1.6 → 7.0.0-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/dist/AppConfig/AppConfig.d.ts +29 -0
- package/dist/AuthCard/AuthCard.d.ts +10 -0
- package/dist/AuthCard/AuthCard.stories.d.ts +34 -0
- package/dist/AuthCard/style.css.d.ts +23 -0
- package/dist/DialogTrigger/index.d.ts +13 -0
- package/dist/DocumentTitle/DocumentTitle.d.ts +3 -0
- package/dist/EnumMapper.d.ts +25 -0
- package/dist/ExternalLink.d.ts +3 -0
- package/dist/FullscreenDismissBlocker.d.ts +5 -0
- package/{lib/HistoryState.ts → dist/HistoryState.d.ts} +2 -5
- package/dist/IndieTabletopClubLogo.d.ts +7 -0
- package/dist/IndieTabletopClubSymbol.d.ts +7 -0
- package/dist/InfoPage/index.d.ts +8 -0
- package/dist/InfoPage/pages.d.ts +2 -0
- package/dist/InfoPage/style.css.d.ts +5 -0
- package/dist/Letterhead/index.d.ts +19 -0
- package/dist/Letterhead/stories.d.ts +13 -0
- package/dist/Letterhead/style.css.d.ts +46 -0
- package/dist/LetterheadForm/LetterheadReadonlyTextField.stories.d.ts +17 -0
- package/dist/LetterheadForm/LetterheadSubmitError.stories.d.ts +11 -0
- package/dist/LetterheadForm/LetterheadTextField.stories.d.ts +336 -0
- package/dist/LetterheadForm/index.d.ts +44 -0
- package/dist/LetterheadForm/style.css.d.ts +8 -0
- package/dist/LoadingIndicator.d.ts +3 -0
- package/dist/MiddotSeparated/MiddotSeparated.d.ts +8 -0
- package/dist/MiddotSeparated/MiddotSeparated.stories.d.ts +586 -0
- package/dist/MiddotSeparated/style.css.d.ts +1 -0
- package/dist/ModalDialog/index.d.ts +12 -0
- package/dist/ModalDialog/style.css.d.ts +58 -0
- package/dist/ModernIDB/Cursor.d.ts +56 -0
- package/dist/ModernIDB/ModernIDB.d.ts +66 -0
- package/dist/ModernIDB/ModernIDBError.d.ts +3 -0
- package/dist/ModernIDB/ObjectStore.d.ts +112 -0
- package/dist/ModernIDB/ObjectStoreIndex.d.ts +53 -0
- package/dist/ModernIDB/Transaction.d.ts +16 -0
- package/dist/ModernIDB/VersionChangeManager.d.ts +30 -0
- package/dist/ModernIDB/bindings/factory.d.ts +12 -0
- package/dist/ModernIDB/bindings/index.d.ts +2 -0
- package/{lib/ModernIDB/bindings/types.ts → dist/ModernIDB/bindings/types.d.ts} +13 -32
- package/dist/ModernIDB/bindings/utils.d.ts +2 -0
- package/dist/ModernIDB/index.d.ts +10 -0
- package/dist/ModernIDB/types.d.ts +88 -0
- package/dist/ModernIDB/utils.d.ts +4 -0
- package/dist/QRCode/QRCode.d.ts +7 -0
- package/dist/QRCode/QRCode.stories.d.ts +33 -0
- package/dist/QRCode/style.css.d.ts +4 -0
- package/dist/ReleaseInfo/index.d.ts +5 -0
- package/dist/RulesetResolver.d.ts +87 -0
- package/dist/SafariCheck/SafariCheck.d.ts +23 -0
- package/dist/SafariCheck/SafariCheck.stories.d.ts +73 -0
- package/dist/SafariCheck/style.css.d.ts +17 -0
- package/dist/ServiceWorkerHandler.d.ts +11 -0
- package/dist/ShareButton/ShareButton.d.ts +57 -0
- package/dist/ShareButton/ShareButton.stories.d.ts +1577 -0
- package/dist/ShareButton/test.css.d.ts +1 -0
- package/dist/SubscribeCard/LetterheadInfoCard.d.ts +2 -0
- package/dist/SubscribeCard/SubscribeByEmailCard.d.ts +24 -0
- package/dist/SubscribeCard/SubscribeByEmailCard.stories.d.ts +10 -0
- package/dist/SubscribeCard/SubscribeByPledgeCard.d.ts +36 -0
- package/dist/SubscribeCard/SubscribeByPledgeCard.stories.d.ts +65 -0
- package/dist/SubscribeCard/style.css.d.ts +4 -0
- package/dist/account/AccountIssueView.d.ts +3 -0
- package/dist/account/AlreadyLoggedInView.d.ts +5 -0
- package/dist/account/CurrentUserFetcher.d.ts +20 -0
- package/dist/account/CurrentUserFetcher.stories.d.ts +136 -0
- package/dist/account/FailureFallbackView.d.ts +1 -0
- package/dist/account/JoinCard.d.ts +14 -0
- package/dist/account/JoinCard.stories.d.ts +143 -0
- package/dist/account/LoadingView.d.ts +1 -0
- package/dist/account/LoginCard.d.ts +39 -0
- package/dist/account/LoginCard.stories.d.ts +217 -0
- package/dist/account/LoginView.d.ts +10 -0
- package/dist/account/NoConnectionView.d.ts +4 -0
- package/dist/account/PasswordResetCard.d.ts +15 -0
- package/dist/account/PasswordResetCard.stories.d.ts +128 -0
- package/dist/account/UserMismatchView.d.ts +6 -0
- package/dist/account/VerifyPage.d.ts +13 -0
- package/dist/account/style.css.d.ts +10 -0
- package/{lib/account/types.ts → dist/account/types.d.ts} +3 -6
- package/dist/account/useFetchCurrentUser.d.ts +28 -0
- package/dist/account/useRedirectPath.d.ts +6 -0
- package/dist/animations.css.d.ts +3 -0
- package/dist/append-copy-to-text.d.ts +10 -0
- package/dist/append-copy-to-text.test.d.ts +1 -0
- package/dist/appkit.css +1 -0
- package/dist/appkit.js +10692 -0
- package/dist/async-op.d.ts +101 -0
- package/dist/atomic.css.d.ts +6 -0
- package/{lib/caught-value.ts → dist/caught-value.d.ts} +1 -11
- package/{lib/class-names.ts → dist/class-names.d.ts} +6 -17
- package/dist/client.d.ts +424 -0
- package/dist/common.css.d.ts +5 -0
- package/dist/copyrightRange.d.ts +1 -0
- package/dist/copyrightRange.test.d.ts +1 -0
- package/dist/createSafeStorage.d.ts +34 -0
- package/dist/failureMessages.d.ts +20 -0
- package/dist/failureMessages.test.d.ts +1 -0
- package/dist/form/FormSubmitButton.d.ts +17 -0
- package/dist/form/SubmitErrorAlert.d.ts +5 -0
- package/dist/form/style.css.d.ts +3 -0
- package/dist/globals.css.d.ts +0 -0
- package/dist/groupBy.d.ts +1 -0
- package/dist/groupBy.test.d.ts +1 -0
- package/dist/hrefs.d.ts +32 -0
- package/dist/hrefs.test.d.ts +1 -0
- package/dist/idToDate.d.ts +5 -0
- package/dist/idToDate.test.d.ts +1 -0
- package/dist/ids.d.ts +1 -0
- package/dist/ids.test.d.ts +1 -0
- package/dist/index.d.ts +64 -0
- package/dist/internal.css.d.ts +2 -0
- package/dist/mailto.d.ts +8 -0
- package/dist/mailto.test.d.ts +1 -0
- package/dist/media.d.ts +39 -0
- package/dist/random.d.ts +3 -0
- package/dist/result/swr.d.ts +4 -0
- package/{lib/sleep.ts → dist/sleep.d.ts} +1 -3
- package/dist/store/index.d.ts +237 -0
- package/dist/store/store.d.ts +144 -0
- package/dist/store/types.d.ts +49 -0
- package/dist/store/utils.d.ts +10 -0
- package/dist/storybook/decorators.d.ts +3 -0
- package/dist/structs.d.ts +1 -0
- package/{lib/typeguards.ts → dist/typeguards.d.ts} +1 -3
- package/dist/typeguards.test.d.ts +1 -0
- package/{lib/types.ts → dist/types.d.ts} +12 -23
- package/dist/unique.d.ts +10 -0
- package/dist/unique.test.d.ts +1 -0
- package/dist/use-async-op.d.ts +6 -0
- package/dist/use-document-background-color.d.ts +4 -0
- package/dist/use-form.d.ts +29 -0
- package/dist/use-is-installed.d.ts +8 -0
- package/dist/use-media-query.d.ts +1 -0
- package/dist/use-reverting-state.d.ts +5 -0
- package/dist/use-scroll-restoration.d.ts +25 -0
- package/dist/useEnsureValue.d.ts +6 -0
- package/dist/useInvokeClient.d.ts +25 -0
- package/dist/useIsVisible.d.ts +4 -0
- package/dist/utm.d.ts +58 -0
- package/dist/utm.test.d.ts +1 -0
- package/dist/validations.d.ts +3 -0
- package/dist/vars.css.d.ts +10 -0
- package/package.json +12 -5
- package/lib/AppConfig/AppConfig.tsx +0 -61
- package/lib/AuthCard/AuthCard.stories.ts +0 -34
- package/lib/AuthCard/AuthCard.tsx +0 -64
- package/lib/AuthCard/style.css.ts +0 -49
- package/lib/DialogTrigger/index.tsx +0 -36
- package/lib/DocumentTitle/DocumentTitle.tsx +0 -10
- package/lib/EnumMapper.ts +0 -50
- package/lib/ExternalLink.tsx +0 -10
- package/lib/FullscreenDismissBlocker.tsx +0 -23
- package/lib/IndieTabletopClubLogo.tsx +0 -44
- package/lib/IndieTabletopClubSymbol.tsx +0 -37
- package/lib/InfoPage/index.tsx +0 -46
- package/lib/InfoPage/pages.tsx +0 -36
- package/lib/InfoPage/style.css.ts +0 -36
- package/lib/Letterhead/index.tsx +0 -85
- package/lib/Letterhead/stories.tsx +0 -41
- package/lib/Letterhead/style.css.ts +0 -152
- package/lib/LetterheadForm/LetterheadReadonlyTextField.stories.tsx +0 -17
- package/lib/LetterheadForm/LetterheadSubmitError.stories.tsx +0 -19
- package/lib/LetterheadForm/LetterheadTextField.stories.tsx +0 -19
- package/lib/LetterheadForm/index.tsx +0 -137
- package/lib/LetterheadForm/style.css.ts +0 -89
- package/lib/LoadingIndicator.tsx +0 -40
- package/lib/MiddotSeparated/MiddotSeparated.stories.ts +0 -26
- package/lib/MiddotSeparated/MiddotSeparated.tsx +0 -26
- package/lib/MiddotSeparated/style.css.ts +0 -10
- package/lib/ModalDialog/index.tsx +0 -28
- package/lib/ModalDialog/style.css.ts +0 -88
- package/lib/ModernIDB/Cursor.ts +0 -91
- package/lib/ModernIDB/ModernIDB.ts +0 -337
- package/lib/ModernIDB/ModernIDBError.ts +0 -9
- package/lib/ModernIDB/ObjectStore.ts +0 -195
- package/lib/ModernIDB/ObjectStoreIndex.ts +0 -102
- package/lib/ModernIDB/README.md +0 -9
- package/lib/ModernIDB/Transaction.ts +0 -40
- package/lib/ModernIDB/VersionChangeManager.ts +0 -57
- package/lib/ModernIDB/bindings/factory.tsx +0 -165
- package/lib/ModernIDB/bindings/index.ts +0 -2
- package/lib/ModernIDB/bindings/utils.tsx +0 -32
- package/lib/ModernIDB/index.ts +0 -10
- package/lib/ModernIDB/types.ts +0 -120
- package/lib/ModernIDB/utils.ts +0 -51
- package/lib/QRCode/QRCode.stories.tsx +0 -41
- package/lib/QRCode/QRCode.tsx +0 -54
- package/lib/QRCode/style.css.ts +0 -23
- package/lib/ReleaseInfo/index.tsx +0 -29
- package/lib/RulesetResolver.ts +0 -214
- package/lib/SafariCheck/SafariCheck.stories.tsx +0 -99
- package/lib/SafariCheck/SafariCheck.tsx +0 -273
- package/lib/SafariCheck/addToDock.svg +0 -13
- package/lib/SafariCheck/addToHomeScreen.svg +0 -12
- package/lib/SafariCheck/safari.svg +0 -32
- package/lib/SafariCheck/shareIcon.svg +0 -11
- package/lib/SafariCheck/style.css.ts +0 -106
- package/lib/ServiceWorkerHandler.tsx +0 -53
- package/lib/ShareButton/ShareButton.stories.tsx +0 -58
- package/lib/ShareButton/ShareButton.tsx +0 -153
- package/lib/ShareButton/test.css.ts +0 -3
- package/lib/SubscribeCard/LetterheadInfoCard.tsx +0 -23
- package/lib/SubscribeCard/SubscribeByEmailCard.stories.tsx +0 -69
- package/lib/SubscribeCard/SubscribeByEmailCard.tsx +0 -183
- package/lib/SubscribeCard/SubscribeByPledgeCard.stories.tsx +0 -133
- package/lib/SubscribeCard/SubscribeByPledgeCard.tsx +0 -127
- package/lib/SubscribeCard/style.css.ts +0 -14
- package/lib/account/AccountIssueView.tsx +0 -44
- package/lib/account/AlreadyLoggedInView.tsx +0 -47
- package/lib/account/CurrentUserFetcher.stories.tsx +0 -292
- package/lib/account/CurrentUserFetcher.tsx +0 -118
- package/lib/account/FailureFallbackView.tsx +0 -36
- package/lib/account/JoinCard.stories.tsx +0 -257
- package/lib/account/JoinCard.tsx +0 -301
- package/lib/account/LoadingView.tsx +0 -14
- package/lib/account/LoginCard.stories.tsx +0 -288
- package/lib/account/LoginCard.tsx +0 -100
- package/lib/account/LoginView.tsx +0 -151
- package/lib/account/NoConnectionView.tsx +0 -34
- package/lib/account/PasswordResetCard.stories.tsx +0 -242
- package/lib/account/PasswordResetCard.tsx +0 -296
- package/lib/account/UserMismatchView.tsx +0 -62
- package/lib/account/VerifyPage.tsx +0 -195
- package/lib/account/style.css.ts +0 -57
- package/lib/account/useFetchCurrentUser.tsx +0 -63
- package/lib/account/useRedirectPath.ts +0 -21
- package/lib/animations.css.ts +0 -17
- package/lib/append-copy-to-text.ts +0 -35
- package/lib/async-op.ts +0 -286
- package/lib/atomic.css.ts +0 -11
- package/lib/client.ts +0 -662
- package/lib/common.css.ts +0 -48
- package/lib/copyrightRange.ts +0 -10
- package/lib/createSafeStorage.ts +0 -91
- package/lib/failureMessages.ts +0 -108
- package/lib/form/FormSubmitButton.tsx +0 -58
- package/lib/form/SubmitErrorAlert.tsx +0 -21
- package/lib/form/style.css.ts +0 -9
- package/lib/globals.css.ts +0 -62
- package/lib/groupBy.ts +0 -25
- package/lib/hrefs.ts +0 -48
- package/lib/idToDate.ts +0 -8
- package/lib/ids.ts +0 -6
- package/lib/index.ts +0 -71
- package/lib/internal.css.ts +0 -10
- package/lib/mailto.ts +0 -40
- package/lib/media.ts +0 -50
- package/lib/random.ts +0 -19
- package/lib/result/swr.ts +0 -18
- package/lib/store/index.tsx +0 -241
- package/lib/store/store.ts +0 -479
- package/lib/store/types.ts +0 -45
- package/lib/store/utils.ts +0 -54
- package/lib/storybook/decorators.tsx +0 -10
- package/lib/structs.ts +0 -3
- package/lib/unique.ts +0 -24
- package/lib/use-async-op.ts +0 -16
- package/lib/use-document-background-color.ts +0 -16
- package/lib/use-form.ts +0 -78
- package/lib/use-is-installed.ts +0 -17
- package/lib/use-media-query.ts +0 -21
- package/lib/use-reverting-state.ts +0 -32
- package/lib/use-scroll-restoration.ts +0 -99
- package/lib/useEnsureValue.ts +0 -31
- package/lib/useInvokeClient.ts +0 -54
- package/lib/useIsVisible.ts +0 -27
- package/lib/utm.ts +0 -92
- package/lib/validations.ts +0 -25
- package/lib/vars.css.ts +0 -13
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { http, HttpResponse } from "msw";
|
|
2
|
-
import preview from "../../.storybook/preview.tsx";
|
|
3
|
-
import { LetterheadParagraph } from "../Letterhead/index.tsx";
|
|
4
|
-
import { sleep } from "../sleep.ts";
|
|
5
|
-
import { SubscribeByPledgeCard } from "./SubscribeByPledgeCard.tsx";
|
|
6
|
-
|
|
7
|
-
const pledge = {
|
|
8
|
-
id: "1",
|
|
9
|
-
email: "test@example.com",
|
|
10
|
-
contactSubscribed: false,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const subscribeByPledgeId = {
|
|
14
|
-
success() {
|
|
15
|
-
return http.post(
|
|
16
|
-
"http://mock.api/v1/newsletters/changelog/subscriptions",
|
|
17
|
-
async () => {
|
|
18
|
-
await sleep(2000);
|
|
19
|
-
|
|
20
|
-
return HttpResponse.json(
|
|
21
|
-
{ message: "Added to newsletter" },
|
|
22
|
-
{ status: 201 },
|
|
23
|
-
);
|
|
24
|
-
},
|
|
25
|
-
);
|
|
26
|
-
},
|
|
27
|
-
noConnection() {
|
|
28
|
-
return http.post(
|
|
29
|
-
"http://mock.api/v1/newsletters/changelog/subscriptions",
|
|
30
|
-
async () => {
|
|
31
|
-
return HttpResponse.error();
|
|
32
|
-
},
|
|
33
|
-
);
|
|
34
|
-
},
|
|
35
|
-
error() {
|
|
36
|
-
return http.post(
|
|
37
|
-
"http://mock.api/v1/newsletters/changelog/subscriptions",
|
|
38
|
-
async () => {
|
|
39
|
-
await sleep(2000);
|
|
40
|
-
|
|
41
|
-
return HttpResponse.text("Application error", { status: 500 });
|
|
42
|
-
},
|
|
43
|
-
);
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Allows users to subscribe to ITC's newsletter using the email provided
|
|
49
|
-
* in their pledge.
|
|
50
|
-
*/
|
|
51
|
-
const meta = preview.meta({
|
|
52
|
-
title: "Newsletter/Subscribe By Pledge Card",
|
|
53
|
-
component: SubscribeByPledgeCard,
|
|
54
|
-
tags: ["autodocs"],
|
|
55
|
-
args: {
|
|
56
|
-
pledge,
|
|
57
|
-
content: {
|
|
58
|
-
SUBSCRIBE: {
|
|
59
|
-
title: "Space Gits on Indie Tabletop Club",
|
|
60
|
-
description: (
|
|
61
|
-
<LetterheadParagraph>
|
|
62
|
-
Space Gits is getting a fancy <strong>gang builder</strong> and{" "}
|
|
63
|
-
<strong>smart rules</strong> in late 2025 in collaboration with
|
|
64
|
-
Indie Tabletop Club. Subscribe to ITC's{" "}
|
|
65
|
-
<em>at‑most‑one‑a‑month</em> newsletter and be among the first to
|
|
66
|
-
gain early access. It's gonna be rad.
|
|
67
|
-
</LetterheadParagraph>
|
|
68
|
-
),
|
|
69
|
-
},
|
|
70
|
-
SUBSCRIBE_SUCCESS: {
|
|
71
|
-
title: "Subscribed!",
|
|
72
|
-
description:
|
|
73
|
-
"Thank you for being awesome. Once Space Gits is available for " +
|
|
74
|
-
"early access, you will be among the first to know!",
|
|
75
|
-
},
|
|
76
|
-
PREVIOUSLY_SUBSCRIBED: {
|
|
77
|
-
title: "Space Gits on Indie Tabletop Club",
|
|
78
|
-
description: (
|
|
79
|
-
<>
|
|
80
|
-
<LetterheadParagraph>
|
|
81
|
-
Space Gits is getting a fancy <strong>gang builder</strong> and{" "}
|
|
82
|
-
<strong>smart rules</strong> in late 2025 in collaboration with
|
|
83
|
-
Indie Tabletop Club.
|
|
84
|
-
</LetterheadParagraph>
|
|
85
|
-
|
|
86
|
-
<LetterheadParagraph>
|
|
87
|
-
Early access will be announced via ITC's newsletter, which
|
|
88
|
-
— according to our records — you are are already
|
|
89
|
-
subscribed to! Nothing left to do but await the good news in your
|
|
90
|
-
inbox!
|
|
91
|
-
</LetterheadParagraph>
|
|
92
|
-
</>
|
|
93
|
-
),
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
parameters: {
|
|
98
|
-
msw: {
|
|
99
|
-
handlers: {
|
|
100
|
-
subscribeByPledgeId: subscribeByPledgeId.success(),
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* The default case, in which the user is not yet subscribed to ITC's newsletter
|
|
108
|
-
* and the submission is successful.
|
|
109
|
-
*/
|
|
110
|
-
export const Default = meta.story({});
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Same like the default case, but the form submission fails. Errors are
|
|
114
|
-
* differentiated using the `getSubmitFailureMessage` helper, so all the basics
|
|
115
|
-
* should be covered, as this page doesn't have special cases.
|
|
116
|
-
*/
|
|
117
|
-
export const FailureOnSubmit = meta.story({
|
|
118
|
-
parameters: {
|
|
119
|
-
msw: {
|
|
120
|
-
handlers: {
|
|
121
|
-
subscribeByPledgeId: subscribeByPledgeId.error(),
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* In this case, the email address associated with this user account is
|
|
129
|
-
* already subscribed to our newsletter.
|
|
130
|
-
*/
|
|
131
|
-
export const AlreadySubscribed = meta.story({
|
|
132
|
-
args: { pledge: { ...pledge, contactSubscribed: true } },
|
|
133
|
-
});
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { Form } from "@ariakit/react";
|
|
2
|
-
import {
|
|
3
|
-
getSubmitFailureMessage,
|
|
4
|
-
Letterhead,
|
|
5
|
-
LetterheadHeading,
|
|
6
|
-
LetterheadParagraph,
|
|
7
|
-
LetterheadSubmitButton,
|
|
8
|
-
LetterheadSubmitError,
|
|
9
|
-
useForm,
|
|
10
|
-
type RedeemedPledge,
|
|
11
|
-
} from "@indietabletop/appkit";
|
|
12
|
-
import { useState, type ReactNode } from "react";
|
|
13
|
-
import { useClient } from "../AppConfig/AppConfig.tsx";
|
|
14
|
-
import { LetterheadInfoCard } from "./LetterheadInfoCard.tsx";
|
|
15
|
-
import * as css from "./style.css.ts";
|
|
16
|
-
|
|
17
|
-
type Pledge = Pick<RedeemedPledge, "id" | "email" | "contactSubscribed">;
|
|
18
|
-
|
|
19
|
-
function SubscribeView(
|
|
20
|
-
props: ViewContent & {
|
|
21
|
-
onSuccess: () => void;
|
|
22
|
-
pledge: Pledge;
|
|
23
|
-
},
|
|
24
|
-
) {
|
|
25
|
-
const { pledge, title, description, onSuccess } = props;
|
|
26
|
-
|
|
27
|
-
const client = useClient();
|
|
28
|
-
const { form, submitName } = useForm({
|
|
29
|
-
defaultValues: {},
|
|
30
|
-
onSuccess,
|
|
31
|
-
async onSubmit() {
|
|
32
|
-
const result = await client.subscribeToNewsletterByPledgeId(
|
|
33
|
-
"changelog",
|
|
34
|
-
pledge.id,
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
return result.mapFailure(getSubmitFailureMessage);
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
return (
|
|
42
|
-
<Letterhead>
|
|
43
|
-
<LetterheadHeading className={css.card.heading}>
|
|
44
|
-
{title}
|
|
45
|
-
</LetterheadHeading>
|
|
46
|
-
|
|
47
|
-
{description}
|
|
48
|
-
|
|
49
|
-
<Form store={form} className={css.card.form}>
|
|
50
|
-
<LetterheadSubmitError name={submitName} />
|
|
51
|
-
|
|
52
|
-
<LetterheadSubmitButton>Subscribe</LetterheadSubmitButton>
|
|
53
|
-
|
|
54
|
-
<LetterheadParagraph size="small">
|
|
55
|
-
Using {pledge.email} from your pledge.
|
|
56
|
-
</LetterheadParagraph>
|
|
57
|
-
</Form>
|
|
58
|
-
</Letterhead>
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
type SubscribeStep =
|
|
63
|
-
| "PREVIOUSLY_SUBSCRIBED"
|
|
64
|
-
| "SUBSCRIBE"
|
|
65
|
-
| "SUBSCRIBE_SUCCESS";
|
|
66
|
-
|
|
67
|
-
export type ViewContent = {
|
|
68
|
-
title: ReactNode;
|
|
69
|
-
description: ReactNode;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Allows users to sign up to the newsletter using the email associated with
|
|
74
|
-
* their pledge ID.
|
|
75
|
-
*
|
|
76
|
-
* Emails are not verified using a one-time code, as the user has just
|
|
77
|
-
* implicitly verified their address by navigating to the page with the unique
|
|
78
|
-
* pledge ID.
|
|
79
|
-
*/
|
|
80
|
-
export function SubscribeByPledgeCard(props: {
|
|
81
|
-
/**
|
|
82
|
-
* The pledge data that will be used to determine whether the user should
|
|
83
|
-
* be prompted for signup.
|
|
84
|
-
*/
|
|
85
|
-
pledge: Pledge;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Content for each of the subscribe steps. You probably want to customize it
|
|
89
|
-
* for each step, so it is left to be defined at point of usage.
|
|
90
|
-
*
|
|
91
|
-
* If the `description` is a string, it will be wrapped in
|
|
92
|
-
* `<LetterheadParagraph>`, otherwise it will be left as is.
|
|
93
|
-
*/
|
|
94
|
-
content: Record<SubscribeStep, ViewContent>;
|
|
95
|
-
}) {
|
|
96
|
-
const { pledge } = props;
|
|
97
|
-
|
|
98
|
-
const [step, setStep] = useState<SubscribeStep>(
|
|
99
|
-
pledge.contactSubscribed ? "PREVIOUSLY_SUBSCRIBED" : "SUBSCRIBE",
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
const content = props.content[step];
|
|
103
|
-
|
|
104
|
-
switch (step) {
|
|
105
|
-
case "SUBSCRIBE": {
|
|
106
|
-
return (
|
|
107
|
-
<SubscribeView
|
|
108
|
-
{...props}
|
|
109
|
-
{...content}
|
|
110
|
-
onSuccess={() => void setStep("SUBSCRIBE_SUCCESS")}
|
|
111
|
-
/>
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
case "PREVIOUSLY_SUBSCRIBED":
|
|
116
|
-
case "SUBSCRIBE_SUCCESS": {
|
|
117
|
-
return <LetterheadInfoCard {...content} />;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export {
|
|
123
|
-
/**
|
|
124
|
-
* @deprecated Use {@link SubscribeByPledgeCard}
|
|
125
|
-
*/
|
|
126
|
-
SubscribeByPledgeCard as SubscribeCard,
|
|
127
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { style } from "@vanilla-extract/css";
|
|
2
|
-
|
|
3
|
-
export const card = {
|
|
4
|
-
heading: style({
|
|
5
|
-
maxInlineSize: "20rem",
|
|
6
|
-
marginInline: "auto",
|
|
7
|
-
}),
|
|
8
|
-
form: style({
|
|
9
|
-
marginBlockStart: "2.5rem",
|
|
10
|
-
display: "flex",
|
|
11
|
-
flexDirection: "column",
|
|
12
|
-
gap: "1rem",
|
|
13
|
-
}),
|
|
14
|
-
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Button } from "@ariakit/react";
|
|
2
|
-
import { cx } from "../class-names.ts";
|
|
3
|
-
import { interactiveText } from "../common.css.ts";
|
|
4
|
-
import {
|
|
5
|
-
Letterhead,
|
|
6
|
-
LetterheadHeading,
|
|
7
|
-
LetterheadParagraph,
|
|
8
|
-
} from "../Letterhead/index.tsx";
|
|
9
|
-
import { useAppActions } from "../store/index.tsx";
|
|
10
|
-
|
|
11
|
-
export function AccountIssueView(props: { reload: () => void }) {
|
|
12
|
-
const { reload } = props;
|
|
13
|
-
const { logout } = useAppActions();
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<Letterhead>
|
|
17
|
-
<LetterheadHeading>Account issue</LetterheadHeading>
|
|
18
|
-
|
|
19
|
-
<LetterheadParagraph>
|
|
20
|
-
You appear to be logged into an account that no longer exists, or is not
|
|
21
|
-
working as expected. Sorry about that!
|
|
22
|
-
</LetterheadParagraph>
|
|
23
|
-
|
|
24
|
-
<LetterheadParagraph>
|
|
25
|
-
{"You can try "}
|
|
26
|
-
<Button
|
|
27
|
-
{...cx(interactiveText)}
|
|
28
|
-
onClick={async () => {
|
|
29
|
-
await logout();
|
|
30
|
-
reload();
|
|
31
|
-
}}
|
|
32
|
-
>
|
|
33
|
-
logging out
|
|
34
|
-
</Button>
|
|
35
|
-
{" and in again. "}
|
|
36
|
-
{"If the issue persists, please get in touch at "}
|
|
37
|
-
<a {...cx(interactiveText)} href="mailto:support@indietabletop.club">
|
|
38
|
-
support@indietabletop.club
|
|
39
|
-
</a>
|
|
40
|
-
{"."}
|
|
41
|
-
</LetterheadParagraph>
|
|
42
|
-
</Letterhead>
|
|
43
|
-
);
|
|
44
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { Button } from "@ariakit/react";
|
|
2
|
-
import { Link } from "wouter";
|
|
3
|
-
import { useAppConfig } from "../AppConfig/AppConfig.tsx";
|
|
4
|
-
import { interactiveText } from "../common.css.ts";
|
|
5
|
-
import {
|
|
6
|
-
Letterhead,
|
|
7
|
-
LetterheadHeading,
|
|
8
|
-
LetterheadParagraph,
|
|
9
|
-
} from "../Letterhead/index.tsx";
|
|
10
|
-
import { useAppActions } from "../store/index.tsx";
|
|
11
|
-
import type { CurrentUser } from "../types.ts";
|
|
12
|
-
|
|
13
|
-
export function AlreadyLoggedInView(props: {
|
|
14
|
-
currentUser: CurrentUser;
|
|
15
|
-
reload: () => void;
|
|
16
|
-
}) {
|
|
17
|
-
const { currentUser, reload } = props;
|
|
18
|
-
const { hrefs } = useAppConfig();
|
|
19
|
-
const { logout } = useAppActions();
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<Letterhead>
|
|
23
|
-
<LetterheadHeading>Logged in</LetterheadHeading>
|
|
24
|
-
<LetterheadParagraph>
|
|
25
|
-
You are already logged into Indie Tabletop Club as{" "}
|
|
26
|
-
<em>{currentUser.email}</em>.
|
|
27
|
-
</LetterheadParagraph>
|
|
28
|
-
|
|
29
|
-
<LetterheadParagraph>
|
|
30
|
-
<Link className={interactiveText} href={hrefs.dashboard()}>
|
|
31
|
-
Continue
|
|
32
|
-
</Link>
|
|
33
|
-
{` as the current user, or `}
|
|
34
|
-
<Button
|
|
35
|
-
className={interactiveText}
|
|
36
|
-
onClick={async () => {
|
|
37
|
-
await logout();
|
|
38
|
-
reload();
|
|
39
|
-
}}
|
|
40
|
-
>
|
|
41
|
-
log out
|
|
42
|
-
</Button>
|
|
43
|
-
.
|
|
44
|
-
</LetterheadParagraph>
|
|
45
|
-
</Letterhead>
|
|
46
|
-
);
|
|
47
|
-
}
|
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
import { http, HttpResponse } from "msw";
|
|
2
|
-
import preview from "../../.storybook/preview.tsx";
|
|
3
|
-
import { sleep } from "../sleep.ts";
|
|
4
|
-
import type { CurrentUser, SessionInfo } from "../types.ts";
|
|
5
|
-
import { CurrentUserFetcher } from "./CurrentUserFetcher.tsx";
|
|
6
|
-
|
|
7
|
-
function createMocks(options?: { responseSpeed?: number }) {
|
|
8
|
-
const simulateNetwork = () => sleep(options?.responseSpeed ?? 2000);
|
|
9
|
-
|
|
10
|
-
const john: CurrentUser = {
|
|
11
|
-
id: "john",
|
|
12
|
-
email: "john@example.com",
|
|
13
|
-
isVerified: true,
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const mary: CurrentUser = {
|
|
17
|
-
id: "mary",
|
|
18
|
-
email: "mary@example.com",
|
|
19
|
-
isVerified: true,
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const vernon: CurrentUser = {
|
|
23
|
-
id: "vernon",
|
|
24
|
-
email: "vernon@example.com",
|
|
25
|
-
isVerified: false,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const sessionInfo: SessionInfo = {
|
|
29
|
-
createdTs: 123,
|
|
30
|
-
expiresTs: 123,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
data: { john, mary, vernon },
|
|
35
|
-
handlers: {
|
|
36
|
-
refreshTokens: {
|
|
37
|
-
success: () => {
|
|
38
|
-
return http.post(
|
|
39
|
-
"http://mock.api/v1/sessions/access-tokens",
|
|
40
|
-
async () => {
|
|
41
|
-
await simulateNetwork();
|
|
42
|
-
return HttpResponse.json({ sessionInfo });
|
|
43
|
-
},
|
|
44
|
-
);
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
failed: () => {
|
|
48
|
-
return http.post(
|
|
49
|
-
"http://mock.api/v1/sessions/access-tokens",
|
|
50
|
-
async () => {
|
|
51
|
-
await simulateNetwork();
|
|
52
|
-
return HttpResponse.text("Refresh token expired or missing", {
|
|
53
|
-
status: 401,
|
|
54
|
-
});
|
|
55
|
-
},
|
|
56
|
-
);
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
getCurrentUser: {
|
|
61
|
-
success: (currentUser: CurrentUser) => {
|
|
62
|
-
return http.get("http://mock.api/v1/users/me", async () => {
|
|
63
|
-
await simulateNetwork();
|
|
64
|
-
return HttpResponse.json(currentUser);
|
|
65
|
-
});
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Cookie is valid, but user doesn't exist any more. This can happen
|
|
70
|
-
* after user deletion.
|
|
71
|
-
*/
|
|
72
|
-
notFound: () => {
|
|
73
|
-
return http.get("http://mock.api/v1/users/me", async () => {
|
|
74
|
-
await simulateNetwork();
|
|
75
|
-
return HttpResponse.text("User not found", { status: 404 });
|
|
76
|
-
});
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
noConnection: () => {
|
|
80
|
-
return http.get("http://mock.api/v1/users/me", async () => {
|
|
81
|
-
return HttpResponse.error();
|
|
82
|
-
});
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
unknownFailure: () => {
|
|
86
|
-
return http.get("http://mock.api/v1/users/me", async () => {
|
|
87
|
-
await simulateNetwork();
|
|
88
|
-
return HttpResponse.text("Internal server error", { status: 500 });
|
|
89
|
-
});
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Auth cookies no longer valid to make this request.
|
|
94
|
-
*/
|
|
95
|
-
notAuthenticated: () => {
|
|
96
|
-
return http.get("http://mock.api/v1/users/me", async () => {
|
|
97
|
-
await simulateNetwork();
|
|
98
|
-
return HttpResponse.text("Not authenticated", { status: 401 });
|
|
99
|
-
});
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
createNewSession: {
|
|
104
|
-
success: (currentUser: CurrentUser) => {
|
|
105
|
-
return http.post("http://mock.api/v1/sessions", async () => {
|
|
106
|
-
await simulateNetwork();
|
|
107
|
-
return HttpResponse.json({ currentUser, sessionInfo });
|
|
108
|
-
});
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
invalidCredentials: () => {
|
|
112
|
-
return http.post("http://mock.api/v1/sessions", async () => {
|
|
113
|
-
await simulateNetwork();
|
|
114
|
-
return HttpResponse.text("Credentials do not match", {
|
|
115
|
-
status: 401,
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
userNotFound: () => {
|
|
121
|
-
return http.post("http://mock.api/v1/sessions", async () => {
|
|
122
|
-
await simulateNetwork();
|
|
123
|
-
return HttpResponse.text("User not found", { status: 404 });
|
|
124
|
-
});
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
unknownFailure: () => {
|
|
128
|
-
return http.post("http://mock.api/v1/sessions", async () => {
|
|
129
|
-
await simulateNetwork();
|
|
130
|
-
return HttpResponse.text("Internal server error", { status: 500 });
|
|
131
|
-
});
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
|
|
135
|
-
requestVerify: {
|
|
136
|
-
success: () => {
|
|
137
|
-
return http.post(
|
|
138
|
-
"http://mock.api/v1/user-verification-tokens",
|
|
139
|
-
async () => {
|
|
140
|
-
await simulateNetwork();
|
|
141
|
-
return HttpResponse.json({ message: "OK", tokenId: "1" });
|
|
142
|
-
},
|
|
143
|
-
);
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
verify: {
|
|
148
|
-
success: () => {
|
|
149
|
-
return http.put(
|
|
150
|
-
"http://mock.api/v1/user-verification-tokens/:id",
|
|
151
|
-
async () => {
|
|
152
|
-
await simulateNetwork();
|
|
153
|
-
return HttpResponse.json({ message: "OK" });
|
|
154
|
-
},
|
|
155
|
-
);
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const { data, handlers } = createMocks({ responseSpeed: 700 });
|
|
163
|
-
|
|
164
|
-
const meta = preview.meta({
|
|
165
|
-
title: "Account/Current User Fetcher",
|
|
166
|
-
component: CurrentUserFetcher,
|
|
167
|
-
tags: ["autodocs"],
|
|
168
|
-
args: {
|
|
169
|
-
children: (
|
|
170
|
-
<div
|
|
171
|
-
style={{
|
|
172
|
-
minBlockSize: "20rem",
|
|
173
|
-
backgroundColor: "white",
|
|
174
|
-
display: "flex",
|
|
175
|
-
alignItems: "center",
|
|
176
|
-
justifyContent: "center",
|
|
177
|
-
borderRadius: "1rem",
|
|
178
|
-
}}
|
|
179
|
-
>
|
|
180
|
-
App content
|
|
181
|
-
</div>
|
|
182
|
-
),
|
|
183
|
-
},
|
|
184
|
-
parameters: {
|
|
185
|
-
msw: {
|
|
186
|
-
handlers: {
|
|
187
|
-
refreshTokens: handlers.refreshTokens.failed(),
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* The default case, in which a local user is provided (so they have previously
|
|
195
|
-
* logged in), and the current user request returns the same user as is
|
|
196
|
-
* the local user (determined by the user id).
|
|
197
|
-
*/
|
|
198
|
-
export const Default = meta.story({
|
|
199
|
-
parameters: {
|
|
200
|
-
msw: {
|
|
201
|
-
handlers: {
|
|
202
|
-
getCurrentUser: handlers.getCurrentUser.success(data.john),
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* In this case, no local user is provided and the component simply renders
|
|
210
|
-
* its children. There should be no network request in this case.
|
|
211
|
-
*/
|
|
212
|
-
export const NoLocalUser = meta.story({});
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* In this case, the local user is provided and the current user request returns
|
|
216
|
-
* error 401. The user should supply their credentials again.
|
|
217
|
-
*/
|
|
218
|
-
export const SessionExpired = meta.story({
|
|
219
|
-
parameters: {
|
|
220
|
-
msw: {
|
|
221
|
-
handlers: {
|
|
222
|
-
getCurrentUser: handlers.getCurrentUser.notAuthenticated(),
|
|
223
|
-
},
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* In this case, the local user is provided and the current user request returns
|
|
230
|
-
* a different user (determined by user ID).
|
|
231
|
-
*
|
|
232
|
-
* This case can happen when user A logs into app X, then user B logs into
|
|
233
|
-
* app Y. Returning to app X, user B will be logged into ITC with their account
|
|
234
|
-
* but local data belong to user A.
|
|
235
|
-
*
|
|
236
|
-
* In practice this should be a rare case, but with unpleasant circumstances
|
|
237
|
-
* if not handled correctly.
|
|
238
|
-
*/
|
|
239
|
-
export const UserMismatch = meta.story({
|
|
240
|
-
parameters: {
|
|
241
|
-
msw: {
|
|
242
|
-
handlers: {
|
|
243
|
-
getCurrentUser: handlers.getCurrentUser.success(data.mary),
|
|
244
|
-
},
|
|
245
|
-
},
|
|
246
|
-
},
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
*/
|
|
251
|
-
export const UserUnverified = meta.story({
|
|
252
|
-
parameters: {
|
|
253
|
-
msw: {
|
|
254
|
-
handlers: {
|
|
255
|
-
getCurrentUser: handlers.getCurrentUser.success(data.vernon),
|
|
256
|
-
requestVerify: handlers.requestVerify.success(),
|
|
257
|
-
verify: handlers.verify.success(),
|
|
258
|
-
refreshTokens: handlers.refreshTokens.success(),
|
|
259
|
-
},
|
|
260
|
-
},
|
|
261
|
-
},
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* In this case, the local user is provided and the current user request returns
|
|
266
|
-
* 404, indicating that the current user no longer exists.
|
|
267
|
-
*
|
|
268
|
-
* This can happen if users delete their accounts but
|
|
269
|
-
*/
|
|
270
|
-
export const UserNotFound = meta.story({
|
|
271
|
-
parameters: {
|
|
272
|
-
msw: {
|
|
273
|
-
handlers: {
|
|
274
|
-
getCurrentUser: handlers.getCurrentUser.notFound(),
|
|
275
|
-
},
|
|
276
|
-
},
|
|
277
|
-
},
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* The proactive user session check has failed due to an error that doesn't
|
|
282
|
-
* carry any special meaning.
|
|
283
|
-
*/
|
|
284
|
-
export const UnknownFailure = meta.story({
|
|
285
|
-
parameters: {
|
|
286
|
-
msw: {
|
|
287
|
-
handlers: {
|
|
288
|
-
getCurrentUser: handlers.getCurrentUser.unknownFailure(),
|
|
289
|
-
},
|
|
290
|
-
},
|
|
291
|
-
},
|
|
292
|
-
});
|