Skip to content

Commit

Permalink
Merge pull request #92 from sparrowapp-dev/revamp-login-flow
Browse files Browse the repository at this point in the history
Revamp login flow
  • Loading branch information
Astitva877 authored Dec 17, 2024
2 parents d445a87 + 4024b43 commit 01926c0
Show file tree
Hide file tree
Showing 14 changed files with 1,170 additions and 531 deletions.
2 changes: 2 additions & 0 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import { onMount } from 'svelte';
import VerifyMagicCode from './pages/Auth/verify-magic-code/VerifyMagicCode.svelte';
import CoolDownPage from './pages/Auth/cool-down-page/CoolDownPage.svelte';
import PasswordLogin from './pages/Auth/password-login/PasswordLogin.svelte';
export let url = '/';
</script>
Expand All @@ -41,6 +42,7 @@
<!-- <Route path="/success" component={AuthSuccess} /> -->
<Route path="/verify-magic-code/:id" component={VerifyMagicCode} />
<Route path="/cool-down-active" component={CoolDownPage} />
<Route path="/password-login" component={PasswordLogin} />
<Route path="/*"><Navigate to="/init" /></Route>
</Router>
<Toast/>
Expand Down
4 changes: 2 additions & 2 deletions src/lib/utils/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ export const forgotPasswordSchema = yup.object().shape({
.required('Please enter an Email ID')
.matches(
emailRegex,
'Please enter a valid Email ID'
'Please enter a valid email address'
)
.required('Please enter a valid Email ID')
.required('Please enter a valid email address')
});

