@meith/web 0.35.0 → 0.36.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/app/(board)/member/[id]/reputation/page.tsx +2 -4
- package/app/(board)/plugins/[key]/[[...path]]/page.tsx +2 -1
- package/app/(board)/search/page.tsx +2 -1
- package/app/(board)/unsubscribe/page.tsx +2 -2
- package/app/admin/layout.tsx +9 -1
- package/app/admin/plugins/[key]/[[...path]]/page.tsx +1 -3
- package/app/auth/passkey/verify/route.ts +1 -2
- package/app/install/page.tsx +2 -4
- package/app/layout.tsx +2 -0
- package/package.json +50 -50
- package/src/components/account/active-sessions.tsx +2 -2
- package/src/components/account/avatar-form.tsx +3 -2
- package/src/components/account/feed-token.tsx +5 -5
- package/src/components/account/notification-forms.tsx +4 -6
- package/src/components/account/push-device-form.tsx +3 -2
- package/src/components/account/reputation-forms.tsx +5 -4
- package/src/components/account/sign-in-methods.tsx +2 -2
- package/src/components/account/subscription-forms.tsx +6 -8
- package/src/components/account/two-factor-forms.tsx +3 -4
- package/src/components/account/usercp-forms.tsx +48 -59
- package/src/components/admin/admin-forms.tsx +27 -18
- package/src/components/admin/form-bits.tsx +2 -3
- package/src/components/admin/mail-test-card.tsx +3 -1
- package/src/components/admin/theme-forms.tsx +4 -5
- package/src/components/auth/form-controls.tsx +22 -11
- package/src/components/content/edit-post-form.tsx +3 -2
- package/src/components/content/new-thread-form.tsx +4 -4
- package/src/components/messages/message-forms.tsx +9 -10
- package/src/components/moderation/inline-moderation-form.tsx +3 -2
- package/src/components/moderation/queue-form.tsx +3 -3
- package/src/components/moderation/report-forms.tsx +3 -3
- package/src/components/moderation/thread-surgery-form.tsx +4 -4
- package/src/components/moderation/thread-tools-form.tsx +4 -4
- package/src/components/moderation/warning-forms.tsx +8 -8
- package/src/components/shell/install-action.tsx +3 -2
- package/src/components/shell/nav-disclosure-enhancer.tsx +3 -0
- package/src/components/shell/scheme-toggle.tsx +1 -1
- package/src/components/shell/theme-switcher.tsx +9 -8
- package/src/components/shell/view-tabs.tsx +1 -65
- package/src/server/admin-actions.ts +30 -21
- package/src/server/auth-actions.ts +11 -4
- package/src/server/federation.ts +3 -1
- package/src/server/upgrade-notice.ts +1 -1
- package/src/styles/globals.css +63 -0
- package/src/view/copy.ts +2 -0
- package/src/view/panel-nav.ts +8 -10
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Metadata } from 'next'
|
|
2
2
|
import { notFound } from 'next/navigation'
|
|
3
3
|
|
|
4
|
-
import { TextLink } from '@meith/ui'
|
|
4
|
+
import { PageTitle, TextLink } from '@meith/ui'
|
|
5
5
|
|
|
6
6
|
import { RateMemberForm, WithdrawRatingForm } from '@/components/account/reputation-forms'
|
|
7
7
|
import { BoardNotice } from '@/components/shell/board-notice'
|
|
@@ -92,9 +92,7 @@ export default async function ReputationPage({
|
|
|
92
92
|
)}
|
|
93
93
|
|
|
94
94
|
<div className="flex flex-col gap-1">
|
|
95
|
-
<
|
|
96
|
-
{profile.username}’s reputation
|
|
97
|
-
</h1>
|
|
95
|
+
<PageTitle>{profile.username}’s reputation</PageTitle>
|
|
98
96
|
<p className="text-sm text-muted-foreground">
|
|
99
97
|
{reputationLabel(view.summary, translator)}
|
|
100
98
|
</p>
|
|
@@ -2,6 +2,7 @@ import type { Metadata } from 'next'
|
|
|
2
2
|
import { notFound, redirect } from 'next/navigation'
|
|
3
3
|
|
|
4
4
|
import { pluginPagePath } from '@meith/plugin-kit'
|
|
5
|
+
import { PageTitle } from '@meith/ui'
|
|
5
6
|
|
|
6
7
|
import { boardUrl } from '@/server/board-url'
|
|
7
8
|
import { getActor } from '@/server/context'
|
|
@@ -59,7 +60,7 @@ export default async function PluginBoardPage({
|
|
|
59
60
|
tabIndex={-1}
|
|
60
61
|
className="mx-auto flex w-full max-w-4xl flex-col gap-6 px-6 py-8 flex-1"
|
|
61
62
|
>
|
|
62
|
-
<
|
|
63
|
+
<PageTitle>{result.title}</PageTitle>
|
|
63
64
|
{result.node === null ? (
|
|
64
65
|
<p className="rounded-lg border border-border p-4 text-sm text-muted-foreground">
|
|
65
66
|
{(await getTranslator()).t('board.plugin.failed')}
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
type SearchFormModel,
|
|
23
23
|
slotCopy,
|
|
24
24
|
} from '@meith/theme-kit'
|
|
25
|
+
import { PageTitle } from '@meith/ui'
|
|
25
26
|
|
|
26
27
|
import { SearchOffNotice } from '@/components/board/search-off-notice'
|
|
27
28
|
import { getContainer } from '@/server/container'
|
|
@@ -126,7 +127,7 @@ async function Page({ children }: { children: React.ReactNode }) {
|
|
|
126
127
|
tabIndex={-1}
|
|
127
128
|
className="mx-auto flex w-full max-w-3xl flex-col gap-6 px-6 py-8 flex-1"
|
|
128
129
|
>
|
|
129
|
-
<
|
|
130
|
+
<PageTitle>{translator.t('board.search.title')}</PageTitle>
|
|
130
131
|
{children}
|
|
131
132
|
</main>
|
|
132
133
|
)
|
|
@@ -2,7 +2,7 @@ import type { Metadata } from 'next'
|
|
|
2
2
|
|
|
3
3
|
import { env } from '@meith/core'
|
|
4
4
|
import { readUnsubscribeToken } from '@meith/subscriptions'
|
|
5
|
-
import { TextLink } from '@meith/ui'
|
|
5
|
+
import { PageTitle, TextLink } from '@meith/ui'
|
|
6
6
|
|
|
7
7
|
import { UnsubscribeConfirmForm } from '@/components/account/subscription-forms'
|
|
8
8
|
import { BoardNotice } from '@/components/shell/board-notice'
|
|
@@ -30,7 +30,7 @@ export default async function UnsubscribePage({
|
|
|
30
30
|
return (
|
|
31
31
|
<main id="board-content" tabIndex={-1} className="flex-1">
|
|
32
32
|
<div className="mx-auto flex w-full max-w-xl flex-col gap-6 px-6 py-10">
|
|
33
|
-
<
|
|
33
|
+
<PageTitle>{translator.t('page.unsubscribe')}</PageTitle>
|
|
34
34
|
|
|
35
35
|
{done !== null ? (
|
|
36
36
|
<>
|
package/app/admin/layout.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import type { Metadata } from 'next'
|
|
|
2
2
|
import { notFound } from 'next/navigation'
|
|
3
3
|
|
|
4
4
|
import { ADMIN_IDLE_MINUTES } from '@meith/admin'
|
|
5
|
+
import { NavigationDrawerTrigger } from '@meith/ui'
|
|
5
6
|
|
|
6
7
|
import {
|
|
7
8
|
AdminSecondFactorForm,
|
|
@@ -9,6 +10,7 @@ import {
|
|
|
9
10
|
AdminSignOutForm,
|
|
10
11
|
} from '@/components/admin/admin-forms'
|
|
11
12
|
import { AdminNav } from '@/components/admin/admin-nav'
|
|
13
|
+
import { NavDisclosureEnhancer } from '@/components/shell/nav-disclosure-enhancer'
|
|
12
14
|
import { PanelShell } from '@/components/shell/panel-shell'
|
|
13
15
|
import { askForPassword, pendingAdminSecondFactor, resolveAdmin } from '@/server/admin'
|
|
14
16
|
import { getActor } from '@/server/context'
|
|
@@ -66,6 +68,7 @@ export default async function AdminLayout({ children }: { children: React.ReactN
|
|
|
66
68
|
|
|
67
69
|
return (
|
|
68
70
|
<div className="min-h-screen bg-background text-foreground">
|
|
71
|
+
<NavDisclosureEnhancer />
|
|
69
72
|
<a
|
|
70
73
|
href="#board-content"
|
|
71
74
|
className="sr-only focus-visible:not-sr-only focus-visible:absolute focus-visible:top-4 focus-visible:left-4 focus-visible:z-50 focus-visible:inline-flex focus-visible:h-9 focus-visible:items-center focus-visible:rounded-md focus-visible:border focus-visible:border-border focus-visible:bg-card focus-visible:px-3 focus-visible:text-sm focus-visible:font-medium focus-visible:text-foreground focus-visible:shadow-lg"
|
|
@@ -74,7 +77,7 @@ export default async function AdminLayout({ children }: { children: React.ReactN
|
|
|
74
77
|
</a>
|
|
75
78
|
|
|
76
79
|
<header className="sticky top-0 z-30 border-b border-border bg-card/95 backdrop-blur supports-[backdrop-filter]:bg-card/85">
|
|
77
|
-
<div className="mx-auto flex h-14 w-full max-w-
|
|
80
|
+
<div className="mx-auto flex h-14 w-full max-w-7xl items-center gap-x-3 px-4 sm:gap-x-4 sm:px-6">
|
|
78
81
|
<a
|
|
79
82
|
href="/admin"
|
|
80
83
|
className="flex min-w-0 items-center gap-2.5 font-heading text-base font-semibold whitespace-nowrap text-foreground sm:text-lg"
|
|
@@ -100,6 +103,11 @@ export default async function AdminLayout({ children }: { children: React.ReactN
|
|
|
100
103
|
</a>
|
|
101
104
|
<div className="ml-auto flex shrink-0 items-center gap-3 text-sm whitespace-nowrap sm:gap-4">
|
|
102
105
|
<AdminSignOutForm copy={adminFormsCopy(t)} />
|
|
106
|
+
<NavigationDrawerTrigger
|
|
107
|
+
target="panel-admincp-navigation"
|
|
108
|
+
label={t.t('default.panelNav.open')}
|
|
109
|
+
className="lg:hidden"
|
|
110
|
+
/>
|
|
103
111
|
</div>
|
|
104
112
|
</div>
|
|
105
113
|
</header>
|
|
@@ -72,9 +72,7 @@ export default async function AdminPluginPage({
|
|
|
72
72
|
{rendered.node === null ? (
|
|
73
73
|
<p className={PANEL_NOTE}>{t.t('adminPluginDetail.pluginPageError')}</p>
|
|
74
74
|
) : (
|
|
75
|
-
<section className="
|
|
76
|
-
{rendered.node}
|
|
77
|
-
</section>
|
|
75
|
+
<section className="min-w-0">{rendered.node}</section>
|
|
78
76
|
)}
|
|
79
77
|
</PanelPage>
|
|
80
78
|
)
|
|
@@ -213,7 +213,7 @@ export async function POST(request: NextRequest): Promise<Response> {
|
|
|
213
213
|
return problem(await tr('authRoute.passkey.signInExpired'), 403)
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
await identity.
|
|
216
|
+
await identity.spendSecondFactorAttempt(pending.userId)
|
|
217
217
|
|
|
218
218
|
const proved = await service.proveOwnership({
|
|
219
219
|
userId: pending.userId,
|
|
@@ -224,7 +224,6 @@ export async function POST(request: NextRequest): Promise<Response> {
|
|
|
224
224
|
})
|
|
225
225
|
|
|
226
226
|
if (!proved) {
|
|
227
|
-
await identity.recordSecondFactorFailure(pending.userId)
|
|
228
227
|
await recordAuthEvent({ userId: pending.userId, kind: 'second_factor_failed' })
|
|
229
228
|
return problem(await tr('authRoute.passkey.notForAccount'), 403)
|
|
230
229
|
}
|
package/app/install/page.tsx
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
warnings,
|
|
14
14
|
} from '@meith/install'
|
|
15
15
|
import { isUsableOrigin, MAIL_PRESETS, normaliseOrigin } from '@meith/settings'
|
|
16
|
-
import { Alert, AlertDescription, AlertTitle, Disclosure } from '@meith/ui'
|
|
16
|
+
import { Alert, AlertDescription, AlertTitle, Disclosure, PageTitle } from '@meith/ui'
|
|
17
17
|
|
|
18
18
|
import { InstallForm } from '@/components/install/install-form'
|
|
19
19
|
import { InstallRestoreForm } from '@/components/install/restore-form'
|
|
@@ -88,9 +88,7 @@ export default async function InstallPage() {
|
|
|
88
88
|
return (
|
|
89
89
|
<main className="mx-auto flex w-full max-w-2xl flex-col gap-8 px-6 py-12">
|
|
90
90
|
<header className="flex flex-col gap-2">
|
|
91
|
-
<
|
|
92
|
-
{t.t('page.install-this-board')}
|
|
93
|
-
</h1>
|
|
91
|
+
<PageTitle>{t.t('page.install-this-board')}</PageTitle>
|
|
94
92
|
<p className="text-sm text-muted-foreground">{t.t('page.this-page-works-once-when')}</p>
|
|
95
93
|
</header>
|
|
96
94
|
|
package/app/layout.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import { env } from '@meith/core'
|
|
|
5
5
|
import { currentRequestId } from '@meith/core/logger'
|
|
6
6
|
import { localeDirection, SOURCE_LOCALE } from '@meith/i18n'
|
|
7
7
|
import { resolveBoardUrl } from '@meith/settings'
|
|
8
|
+
import { NavTabsEnhancer } from '@meith/ui/nav-tabs-enhancer'
|
|
8
9
|
|
|
9
10
|
import { CopyProvider } from '@/components/shell/copy'
|
|
10
11
|
import { CrashNoticeProvider } from '@/components/shell/crash-notice'
|
|
@@ -108,6 +109,7 @@ export default async function RootLayout({
|
|
|
108
109
|
<ServiceWorkerRegistrar />
|
|
109
110
|
</head>
|
|
110
111
|
<body className="font-sans antialiased">
|
|
112
|
+
<NavTabsEnhancer />
|
|
111
113
|
<DemoBanner />
|
|
112
114
|
<CrashNoticeProvider
|
|
113
115
|
notice={notice}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meith/web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"description": "The board itself: the Next.js app, and the forum-web bin that materializes it into an external board workspace.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -43,55 +43,55 @@
|
|
|
43
43
|
"react-dom": "19.2.8",
|
|
44
44
|
"tailwindcss": "^4.3.3",
|
|
45
45
|
"typescript": "7.0.2",
|
|
46
|
-
"@meith/accounts": "0.
|
|
47
|
-
"@meith/admin": "0.
|
|
48
|
-
"@meith/antispam": "0.
|
|
49
|
-
"@meith/api": "0.
|
|
50
|
-
"@meith/attachments": "0.
|
|
51
|
-
"@meith/authorization": "0.
|
|
52
|
-
"@meith/avatars": "0.
|
|
53
|
-
"@meith/backup": "0.
|
|
54
|
-
"@meith/board-digest": "0.
|
|
55
|
-
"@meith/core": "0.
|
|
56
|
-
"@meith/db": "0.
|
|
57
|
-
"@meith/demo": "0.
|
|
58
|
-
"@meith/drafts": "0.
|
|
59
|
-
"@meith/drivers": "0.
|
|
60
|
-
"@meith/events": "0.
|
|
61
|
-
"@meith/forums": "0.
|
|
62
|
-
"@meith/groups": "0.
|
|
63
|
-
"@meith/i18n": "0.
|
|
64
|
-
"@meith/import": "0.
|
|
65
|
-
"@meith/install": "0.
|
|
66
|
-
"@meith/mail": "0.
|
|
67
|
-
"@meith/markdown": "0.
|
|
68
|
-
"@meith/marketplace": "0.
|
|
69
|
-
"@meith/messages": "0.
|
|
70
|
-
"@meith/moderation": "0.
|
|
71
|
-
"@meith/notifications": "0.
|
|
72
|
-
"@meith/plugin-calendar": "0.
|
|
73
|
-
"@meith/plugin-dues": "0.
|
|
74
|
-
"@meith/plugin-kit": "0.
|
|
75
|
-
"@meith/polls": "0.
|
|
76
|
-
"@meith/posts": "0.
|
|
77
|
-
"@meith/profile-fields": "0.
|
|
78
|
-
"@meith/relations": "0.
|
|
79
|
-
"@meith/reputation": "0.
|
|
80
|
-
"@meith/runtime": "0.
|
|
81
|
-
"@meith/search": "0.
|
|
82
|
-
"@meith/settings": "0.
|
|
83
|
-
"@meith/signatures": "0.
|
|
84
|
-
"@meith/subscriptions": "0.
|
|
85
|
-
"@meith/tasks": "0.
|
|
86
|
-
"@meith/theme-clubhouse": "0.
|
|
87
|
-
"@meith/theme-default": "0.
|
|
88
|
-
"@meith/theme-kit": "0.
|
|
89
|
-
"@meith/theme-midnight": "0.
|
|
90
|
-
"@meith/theme-phasebook": "0.
|
|
91
|
-
"@meith/theme-raidframe": "0.
|
|
92
|
-
"@meith/threads": "0.
|
|
93
|
-
"@meith/ui": "0.
|
|
94
|
-
"@meith/upgrade": "0.
|
|
46
|
+
"@meith/accounts": "0.36.0",
|
|
47
|
+
"@meith/admin": "0.36.0",
|
|
48
|
+
"@meith/antispam": "0.36.0",
|
|
49
|
+
"@meith/api": "0.36.0",
|
|
50
|
+
"@meith/attachments": "0.36.0",
|
|
51
|
+
"@meith/authorization": "0.36.0",
|
|
52
|
+
"@meith/avatars": "0.36.0",
|
|
53
|
+
"@meith/backup": "0.36.0",
|
|
54
|
+
"@meith/board-digest": "0.36.0",
|
|
55
|
+
"@meith/core": "0.36.0",
|
|
56
|
+
"@meith/db": "0.36.0",
|
|
57
|
+
"@meith/demo": "0.36.0",
|
|
58
|
+
"@meith/drafts": "0.36.0",
|
|
59
|
+
"@meith/drivers": "0.36.0",
|
|
60
|
+
"@meith/events": "0.36.0",
|
|
61
|
+
"@meith/forums": "0.36.0",
|
|
62
|
+
"@meith/groups": "0.36.0",
|
|
63
|
+
"@meith/i18n": "0.36.0",
|
|
64
|
+
"@meith/import": "0.36.0",
|
|
65
|
+
"@meith/install": "0.36.0",
|
|
66
|
+
"@meith/mail": "0.36.0",
|
|
67
|
+
"@meith/markdown": "0.36.0",
|
|
68
|
+
"@meith/marketplace": "0.36.0",
|
|
69
|
+
"@meith/messages": "0.36.0",
|
|
70
|
+
"@meith/moderation": "0.36.0",
|
|
71
|
+
"@meith/notifications": "0.36.0",
|
|
72
|
+
"@meith/plugin-calendar": "0.36.0",
|
|
73
|
+
"@meith/plugin-dues": "0.36.0",
|
|
74
|
+
"@meith/plugin-kit": "0.36.0",
|
|
75
|
+
"@meith/polls": "0.36.0",
|
|
76
|
+
"@meith/posts": "0.36.0",
|
|
77
|
+
"@meith/profile-fields": "0.36.0",
|
|
78
|
+
"@meith/relations": "0.36.0",
|
|
79
|
+
"@meith/reputation": "0.36.0",
|
|
80
|
+
"@meith/runtime": "0.36.0",
|
|
81
|
+
"@meith/search": "0.36.0",
|
|
82
|
+
"@meith/settings": "0.36.0",
|
|
83
|
+
"@meith/signatures": "0.36.0",
|
|
84
|
+
"@meith/subscriptions": "0.36.0",
|
|
85
|
+
"@meith/tasks": "0.36.0",
|
|
86
|
+
"@meith/theme-clubhouse": "0.36.0",
|
|
87
|
+
"@meith/theme-default": "0.36.0",
|
|
88
|
+
"@meith/theme-kit": "0.36.0",
|
|
89
|
+
"@meith/theme-midnight": "0.36.0",
|
|
90
|
+
"@meith/theme-phasebook": "0.36.0",
|
|
91
|
+
"@meith/theme-raidframe": "0.36.0",
|
|
92
|
+
"@meith/threads": "0.36.0",
|
|
93
|
+
"@meith/ui": "0.36.0",
|
|
94
|
+
"@meith/upgrade": "0.36.0"
|
|
95
95
|
},
|
|
96
96
|
"scripts": {
|
|
97
97
|
"dev": "next dev",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useActionState } from 'react'
|
|
4
4
|
|
|
5
|
-
import { buttonVariants } from '@meith/ui'
|
|
5
|
+
import { buttonVariants, surfaceVariants } from '@meith/ui'
|
|
6
6
|
|
|
7
7
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
8
8
|
import { revokeOtherSessionsAction, revokeSessionAction } from '@/server/session-actions'
|
|
@@ -10,7 +10,7 @@ import { revokeOtherSessionsAction, revokeSessionAction } from '@/server/session
|
|
|
10
10
|
import { FormError, PendingButton } from '../auth/form-controls'
|
|
11
11
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
12
12
|
|
|
13
|
-
const CARD =
|
|
13
|
+
const CARD = surfaceVariants({ padded: true })
|
|
14
14
|
|
|
15
15
|
const ROW =
|
|
16
16
|
'flex flex-wrap items-center justify-between gap-3 rounded-md border border-border px-3 py-2'
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { useActionState } from 'react'
|
|
4
4
|
|
|
5
5
|
import { AVATAR_BOX } from '@meith/avatars/limits'
|
|
6
|
+
import { surfaceVariants } from '@meith/ui'
|
|
6
7
|
|
|
7
8
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
8
9
|
import { removeAvatarAction, saveAvatarAction } from '@/server/usercp-actions'
|
|
@@ -10,7 +11,7 @@ import { removeAvatarAction, saveAvatarAction } from '@/server/usercp-actions'
|
|
|
10
11
|
import { FormError, SubmitButton } from '../auth/form-controls'
|
|
11
12
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
12
13
|
|
|
13
|
-
const CARD =
|
|
14
|
+
const CARD = surfaceVariants({ padded: true })
|
|
14
15
|
|
|
15
16
|
export function AvatarForm({
|
|
16
17
|
currentUrl,
|
|
@@ -86,7 +87,7 @@ export function AvatarForm({
|
|
|
86
87
|
|
|
87
88
|
<form action={save} className={CARD} noValidate>
|
|
88
89
|
<FormError message={saveState.error} />
|
|
89
|
-
<label className="flex flex-col gap-
|
|
90
|
+
<label className="flex min-w-0 flex-col gap-2 text-sm">
|
|
90
91
|
<span className="font-medium">{fromCopy(copy, 'accountForm.avatar.choose')}</span>
|
|
91
92
|
<input
|
|
92
93
|
type="file"
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
import { useActionState } from 'react'
|
|
4
4
|
|
|
5
|
+
import { buttonVariants, surfaceVariants } from '@meith/ui'
|
|
6
|
+
|
|
5
7
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
6
8
|
import { regenerateFeedTokenAction, revokeFeedTokenAction } from '@/server/feed-token-actions'
|
|
7
9
|
|
|
8
10
|
import { FormError, PendingButton } from '../auth/form-controls'
|
|
9
11
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
10
12
|
|
|
11
|
-
const CARD =
|
|
13
|
+
const CARD = surfaceVariants({ padded: true })
|
|
12
14
|
|
|
13
|
-
const BUTTON =
|
|
14
|
-
'inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
15
|
+
const BUTTON = buttonVariants({ variant: 'primary', size: 'default' })
|
|
15
16
|
|
|
16
|
-
const GHOST_BUTTON =
|
|
17
|
-
'inline-flex h-9 items-center justify-center rounded-md border border-border bg-background px-4 text-sm font-medium transition-opacity hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
17
|
+
const GHOST_BUTTON = buttonVariants({ variant: 'outline', size: 'default' })
|
|
18
18
|
|
|
19
19
|
const REVEAL_CODE = 'block overflow-x-auto rounded-sm bg-card px-2 py-1 font-mono text-xs'
|
|
20
20
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useActionState } from 'react'
|
|
4
4
|
|
|
5
|
-
import { textLinkVariants } from '@meith/ui'
|
|
5
|
+
import { buttonVariants, controlVariants, textLinkVariants } from '@meith/ui'
|
|
6
6
|
|
|
7
7
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
8
8
|
import {
|
|
@@ -16,8 +16,7 @@ import { saveBoardDigestCadenceAction } from '@/server/usercp-actions'
|
|
|
16
16
|
import { FormError, PendingButton } from '../auth/form-controls'
|
|
17
17
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
18
18
|
|
|
19
|
-
const BUTTON =
|
|
20
|
-
'inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
19
|
+
const BUTTON = buttonVariants({ variant: 'primary', size: 'default' })
|
|
21
20
|
|
|
22
21
|
const LINK_BUTTON = `${textLinkVariants({ size: 'sm' })} focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring`
|
|
23
22
|
|
|
@@ -203,8 +202,7 @@ export function AnnouncementsOptInForm({ optedIn, copy }: { optedIn: boolean; co
|
|
|
203
202
|
)
|
|
204
203
|
}
|
|
205
204
|
|
|
206
|
-
const FIELD =
|
|
207
|
-
'w-full max-w-xs rounded-md border border-input bg-card px-3 py-2 text-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
205
|
+
const FIELD = controlVariants()
|
|
208
206
|
|
|
209
207
|
export function BoardDigestCadenceForm({ cadence, copy }: { cadence: string; copy: Copy }) {
|
|
210
208
|
const [state, action] = useActionState(saveBoardDigestCadenceAction, EMPTY_STATE)
|
|
@@ -216,7 +214,7 @@ export function BoardDigestCadenceForm({ cadence, copy }: { cadence: string; cop
|
|
|
216
214
|
>
|
|
217
215
|
<FormError message={state.error} />
|
|
218
216
|
|
|
219
|
-
<label className="flex flex-col gap-
|
|
217
|
+
<label className="flex min-w-0 flex-col gap-2 text-sm">
|
|
220
218
|
<span className="font-medium">{fromCopy(copy, 'accountForm.boardDigest.legend')}</span>
|
|
221
219
|
<span className="text-xs text-muted-foreground">
|
|
222
220
|
{fromCopy(copy, 'accountForm.boardDigest.description')}
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useState } from 'react'
|
|
4
4
|
|
|
5
|
+
import { buttonVariants } from '@meith/ui'
|
|
6
|
+
|
|
5
7
|
import { subscribeToPushAction, unsubscribeFromPushAction } from '@/server/push-actions'
|
|
6
8
|
|
|
7
9
|
import { FormError, FormNotice } from '../auth/form-controls'
|
|
8
10
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
9
11
|
|
|
10
|
-
const BUTTON =
|
|
11
|
-
'inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:opacity-60'
|
|
12
|
+
const BUTTON = buttonVariants({ variant: 'primary', size: 'default' })
|
|
12
13
|
|
|
13
14
|
type Status = 'checking' | 'unsupported' | 'blocked' | 'off' | 'on' | 'working'
|
|
14
15
|
|
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
import { useActionState } from 'react'
|
|
4
4
|
|
|
5
|
+
import { controlVariants, surfaceVariants } from '@meith/ui'
|
|
6
|
+
|
|
5
7
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
6
8
|
import { rateMemberAction, withdrawRatingAction } from '@/server/reputation-actions'
|
|
7
9
|
|
|
8
10
|
import { FormError, PendingButton } from '../auth/form-controls'
|
|
9
11
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
10
12
|
|
|
11
|
-
const FIELD =
|
|
12
|
-
'w-full rounded-md border border-input bg-card px-3 py-2 text-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
13
|
+
const FIELD = controlVariants()
|
|
13
14
|
|
|
14
|
-
const CARD =
|
|
15
|
+
const CARD = surfaceVariants({ padded: true })
|
|
15
16
|
|
|
16
17
|
const CHOICE =
|
|
17
18
|
'inline-flex h-9 items-center justify-center rounded-md border border-border px-4 text-sm font-medium hover:bg-muted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
@@ -52,7 +53,7 @@ export function RateMemberForm({
|
|
|
52
53
|
: fromCopy(copy, 'accountForm.rate.changeTitle')}
|
|
53
54
|
</h2>
|
|
54
55
|
|
|
55
|
-
<label className="flex flex-col gap-
|
|
56
|
+
<label className="flex min-w-0 flex-col gap-2 text-sm">
|
|
56
57
|
<span className="font-medium">
|
|
57
58
|
{commentRequired
|
|
58
59
|
? fromCopy(copy, 'accountForm.rate.why')
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useActionState } from 'react'
|
|
4
4
|
|
|
5
|
-
import { buttonVariants } from '@meith/ui'
|
|
5
|
+
import { buttonVariants, surfaceVariants } from '@meith/ui'
|
|
6
6
|
|
|
7
7
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
8
8
|
import { removePasskeyAction, unlinkIdentityAction } from '@/server/federation-actions'
|
|
@@ -10,7 +10,7 @@ import { removePasskeyAction, unlinkIdentityAction } from '@/server/federation-a
|
|
|
10
10
|
import { FormError, PendingButton } from '../auth/form-controls'
|
|
11
11
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
12
12
|
|
|
13
|
-
const CARD =
|
|
13
|
+
const CARD = surfaceVariants({ padded: true })
|
|
14
14
|
|
|
15
15
|
const ROW =
|
|
16
16
|
'flex flex-wrap items-center justify-between gap-3 rounded-md border border-border px-3 py-2'
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { useActionState, useEffect, useState } from 'react'
|
|
4
4
|
|
|
5
|
+
import { buttonVariants, controlVariants } from '@meith/ui'
|
|
6
|
+
|
|
5
7
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
6
8
|
import {
|
|
7
9
|
subscribeAction,
|
|
@@ -13,17 +15,13 @@ import { FormError, PendingButton } from '../auth/form-controls'
|
|
|
13
15
|
import { ProgressiveMarker } from '../content/progressive-marker'
|
|
14
16
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
15
17
|
|
|
16
|
-
const BUTTON =
|
|
17
|
-
'inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
18
|
+
const BUTTON = buttonVariants({ variant: 'primary', size: 'default' })
|
|
18
19
|
|
|
19
|
-
const QUIET_BUTTON =
|
|
20
|
-
'inline-flex h-9 items-center justify-center rounded-md border border-border px-3 text-sm font-medium transition-colors hover:bg-muted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
20
|
+
const QUIET_BUTTON = buttonVariants({ variant: 'outline', size: 'default' })
|
|
21
21
|
|
|
22
|
-
const GHOST_BUTTON =
|
|
23
|
-
'inline-flex h-9 items-center justify-center rounded-md px-3 text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
22
|
+
const GHOST_BUTTON = buttonVariants({ variant: 'ghost', size: 'default' })
|
|
24
23
|
|
|
25
|
-
const FIELD =
|
|
26
|
-
'rounded-md border border-border bg-background px-2 py-1 text-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
24
|
+
const FIELD = controlVariants({ size: 'sm', className: 'w-auto max-w-full' })
|
|
27
25
|
|
|
28
26
|
export interface ModeOption {
|
|
29
27
|
readonly value: string
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useActionState } from 'react'
|
|
4
4
|
|
|
5
|
-
import { buttonVariants } from '@meith/ui'
|
|
5
|
+
import { buttonVariants, surfaceVariants } from '@meith/ui'
|
|
6
6
|
|
|
7
7
|
import { EMPTY_STATE, type FormState } from '@/server/auth-form-state'
|
|
8
8
|
import {
|
|
@@ -18,10 +18,9 @@ import { Field, FormError, PendingButton } from '../auth/form-controls'
|
|
|
18
18
|
import { OtpField, otpRecoveryFromCopy } from '../auth/otp-field'
|
|
19
19
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
20
20
|
|
|
21
|
-
const CARD =
|
|
21
|
+
const CARD = surfaceVariants({ padded: true })
|
|
22
22
|
|
|
23
|
-
const BUTTON =
|
|
24
|
-
'inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
23
|
+
const BUTTON = buttonVariants({ variant: 'primary', size: 'default' })
|
|
25
24
|
|
|
26
25
|
function RecoveryCodes({ state, copy }: { readonly state: FormState; readonly copy: Copy }) {
|
|
27
26
|
const codes = state.values?.[RECOVERY_CODES_FIELD]
|