Next.js Supabase V3 (#463)
Version 3 of the kit: - Radix UI replaced with Base UI (using the Shadcn UI patterns) - next-intl replaces react-i18next - enhanceAction deprecated; usage moved to next-safe-action - main layout now wrapped with [locale] path segment - Teams only mode - Layout updates - Zod v4 - Next.js 16.2 - Typescript 6 - All other dependencies updated - Removed deprecated Edge CSRF - Dynamic Github Action runner
This commit is contained in:
committed by
GitHub
parent
4912e402a3
commit
7ebff31475
@@ -1,10 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { useFormStatus } from 'react-dom';
|
||||
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useAction } from 'next-safe-action/hooks';
|
||||
import { useForm, useWatch } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
import * as z from 'zod';
|
||||
|
||||
import { ErrorBoundary } from '@kit/monitoring/components';
|
||||
import { VerifyOtpForm } from '@kit/otp/components';
|
||||
@@ -100,12 +99,12 @@ function DeleteTeamContainer(props: {
|
||||
<div className={'flex flex-col space-y-4'}>
|
||||
<div className={'flex flex-col space-y-1'}>
|
||||
<span className={'text-sm font-medium'}>
|
||||
<Trans i18nKey={'teams:deleteTeam'} />
|
||||
<Trans i18nKey={'teams.deleteTeam'} />
|
||||
</span>
|
||||
|
||||
<p className={'text-muted-foreground text-sm'}>
|
||||
<Trans
|
||||
i18nKey={'teams:deleteTeamDescription'}
|
||||
i18nKey={'teams.deleteTeamDescription'}
|
||||
values={{
|
||||
teamName: props.account.name,
|
||||
}}
|
||||
@@ -115,25 +114,27 @@ function DeleteTeamContainer(props: {
|
||||
|
||||
<div>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button
|
||||
data-test={'delete-team-trigger'}
|
||||
type={'button'}
|
||||
variant={'destructive'}
|
||||
>
|
||||
<Trans i18nKey={'teams:deleteTeam'} />
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogTrigger
|
||||
render={
|
||||
<Button
|
||||
data-test={'delete-team-trigger'}
|
||||
type={'button'}
|
||||
variant={'destructive'}
|
||||
>
|
||||
<Trans i18nKey={'teams.deleteTeam'} />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
<AlertDialogContent onEscapeKeyDown={(e) => e.preventDefault()}>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
<Trans i18nKey={'teams:deletingTeam'} />
|
||||
<Trans i18nKey={'teams.deletingTeam'} />
|
||||
</AlertDialogTitle>
|
||||
|
||||
<AlertDialogDescription>
|
||||
<Trans
|
||||
i18nKey={'teams:deletingTeamDescription'}
|
||||
i18nKey={'teams.deletingTeamDescription'}
|
||||
values={{
|
||||
teamName: props.account.name,
|
||||
}}
|
||||
@@ -161,6 +162,8 @@ function DeleteTeamConfirmationForm({
|
||||
}) {
|
||||
const { data: user } = useUser();
|
||||
|
||||
const { execute, isPending } = useAction(deleteTeamAccountAction);
|
||||
|
||||
const form = useForm({
|
||||
mode: 'onChange',
|
||||
reValidateMode: 'onChange',
|
||||
@@ -188,7 +191,7 @@ function DeleteTeamConfirmationForm({
|
||||
onSuccess={(otp) => form.setValue('otp', otp, { shouldValidate: true })}
|
||||
CancelButton={
|
||||
<AlertDialogCancel className={'m-0'}>
|
||||
<Trans i18nKey={'common:cancel'} />
|
||||
<Trans i18nKey={'common.cancel'} />
|
||||
</AlertDialogCancel>
|
||||
}
|
||||
/>
|
||||
@@ -201,7 +204,10 @@ function DeleteTeamConfirmationForm({
|
||||
<form
|
||||
data-test={'delete-team-form'}
|
||||
className={'flex flex-col space-y-4'}
|
||||
action={deleteTeamAccountAction}
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
execute({ accountId: id, otp });
|
||||
}}
|
||||
>
|
||||
<div className={'flex flex-col space-y-2'}>
|
||||
<div
|
||||
@@ -211,7 +217,7 @@ function DeleteTeamConfirmationForm({
|
||||
>
|
||||
<div>
|
||||
<Trans
|
||||
i18nKey={'teams:deleteTeamDisclaimer'}
|
||||
i18nKey={'teams.deleteTeamDisclaimer'}
|
||||
values={{
|
||||
teamName: name,
|
||||
}}
|
||||
@@ -219,20 +225,24 @@ function DeleteTeamConfirmationForm({
|
||||
</div>
|
||||
|
||||
<div className={'text-sm'}>
|
||||
<Trans i18nKey={'common:modalConfirmationQuestion'} />
|
||||
<Trans i18nKey={'common.modalConfirmationQuestion'} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" value={id} name={'accountId'} />
|
||||
<input type="hidden" value={otp} name={'otp'} />
|
||||
</div>
|
||||
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>
|
||||
<Trans i18nKey={'common:cancel'} />
|
||||
<Trans i18nKey={'common.cancel'} />
|
||||
</AlertDialogCancel>
|
||||
|
||||
<DeleteTeamSubmitButton />
|
||||
<Button
|
||||
type="submit"
|
||||
data-test={'delete-team-form-confirm-button'}
|
||||
disabled={isPending}
|
||||
variant={'destructive'}
|
||||
>
|
||||
<Trans i18nKey={'teams.deleteTeam'} />
|
||||
</Button>
|
||||
</AlertDialogFooter>
|
||||
</form>
|
||||
</Form>
|
||||
@@ -240,26 +250,14 @@ function DeleteTeamConfirmationForm({
|
||||
);
|
||||
}
|
||||
|
||||
function DeleteTeamSubmitButton() {
|
||||
const { pending } = useFormStatus();
|
||||
|
||||
return (
|
||||
<Button
|
||||
data-test={'delete-team-form-confirm-button'}
|
||||
disabled={pending}
|
||||
variant={'destructive'}
|
||||
>
|
||||
<Trans i18nKey={'teams:deleteTeam'} />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
function LeaveTeamContainer(props: {
|
||||
account: {
|
||||
name: string;
|
||||
id: string;
|
||||
};
|
||||
}) {
|
||||
const { execute, isPending } = useAction(leaveTeamAccountAction);
|
||||
|
||||
const form = useForm({
|
||||
resolver: zodResolver(
|
||||
z.object({
|
||||
@@ -278,7 +276,7 @@ function LeaveTeamContainer(props: {
|
||||
<div className={'flex flex-col space-y-4'}>
|
||||
<p className={'text-muted-foreground text-sm'}>
|
||||
<Trans
|
||||
i18nKey={'teams:leaveTeamDescription'}
|
||||
i18nKey={'teams.leaveTeamDescription'}
|
||||
values={{
|
||||
teamName: props.account.name,
|
||||
}}
|
||||
@@ -286,26 +284,26 @@ function LeaveTeamContainer(props: {
|
||||
</p>
|
||||
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<div>
|
||||
<AlertDialogTrigger
|
||||
render={
|
||||
<Button
|
||||
data-test={'leave-team-button'}
|
||||
type={'button'}
|
||||
variant={'destructive'}
|
||||
>
|
||||
<Trans i18nKey={'teams:leaveTeam'} />
|
||||
<Trans i18nKey={'teams.leaveTeam'} />
|
||||
</Button>
|
||||
</div>
|
||||
</AlertDialogTrigger>
|
||||
}
|
||||
/>
|
||||
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
<Trans i18nKey={'teams:leavingTeamModalHeading'} />
|
||||
<Trans i18nKey={'teams.leavingTeamModalHeading'} />
|
||||
</AlertDialogTitle>
|
||||
|
||||
<AlertDialogDescription>
|
||||
<Trans i18nKey={'teams:leavingTeamModalDescription'} />
|
||||
<Trans i18nKey={'teams.leavingTeamModalDescription'} />
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
|
||||
@@ -313,21 +311,20 @@ function LeaveTeamContainer(props: {
|
||||
<Form {...form}>
|
||||
<form
|
||||
className={'flex flex-col space-y-4'}
|
||||
action={leaveTeamAccountAction}
|
||||
onSubmit={form.handleSubmit((data) => {
|
||||
execute({
|
||||
accountId: props.account.id,
|
||||
confirmation: data.confirmation,
|
||||
});
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type={'hidden'}
|
||||
value={props.account.id}
|
||||
name={'accountId'}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
name={'confirmation'}
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
<Trans i18nKey={'teams:leaveTeamInputLabel'} />
|
||||
<Trans i18nKey={'teams.leaveTeamInputLabel'} />
|
||||
</FormLabel>
|
||||
|
||||
<FormControl>
|
||||
@@ -344,7 +341,7 @@ function LeaveTeamContainer(props: {
|
||||
</FormControl>
|
||||
|
||||
<FormDescription>
|
||||
<Trans i18nKey={'teams:leaveTeamInputDescription'} />
|
||||
<Trans i18nKey={'teams.leaveTeamInputDescription'} />
|
||||
</FormDescription>
|
||||
|
||||
<FormMessage />
|
||||
@@ -355,10 +352,17 @@ function LeaveTeamContainer(props: {
|
||||
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>
|
||||
<Trans i18nKey={'common:cancel'} />
|
||||
<Trans i18nKey={'common.cancel'} />
|
||||
</AlertDialogCancel>
|
||||
|
||||
<LeaveTeamSubmitButton />
|
||||
<Button
|
||||
type="submit"
|
||||
data-test={'confirm-leave-organization-button'}
|
||||
disabled={isPending}
|
||||
variant={'destructive'}
|
||||
>
|
||||
<Trans i18nKey={'teams.leaveTeam'} />
|
||||
</Button>
|
||||
</AlertDialogFooter>
|
||||
</form>
|
||||
</Form>
|
||||
@@ -369,36 +373,22 @@ function LeaveTeamContainer(props: {
|
||||
);
|
||||
}
|
||||
|
||||
function LeaveTeamSubmitButton() {
|
||||
const { pending } = useFormStatus();
|
||||
|
||||
return (
|
||||
<Button
|
||||
data-test={'confirm-leave-organization-button'}
|
||||
disabled={pending}
|
||||
variant={'destructive'}
|
||||
>
|
||||
<Trans i18nKey={'teams:leaveTeam'} />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
function LeaveTeamErrorAlert() {
|
||||
return (
|
||||
<div className={'flex flex-col space-y-4'}>
|
||||
<Alert variant={'destructive'}>
|
||||
<AlertTitle>
|
||||
<Trans i18nKey={'teams:leaveTeamErrorHeading'} />
|
||||
<Trans i18nKey={'teams.leaveTeamErrorHeading'} />
|
||||
</AlertTitle>
|
||||
|
||||
<AlertDescription>
|
||||
<Trans i18nKey={'common:genericError'} />
|
||||
<Trans i18nKey={'common.genericError'} />
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>
|
||||
<Trans i18nKey={'common:cancel'} />
|
||||
<Trans i18nKey={'common.cancel'} />
|
||||
</AlertDialogCancel>
|
||||
</AlertDialogFooter>
|
||||
</div>
|
||||
@@ -410,17 +400,17 @@ function DeleteTeamErrorAlert() {
|
||||
<div className={'flex flex-col space-y-4'}>
|
||||
<Alert variant={'destructive'}>
|
||||
<AlertTitle>
|
||||
<Trans i18nKey={'teams:deleteTeamErrorHeading'} />
|
||||
<Trans i18nKey={'teams.deleteTeamErrorHeading'} />
|
||||
</AlertTitle>
|
||||
|
||||
<AlertDescription>
|
||||
<Trans i18nKey={'common:genericError'} />
|
||||
<Trans i18nKey={'common.genericError'} />
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>
|
||||
<Trans i18nKey={'common:cancel'} />
|
||||
<Trans i18nKey={'common.cancel'} />
|
||||
</AlertDialogCancel>
|
||||
</AlertDialogFooter>
|
||||
</div>
|
||||
@@ -432,11 +422,11 @@ function DangerZoneCard({ children }: React.PropsWithChildren) {
|
||||
<Card className={'border-destructive border'}>
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<Trans i18nKey={'teams:settings.dangerZone'} />
|
||||
<Trans i18nKey={'teams.settings.dangerZone'} />
|
||||
</CardTitle>
|
||||
|
||||
<CardDescription>
|
||||
<Trans i18nKey={'teams:settings.dangerZoneDescription'} />
|
||||
<Trans i18nKey={'teams.settings.dangerZoneDescription'} />
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user