Files
myeasycms-v2/packages/features/auth/src/components/oauth-providers.tsx

127 lines
3.4 KiB
TypeScript

'use client';
import { useCallback } from 'react';
import type { Provider } from '@supabase/supabase-js';
import { useSignInWithProvider } from '@kit/supabase/hooks/use-sign-in-with-provider';
import { If } from '@kit/ui/if';
import { LoadingOverlay } from '@kit/ui/loading-overlay';
import { Trans } from '@kit/ui/trans';
import { AuthErrorAlert } from './auth-error-alert';
import { AuthProviderButton } from './auth-provider-button';
export function OauthProviders(props: {
inviteToken?: string;
shouldCreateUser: boolean;
enabledProviders: Provider[];
paths: {
callback: string;
returnPath: string;
};
}) {
const signInWithProviderMutation = useSignInWithProvider();
// we make the UI "busy" until the next page is fully loaded
const loading = signInWithProviderMutation.isPending;
const onSignInWithProvider = useCallback(
async (signInRequest: () => Promise<unknown>) => {
const credential = await signInRequest();
if (!credential) {
return Promise.reject();
}
},
[],
);
const enabledProviders = props.enabledProviders;
if (!enabledProviders?.length) {
return null;
}
return (
<>
<If condition={loading}>
<LoadingOverlay />
</If>
<div className={'flex w-full flex-1 flex-col space-y-3'}>
<div className={'flex-col space-y-2'}>
{enabledProviders.map((provider) => {
return (
<AuthProviderButton
key={provider}
providerId={provider}
onClick={() => {
const origin = window.location.origin;
const queryParams = new URLSearchParams();
if (props.paths.returnPath) {
queryParams.set('next', props.paths.returnPath);
}
if (props.inviteToken) {
queryParams.set('invite_token', props.inviteToken);
}
const redirectPath = [
props.paths.callback,
queryParams.toString(),
].join('?');
const redirectTo = [origin, redirectPath].join('');
const scopesOpts =
provider === 'azure'
? {
scopes: 'email',
}
: {};
const credentials = {
provider,
options: {
shouldCreateUser: props.shouldCreateUser,
redirectTo,
...scopesOpts,
},
};
return onSignInWithProvider(() =>
signInWithProviderMutation.mutateAsync(credentials),
);
}}
>
<Trans
i18nKey={'auth:signInWithProvider'}
values={{
provider: getProviderName(provider),
}}
/>
</AuthProviderButton>
);
})}
</div>
<AuthErrorAlert error={signInWithProviderMutation.error} />
</div>
</>
);
}
function getProviderName(providerId: string) {
const capitalize = (value: string) =>
value.slice(0, 1).toUpperCase() + value.slice(1);
if (providerId.endsWith('.com')) {
return capitalize(providerId.split('.com')[0]!);
}
return capitalize(providerId);
}