feat: implement login and signup pages with shared authentication styles, including form validation and Redux integration for authentication state management

This commit is contained in:
louiscklaw
2025-06-17 23:47:18 +08:00
parent 1325a361dc
commit 2b09261f0a
6 changed files with 145 additions and 30 deletions

View File

@@ -1,16 +0,0 @@
#login-page, #signup-page, #support-page {
.login-logo {
padding: 20px 0;
min-height: 200px;
text-align: center;
}
.login-logo img {
max-width: 150px;
}
.list {
margin-bottom: 0;
}
}

View File

@@ -0,0 +1,30 @@
/**
* Shared Authentication Styles
*
* Contains common styling for:
* - Login page
* - Signup page
* - Support page
*
* Key features:
* - Logo positioning and sizing
* - Form list styling
* - Responsive design for all screen sizes
*/
#login-page,
#signup-page,
#support-page {
.login-logo {
padding: 20px 0;
min-height: 200px;
text-align: center;
}
.login-logo img {
max-width: 150px;
}
.list {
margin-bottom: 0;
}
}

View File

@@ -1,3 +1,16 @@
/**
* Login Page Component
*
* Handles user authentication with:
* - Username/password input
* - Form validation
* - Login state management
* - Navigation to signup page
*
* Connects to Redux store for:
* - Setting authentication state
* - Storing username
*/
import React, { useState } from 'react'; import React, { useState } from 'react';
import { import {
IonHeader, IonHeader,
@@ -16,8 +29,8 @@ import {
IonText, IonText,
} from '@ionic/react'; } from '@ionic/react';
import './Login.scss'; import './Login.scss';
import { setIsLoggedIn, setUsername } from '../data/user/user.actions'; import { setIsLoggedIn, setUsername } from '../../data/user/user.actions';
import { connect } from '../data/connect'; import { connect } from '../../data/connect';
import { RouteComponentProps } from 'react-router'; import { RouteComponentProps } from 'react-router';
interface OwnProps extends RouteComponentProps {} interface OwnProps extends RouteComponentProps {}
@@ -59,12 +72,12 @@ const Login: React.FC<LoginProps> = ({
return ( return (
<IonPage id="login-page"> <IonPage id="login-page">
<IonHeader> <IonHeader className="ion-no-border">
<IonToolbar> <IonToolbar>
<IonButtons slot="start"> <IonButtons slot="start">
<IonMenuButton></IonMenuButton> <IonMenuButton></IonMenuButton>
</IonButtons> </IonButtons>
<IonTitle>Login</IonTitle> <IonTitle>Example Login Page</IonTitle>
</IonToolbar> </IonToolbar>
</IonHeader> </IonHeader>
<IonContent> <IonContent>

View File

@@ -1,11 +1,21 @@
// REQ0053/profile-page /**
// * Not Logged In Profile View Component
// PURPOSE: *
// - Provides functionality view user profile * Displays when user is not authenticated, with:
// * - Visual placeholder for profile
// RULES: * - Login button (regular user)
// - T.B.A. * - Party member login button
// * - Signup encouragement
*
* Features:
* - Pull-to-refresh functionality
* - Responsive design for all screen sizes
* - Clear call-to-action buttons
*
* Connected to:
* - Redux store for speaker data
* - Router for navigation
*/
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { import {
IonHeader, IonHeader,
@@ -104,6 +114,18 @@ const MyProfile: React.FC<SpeakerListProps> = ({ speakers, speakerSessions }) =>
} }
} }
const [disableForwardPartyUserLoginButton, setDisableForwardPartyUserLoginButton] =
useState(false);
function handleForwardPartyUserLoginPage() {
try {
setDisableForwardPartyUserLoginButton(true);
router.push(PATHS.PARTY_USER_SIGN_IN);
setDisableForwardPartyUserLoginButton(false);
} catch (error) {
console.error(error);
}
}
useEffect(() => { useEffect(() => {
getProfileById('2').then(({ data }) => { getProfileById('2').then(({ data }) => {
console.log({ data }); console.log({ data });
@@ -180,6 +202,7 @@ const MyProfile: React.FC<SpeakerListProps> = ({ speakers, speakerSessions }) =>
not login yet, <br /> not login yet, <br />
please login or sign up please login or sign up
</div> </div>
{/* */}
<div <div
style={{ style={{
display: 'flex', display: 'flex',
@@ -192,6 +215,24 @@ const MyProfile: React.FC<SpeakerListProps> = ({ speakers, speakerSessions }) =>
Login Login
</IonButton> </IonButton>
</div> </div>
{/* */}
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
>
<IonButton
disabled={disableForwardPartyUserLoginButton}
onClick={handleForwardPartyUserLoginPage}
>
Party Member Login
</IonButton>
</div>
</div> </div>
</div> </div>
</IonContent> </IonContent>

View File

@@ -0,0 +1,32 @@
/**
* Shared Authentication Styles (Duplicate)
*
* Note: This file is identical to ../Login/Login.scss
*
* Contains common styling for:
* - Login page
* - Signup page
* - Support page
*
* Key features:
* - Logo positioning and sizing
* - Form list styling
* - Responsive design for all screen sizes
*/
#login-page,
#signup-page,
#support-page {
.login-logo {
padding: 20px 0;
min-height: 200px;
text-align: center;
}
.login-logo img {
max-width: 150px;
}
.list {
margin-bottom: 0;
}
}

View File

@@ -1,3 +1,18 @@
/**
* Signup Page Component
*
* Handles new user registration with:
* - Username/password input fields
* - Form validation
* - Registration state management
*
* Note: Currently shares styling and some logic with Login page
* (imports Login.scss and similar state management)
*
* Connects to Redux store for:
* - Setting authentication state
* - Storing username
*/
import React, { useState } from 'react'; import React, { useState } from 'react';
import { import {
IonHeader, IonHeader,
@@ -16,8 +31,8 @@ import {
IonText, IonText,
} from '@ionic/react'; } from '@ionic/react';
import './Login.scss'; import './Login.scss';
import { setIsLoggedIn, setUsername } from '../data/user/user.actions'; import { setIsLoggedIn, setUsername } from '../../data/user/user.actions';
import { connect } from '../data/connect'; import { connect } from '../../data/connect';
import { RouteComponentProps } from 'react-router'; import { RouteComponentProps } from 'react-router';
interface OwnProps extends RouteComponentProps {} interface OwnProps extends RouteComponentProps {}