#1 feature/forgot-password-flow

Merged
kj merged 2 commits from feature/forgot-password-flow into master 4 years ago
  1. +4
    -0
      src/App.tsx
  2. +143
    -0
      src/commonStyles/loginFlow/LoginStyles.module.scss
  3. +43
    -30
      src/components/input/InputWidget.module.scss
  4. +6
    -2
      src/components/input/InputWidget.tsx
  5. +54
    -0
      src/pages/forgotPassword/EnterNewPassword.module.scss
  6. +58
    -0
      src/pages/forgotPassword/EnterOTP.module.scss
  7. +49
    -0
      src/pages/forgotPassword/ForgotPassword.module.scss
  8. +56
    -0
      src/pages/forgotPassword/enterNewPassword.tsx
  9. +72
    -0
      src/pages/forgotPassword/enterOTP.tsx
  10. +41
    -0
      src/pages/forgotPassword/forgotPassword.tsx
  11. +22
    -0
      src/pages/forgotPassword/forgotPasswordIndex.tsx
  12. +59
    -115
      src/pages/login/Login.module.scss
  13. +4
    -3
      src/pages/login/Login.tsx
  14. +346
    -349
      src/pages/signup/AdditionalQuestions.module.scss
  15. +137
    -136
      src/pages/signup/Signup.module.scss
  16. +21
    -15
      src/theme/variables.css

+ 4
- 0
src/App.tsx View File

@@ -4,6 +4,7 @@ import { IonReactRouter } from '@ionic/react-router';
import WelcomePage from './pages/onboarding/Welcome';
import LoginPage from './pages/login/Login';
import SignupPage from './pages/signup/Signup';
import ForgotPasswordIndex from './pages/forgotPassword/forgotPasswordIndex';

/* Core CSS required for Ionic components to work properly */
import '@ionic/react/css/core.css';
@@ -41,6 +42,9 @@ const App: React.FC = () => (
<Route exact path="/">
<Redirect to="/welcome" />
</Route>
<Route exact path="/forgotPassword">
<ForgotPasswordIndex />
</Route>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>


+ 143
- 0
src/commonStyles/loginFlow/LoginStyles.module.scss View File

@@ -0,0 +1,143 @@
.upfold {
background-color: var(--charcoal);
height: auto;
transform: translateY(-50vh);
width: 100%;
border-bottom-right-radius: 30px;
border-bottom-left-radius: 30px;
position: relative;
z-index: 1;
box-shadow: 0px 0px 10px 5px var(--black-rock);
animation: riseDown 1s forwards;
display: flex;
align-items: center;
justify-content: center;

.container {
padding: 20px 5%;
text-align: center;
}

h2 {
font-size: 26px;
color: var(--white);
margin: 10px 0;
}

p {
margin: 10px 0;
font-size: 14px;
color: var(--grey-rock);
}

figure {
display: block;
width: 100%;
margin: 10px 0;
animation: fadeIn 1s forwards;
opacity: 0;
transform: translateY(10vh);
}

img {
margin: 0 auto;
width: 50%;
display: block;
}

@keyframes riseDown {
from {
transform: translateY(-50vh);
}
to {
transform: translateY(0vh);
}
}
}

@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10vh);
}

to {
opacity: 1;
transform: translateY(0vh);
}
}

.margTopBtm20 {
margin: 20px 0;
}

.linkBtn {
&.greyLink {
color: var(--ash-dust);
}

&.whiteLink {
color: var(--ion-color-primary-contrast);
}

&.shamrockLink {
color: var(--shamrock);
}

&.shamrockBG {
background-color: var(--shamrock);
padding: 4px 6px;
border-radius: 10px;
}

&.fullWidth {
display: flex;
justify-content: center;
width: 100%;
}
}

.successToast {
--background: transparent;
--box-shadow: none;

.toast-wrapper {
background-color: red;
}

&::part(header) {
font-size: 16px;
font-weight: bold;
background: var(--white);
width: 175px;
padding: 10px 0;
height: auto;
text-align: center;
border-radius: 20px;
color: var(--shamrock);
position: relative;
top: 20px;
left: 20px;
box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.25);

&::before {
content: "\2713";
display: inline-block;
width: 20px;
height: 20px;
border-radius: 50%;
border: 4px solid var(--shamrock);
position: relative;
left: -20px;
}
}

&::part(message) {
padding: 30px 15px 12px;
background: var(--shamrock);
color: var(--white);
font-size: 12px;
border-radius: 20px;
box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.25);
}
}

+ 43
- 30
src/components/input/InputWidget.module.scss View File

