@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.
Files changed (269) hide show
  1. package/dist/AppConfig/AppConfig.d.ts +29 -0
  2. package/dist/AuthCard/AuthCard.d.ts +10 -0
  3. package/dist/AuthCard/AuthCard.stories.d.ts +34 -0
  4. package/dist/AuthCard/style.css.d.ts +23 -0
  5. package/dist/DialogTrigger/index.d.ts +13 -0
  6. package/dist/DocumentTitle/DocumentTitle.d.ts +3 -0
  7. package/dist/EnumMapper.d.ts +25 -0
  8. package/dist/ExternalLink.d.ts +3 -0
  9. package/dist/FullscreenDismissBlocker.d.ts +5 -0
  10. package/{lib/HistoryState.ts → dist/HistoryState.d.ts} +2 -5
  11. package/dist/IndieTabletopClubLogo.d.ts +7 -0
  12. package/dist/IndieTabletopClubSymbol.d.ts +7 -0
  13. package/dist/InfoPage/index.d.ts +8 -0
  14. package/dist/InfoPage/pages.d.ts +2 -0
  15. package/dist/InfoPage/style.css.d.ts +5 -0
  16. package/dist/Letterhead/index.d.ts +19 -0
  17. package/dist/Letterhead/stories.d.ts +13 -0
  18. package/dist/Letterhead/style.css.d.ts +46 -0
  19. package/dist/LetterheadForm/LetterheadReadonlyTextField.stories.d.ts +17 -0
  20. package/dist/LetterheadForm/LetterheadSubmitError.stories.d.ts +11 -0
  21. package/dist/LetterheadForm/LetterheadTextField.stories.d.ts +336 -0
  22. package/dist/LetterheadForm/index.d.ts +44 -0
  23. package/dist/LetterheadForm/style.css.d.ts +8 -0
  24. package/dist/LoadingIndicator.d.ts +3 -0
  25. package/dist/MiddotSeparated/MiddotSeparated.d.ts +8 -0
  26. package/dist/MiddotSeparated/MiddotSeparated.stories.d.ts +586 -0
  27. package/dist/MiddotSeparated/style.css.d.ts +1 -0
  28. package/dist/ModalDialog/index.d.ts +12 -0
  29. package/dist/ModalDialog/style.css.d.ts +58 -0
  30. package/dist/ModernIDB/Cursor.d.ts +56 -0
  31. package/dist/ModernIDB/ModernIDB.d.ts +66 -0
  32. package/dist/ModernIDB/ModernIDBError.d.ts +3 -0
  33. package/dist/ModernIDB/ObjectStore.d.ts +112 -0
  34. package/dist/ModernIDB/ObjectStoreIndex.d.ts +53 -0
  35. package/dist/ModernIDB/Transaction.d.ts +16 -0
  36. package/dist/ModernIDB/VersionChangeManager.d.ts +30 -0
  37. package/dist/ModernIDB/bindings/factory.d.ts +12 -0
  38. package/dist/ModernIDB/bindings/index.d.ts +2 -0
  39. package/{lib/ModernIDB/bindings/types.ts → dist/ModernIDB/bindings/types.d.ts} +13 -32
  40. package/dist/ModernIDB/bindings/utils.d.ts +2 -0
  41. package/dist/ModernIDB/index.d.ts +10 -0
  42. package/dist/ModernIDB/types.d.ts +88 -0
  43. package/dist/ModernIDB/utils.d.ts +4 -0
  44. package/dist/QRCode/QRCode.d.ts +7 -0
  45. package/dist/QRCode/QRCode.stories.d.ts +33 -0
  46. package/dist/QRCode/style.css.d.ts +4 -0
  47. package/dist/ReleaseInfo/index.d.ts +5 -0
  48. package/dist/RulesetResolver.d.ts +87 -0
  49. package/dist/SafariCheck/SafariCheck.d.ts +23 -0
  50. package/dist/SafariCheck/SafariCheck.stories.d.ts +73 -0
  51. package/dist/SafariCheck/style.css.d.ts +17 -0
  52. package/dist/ServiceWorkerHandler.d.ts +11 -0
  53. package/dist/ShareButton/ShareButton.d.ts +57 -0
  54. package/dist/ShareButton/ShareButton.stories.d.ts +1577 -0
  55. package/dist/ShareButton/test.css.d.ts +1 -0
  56. package/dist/SubscribeCard/LetterheadInfoCard.d.ts +2 -0
  57. package/dist/SubscribeCard/SubscribeByEmailCard.d.ts +24 -0
  58. package/dist/SubscribeCard/SubscribeByEmailCard.stories.d.ts +10 -0
  59. package/dist/SubscribeCard/SubscribeByPledgeCard.d.ts +36 -0
  60. package/dist/SubscribeCard/SubscribeByPledgeCard.stories.d.ts +65 -0
  61. package/dist/SubscribeCard/style.css.d.ts +4 -0
  62. package/dist/account/AccountIssueView.d.ts +3 -0
  63. package/dist/account/AlreadyLoggedInView.d.ts +5 -0
  64. package/dist/account/CurrentUserFetcher.d.ts +20 -0
  65. package/dist/account/CurrentUserFetcher.stories.d.ts +136 -0
  66. package/dist/account/FailureFallbackView.d.ts +1 -0
  67. package/dist/account/JoinCard.d.ts +14 -0
  68. package/dist/account/JoinCard.stories.d.ts +143 -0
  69. package/dist/account/LoadingView.d.ts +1 -0
  70. package/dist/account/LoginCard.d.ts +39 -0
  71. package/dist/account/LoginCard.stories.d.ts +217 -0
  72. package/dist/account/LoginView.d.ts +10 -0
  73. package/dist/account/NoConnectionView.d.ts +4 -0
  74. package/dist/account/PasswordResetCard.d.ts +15 -0
  75. package/dist/account/PasswordResetCard.stories.d.ts +128 -0
  76. package/dist/account/UserMismatchView.d.ts +6 -0
  77. package/dist/account/VerifyPage.d.ts +13 -0
  78. package/dist/account/style.css.d.ts +10 -0
  79. package/{lib/account/types.ts → dist/account/types.d.ts} +3 -6
  80. package/dist/account/useFetchCurrentUser.d.ts +28 -0
  81. package/dist/account/useRedirectPath.d.ts +6 -0
  82. package/dist/animations.css.d.ts +3 -0
  83. package/dist/append-copy-to-text.d.ts +10 -0
  84. package/dist/append-copy-to-text.test.d.ts +1 -0
  85. package/dist/appkit.css +1 -0
  86. package/dist/appkit.js +10692 -0
  87. package/dist/async-op.d.ts +101 -0
  88. package/dist/atomic.css.d.ts +6 -0
  89. package/{lib/caught-value.ts → dist/caught-value.d.ts} +1 -11
  90. package/{lib/class-names.ts → dist/class-names.d.ts} +6 -17
  91. package/dist/client.d.ts +424 -0
  92. package/dist/common.css.d.ts +5 -0
  93. package/dist/copyrightRange.d.ts +1 -0
  94. package/dist/copyrightRange.test.d.ts +1 -0
  95. package/dist/createSafeStorage.d.ts +34 -0
  96. package/dist/failureMessages.d.ts +20 -0
  97. package/dist/failureMessages.test.d.ts +1 -0
  98. package/dist/form/FormSubmitButton.d.ts +17 -0
  99. package/dist/form/SubmitErrorAlert.d.ts +5 -0
  100. package/dist/form/style.css.d.ts +3 -0
  101. package/dist/globals.css.d.ts +0 -0
  102. package/dist/groupBy.d.ts +1 -0
  103. package/dist/groupBy.test.d.ts +1 -0
  104. package/dist/hrefs.d.ts +32 -0
  105. package/dist/hrefs.test.d.ts +1 -0
  106. package/dist/idToDate.d.ts +5 -0
  107. package/dist/idToDate.test.d.ts +1 -0
  108. package/dist/ids.d.ts +1 -0
  109. package/dist/ids.test.d.ts +1 -0
  110. package/dist/index.d.ts +64 -0
  111. package/dist/internal.css.d.ts +2 -0
  112. package/dist/mailto.d.ts +8 -0
  113. package/dist/mailto.test.d.ts +1 -0
  114. package/dist/media.d.ts +39 -0
  115. package/dist/random.d.ts +3 -0
  116. package/dist/result/swr.d.ts +4 -0
  117. package/{lib/sleep.ts → dist/sleep.d.ts} +1 -3
  118. package/dist/store/index.d.ts +237 -0
  119. package/dist/store/store.d.ts +144 -0
  120. package/dist/store/types.d.ts +49 -0
  121. package/dist/store/utils.d.ts +10 -0
  122. package/dist/storybook/decorators.d.ts +3 -0
  123. package/dist/structs.d.ts +1 -0
  124. package/{lib/typeguards.ts → dist/typeguards.d.ts} +1 -3
  125. package/dist/typeguards.test.d.ts +1 -0
  126. package/{lib/types.ts → dist/types.d.ts} +12 -23
  127. package/dist/unique.d.ts +10 -0
  128. package/dist/unique.test.d.ts +1 -0
  129. package/dist/use-async-op.d.ts +6 -0
  130. package/dist/use-document-background-color.d.ts +4 -0
  131. package/dist/use-form.d.ts +29 -0
  132. package/dist/use-is-installed.d.ts +8 -0
  133. package/dist/use-media-query.d.ts +1 -0
  134. package/dist/use-reverting-state.d.ts +5 -0
  135. package/dist/use-scroll-restoration.d.ts +25 -0
  136. package/dist/useEnsureValue.d.ts +6 -0
  137. package/dist/useInvokeClient.d.ts +25 -0
  138. package/dist/useIsVisible.d.ts +4 -0
  139. package/dist/utm.d.ts +58 -0
  140. package/dist/utm.test.d.ts +1 -0
  141. package/dist/validations.d.ts +3 -0
  142. package/dist/vars.css.d.ts +10 -0
  143. package/package.json +12 -5
  144. package/lib/AppConfig/AppConfig.tsx +0 -61
  145. package/lib/AuthCard/AuthCard.stories.ts +0 -34
  146. package/lib/AuthCard/AuthCard.tsx +0 -64
  147. package/lib/AuthCard/style.css.ts +0 -49
  148. package/lib/DialogTrigger/index.tsx +0 -36
  149. package/lib/DocumentTitle/DocumentTitle.tsx +0 -10
  150. package/lib/EnumMapper.ts +0 -50
  151. package/lib/ExternalLink.tsx +0 -10
  152. package/lib/FullscreenDismissBlocker.tsx +0 -23
  153. package/lib/IndieTabletopClubLogo.tsx +0 -44
  154. package/lib/IndieTabletopClubSymbol.tsx +0 -37
  155. package/lib/InfoPage/index.tsx +0 -46
  156. package/lib/InfoPage/pages.tsx +0 -36
  157. package/lib/InfoPage/style.css.ts +0 -36
  158. package/lib/Letterhead/index.tsx +0 -85
  159. package/lib/Letterhead/stories.tsx +0 -41
  160. package/lib/Letterhead/style.css.ts +0 -152
  161. package/lib/LetterheadForm/LetterheadReadonlyTextField.stories.tsx +0 -17
  162. package/lib/LetterheadForm/LetterheadSubmitError.stories.tsx +0 -19
  163. package/lib/LetterheadForm/LetterheadTextField.stories.tsx +0 -19
  164. package/lib/LetterheadForm/index.tsx +0 -137
  165. package/lib/LetterheadForm/style.css.ts +0 -89
  166. package/lib/LoadingIndicator.tsx +0 -40
  167. package/lib/MiddotSeparated/MiddotSeparated.stories.ts +0 -26
  168. package/lib/MiddotSeparated/MiddotSeparated.tsx +0 -26
  169. package/lib/MiddotSeparated/style.css.ts +0 -10
  170. package/lib/ModalDialog/index.tsx +0 -28
  171. package/lib/ModalDialog/style.css.ts +0 -88
  172. package/lib/ModernIDB/Cursor.ts +0 -91
  173. package/lib/ModernIDB/ModernIDB.ts +0 -337
  174. package/lib/ModernIDB/ModernIDBError.ts +0 -9
  175. package/lib/ModernIDB/ObjectStore.ts +0 -195
  176. package/lib/ModernIDB/ObjectStoreIndex.ts +0 -102
  177. package/lib/ModernIDB/README.md +0 -9
  178. package/lib/ModernIDB/Transaction.ts +0 -40
  179. package/lib/ModernIDB/VersionChangeManager.ts +0 -57
  180. package/lib/ModernIDB/bindings/factory.tsx +0 -165
  181. package/lib/ModernIDB/bindings/index.ts +0 -2
  182. package/lib/ModernIDB/bindings/utils.tsx +0 -32
  183. package/lib/ModernIDB/index.ts +0 -10
  184. package/lib/ModernIDB/types.ts +0 -120
  185. package/lib/ModernIDB/utils.ts +0 -51
  186. package/lib/QRCode/QRCode.stories.tsx +0 -41
  187. package/lib/QRCode/QRCode.tsx +0 -54
  188. package/lib/QRCode/style.css.ts +0 -23
  189. package/lib/ReleaseInfo/index.tsx +0 -29
  190. package/lib/RulesetResolver.ts +0 -214
  191. package/lib/SafariCheck/SafariCheck.stories.tsx +0 -99
  192. package/lib/SafariCheck/SafariCheck.tsx +0 -273
  193. package/lib/SafariCheck/addToDock.svg +0 -13
  194. package/lib/SafariCheck/addToHomeScreen.svg +0 -12
  195. package/lib/SafariCheck/safari.svg +0 -32
  196. package/lib/SafariCheck/shareIcon.svg +0 -11
  197. package/lib/SafariCheck/style.css.ts +0 -106
  198. package/lib/ServiceWorkerHandler.tsx +0 -53
  199. package/lib/ShareButton/ShareButton.stories.tsx +0 -58
  200. package/lib/ShareButton/ShareButton.tsx +0 -153
  201. package/lib/ShareButton/test.css.ts +0 -3
  202. package/lib/SubscribeCard/LetterheadInfoCard.tsx +0 -23
  203. package/lib/SubscribeCard/SubscribeByEmailCard.stories.tsx +0 -69
  204. package/lib/SubscribeCard/SubscribeByEmailCard.tsx +0 -183
  205. package/lib/SubscribeCard/SubscribeByPledgeCard.stories.tsx +0 -133
  206. package/lib/SubscribeCard/SubscribeByPledgeCard.tsx +0 -127
  207. package/lib/SubscribeCard/style.css.ts +0 -14
  208. package/lib/account/AccountIssueView.tsx +0 -44
  209. package/lib/account/AlreadyLoggedInView.tsx +0 -47
  210. package/lib/account/CurrentUserFetcher.stories.tsx +0 -292
  211. package/lib/account/CurrentUserFetcher.tsx +0 -118
  212. package/lib/account/FailureFallbackView.tsx +0 -36
  213. package/lib/account/JoinCard.stories.tsx +0 -257
  214. package/lib/account/JoinCard.tsx +0 -301
  215. package/lib/account/LoadingView.tsx +0 -14
  216. package/lib/account/LoginCard.stories.tsx +0 -288
  217. package/lib/account/LoginCard.tsx +0 -100
  218. package/lib/account/LoginView.tsx +0 -151
  219. package/lib/account/NoConnectionView.tsx +0 -34
  220. package/lib/account/PasswordResetCard.stories.tsx +0 -242
  221. package/lib/account/PasswordResetCard.tsx +0 -296
  222. package/lib/account/UserMismatchView.tsx +0 -62
  223. package/lib/account/VerifyPage.tsx +0 -195
  224. package/lib/account/style.css.ts +0 -57
  225. package/lib/account/useFetchCurrentUser.tsx +0 -63
  226. package/lib/account/useRedirectPath.ts +0 -21
  227. package/lib/animations.css.ts +0 -17
  228. package/lib/append-copy-to-text.ts +0 -35
  229. package/lib/async-op.ts +0 -286
  230. package/lib/atomic.css.ts +0 -11
  231. package/lib/client.ts +0 -662
  232. package/lib/common.css.ts +0 -48
  233. package/lib/copyrightRange.ts +0 -10
  234. package/lib/createSafeStorage.ts +0 -91
  235. package/lib/failureMessages.ts +0 -108
  236. package/lib/form/FormSubmitButton.tsx +0 -58
  237. package/lib/form/SubmitErrorAlert.tsx +0 -21
  238. package/lib/form/style.css.ts +0 -9
  239. package/lib/globals.css.ts +0 -62
  240. package/lib/groupBy.ts +0 -25
  241. package/lib/hrefs.ts +0 -48
  242. package/lib/idToDate.ts +0 -8
  243. package/lib/ids.ts +0 -6
  244. package/lib/index.ts +0 -71
  245. package/lib/internal.css.ts +0 -10
  246. package/lib/mailto.ts +0 -40
  247. package/lib/media.ts +0 -50
  248. package/lib/random.ts +0 -19
  249. package/lib/result/swr.ts +0 -18
  250. package/lib/store/index.tsx +0 -241
  251. package/lib/store/store.ts +0 -479
  252. package/lib/store/types.ts +0 -45
  253. package/lib/store/utils.ts +0 -54
  254. package/lib/storybook/decorators.tsx +0 -10
  255. package/lib/structs.ts +0 -3
  256. package/lib/unique.ts +0 -24
  257. package/lib/use-async-op.ts +0 -16
  258. package/lib/use-document-background-color.ts +0 -16
  259. package/lib/use-form.ts +0 -78
  260. package/lib/use-is-installed.ts +0 -17
  261. package/lib/use-media-query.ts +0 -21
  262. package/lib/use-reverting-state.ts +0 -32
  263. package/lib/use-scroll-restoration.ts +0 -99
  264. package/lib/useEnsureValue.ts +0 -31
  265. package/lib/useInvokeClient.ts +0 -54
  266. package/lib/useIsVisible.ts +0 -27
  267. package/lib/utm.ts +0 -92
  268. package/lib/validations.ts +0 -25
  269. package/lib/vars.css.ts +0 -13
