"feat: update data APIs to fetch orders and events via fetch instead of axios, add Order and Event models, update selectors and reducers, add EventDetail page with joined members display"
This commit is contained in:
@@ -31,7 +31,7 @@ import {
|
||||
} from '@ionic/react';
|
||||
import SpeakerItem from '../../components/SpeakerItem';
|
||||
import { Speaker } from '../../models/Speaker';
|
||||
import { Order } from '../../models/Order';
|
||||
import { IOrderItem } from '../../models/Order';
|
||||
import { Session } from '../../models/Schedule';
|
||||
import { connect } from '../../data/connect';
|
||||
import * as selectors from '../../data/selectors';
|
||||
@@ -39,7 +39,15 @@ import '../SpeakerList.scss';
|
||||
import { getEvents } from '../../api/getEvents';
|
||||
import { format } from 'date-fns';
|
||||
// import { Order } from './types';
|
||||
import { bookmarksOutline, 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';
|
||||
@@ -48,7 +56,7 @@ import paths from '../../paths';
|
||||
interface OwnProps {}
|
||||
|
||||
interface StateProps {
|
||||
orders: Order[];
|
||||
fetchOrderResult: { result: { status: number; ok: boolean }; data: IOrderItem[] };
|
||||
//
|
||||
speakerSessions: { [key: string]: Session[] };
|
||||
}
|
||||
@@ -78,9 +86,19 @@ const NumApplicants: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
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
|
||||
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 style={{ minWidth: '75px', display: 'inline-flex', justifyContent: 'flex-end' }}>
|
||||
{amount}{' '}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -91,7 +109,9 @@ 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 style={{ minWidth: '50px', display: 'inline-flex', justifyContent: 'flex-end' }}>
|
||||
{amount}{' '}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -102,7 +122,9 @@ const Shipping: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
<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 style={{ minWidth: '50px', display: 'inline-flex', justifyContent: 'flex-end' }}>
|
||||
{amount}{' '}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -114,7 +136,9 @@ const Discount: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
<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 style={{ minWidth: '50px', display: 'inline-flex', justifyContent: 'flex-end' }}>
|
||||
{amount}{' '}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -126,25 +150,25 @@ const Tax: React.FC<{ amount: number }> = ({ amount }) => {
|
||||
<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 style={{ minWidth: '50px', display: 'inline-flex', justifyContent: 'flex-end' }}>
|
||||
{amount}{' '}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const EventList: React.FC<SpeakerListProps> = ({ orders, speakerSessions }) => {
|
||||
const OrderList: React.FC<SpeakerListProps> = ({ fetchOrderResult, speakerSessions }) => {
|
||||
const router = useIonRouter();
|
||||
|
||||
const [showPopover, setShowPopover] = useState(false);
|
||||
const [popoverEvent, setPopoverEvent] = useState<MouseEvent>();
|
||||
const modal = useRef<HTMLIonModalElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// getOrders().then(({ data }) => {
|
||||
// console.log({ data });
|
||||
// setEvents(data);
|
||||
// });
|
||||
}, []);
|
||||
const {
|
||||
result: { status },
|
||||
data: { orders },
|
||||
} = fetchOrderResult;
|
||||
|
||||
function handleRefresh(event: CustomEvent<RefresherEventDetail>) {
|
||||
setTimeout(() => {
|
||||
@@ -165,8 +189,13 @@ const EventList: React.FC<SpeakerListProps> = ({ orders, speakerSessions }) => {
|
||||
router.push(paths.FAVOURITES_LIST);
|
||||
}
|
||||
|
||||
if (status != 200)
|
||||
return <>Error during fetching order list, check /orders endpoint if working</>;
|
||||
|
||||
if (!orders) return <Loading />;
|
||||
|
||||
if (orders.length == 0) return <>order list is empty</>;
|
||||
|
||||
return (
|
||||
<IonPage id="speaker-list">
|
||||
<IonHeader translucent={true} className="ion-no-border">
|
||||
@@ -183,7 +212,12 @@ const EventList: React.FC<SpeakerListProps> = ({ orders, speakerSessions }) => {
|
||||
|
||||
<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">
|
||||
@@ -193,17 +227,27 @@ const EventList: React.FC<SpeakerListProps> = ({ orders, speakerSessions }) => {
|
||||
</IonHeader>
|
||||
|
||||
<IonList>
|
||||
{orders.map((order, idx) => (
|
||||
<IonItem button onClick={handleNotImplemented}>
|
||||
{orders.map((order: IOrderItem, idx: number) => (
|
||||
<IonItem button onClick={() => handleShowOrderDetail(order.id)} key={idx}>
|
||||
<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" />
|
||||
<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' }}>
|
||||
<div
|
||||
style={{
|
||||
marginTop: '1rem',
|
||||
display: 'inline-flex',
|
||||
flexDirection: 'column',
|
||||
gap: '0.5rem',
|
||||
}}
|
||||
>
|
||||
<NumApplicants amount={38} />
|
||||
<RemainingDays amount={50} />
|
||||
</div>
|
||||
@@ -228,8 +272,12 @@ const EventList: React.FC<SpeakerListProps> = ({ orders, speakerSessions }) => {
|
||||
}}
|
||||
>
|
||||
<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 shape="round" size="small" fill="clear">
|
||||
<IonIcon
|
||||
slot="icon-only"
|
||||
icon={chevronForwardOutline}
|
||||
size="small"
|
||||
></IonIcon>
|
||||
</IonButton>
|
||||
</div>
|
||||
|
||||
@@ -272,9 +320,9 @@ const EventList: React.FC<SpeakerListProps> = ({ orders, speakerSessions }) => {
|
||||
|
||||
export default connect<OwnProps, StateProps, DispatchProps>({
|
||||
mapStateToProps: (state) => ({
|
||||
orders: selectors.getOrders(state),
|
||||
// TODO: review below
|
||||
fetchOrderResult: selectors.getOrders(state),
|
||||
// TODO: review unused code
|
||||
speakerSessions: selectors.getSpeakerSessions(state),
|
||||
}),
|
||||
component: React.memo(EventList),
|
||||
component: React.memo(OrderList),
|
||||
});
|
||||
|
Reference in New Issue
Block a user