@@ -1,34 +1,47 @@
.inputHolder {
background-color: white;
box-shadow: 0px 0px 5px inset var(--grey-rock);
border-radius: 30px;
display: flex;
align-items: center;
justify-content: flex-start;
height: 50px;
padding: 0px 20px;
background-color: var(--white);
box-shadow: 0px 0px 5px inset var(--grey-rock);
border-radius: 30px;
display: flex;
align-items: center;
justify-content: flex-start;
height: 50px;
padding: 0px 20px;

.leftIcon {
font-size: 16px;
color: var(--grey-rock);
}
.leftIcon {
font-size: 16px;
color: var(--grey-rock);
}

input {
background-color: transparent;
border: none;
font-size: 15px;
outline: none;
padding: 0 10px;
width: calc(100% - 60px);
color: var(--black-rock);
}
input {
background-color: transparent;
border: none;
font-size: 15px;
outline: none;
padding: 0 10px;
width: calc(100% - 60px);
color: var(--black-rock);
}

.eyeButton {
margin: 0;
--color: var(--grey-rock);
--background: transparent;
--box-shadow: none;
margin-left: auto;
font-size: 16px;
}
}
.eyeButton {
margin: 0;
--color: var(--grey-rock);
--background: transparent;
--box-shadow: none;
margin-left: auto;
font-size: 16px;
}
}

.rounded {
width: 60px;
height: 60px;
border-radius: 50%;

input {
width: 100%;
text-align: center;
padding: 0;
font-size: 18px;
}
}

+ 6
- 2
src/components/input/InputWidget.tsx View File

@@ -6,14 +6,17 @@ import styles from './InputWidget.module.scss';
type Props = {
icon?: string,
placeholder?: string,
type: 'TEXT' | 'PASSWORD' | 'PHONE';
type: 'TEXT' | 'PASSWORD' | 'PHONE' | 'NUMBER';
hideEye?: boolean
displayType?: string
autoTabHandler?: any
maxlength?: number
};

const InputWidget: React.FC<Props> = (props) => {
let [showPassword, toggleEye] = useState(false);

return (<section className={styles.inputHolder}>
return (<section className={`${styles.inputHolder} ${props.displayType? styles.rounded : ''}`} >
{ props.icon && <IonIcon className={styles.leftIcon} icon={props.icon}></IonIcon> }
{ props.type === 'TEXT' && <input type='text' placeholder={props.placeholder} /> }
@@ -27,6 +30,7 @@ const InputWidget: React.FC<Props> = (props) => {
{ !showPassword && <IonIcon icon={eyeOutline}></IonIcon> }
</IonButton>
}
{ props.type === 'NUMBER' && <input type="number" maxLength={props.maxlength} placeholder={props.placeholder} pattern="[0-9]?" onKeyUp={props.autoTabHandler} /> }
</section>);
};



+ 54
- 0
src/pages/forgotPassword/EnterNewPassword.module.scss View File

@@ -0,0 +1,54 @@
.inputForm {
width: 75%;
margin: 40px auto 0;
opacity: 0;
transform: translateY(10vh);
position: relative;
animation: fadeIn 1s forwards;

.input {
margin: 20px 0;
}

.otpInput {
display: flex;
justify-content: space-between;
}

.actionButtonsHolder {
width: 60%;
margin: 20px auto;

.actionButton {
height: 50px;
text-transform: none;
font-size: 16px;
--border-radius: 30px;
--border-color: var(--shamrock);
font-weight: 500;

&:nth-child(1) {
--background: var(--shamrock);
}
}
}

.info {
font-size: 14px;
text-align: center;
color: var(--ash);
margin: 40px 0;
}
}

@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10vh);
}

to {
opacity: 1;
transform: translateY(0vh);
}
}

+ 58
- 0
src/pages/forgotPassword/EnterOTP.module.scss View File

@@ -0,0 +1,58 @@
.inputForm {
width: 75%;
margin: 40px auto 0;
opacity: 0;
transform: translateY(10vh);
position: relative;
animation: fadeIn 1s forwards;

.input {
margin: 20px 0;
}

.otpInput {
display: flex;
justify-content: space-between;
}

.actionButtonsHolder {
width: 60%;
margin: 20px auto;

.actionButton {
height: 50px;
text-transform: none;
font-size: 16px;
--border-radius: 30px;
--border-color: var(--shamrock);
font-weight: 500;

&:nth-child(1) {
--background: var(--shamrock);
}

&.disabled {
--background: var(--ash-dust);
}
}
}

.info {
font-size: 14px;
text-align: center;
color: var(--grey-rock);
margin: 40px 0;
}
}

@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10vh);
}

to {
opacity: 1;
transform: translateY(0vh);
}
}

+ 49
- 0
src/pages/forgotPassword/ForgotPassword.module.scss View File

@@ -0,0 +1,49 @@
.inputForm {
width: 80%;
margin: 40px auto 0;
opacity: 0;
transform: translateY(10vh);
position: relative;
animation: fadeIn 1s forwards;

.input {
margin: 20px 0;
}

.actionButtonsHolder {
width: 60%;
margin: 20px auto;

.actionButton {
height: 50px;
text-transform: none;
font-size: 16px;
--border-radius: 30px;
--border-color: var(--shamrock);
font-weight: 500;

&:nth-child(1) {
--background: var(--shamrock);
}
}
}

.info {
font-size: 14px;
text-align: center;
color: var(--grey-rock);
margin: 40px 0;
}
}

@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10vh);
}

to {
opacity: 1;
transform: translateY(0vh);
}
}

+ 56
- 0
src/pages/forgotPassword/enterNewPassword.tsx View File

