* refactor: streamline sign-in and sign-up methods containers for improved conditional rendering

- Updated SignInMethodsContainer and SignUpMethodsContainer to conditionally render the separator and "or continue with" text only when applicable authentication methods are available.
- Enhanced code readability by removing redundant div elements and improving the structure of conditional rendering.

* refactor: enhance UI components with improved styling and structure

- Updated PlanIntervalSwitcher to include hover effects and adjusted button size for better user interaction.
- Refined PersonalAccountDropdown by removing unnecessary animation classes for cleaner code.
- Modified Footer component to standardize padding across different screen sizes.
- Adjusted Pill component's height and padding for a more consistent appearance.

* refactor: enhance admin members and memberships tables with date rendering and sorting adjustments

- Removed User ID column from both AdminMembersTable and AdminMembershipsTable for a cleaner interface.
- Added date rendering functionality for Created At and Updated At columns, displaying time in a user-friendly format.
- Disabled sorting for Name, Email, Role, Created At, and Updated At columns to improve usability.

* fix: update account linking messages and redirect logic

- Changed the success message for account linking to indicate that a request has been sent and to prompt the user to wait.
- Added a redirect path to the PersonalAccountSettingsContainer for improved navigation after account linking.
- Removed the unused useUnlinkIdentity hook to clean up the codebase.
This commit is contained in:
Giancarlo Buomprisco
2025-11-28 08:42:33 +08:00
committed by GitHub
parent db4aa6007e
commit a78da16790
11 changed files with 77 additions and 56 deletions

View File

