init commit,
This commit is contained in:
305
03_source/mobile/src/pages/MyProfile/index.tsx
Normal file
305
03_source/mobile/src/pages/MyProfile/index.tsx
Normal file
@@ -0,0 +1,305 @@
|
||||
// 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';
|
||||
|
||||
interface OwnProps {}
|
||||
|
||||
interface StateProps {
|
||||
speakers: Speaker[];
|
||||
speakerSessions: { [key: string]: Session[] };
|
||||
}
|
||||
|
||||
interface DispatchProps {}
|
||||
|
||||
interface SpeakerListProps extends OwnProps, StateProps, DispatchProps {}
|
||||
|
||||
const MyProfile: React.FC<SpeakerListProps> = ({ speakers, speakerSessions }) => {
|
||||
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),
|
||||
}),
|
||||
component: React.memo(MyProfile),
|
||||
});
|
Reference in New Issue
Block a user