@@ -0,0 +1,56 @@
import { IonContent, IonButton, IonToast } from '@ionic/react';
import { lockOpenOutline } from 'ionicons/icons';
import React, { useState } from 'react';
import InputWidget from '../../components/input/InputWidget';
import styles from './EnterOTP.module.scss';
import loginStyles from '../../commonStyles/loginFlow/LoginStyles.module.scss';



type Props = { };

const EnterOTPView: React.FC<Props> = () => {

const [successState, setSuccessState] = useState(false);

return(
<IonContent>
<section className={loginStyles.upfold}>
<div className={loginStyles.container}>
<figure>
<img src='assets/images/welcome/upfold.svg' alt='upfold image'/>
</figure>
<h2> Enter New Password </h2>
<p>Your password must be at least 6 characters.</p>
</div>
</section>
<section className={styles.inputForm}>
<div className={styles.input}>
<InputWidget type={'PASSWORD'} icon={lockOpenOutline} placeholder={'Enter your new password'} />
</div>
<div className={styles.input}>
<InputWidget type={'PASSWORD'} icon={lockOpenOutline} placeholder={'Confirm new password'} />
</div>
<div className={styles.info}>
<p>(i) Do not enter any of the old passwords, system will reject the repeated passwords.</p>
</div>
<div className={styles.actionButtonsHolder}>
<IonButton className={`${styles.actionButton}`} expand='block' onClick={()=>setSuccessState(true)}> Change </IonButton>
<IonToast
isOpen={successState}
onDidDismiss={() => setSuccessState(false)}
header= 'Success!'
message="You have successfully changed your password. Please use your newly set password"
// duration={2000}
cssClass={loginStyles.successToast}
/>
</div>
</section>
</IonContent>

)

}

export default EnterOTPView;

+ 72
- 0
src/pages/forgotPassword/enterOTP.tsx View File

@@ -0,0 +1,72 @@
import { IonContent, IonButton } from '@ionic/react';
import React, { useState } from 'react';
import InputWidget from '../../components/input/InputWidget';
import styles from './EnterOTP.module.scss';
import loginStyles from '../../commonStyles/loginFlow/LoginStyles.module.scss';



type Props = {
changeStep:any,
forgotPasswordStep:string
};

const EnterOTPView: React.FC<Props> = (props) => {

const [disableSubmitBtn, updateBtnState] = useState(true)

const autoTab = (event:any) => {
const { maxLength, value } = event.target;
if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >=96 && event.keyCode <= 105)){ /* check number keyCode */
if(value.length == maxLength){
const nextField = event.target.parentElement.nextElementSibling?.querySelector('input')
if (nextField !== null) {
nextField?.focus();
nextField?.select(); // temporary usage to restrict 1 input value; could be changed once form validations are added
}
}
}

if(disableSubmitBtn){
updateBtnState(false)
}
}
return(
<IonContent>
<section className={loginStyles.upfold}>
<div className={loginStyles.container}>
<figure>
<img src='assets/images/welcome/upfold.svg' alt='upfold image'/>
</figure>
<h2> Enter OTP </h2>
<p>Please enter the OTP that has been sent to </p>
<p>angelashelton@email.com <button className={`${loginStyles.linkBtn} ${loginStyles.whiteLink} ${loginStyles.shamrockBG}`}> change </button></p>
</div>
</section>
<section className={styles.inputForm}>
<div className={`${styles.input} ${styles.otpInput}`}>
<InputWidget autoTabHandler={autoTab} type={'NUMBER'} maxlength={1} displayType="rounded" />
<InputWidget autoTabHandler={autoTab} type={'NUMBER'} maxlength={1} displayType="rounded" />
<InputWidget autoTabHandler={autoTab} type={'NUMBER'} maxlength={1} displayType="rounded" />
<InputWidget autoTabHandler={autoTab} type={'NUMBER'} maxlength={1} displayType="rounded" />
</div>
<div className={styles.info}>
<p>Enter the 4 digit OTP which you received in your mobile</p>
</div>
<div className={styles.actionButtonsHolder}>
<IonButton className={`${styles.actionButton} ${disableSubmitBtn ? styles.disabled : ''}`} expand='block' onClick={()=>props.changeStep('NEWPASSWORD')} disabled={disableSubmitBtn}> Submit </IonButton>
<a className={`${loginStyles.linkBtn} ${loginStyles.shamrockLink} ${loginStyles.fullWidth} ${loginStyles.margTopBtm20} `} > Resend OTP </a>
</div>
</section>
</IonContent>

)

}

export default EnterOTPView;

+ 41
- 0
src/pages/forgotPassword/forgotPassword.tsx View File

@@ -0,0 +1,41 @@
import { IonContent, IonPage, IonButton } from '@ionic/react';
import { mailOpenOutline } from 'ionicons/icons';
import React from 'react';
import InputWidget from '../../components/input/InputWidget';
import styles from './ForgotPassword.module.scss';
import loginStyles from '../../commonStyles/loginFlow/LoginStyles.module.scss';

type Props = {
changeStep:any,
forgotPasswordStep:string
};

