add authentication routes, components, and pages including AuthHome, Login, and SignUp, and implement form fields utility functions
```
This commit is contained in:
louiscklaw
2025-05-12 19:22:00 +08:00
parent ee0aa0353b
commit 3f10a0728c
14 changed files with 543 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
import {
IonButton,
IonCardTitle,
IonCol,
IonContent,
IonFooter,
IonGrid,
IonHeader,
IonImg,
IonPage,
IonRouterLink,
IonRow,
IonToolbar,
} from '@ionic/react';
// import { Action } from '../components/Action';
import styles from './style.module.scss';
import { Action } from '../../../components/Action';
const AuthHome = () => {
return (
<IonPage className={'styles.homePage'}>
<IonHeader>
{/* <IonToolbar className="ion-no-margin ion-no-padding"> */}
<IonImg src="/assets/login2.jpeg" />
{/* </IonToolbar> */}
</IonHeader>
<IonContent fullscreen>
<div className={styles.getStarted}>
<IonGrid>
<IonRow className={`ion-text-center ion-justify-content-center ${styles.heading}`}>
<IonCol size="11" className={styles.headingText}>
<IonCardTitle>Join millions of other people discovering their creative side</IonCardTitle>
</IonCol>
</IonRow>
<IonRow className={`ion-text-center ion-justify-content-center`}>
<IonRouterLink routerLink="/signup" className="custom-link">
<IonCol size="11">
<IonButton className={`${styles.getStartedButton} custom-button`}>Get started &rarr;</IonButton>
</IonCol>
</IonRouterLink>
</IonRow>
</IonGrid>
</div>
</IonContent>
<IonFooter>
<IonGrid>
<Action message="Already got an account?" text="Login" link="/login" />
</IonGrid>
</IonFooter>
</IonPage>
);
};
export default AuthHome;

View File

@@ -0,0 +1,41 @@
.homePage {
ion-header {
ion-img {
border-bottom: 3px solid rgb(236, 149, 35);
}
}
ion-footer {
// background-color: #7c3b6a;
color: white;
}
}
.getStarted {
height: 100%;
background-color: #ffffff;
background-image: radial-gradient(#b8b8b8 1px, transparent 1px), radial-gradient(#b8b8b8 1px, #ffffff 1px);
background-size: 40px 40px;
background-position:
0 0,
20px 20px;
ion-card-title {
color: black !important;
letter-spacing: -0.08rem;
font-weight: 900 !important;
}
}
.heading {
margin-top: 7rem;
}
.getStartedButton {
font-size: 1.2rem;
margin-top: 1rem;
}
.helloworld {
color: gold;
}

View File

@@ -0,0 +1,93 @@
import {
IonBackButton,
IonButton,
IonButtons,
IonCardTitle,
IonCol,
IonContent,
IonFooter,
IonGrid,
IonHeader,
IonIcon,
IonImg,
IonInput,
IonInputPasswordToggle,
IonPage,
IonRouterLink,
IonRow,
IonText,
IonToolbar,
} from '@ionic/react';
import styles from './style.module.scss';
import { arrowBack, shapesOutline } from 'ionicons/icons';
import { CustomField } from '../../../components/CustomField';
import { useLoginFields } from '../../../data/fields';
import { Action } from '../../../components/Action';
import { Wave } from '../../../components/Wave';
import { useEffect, useState } from 'react';
import { useParams } from 'react-router';
function AuthLogin(): React.JSX.Element {
const params = useParams();
const [errors, setErrors] = useState(false);
const login = () => {};
return (
<IonPage className={styles.loginPage}>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton icon={arrowBack} text="" className="custom-back" />
</IonButtons>
<IonButtons slot="end">
<IonButton className="custom-button">
<IonIcon icon={shapesOutline} />
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
{/* */}
<IonContent fullscreen>
<IonGrid className="ion-padding">
<IonRow>
<IonCol size="12" className={styles.headingText}>
<IonCardTitle>Log in</IonCardTitle>
<h5>Welcome back, hope you're doing well</h5>
</IonCol>
</IonRow>
<IonRow className="ion-margin-top ion-padding-top">
<IonCol size="12">
<IonInput labelPlacement="floating" value="hi@ionic.io">
<div slot="label">
Email <IonText color="danger">(Required)</IonText>
</div>
</IonInput>
<IonInput type="password" label="Password" value="NeverGonnaGiveYouUp">
<IonInputPasswordToggle slot="end"></IonInputPasswordToggle>
</IonInput>
<IonButton className="custom-button" expand="block" onClick={login}>
Login
</IonButton>
</IonCol>
</IonRow>
</IonGrid>
</IonContent>
{/* */}
<IonFooter>
<IonGrid className="ion-no-margin ion-no-padding">
<Action message="Don't have an account?" text="Sign up" link="/auth/signup" />
<Wave />
</IonGrid>
</IonFooter>
</IonPage>
);
}
export { AuthLogin };

View File

@@ -0,0 +1,17 @@
.loginPage {
ion-toolbar {
--border-style: none;
--border-color: transparent;
--padding-top: 1rem;
--padding-bottom: 1rem;
--padding-start: 1rem;
--padding-end: 1rem;
}
}
.headingText {
h5 {
margin-top: 0.2rem;
// color: #d3a6c7;
}
}

View File

@@ -0,0 +1,95 @@
import {
IonBackButton,
IonButton,
IonButtons,
IonCardTitle,
IonCol,
IonContent,
IonFooter,
IonGrid,
IonHeader,
IonIcon,
IonImg,
IonInput,
IonInputPasswordToggle,
IonPage,
IonRouterLink,
IonRow,
IonText,
IonToolbar,
} from '@ionic/react';
import styles from './style.module.scss';
import { arrowBack, shapesOutline } from 'ionicons/icons';
import { CustomField } from '../../../components/CustomField';
import { useLoginFields, useSignupFields } from '../../../data/fields';
import { Action } from '../../../components/Action';
import { Wave } from '../../../components/Wave';
import { useEffect, useState } from 'react';
import { useParams } from 'react-router';
function AuthSignUp(): React.JSX.Element {
const params = useParams();
const fields = useSignupFields();
const [errors, setErrors] = useState(false);
const login = () => {};
function createAccount() {}
return (
<IonPage className={styles.loginPage}>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton icon={arrowBack} text="" className="custom-back" />
</IonButtons>
<IonButtons slot="end">
<IonButton className="custom-button">
<IonIcon icon={shapesOutline} />
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
{/* */}
<IonContent fullscreen>
<IonGrid className="ion-padding">
<IonRow>
<IonCol size="12" className={styles.headingText}>
<IonCardTitle>Sign up</IonCardTitle>
<h5>Lets get to know each other</h5>
</IonCol>
</IonRow>
<IonRow className="ion-margin-top ion-padding-top">
<IonCol size="12">
{fields.map((field, i) => {
return (
<div key={i}>
<CustomField field={field} errors={errors} />
</div>
);
})}
<IonButton className="custom-button" expand="block" onClick={createAccount}>
Create account
</IonButton>
</IonCol>
</IonRow>
</IonGrid>
</IonContent>
{/* */}
<IonFooter>
<IonGrid className="ion-no-margin ion-no-padding">
<Action message="Already got an account?" text="Login" link="/auth/login" />
<Wave />
</IonGrid>
</IonFooter>
</IonPage>
);
}
export { AuthSignUp };

View File

@@ -0,0 +1,17 @@
.signupPage {
ion-toolbar {
--border-style: none;
--border-color: transparent;
--padding-top: 1rem;
--padding-bottom: 1rem;
--padding-start: 1rem;
--padding-end: 1rem;
}
}
.headingText {
h5 {
margin-top: 0.2rem;
// color: #d3a6c7;
}
}