"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:
@@ -0,0 +1,12 @@
|
||||
import { IonIcon } from '@ionic/react';
|
||||
import { woman } from 'ionicons/icons';
|
||||
import React from 'react';
|
||||
|
||||
export function NumOfFemaleMemberJoin({ joinMembers }) {
|
||||
return (
|
||||
<>
|
||||
<IonIcon icon={woman} style={{ fontSize: '1.1rem', color: 'rgb(235, 50, 35)' }}></IonIcon>
|
||||
<div>{joinMembers.filter((jm) => jm.sex == 'F').length}</div>
|
||||
</>
|
||||
);
|
||||
}
|
12
03_source/mobile/src/pages/EventList/NumOfMaleMemberJoin.tsx
Normal file
12
03_source/mobile/src/pages/EventList/NumOfMaleMemberJoin.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { IonIcon } from '@ionic/react';
|
||||
import { man } from 'ionicons/icons';
|
||||
import React from 'react';
|
||||
|
||||
export function NumOfMaleMemberJoin({ joinMembers }) {
|
||||
return (
|
||||
<>
|
||||
<IonIcon icon={man} style={{ fontSize: '1.1rem', color: 'rgb(67, 110, 205)' }}></IonIcon>
|
||||
<div>{joinMembers.filter((jm) => jm.sex == 'M').length}</div>
|
||||
</>
|
||||
);
|
||||
}
|
15
03_source/mobile/src/pages/EventList/NumOfMemberJoin.tsx
Normal file
15
03_source/mobile/src/pages/EventList/NumOfMemberJoin.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { IonIcon } from '@ionic/react';
|
||||
import { accessibility } from 'ionicons/icons';
|
||||
import React from 'react';
|
||||
|
||||
export function NumOfMemberJoin({ joinMembers }) {
|
||||
return (
|
||||
<>
|
||||
<IonIcon
|
||||
icon={accessibility}
|
||||
style={{ fontSize: '1.1rem', color: 'rgb(139, 44, 245)' }}
|
||||
></IonIcon>
|
||||
<div>{joinMembers.length}</div>
|
||||
</>
|
||||
);
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
// REQ0041/home_discover_event_tab
|
||||
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import {
|
||||
IonHeader,
|
||||
IonToolbar,
|
||||
@@ -8,54 +8,49 @@ import {
|
||||
IonContent,
|
||||
IonPage,
|
||||
IonButtons,
|
||||
IonMenuButton,
|
||||
IonGrid,
|
||||
IonRow,
|
||||
IonCol,
|
||||
useIonRouter,
|
||||
IonButton,
|
||||
IonIcon,
|
||||
IonPopover,
|
||||
IonAvatar,
|
||||
IonImg,
|
||||
IonItem,
|
||||
IonLabel,
|
||||
IonList,
|
||||
IonModal,
|
||||
IonSearchbar,
|
||||
useIonModal,
|
||||
IonInput,
|
||||
IonRefresher,
|
||||
IonRefresherContent,
|
||||
RefresherEventDetail,
|
||||
} 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 { chevronDownCircleOutline, heart, menuOutline } from 'ionicons/icons';
|
||||
import AboutPopover from '../../components/AboutPopover';
|
||||
|
||||
// import { Event } from './types';
|
||||
import { chevronDownCircleOutline, menuOutline } from 'ionicons/icons';
|
||||
import Loading from '../../components/Loading';
|
||||
import { Event } from '../../models/Event';
|
||||
//
|
||||
import { NumOfMemberJoin } from './NumOfMemberJoin';
|
||||
import { NumOfMaleMemberJoin } from './NumOfMaleMemberJoin';
|
||||
import { NumOfFemaleMemberJoin } from './NumOfFemaleMemberJoin';
|
||||
|
||||
interface OwnProps {}
|
||||
|
||||
interface StateProps {
|
||||
events: Event[];
|
||||
fetchEventResult: any;
|
||||
}
|
||||
|
||||
interface DispatchProps {}
|
||||
|
||||
interface SpeakerListProps extends OwnProps, StateProps, DispatchProps {}
|
||||
|
||||
const EventList: React.FC<SpeakerListProps> = ({ events }) => {
|
||||
const EventList: React.FC<SpeakerListProps> = ({ fetchEventResult }) => {
|
||||
const router = useIonRouter();
|
||||
const modal = useRef<HTMLIonModalElement>(null);
|
||||
|
||||
const router = useIonRouter();
|
||||
const {
|
||||
result: { status },
|
||||
data: { events },
|
||||
} = fetchEventResult;
|
||||
|
||||
function handleShowPartyEventDetail(event_id: string) {
|
||||
router.push(`/event_detail/${event_id}`);
|
||||
@@ -68,6 +63,9 @@ const EventList: React.FC<SpeakerListProps> = ({ events }) => {
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
if (status != 200)
|
||||
return <>Error during fetching event list, check /events endpoint if working</>;
|
||||
|
||||
if (!events || events.length == 0) return <Loading />;
|
||||
|
||||
return (
|
||||
@@ -84,9 +82,14 @@ const EventList: React.FC<SpeakerListProps> = ({ events }) => {
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
|
||||
<IonContent fullscreen={true}>
|
||||
<IonContent className="ion-padding" 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">
|
||||
@@ -101,35 +104,43 @@ const EventList: React.FC<SpeakerListProps> = ({ events }) => {
|
||||
<IonCol size="12" size-md="6" key={idx}>
|
||||
<div
|
||||
style={{
|
||||
padding: '1rem',
|
||||
border: '1px solid black',
|
||||
border: '1px solid lightgrey',
|
||||
borderRadius: '1rem',
|
||||
}}
|
||||
onClick={() => handleShowPartyEventDetail(event.id)}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
backgroundImage: `url("https://plus.unsplash.com/premium_photo-1683121126477-17ef068309bc")`,
|
||||
backgroundImage: `url(${event.avatar[0]})`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
height: '33vw',
|
||||
//
|
||||
borderRadius: '1rem 1rem 0 0',
|
||||
}}
|
||||
></div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '1rem',
|
||||
//
|
||||
marginTop: '1rem',
|
||||
}}
|
||||
>
|
||||
<div>{format(new Date(event.eventDate), 'yyyy-MM-dd')}</div>
|
||||
<div>{event.title}</div>
|
||||
<div>{event.currency}</div>
|
||||
<div>{event.price}</div>
|
||||
<div>
|
||||
{40} {20} {20}
|
||||
<div style={{ marginTop: '1rem' }}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '0.5rem',
|
||||
padding: '0.5rem',
|
||||
paddingBottom: '1rem',
|
||||
}}
|
||||
>
|
||||
{/* <div>{format(new Date(event.eve ntDate), 'yyyy-MM-dd')}</div> */}
|
||||
<div style={{ color: 'rgb(0, 122, 255)' }}>
|
||||
{format(new Date(event.eventDate), 'EEE, dd MMM yyyy, hh:mm a')}
|
||||
</div>
|
||||
<div style={{ fontSize: '1.2rem', fontWeight: 'bold' }}>{event.name}</div>
|
||||
<div style={{ fontSize: '1.2rem', fontWeight: 'bold' }}>{event.price}</div>
|
||||
|
||||
<div style={{ display: 'flex', gap: '0.25rem', alignItems: 'center' }}>
|
||||
<NumOfMemberJoin joinMembers={event.joinMembers} />
|
||||
<NumOfMaleMemberJoin joinMembers={event.joinMembers} />
|
||||
<NumOfFemaleMemberJoin joinMembers={event.joinMembers} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -140,7 +151,12 @@ const EventList: React.FC<SpeakerListProps> = ({ events }) => {
|
||||
</IonContent>
|
||||
|
||||
{/* REQ0079/event-filter */}
|
||||
<IonModal ref={modal} trigger="events-open-modal" initialBreakpoint={0.5} breakpoints={[0, 0.25, 0.5, 0.75]}>
|
||||
<IonModal
|
||||
ref={modal}
|
||||
trigger="events-open-modal"
|
||||
initialBreakpoint={0.5}
|
||||
breakpoints={[0, 0.25, 0.5, 0.75]}
|
||||
>
|
||||
<IonContent className="ion-padding">
|
||||
<div
|
||||
style={{
|
||||
@@ -203,8 +219,10 @@ const EventList: React.FC<SpeakerListProps> = ({ events }) => {
|
||||
};
|
||||
|
||||
export default connect<OwnProps, StateProps, DispatchProps>({
|
||||
mapStateToProps: (state) => ({
|
||||
events: selectors.getEvents(state),
|
||||
}),
|
||||
mapStateToProps: (state) => {
|
||||
return {
|
||||
fetchEventResult: selectors.getEvents(state),
|
||||
};
|
||||
},
|
||||
component: React.memo(EventList),
|
||||
});
|
||||
|
@@ -1,4 +1,5 @@
|
||||
export interface Event {
|
||||
// OBSOLETED
|
||||
export interface EventOBSOLETED {
|
||||
eventDate: Date;
|
||||
joinMembers: undefined;
|
||||
title: string;
|
||||
|
Reference in New Issue
Block a user