const ForgotPasswordPage: React.FC<Props> = (props) => {
return (
<IonContent fullscreen>
<section className={loginStyles.upfold}>
<div className={loginStyles.container}>
<figure>
<img src='assets/images/welcome/upfold.svg' alt='upfold image'/>
</figure>
<h2> Forgot your Password? </h2>
<p> Lorem Ipsum is simply dummy text of the printing and typesetting </p>
</div>
</section>
<section className={styles.inputForm}>
<div className={styles.input}>
<InputWidget type={'TEXT'} icon={mailOpenOutline} placeholder={'Email'} />
</div>
<div className={ styles.info }>
Enter your registered email address to reset password through the OTP
</div>

<div className={styles.actionButtonsHolder}>
<IonButton className={styles.actionButton} onClick={()=>props.changeStep('OTP')} expand='block'> Send OTP </IonButton>
</div>
</section>
</IonContent>
)
}

export default ForgotPasswordPage;

+ 22
- 0
src/pages/forgotPassword/forgotPasswordIndex.tsx View File

@@ -0,0 +1,22 @@
import { IonPage } from '@ionic/react';
import React, { useState } from 'react';

import ForgotPasswordPage from './forgotPassword';
import EnterOTPView from './enterOTP';
import EnterNewPasswordView from './enterNewPassword';


type Props = { };

const ForgotPasswordIndex: React.FC<Props> = () => {
let [forgotPasswordStep, changeStep] = useState('INIT');
return(
<IonPage>
{ forgotPasswordStep === 'INIT' && <ForgotPasswordPage forgotPasswordStep={forgotPasswordStep} changeStep={changeStep}/>}
{ forgotPasswordStep === 'OTP' && <EnterOTPView forgotPasswordStep={forgotPasswordStep} changeStep={changeStep}/>}
{ forgotPasswordStep === 'NEWPASSWORD' && <EnterNewPasswordView />}
</IonPage>
)
}
export default ForgotPasswordIndex;

+ 59
- 115
src/pages/login/Login.module.scss View File

@@ -1,125 +1,69 @@
.upfold {
background-color: var(--charcoal);
height: auto;
transform: translateY(-50vh);
width: 100%;
border-bottom-right-radius: 30px;
border-bottom-left-radius: 30px;
position: relative;
z-index: 1;
box-shadow: 0px 0px 10px 5px var(--black-rock);
animation: riseDown 1s forwards;
display: flex;
align-items: center;
justify-content: center;

.container {
padding: 20px 5%;
text-align: center;
}

h2 {
font-size: 26px;
color: white;
margin: 10px 0;
}

p {
margin: 10px 0;
font-size: 14px;
color: var(--grey-rock);
}

figure {
display: block;
width: 100%;
margin: 10px 0;
animation: fadeIn 1s forwards;
opacity: 0;
transform: translateY(10vh);
}

img {
margin: 0 auto;
width: 50%;
display: block;
}

@keyframes riseDown {
from {
transform: translateY(-50vh);
}
to {
transform: translateY(0vh);
}
}
}

.inputForm {
width: 80%;
margin: 40px auto 0;
opacity: 0;
transform: translateY(10vh);
position: relative;
animation: fadeIn 1s forwards;

.input {
margin: 20px 0;
width: 80%;
margin: 40px auto 0;
opacity: 0;
transform: translateY(10vh);
position: relative;
animation: fadeIn 1s forwards;

.input {
margin: 20px 0;
}

.actionLink {
text-align: right;
margin: 20px 0;

a {
font-size: 14px;
color: var(--rock);
text-decoration: none;
}

.actionLink {
text-align: right;
margin: 20px 0;

a {
font-size: 14px;
color: var(--rock);
text-decoration: none;
}
}

.actionButtonsHolder {
width: 60%;
margin: 20px auto;

.actionButton {
height: 50px;
text-transform: none;
font-size: 16px;
--border-radius: 30px;
--border-color: var(--shamrock);
font-weight: 500;

&:nth-child(1) {
--background: var(--shamrock);
}
}

.actionButtonsHolder {
width: 60%;
margin: 20px auto;

.actionButton {
height: 50px;
text-transform: none;
font-size: 16px;
--border-radius: 30px;
--border-color: var(--shamrock);
font-weight: 500;

&:nth-child(1) {
--background: var(--shamrock);
}
}
}
}
}

.navigationLink {
position: absolute;
left: 0;
width: 100%;
bottom: 10px;
text-align: center;
font-size: 14px;
color: var(--rock);

a, span {
color: var(--shamrock);
text-decoration: none;
}
position: absolute;
left: 0;
width: 100%;
bottom: 10px;
text-align: center;
font-size: 14px;
color: var(--rock);

a,
span {
color: var(--shamrock);
text-decoration: none;
}
}

@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10vh);
}
from {
opacity: 0;
transform: translateY(10vh);
}

to {
opacity: 1;
transform: translateY(0vh);
}
}
to {
opacity: 1;
transform: translateY(0vh);
}
}

+ 4
- 3
src/pages/login/Login.tsx View File

@@ -3,6 +3,7 @@ import { personOutline, lockOpenOutline } from 'ionicons/icons';
import React from 'react';
import InputWidget from '../../components/input/InputWidget';
import styles from './Login.module.scss';
import loginStyles from '../../commonStyles/loginFlow/LoginStyles.module.scss';
import { Link } from "react-router-dom";

