@atproto/oauth-provider-ui 0.1.0 → 0.1.2

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 (194) hide show
  1. package/dist/authorization-page-Dhx8lvtZ.js +3 -0
  2. package/dist/authorization-page-Dhx8lvtZ.js.map +1 -0
  3. package/dist/bundle-manifest.json +630 -0
  4. package/dist/error-page-DC6Vc-cv.js +2 -0
  5. package/dist/error-page-DC6Vc-cv.js.map +1 -0
  6. package/dist/error-view-CRGNTAn2.css +1 -0
  7. package/dist/error-view-MVy7C9l0.js +59 -0
  8. package/dist/error-view-MVy7C9l0.js.map +1 -0
  9. package/dist/index-CHPoD7Rp.js +20 -0
  10. package/dist/index-CHPoD7Rp.js.map +1 -0
  11. package/dist/messages-B0mgsxS-.js +2 -0
  12. package/dist/messages-B0mgsxS-.js.map +1 -0
  13. package/dist/messages-B5g8Fkio.js +2 -0
  14. package/dist/messages-B5g8Fkio.js.map +1 -0
  15. package/dist/messages-BCMss-Kt.js +2 -0
  16. package/dist/messages-BCMss-Kt.js.map +1 -0
  17. package/dist/messages-BGUrKgyK.js +2 -0
  18. package/dist/messages-BGUrKgyK.js.map +1 -0
  19. package/dist/messages-BjxAnLDp.js +2 -0
  20. package/dist/messages-BjxAnLDp.js.map +1 -0
  21. package/dist/messages-Bjysz3rI.js +2 -0
  22. package/dist/messages-Bjysz3rI.js.map +1 -0
  23. package/dist/messages-BvvEr3UX.js +2 -0
  24. package/dist/messages-BvvEr3UX.js.map +1 -0
  25. package/dist/messages-Bz6JOhJf.js +2 -0
  26. package/dist/messages-Bz6JOhJf.js.map +1 -0
  27. package/dist/messages-BzL3D1EU.js +2 -0
  28. package/dist/messages-BzL3D1EU.js.map +1 -0
  29. package/dist/messages-CAvN5UoW.js +2 -0
  30. package/dist/messages-CAvN5UoW.js.map +1 -0
  31. package/dist/messages-CEmswT1Q.js +2 -0
  32. package/dist/messages-CEmswT1Q.js.map +1 -0
  33. package/dist/messages-CHYqz0q6.js +2 -0
  34. package/dist/messages-CHYqz0q6.js.map +1 -0
  35. package/dist/messages-CRmpdijj.js +2 -0
  36. package/dist/messages-CRmpdijj.js.map +1 -0
  37. package/dist/messages-Cdb79R6S.js +2 -0
  38. package/dist/messages-Cdb79R6S.js.map +1 -0
  39. package/dist/messages-ChkJ_0WT.js +2 -0
  40. package/dist/messages-ChkJ_0WT.js.map +1 -0
  41. package/dist/messages-CqiEX6JJ.js +2 -0
  42. package/dist/messages-CqiEX6JJ.js.map +1 -0
  43. package/dist/messages-CxkHjJSR.js +2 -0
  44. package/dist/messages-CxkHjJSR.js.map +1 -0
  45. package/dist/messages-D0-cWoJ9.js +2 -0
  46. package/dist/messages-D0-cWoJ9.js.map +1 -0
  47. package/dist/messages-D2MnAxYY.js +2 -0
  48. package/dist/messages-D2MnAxYY.js.map +1 -0
  49. package/dist/messages-D5TZVsui.js +2 -0
  50. package/dist/messages-D5TZVsui.js.map +1 -0
  51. package/dist/messages-DBdV4-iw.js +2 -0
  52. package/dist/messages-DBdV4-iw.js.map +1 -0
  53. package/dist/messages-DEK3zybC.js +2 -0
  54. package/dist/messages-DEK3zybC.js.map +1 -0
  55. package/dist/messages-DGSM5jkd.js +2 -0
  56. package/dist/messages-DGSM5jkd.js.map +1 -0
  57. package/dist/messages-DJgAnSTQ.js +2 -0
  58. package/dist/messages-DJgAnSTQ.js.map +1 -0
  59. package/dist/messages-DK7O7sb_.js +2 -0
  60. package/dist/messages-DK7O7sb_.js.map +1 -0
  61. package/dist/messages-DRp7qc3j.js +2 -0
  62. package/dist/messages-DRp7qc3j.js.map +1 -0
  63. package/dist/messages-DT6xRw0m.js +2 -0
  64. package/dist/messages-DT6xRw0m.js.map +1 -0
  65. package/dist/messages-LnzLtU0L.js +2 -0
  66. package/dist/messages-LnzLtU0L.js.map +1 -0
  67. package/dist/messages-_Nk2qNGw.js +2 -0
  68. package/dist/messages-_Nk2qNGw.js.map +1 -0
  69. package/dist/messages-eHH6nZyF.js +2 -0
  70. package/dist/messages-eHH6nZyF.js.map +1 -0
  71. package/dist/messages-iNw8zY2C.js +2 -0
  72. package/dist/messages-iNw8zY2C.js.map +1 -0
  73. package/dist/messages-ipc0L8yF.js +2 -0
  74. package/dist/messages-ipc0L8yF.js.map +1 -0
  75. package/dist/messages-j7LsWm2F.js +2 -0
  76. package/dist/messages-j7LsWm2F.js.map +1 -0
  77. package/dist/messages-mgE_5UEw.js +2 -0
  78. package/dist/messages-mgE_5UEw.js.map +1 -0
  79. package/dist/messages-oRd-J5--.js +2 -0
  80. package/dist/messages-oRd-J5--.js.map +1 -0
  81. package/package.json +10 -8
  82. package/.linguirc +0 -57
  83. package/CHANGELOG.md +0 -17
  84. package/CONTRIBUTING.md +0 -6
  85. package/authorization-page.html +0 -186
  86. package/error-page.html +0 -118
  87. package/index.html +0 -13
  88. package/src/authorization-page.tsx +0 -49
  89. package/src/components/forms/button-toggle-visibility.tsx +0 -43
  90. package/src/components/forms/button.tsx +0 -60
  91. package/src/components/forms/fieldset.tsx +0 -55
  92. package/src/components/forms/form-card-async.tsx +0 -103
  93. package/src/components/forms/form-card.tsx +0 -49
  94. package/src/components/forms/input-checkbox.tsx +0 -78
  95. package/src/components/forms/input-container.tsx +0 -107
  96. package/src/components/forms/input-email-address.tsx +0 -65
  97. package/src/components/forms/input-new-password.tsx +0 -62
  98. package/src/components/forms/input-password.tsx +0 -87
  99. package/src/components/forms/input-text.tsx +0 -82
  100. package/src/components/forms/input-token.tsx +0 -94
  101. package/src/components/forms/wizard-card.tsx +0 -116
  102. package/src/components/layouts/layout-title-page.tsx +0 -78
  103. package/src/components/layouts/layout-welcome.tsx +0 -78
  104. package/src/components/utils/account-identifier.tsx +0 -23
  105. package/src/components/utils/account-image.tsx +0 -33
  106. package/src/components/utils/admonition.tsx +0 -52
  107. package/src/components/utils/client-name.tsx +0 -71
  108. package/src/components/utils/error-card.tsx +0 -93
  109. package/src/components/utils/error-message.tsx +0 -88
  110. package/src/components/utils/help-card.tsx +0 -46
  111. package/src/components/utils/icons.tsx +0 -88
  112. package/src/components/utils/link-anchor.tsx +0 -28
  113. package/src/components/utils/link-title.tsx +0 -26
  114. package/src/components/utils/multi-lang-string.tsx +0 -62
  115. package/src/components/utils/password-strength-label.tsx +0 -37
  116. package/src/components/utils/password-strength-meter.tsx +0 -58
  117. package/src/components/utils/url-viewer.tsx +0 -73
  118. package/src/error-page.tsx +0 -23
  119. package/src/hooks/use-api.ts +0 -202
  120. package/src/hooks/use-async-action.ts +0 -120
  121. package/src/hooks/use-bound-dispatch.ts +0 -5
  122. package/src/hooks/use-browser-color-scheme.ts +0 -31
  123. package/src/hooks/use-random-string.ts +0 -37
  124. package/src/hooks/use-stepper.ts +0 -87
  125. package/src/lib/api.ts +0 -225
  126. package/src/lib/cookies.ts +0 -17
  127. package/src/lib/json-client.ts +0 -141
  128. package/src/lib/password.ts +0 -98
  129. package/src/lib/ref.ts +0 -17
  130. package/src/lib/util.ts +0 -14
  131. package/src/locales/an/messages.po +0 -494
  132. package/src/locales/ast/messages.po +0 -494
  133. package/src/locales/ca/messages.po +0 -494
  134. package/src/locales/da/messages.po +0 -494
  135. package/src/locales/de/messages.po +0 -494
  136. package/src/locales/el/messages.po +0 -494
  137. package/src/locales/en/messages.po +0 -494
  138. package/src/locales/en-GB/messages.po +0 -494
  139. package/src/locales/es/messages.po +0 -494
  140. package/src/locales/eu/messages.po +0 -494
  141. package/src/locales/fi/messages.po +0 -494
  142. package/src/locales/fr/messages.po +0 -494
  143. package/src/locales/ga/messages.po +0 -494
  144. package/src/locales/gl/messages.po +0 -494
  145. package/src/locales/hi/messages.po +0 -494
  146. package/src/locales/hu/messages.po +0 -494
  147. package/src/locales/ia/messages.po +0 -494
  148. package/src/locales/id/messages.po +0 -494
  149. package/src/locales/it/messages.po +0 -494
  150. package/src/locales/ja/messages.po +0 -494
  151. package/src/locales/km/messages.po +0 -494
  152. package/src/locales/ko/messages.po +0 -494
  153. package/src/locales/load.ts +0 -8
  154. package/src/locales/locale-provider.tsx +0 -108
  155. package/src/locales/locale-selector.tsx +0 -57
  156. package/src/locales/locales.ts +0 -183
  157. package/src/locales/ne/messages.po +0 -494
  158. package/src/locales/nl/messages.po +0 -494
  159. package/src/locales/pl/messages.po +0 -494
  160. package/src/locales/pt-BR/messages.po +0 -494
  161. package/src/locales/ro/messages.po +0 -494
  162. package/src/locales/ru/messages.po +0 -494
  163. package/src/locales/sv/messages.po +0 -494
  164. package/src/locales/th/messages.po +0 -494
  165. package/src/locales/tr/messages.po +0 -494
  166. package/src/locales/uk/messages.po +0 -494
  167. package/src/locales/vi/messages.po +0 -494
  168. package/src/locales/zh-CN/messages.po +0 -494
  169. package/src/locales/zh-HK/messages.po +0 -494
  170. package/src/locales/zh-TW/messages.po +0 -494
  171. package/src/style.css +0 -219
  172. package/src/views/authorize/accept/accept-form.tsx +0 -155
  173. package/src/views/authorize/accept/accept-view.tsx +0 -70
  174. package/src/views/authorize/authorize-view.tsx +0 -186
  175. package/src/views/authorize/reset-password/reset-password-confirm-form.tsx +0 -88
  176. package/src/views/authorize/reset-password/reset-password-request-form.tsx +0 -80
  177. package/src/views/authorize/reset-password/reset-password-view.tsx +0 -127
  178. package/src/views/authorize/sign-in/sign-in-form.tsx +0 -240
  179. package/src/views/authorize/sign-in/sign-in-picker.tsx +0 -116
  180. package/src/views/authorize/sign-in/sign-in-view.tsx +0 -145
  181. package/src/views/authorize/sign-up/sign-up-account-form.tsx +0 -142
  182. package/src/views/authorize/sign-up/sign-up-disclaimer.tsx +0 -51
  183. package/src/views/authorize/sign-up/sign-up-handle-form.tsx +0 -287
  184. package/src/views/authorize/sign-up/sign-up-hcaptcha-form.tsx +0 -108
  185. package/src/views/authorize/sign-up/sign-up-view.tsx +0 -158
  186. package/src/views/authorize/welcome/welcome-view.tsx +0 -56
  187. package/src/views/error/error-view.tsx +0 -31
  188. package/tsconfig.json +0 -7
  189. package/tsconfig.src.json +0 -13
  190. package/tsconfig.src.tsbuildinfo +0 -1
  191. package/tsconfig.tools.json +0 -8
  192. package/tsconfig.tools.tsbuildinfo +0 -1
  193. package/vite.config.mjs +0 -47
  194. /package/{src/hydration-data.d.ts → hydration-data.d.ts} +0 -0
