Files
myeasycms-v2/apps/web/app/identities/page.tsx
Giancarlo Buomprisco fa2fa9a15c chore: improve invitation flow, update project dependencies and documentation for Next.js 16 (#408)
* chore: update project dependencies and documentation for Next.js 16

- Upgraded Next.js from version 15 to 16 across various documentation files and components.
- Updated references to Next.js 16 in AGENTS.md and CLAUDE.md for consistency.
- Incremented application version to 2.21.0 in package.json.
- Refactored identity setup components to improve user experience and added confirmation dialogs for authentication methods.
- Enhanced invitation flow with new logic for handling user redirection and token generation.

* refactor: streamline invitation flow in e2e tests

- Simplified the invitation flow test by using a predefined email instead of generating a random one.
- Removed unnecessary steps such as clearing cookies and reloading the page before user sign-up.
- Enhanced clarity by eliminating commented-out code related to identity verification and user membership checks.

* refactor: improve code readability in IdentitiesPage and UpdatePasswordForm components

- Enhanced formatting of JSX elements in IdentitiesPage and UpdatePasswordForm for better readability.
- Adjusted indentation and line breaks to maintain consistent coding style across components.

* refactor: enhance LinkAccountsList component with user redirection logic

- Updated the LinkAccountsList component to include a redirectToPath option in the useLinkIdentityWithProvider hook for improved user experience.
- Removed redundant user hook declaration to streamline the code structure.

* refactor: update account setup logic in JoinTeamAccountPage

- Introduced a check for email-only authentication support to streamline account setup requirements.
- Adjusted the conditions for determining if a new account should set up additional authentication methods, enhancing user experience for new users.
2025-11-05 11:39:08 +07:00

126 lines
3.6 KiB
TypeScript

import { Metadata } from 'next';
import { redirect } from 'next/navigation';
import { AuthLayoutShell } from '@kit/auth/shared';
import { requireUser } from '@kit/supabase/require-user';
import { getSupabaseServerClient } from '@kit/supabase/server-client';
import { Heading } from '@kit/ui/heading';
import { Trans } from '@kit/ui/trans';
import { AppLogo } from '~/components/app-logo';
import authConfig from '~/config/auth.config';
import pathsConfig from '~/config/paths.config';
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
import { withI18n } from '~/lib/i18n/with-i18n';
import { IdentitiesStepWrapper } from './_components/identities-step-wrapper';
export const meta = async (): Promise<Metadata> => {
const i18n = await createI18nServerInstance();
return {
title: i18n.t('auth:setupAccount'),
};
};
type IdentitiesPageProps = {
searchParams: Promise<{ next?: string }>;
};
/**
* @name IdentitiesPage
* @description Displays linked accounts and available authentication methods.
*/
async function IdentitiesPage(props: IdentitiesPageProps) {
const {
nextPath,
showPasswordOption,
showEmailOption,
oAuthProviders,
enableIdentityLinking,
requiresConfirmation,
} = await fetchData(props);
return (
<AuthLayoutShell
Logo={AppLogo}
contentClassName="max-w-md overflow-y-hidden"
>
<div
className={
'flex max-h-[70vh] w-full flex-col items-center space-y-6 overflow-y-auto'
}
>
<div className={'flex flex-col items-center gap-1'}>
<Heading
level={4}
className="text-center"
data-test="identities-page-heading"
>
<Trans i18nKey={'auth:linkAccountToSignIn'} />
</Heading>
<Heading
level={6}
className={'text-muted-foreground text-center text-sm'}
data-test="identities-page-description"
>
<Trans i18nKey={'auth:linkAccountToSignInDescription'} />
</Heading>
</div>
<IdentitiesStepWrapper
nextPath={nextPath}
showPasswordOption={showPasswordOption}
showEmailOption={showEmailOption}
oAuthProviders={oAuthProviders}
enableIdentityLinking={enableIdentityLinking}
requiresConfirmation={requiresConfirmation}
/>
</div>
</AuthLayoutShell>
);
}
export default withI18n(IdentitiesPage);
async function fetchData(props: IdentitiesPageProps) {
const searchParams = await props.searchParams;
const client = getSupabaseServerClient();
const auth = await requireUser(client);
// If not authenticated, redirect to sign in
if (!auth.data) {
throw redirect(pathsConfig.auth.signIn);
}
// Get the next path from URL params (where to redirect after setup)
const nextPath = searchParams.next || pathsConfig.app.home;
// Available auth methods to add
const showPasswordOption = authConfig.providers.password;
// Show email option if password, magic link, or OTP is enabled
const showEmailOption =
authConfig.providers.password ||
authConfig.providers.magicLink ||
authConfig.providers.otp;
const oAuthProviders = authConfig.providers.oAuth;
const enableIdentityLinking = authConfig.enableIdentityLinking;
// Only require confirmation if password or oauth providers are enabled
const requiresConfirmation =
authConfig.providers.password || oAuthProviders.length > 0;
return {
nextPath,
showPasswordOption,
showEmailOption,
oAuthProviders,
enableIdentityLinking,
requiresConfirmation,
};
}