type Props = { };
@@ -11,8 +12,8 @@ const LoginPage: React.FC<Props> = () => {
return (
<IonPage>
<IonContent fullscreen>
<section className={styles.upfold}>
<div className={styles.container}>
<section className={loginStyles.upfold}>
<div className={loginStyles.container}>
<figure>
<img src='assets/images/welcome/upfold.svg' alt='upfold image'/>
</figure>
@@ -29,7 +30,7 @@ const LoginPage: React.FC<Props> = () => {
<InputWidget type={'PASSWORD'} icon={lockOpenOutline} placeholder={'Password'} />
</div>

<div className={ styles.actionLink }> <a> Forgot Password? </a> </div>
<div className={ styles.actionLink }> <Link to='/forgotPassword'> <span> Forgot Password? </span> </Link> </div>

<div className={styles.actionButtonsHolder}>
<IonButton className={styles.actionButton} expand='block'> Login </IonButton>


+ 346
- 349
src/pages/signup/AdditionalQuestions.module.scss View File

@@ -1,386 +1,383 @@
.slidersNavBar {
height: 60px;
display: flex;
align-items: center;
justify-content: center;

h4 {
width: 60%;
text-align: right;
font-size: 24px;
color: var(--charcoal);

span {
font-size: 18px;
font-weight: 400;
color: var(--ash);
}
height: 60px;
display: flex;
align-items: center;
justify-content: center;

h4 {
width: 60%;
text-align: right;
font-size: 24px;
color: var(--charcoal);

span {
font-size: 18px;
font-weight: 400;
color: var(--ash);
}
}

ion-button {
--background: transparent;
--color: var(--ash);
--box-shadow: none;
font-size: 14px;
margin-left: auto;
margin-right: 5%;

ion-icon {
font-size: 16px;
margin-left: 5px;
transform: translateY(2px);
}
ion-button {
--background: transparent;
--color: var(--ash);
--box-shadow: none;
font-size: 14px;
margin-left: auto;
margin-right: 5%;

ion-icon {
font-size: 16px;
margin-left: 5px;
transform: translateY(2px);
}
}
}

.slides {
width: 100%;
margin-top: 20px;
overflow: hidden;
height: calc(100vh - 60px - 20px);
ion-slide {
text-align: left;
display: block;
width: 100%;
margin-top: 20px;
overflow: hidden;
height: calc(100vh - 60px - 20px);

ion-slide {
text-align: left;
display: block;
}

.questionContainer {
height: 35%;
position: relative;
padding: 0 7%;

.question {
word-spacing: 1px;
font-size: 28px;
font-weight: 400;
color: var(--charcoal);
}

.questionContainer {
height: 35%;
position: relative;
padding: 0 7%;

.question {
word-spacing: 1px;
font-size: 28px;
font-weight: 400;
color: var(--charcoal);
}

.hint {
position: absolute;
bottom: 40px;
left: 7%;
font-size: 14px;
color: var(--grey-rock);
}
.hint {
position: absolute;
bottom: 40px;
left: 7%;
font-size: 14px;
color: var(--grey-rock);
}
}

.choiceContainer {
height: 65%;
background-color: var(--dark-charcoal);
padding: 40px 7%;
border-top-left-radius: 35px;
border-top-right-radius: 35px;
.optionButtons button {
width: 100%;
text-align: left;
outline: none;
padding: 0 30px;
display: block;
background-color: var(--charcoal);
box-shadow: 0px 0px 10px black;
border-radius: 10px;
height: 55px;
font-size: 16px;
color: var(--grey-rock);
margin-bottom: 30px;
transition: box-shadow 0.3s, color 0.3s;

&.optionButton {
color: white;
padding-right: 15px;
}

&.active {
color: white;
box-shadow: 0px 0px 10px 1px var(--shamrock);

ion-icon.checkmark {
opacity: 1;
}
}

ion-icon {
font-size: 20px;
vertical-align: middle;
transition: opacity 0.3s;
&.leftIcon {
margin-right: 15px;
}

&.checkmark {
opacity: 0;
float: right;
}

&.option {
float: right;
}

&.sectorIcon {
margin-right: 10px;
}
}
.choiceContainer {
height: 65%;
background-color: var(--dark-charcoal);
padding: 40px 7%;
border-top-left-radius: 35px;
border-top-right-radius: 35px;

.optionButtons button {
width: 100%;
text-align: left;
outline: none;
padding: 0 30px;
display: block;
background-color: var(--charcoal);
box-shadow: 0px 0px 10px black;
border-radius: 10px;
height: 55px;
font-size: 16px;
color: var(--grey-rock);
margin-bottom: 30px;
transition: box-shadow 0.3s, color 0.3s;

&.optionButton {
color: var(--white);
padding-right: 15px;
}

&.active {
color: var(--white);
box-shadow: 0px 0px 10px 1px var(--shamrock);

ion-icon.checkmark {
opacity: 1;
}
}

ion-icon {
font-size: 20px;
vertical-align: middle;
transition: opacity 0.3s;

ion-range {
--bar-height: 5px;
--bar-background: var(--black-rock);
--bar-background-active: var(--shamrock);
--knob-size: 20px;
--bar-border-radius: 30px;
&.leftIcon {
margin-right: 15px;
}

p {
text-align: center;
font-size: 30px;
color: var(--ash);
font-weight: 600;
letter-spacing: 1px;
&.checkmark {
opacity: 0;
float: right;
}

.modules {
list-style: none;
width: 100%;
position: relative;
text-align: center;
position: relative;
align-items: center;
justify-content: center;
display: grid;
grid-row-gap: 20px;
grid-column-gap: 10px;
margin: 0;
padding: 0;

li:nth-of-type(1) {
grid-column: 1;
}
li:nth-of-type(2) {
grid-column: 2;
}
li:nth-of-type(3) {
grid-column: 3;
}
li:nth-of-type(4) {
grid-column: 4;
}
li:nth-of-type(5) {
grid-column: 1 / span 2;
grid-row: 2;
}

li:nth-of-type(6) {
grid-column: 1 / span 5;
grid-row: 2;
}

li:nth-of-type(7) {
grid-column: 3 / span 3;
grid-row: 2;
}

li:nth-of-type(8) {
grid-column: 2;
}

li:nth-of-type(9) {
grid-column: 3;
}
button {
width: 18vw;
height: 18vw;
border-radius: 50%;
font-size: 10px;
display: inline-block;
outline: none;
background-color: var(--ash-dust);
color: var(--black-rock);
border: 2px solid var(--ash-dust);
transition: border-color 0.3s;

&.active {
border-color: var(--shamrock);
box-shadow: 0px 0px 10px 0px var(--shamrock);
}
}

ion-icon {
display: block;
margin: 0 auto 5px;
font-size: 24px;
}
&.option {
float: right;
}
.profileImages {
display: flex;
width: 100vw;
list-style: none;
height: 100%;
left: -7%;
position: relative;
overflow-y: hidden;
overflow-x: auto;
justify-content: flex-start;
flex-direction: column;
flex-wrap: wrap;
padding: 20px 0;
button {
margin: 0 auto;
display: block;
width: 19vw;
height: 19vw;
border-radius: 50%;
font-size: 10px;
outline: none;
background-color: var(--ash-dust);
color: var(--black-rock);
border: 0px solid var(--ash-dust);
transition: border-color 0.3s, border-width 0.3s;
margin: 10px;

&.active {
border-color: var(--shamrock);
border-width: 2px;
box-shadow: 0px 0px 10px 0px var(--shamrock);
}

&.upload {
background-color: transparent;
border-color: var(--shamrock);
border-width: 2px;
font-size: 12px;
color: var(--shamrock);

ion-icon {
width: 30px;
height: 30px;
font-size: 20px;
display: block;
margin: 0 auto;
}
}
}

ion-icon {
width: 100%;
height: 100%;
}

&.sectorIcon {
margin-right: 10px;
}
}
}
}

ion-range {
--bar-height: 5px;
--bar-background: var(--black-rock);
--bar-background-active: var(--shamrock);
--knob-size: 20px;
--bar-border-radius: 30px;
}

.nextButton {
position: fixed;
bottom: 5%;
right: 7%;
z-index: 1;
width: 150px;
height: 60px;
--border-radius: 30px;
--box-shadow: none;
--background: var(--shamrock);
--color: white;
font-size: 18px;
filter: grayscale(0%);
transition: filter 0.3s;
p {
text-align: center;
font-size: 30px;
color: var(--ash);
font-weight: 600;
letter-spacing: 1px;
}

transition: opacity 0.3;
.modules {
list-style: none;
width: 100%;
position: relative;
text-align: center;
position: relative;
align-items: center;
justify-content: center;
display: grid;
grid-row-gap: 20px;
grid-column-gap: 10px;
margin: 0;
padding: 0;

li:nth-of-type(1) {
grid-column: 1;
}

li:nth-of-type(2) {
grid-column: 2;
}

li:nth-of-type(3) {
grid-column: 3;
}

li:nth-of-type(4) {
grid-column: 4;
}

li:nth-of-type(5) {
grid-column: 1 / span 2;
grid-row: 2;
}

li:nth-of-type(6) {
grid-column: 1 / span 5;
grid-row: 2;
}

li:nth-of-type(7) {
grid-column: 3 / span 3;
grid-row: 2;
}

li:nth-of-type(8) {
grid-column: 2;
}

li:nth-of-type(9) {
grid-column: 3;
}

button {
width: 18vw;
height: 18vw;
border-radius: 50%;
font-size: 10px;
display: inline-block;
outline: none;
background-color: var(--ash-dust);
color: var(--black-rock);
border: 2px solid var(--ash-dust);
transition: border-color 0.3s;

&.active {
border-color: var(--shamrock);
box-shadow: 0px 0px 10px 0px var(--shamrock);
}
}

&.inactive {
pointer-events: none;
filter: grayscale(100%);
ion-icon {
display: block;
margin: 0 auto 5px;
font-size: 24px;
}
}

ion-icon {
font-size: 18px;
margin-left: 10px;
.profileImages {
display: flex;
width: 100vw;
list-style: none;
height: 100%;
left: -7%;
position: relative;
overflow-y: hidden;
overflow-x: auto;
justify-content: flex-start;
flex-direction: column;
flex-wrap: wrap;
padding: 20px 0;

button {
margin: 0 auto;
display: block;
width: 19vw;
height: 19vw;
border-radius: 50%;
font-size: 10px;
outline: none;
background-color: var(--ash-dust);
color: var(--black-rock);
border: 0px solid var(--ash-dust);
transition: border-color 0.3s, border-width 0.3s;
margin: 10px;

&.active {
border-color: var(--shamrock);
border-width: 2px;
box-shadow: 0px 0px 10px 0px var(--shamrock);
}

&.upload {
background-color: transparent;
border-color: var(--shamrock);
border-width: 2px;
font-size: 12px;
color: var(--shamrock);

ion-icon {
width: 30px;
height: 30px;
font-size: 20px;
display: block;
margin: 0 auto;
}
}
}

ion-icon {
width: 100%;
height: 100%;
}
}
}
}

.prevButton {
position: fixed;
bottom: 5%;
left: 7%;
z-index: 1;
width: 60px;
height: 60px;
--border-color: var(--rock);
--color: var(--rock);
--background: var(--charcoal);
--border-radius: 50%;
--border-width: 2px;
transition: opacity 0.3;

&.inactive {
pointer-events: none;
opacity: 0;
}
.nextButton {
position: fixed;
bottom: 5%;
right: 7%;
z-index: 1;
width: 150px;
height: 60px;
--border-radius: 30px;
--box-shadow: none;
--background: var(--shamrock);
--color: var(--white);
font-size: 18px;
filter: grayscale(0%);
transition: filter 0.3s;

transition: opacity 0.3;

&.inactive {
pointer-events: none;
filter: grayscale(100%);
}

ion-icon {
font-size: 18px;
margin-left: 10px;
}
}

ion-icon {
opacity: 0.4;
transform: rotateY(180deg);
}
.prevButton {
position: fixed;
bottom: 5%;
left: 7%;
z-index: 1;
width: 60px;
height: 60px;
--border-color: var(--rock);
--color: var(--rock);
--background: var(--charcoal);
--border-radius: 50%;
--border-width: 2px;
transition: opacity 0.3;

&.inactive {
pointer-events: none;
opacity: 0;
}

ion-icon {
opacity: 0.4;
transform: rotateY(180deg);
}
}

.picker {
position: fixed;
left: 0;
top: 0;
z-index: 1;
position: fixed;
left: 0;
top: 0;
z-index: 1;
width: 100%;
height: 100vh;
background-color: var(--dark-charcoal);
display: flex;
align-items: center;
justify-content: center;

.container {
width: 100%;
height: 100vh;
background-color: var(--dark-charcoal);
display: flex;
align-items: center;
justify-content: center;

.container {
width: 100%;
height: 90%;
overflow: auto;
padding: 10% 0;

ul {
list-style: none;
padding: 0;
margin: 0;
color: white;
width: 100%;
display: block;
}
height: 90%;
overflow: auto;
padding: 10% 0;

ul {
list-style: none;
padding: 0;
margin: 0;
color: var(--white);
width: 100%;
display: block;
}

li {
height: 60px;
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 10%;
font-size: 14px;
opacity: 0.5;
transition: box-shadow 0.3s, opacity 0.3s;

&.active {
box-shadow: 0px 0px 10px black;
opacity: 1;
}

ion-icon {
font-size: 20px;
margin-right: 20px;
}
}
li {
height: 60px;
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 10%;
font-size: 14px;
opacity: 0.5;
transition: box-shadow 0.3s, opacity 0.3s;

&.active {
box-shadow: 0px 0px 10px black;
opacity: 1;
}

ion-icon {
font-size: 20px;
margin-right: 20px;
}
}
}
}
}

+ 137
- 136
src/pages/signup/Signup.module.scss View File

@@ -1,159 +1,160 @@
.upfold {
background-color: var(--charcoal);
height: auto;
transform: translateY(-50vh);
width: 100%;
border-bottom-right-radius: 30px;
border-bottom-left-radius: 30px;
position: relative;
z-index: 1;
box-shadow: 0px 0px 10px 5px var(--black-rock);
animation: riseDown 1s forwards;
display: flex;
align-items: center;
justify-content: center;
.container {
padding: 30px 5%;
text-align: center;
}
background-color: var(--charcoal);
height: auto;
transform: translateY(-50vh);
width: 100%;
border-bottom-right-radius: 30px;
border-bottom-left-radius: 30px;
position: relative;
z-index: 1;
box-shadow: 0px 0px 10px 5px var(--black-rock);
animation: riseDown 1s forwards;
display: flex;
align-items: center;
justify-content: center;
.container {
padding: 30px 5%;
text-align: center;
}

h2 {
font-size: 26px;
color: white;
}
h2 {
font-size: 26px;
color: var(--white);
}

p {
font-size: 14px;
color: var(--grey-rock);
}
p {
font-size: 14px;
color: var(--grey-rock);
}

figure {
position: absolute;
left: 0;
top: 0;
z-index: 0;
display: block;
width: 100%;
height: 100%;
margin: 10px 0;
animation: fadeIn 1s forwards;
opacity: 0;
transform: translateY(10vh);
}

figure {
position: absolute;
left: 0;
top: 0;
z-index: 0;
display: block;
width: 100%;
height: 100%;
margin: 10px 0;
animation: fadeIn 1s forwards;
opacity: 0;
transform: translateY(10vh);
}
img {
margin: 5px auto 0;
width: 70%;
display: block;
}

img {
margin: 5px auto 0;
width: 70%;
display: block;
@keyframes riseDown {
from {
transform: translateY(-50vh);
}

@keyframes riseDown {
from {
transform: translateY(-50vh);
}
to {
transform: translateY(0vh);
}
to {
transform: translateY(0vh);
}
}
}

.inputForm {
width: 80%;
margin: 40px auto 0;
opacity: 0;
transform: translateY(10vh);
position: relative;
animation: fadeIn 1s forwards;

.confirmationAction {
padding: 10px;
display: flex;
align-items: center;
justify-content: space-between;
overflow: visible;

label {
margin: 0;
font-size: 14px;
text-align: left;
color: var(--rock);
}

.toggle {
contain: none;
--handle-background: var(--apricot);
--handle-background-checked: var(--shamrock);
--background: var(--ash-dust);
--background-checked: var(--ash-dust);
}
width: 80%;
margin: 40px auto 0;
opacity: 0;
transform: translateY(10vh);
position: relative;
animation: fadeIn 1s forwards;

.confirmationAction {
padding: 10px;
display: flex;
align-items: center;
justify-content: space-between;
overflow: visible;

label {
margin: 0;
font-size: 14px;
text-align: left;
color: var(--rock);
}

.separator {
display: block;
width: 100%;
height: 0px;
overflow: visible;
margin: 40px 0;
border-bottom: 1px dashed var(--ash);
border-width: 2px;
.toggle {
contain: none;
--handle-background: var(--apricot);
--handle-background-checked: var(--shamrock);
--background: var(--ash-dust);
--background-checked: var(--ash-dust);
}
}

.input {
margin: 20px 0;
.separator {
display: block;
width: 100%;
height: 0px;
overflow: visible;
margin: 40px 0;
border-bottom: 1px dashed var(--ash);
border-width: 2px;
}

.input {
margin: 20px 0;
}

.actionLink {
text-align: right;
margin: 20px 0;

span {
font-size: 14px;
color: var(--rock);
text-decoration: none;
}

.actionLink {
text-align: right;
margin: 20px 0;

span {
font-size: 14px;
color: var(--rock);
text-decoration: none;
}
}

.actionButtonsHolder {
width: 60%;
margin: 20px auto;

.actionButton {
height: 50px;
text-transform: none;
font-size: 16px;
--border-radius: 30px;
--border-color: var(--shamrock);
font-weight: 500;

&:nth-child(1) {
--background: var(--shamrock);
}
}

.actionButtonsHolder {
width: 60%;
margin: 20px auto;

.actionButton {
height: 50px;
text-transform: none;
font-size: 16px;
--border-radius: 30px;
--border-color: var(--shamrock);
font-weight: 500;

&:nth-child(1) {
--background: var(--shamrock);
}
}
}
}
}

.navigationLink {
width: 100%;
text-align: center;
font-size: 14px;
color: var(--rock);
margin-top: 30px;

span, a {
color: var(--shamrock);
text-decoration: none;
}
width: 100%;
text-align: center;
font-size: 14px;
color: var(--rock);
margin-top: 30px;

span,
a {
color: var(--shamrock);
text-decoration: none;
}
}

@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10vh);
}
from {
opacity: 0;
transform: translateY(10vh);
}

to {
opacity: 1;
transform: translateY(0vh);
}
}
to {
opacity: 1;
transform: translateY(0vh);
}
}

+ 21
- 15
src/theme/variables.css View File

@@ -1,28 +1,33 @@
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;600;700&display=swap');
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;600;700&display=swap");

* {
font-family: 'Poppins', sans-serif;
font-weight: 500;
letter-spacing: 0.5px;
line-height: 1.5;
margin: 0;
padding: 0;
font-family: "Poppins", sans-serif;
font-weight: 500;
letter-spacing: 0.5px;
line-height: 1.5;
margin: 0;
padding: 0;
}

ion-button {
--padding-start: 0;
--padding-bottom: 0;
--padding-top: 0;
--padding-end: 0;
text-transform: none;
--padding-start: 0;
--padding-bottom: 0;
--padding-top: 0;
--padding-end: 0;
text-transform: none;
}

h1, h2, h3, h4, h5, h6 {
font-weight: 700;
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 700;
}

ion-content {
--background: white;
--background: white;
}

/* Ionic Variables and Theming. For more info, please see:
@@ -125,4 +130,5 @@ http://ionicframework.com/docs/theming/ */
--ash-dust: #e5e5e5;
--ivory: #f4f4f4;
--pearl: #f7f7f7;
--white: #ffffff;
}

Loading…
Cancel
Save