"feat: rename 'createdDate' to 'createDate' across frontend, backend, and mobile codebases"
This commit is contained in:
@@ -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