168 lines
5.0 KiB
TypeScript
168 lines
5.0 KiB
TypeScript
import React, { useRef, useState } from 'react';
|
|
|
|
import {
|
|
IonButton,
|
|
IonButtons,
|
|
IonContent,
|
|
IonHeader,
|
|
IonIcon,
|
|
IonMenuButton,
|
|
IonModal,
|
|
IonPage,
|
|
IonRefresher,
|
|
IonRefresherContent,
|
|
IonSearchbar,
|
|
IonSegment,
|
|
IonSegmentButton,
|
|
IonTitle,
|
|
IonToast,
|
|
IonToolbar,
|
|
getConfig,
|
|
} from '@ionic/react';
|
|
import { options, search } from 'ionicons/icons';
|
|
|
|
import SessionList from '../components/SessionList';
|
|
import SessionListFilter from '../components/SessionListFilter';
|
|
import './SchedulePage.scss';
|
|
|
|
import ShareSocialFab from '../components/ShareSocialFab';
|
|
|
|
import { connect } from '../data/connect';
|
|
import * as selectors from '../data/selectors';
|
|
import { setSearchText } from '../data/sessions/sessions.actions';
|
|
import { Schedule } from '../models/Schedule';
|
|
|
|
interface OwnProps {}
|
|
|
|
interface StateProps {
|
|
schedule: Schedule;
|
|
favoritesSchedule: Schedule;
|
|
mode: 'ios' | 'md';
|
|
}
|
|
|
|
interface DispatchProps {
|
|
setSearchText: typeof setSearchText;
|
|
}
|
|
|
|
type SchedulePageProps = OwnProps & StateProps & DispatchProps;
|
|
|
|
const SchedulePage: React.FC<SchedulePageProps> = ({ favoritesSchedule, schedule, setSearchText, mode }) => {
|
|
const [segment, setSegment] = useState<'all' | 'favorites'>('all');
|
|
const [showSearchbar, setShowSearchbar] = useState<boolean>(false);
|
|
const [showFilterModal, setShowFilterModal] = useState(false);
|
|
const ionRefresherRef = useRef<HTMLIonRefresherElement>(null);
|
|
const [showCompleteToast, setShowCompleteToast] = useState(false);
|
|
|
|
const pageRef = useRef<HTMLElement>(null);
|
|
|
|
const ios = mode === 'ios';
|
|
|
|
const doRefresh = () => {
|
|
setTimeout(() => {
|
|
ionRefresherRef.current!.complete();
|
|
setShowCompleteToast(true);
|
|
}, 2500);
|
|
};
|
|
|
|
return (
|
|
<IonPage ref={pageRef} id="schedule-page">
|
|
<IonHeader translucent={true}>
|
|
<IonToolbar>
|
|
{!showSearchbar && (
|
|
<IonButtons slot="start">
|
|
<IonMenuButton />
|
|
</IonButtons>
|
|
)}
|
|
{ios && (
|
|
<IonSegment value={segment} onIonChange={e => setSegment(e.detail.value as any)}>
|
|
<IonSegmentButton value="all">All</IonSegmentButton>
|
|
<IonSegmentButton value="favorites">Favorites</IonSegmentButton>
|
|
</IonSegment>
|
|
)}
|
|
{!ios && !showSearchbar && <IonTitle>Schedule</IonTitle>}
|
|
{showSearchbar && (
|
|
<IonSearchbar
|
|
showCancelButton="always"
|
|
placeholder="Search"
|
|
onIonInput={(e: CustomEvent) => setSearchText(e.detail.value)}
|
|
onIonCancel={() => setShowSearchbar(false)}
|
|
></IonSearchbar>
|
|
)}
|
|
|
|
<IonButtons slot="end">
|
|
{!ios && !showSearchbar && (
|
|
<IonButton onClick={() => setShowSearchbar(true)}>
|
|
<IonIcon slot="icon-only" icon={search}></IonIcon>
|
|
</IonButton>
|
|
)}
|
|
{!showSearchbar && (
|
|
<IonButton onClick={() => setShowFilterModal(true)}>
|
|
{mode === 'ios' ? 'Filter' : <IonIcon icon={options} slot="icon-only" />}
|
|
</IonButton>
|
|
)}
|
|
</IonButtons>
|
|
</IonToolbar>
|
|
|
|
{!ios && (
|
|
<IonToolbar>
|
|
<IonSegment value={segment} onIonChange={e => setSegment(e.detail.value as any)}>
|
|
<IonSegmentButton value="all">All</IonSegmentButton>
|
|
<IonSegmentButton value="favorites">Favorites</IonSegmentButton>
|
|
</IonSegment>
|
|
</IonToolbar>
|
|
)}
|
|
</IonHeader>
|
|
|
|
<IonContent fullscreen={true}>
|
|
<IonHeader collapse="condense">
|
|
<IonToolbar>
|
|
<IonTitle size="large">Schedule</IonTitle>
|
|
</IonToolbar>
|
|
<IonToolbar>
|
|
<IonSearchbar
|
|
placeholder="Search"
|
|
onIonInput={(e: CustomEvent) => setSearchText(e.detail.value)}
|
|
></IonSearchbar>
|
|
</IonToolbar>
|
|
</IonHeader>
|
|
|
|
<IonRefresher slot="fixed" ref={ionRefresherRef} onIonRefresh={doRefresh}>
|
|
<IonRefresherContent />
|
|
</IonRefresher>
|
|
|
|
<IonToast
|
|
isOpen={showCompleteToast}
|
|
message="Refresh complete"
|
|
duration={2000}
|
|
onDidDismiss={() => setShowCompleteToast(false)}
|
|
/>
|
|
|
|
<SessionList schedule={schedule} listType={segment} hide={segment === 'favorites'} />
|
|
<SessionList schedule={favoritesSchedule} listType={segment} hide={segment === 'all'} />
|
|
</IonContent>
|
|
|
|
<IonModal
|
|
isOpen={showFilterModal}
|
|
onDidDismiss={() => setShowFilterModal(false)}
|
|
presentingElement={pageRef.current!}
|
|
>
|
|
<SessionListFilter onDismissModal={() => setShowFilterModal(false)} />
|
|
</IonModal>
|
|
|
|
<ShareSocialFab />
|
|
</IonPage>
|
|
);
|
|
};
|
|
|
|
export default connect<OwnProps, StateProps, DispatchProps>({
|
|
mapStateToProps: state => ({
|
|
schedule: selectors.getSearchedSchedule(state),
|
|
favoritesSchedule: selectors.getGroupedFavorites(state),
|
|
mode: getConfig()!.get('mode'),
|
|
}),
|
|
mapDispatchToProps: {
|
|
setSearchText,
|
|
},
|
|
component: React.memo(SchedulePage),
|
|
});
|