343 lines
11 KiB
TypeScript
343 lines
11 KiB
TypeScript
// REQ0053/profile-page
|
|
//
|
|
// PURPOSE:
|
|
// - Provides functionality view user profile
|
|
//
|
|
// RULES:
|
|
// - T.B.A.
|
|
//
|
|
import React, { useEffect, useRef, useState } from 'react';
|
|
import {
|
|
IonHeader,
|
|
IonToolbar,
|
|
IonTitle,
|
|
IonContent,
|
|
IonPage,
|
|
IonButtons,
|
|
IonMenuButton,
|
|
IonGrid,
|
|
IonRow,
|
|
IonCol,
|
|
useIonRouter,
|
|
IonButton,
|
|
IonIcon,
|
|
IonPopover,
|
|
IonAvatar,
|
|
IonImg,
|
|
IonItem,
|
|
IonLabel,
|
|
IonList,
|
|
IonModal,
|
|
IonSearchbar,
|
|
useIonModal,
|
|
IonInput,
|
|
RefresherEventDetail,
|
|
IonRefresher,
|
|
IonRefresherContent,
|
|
} from '@ionic/react';
|
|
import SpeakerItem from '../../components/SpeakerItem';
|
|
import { Speaker } from '../../models/Speaker';
|
|
import { Session } from '../../models/Schedule';
|
|
import { connect } from '../../data/connect';
|
|
import * as selectors from '../../data/selectors';
|
|
import '../SpeakerList.scss';
|
|
import { getEvents } from '../../api/getEvents';
|
|
import { format } from 'date-fns';
|
|
import { Event } from './types';
|
|
import {
|
|
alertOutline,
|
|
chevronDownCircleOutline,
|
|
createOutline,
|
|
heart,
|
|
menuOutline,
|
|
settingsOutline,
|
|
} from 'ionicons/icons';
|
|
import AboutPopover from '../../components/AboutPopover';
|
|
import PATHS from '../../PATHS';
|
|
import { getProfileById } from '../../api/getProfileById';
|
|
import { defaultMember, Member } from '../MemberProfile/type';
|
|
import NotLoggedIn from './NotLoggedIn';
|
|
|
|
interface OwnProps {}
|
|
|
|
interface StateProps {
|
|
isLoggedin: boolean;
|
|
//
|
|
speakers: Speaker[];
|
|
speakerSessions: { [key: string]: Session[] };
|
|
}
|
|
|
|
interface DispatchProps {}
|
|
|
|
interface SpeakerListProps extends OwnProps, StateProps, DispatchProps {}
|
|
|
|
const MyProfilePage: React.FC<SpeakerListProps> = ({ speakers, speakerSessions, isLoggedin }) => {
|
|
if (!isLoggedin) return <NotLoggedIn />;
|
|
|
|
const [profile, setProfile] = useState<Member>(defaultMember);
|
|
|
|
const [showPopover, setShowPopover] = useState(false);
|
|
const [popoverEvent, setPopoverEvent] = useState<MouseEvent>();
|
|
const modal = useRef<HTMLIonModalElement>(null);
|
|
|
|
const router = useIonRouter();
|
|
|
|
function handleShowSettingButtonClick() {
|
|
router.push(PATHS.SETTINGS);
|
|
}
|
|
|
|
function handleNotImplementedClick() {
|
|
router.push(PATHS.NOT_IMPLEMENTED);
|
|
}
|
|
|
|
function handleRefresh(event: CustomEvent<RefresherEventDetail>) {
|
|
setTimeout(() => {
|
|
// Any calls to load data go here
|
|
event.detail.complete();
|
|
}, 2000);
|
|
}
|
|
|
|
useEffect(() => {
|
|
getProfileById('2').then(({ data }) => {
|
|
console.log({ data });
|
|
setProfile(data);
|
|
});
|
|
}, []);
|
|
|
|
if (!profile) return <>loading</>;
|
|
|
|
return (
|
|
<IonPage id="speaker-list">
|
|
<IonHeader translucent={true} className="ion-no-border">
|
|
<IonToolbar>
|
|
<IonButtons slot="end">
|
|
{/* <IonMenuButton /> */}
|
|
<IonButton shape="round" onClick={() => handleShowSettingButtonClick()}>
|
|
<IonIcon slot="icon-only" icon={settingsOutline}></IonIcon>
|
|
</IonButton>
|
|
</IonButtons>
|
|
<IonTitle>My profile</IonTitle>
|
|
</IonToolbar>
|
|
</IonHeader>
|
|
|
|
<IonContent fullscreen={true}>
|
|
<IonRefresher slot="fixed" onIonRefresh={handleRefresh}>
|
|
<IonRefresherContent
|
|
pullingIcon={chevronDownCircleOutline}
|
|
pullingText="Pull to refresh"
|
|
refreshingSpinner="circles"
|
|
refreshingText="Refreshing..."
|
|
></IonRefresherContent>
|
|
</IonRefresher>
|
|
|
|
<IonHeader collapse="condense" className="ion-no-border">
|
|
<IonToolbar>
|
|
<IonTitle size="large">My profile</IonTitle>
|
|
</IonToolbar>
|
|
</IonHeader>
|
|
|
|
<IonList lines="none">
|
|
<IonItem>
|
|
<div
|
|
style={{
|
|
marginTop: '1rem',
|
|
border: '1px solid lightgray',
|
|
borderRadius: '1rem',
|
|
width: '100%',
|
|
}}
|
|
>
|
|
<div style={{ padding: '1rem', display: 'flex', gap: '1rem' }}>
|
|
<IonAvatar>
|
|
<img
|
|
alt="Silhouette of a person's head"
|
|
src="https://plus.unsplash.com/premium_photo-1683121126477-17ef068309bc"
|
|
/>
|
|
</IonAvatar>
|
|
<div style={{ flexGrow: 1 }}>
|
|
<div
|
|
style={{
|
|
//
|
|
display: 'flex',
|
|
gap: '1rem',
|
|
alignItems: 'center',
|
|
}}
|
|
>
|
|
<div style={{ fontSize: '1.2rem', fontWeight: 'bold' }}>{profile.name}</div>
|
|
<div style={{ fontSize: '0.8rem' }}>{profile.rank}</div>
|
|
<div style={{ fontSize: '0.8rem' }}>{profile.verified}</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<IonButton
|
|
shape="round"
|
|
fill="clear"
|
|
size="large"
|
|
onClick={handleNotImplementedClick}
|
|
>
|
|
<IonIcon slot="icon-only" icon={createOutline}></IonIcon>
|
|
</IonButton>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</IonItem>
|
|
|
|
<IonItem>
|
|
<div
|
|
style={{
|
|
marginTop: '3rem',
|
|
//
|
|
borderRadius: '1rem',
|
|
width: '100%',
|
|
backgroundColor: 'gold',
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
padding: '1rem',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: '1rem',
|
|
}}
|
|
>
|
|
<div style={{ fontWeight: 'bold', fontSize: '1.1rem' }}>Membership</div>
|
|
<div>7 of the exclusive privileges</div>
|
|
<div>
|
|
<IonButton
|
|
expand="full"
|
|
shape="round"
|
|
size="large"
|
|
onClick={handleNotImplementedClick}
|
|
>
|
|
Unlock
|
|
</IonButton>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</IonItem>
|
|
<IonItem>
|
|
<div style={{ marginTop: '3rem' }}>
|
|
<div style={{ fontSize: '1.1rem', fontWeight: 'bold' }}>Privileges Unlocked</div>
|
|
<div
|
|
style={{
|
|
marginTop: '1rem',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: '1rem',
|
|
fontSize: '1rem',
|
|
}}
|
|
>
|
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
<div style={{ flexGrow: 1 }}>Unlock participant list</div>
|
|
<IonIcon icon={alertOutline}></IonIcon>
|
|
</div>
|
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
<div style={{ flexGrow: 1 }}>Exclusive vip logo</div>
|
|
<IonIcon icon={alertOutline}></IonIcon>
|
|
</div>
|
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
<div style={{ flexGrow: 1 }}>View visitors</div>
|
|
<IonIcon icon={alertOutline}></IonIcon>
|
|
</div>
|
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
<div style={{ flexGrow: 1 }}>Tips of message read</div>
|
|
<IonIcon icon={alertOutline}></IonIcon>
|
|
</div>
|
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
<div style={{ flexGrow: 1 }}>Voice and images transmission</div>
|
|
<IonIcon icon={alertOutline}></IonIcon>
|
|
</div>
|
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
<div style={{ flexGrow: 1 }}>Pinned to the top of nearby list every 24 hours</div>
|
|
<IonIcon icon={alertOutline}></IonIcon>
|
|
</div>
|
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
<div style={{ flexGrow: 1 }}>Unlimited chat</div>
|
|
<IonIcon icon={alertOutline}></IonIcon>
|
|
</div>
|
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
<div style={{ flexGrow: 1 }}>Filter verified users</div>
|
|
<IonIcon icon={alertOutline}></IonIcon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</IonItem>
|
|
</IonList>
|
|
</IonContent>
|
|
|
|
{/* REQ0079/event-filter */}
|
|
<IonModal
|
|
ref={modal}
|
|
trigger="my-profile-open-modal"
|
|
initialBreakpoint={0.5}
|
|
breakpoints={[0, 0.25, 0.5, 0.75]}
|
|
>
|
|
<IonContent className="ion-padding">
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
justifyContent: 'center',
|
|
gap: '1rem',
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
textAlign: 'center',
|
|
fontWeight: '1rem',
|
|
fontSize: '1.5rem',
|
|
marginTop: '0.5rem',
|
|
marginBottom: '0.5rem',
|
|
}}
|
|
>
|
|
Filter
|
|
</div>
|
|
<div
|
|
style={{
|
|
textAlign: 'center',
|
|
fontWeight: '1rem',
|
|
marginTop: '0.5rem',
|
|
marginBottom: '0.5rem',
|
|
}}
|
|
>
|
|
Maximum number of participant
|
|
</div>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
<IonButton shape="round">2-10</IonButton>
|
|
<IonButton shape="round">12-40</IonButton>
|
|
<IonButton shape="round">All</IonButton>
|
|
</div>
|
|
<div
|
|
style={{
|
|
textAlign: 'center',
|
|
fontWeight: '1rem',
|
|
marginTop: '0.5rem',
|
|
marginBottom: '0.5rem',
|
|
}}
|
|
>
|
|
Held date
|
|
</div>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
<IonButton shape="round">Weekly</IonButton>
|
|
<IonButton shape="round">Monthly</IonButton>
|
|
<IonButton shape="round">All</IonButton>
|
|
</div>
|
|
|
|
<IonButton shape="round" style={{ marginTop: '1rem', marginBottom: '1rem' }}>
|
|
Apply
|
|
</IonButton>
|
|
</div>
|
|
</IonContent>
|
|
</IonModal>
|
|
</IonPage>
|
|
);
|
|
};
|
|
|
|
export default connect<OwnProps, StateProps, DispatchProps>({
|
|
mapStateToProps: (state) => ({
|
|
speakers: selectors.getSpeakers(state),
|
|
speakerSessions: selectors.getSpeakerSessions(state),
|
|
isLoggedin: state.user.isLoggedin,
|
|
}),
|
|
component: React.memo(MyProfilePage),
|
|
});
|