Selaa lähdekoodia

Converted React class components into Functional Components

master
kj1352 4 vuotta sitten
vanhempi
commit
7239d7a0db
6 muutettua tiedostoa jossa 176 lisäystä ja 245 poistoa
  1. +13
    -26
      src/components/input/InputWidget.tsx
  2. +5
    -14
      src/pages/login/Login.tsx
  3. +23
    -34
      src/pages/onboarding/Welcome.tsx
  4. +86
    -106
      src/pages/signup/AdditionalQuestions.tsx
  5. +2
    -4
      src/pages/signup/Signup.module.scss
  6. +47
    -61
      src/pages/signup/Signup.tsx

+ 13
- 26
src/components/input/InputWidget.tsx Näytä tiedosto

@@ -1,6 +1,6 @@
import { IonButton, IonIcon } from '@ionic/react';
import { eyeOutline, eyeOffOutline } from 'ionicons/icons';
import { Component } from 'react';
import React, { useState } from 'react';
import styles from './InputWidget.module.scss';

type Props = {
@@ -10,37 +10,24 @@ type Props = {
hideEye?: boolean
};

type OwnState = {
showPassword: boolean,
};

class InputWidget extends Component<Props, OwnState> {
constructor(
props: Props
) {
super(props);
this.state = {
showPassword: false
};
}
const InputWidget: React.FC<Props> = (props) => {
let [showPassword, toggleEye] = useState(false);

render() {
return <section className={styles.inputHolder}>
{ this.props.icon && <IonIcon className={styles.leftIcon} icon={this.props.icon}></IonIcon> }
return (<section className={styles.inputHolder}>
{ props.icon && <IonIcon className={styles.leftIcon} icon={props.icon}></IonIcon> }
{ this.props.type === 'TEXT' && <input type='text' placeholder={this.props.placeholder} /> }
{ this.props.type === 'PASSWORD' && <input type={this.state.showPassword ? 'text' : 'password'} placeholder={this.props.placeholder} /> }
{ props.type === 'TEXT' && <input type='text' placeholder={props.placeholder} /> }
{ props.type === 'PASSWORD' && <input type={showPassword ? 'text' : 'password'} placeholder={props.placeholder} /> }

{ this.props.type === 'PHONE' && <input type='tel' placeholder={this.props.placeholder} /> }
{ props.type === 'PHONE' && <input type='tel' placeholder={props.placeholder} /> }

{ this.props.type === 'PASSWORD' && !this.props.hideEye &&
<IonButton className={styles.eyeButton} onClick={e => this.setState({ showPassword: !this.state.showPassword })}>
{ this.state.showPassword && <IonIcon icon={eyeOffOutline}></IonIcon> }
{ !this.state.showPassword && <IonIcon icon={eyeOutline}></IonIcon> }
{ props.type === 'PASSWORD' && !props.hideEye &&
<IonButton className={styles.eyeButton} onClick={ () => { toggleEye(showPassword = !showPassword) } }>
{ showPassword && <IonIcon icon={eyeOffOutline}></IonIcon> }
{ !showPassword && <IonIcon icon={eyeOutline}></IonIcon> }
</IonButton>
}
</section>
};
</section>);
};

export default InputWidget;

+ 5
- 14
src/pages/login/Login.tsx Näytä tiedosto

@@ -1,24 +1,15 @@
import { IonContent, IonPage, IonButton } from '@ionic/react';
import { personOutline, lockOpenOutline } from 'ionicons/icons';
import { Component } from 'react';
import React from 'react';
import InputWidget from '../../components/input/InputWidget';
import styles from './Login.module.scss';
import { Link } from "react-router-dom";

type Props = { };

type OwnState = { };

class LoginPage extends Component<Props, OwnState> {
constructor(
props: Props
) {
super(props);
this.state = {};
}

render() {
return <IonPage>
const LoginPage: React.FC<Props> = () => {
return (
<IonPage>
<IonContent fullscreen>
<section className={styles.upfold}>
<div className={styles.container}>
@@ -48,7 +39,7 @@ class LoginPage extends Component<Props, OwnState> {
<div className={ styles.navigationLink }> Don't have an account? <Link to='/signup'> <span> Signup </span> </Link> </div>
</IonContent>
</IonPage>
};
);
};

export default LoginPage;

+ 23
- 34
src/pages/onboarding/Welcome.tsx Näytä tiedosto

@@ -1,45 +1,34 @@
import { IonContent, IonPage, IonButton } from '@ionic/react';
import { Component } from 'react';
import React from 'react';
import styles from './Welcome.module.scss';

type Props = { };

type OwnState = { };
const WelcomePage: React.FC<Props> = () => {
return (<IonPage>
<IonContent fullscreen>
<section className={styles.upfold}>
<figure>
<img src="assets/images/welcome/upfold.svg" alt="upfold image"/>
</figure>
</section>

class WelcomePage extends Component<Props, OwnState> {
constructor(
props: Props
) {
super(props);
this.state = {};
}
<section className={styles.content}>
<div className={styles.container}>
<h2> Let's Get Started </h2>
<p>
Welcome to <strong> WorkX </strong>
</p>

render() {
return <IonPage>
<IonContent fullscreen>
<section className={styles.upfold}>
<figure>
<img src="assets/images/welcome/upfold.svg" alt="upfold image"/>
</figure>
</section>

<section className={styles.content}>
<div className={styles.container}>
<h2> Let's Get Started </h2>
<p>
Welcome to <strong> WorkX </strong>
</p>

<div className={styles.actionButtonsHolder}>
<IonButton className={styles.actionButton} expand="block" routerLink="/signup"> Create Account </IonButton>
<IonButton className={styles.actionButton} fill="outline" expand="block" routerLink="/login"> Login </IonButton>
</div>
<div className={styles.actionButtonsHolder}>
<IonButton className={styles.actionButton} expand="block" routerLink="/signup"> Create Account </IonButton>
<IonButton className={styles.actionButton} fill="outline" expand="block" routerLink="/login"> Login </IonButton>
</div>
</section>
</IonContent>
</IonPage>
};
</div>
</section>
</IonContent>
</IonPage>);
};

export default WelcomePage;

+ 86
- 106
src/pages/signup/AdditionalQuestions.tsx Näytä tiedosto

@@ -1,20 +1,7 @@
import { IonContent, IonRange, IonButton, IonSlides, IonSlide, IonIcon } from '@ionic/react';
import { Component } from 'react';
import React, { useState, useRef, createRef } from 'react';
import styles from './AdditionalQuestions.module.scss';

type Props = { };

type OwnState = {
index: number,
userType: 'INDIVIDUAL' | 'COMPANY' | '',
userSector: {
value: number,
icon: string,
text: string
} | undefined,
showPicker: boolean,
};

const slideOpts = {
initialSlide: 2,
speed: 400,
@@ -66,124 +53,117 @@ const jobSectors = [{
text: 'Others'
}];

const AdditionalQuestions: React.FC = () => {
let [index, setIndex] = useState(0),
[userType, changeUserType] = useState('INDIVIDUAL'),
[userSector, changeUserSector] = useState(jobSectors[0]),
[showPicker, toggleShowPicker] = useState(false);

const additionalSlides: any = useRef(null);

class AdditionalQuestions extends Component<Props, OwnState> {
constructor(
props: Props
) {
super(props);
this.state = {
index: 0,
userType: 'INDIVIDUAL',
showPicker: false,
userSector: undefined,
};

const changeIndex = async (event: any) => {
await event.target.getActiveIndex().then((index: number) => setIndex(index = index));
}

getPadding = (digit: number) => {
const getPadding = (digit: number) => {
return digit.toString().padStart(2, '0');
}

nextSlide = async () => {
let slides: any = document.querySelector('#slides');
const swiper: any = await slides?.getSwiper();
const nextSlide = async () => {
const swiper: any = await additionalSlides.current?.getSwiper();
swiper.slideNext();
}

prevSlide = async () => {
let slides: any = document.querySelector('#slides');
const swiper: any = await slides?.getSwiper();
const prevSlide = async () => {
const swiper: any = await additionalSlides.current?.getSwiper();
swiper.slidePrev();
}

render() {
return <IonContent fullscreen>
<header className={styles.slidersNavBar}>
<h4>
{ this.getPadding(this.state.index + 1)}<span>/05 </span>
</h4>
<IonButton> Skip <IonIcon src='assets/images/signup/skip.svg'></IonIcon> </IonButton>
</header>
<IonSlides options={slideOpts} className={styles.slides} id="slides">
<IonSlide>
<div className={styles.questionContainer}>
<p className={styles.question}> Select if you represent a <strong> company </strong> or if you're an <strong> individual </strong> </p>
<p className={styles.hint}> Select answer below </p>
</div>
<div className={styles.choiceContainer}>
<div className={styles.optionButtons}>
<button className={ this.state.userType === 'COMPANY' ? styles.active : '' }
onClick={e => this.setState({ userType: 'COMPANY' })}> <IonIcon className={styles.leftIcon} src='assets/images/signup/building.svg'></IonIcon> Company <IonIcon className={styles.checkmark} src='assets/images/signup/checkmark.svg'></IonIcon> </button>
<button className={ this.state.userType === 'INDIVIDUAL' ? styles.active : '' }
onClick={e => this.setState({ userType: 'INDIVIDUAL' })}> <IonIcon className={styles.leftIcon} src='assets/images/signup/user.svg'></IonIcon> Individual <IonIcon className={styles.checkmark} src='assets/images/signup/checkmark.svg'></IonIcon> </button>
</div>
</div>
</IonSlide>

<IonSlide>
<div className={styles.questionContainer}>
<p className={styles.question}> Which <strong> sector </strong>
{ this.state.userType === 'COMPANY' && <span> does your company below to? </span> }
{ this.state.userType === 'INDIVIDUAL' && <span> do you work under? </span> } </p>
<p className={styles.hint}> Select answer below </p>
return (<IonContent fullscreen>
<header className={styles.slidersNavBar}>
<h4>
{ getPadding(index + 1)}<span>/05 </span>
</h4>
<IonButton> Skip <IonIcon src='assets/images/signup/skip.svg'></IonIcon> </IonButton>
</header>

<IonSlides options={slideOpts} className={styles.slides}
ref={additionalSlides} onIonSlideDidChange={(e) => changeIndex(e)}>
<IonSlide>
<div className={styles.questionContainer}>
<p className={styles.question}> Select if you represent a <strong> company </strong> or if you're an <strong> individual </strong> </p>
<p className={styles.hint}> Select answer below </p>
</div>
<div className={styles.choiceContainer}>
<div className={styles.optionButtons}>
<button className={ userType === 'COMPANY' ? styles.active : '' }
onClick={() => changeUserType(userType = 'COMPANY')}> <IonIcon className={styles.leftIcon} src='assets/images/signup/building.svg'></IonIcon> Company <IonIcon className={styles.checkmark} src='assets/images/signup/checkmark.svg'></IonIcon> </button>
<button className={ userType === 'INDIVIDUAL' ? styles.active : '' }
onClick={() => changeUserType(userType = 'INDIVIDUAL')}> <IonIcon className={styles.leftIcon} src='assets/images/signup/user.svg'></IonIcon> Individual <IonIcon className={styles.checkmark} src='assets/images/signup/checkmark.svg'></IonIcon> </button>
</div>
<div className={styles.choiceContainer}>
<div className={styles.optionButtons}>
<button className={styles.optionButton} onClick={ () => this.setState({ showPicker: true })}> { this.state.userSector ? <span> <IonIcon className={styles.sectorIcon} src={this.state.userSector.icon}></IonIcon> { this.state.userSector.text } </span> : <span> Select an Option </span> } <IonIcon className={styles.option} src='assets/images/signup/options.svg'></IonIcon> </button>
</div>
</div>
</IonSlide>

<IonSlide>
<div className={styles.questionContainer}>
<p className={styles.question}> Which <strong> sector </strong>
{ userType === 'COMPANY' && <span> does your company below to? </span> }
{ userType === 'INDIVIDUAL' && <span> do you work under? </span> } </p>
<p className={styles.hint}> Select answer below </p>
</div>
<div className={styles.choiceContainer}>
<div className={styles.optionButtons}>
<button className={styles.optionButton} onClick={ () => toggleShowPicker( showPicker = true )}> { userSector ? <span> <IonIcon className={styles.sectorIcon} src={ userSector.icon }></IonIcon> { userSector.text } </span> : <span> Select an Option </span> } <IonIcon className={styles.option} src='assets/images/signup/options.svg'></IonIcon> </button>
</div>
</IonSlide>
</div>
</IonSlide>


<IonSlide>
<div className={styles.questionContainer}>
<p className={styles.question}> What is your working <strong> team size? </strong> </p>
<p className={styles.hint}> Select answer below </p>
</div>
<div className={styles.choiceContainer}>
<IonRange mode={'ios'} value={30} min={1} max={100} step={10} snaps={true} />
</div>
</IonSlide>
<IonSlide>
<div className={styles.questionContainer}>
<p className={styles.question}> What is your working <strong> team size? </strong> </p>
<p className={styles.hint}> Select answer below </p>
</div>
<div className={styles.choiceContainer}>
<IonRange mode={'ios'} value={30} min={1} max={100} step={10} snaps={true} />
</div>
</IonSlide>


<IonSlide>
<div className={styles.questionContainer}>
<p className={styles.question}> Select the <strong> modules </strong> that will be used. </p>
<p className={styles.hint}> Select answer below </p>
</div>
<div className={styles.choiceContainer}>
<IonSlide>
<div className={styles.questionContainer}>
<p className={styles.question}> Select the <strong> modules </strong> that will be used. </p>
<p className={styles.hint}> Select answer below </p>
</div>
<div className={styles.choiceContainer}>

</div>
</IonSlide>
</IonSlides>
</div>
</IonSlide>
</IonSlides>


<IonButton className={styles.prevButton} fill="outline" onClick={ () => this.prevSlide() }>
<IonIcon src='assets/images/signup/arrow-next.svg'></IonIcon>
</IonButton>
<IonButton className={styles.prevButton} fill="outline" onClick={ () => prevSlide() }>
<IonIcon src='assets/images/signup/arrow-next.svg'></IonIcon>
</IonButton>

<IonButton className={styles.nextButton} onClick={ () => this.nextSlide() }>
Next <IonIcon src='assets/images/signup/arrow-next.svg'></IonIcon>
</IonButton>
<IonButton className={styles.nextButton} onClick={ () => nextSlide() }>
Next <IonIcon src='assets/images/signup/arrow-next.svg'></IonIcon>
</IonButton>


{ this.state.showPicker && <section className={styles.picker}>
<div className={styles.container}>
<ul>
{ jobSectors.map((sector) => <li key={sector.value}
className={this.state.userSector === sector ? styles.active : ''}
onClick={() => this.setState({ userSector: sector, showPicker: false })}>
<IonIcon src={sector.icon}></IonIcon> { sector.text }
</li>) }
</ul>
</div>
</section> }
{ showPicker && <section className={styles.picker}>
<div className={styles.container}>
<ul>
{ jobSectors.map((sector) => <li key={sector.value}
className={userSector === sector ? styles.active : ''}
onClick={() => { toggleShowPicker(showPicker = false); changeUserSector(userSector = sector); } }>
<IonIcon src={sector.icon}></IonIcon> { sector.text }
</li>) }
</ul>
</div>
</section> }

</IonContent>
};
</IonContent>);
};

export default AdditionalQuestions;

+ 2
- 4
src/pages/signup/Signup.module.scss Näytä tiedosto

@@ -134,13 +134,11 @@
}

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

span, a {
color: var(--shamrock);


+ 47
- 61
src/pages/signup/Signup.tsx Näytä tiedosto

@@ -1,79 +1,65 @@
import { IonContent, IonPage, IonButton, IonToggle } from '@ionic/react';
import { personOutline, lockOpenOutline, mailOutline, phonePortraitOutline } from 'ionicons/icons';
import { Component } from 'react';
import React, { useState } from 'react';
import InputWidget from '../../components/input/InputWidget';
import styles from './Signup.module.scss';
import { Link } from "react-router-dom";
import AdditionalQuestions from '../signup/AdditionalQuestions';

type Props = { };

type OwnState = {
signupStep: 'BASIC' | 'ADDITIONAL';
};

class SignupPage extends Component<Props, OwnState> {
constructor(
props: Props
) {
super(props);
this.state = {
signupStep: 'ADDITIONAL'
};
}
const SignupPage: React.FC = () => {
let [signupStep, changeStep] = useState('BASIC');

render() {
return <IonPage>
{ this.state.signupStep === 'BASIC' &&
<IonContent fullscreen>
<section className={styles.upfold}>
<div className={styles.container}>
<figure>
<img src="assets/images/signup/rocket.svg" alt="rocket image"/>
</figure>
<h2> Let's Create </h2>
<p> Please provide few details below. </p>
</div>
</section>
return (<IonPage>
{ signupStep === 'BASIC' &&
<IonContent fullscreen>
<section className={styles.upfold}>
<div className={styles.container}>
<figure>
<img src="assets/images/signup/rocket.svg" alt="rocket image"/>
</figure>
<h2> Let's Create </h2>
<p> Please provide few details below. </p>
</div>
</section>

<section className={styles.inputForm}>
<div className={styles.input}>
<InputWidget type={'TEXT'} icon={personOutline} placeholder={'Full Name'} />
</div>
<div className={styles.input}>
<InputWidget type={'TEXT'} icon={mailOutline} placeholder={'Email'} />
</div>
<div className={styles.input}>
<InputWidget type={'PHONE'} icon={phonePortraitOutline} placeholder={'Phone'} />
</div>
<section className={styles.separator}></section>
<section className={styles.inputForm}>
<div className={styles.input}>
<InputWidget type={'TEXT'} icon={personOutline} placeholder={'Full Name'} />
</div>
<div className={styles.input}>
<InputWidget type={'TEXT'} icon={mailOutline} placeholder={'Email'} />
</div>
<div className={styles.input}>
<InputWidget type={'PHONE'} icon={phonePortraitOutline} placeholder={'Phone'} />
</div>
<section className={styles.separator}></section>

<div className={styles.input}>
<InputWidget type={'PASSWORD'} icon={lockOpenOutline} placeholder={'Password'} />
</div>
<div className={styles.input}>
<InputWidget type={'PASSWORD'} icon={lockOpenOutline} placeholder={'Password'} />
</div>

<div className={styles.input}>
<InputWidget type={'PASSWORD'} hideEye={true} icon={lockOpenOutline} placeholder={'Confirm Password'} />
</div>
<div className={styles.input}>
<InputWidget type={'PASSWORD'} hideEye={true} icon={lockOpenOutline} placeholder={'Confirm Password'} />
</div>

<div className={styles.confirmationAction}>
<label> Login with fingerprint scanner </label>
<IonToggle className={styles.toggle} />
</div>
<div className={styles.confirmationAction}>
<label> Login with fingerprint scanner </label>
<IonToggle className={styles.toggle} />
</div>

<div className={styles.actionButtonsHolder}>
<IonButton className={styles.actionButton} expand="block"
onClick={e => this.setState({ signupStep: 'ADDITIONAL' })}> Create </IonButton>
</div>
</section>
<div className={styles.actionButtonsHolder}>
<IonButton className={styles.actionButton} expand="block"
onClick={() => changeStep(signupStep = 'ADDITIONAL')}> Create </IonButton>
</div>
</section>

<div className={ styles.navigationLink }> Already have an account? <Link to='/login'> <span> Login </span> </Link> </div>
</IonContent> }
{ this.state.signupStep === 'ADDITIONAL' && <AdditionalQuestions /> }
</IonPage>
};
<div className={ styles.navigationLink }> Already have an account? <Link to='/login'> <span> Login </span> </Link> </div>
</IonContent> }
{ signupStep === 'ADDITIONAL' && <AdditionalQuestions /> }
</IonPage>);
};

export default SignupPage;

Ladataan…
Peruuta
Tallenna