@meith/web 0.25.0 → 0.25.1
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 -2
- package/app/(board)/messages/[id]/page.tsx +28 -20
- package/app/(board)/messages/page.tsx +2 -2
- package/app/(board)/notifications/page.tsx +3 -1
- package/app/(board)/subscriptions/page.tsx +6 -2
- package/app/(board)/usercp/contacts/page.tsx +3 -7
- package/app/admin/api-tokens/page.tsx +3 -2
- package/app/admin/forums/[id]/page.tsx +25 -22
- package/app/admin/groups/memberships/page.tsx +6 -6
- package/app/admin/groups/promotions/page.tsx +14 -16
- package/app/admin/log/page.tsx +5 -3
- package/app/admin/security/page.tsx +4 -3
- package/app/admin/system/page.tsx +13 -10
- package/package.json +48 -48
- package/src/components/account/active-sessions.tsx +9 -6
- package/src/components/account/credential-proof-form.tsx +6 -7
- package/src/components/account/logout-form.tsx +5 -3
- package/src/components/account/notification-forms.tsx +9 -9
- package/src/components/account/relation-forms.tsx +5 -5
- package/src/components/account/reputation-forms.tsx +10 -10
- package/src/components/account/sign-in-methods.tsx +12 -6
- package/src/components/account/subscription-forms.tsx +7 -7
- package/src/components/account/two-factor-forms.tsx +12 -12
- package/src/components/account/usercp-forms.tsx +13 -13
- package/src/components/admin/admin-forms.tsx +7 -7
- package/src/components/admin/badge-forms.tsx +3 -3
- package/src/components/admin/ban-filter-forms.tsx +4 -4
- package/src/components/admin/branding-forms.tsx +3 -3
- package/src/components/admin/content-forms.tsx +15 -15
- package/src/components/admin/forum-forms.tsx +7 -7
- package/src/components/admin/group-forms.tsx +5 -5
- package/src/components/admin/mail-test-card.tsx +3 -3
- package/src/components/admin/marketplace-forms.tsx +4 -4
- package/src/components/admin/navigation-forms.tsx +3 -3
- package/src/components/admin/plugin-forms.tsx +7 -7
- package/src/components/admin/settings-form.tsx +5 -2
- package/src/components/admin/theme-forms.tsx +7 -10
- package/src/components/auth/form-controls.tsx +23 -1
- package/src/components/auth/second-factor-form.tsx +4 -4
- package/src/components/content/composer-intents.tsx +7 -6
- package/src/components/content/edit-post-form.tsx +7 -7
- package/src/components/content/poll-edit-form.tsx +3 -1
- package/src/components/content/poll.tsx +4 -2
- package/src/components/content/thanks-button.tsx +3 -3
- package/src/components/content/thread-rating.tsx +3 -3
- package/src/components/messages/message-forms.tsx +15 -15
- package/src/components/moderation/inline-moderation-form.tsx +19 -20
- package/src/components/moderation/queue-form.tsx +5 -7
- package/src/components/moderation/report-forms.tsx +8 -10
- package/src/components/moderation/signature-lock-form.tsx +5 -5
- package/src/components/moderation/thread-surgery-form.tsx +8 -5
- package/src/components/moderation/thread-tools-form.tsx +11 -22
- package/src/components/moderation/warning-forms.tsx +6 -6
- package/src/components/shell/onboarding-banner.tsx +6 -2
- package/src/components/shell/theme-switcher.tsx +6 -6
- package/src/components/shell/view-tabs.tsx +12 -7
- package/src/server/upgrade-notice.ts +1 -1
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import { useActionState } from 'react'
|
|
4
4
|
|
|
5
|
-
import { Input } from '@meith/ui'
|
|
6
|
-
import { Button } from '@meith/ui/button'
|
|
5
|
+
import { buttonVariants, Input } from '@meith/ui'
|
|
7
6
|
|
|
8
7
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
9
8
|
import { proveCredentialAction } from '@/server/credential-proof-actions'
|
|
10
9
|
|
|
11
|
-
import { FormError } from '../auth/form-controls'
|
|
10
|
+
import { FormError, PendingButton } from '../auth/form-controls'
|
|
12
11
|
import { OtpField } from '../auth/otp-field'
|
|
13
12
|
|
|
14
13
|
export interface CredentialProofCopy {
|
|
@@ -50,9 +49,9 @@ export function CredentialProofForm({
|
|
|
50
49
|
<Input name="password" type="password" autoComplete="current-password" required />
|
|
51
50
|
</label>
|
|
52
51
|
<div>
|
|
53
|
-
<
|
|
52
|
+
<PendingButton showWorking className={buttonVariants({ variant: 'primary' })}>
|
|
54
53
|
{copy.passwordSubmit}
|
|
55
|
-
</
|
|
54
|
+
</PendingButton>
|
|
56
55
|
</div>
|
|
57
56
|
</form>
|
|
58
57
|
) : null}
|
|
@@ -75,9 +74,9 @@ export function CredentialProofForm({
|
|
|
75
74
|
/>
|
|
76
75
|
<p className="text-sm text-muted-foreground">{copy.codeConsumed}</p>
|
|
77
76
|
<div>
|
|
78
|
-
<
|
|
77
|
+
<PendingButton showWorking className={buttonVariants({ variant: 'primary' })}>
|
|
79
78
|
{copy.codeSubmit}
|
|
80
|
-
</
|
|
79
|
+
</PendingButton>
|
|
81
80
|
</div>
|
|
82
81
|
</form>
|
|
83
82
|
) : null}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { logoutAction } from '@/server/auth-actions'
|
|
2
2
|
|
|
3
|
+
import { PendingButton } from '../auth/form-controls'
|
|
4
|
+
|
|
3
5
|
export function LogoutForm({ label }: { label: string }) {
|
|
4
6
|
return (
|
|
5
7
|
<form action={logoutAction}>
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
+
<PendingButton
|
|
9
|
+
showWorking
|
|
8
10
|
className="font-medium text-foreground hover:underline underline-offset-2"
|
|
9
11
|
>
|
|
10
12
|
{label}
|
|
11
|
-
</
|
|
13
|
+
</PendingButton>
|
|
12
14
|
</form>
|
|
13
15
|
)
|
|
14
16
|
}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
saveNotificationPreferencesAction,
|
|
11
11
|
} from '@/server/notification-actions'
|
|
12
12
|
|
|
13
|
-
import { FormError } from '../auth/form-controls'
|
|
13
|
+
import { FormError, PendingButton } from '../auth/form-controls'
|
|
14
14
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
15
15
|
|
|
16
16
|
const BUTTON =
|
|
@@ -32,9 +32,9 @@ export function MarkNotificationReadForm({
|
|
|
32
32
|
<form action={action} className="contents">
|
|
33
33
|
<input type="hidden" name="notificationId" value={notificationId} />
|
|
34
34
|
<FormError message={state.error} />
|
|
35
|
-
<
|
|
35
|
+
<PendingButton showWorking className={LINK_BUTTON}>
|
|
36
36
|
{fromCopy(copy, 'accountForm.notifications.markRead')}
|
|
37
|
-
</
|
|
37
|
+
</PendingButton>
|
|
38
38
|
</form>
|
|
39
39
|
)
|
|
40
40
|
}
|
|
@@ -47,9 +47,9 @@ export function MarkAllNotificationsReadForm({ unread, copy }: { unread: number;
|
|
|
47
47
|
return (
|
|
48
48
|
<form action={action}>
|
|
49
49
|
<FormError message={state.error} />
|
|
50
|
-
<
|
|
50
|
+
<PendingButton showWorking className={BUTTON}>
|
|
51
51
|
{fromCopy(copy, 'accountForm.notifications.markAllRead')}
|
|
52
|
-
</
|
|
52
|
+
</PendingButton>
|
|
53
53
|
</form>
|
|
54
54
|
)
|
|
55
55
|
}
|
|
@@ -149,9 +149,9 @@ export function NotificationPreferencesForm({
|
|
|
149
149
|
</p>
|
|
150
150
|
|
|
151
151
|
<div>
|
|
152
|
-
<
|
|
152
|
+
<PendingButton showWorking className={BUTTON}>
|
|
153
153
|
{fromCopy(copy, 'accountForm.notifications.submit')}
|
|
154
|
-
</
|
|
154
|
+
</PendingButton>
|
|
155
155
|
</div>
|
|
156
156
|
</form>
|
|
157
157
|
)
|
|
@@ -193,9 +193,9 @@ export function AnnouncementsOptInForm({ optedIn, copy }: { optedIn: boolean; co
|
|
|
193
193
|
</p>
|
|
194
194
|
|
|
195
195
|
<div>
|
|
196
|
-
<
|
|
196
|
+
<PendingButton showWorking className={BUTTON}>
|
|
197
197
|
{fromCopy(copy, 'accountForm.announcements.submit')}
|
|
198
|
-
</
|
|
198
|
+
</PendingButton>
|
|
199
199
|
</div>
|
|
200
200
|
</form>
|
|
201
201
|
)
|
|
@@ -5,7 +5,7 @@ import { useActionState } from 'react'
|
|
|
5
5
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
6
6
|
import { removeRelationAction, setRelationAction } from '@/server/relation-actions'
|
|
7
7
|
|
|
8
|
-
import { FormError } from '../auth/form-controls'
|
|
8
|
+
import { FormError, PendingButton } from '../auth/form-controls'
|
|
9
9
|
|
|
10
10
|
const LINK_BUTTON =
|
|
11
11
|
'text-sm font-medium text-foreground underline decoration-border underline-offset-2 hover:decoration-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
|
|
@@ -35,9 +35,9 @@ export function SetRelationForm({
|
|
|
35
35
|
<input type="hidden" name="username" value={username} />
|
|
36
36
|
<input type="hidden" name="kind" value={kind} />
|
|
37
37
|
<input type="hidden" name="returnTo" value={returnTo} />
|
|
38
|
-
<
|
|
38
|
+
<PendingButton showWorking className={kind === 'buddy' ? LINK_BUTTON : QUIET_BUTTON}>
|
|
39
39
|
{label}
|
|
40
|
-
</
|
|
40
|
+
</PendingButton>
|
|
41
41
|
</form>
|
|
42
42
|
)
|
|
43
43
|
}
|
|
@@ -61,9 +61,9 @@ export function RemoveRelationForm({
|
|
|
61
61
|
<input type="hidden" name="userId" value={userId} />
|
|
62
62
|
<input type="hidden" name="username" value={username} />
|
|
63
63
|
<input type="hidden" name="returnTo" value={returnTo} />
|
|
64
|
-
<
|
|
64
|
+
<PendingButton showWorking className={QUIET_BUTTON}>
|
|
65
65
|
{label}
|
|
66
|
-
</
|
|
66
|
+
</PendingButton>
|
|
67
67
|
</form>
|
|
68
68
|
)
|
|
69
69
|
}
|
|
@@ -5,7 +5,7 @@ import { useActionState } from 'react'
|
|
|
5
5
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
6
6
|
import { rateMemberAction, withdrawRatingAction } from '@/server/reputation-actions'
|
|
7
7
|
|
|
8
|
-
import { FormError } from '../auth/form-controls'
|
|
8
|
+
import { FormError, PendingButton } from '../auth/form-controls'
|
|
9
9
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
10
10
|
|
|
11
11
|
const FIELD =
|
|
@@ -72,20 +72,20 @@ export function RateMemberForm({
|
|
|
72
72
|
</label>
|
|
73
73
|
|
|
74
74
|
<div className="flex flex-wrap items-center gap-2">
|
|
75
|
-
<
|
|
75
|
+
<PendingButton name="points" value="1" className={CHOICE}>
|
|
76
76
|
{allowNegative
|
|
77
77
|
? fromCopy(copy, 'accountForm.rate.positive')
|
|
78
78
|
: fromCopy(copy, 'accountForm.rate.thanks')}
|
|
79
|
-
</
|
|
80
|
-
<
|
|
79
|
+
</PendingButton>
|
|
80
|
+
<PendingButton name="points" value="0" className={CHOICE}>
|
|
81
81
|
{allowNegative
|
|
82
82
|
? fromCopy(copy, 'accountForm.rate.neutral')
|
|
83
83
|
: fromCopy(copy, 'accountForm.rate.justComment')}
|
|
84
|
-
</
|
|
84
|
+
</PendingButton>
|
|
85
85
|
{allowNegative && (
|
|
86
|
-
<
|
|
86
|
+
<PendingButton name="points" value="-1" className={CHOICE}>
|
|
87
87
|
{fromCopy(copy, 'accountForm.rate.negative')}
|
|
88
|
-
</
|
|
88
|
+
</PendingButton>
|
|
89
89
|
)}
|
|
90
90
|
</div>
|
|
91
91
|
|
|
@@ -113,12 +113,12 @@ export function WithdrawRatingForm({
|
|
|
113
113
|
<input type="hidden" name="ratingId" value={ratingId} />
|
|
114
114
|
<input type="hidden" name="userId" value={userId} />
|
|
115
115
|
<input type="hidden" name="returnTo" value={returnTo} />
|
|
116
|
-
<
|
|
117
|
-
|
|
116
|
+
<PendingButton
|
|
117
|
+
showWorking
|
|
118
118
|
className="text-xs text-muted-foreground hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring"
|
|
119
119
|
>
|
|
120
120
|
{fromCopy(copy, 'accountForm.rate.withdraw')}
|
|
121
|
-
</
|
|
121
|
+
</PendingButton>
|
|
122
122
|
</form>
|
|
123
123
|
)
|
|
124
124
|
}
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import { useActionState } from 'react'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { buttonVariants } from '@meith/ui'
|
|
6
6
|
|
|
7
7
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
8
8
|
import { removePasskeyAction, unlinkIdentityAction } from '@/server/federation-actions'
|
|
9
9
|
|
|
10
|
-
import { FormError } from '../auth/form-controls'
|
|
10
|
+
import { FormError, PendingButton } from '../auth/form-controls'
|
|
11
11
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
12
12
|
|
|
13
13
|
const CARD = 'flex flex-col gap-4 rounded-lg border border-border bg-card p-5'
|
|
@@ -79,9 +79,12 @@ export function LinkedSignIns({
|
|
|
79
79
|
{manageable ? (
|
|
80
80
|
<form action={action}>
|
|
81
81
|
<input type="hidden" name="identityId" value={identity.id} />
|
|
82
|
-
<
|
|
82
|
+
<PendingButton
|
|
83
|
+
showWorking
|
|
84
|
+
className={buttonVariants({ variant: 'destructive', size: 'sm' })}
|
|
85
|
+
>
|
|
83
86
|
{fromCopy(copy, 'accountForm.linked.unlink')}
|
|
84
|
-
</
|
|
87
|
+
</PendingButton>
|
|
85
88
|
</form>
|
|
86
89
|
) : null}
|
|
87
90
|
</li>
|
|
@@ -150,9 +153,12 @@ export function PasskeyList({
|
|
|
150
153
|
{manageable ? (
|
|
151
154
|
<form action={action}>
|
|
152
155
|
<input type="hidden" name="passkeyId" value={passkey.id} />
|
|
153
|
-
<
|
|
156
|
+
<PendingButton
|
|
157
|
+
showWorking
|
|
158
|
+
className={buttonVariants({ variant: 'destructive', size: 'sm' })}
|
|
159
|
+
>
|
|
154
160
|
{fromCopy(copy, 'accountForm.passkeys.remove')}
|
|
155
|
-
</
|
|
161
|
+
</PendingButton>
|
|
156
162
|
</form>
|
|
157
163
|
) : null}
|
|
158
164
|
</li>
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
unsubscribeByTokenAction,
|
|
10
10
|
} from '@/server/subscription-actions'
|
|
11
11
|
|
|
12
|
-
import { FormError } from '../auth/form-controls'
|
|
12
|
+
import { FormError, PendingButton } from '../auth/form-controls'
|
|
13
13
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
14
14
|
|
|
15
15
|
const BUTTON =
|
|
@@ -77,11 +77,11 @@ export function FollowForm({
|
|
|
77
77
|
</select>
|
|
78
78
|
</label>
|
|
79
79
|
|
|
80
|
-
<
|
|
80
|
+
<PendingButton className={QUIET_BUTTON}>
|
|
81
81
|
{mode === null
|
|
82
82
|
? fromCopy(copy, 'accountForm.follow.follow')
|
|
83
83
|
: fromCopy(copy, 'accountForm.follow.save')}
|
|
84
|
-
</
|
|
84
|
+
</PendingButton>
|
|
85
85
|
</form>
|
|
86
86
|
|
|
87
87
|
{mode !== null && (
|
|
@@ -89,9 +89,9 @@ export function FollowForm({
|
|
|
89
89
|
<input type="hidden" name="target" value={target} />
|
|
90
90
|
<input type="hidden" name="targetId" value={targetId} />
|
|
91
91
|
<input type="hidden" name="back" value={back} />
|
|
92
|
-
<
|
|
92
|
+
<PendingButton className={GHOST_BUTTON}>
|
|
93
93
|
{fromCopy(copy, 'accountForm.follow.stop')}
|
|
94
|
-
</
|
|
94
|
+
</PendingButton>
|
|
95
95
|
</form>
|
|
96
96
|
)}
|
|
97
97
|
</div>
|
|
@@ -142,9 +142,9 @@ export function UnsubscribeConfirmForm({
|
|
|
142
142
|
<input type="hidden" name="token" value={token} />
|
|
143
143
|
<p className="text-sm">{description}</p>
|
|
144
144
|
<div>
|
|
145
|
-
<
|
|
145
|
+
<PendingButton showWorking className={BUTTON}>
|
|
146
146
|
{fromCopy(copy, 'accountForm.follow.unsubscribe')}
|
|
147
|
-
</
|
|
147
|
+
</PendingButton>
|
|
148
148
|
</div>
|
|
149
149
|
</form>
|
|
150
150
|
)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useActionState } from 'react'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { buttonVariants } from '@meith/ui'
|
|
6
6
|
|
|
7
7
|
import { EMPTY_STATE, type FormState } from '@/server/auth-form-state'
|
|
8
8
|
import {
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from '@/server/two-factor-actions'
|
|
15
15
|
import { RECOVERY_CODES_FIELD } from '@/view/two-factor'
|
|
16
16
|
|
|
17
|
-
import { Field, FormError } from '../auth/form-controls'
|
|
17
|
+
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
|
|
|
@@ -103,17 +103,17 @@ export function TwoFactorSetup({
|
|
|
103
103
|
hint={fromCopy(copy, 'accountForm.twoFactor.codeHint')}
|
|
104
104
|
/>
|
|
105
105
|
<div className="flex flex-wrap gap-2">
|
|
106
|
-
<
|
|
106
|
+
<PendingButton showWorking className={BUTTON}>
|
|
107
107
|
{fromCopy(copy, 'accountForm.twoFactor.turnOn')}
|
|
108
|
-
</
|
|
108
|
+
</PendingButton>
|
|
109
109
|
</div>
|
|
110
110
|
</form>
|
|
111
111
|
|
|
112
112
|
<form action={abandon}>
|
|
113
113
|
<FormError message={abandonState.error} />
|
|
114
|
-
<
|
|
114
|
+
<PendingButton showWorking className={buttonVariants({ variant: 'ghost', size: 'sm' })}>
|
|
115
115
|
{fromCopy(copy, 'accountForm.twoFactor.cancel')}
|
|
116
|
-
</
|
|
116
|
+
</PendingButton>
|
|
117
117
|
</form>
|
|
118
118
|
</section>
|
|
119
119
|
)
|
|
@@ -148,9 +148,9 @@ export function TwoFactorPanel({
|
|
|
148
148
|
</p>
|
|
149
149
|
<FormError message={beginState.error} />
|
|
150
150
|
<form action={begin}>
|
|
151
|
-
<
|
|
151
|
+
<PendingButton showWorking className={BUTTON}>
|
|
152
152
|
{fromCopy(copy, 'accountForm.twoFactor.begin')}
|
|
153
|
-
</
|
|
153
|
+
</PendingButton>
|
|
154
154
|
</form>
|
|
155
155
|
</section>
|
|
156
156
|
)
|
|
@@ -199,9 +199,9 @@ export function TwoFactorPanel({
|
|
|
199
199
|
</p>
|
|
200
200
|
{proof('replace')}
|
|
201
201
|
<div>
|
|
202
|
-
<
|
|
202
|
+
<PendingButton showWorking className={BUTTON}>
|
|
203
203
|
{fromCopy(copy, 'accountForm.twoFactor.replaceSubmit')}
|
|
204
|
-
</
|
|
204
|
+
</PendingButton>
|
|
205
205
|
</div>
|
|
206
206
|
</form>
|
|
207
207
|
|
|
@@ -215,9 +215,9 @@ export function TwoFactorPanel({
|
|
|
215
215
|
<p className="text-sm font-medium">{fromCopy(copy, 'accountForm.twoFactor.offTitle')}</p>
|
|
216
216
|
{proof('disable')}
|
|
217
217
|
<div>
|
|
218
|
-
<
|
|
218
|
+
<PendingButton showWorking className={buttonVariants({ variant: 'destructive' })}>
|
|
219
219
|
{fromCopy(copy, 'accountForm.twoFactor.offSubmit')}
|
|
220
|
-
</
|
|
220
|
+
</PendingButton>
|
|
221
221
|
</div>
|
|
222
222
|
</form>
|
|
223
223
|
)}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
saveSignatureAction,
|
|
13
13
|
} from '@/server/usercp-actions'
|
|
14
14
|
|
|
15
|
-
import { FormError } from '../auth/form-controls'
|
|
15
|
+
import { FormError, PendingButton } from '../auth/form-controls'
|
|
16
16
|
import { MarkdownEditor } from '../content/markdown-editor'
|
|
17
17
|
import { CustomField, type CustomFieldInput } from '../profile/custom-field'
|
|
18
18
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
@@ -75,9 +75,9 @@ export function ProfileForm({
|
|
|
75
75
|
))}
|
|
76
76
|
|
|
77
77
|
<div>
|
|
78
|
-
<
|
|
78
|
+
<PendingButton showWorking className={BUTTON}>
|
|
79
79
|
{fromCopy(copy, 'accountForm.profile.submit')}
|
|
80
|
-
</
|
|
80
|
+
</PendingButton>
|
|
81
81
|
</div>
|
|
82
82
|
</form>
|
|
83
83
|
)
|
|
@@ -116,9 +116,9 @@ export function DisplayGroupForm({
|
|
|
116
116
|
</label>
|
|
117
117
|
|
|
118
118
|
<div>
|
|
119
|
-
<
|
|
119
|
+
<PendingButton showWorking className={BUTTON}>
|
|
120
120
|
{fromCopy(copy, 'accountForm.displayGroup.submit')}
|
|
121
|
-
</
|
|
121
|
+
</PendingButton>
|
|
122
122
|
</div>
|
|
123
123
|
</form>
|
|
124
124
|
)
|
|
@@ -214,9 +214,9 @@ export function OptionsForm({
|
|
|
214
214
|
</label>
|
|
215
215
|
|
|
216
216
|
<div>
|
|
217
|
-
<
|
|
217
|
+
<PendingButton showWorking className={BUTTON}>
|
|
218
218
|
{fromCopy(copy, 'accountForm.options.submit')}
|
|
219
|
-
</
|
|
219
|
+
</PendingButton>
|
|
220
220
|
</div>
|
|
221
221
|
</form>
|
|
222
222
|
)
|
|
@@ -270,9 +270,9 @@ export function PasswordForm({ minLength, copy }: { minLength: number; copy: Cop
|
|
|
270
270
|
<p className="text-xs text-muted-foreground">{fromCopy(copy, 'accountForm.password.note')}</p>
|
|
271
271
|
|
|
272
272
|
<div>
|
|
273
|
-
<
|
|
273
|
+
<PendingButton showWorking className={BUTTON}>
|
|
274
274
|
{fromCopy(copy, 'accountForm.password.submit')}
|
|
275
|
-
</
|
|
275
|
+
</PendingButton>
|
|
276
276
|
</div>
|
|
277
277
|
</form>
|
|
278
278
|
)
|
|
@@ -313,9 +313,9 @@ export function EmailForm({ email, copy }: { email: string; copy: Copy }) {
|
|
|
313
313
|
<p className="text-xs text-muted-foreground">{fromCopy(copy, 'accountForm.email.note')}</p>
|
|
314
314
|
|
|
315
315
|
<div>
|
|
316
|
-
<
|
|
316
|
+
<PendingButton showWorking className={BUTTON}>
|
|
317
317
|
{fromCopy(copy, 'accountForm.email.submit')}
|
|
318
|
-
</
|
|
318
|
+
</PendingButton>
|
|
319
319
|
</div>
|
|
320
320
|
</form>
|
|
321
321
|
)
|
|
@@ -378,9 +378,9 @@ export function SignatureForm({
|
|
|
378
378
|
/>
|
|
379
379
|
|
|
380
380
|
<div>
|
|
381
|
-
<
|
|
381
|
+
<PendingButton showWorking className={BUTTON}>
|
|
382
382
|
{fromCopy(copy, 'accountForm.signature.submit')}
|
|
383
|
-
</
|
|
383
|
+
</PendingButton>
|
|
384
384
|
</div>
|
|
385
385
|
</form>
|
|
386
386
|
)
|
|
@@ -5,7 +5,7 @@ import { useActionState } from 'react'
|
|
|
5
5
|
import { adminSignInAction, adminSignOutAction } from '@/server/admin-actions'
|
|
6
6
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
7
7
|
|
|
8
|
-
import { FormError } from '../auth/form-controls'
|
|
8
|
+
import { FormError, PendingButton } from '../auth/form-controls'
|
|
9
9
|
import { OtpField, otpRecoveryFromCopy } from '../auth/otp-field'
|
|
10
10
|
import { type Copy, formatFromCopy, fromCopy } from '../shell/copy'
|
|
11
11
|
|
|
@@ -59,12 +59,12 @@ export function AdminSignInForm({
|
|
|
59
59
|
recovery={otpRecoveryFromCopy(copy)}
|
|
60
60
|
/>
|
|
61
61
|
|
|
62
|
-
<
|
|
63
|
-
|
|
62
|
+
<PendingButton
|
|
63
|
+
showWorking
|
|
64
64
|
className="inline-flex h-10 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring"
|
|
65
65
|
>
|
|
66
66
|
{fromCopy(copy, 'adminPanel.enter')}
|
|
67
|
-
</
|
|
67
|
+
</PendingButton>
|
|
68
68
|
|
|
69
69
|
<p className="text-xs text-muted-foreground">
|
|
70
70
|
{formatFromCopy(copy, 'adminPanel.idleNote', { minutes: idleMinutes })}
|
|
@@ -76,12 +76,12 @@ export function AdminSignInForm({
|
|
|
76
76
|
export function AdminSignOutForm({ copy }: { copy: Copy }) {
|
|
77
77
|
return (
|
|
78
78
|
<form action={adminSignOutAction}>
|
|
79
|
-
<
|
|
80
|
-
|
|
79
|
+
<PendingButton
|
|
80
|
+
showWorking
|
|
81
81
|
className="text-sm text-muted-foreground hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring"
|
|
82
82
|
>
|
|
83
83
|
{fromCopy(copy, 'adminPanel.leave')}
|
|
84
|
-
</
|
|
84
|
+
</PendingButton>
|
|
85
85
|
</form>
|
|
86
86
|
)
|
|
87
87
|
}
|
|
@@ -8,7 +8,7 @@ import { PANEL_CARD } from '@/components/shell/panel-list'
|
|
|
8
8
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
9
9
|
import { removeBadgeAction, saveBadgeAction } from '@/server/group-badge-actions'
|
|
10
10
|
|
|
11
|
-
import { FormError, SubmitButton } from '../auth/form-controls'
|
|
11
|
+
import { FormError, PendingButton, SubmitButton } from '../auth/form-controls'
|
|
12
12
|
import { type Copy, formatFromCopy, fromCopy } from '../shell/copy'
|
|
13
13
|
import { Saved } from './form-bits'
|
|
14
14
|
|
|
@@ -86,9 +86,9 @@ export function BadgeUploadForm({
|
|
|
86
86
|
<form action={removeAction}>
|
|
87
87
|
<input type="hidden" name="groupId" value={groupId} />
|
|
88
88
|
<input type="hidden" name="scheme" value={scheme} />
|
|
89
|
-
<
|
|
89
|
+
<PendingButton showWorking className={GHOST}>
|
|
90
90
|
{fromCopy(copy, 'admin.remove')}
|
|
91
|
-
</
|
|
91
|
+
</PendingButton>
|
|
92
92
|
</form>
|
|
93
93
|
)}
|
|
94
94
|
</div>
|
|
@@ -5,7 +5,7 @@ import { useActionState } from 'react'
|
|
|
5
5
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
6
6
|
import { addBanFilterAction, removeBanFilterAction } from '@/server/ban-filter-admin-actions'
|
|
7
7
|
|
|
8
|
-
import { FormError, SubmitButton } from '../auth/form-controls'
|
|
8
|
+
import { FormError, PendingButton, SubmitButton } from '../auth/form-controls'
|
|
9
9
|
import { type Copy, formatFromCopy, fromCopy } from '../shell/copy'
|
|
10
10
|
import { INPUT, Saved } from './form-bits'
|
|
11
11
|
|
|
@@ -92,13 +92,13 @@ export function RemoveBanFilterForm({
|
|
|
92
92
|
<form action={action} className="flex flex-col items-end gap-1">
|
|
93
93
|
<FormError message={state.error} />
|
|
94
94
|
<input type="hidden" name="id" value={id} />
|
|
95
|
-
<
|
|
96
|
-
|
|
95
|
+
<PendingButton
|
|
96
|
+
showWorking
|
|
97
97
|
className="text-xs text-destructive hover:underline"
|
|
98
98
|
aria-label={formatFromCopy(copy, 'adminBanFilter.removeFilter', { pattern })}
|
|
99
99
|
>
|
|
100
100
|
{fromCopy(copy, 'admin.remove')}
|
|
101
|
-
</
|
|
101
|
+
</PendingButton>
|
|
102
102
|
</form>
|
|
103
103
|
)
|
|
104
104
|
}
|
|
@@ -6,7 +6,7 @@ import { PANEL_CARD } from '@/components/shell/panel-list'
|
|
|
6
6
|
import { EMPTY_STATE } from '@/server/auth-form-state'
|
|
7
7
|
import { removeLogoAction, saveLogoAction } from '@/server/branding-actions'
|
|
8
8
|
|
|
9
|
-
import { FormError, SubmitButton } from '../auth/form-controls'
|
|
9
|
+
import { FormError, PendingButton, SubmitButton } from '../auth/form-controls'
|
|
10
10
|
import { type Copy, formatFromCopy, fromCopy } from '../shell/copy'
|
|
11
11
|
import { Saved } from './form-bits'
|
|
12
12
|
|
|
@@ -87,9 +87,9 @@ export function LogoUploadForm({
|
|
|
87
87
|
{slot.src !== null && (
|
|
88
88
|
<form action={removeAction}>
|
|
89
89
|
<input type="hidden" name="scheme" value={slot.scheme} />
|
|
90
|
-
<
|
|
90
|
+
<PendingButton showWorking className={GHOST}>
|
|
91
91
|
{fromCopy(copy, 'admin.remove')}
|
|
92
|
-
</
|
|
92
|
+
</PendingButton>
|
|
93
93
|
</form>
|
|
94
94
|
)}
|
|
95
95
|
</div>
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
updateWordFilterAction,
|
|
25
25
|
} from '@/server/content-admin-actions'
|
|
26
26
|
|
|
27
|
-
import { FormError, SubmitButton } from '../auth/form-controls'
|
|
27
|
+
import { FormError, PendingButton, SubmitButton } from '../auth/form-controls'
|
|
28
28
|
import { type Copy, fromCopy } from '../shell/copy'
|
|
29
29
|
import { INPUT, Saved } from './form-bits'
|
|
30
30
|
|
|
@@ -87,9 +87,9 @@ export function WordFilterRowForm({ filter, copy }: { filter: WordFilterValues;
|
|
|
87
87
|
|
|
88
88
|
<form action={removeAction}>
|
|
89
89
|
<input type="hidden" name="id" value={filter.id} />
|
|
90
|
-
<
|
|
90
|
+
<PendingButton showWorking className="text-xs text-muted-foreground hover:underline">
|
|
91
91
|
{fromCopy(copy, 'adminContent.filter.removeThis')}
|
|
92
|
-
</
|
|
92
|
+
</PendingButton>
|
|
93
93
|
</form>
|
|
94
94
|
</div>
|
|
95
95
|
)
|
|
@@ -143,9 +143,9 @@ export function DeletePrefixForm({ prefix, copy }: { prefix: PrefixValues; copy:
|
|
|
143
143
|
<form action={action} className="flex items-center gap-2">
|
|
144
144
|
<FormError message={state.error} />
|
|
145
145
|
<input type="hidden" name="id" value={prefix.id} />
|
|
146
|
-
<
|
|
146
|
+
<PendingButton showWorking className="text-xs text-muted-foreground hover:underline">
|
|
147
147
|
{fromCopy(copy, 'admin.remove')}
|
|
148
|
-
</
|
|
148
|
+
</PendingButton>
|
|
149
149
|
</form>
|
|
150
150
|
)
|
|
151
151
|
}
|
|
@@ -252,9 +252,9 @@ export function SmileyRowForm({ smiley, copy }: { smiley: SmileyValues; copy: Co
|
|
|
252
252
|
|
|
253
253
|
<form action={removeAction}>
|
|
254
254
|
<input type="hidden" name="id" value={smiley.id} />
|
|
255
|
-
<
|
|
255
|
+
<PendingButton showWorking className="text-xs text-destructive hover:underline">
|
|
256
256
|
{fromCopy(copy, 'admin.remove')}
|
|
257
|
-
</
|
|
257
|
+
</PendingButton>
|
|
258
258
|
</form>
|
|
259
259
|
</div>
|
|
260
260
|
)
|
|
@@ -362,9 +362,9 @@ export function DirectiveRowForm({ directive, copy }: { directive: DirectiveValu
|
|
|
362
362
|
|
|
363
363
|
<form action={removeAction}>
|
|
364
364
|
<input type="hidden" name="id" value={directive.id} />
|
|
365
|
-
<
|
|
365
|
+
<PendingButton showWorking className="text-xs text-destructive hover:underline">
|
|
366
366
|
{fromCopy(copy, 'admin.remove')}
|
|
367
|
-
</
|
|
367
|
+
</PendingButton>
|
|
368
368
|
</form>
|
|
369
369
|
</div>
|
|
370
370
|
)
|
|
@@ -422,9 +422,9 @@ export function DeleteAttachmentForm({ attachmentId, copy }: { attachmentId: num
|
|
|
422
422
|
<form action={action} className="shrink-0">
|
|
423
423
|
<FormError message={state.error} />
|
|
424
424
|
<input type="hidden" name="id" value={attachmentId} />
|
|
425
|
-
<
|
|
425
|
+
<PendingButton showWorking className="text-xs text-destructive hover:underline">
|
|
426
426
|
{fromCopy(copy, 'adminContent.attachment.delete')}
|
|
427
|
-
</
|
|
427
|
+
</PendingButton>
|
|
428
428
|
</form>
|
|
429
429
|
)
|
|
430
430
|
}
|
|
@@ -568,9 +568,9 @@ export function AnnouncementRowForm({
|
|
|
568
568
|
|
|
569
569
|
<form action={removeAction}>
|
|
570
570
|
<input type="hidden" name="id" value={announcement.id} />
|
|
571
|
-
<
|
|
571
|
+
<PendingButton showWorking className="text-xs text-destructive hover:underline">
|
|
572
572
|
{fromCopy(copy, 'admin.remove')}
|
|
573
|
-
</
|
|
573
|
+
</PendingButton>
|
|
574
574
|
</form>
|
|
575
575
|
</div>
|
|
576
576
|
)
|
|
@@ -670,9 +670,9 @@ export function CaptchaQuestionRowForm({
|
|
|
670
670
|
|
|
671
671
|
<form action={removeAction}>
|
|
672
672
|
<input type="hidden" name="id" value={question.id} />
|
|
673
|
-
<
|
|
673
|
+
<PendingButton showWorking className="text-xs text-destructive hover:underline">
|
|
674
674
|
{fromCopy(copy, 'admin.remove')}
|
|
675
|
-
</
|
|
675
|
+
</PendingButton>
|
|
676
676
|
</form>
|
|
677
677
|
</div>
|
|
678
678
|
)
|