"feat: rename 'createdDate' to 'createDate' across frontend, backend, and mobile codebases"
This commit is contained in:
@@ -17,6 +17,7 @@ import MyProfile from './MyProfile';
|
||||
import MessageList from './MessageList';
|
||||
import paths from '../paths';
|
||||
import Favourites from './Favourites';
|
||||
import TabAppRoute from '../TabAppRoute';
|
||||
|
||||
interface MainTabsProps {}
|
||||
|
||||
@@ -40,22 +41,7 @@ const MainTabs: React.FC<MainTabsProps> = () => {
|
||||
<Route path="/tabs/about" render={() => <About />} exact={true} />
|
||||
|
||||
{/* */}
|
||||
<Route path="/tabs/events" render={() => <EventList />} exact={true} />
|
||||
|
||||
{/* */}
|
||||
<Route path={paths.NEARBY_LIST} render={() => <MembersNearByList />} exact={true} />
|
||||
|
||||
{/* */}
|
||||
<Route path={paths.ORDERS_LIST} render={() => <OrderList />} exact={true} />
|
||||
|
||||
{/* */}
|
||||
<Route path={paths.MESSAGE_LIST} render={() => <MessageList />} exact={true} />
|
||||
|
||||
{/* */}
|
||||
<Route path={paths.FAVOURITES_LIST} render={() => <Favourites />} exact={true} />
|
||||
|
||||
{/* */}
|
||||
<Route path="/tabs/my_profile" render={() => <MyProfile />} exact={true} />
|
||||
<TabAppRoute />
|
||||
</IonRouterOutlet>
|
||||
{/* */}
|
||||
<IonTabBar slot="bottom">
|
||||
|
155
03_source/mobile/src/pages/MyProfile/NotLoggedIn/index.tsx
Normal file
155
03_source/mobile/src/pages/MyProfile/NotLoggedIn/index.tsx
Normal file
@@ -0,0 +1,155 @@
|
||||
// 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);
|
||||
}
|
||||
|
||||
const [disableForwardLoginButton, setDisableForwardLoginButton] = useState(false);
|
||||
function handleForwardLoginPage() {
|
||||
try {
|
||||
setDisableForwardLoginButton(true);
|
||||
router.push(paths.login);
|
||||
setDisableForwardLoginButton(false);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
|
||||
<div style={{ height: '50vh', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<div>
|
||||
not login yet, <br />
|
||||
please login or sign up
|
||||
</div>
|
||||
<div style={{ height: '50vh', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<IonButton disabled={disableForwardLoginButton} onClick={handleForwardLoginPage}>
|
||||
Login
|
||||
</IonButton>
|
||||
</div>
|
||||
</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default connect<OwnProps, StateProps, DispatchProps>({
|
||||
mapStateToProps: (state) => ({
|
||||
speakers: selectors.getSpeakers(state),
|
||||
speakerSessions: selectors.getSpeakerSessions(state),
|
||||
}),
|
||||
component: React.memo(MyProfile),
|
||||
});
|
@@ -49,6 +49,7 @@ 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 {}
|
||||
|
||||
@@ -63,6 +64,7 @@ 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);
|
||||
@@ -92,6 +94,7 @@ const MyProfile: React.FC<SpeakerListProps> = ({ speakers, speakerSessions }) =>
|
||||
}, []);
|
||||
|
||||
if (!profile) return <>loading</>;
|
||||
if (profile.id == -1) return <NotLoggedIn />;
|
||||
|
||||
return (
|
||||
<IonPage id="speaker-list">
|
||||
|
@@ -7,34 +7,9 @@
|
||||
// - T.B.A.
|
||||
//
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
IonHeader,
|
||||
IonToolbar,
|
||||
IonContent,
|
||||
IonPage,
|
||||
IonButtons,
|
||||
IonMenuButton,
|
||||
IonButton,
|
||||
IonIcon,
|
||||
IonDatetime,
|
||||
IonSelectOption,
|
||||
IonList,
|
||||
IonItem,
|
||||
IonLabel,
|
||||
IonSelect,
|
||||
IonPopover,
|
||||
IonText,
|
||||
IonFooter,
|
||||
useIonRouter,
|
||||
} from '@ionic/react';
|
||||
import { IonHeader, IonToolbar, IonContent, IonPage, IonButtons, IonMenuButton, IonButton, IonIcon, IonDatetime, IonSelectOption, IonList, IonItem, IonLabel, IonSelect, IonPopover, IonText, IonFooter, useIonRouter } from '@ionic/react';
|
||||
import './style.scss';
|
||||
import {
|
||||
chevronBackOutline,
|
||||
ellipsisHorizontal,
|
||||
ellipsisVertical,
|
||||
heart,
|
||||
logoIonic,
|
||||
} from 'ionicons/icons';
|
||||
import { chevronBackOutline, ellipsisHorizontal, ellipsisVertical, heart, logoIonic } from 'ionicons/icons';
|
||||
import AboutPopover from '../../components/AboutPopover';
|
||||
import { format, parseISO } from 'date-fns';
|
||||
import { TestContent } from './TestContent';
|
||||
@@ -60,12 +35,8 @@ interface Event {
|
||||
const EventDetail: React.FC<AboutProps> = () => {
|
||||
const [showPopover, setShowPopover] = useState(false);
|
||||
const [popoverEvent, setPopoverEvent] = useState<MouseEvent>();
|
||||
const [location, setLocation] = useState<
|
||||
'madison' | 'austin' | 'chicago' | 'seattle'
|
||||
>('madison');
|
||||
const [conferenceDate, setConferenceDate] = useState(
|
||||
'2047-05-17T00:00:00-05:00'
|
||||
);
|
||||
const [location, setLocation] = useState<'madison' | 'austin' | 'chicago' | 'seattle'>('madison');
|
||||
const [conferenceDate, setConferenceDate] = useState('2047-05-17T00:00:00-05:00');
|
||||
|
||||
const selectOptions = {
|
||||
header: 'Select a Location',
|
||||
@@ -95,8 +66,6 @@ const EventDetail: React.FC<AboutProps> = () => {
|
||||
router.goBack();
|
||||
}
|
||||
|
||||
if (!eventDetail) return <>loading</>;
|
||||
|
||||
return (
|
||||
<IonPage id="about-page">
|
||||
<IonContent>
|
||||
@@ -110,11 +79,7 @@ const EventDetail: React.FC<AboutProps> = () => {
|
||||
</IonButtons>
|
||||
<IonButtons slot="end">
|
||||
<IonButton onClick={presentPopover}>
|
||||
<IonIcon
|
||||
slot="icon-only"
|
||||
ios={ellipsisHorizontal}
|
||||
md={ellipsisVertical}
|
||||
></IonIcon>
|
||||
<IonIcon slot="icon-only" ios={ellipsisHorizontal} md={ellipsisVertical}></IonIcon>
|
||||
</IonButton>
|
||||
</IonButtons>
|
||||
</IonToolbar>
|
||||
@@ -143,7 +108,8 @@ const EventDetail: React.FC<AboutProps> = () => {
|
||||
backgroundPosition: 'center',
|
||||
}}
|
||||
></div>
|
||||
Sorry but Not implemented
|
||||
Sorry this feature
|
||||
<br /> Not implemented
|
||||
<IonButton onClick={handleBackOnClick} fill="clear" size="large">
|
||||
<IonIcon icon={chevronBackOutline} slot="start"></IonIcon>
|
||||
Back
|
||||
|
@@ -38,17 +38,11 @@ import '../SpeakerList.scss';
|
||||
import { getEvents } from '../../api/getEvents';
|
||||
import { format } from 'date-fns';
|
||||
import { Order } from './types';
|
||||
import {
|
||||
chevronBackOutline,
|
||||
chevronDownCircleOutline,
|
||||
chevronForwardOutline,
|
||||
heart,
|
||||
logoIonic,
|
||||
menuOutline,
|
||||
} from 'ionicons/icons';
|
||||
import { bookmarksOutline, chevronBackOutline, chevronDownCircleOutline, chevronForwardOutline, heart, logoIonic, menuOutline } from 'ionicons/icons';
|
||||
import AboutPopover from '../../components/AboutPopover';
|
||||
import { getOrders } from '../../api/getOrders';
|
||||
import Loading from '../../components/Loading';
|
||||
import paths from '../../paths';
|
||||
|
||||
interface OwnProps {}
|
||||
|
||||
@@ -61,17 +55,14 @@ interface DispatchProps {}
|
||||
|
||||
interface SpeakerListProps extends OwnProps, StateProps, DispatchProps {}
|
||||
|
||||
const EventList: React.FC<SpeakerListProps> = ({
|
||||
speakers,
|
||||
speakerSessions,
|
||||
}) => {
|
||||
const [orders, setEvents] = useState<Order[] | []>([]);
|
||||
const EventList: React.FC<SpeakerListProps> = ({ speakers, speakerSessions }) => {
|
||||
const router = useIonRouter();
|
||||
const [orders, setEvents] = useState<Order[]>([]);
|
||||
|
||||
const [showPopover, setShowPopover] = useState(false);
|
||||
const [popoverEvent, setPopoverEvent] = useState<MouseEvent>();
|
||||
const modal = useRef<HTMLIonModalElement>(null);
|
||||
|
||||
const router = useIonRouter();
|
||||
|
||||
useEffect(() => {
|
||||
getOrders().then(({ data }) => {
|
||||
console.log({ data });
|
||||
@@ -86,8 +77,16 @@ const EventList: React.FC<SpeakerListProps> = ({
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function handleShowOrderDetail(event_id: string) {
|
||||
router.push(`/order_detail/${event_id}`);
|
||||
function handleShowOrderDetail(order_id: string) {
|
||||
router.push(paths.getOrderDetail(order_id));
|
||||
}
|
||||
|
||||
function handleNotImplemented() {
|
||||
router.push(paths.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
function handleBookmarksClick() {
|
||||
router.push(paths.FAVOURITES_LIST);
|
||||
}
|
||||
|
||||
if (!orders) return <Loading />;
|
||||
@@ -96,18 +95,19 @@ const EventList: React.FC<SpeakerListProps> = ({
|
||||
<IonPage id="speaker-list">
|
||||
<IonHeader translucent={true} className="ion-no-border">
|
||||
<IonToolbar>
|
||||
<IonButtons slot="end">
|
||||
{/* <IonMenuButton /> */}
|
||||
<IonButton shape="round" expand="block" onClick={handleBookmarksClick}>
|
||||
<IonIcon slot="icon-only" icon={bookmarksOutline}></IonIcon>
|
||||
</IonButton>
|
||||
</IonButtons>
|
||||
<IonTitle>My Orders</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
|
||||
<IonContent fullscreen={true}>
|
||||
<IonRefresher slot="fixed" onIonRefresh={handleRefresh}>
|
||||
<IonRefresherContent
|
||||
pullingIcon={chevronDownCircleOutline}
|
||||
pullingText="Pull to refresh"
|
||||
refreshingSpinner="circles"
|
||||
refreshingText="Refreshing..."
|
||||
></IonRefresherContent>
|
||||
<IonRefresherContent pullingIcon={chevronDownCircleOutline} pullingText="Pull to refresh" refreshingSpinner="circles" refreshingText="Refreshing..."></IonRefresherContent>
|
||||
</IonRefresher>
|
||||
|
||||
<IonHeader collapse="condense">
|
||||
@@ -116,94 +116,73 @@ const EventList: React.FC<SpeakerListProps> = ({
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
|
||||
<IonGrid fixed>
|
||||
<IonRow>
|
||||
{orders.map((order, idx) => (
|
||||
<IonCol size="12" size-md="6" key={idx}>
|
||||
<div>
|
||||
<IonList>
|
||||
{orders.map((order, idx) => (
|
||||
<IonItem button onClick={handleNotImplemented}>
|
||||
<div
|
||||
style={{
|
||||
paddingBottom: '1rem',
|
||||
paddingTop: '1rem',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
gap: '1rem',
|
||||
}}
|
||||
>
|
||||
<div style={{ width: '70px' }}>
|
||||
<IonAvatar>
|
||||
<img alt="Silhouette of a person's head" src="https://plus.unsplash.com/premium_photo-1683121126477-17ef068309bc" />
|
||||
</IonAvatar>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '1rem',
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<div style={{ width: '70px' }}>
|
||||
<IonAvatar>
|
||||
<img
|
||||
alt="Silhouette of a person's head"
|
||||
src="https://plus.unsplash.com/premium_photo-1683121126477-17ef068309bc"
|
||||
/>
|
||||
</IonAvatar>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: '1.2rem' }}>{order.title}</div>
|
||||
<IonButton shape="round" onClick={() => handleShowOrderDetail('1')} size="small" fill="clear">
|
||||
<IonIcon slot="icon-only" icon={chevronForwardOutline} size="small"></IonIcon>
|
||||
</IonButton>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '1rem',
|
||||
flexGrow: 1,
|
||||
gap: '0.33rem',
|
||||
fontSize: '0.9rem',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: '1.2rem' }}>{order.title}</div>
|
||||
<IonButton
|
||||
shape="round"
|
||||
onClick={() => handleShowOrderDetail('1')}
|
||||
size="small"
|
||||
fill="clear"
|
||||
>
|
||||
<IonIcon
|
||||
slot="icon-only"
|
||||
icon={chevronForwardOutline}
|
||||
size="small"
|
||||
></IonIcon>
|
||||
</IonButton>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '0.33rem',
|
||||
fontSize: '0.9rem',
|
||||
}}
|
||||
>
|
||||
<div>Order time: {order.createdAt} </div>
|
||||
<div>Last payment date: {order.last_payment_date}</div>
|
||||
<div>Number of applicants: 38 </div>
|
||||
<div>Remaining dates: 50 </div>
|
||||
<div>
|
||||
<IonButton fill="outline">{order.status}</IonButton>
|
||||
</div>
|
||||
<div>Order time: {order.createdAt} </div>
|
||||
<div>Last payment date: {order.last_payment_date}</div>
|
||||
<div>Number of applicants: 38 </div>
|
||||
<div>Remaining dates: 50 </div>
|
||||
<div>
|
||||
<IonButton fill="outline">{order.status}</IonButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
borderBottom: '1px solid lightgray',
|
||||
marginTop: '0.5rem',
|
||||
marginBottom: '0.5rem',
|
||||
}}
|
||||
></div>
|
||||
</IonCol>
|
||||
))}
|
||||
</IonRow>
|
||||
</IonGrid>
|
||||
</div>
|
||||
</IonItem>
|
||||
))}
|
||||
</IonList>
|
||||
</IonContent>
|
||||
|
||||
{/* REQ0079/event-filter */}
|
||||
<IonModal
|
||||
ref={modal}
|
||||
trigger="open-modal"
|
||||
initialBreakpoint={0.5}
|
||||
breakpoints={[0, 0.25, 0.5, 0.75]}
|
||||
>
|
||||
<IonModal ref={modal} trigger="open-modal" initialBreakpoint={0.5} breakpoints={[0, 0.25, 0.5, 0.75]}>
|
||||
<IonContent className="ion-padding">
|
||||
<div
|
||||
style={{
|
||||
@@ -255,10 +234,7 @@ const EventList: React.FC<SpeakerListProps> = ({
|
||||
<IonButton shape="round">All</IonButton>
|
||||
</div>
|
||||
|
||||
<IonButton
|
||||
shape="round"
|
||||
style={{ marginTop: '1rem', marginBottom: '1rem' }}
|
||||
>
|
||||
<IonButton shape="round" style={{ marginTop: '1rem', marginBottom: '1rem' }}>
|
||||
Apply
|
||||
</IonButton>
|
||||
</div>
|
||||
|
@@ -31,13 +31,14 @@ import {
|
||||
} from '@ionic/react';
|
||||
import SpeakerItem from '../../components/SpeakerItem';
|
||||
import { Speaker } from '../../models/Speaker';
|
||||
import { Order } from '../../models/Order';
|
||||
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 { Order } from './types';
|
||||
// import { Order } from './types';
|
||||
import { bookmarksOutline, chevronBackOutline, chevronDownCircleOutline, chevronForwardOutline, heart, logoIonic, menuOutline } from 'ionicons/icons';
|
||||
import AboutPopover from '../../components/AboutPopover';
|
||||
import { getOrders } from '../../api/getOrders';
|
||||
@@ -47,7 +48,8 @@ import paths from '../../paths';
|
||||
interface OwnProps {}
|
||||
|
||||
interface StateProps {
|
||||
speakers: Speaker[];
|
||||
orders: Order[];
|
||||
//
|
||||
speakerSessions: { [key: string]: Session[] };
|
||||
}
|
||||
|
||||
@@ -55,19 +57,93 @@ interface DispatchProps {}
|
||||
|
||||
interface SpeakerListProps extends OwnProps, StateProps, DispatchProps {}
|
||||
|
||||
const EventList: React.FC<SpeakerListProps> = ({ speakers, speakerSessions }) => {
|
||||
const RemainingDays: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
return (
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div>#Rem:</div>
|
||||
<div>{amount}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const NumApplicants: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
return (
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div>#app. :</div>
|
||||
<div>{amount}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const TotalAmount: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
return (
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '1.1rem' }}>
|
||||
<div style={{ display: 'flex', gap: '1rem', fontWeight: 'bold', fontSize: '1.2rem', opacity: 0.8 }}>
|
||||
<div>Total:</div>
|
||||
<div style={{ minWidth: '75px', display: 'inline-flex', justifyContent: 'flex-end' }}>{amount} </div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Subtotal HK$83.74
|
||||
const Subtotal: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
return (
|
||||
<div style={{ display: 'flex', gap: '0.5rem', justifyContent: 'flex-end' }}>
|
||||
<div>Subtotal:</div>
|
||||
<div style={{ minWidth: '50px', display: 'inline-flex', justifyContent: 'flex-end' }}>{amount} </div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Shipping - HK$10
|
||||
const Shipping: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
return (
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<div style={{ display: 'flex', gap: '1rem', fontWeight: 'bold' }}>
|
||||
<div>Shipping:</div>
|
||||
<div style={{ minWidth: '50px', display: 'inline-flex', justifyContent: 'flex-end' }}>{amount} </div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Discount - HK$10
|
||||
const Discount: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
return (
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<div style={{ display: 'flex', gap: '1rem', fontWeight: 'bold' }}>
|
||||
<div>Discount:</div>
|
||||
<div style={{ minWidth: '50px', display: 'inline-flex', justifyContent: 'flex-end' }}>{amount} </div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Taxes HK$10
|
||||
const Tax: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
return (
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<div style={{ display: 'flex', gap: '1rem', fontWeight: 'bold' }}>
|
||||
<div>Tax:</div>
|
||||
<div style={{ minWidth: '50px', display: 'inline-flex', justifyContent: 'flex-end' }}>{amount} </div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const EventList: React.FC<SpeakerListProps> = ({ orders, speakerSessions }) => {
|
||||
const router = useIonRouter();
|
||||
const [orders, setEvents] = useState<Order[] | []>([]);
|
||||
|
||||
const [showPopover, setShowPopover] = useState(false);
|
||||
const [popoverEvent, setPopoverEvent] = useState<MouseEvent>();
|
||||
const modal = useRef<HTMLIonModalElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
getOrders().then(({ data }) => {
|
||||
console.log({ data });
|
||||
setEvents(data);
|
||||
});
|
||||
// getOrders().then(({ data }) => {
|
||||
// console.log({ data });
|
||||
// setEvents(data);
|
||||
// });
|
||||
}, []);
|
||||
|
||||
function handleRefresh(event: CustomEvent<RefresherEventDetail>) {
|
||||
@@ -119,58 +195,68 @@ const EventList: React.FC<SpeakerListProps> = ({ speakers, speakerSessions }) =>
|
||||
<IonList>
|
||||
{orders.map((order, idx) => (
|
||||
<IonItem button onClick={handleNotImplemented}>
|
||||
<div
|
||||
style={{
|
||||
paddingBottom: '1rem',
|
||||
paddingTop: '1rem',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
gap: '1rem',
|
||||
}}
|
||||
>
|
||||
<div style={{ width: '70px' }}>
|
||||
<IonAvatar>
|
||||
<img alt="Silhouette of a person's head" src="https://plus.unsplash.com/premium_photo-1683121126477-17ef068309bc" />
|
||||
</IonAvatar>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '1rem',
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: '1.2rem' }}>{order.title}</div>
|
||||
<IonButton shape="round" onClick={() => handleShowOrderDetail('1')} size="small" fill="clear">
|
||||
<IonIcon slot="icon-only" icon={chevronForwardOutline} size="small"></IonIcon>
|
||||
</IonButton>
|
||||
<div style={{ paddingBottom: '1rem', paddingTop: '1rem' }}>
|
||||
<div style={{ display: 'flex', gap: '0.5rem', width: 'calc( 100vw - 35px )' }}>
|
||||
<div style={{}}>
|
||||
<div>
|
||||
<div style={{ width: '70px' }}>
|
||||
<IonAvatar>
|
||||
<img alt="Silhouette of a person's head" src="https://plus.unsplash.com/premium_photo-1683121126477-17ef068309bc" />
|
||||
</IonAvatar>
|
||||
<div style={{ marginTop: '1rem', display: 'inline-flex', flexDirection: 'column', gap: '0.5rem' }}>
|
||||
<NumApplicants amount={38} />
|
||||
<RemainingDays amount={50} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<div
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
//
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '0.33rem',
|
||||
fontSize: '0.9rem',
|
||||
gap: '1rem',
|
||||
}}
|
||||
>
|
||||
<div>Order time: {order.createdAt} </div>
|
||||
<div>Last payment date: {order.last_payment_date}</div>
|
||||
<div>Number of applicants: 38 </div>
|
||||
<div>Remaining dates: 50 </div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: '1.2rem' }}>{order.orderNumber}</div>
|
||||
<IonButton shape="round" onClick={() => handleShowOrderDetail('1')} size="small" fill="clear">
|
||||
<IonIcon slot="icon-only" icon={chevronForwardOutline} size="small"></IonIcon>
|
||||
</IonButton>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '0.33rem',
|
||||
fontSize: '0.9rem',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'inline-flex', gap: '0.5rem' }}>
|
||||
<div style={{ fontWeight: 'bold' }}>Order time:</div>
|
||||
<div>{order.createdAt.split('T')[0]}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontWeight: 'bold' }}>Last payment date:</div>
|
||||
<div>{order.last_payment_date}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<IonButton fill="outline">{order.status}</IonButton>
|
||||
<Subtotal amount={order.subtotal} />
|
||||
<Shipping amount={order.shipping} />
|
||||
<Discount amount={order.discount} />
|
||||
<Tax amount={order.taxes} />
|
||||
<TotalAmount amount={order.totalAmount} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -180,73 +266,14 @@ const EventList: React.FC<SpeakerListProps> = ({ speakers, speakerSessions }) =>
|
||||
))}
|
||||
</IonList>
|
||||
</IonContent>
|
||||
|
||||
{/* REQ0079/event-filter */}
|
||||
<IonModal ref={modal} trigger="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),
|
||||
orders: selectors.getOrders(state),
|
||||
// TODO: review below
|
||||
speakerSessions: selectors.getSpeakerSessions(state),
|
||||
}),
|
||||
component: React.memo(EventList),
|
||||
|
Reference in New Issue
Block a user