diff --git a/src/app/widget/login/components/EmailWidget.tsx b/src/app/widget/login/components/EmailWidget.tsx new file mode 100644 index 00000000..b36a31ee --- /dev/null +++ b/src/app/widget/login/components/EmailWidget.tsx @@ -0,0 +1,158 @@ +import React from 'react'; +import { Button } from '@/components/ui/Button'; +import { Input } from '@/components/ui/Input'; +import { + Card, + CardContent, + CardFooter, + CardHeader +} from '@/components/ui/card'; +import { getSocialLoginUrl } from '@/lib/utils'; +import { useOrgData } from '../widgetStore'; +import { ToastProps } from '@/components/ui/toast'; +import { useToast } from '@/components/ui/use-toast'; +import { + SocialLoginCollection, + SocialLoginLabel, + SocialLoginValue +} from '@/types/social-logins'; +import { Icons } from './icons'; +import { SocialLogin } from './SocialLogin'; +import { allSocialLogins } from './data'; +import { $TsFixMe } from '@/types'; +import { LoginMethodSeparator } from './LoginMethodSeparator'; +import Link from 'next/link'; +import Image from 'next/image'; + +interface EmailWidgetProps { + email: string; + setEmail: (NewPass: string) => void; + loading: boolean; + handleSubmit: (e: { preventDefault: () => void }) => Promise; +} + +const initiateSocialLogin = async ( + social: string, + orgToken: string, + toast?: (props: ToastProps) => void +): Promise => { + try { + const url = await getSocialLoginUrl({ provider: social, orgToken }); + window.location.href = url; + } catch (error: $TsFixMe) { + const message = `Social Login Failed: ${ + error?.message ?? 'Something Went Wrong' + }`; + toast?.({ + variant: 'destructive', + title: message + }); + } +}; + +// TODO: test email-login and social-login flow +export function EmailWidget({ + handleSubmit, + email, + setEmail, + loading +}: EmailWidgetProps) { + const { toast } = useToast(); + const orangizationData = useOrgData(state => state.data); + const organizationToken = useOrgData(state => state.org_token); + + const organizationLogoURL = orangizationData.widget.logo_url; + const organizationName = orangizationData.widget.name; + + //INFO: using filter because of lack of config typesaftey and data + const allowedSocialLogins = Object.keys(orangizationData.social) + .map(e => allSocialLogins[e as SocialLoginValue]) + .filter(e => e); + const isLoginWithEmailEnabled = orangizationData.email_val; + return ( + + + {'logo'} + + +
+

Sign in

+

+ to continue to{' '} + {organizationName} +

+
+
+ {allowedSocialLogins.map(item => { + const Icon = Icons[item.icon]; + return ( + + initiateSocialLogin(item.value, organizationToken, toast) + } + > + + Continue with {item.label} + + ); + })} +
+ {isLoginWithEmailEnabled && ( + <> + +
+ + setEmail(e.target.value)} + required + /> + +
+ + )} +
+ {/* Not handling pp and tnc because no response type available, `unknown` cannot be used. + Ref: https://github.com/One-Click-Auth/auth_frontend/pull/265#issuecomment-1912395385 + */} + +

+ By proceeding, I acknowledge and agree to abide by the terms outlined + in the  + + + Privacy Policy + + +  and{' '} + + + Terms & Conditions. + + +

+
+
+ ); +} diff --git a/src/app/widget/login/components/LoginMethodSeparator.tsx b/src/app/widget/login/components/LoginMethodSeparator.tsx new file mode 100644 index 00000000..d56bc80b --- /dev/null +++ b/src/app/widget/login/components/LoginMethodSeparator.tsx @@ -0,0 +1,11 @@ +import { Separator } from '@/components/ui/seperator'; + +export function LoginMethodSeparator() { + return ( +
+ + or + +
+ ); +} diff --git a/src/app/widget/login/components/SocialLogin.tsx b/src/app/widget/login/components/SocialLogin.tsx new file mode 100644 index 00000000..26286fec --- /dev/null +++ b/src/app/widget/login/components/SocialLogin.tsx @@ -0,0 +1,15 @@ +import { Button } from '@/components/ui/Button'; + +export function SocialLogin({ + onClick, + ...props +}: React.HTMLAttributes) { + return ( +