@@ -1,14 +0,0 @@
1
- import { cx } from "../class-names.ts";
2
- import { Letterhead } from "../Letterhead/index.tsx";
3
- import { LoadingIndicator } from "../LoadingIndicator.tsx";
4
- import { loadingView } from "./style.css.ts";
5
-
6
- export function LoadingView() {
7
- return (
8
- <Letterhead>
9
- <div {...cx(loadingView.container)}>
10
- <LoadingIndicator />
11
- </div>
12
- </Letterhead>
13
- );
14
- }
@@ -1,288 +0,0 @@
1
- import { http, HttpResponse } from "msw";
2
- import { fn } from "storybook/test";
3
- import preview from "../../.storybook/preview.tsx";
4
- import { sleep } from "../sleep.ts";
5
- import type { CurrentUser, SessionInfo } from "../types.ts";
6
- import { LoginCard } from "./LoginCard.tsx";
7
-
8
- function createMocks(options?: { responseSpeed?: number }) {
9
- const simulateNetwork = () => sleep(options?.responseSpeed ?? 2000);
10
-
11
- const john: CurrentUser = {
12
- id: "john",
13
- email: "john@example.com",
14
- isVerified: true,
15
- };
16
-
17
- const mary: CurrentUser = {
18
- id: "mary",
19
- email: "mary@example.com",
20
- isVerified: true,
21
- };
22
-
23
- const sessionInfo: SessionInfo = {
24
- createdTs: 123,
25
- expiresTs: 123,
26
- };
27
-
28
- return {
29
- data: { john, mary },
30
- handlers: {
31
- refreshTokens: {
32
- failed: () => {
33
- return http.post(
34
- "http://mock.api/v1/sessions/access-tokens",
35
- async () => {
36
- await simulateNetwork();
37
- return HttpResponse.text("Refresh token expired or missing", {
38
- status: 401,
39
- });
40
- },
41
- );
42
- },
43
- },
44
-
45
- getCurrentUser: {
46
- success: (currentUser: CurrentUser) => {
47
- return http.get("http://mock.api/v1/users/me", async () => {
48
- await simulateNetwork();
49
- return HttpResponse.json(currentUser);
50
- });
51
- },
52
-
53
- /**
54
- * Cookie is valid, but user doesn't exist any more. This can happen
55
- * after user deletion.
56
- */
57
- notFound: () => {
58
- return http.get("http://mock.api/v1/users/me", async () => {
59
- await simulateNetwork();
60
- return HttpResponse.text("User not found", { status: 404 });
61
- });
62
- },
63
-
64
- noConnection: () => {
65
- return http.get("http://mock.api/v1/users/me", async () => {
66
- return HttpResponse.error();
67
- });
68
- },
69
-
70
- unknownFailure: () => {
71
- return http.get("http://mock.api/v1/users/me", async () => {
72
- await simulateNetwork();
73
- return HttpResponse.text("Internal server error", { status: 500 });
74
- });
75
- },
76
-
77
- /**
78
- * Auth cookies no longer valid to make this request.
79
- */
80
- notAuthenticated: () => {
81
- return http.get("http://mock.api/v1/users/me", async () => {
82
- await simulateNetwork();
83
- return HttpResponse.text("Not authenticated", { status: 401 });
84
- });
85
- },
86
- },
87
-
88
- createNewSession: {
89
- success: (currentUser: CurrentUser) => {
90
- return http.post("http://mock.api/v1/sessions", async () => {
91
- await simulateNetwork();
92
- return HttpResponse.json({ currentUser, sessionInfo });
93
- });
94
- },
95
-
96
- invalidCredentials: () => {
97
- return http.post("http://mock.api/v1/sessions", async () => {
98
- await simulateNetwork();
99
- return HttpResponse.text("Credentials do not match", {
100
- status: 401,
101
- });
102
- });
103
- },
104
-
105
- userNotFound: () => {
106
- return http.post("http://mock.api/v1/sessions", async () => {
107
- await simulateNetwork();
108
- return HttpResponse.text("User not found", { status: 404 });
109
- });
110
- },
111
-
112
- unknownFailure: () => {
113
- return http.post("http://mock.api/v1/sessions", async () => {
114
- await simulateNetwork();
115
- return HttpResponse.text("Internal server error", { status: 500 });
116
- });
117
- },
118
- },
119
- },
120
- };
121
- }
122
-
123
- const { data, handlers } = createMocks({ responseSpeed: 700 });
124
-
125
- const meta = preview.meta({
126
- title: "Account/Login Card",
127
- component: LoginCard,
128
- tags: ["autodocs"],
129
- args: {
130
- description: "Log in to Indie Tabletop Club to enable backup & sync.",
131
- defaultValues: {},
132
- onLogin: fn(),
133
- },
134
- parameters: {
135
- msw: {
136
- handlers: {
137
- refreshTokens: handlers.refreshTokens.failed(),
138
- },
139
- },
140
- },
141
- });
142
-
143
- /**
144
- * The majority case where no user is stored locally, proactive user session
145
- * check returns 401, and subsequently correct credentials are provided.
146
- */
147
- export const Default = meta.story({
148
- parameters: {
149
- msw: {
150
- handlers: {
151
- getCurrentUser: handlers.getCurrentUser.notAuthenticated(),
152
- createNewSession: handlers.createNewSession.success(data.john),
153
- },
154
- },
155
- },
156
- });
157
-
158
- /**
159
- * Similar to the default case, but invalid credentials are provided to when
160
- * attempting to create a new session.
161
- */
162
- export const InvalidCredentialsOnSubmit = meta.story({
163
- parameters: {
164
- msw: {
165
- handlers: {
166
- getCurrentUser: handlers.getCurrentUser.notAuthenticated(),
167
- createNewSession: handlers.createNewSession.invalidCredentials(),
168
- },
169
- },
170
- },
171
- });
172
-
173
- /**
174
- * Similar to the default case, but when credentials are provided, an account
175
- * email is used that is not currently in the database.
176
- */
177
- export const UserNotFoundOnSubmit = meta.story({
178
- parameters: {
179
- msw: {
180
- handlers: {
181
- getCurrentUser: handlers.getCurrentUser.notAuthenticated(),
182
- createNewSession: handlers.createNewSession.userNotFound(),
183
- },
184
- },
185
- },
186
- });
187
-
188
- /**
189
- * Similar to the default case, but the session creation call returns an error
190
- * that doesn't have a specific meaning in the context of the login page.
191
- */
192
- export const UnknownFailureOnSubmit = meta.story({
193
- parameters: {
194
- msw: {
195
- handlers: {
196
- getCurrentUser: handlers.getCurrentUser.notAuthenticated(),
197
- createNewSession: handlers.createNewSession.unknownFailure(),
198
- },
199
- },
200
- },
201
- });
202
-
203
- /**
204
- * A case when user is stored locally, but their server session has expired.
205
- */
206
- export const ReauthenticateSession = meta.story({
207
- parameters: {
208
- msw: {
209
- handlers: {
210
- getCurrentUser: handlers.getCurrentUser.notAuthenticated(),
211
- createNewSession: handlers.createNewSession.success(data.john),
212
- },
213
- },
214
- },
215
- });
216
-
217
- /**
218
- * The user is already stored in the app, and proactive user-session check
219
- * returns the same user (based on ID).
220
- *
221
- * The user is directed to app without any further steps.
222
- */
223
- export const AlreadyLoggedIn = meta.story({
224
- parameters: {
225
- msw: {
226
- handlers: {
227
- getCurrentUser: handlers.getCurrentUser.success(data.john),
228
- },
229
- },
230
- },
231
- });
232
-
233
- /**
234
- * A user is provided, and proactive user session check returns a different
235
- * user. This can happen when different users log into separate apps with
236
- * different credentials.
237
- */
238
- export const UserMismatch = meta.story({
239
- parameters: {
240
- msw: {
241
- handlers: {
242
- getCurrentUser: handlers.getCurrentUser.success(data.mary),
243
- },
244
- },
245
- },
246
- });
247
-
248
- /**
249
- * During the proactive user session check, the user is reportd as not found.
250
- * This means that the tokens are still valid, but the user DB entity is gone.
251
- * This can happen if a user closed their account.
252
- */
253
- export const UserNotFound = meta.story({
254
- parameters: {
255
- msw: {
256
- handlers: {
257
- getCurrentUser: handlers.getCurrentUser.notFound(),
258
- },
259
- },
260
- },
261
- });
262
-
263
- /**
264
- * The proactive user session check has failed due to connection issues.
265
- */
266
- export const NoConnection = meta.story({
267
- parameters: {
268
- msw: {
269
- handlers: {
270
- getCurrentUser: handlers.getCurrentUser.noConnection(),
271
- },
272
- },
273
- },
274
- });
275
-
276
- /**
277
- * The proactive user session check has failed due to an error that doesn't
278
- * carry any special meaning.
279
- */
280
- export const UnknownFailure = meta.story({
281
- parameters: {
282
- msw: {
283
- handlers: {
284
- getCurrentUser: handlers.getCurrentUser.unknownFailure(),
285
- },
286
- },
287
- },
288
- });
@@ -1,100 +0,0 @@
1
- import { type ReactNode } from "react";
2
- import { useCurrentUser } from "../store/index.tsx";
3
- import { AccountIssueView } from "./AccountIssueView.tsx";
4
- import { AlreadyLoggedInView } from "./AlreadyLoggedInView.tsx";
5
- import { FailureFallbackView } from "./FailureFallbackView.tsx";
6
- import { LoadingView } from "./LoadingView.tsx";
7
- import { LoginView } from "./LoginView.tsx";
8
- import { NoConnectionView } from "./NoConnectionView.tsx";
9
- import type { AuthEventHandler, DefaultFormValues } from "./types.ts";
10
- import { useFetchCurrentUser } from "./useFetchCurrentUser.tsx";
11
- import { UserMismatchView } from "./UserMismatchView.tsx";
12
-
13
- export type LoginCardProps = {
14
- /**
15
- * A description that will appear in the default login case (i.e. when an
16
- * unauthenticated user is prompted to log in).
17
- *
18
- * This should reinforce to the user the benefits that they are going to
19
- * get by signing in. Every app has slightly different capabilities, so this
20
- * should be tailored for each individual app.
21
- */
22
- description: ReactNode;
23
-
24
- /**
25
- * Default values for the login form.
26
- *
27
- * You might want to provide a value from history state or query param, so
28
- * that if a user jumps between multiple pages with email field, the email
29
- * address is maintained across these locations.
30
- */
31
- defaultValues?: DefaultFormValues;
32
-
33
- /**
34
- * Called when the login action succeeds.
35
- *
36
- * If no handler is provided, the component will will navigate to the
37
- * dashboard (as determined by `appConfig.hrefs.dashboard()` return value),
38
- * or a location provided in `redirectTo` query param if it is a valid
39
- * local path.
40
- */
41
- onLogin?: AuthEventHandler;
42
- };
43
-
44
- /**
45
- * Allows the user to log into Indie Tabletop Club.
46
- *
47
- * Will automatically use the `redirectTo` query param value as the redirect
48
- * location after successful login.
49
- *
50
- * Otherwise, the user will be redirected to the app's dashboard.
51
- */
52
- export function LoginCard(props: LoginCardProps) {
53
- const currentUser = useCurrentUser();
54
- const { result, latestAttemptTs, reload } = useFetchCurrentUser();
55
-
56
- return result.unpack(
57
- (serverUser) => {
58
- if (currentUser && currentUser.id !== serverUser.id) {
59
- return (
60
- <UserMismatchView
61
- serverUser={serverUser}
62
- localUser={currentUser}
63
- reload={reload}
64
- />
65
- );
66
- }
67
-
68
- return <AlreadyLoggedInView currentUser={serverUser} reload={reload} />;
69
- },
70
-
71
- (failure) => {
72
- if (failure.type === "API_ERROR") {
73
- if (failure.code === 401) {
74
- return (
75
- <LoginView {...props} currentUser={currentUser} reload={reload} />
76
- );
77
- }
78
-
79
- if (failure.code === 404) {
80
- return <AccountIssueView reload={reload} />;
81
- }
82
- }
83
-
84
- if (failure.type === "NETWORK_ERROR") {
85
- return (
86
- <NoConnectionView
87
- latestAttemptTs={latestAttemptTs}
88
- onRetry={() => reload()}
89
- />
90
- );
91
- }
92
-
93
- return <FailureFallbackView />;
94
- },
95
-
96
- () => {
97
- return <LoadingView />;
98
- },
99
- );
100
- }
@@ -1,151 +0,0 @@
1
- import { Button, Form, useStoreState } from "@ariakit/react";
2
- import type { ReactNode } from "react";
3
- import { Link, useLocation } from "wouter";
4
- import { useAppConfig } from "../AppConfig/AppConfig.tsx";
5
- import { interactiveText } from "../common.css.ts";
6
- import { getSubmitFailureMessage } from "../failureMessages.ts";
7
- import {
8
- Letterhead,
9
- LetterheadHeading,
10
- LetterheadParagraph,
11
- LetterheadSubmitButton,
12
- } from "../Letterhead/index.tsx";
13
- import {
14
- InputsStack,
15
- LetterheadFormActions,
16
- LetterheadHeader,
17
- LetterheadSubmitError,
18
- LetterheadTextField,
19
- } from "../LetterheadForm/index.tsx";
20
- import { useAppActions } from "../store/index.tsx";
21
- import type { CurrentUser } from "../types.ts";
22
- import { useForm } from "../use-form.ts";
23
- import { validEmail } from "../validations.ts";
24
- import type { AuthEventHandler, DefaultFormValues } from "./types.ts";
25
- import { useRedirectPath } from "./useRedirectPath.ts";
26
-
27
- export function LoginView(props: {
28
- defaultValues?: DefaultFormValues;
29
- onLogin?: AuthEventHandler;
30
- currentUser: CurrentUser | null;
31
- description: ReactNode;
32
- reload: () => void;
33
- }) {
34
- const { currentUser, defaultValues, description, onLogin, reload } = props;
35
- const { placeholders, client, hrefs } = useAppConfig();
36
- const { logout } = useAppActions();
37
-
38
- const localUserPresent = !!currentUser?.email;
39
- const defaultEmailValue = currentUser?.email ?? defaultValues?.email ?? "";
40
- const redirectPath = useRedirectPath() ?? hrefs.dashboard();
41
- const [_, navigate] = useLocation();
42
-
43
- const { form, submitName } = useForm({
44
- defaultValues: { email: defaultEmailValue, password: "" },
45
- validate: { email: validEmail },
46
- async onSubmit({ values }) {
47
- const result = await client.login(values);
48
-
49
- return result.mapFailure((failure) => {
50
- return getSubmitFailureMessage(failure, {
51
- 401: "🔐 Username and password do not match.",
52
- 404: "🤔 Couldn't find a user with this email address.",
53
- });
54
- });
55
- },
56
- onSuccess() {
57
- if (onLogin) {
58
- onLogin();
59
- }
60
-
61
- // If a custom onLogin handler is not provided, will automatically
62
- // navigate to the appropriate redirect path.
63
- else {
64
- navigate(redirectPath);
65
- }
66
- },
67
- });
68
-
69
- const emailValue = useStoreState(form, (state) => state.values.email);
70
-
71
- return (
72
- <Letterhead>
73
- <LetterheadHeader>
74
- <LetterheadHeading>Log in</LetterheadHeading>
75
-
76
- {localUserPresent ? (
77
- <>
78
- <LetterheadParagraph>
79
- Your session has expired. Please log into Indie Tabletop Club
80
- again.
81
- </LetterheadParagraph>
82
-
83
- <LetterheadParagraph>
84
- {"To use a different account, please "}
85
- <Button
86
- className={interactiveText}
87
- onClick={async () => {
88
- await logout();
89
- reload();
90
- }}
91
- >
92
- log out
93
- </Button>
94
- {" first."}
95
- </LetterheadParagraph>
96
- </>
97
- ) : (
98
- <LetterheadParagraph>
99
- {description}
100
- {" Do not have an account? "}
101
- <Link
102
- href={hrefs.join()}
103
- className={interactiveText}
104
- state={{ emailValue }}
105
- >
106
- Join now
107
- </Link>
108
- {"."}
109
- </LetterheadParagraph>
110
- )}
111
- </LetterheadHeader>
112
-
113
- <Form store={form} resetOnSubmit={false}>
114
- <InputsStack>
115
- <LetterheadTextField
116
- name={form.names.email}
117
- placeholder={placeholders.email}
118
- label="Email"
119
- type="email"
120
- readOnly={localUserPresent}
121
- required
122
- />
123
- <LetterheadTextField
124
- name={form.names.password}
125
- label="Password"
126
- placeholder="Your password"
127
- type="password"
128
- required
129
- />
130
- </InputsStack>
131
-
132
- <LetterheadFormActions>
133
- <LetterheadSubmitError name={submitName} />
134
- <LetterheadSubmitButton>Log in</LetterheadSubmitButton>
135
-
136
- <LetterheadParagraph align="start">
137
- Forgot password?{" "}
138
- <Link
139
- href="/password"
140
- className={interactiveText}
141
- state={{ emailValue }}
142
- >
143
- Reset it
144
- </Link>
145
- {"."}
146
- </LetterheadParagraph>
147
- </LetterheadFormActions>
148
- </Form>
149
- </Letterhead>
150
- );
151
- }
@@ -1,34 +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
-
10
- export function NoConnectionView(props: {
11
- latestAttemptTs: number;
12
- onRetry: () => void;
13
- }) {
14
- const { latestAttemptTs, onRetry } = props;
15
-
16
- return (
17
- <Letterhead>
18
- <LetterheadHeading>No connection</LetterheadHeading>
19
-
20
- <LetterheadParagraph>
21
- {"There seems to be an issue reaching to our servers. "}
22
- {"Are you connected to the internet? Last attempt at "}
23
- {new Date(latestAttemptTs).toLocaleTimeString()}
24
- {"."}
25
- </LetterheadParagraph>
26
-
27
- <LetterheadParagraph>
28
- <Button {...cx(interactiveText)} onClick={() => onRetry()}>
29
- Try again
30
- </Button>
31
- </LetterheadParagraph>
32
- </Letterhead>
33
- );
34
- }