export const resetPasswordSchema = yup.object().shape({
Expand Down
5 changes: 3 additions & 2 deletions src/pages/Auth/cool-down-page/CoolDownPage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
let userFromDesktop = localStorage.getItem('isUserFromDesktop');
const sparrowRedirect = `sparrow://?accessToken=&refreshToken=&response=&event=login&method=email&isSparrowEdge=true`;
</script>

Expand Down Expand Up @@ -36,7 +37,7 @@
{#if userFromDesktop}
<div class="w-100 mb-5">

<Button
<Button onClick={() => navigate(sparrowRedirect)}
title={'Try Sparrow Edge'}
buttonClassProp={'w-100 align-items-center d-flex justify-content-center sparrow-fs-16'}
type={'primary'}/>
Expand Down
275 changes: 141 additions & 134 deletions src/pages/Auth/entry-point/EntryPoint.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
loadingMessage: 'Please wait while we are redirecting you to your email account....'
};
let entryLoader = false;
let isSubmitting = false; // Add this new state variable
let showContinueButton=false;
let isSubmitting = false; // Add this new state variable
let showContinueButton = false;
onMount(() => {
// Check the query parameters in the URL
const urlParams = new URLSearchParams(window.location.search);
Expand All @@ -54,21 +54,21 @@
isEmailTouched = true;
entryLoader = true;
showContinueButton=false;
showContinueButton = false;
emailExists = false; // Reset before the check starts
try {
const response = await handleEntry({ email }); // Reuse the same `handleEntry` function
if (response.isSuccessful) {
// Check if the email is registered
showContinueButton=true;
showContinueButton = true;
emailExists =
response?.data?.registeredWith === 'email' || response?.data?.registeredWith === 'google';
} else {
showContinueButton=false;
showContinueButton = false;
emailExists = false; // Email not registered
}
} catch (error) {
showContinueButton=false;
showContinueButton = false;
emailExists = false; // Handle errors gracefully
}
entryLoader = false;
Expand All @@ -78,7 +78,7 @@
try {
const magicCodeResponse = await sendMagicCodeEmail({ email });
if (magicCodeResponse.isSuccessful) {
navigate(`/verify-magic-code/${email}`); // Updated this line
navigate(`/verify-magic-code/${email}`); // Updated this line
} else {
if (magicCodeResponse?.message === 'Cooldown Active') {
navigate('/cool-down-active');
Expand All @@ -105,149 +105,156 @@
loadingMessage={redirectRules.loadingMessage}
/>
{:else} -->
<BgContainer>
<div class="d-flex align-items-start gap-2">
<div
class="text-white d-flex justify-content-center align-items-center bg-sparrowPrimaryColor"
style="height: 23px; width: 23px; border-radius: 6px;"
>
<img height="20px" width="20px" src={sparrowicon} alt="" class="" />
</div>
<p style="font-weight:500;">Sparrow</p>
<BgContainer>
<div class="d-flex align-items-start gap-2">
<div
class="text-white d-flex justify-content-center align-items-center bg-sparrowPrimaryColor"
style="height: 23px; width: 23px; border-radius: 6px;"
>
<img height="20px" width="20px" src={sparrowicon} alt="" class="" />
</div>
<p style="font-weight:500;">Sparrow</p>
</div>

<div style="display: flex ; flex-direction:column; align-items:center;">
<p
class="container-header sparrow-fw-600 text-whiteColor text-center ms-2 me-2 mb-1"
style="font-size:24px; font-weight: 400; padding-top:20px; line-height:28px; text-align:center;"
>
Welcome to Sparrow!
</p>
<p class="" style="color: lightGray; font-size:12px;">The only API Sidekick you need</p>
</div>
<div style="display: flex ; flex-direction:column; align-items:center;">
<p
class="container-header sparrow-fw-600 text-whiteColor text-center ms-2 me-2 mb-1"
style="font-size:24px; font-weight: 400; padding-top:20px; line-height:28px; text-align:center;"
>
Welcome to Sparrow!
</p>
<p class="" style="color: lightGray; font-size:12px;">The only API Sidekick you need</p>
</div>

<Oauth />
<Oauth />

<div class="divider w-100">
<span class="line"></span>
<span class="text" style="color:var(--editor-angle-bracket)">Or</span>
<span class="line"></span>
</div>
<div class="divider w-100">
<span class="line"></span>
<span class="text" style="color:var(--editor-angle-bracket)">Or</span>
<span class="line"></span>
</div>

<form
class="login-form w-100 text-whiteColor ps-1 pe-1 mb-2"
novalidate
on:submit|preventDefault={async () => {
isSubmitting = true;
isEmailTouched = true;
validationErrors = await handleEntryValidation(entryCredentials);
if (!validationErrors?.email) {
entryLoader = true;
const response = await handleEntry(entryCredentials);
if (response.isSuccessful) {
if (
response?.data?.registeredWith === 'email' ||
response?.data?.registeredWith === 'google'
) {
// Send magic code before redirecting
localStorage.setItem(`timer-verify-magic-code-${entryCredentials.email}`, new Date().getTime());
<form
class="login-form w-100 text-whiteColor ps-1 pe-1 mb-2"
novalidate
on:submit|preventDefault={async () => {
isSubmitting = true;
isEmailTouched = true;
validationErrors = await handleEntryValidation(entryCredentials);
if (!validationErrors?.email) {
entryLoader = true;
const response = await handleEntry(entryCredentials);
if (response.isSuccessful) {
if (
response?.data?.registeredWith === 'email' ||
response?.data?.registeredWith === 'google'
) {
// Send magic code before redirecting
localStorage.setItem(
`timer-verify-magic-code-${entryCredentials.email}`,
new Date().getTime()
);

await handleMagicCodeAndRedirect(entryCredentials?.email);
} else {
// New user - redirect to registration
navigate(`/register/${entryCredentials?.email}`);
}
await handleMagicCodeAndRedirect(entryCredentials?.email);
} else {
notifications.error(response?.message);
// New user - redirect to registration
navigate(`/register/${entryCredentials?.email}`);
}
entryLoader = false;
} else {
notifications.error(response?.message);
}
isSubmitting = false;
}}
>
<!-- <p class="card-subtitle sparrow-fs-20 sparrow-fw-500 mb-3">Sign In or Create an Account</p> -->
<div class="mb-3">
<label for="exampleInputEmail1" class="form-label text-Gray sparrow-fs-14 d-flex"
>Email ID
<p class="ms-1 mb-0 sparrow-fw-600 text-dangerColor">*</p></label
>

<div class="d-flex position-relative mt-1">
<input
type="email"
class="form-control pe-5 sparrow-fs-16 border:{validationErrors?.email && isEmailTouched
? '3px'
: '1px'} solid {validationErrors?.email && isEmailTouched
? 'border-error'
: 'border-default'}"
id="exampleInputEmail1"
aria-describedby="emailHelp"
placeholder="Enter your email addresss"
autocorrect="off"
autocapitalize="none"
autocomplete="off"
bind:value={entryCredentials.email}
on:blur={async () => {
isEmailTouched = true;
validationErrors = await handleEntryValidation(entryCredentials);
clearTimeout(checkTimeout);
checkTimeout = setTimeout(
() => checkEmailExistenceOnInput(entryCredentials.email),
1000
);
}}
on:input={async () => {
validationErrors = await handleEntryValidation(entryCredentials);
clearTimeout(checkTimeout);
checkTimeout = setTimeout(
() => checkEmailExistenceOnInput(entryCredentials.email),
1000
);
}}
/>
entryLoader = false;
}
isSubmitting = false;
}}
>
<!-- <p class="card-subtitle sparrow-fs-20 sparrow-fw-500 mb-3">Sign In or Create an Account</p> -->
<div class="mb-3">
<label for="exampleInputEmail1" class="form-label text-Gray sparrow-fs-14 d-flex"
>Email ID
<p class="ms-1 mb-0 sparrow-fw-600 text-dangerColor">*</p></label
>

<button
type="button"
on:click={() => {}}
class=" border-0 position-absolute eye-icon d-flex align-items-center"
>
{#if entryLoader}
<Spinner size={'16px'} />
{:else if emailExists}
<CircleTick height={'16px'} width={'16px'} />
{/if}
</button>
</div>
<div class="d-flex position-relative mt-1">
<input
type="email"
class="form-control pe-5 sparrow-fs-16 border:{validationErrors?.email && isEmailTouched
? '3px'
: '1px'} solid {validationErrors?.email && isEmailTouched
? 'border-error'
: 'border-default'}"
id="exampleInputEmail1"
aria-describedby="emailHelp"
placeholder="Enter your email addresss"
autocorrect="off"
autocapitalize="none"
autocomplete="off"
bind:value={entryCredentials.email}
on:blur={async () => {
isEmailTouched = true;
validationErrors = await handleEntryValidation(entryCredentials);
clearTimeout(checkTimeout);
checkTimeout = setTimeout(
() => checkEmailExistenceOnInput(entryCredentials.email),
1000
);
}}
on:input={async () => {
validationErrors = await handleEntryValidation(entryCredentials);
clearTimeout(checkTimeout);
checkTimeout = setTimeout(
() => checkEmailExistenceOnInput(entryCredentials.email),
1000
);
}}
/>

{#if validationErrors?.email && isEmailTouched}
<small class="form-text text-dangerColor"> {validationErrors?.email}</small>
{/if}
<button
type="button"
on:click={() => {}}
class=" border-0 position-absolute eye-icon d-flex align-items-center"
>
{#if entryLoader}
<Spinner size={'16px'} />
{:else if emailExists}
<CircleTick height={'16px'} width={'16px'} />
{/if}
</button>
</div>

<div>
<Button
disable={entryLoader || isSubmitting}
title={!emailExists && showContinueButton ? 'Continue' : 'Send magic code'}
buttonClassProp={'w-100 align-items-center d-flex justify-content-center sparrow-fs-16'}
type={'primary'}
/>
</div>
</form>
{#if validationErrors?.email && isEmailTouched}
<small class="form-text text-dangerColor"> {validationErrors?.email}</small>
{/if}
</div>

<div class="d-flex align-items-start ms-1">
<div style="height: 24px; width:24px;">
<AiSparkle height={'24px'} width={'24px'} />
</div>
<p class="text-center sparrow-fs-12 pt-1 mb-0" style="margin-left:-10px; color: #CCCCCCE5;">
We will email you a magic code for password free Sign in or you can <span
style="color:#3760F7; cursor:pointer;">continue with password</span
>
</p>
<div>
<Button
disable={entryLoader || isSubmitting}
title={!emailExists && showContinueButton ? 'Continue' : 'Send magic code'}
buttonClassProp={'w-100 align-items-center d-flex justify-content-center sparrow-fs-16'}
type={'primary'}
/>
</div>
<div style="margin-top: 24px;">
<SupportHelp />
</form>

<div class="d-flex align-items-start ms-1">
<div style="height: 24px; width:24px;">
<AiSparkle height={'24px'} width={'24px'} />
</div>
</BgContainer>
<p class="text-center sparrow-fs-12 pt-1 mb-0" style="margin-left:-10px; color: #CCCCCCE5;">
We will email you a magic code for password free Sign in or you can <span
on:click={() => {
navigate('/password-login');
}}
style="color:#3760F7; cursor:pointer;">continue with password</span
>
</p>
</div>
<div style="margin-top: 24px;">
<SupportHelp />
</div>
</BgContainer>

<!-- {/if} -->

<style>
Expand Down
Loading

0 comments on commit 01926c0

Please sign in to comment.