@@ -1,78 +0,0 @@
1
- import { clsx } from 'clsx'
2
- import { JSX, ReactNode } from 'react'
3
- import { Override } from '../../lib/util.ts'
4
- import { LocaleSelector } from '../../locales/locale-selector.tsx'
5
-
6
- export type LayoutTitlePageProps = Override<
7
- JSX.IntrinsicElements['div'],
8
- {
9
- title?: string
10
- subtitle?: ReactNode
11
- children?: ReactNode
12
- }
13
- >
14
-
15
- export function LayoutTitlePage({
16
- children,
17
- title,
18
- subtitle,
19
-
20
- // HTMLDivElement
21
- className,
22
- ...props
23
- }: LayoutTitlePageProps) {
24
- return (
25
- <div
26
- {...props}
27
- className={clsx(
28
- className,
29
- 'flex flex-col items-center',
30
- 'md:flex md:flex-row md:items-center md:justify-stretch',
31
- 'min-w-screen min-h-screen',
32
- 'bg-white text-slate-900',
33
- 'dark:bg-slate-900 dark:text-slate-100',
34
- )}
35
- >
36
- {title && <title>{title}</title>}
37
-
38
- <div
39
- className={clsx(
40
- 'px-6 pt-4',
41
- 'w-full',
42
- 'md:max-w-lg',
43
- 'flex flex-row items-start',
44
- 'md:flex-col md:items-end',
45
- 'md:self-stretch',
46
- 'md:max-w-fix md:w-1/2 md:p-4',
47
- 'md:text-right',
48
- 'md:dark:border-r md:dark:border-slate-700',
49
- 'md:bg-slate-100 md:dark:bg-slate-800',
50
- )}
51
- >
52
- <div className="grid grow content-center md:justify-items-end">
53
- {title && (
54
- <h1
55
- key="title"
56
- className="text-primary text-xl font-semibold md:my-4 md:text-2xl lg:text-5xl"
57
- >
58
- {title}
59
- </h1>
60
- )}
61
-
62
- {subtitle && (
63
- <p
64
- key="subtitle"
65
- className="hidden max-w-xs text-slate-600 md:block dark:text-slate-400"
66
- >
67
- {subtitle}
68
- </p>
69
- )}
70
- </div>
71
-
72
- <LocaleSelector key="localeSelector" className="m-1 md:m-2" />
73
- </div>
74
-
75
- <main className="w-full p-6 md:max-w-3xl md:px-12">{children}</main>
76
- </div>
77
- )
78
- }
@@ -1,78 +0,0 @@
1
- import { useLingui } from '@lingui/react/macro'
2
- import { clsx } from 'clsx'
3
- import { JSX } from 'react'
4
- import type { CustomizationData } from '@atproto/oauth-provider-api'
5
- import { Override } from '../../lib/util.ts'
6
- import { LocaleSelector } from '../../locales/locale-selector.tsx'
7
- import { LinkAnchor } from '../utils/link-anchor.tsx'
8
-
9
- export type LayoutWelcomeProps = Override<
10
- JSX.IntrinsicElements['div'],
11
- {
12
- customizationData: CustomizationData | undefined
13
- title?: string
14
- }
15
- >
16
-
17
- export function LayoutWelcome({
18
- customizationData: { logo, name, links } = {},
19
- title = name,
20
-
21
- // div
22
- className,
23
- children,
24
- ...props
25
- }: LayoutWelcomeProps) {
26
- const { t } = useLingui()
27
-
28
- return (
29
- <div
30
- {...props}
31
- className={clsx(
32
- 'min-h-screen w-full',
33
- 'flex flex-col items-center justify-center',
34
- 'bg-white text-slate-900',
35
- 'dark:bg-slate-900 dark:text-slate-100',
36
- className,
37
- )}
38
- >
39
- {title && <title>{title}</title>}
40
-
41
- <main className="flex w-full grow flex-col items-center justify-center overflow-hidden p-6">
42
- {logo && (
43
- <img
44
- src={logo}
45
- alt={name || t`Logo`}
46
- aria-hidden
47
- className="mb-4 h-16 w-16 md:mb-8 md:h-24 md:w-24"
48
- />
49
- )}
50
-
51
- {name && (
52
- <h1 className="mx-4 mb-4 text-center text-2xl font-bold md:mb-8 md:text-4xl">
53
- {name}
54
- </h1>
55
- )}
56
-
57
- {children}
58
- </main>
59
-
60
- <footer className="bg-contrast-25 dark:bg-contrast-50 flex w-full flex-wrap items-center justify-between overflow-hidden px-4 md:px-6">
61
- <nav className="flex flex-wrap items-center justify-start">
62
- {links?.map((link, i) => (
63
- <LinkAnchor
64
- key={i}
65
- link={link}
66
- className="text-text-light m-2 text-xs hover:underline md:m-4 md:text-sm"
67
- />
68
- ))}
69
- </nav>
70
-
71
- <LocaleSelector
72
- className="m-1 text-xs md:m-2 md:text-sm"
73
- key="localeSelector"
74
- />
75
- </footer>
76
- </div>
77
- )
78
- }
@@ -1,23 +0,0 @@
1
- import { JSX } from 'react'
2
- import type { Account } from '@atproto/oauth-provider-api'
3
- import { Override } from '../../lib/util.ts'
4
-
5
- export type AccountIdentifierProps = Override<
6
- Omit<JSX.IntrinsicElements['b'], 'children'>,
7
- {
8
- account: Account
9
- }
10
- >
11
-
12
- export function AccountIdentifier({
13
- account,
14
-
15
- // b
16
- ...props
17
- }: AccountIdentifierProps) {
18
- return (
19
- <b {...props}>
20
- {account.preferred_username || account.email || account.sub}
21
- </b>
22
- )
23
- }
@@ -1,33 +0,0 @@
1
- import { useEffect, useState } from 'react'
2
- import { AccountIcon } from './icons.tsx'
3
-
4
- export type AccountIconProps = {
5
- src?: string
6
- alt: string
7
- }
8
-
9
- export function AccountImage({ src, alt }: AccountIconProps) {
10
- const [errored, setErrored] = useState(false)
11
-
12
- useEffect(() => {
13
- setErrored(false)
14
- }, [src])
15
-
16
- return src && !errored ? (
17
- <img
18
- aria-hidden
19
- crossOrigin="anonymous"
20
- src={src}
21
- alt={alt}
22
- className="-ml-1 h-6 w-6 rounded-full"
23
- onError={() => setErrored(true)}
24
- />
25
- ) : (
26
- <div
27
- aria-hidden
28
- className="bg-primary border-primary h-6 w-6 overflow-hidden rounded-full border-2 border-solid text-white"
29
- >
30
- <AccountIcon className="-mx-1 -mb-1" />
31
- </div>
32
- )
33
- }
@@ -1,52 +0,0 @@
1
- import { clsx } from 'clsx'
2
- import { JSX, memo } from 'react'
3
- import { Override } from '../../lib/util.ts'
4
- import { AlertIcon, EyeIcon } from './icons.tsx'
5
-
6
- export type AdmonitionProps = Override<
7
- JSX.IntrinsicElements['div'],
8
- {
9
- role: 'alert' | 'status' | 'info'
10
- }
11
- >
12
-
13
- export const Admonition = memo(function Admonition({
14
- role = 'alert',
15
- children,
16
- className,
17
- ...props
18
- }: AdmonitionProps) {
19
- return (
20
- <div
21
- {...props}
22
- role={role}
23
- className={clsx(
24
- 'flex flex-row',
25
- 'gap-2',
26
- 'p-3',
27
- 'rounded-lg',
28
- 'border',
29
- 'border-gray-300 dark:border-gray-700',
30
- role === 'alert' && 'bg-error text-error-contrast',
31
- className,
32
- )}
33
- >
34
- {role === 'info' ? (
35
- <EyeIcon
36
- aria-hidden
37
- className={clsx('h-6 w-6 fill-current', 'text-primary')}
38
- />
39
- ) : (
40
- <AlertIcon
41
- aria-hidden
42
- className={clsx(
43
- 'h-6 w-6 fill-current',
44
- role === 'alert' ? 'text-inherit' : 'text-primary',
45
- )}
46
- />
47
- )}
48
-
49
- <div className="flex flex-1 flex-col">{children}</div>
50
- </div>
51
- )
52
- })
@@ -1,71 +0,0 @@
1
- import { Trans } from '@lingui/react/macro'
2
- import { JSX, useMemo } from 'react'
3
- import type { OAuthClientMetadata } from '@atproto/oauth-types'
4
- import { Override } from '../../lib/util.ts'
5
- import { UrlViewer } from './url-viewer.tsx'
6
-
7
- export type ClientNameProps = Override<
8
- Omit<JSX.IntrinsicElements['span'], 'children'>,
9
- {
10
- clientId: string
11
- clientMetadata: OAuthClientMetadata
12
- clientTrusted: boolean
13
- }
14
- >
15
-
16
- export function ClientName({
17
- clientId,
18
- clientMetadata,
19
- clientTrusted,
20
-
21
- // span
22
- ...attrs
23
- }: ClientNameProps) {
24
- const url = useMemo(() => {
25
- try {
26
- return new URL(clientId)
27
- } catch {
28
- return null
29
- }
30
- }, [clientId])
31
-
32
- if (clientTrusted && clientMetadata.client_name) {
33
- return <span {...attrs}>{clientMetadata.client_name}</span>
34
- }
35
-
36
- // @NOTE: not using isOAuthClientIdLoopback & isOAuthClientIdDiscoverable from
37
- // @atproto/oauth-types here because 1) we don't need to validate here and 2)
38
- // we prefer not to import un-necessary code to improve bundle size.
39
-
40
- if (url?.protocol === 'http:') {
41
- return (
42
- <span {...attrs}>
43
- <Trans>An application on your device</Trans>
44
- </span>
45
- )
46
- }
47
-
48
- if (url?.protocol === 'https:') {
49
- // Only display the url details if the client id does not follow our
50
- // convention.
51
- const simplifiedView =
52
- url.protocol === 'https:' &&
53
- url.pathname === '/oauth-client-metadata.json' &&
54
- !url.port &&
55
- !url.search
56
-
57
- return (
58
- <UrlViewer
59
- {...attrs}
60
- url={url}
61
- proto={!simplifiedView}
62
- host={true}
63
- path={!simplifiedView}
64
- query={!simplifiedView}
65
- hash={false}
66
- />
67
- )
68
- }
69
-
70
- return <span {...attrs}>{clientId}</span>
71
- }
@@ -1,93 +0,0 @@
1
- import { Trans } from '@lingui/react/macro'
2
- import { memo, useEffect, useMemo, useState } from 'react'
3
- import { useRandomString } from '../../hooks/use-random-string.ts'
4
- import { Api } from '../../lib/api.ts'
5
- import { JsonErrorResponse } from '../../lib/json-client.ts'
6
- import { Override } from '../../lib/util.ts'
7
- import { Admonition, AdmonitionProps } from './admonition.tsx'
8
- import { ErrorMessage } from './error-message.tsx'
9
-
10
- export type ErrorCardProps = Override<
11
- Omit<AdmonitionProps, 'role'>,
12
- {
13
- error: unknown
14
- }
15
- >
16
- export const ErrorCard = memo(function ErrorCard({
17
- error,
18
-
19
- // Admonition
20
- children,
21
- onClick,
22
- onKeyDown,
23
- ...props
24
- }: ErrorCardProps) {
25
- const [inputCount, setInputCount] = useState(0)
26
- // Every 5th input will toggle showing the details
27
- const showDetails = ((inputCount / 5) | 0) % 2 === 1
28
-
29
- const detailsDivId = useRandomString('error-card-')
30
-
31
- const parsedError = useMemo(
32
- () =>
33
- error instanceof JsonErrorResponse
34
- ? // Already parsed:
35
- error
36
- : // If "error" is a json object, try parsing it as a JsonErrorResponse:
37
- Api.parseError(error) ?? error,
38
- [error],
39
- )
40
-
41
- useEffect(() => {
42
- // For debugging purposes
43
- console.warn('Displayed error details:', parsedError)
44
-
45
- // Reset the input count when the error changes
46
- setInputCount(0)
47
- }, [parsedError])
48
-
49
- return (
50
- <Admonition
51
- role="alert"
52
- aria-controls={detailsDivId}
53
- tabIndex={0}
54
- onKeyDown={(event) => {
55
- onKeyDown?.(event)
56
- if (!event.defaultPrevented) {
57
- setInputCount((c) => c + 1)
58
- }
59
- }}
60
- onClick={(event) => {
61
- onClick?.(event)
62
- if (!event.defaultPrevented) {
63
- setInputCount((c) => c + 1)
64
- }
65
- }}
66
- {...props}
67
- >
68
- <ErrorMessage error={parsedError} />
69
-
70
- {children && <div className="mt-2">{children}</div>}
71
-
72
- <div hidden={!showDetails} id={detailsDivId} aria-hidden={!showDetails}>
73
- {parsedError instanceof JsonErrorResponse ? (
74
- <dl className="mt-2 grid grid-cols-[auto_1fr] gap-x-2 text-sm">
75
- <dt className="font-semibold">
76
- <Trans>Code</Trans>
77
- </dt>
78
- <dd>
79
- <code>{parsedError.error}</code>
80
- </dd>
81
-
82
- <dt className="font-semibold">
83
- <Trans>Description</Trans>
84
- </dt>
85
- <dd>{parsedError.description}</dd>
86
- </dl>
87
- ) : (
88
- <pre className="text-xs">{JSON.stringify(parsedError, null, 2)}</pre>
89
- )}
90
- </div>
91
- </Admonition>
92
- )
93
- })
@@ -1,88 +0,0 @@
1
- import { Trans } from '@lingui/react/macro'
2
- import { ReactNode, memo } from 'react'
3
- import {
4
- AccessDeniedError,
5
- EmailTakenError,
6
- HandleUnavailableError,
7
- InvalidCredentialsError,
8
- InvalidInviteCodeError,
9
- InvalidRequestError,
10
- RequestExpiredError,
11
- SecondAuthenticationFactorRequiredError,
12
- UnknownRequestUriError,
13
- } from '../../lib/api.ts'
14
- import { JsonErrorResponse } from '../../lib/json-client.ts'
15
-
16
- export type ApiErrorMessageProps = {
17
- error: unknown
18
- }
19
-
20
- export const ErrorMessage = memo(function ErrorMessage({
21
- error,
22
- }: ApiErrorMessageProps): ReactNode {
23
- // Matches the order of the error checks in the API's parseError method (must
24
- // be from most specific to least specific to avoid unreachable code paths).
25
-
26
- if (error instanceof SecondAuthenticationFactorRequiredError) {
27
- return <Trans>A second authentication factor is required</Trans>
28
- }
29
-
30
- if (error instanceof InvalidCredentialsError) {
31
- return <Trans>Wrong identifier or password</Trans>
32
- }
33
-
34
- if (error instanceof InvalidInviteCodeError) {
35
- return <Trans>The invite code is not valid</Trans>
36
- }
37
-
38
- if (error instanceof HandleUnavailableError) {
39
- switch (error.reason) {
40
- case 'syntax':
41
- return <Trans>The handle is invalid</Trans>
42
- case 'domain':
43
- return <Trans>The domain name is not allowed</Trans>
44
- case 'slur':
45
- return <Trans>The handle contains inappropriate language</Trans>
46
- case 'taken':
47
- if (error.description === 'Reserved handle') {
48
- return <Trans>This handle is reserved</Trans>
49
- }
50
- return <Trans>The handle is already in use</Trans>
51
- default:
52
- return <Trans>That handle cannot be used</Trans>
53
- }
54
- }
55
-
56
- if (error instanceof EmailTakenError) {
57
- return <Trans>This email is already used</Trans>
58
- }
59
-
60
- if (
61
- error instanceof UnknownRequestUriError ||
62
- error instanceof RequestExpiredError
63
- ) {
64
- return <Trans>This sign-in session has expired</Trans>
65
- }
66
-
67
- if (error instanceof InvalidRequestError) {
68
- return (
69
- <Trans>
70
- The data you submitted is invalid. Please check the form and try again.
71
- </Trans>
72
- )
73
- }
74
-
75
- if (error instanceof AccessDeniedError) {
76
- return (
77
- <Trans>
78
- This authorization request has been denied. Please try again.
79
- </Trans>
80
- )
81
- }
82
-
83
- if (error instanceof JsonErrorResponse) {
84
- return <Trans>Unexpected server response</Trans>
85
- }
86
-
87
- return <Trans>An unknown error occurred</Trans>
88
- })
@@ -1,46 +0,0 @@
1
- import { Trans } from '@lingui/react/macro'
2
- import { clsx } from 'clsx'
3
- import { JSX } from 'react'
4
- import type { LinkDefinition } from '@atproto/oauth-provider-api'
5
- import { Override } from '../../lib/util.ts'
6
-
7
- export type HelpCardProps = Override<
8
- Omit<JSX.IntrinsicElements['p'], 'children'>,
9
- {
10
- links?: readonly LinkDefinition[]
11
- }
12
- >
13
-
14
- export function HelpCard({
15
- links,
16
-
17
- className,
18
- ...props
19
- }: HelpCardProps) {
20
- const helpLink = links?.find((l) => l.rel === 'help')
21
-
22
- if (!helpLink) return null
23
-
24
- return (
25
- <p
26
- {...props}
27
- className={clsx(
28
- 'rounded-md bg-slate-100 p-3 text-sm text-slate-800 dark:bg-slate-800 dark:text-slate-400',
29
- className,
30
- )}
31
- >
32
- <Trans>
33
- Having trouble?{' '}
34
- <a
35
- role="link"
36
- href={helpLink.href}
37
- rel={helpLink.rel}
38
- target="_blank"
39
- className="text-primary"
40
- >
41
- <Trans>Contact support</Trans>
42
- </a>
43
- </Trans>
44
- </p>
45
- )
46
- }
@@ -1,88 +0,0 @@
1
- import type { FunctionComponent, JSX } from 'react'
2
- import { Override } from '../../lib/util.ts'
3
-
4
- export type IconProps = Override<
5
- Omit<JSX.IntrinsicElements['svg'], 'viewBox' | 'children' | 'xmlns'>,
6
- {
7
- /**
8
- * The title of the icon, used for accessibility.
9
- */
10
- title?: string
11
- }
12
- >
13
-
14
- const makeSvgComponent = (path: string, displayName: string) => {
15
- const SvgComponent: FunctionComponent<IconProps> = ({ title, ...props }) => (
16
- <svg
17
- xmlns="http://www.w3.org/2000/svg"
18
- viewBox="0 0 24 24"
19
- {...props}
20
- aria-hidden={!title}
21
- >
22
- {title && <title>{title}</title>}
23
- <path
24
- fill="currentColor"
25
- fillRule="evenodd"
26
- clipRule="evenodd"
27
- d={path}
28
- ></path>
29
- </svg>
30
- )
31
- SvgComponent.displayName = displayName
32
- return SvgComponent
33
- }
34
-
35
- export const AccountIcon = makeSvgComponent(
36
- 'M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z',
37
- 'AccountIcon',
38
- )
39
-
40
- export const AlertIcon = makeSvgComponent(
41
- 'M11.14 4.494a.995.995 0 0 1 1.72 0l7.001 12.008a.996.996 0 0 1-.86 1.498H4.999a.996.996 0 0 1-.86-1.498L11.14 4.494Zm3.447-1.007c-1.155-1.983-4.019-1.983-5.174 0L2.41 15.494C1.247 17.491 2.686 20 4.998 20h14.004c2.312 0 3.751-2.509 2.587-4.506L14.587 3.487ZM13 9.019a1 1 0 1 0-2 0v2.994a1 1 0 1 0 2 0V9.02Zm-1 4.731a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5Z',
42
- 'AlertIcon',
43
- )
44
-
45
- export const AtSymbolIcon = makeSvgComponent(
46
- 'M12 4a8 8 0 1 0 4.21 14.804 1 1 0 0 1 1.054 1.7A9.958 9.958 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 1.104-.27 2.31-.949 3.243-.716.984-1.849 1.6-3.331 1.465a4.207 4.207 0 0 1-2.93-1.585c-.94 1.21-2.388 1.94-3.985 1.715-2.53-.356-4.04-2.91-3.682-5.458.358-2.547 2.514-4.586 5.044-4.23.905.127 1.68.536 2.286 1.126a1 1 0 0 1 1.964.368l-.515 3.545v.002a2.222 2.222 0 0 0 1.999 2.526c.75.068 1.212-.21 1.533-.65.358-.493.566-1.245.566-2.067a8 8 0 0 0-8-8Zm-.112 5.13c-1.195-.168-2.544.819-2.784 2.529-.24 1.71.784 3.03 1.98 3.198 1.195.168 2.543-.819 2.784-2.529.24-1.71-.784-3.03-1.98-3.198Z',
47
- 'AtSymbolIcon',
48
- )
49
-
50
- export const CaretRightIcon = makeSvgComponent(
51
- 'M8.293 3.293a1 1 0 0 1 1.414 0l8 8a1 1 0 0 1 0 1.414l-8 8a1 1 0 0 1-1.414-1.414L15.586 12 8.293 4.707a1 1 0 0 1 0-1.414Z',
52
- 'CaretRightIcon',
53
- )
54
-
55
- export const CheckMarkIcon = makeSvgComponent(
56
- 'M21.59 3.193a1 1 0 0 1 .217 1.397l-11.706 16a1 1 0 0 1-1.429.193l-6.294-5a1 1 0 1 1 1.244-1.566l5.48 4.353 11.09-15.16a1 1 0 0 1 1.398-.217Z',
57
- 'CheckMarkIcon',
58
- )
59
-
60
- export const EmailIcon = makeSvgComponent(
61
- 'M4.568 4h14.864c.252 0 .498 0 .706.017.229.019.499.063.77.201a2 2 0 0 1 .874.874c.138.271.182.541.201.77.017.208.017.454.017.706v10.864c0 .252 0 .498-.017.706a2.022 2.022 0 0 1-.201.77 2 2 0 0 1-.874.874 2.022 2.022 0 0 1-.77.201c-.208.017-.454.017-.706.017H4.568c-.252 0-.498 0-.706-.017a2.022 2.022 0 0 1-.77-.201 2 2 0 0 1-.874-.874 2.022 2.022 0 0 1-.201-.77C2 17.93 2 17.684 2 17.432V6.568c0-.252 0-.498.017-.706.019-.229.063-.499.201-.77a2 2 0 0 1 .874-.874c.271-.138.541-.182.77-.201C4.07 4 4.316 4 4.568 4Zm.456 2L12 11.708 18.976 6H5.024ZM20 7.747l-6.733 5.509a2 2 0 0 1-2.534 0L4 7.746V17.4a8.187 8.187 0 0 0 .011.589h.014c.116.01.278.011.575.011h14.8a8.207 8.207 0 0 0 .589-.012v-.013c.01-.116.011-.279.011-.575V7.747Z',
62
- 'EmailIcon',
63
- )
64
-
65
- export const EyeIcon = makeSvgComponent(
66
- 'M12 6.5c3.79 0 7.17 2.13 8.82 5.5-1.65 3.37-5.02 5.5-8.82 5.5S4.83 15.37 3.18 12C4.83 8.63 8.21 6.5 12 6.5m0-2C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5m0 5c1.38 0 2.5 1.12 2.5 2.5s-1.12 2.5-2.5 2.5-2.5-1.12-2.5-2.5 1.12-2.5 2.5-2.5m0-2c-2.48 0-4.5 2.02-4.5 4.5s2.02 4.5 4.5 4.5 4.5-2.02 4.5-4.5-2.02-4.5-4.5-4.5',
67
- 'EyeIcon',
68
- )
69
-
70
- export const EyeSlashIcon = makeSvgComponent(
71
- 'M12 6c3.79 0 7.17 2.13 8.82 5.5-.59 1.22-1.42 2.27-2.41 3.12l1.41 1.41c1.39-1.23 2.49-2.77 3.18-4.53C21.27 7.11 17 4 12 4c-1.27 0-2.49.2-3.64.57l1.65 1.65C10.66 6.09 11.32 6 12 6m-1.07 1.14L13 9.21c.57.25 1.03.71 1.28 1.28l2.07 2.07c.08-.34.14-.7.14-1.07C16.5 9.01 14.48 7 12 7c-.37 0-.72.05-1.07.14M2.01 3.87l2.68 2.68C3.06 7.83 1.77 9.53 1 11.5 2.73 15.89 7 19 12 19c1.52 0 2.98-.29 4.32-.82l3.42 3.42 1.41-1.41L3.42 2.45zm7.5 7.5 2.61 2.61c-.04.01-.08.02-.12.02-1.38 0-2.5-1.12-2.5-2.5 0-.05.01-.08.01-.13m-3.4-3.4 1.75 1.75c-.23.55-.36 1.15-.36 1.78 0 2.48 2.02 4.5 4.5 4.5.63 0 1.23-.13 1.77-.36l.98.98c-.88.24-1.8.38-2.75.38-3.79 0-7.17-2.13-8.82-5.5.7-1.43 1.72-2.61 2.93-3.53',
72
- 'EyeSlashIcon',
73
- )
74
-
75
- export const LockIcon = makeSvgComponent(
76
- 'M7 7a5 5 0 0 1 10 0v2h1a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2h1V7Zm-1 4v9h12v-9H6Zm9-2H9V7a3 3 0 1 1 6 0v2Zm-3 4a1 1 0 0 1 1 1v3a1 1 0 1 1-2 0v-3a1 1 0 0 1 1-1Z',
77
- 'LockIcon',
78
- )
79
-
80
- export const TokenIcon = makeSvgComponent(
81
- 'M4 5.5a.5.5 0 0 0-.5.5v2.535a.5.5 0 0 0 .25.433A3.498 3.498 0 0 1 5.5 12a3.498 3.498 0 0 1-1.75 3.032.5.5 0 0 0-.25.433V18a.5.5 0 0 0 .5.5h16a.5.5 0 0 0 .5-.5v-2.535a.5.5 0 0 0-.25-.433A3.498 3.498 0 0 1 18.5 12a3.5 3.5 0 0 1 1.75-3.032.5.5 0 0 0 .25-.433V6a.5.5 0 0 0-.5-.5H4ZM2.5 6A1.5 1.5 0 0 1 4 4.5h16A1.5 1.5 0 0 1 21.5 6v3.17a.5.5 0 0 1-.333.472 2.501 2.501 0 0 0 0 4.716.5.5 0 0 1 .333.471V18a1.5 1.5 0 0 1-1.5 1.5H4A1.5 1.5 0 0 1 2.5 18v-3.17a.5.5 0 0 1 .333-.472 2.501 2.501 0 0 0 0-4.716.5.5 0 0 1-.333-.471V6Zm12 2a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Zm0 4a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Zm0 4a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Z',
82
- 'TokenIcon',
83
- )
84
-
85
- export const XMarkIcon = makeSvgComponent(
86
- 'M4.293 4.293a1 1 0 0 1 1.414 0L12 10.586l6.293-6.293a1 1 0 1 1 1.414 1.414L13.414 12l6.293 6.293a1 1 0 0 1-1.414 1.414L12 13.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L10.586 12 4.293 5.707a1 1 0 0 1 0-1.414Z',
87
- 'XMarkIcon',
88
- )
@@ -1,28 +0,0 @@
1
- import { JSX } from 'react'
2
- import type { LinkDefinition } from '@atproto/oauth-provider-api'
3
- import { Override } from '../../lib/util.ts'
4
- import { LinkTitle } from './link-title.tsx'
5
-
6
- export type LinkAnchorProps = Override<
7
- JSX.IntrinsicElements['a'],
8
- {
9
- link: LinkDefinition
10
- }
11
- >
12
- export function LinkAnchor({
13
- link,
14
-
15
- // a
16
- children = <LinkTitle link={link} />,
17
- role = 'link',
18
- target = '_blank',
19
- href = link.href,
20
- rel = link.rel,
21
- ...props
22
- }: LinkAnchorProps) {
23
- return (
24
- <a {...props} role={role} target={target} href={href} rel={rel}>
25
- {children}
26
- </a>
27
- )
28
- }