@@ -417,7 +417,11 @@ function PlanIntervalSwitcher(
}>,
) {
return (
<div className={'flex gap-x-1 rounded-full border'}>
<div
className={
'hover:border-border flex gap-x-1 rounded-full border border-transparent transition-colors'
}
>
{props.intervals.map((plan, index) => {
const selected = plan === props.interval;
@@ -434,13 +438,14 @@ function PlanIntervalSwitcher(
return (
<Button
key={plan}
size={'sm'}
variant={selected ? 'secondary' : 'ghost'}
className={className}
onClick={() => props.setInterval(plan)}
>
<span className={'flex items-center'}>
<CheckCircle
className={cn('animate-in fade-in zoom-in-95 h-3.5', {
className={cn('animate-in fade-in zoom-in-95 h-3', {
hidden: !selected,
'slide-in-from-left-4': index === 0,
'slide-in-from-right-4': index === props.intervals.length - 1,

View File

@@ -87,7 +87,7 @@ export function PersonalAccountDropdown({
aria-label="Open your profile menu"
data-test={'account-dropdown-trigger'}
className={cn(
'animate-in group/trigger fade-in focus:outline-primary flex cursor-pointer items-center group-data-[minimized=true]/sidebar:px-0',
'group/trigger fade-in focus:outline-primary flex cursor-pointer items-center group-data-[minimized=true]/sidebar:px-0',
className ?? '',
{
['active:bg-secondary/50 items-center gap-4 rounded-md' +
@@ -108,7 +108,7 @@ export function PersonalAccountDropdown({
<If condition={showProfileName}>
<div
className={
'fade-in animate-in flex w-full flex-col truncate text-left group-data-[minimized=true]/sidebar:hidden'
'fade-in flex w-full flex-col truncate text-left group-data-[minimized=true]/sidebar:hidden'
}
>
<span

View File

@@ -174,6 +174,7 @@ export function PersonalAccountSettingsContainer(
enabled={props.features.enableAccountLinking}
showEmailOption={props.features.showLinkEmailOption}
showPasswordOption={props.features.enablePasswordUpdate}
redirectTo={'/home/settings'}
/>
</CardContent>
</Card>

View File

@@ -17,12 +17,9 @@ export function AdminMembersTable(props: { members: Memberships[] }) {
function getColumns(): ColumnDef<Memberships>[] {
return [
{
header: 'User ID',
accessorKey: 'user_id',
},
{
header: 'Name',
enableSorting: false,
cell: ({ row }) => {
const name = row.original.name ?? row.original.email;
@@ -48,9 +45,11 @@ function getColumns(): ColumnDef<Memberships>[] {
{
header: 'Email',
accessorKey: 'email',
enableSorting: false,
},
{
header: 'Role',
enableSorting: false,
cell: ({ row }) => {
return row.original.role;
},
@@ -58,10 +57,22 @@ function getColumns(): ColumnDef<Memberships>[] {
{
header: 'Created At',
accessorKey: 'created_at',
enableSorting: false,
cell: ({ row }) => {
return renderDate(row.original.created_at);
},
},
{
header: 'Updated At',
accessorKey: 'updated_at',
enableSorting: false,
cell: ({ row }) => {
return renderDate(row.original.updated_at);
},
},
];
}
function renderDate(date: string) {
return <span className={'text-xs'}>{new Date(date).toTimeString()}</span>;
}

View File

@@ -20,12 +20,9 @@ export function AdminMembershipsTable(props: { memberships: Membership[] }) {
function getColumns(): ColumnDef<Membership>[] {
return [
{
header: 'User ID',
accessorKey: 'user_id',
},
{
header: 'Team',
enableSorting: false,
cell: ({ row }) => {
return (
<Link
@@ -40,14 +37,27 @@ function getColumns(): ColumnDef<Membership>[] {
{
header: 'Role',
accessorKey: 'account_role',
enableSorting: false,
},
{
header: 'Created At',
accessorKey: 'created_at',
enableSorting: false,
cell: ({ row }) => {
return renderDate(row.original.created_at);
},
},
{
header: 'Updated At',
accessorKey: 'updated_at',
enableSorting: false,
cell: ({ row }) => {
return renderDate(row.original.updated_at);
},
},
];
}
function renderDate(date: string) {
return <span className={'text-xs'}>{new Date(date).toTimeString()}</span>;
}

View File

@@ -72,17 +72,25 @@ export function SignInMethodsContainer(props: {
</If>
<If condition={props.providers.oAuth.length}>
<div className="relative">
<div className="absolute inset-0 flex items-center">
<Separator />
</div>
<If
condition={
props.providers.magicLink ||
props.providers.password ||
props.providers.otp
}
>
<div className="relative">
<div className="absolute inset-0 flex items-center">
<Separator />
</div>
<div className="relative flex justify-center text-xs uppercase">
<span className="bg-background text-muted-foreground px-2">
<Trans i18nKey="auth:orContinueWith" />
</span>
<div className="relative flex justify-center text-xs uppercase">
<span className="bg-background text-muted-foreground px-2">
<Trans i18nKey="auth:orContinueWith" />
</span>
</div>
</div>
</div>
</If>
<OauthProviders
enabledProviders={props.providers.oAuth}

View File

@@ -64,17 +64,25 @@ export function SignUpMethodsContainer(props: {
</If>
<If condition={props.providers.oAuth.length}>
<div className="relative">
<div className="absolute inset-0 flex items-center">
<Separator />
</div>
<If
condition={
props.providers.magicLink ||
props.providers.password ||
props.providers.otp
}
>
<div className="relative">
<div className="absolute inset-0 flex items-center">
<Separator />
</div>
<div className="relative flex justify-center text-xs uppercase">
<span className="bg-background text-muted-foreground px-2">
<Trans i18nKey="auth:orContinueWith" />
</span>
<div className="relative flex justify-center text-xs uppercase">
<span className="bg-background text-muted-foreground px-2">
<Trans i18nKey="auth:orContinueWith" />
</span>
</div>
</div>
</div>
</If>
<OauthProviders
enabledProviders={props.providers.oAuth}

View File

@@ -1,22 +0,0 @@
import type { UserIdentity } from '@supabase/supabase-js';
import { useMutation } from '@tanstack/react-query';
import { useSupabase } from './use-supabase';
export function useUnlinkIdentity() {
const client = useSupabase();
const mutationKey = ['auth', 'unlink-identity'];
const mutationFn = async (identity: UserIdentity) => {
const { error } = await client.auth.unlinkIdentity(identity);
if (error) {
throw error.message ?? error;
}
await client.auth.refreshSession();
};
return useMutation({ mutationKey, mutationFn });
}

View File

@@ -26,7 +26,7 @@ export const Footer: React.FC<FooterProps> = ({
return (
<footer
className={cn(
'site-footer bg-muted/20 relative mt-auto w-full py-8 2xl:py-20',
'site-footer bg-muted/20 relative mt-auto w-full py-8 xl:py-16 2xl:py-20',
className,
)}
{...props}

View File

@@ -14,7 +14,7 @@ export const Pill: React.FC<
return (
<Comp
className={cn(
'bg-muted/50 flex min-h-10 items-center gap-x-1.5 rounded-full border px-2 py-1 text-center text-sm font-medium text-transparent',
'flex min-h-9 items-center gap-x-1.5 rounded-full border px-1.5 py-1 text-center text-sm font-medium text-transparent',
className,
)}
{...props}
@@ -22,7 +22,7 @@ export const Pill: React.FC<
{props.label && (
<span
className={
'text-primary-foreground bg-primary rounded-2xl border px-1.5 py-0.5 text-xs font-bold tracking-tight'
'text-primary-foreground bg-primary rounded-2xl border px-1.5 py-1.5 text-xs font-bold tracking-tight'
}
>
{props.label}