adding load more button to flights page (#114)
This commit was merged in pull request #114.
This commit is contained in:
@@ -5,39 +5,72 @@ import { LogbookEntry } from "../logbook/LogbookEntry.interface";
|
||||
import { initialState, reducer } from "./reducer";
|
||||
import { useOidc } from "../../auth/oidcConfig";
|
||||
import Alert from "../alert/Alert";
|
||||
import { AxiosError, AxiosResponse } from "axios";
|
||||
import httpClient from "../../httpClient/httpClient";
|
||||
import { useBreakpoints } from "../../hooks/useBreakpoints/UseBreakpoints";
|
||||
import { ScreenSize } from "../../enums/screenSize";
|
||||
|
||||
const Flights = () => {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const { logs, logsLoading } = useLogs();
|
||||
const { isUserLoggedIn } = useOidc();
|
||||
const { screenSize } = useBreakpoints();
|
||||
|
||||
const getFlights = async (pageIndex: number, pageSize: number) => {
|
||||
try {
|
||||
const response: AxiosResponse = await httpClient.get(`api/logs/tracks`, {
|
||||
params: {
|
||||
skip: pageIndex,
|
||||
take: pageSize
|
||||
}
|
||||
});
|
||||
const flights: LogbookEntry[] = response.data.entities;
|
||||
const hasMore: boolean = response.data.hasNextPage;
|
||||
const total: number = response.data.total;
|
||||
|
||||
if (flights.length > 0) {
|
||||
const newFlights: LogbookEntry[] = [...state.flights, ...flights]
|
||||
const newPageIndex: number = state.pageIndex + flights.length;
|
||||
|
||||
dispatch({ type: 'SET_FLIGHTS', payload: { flights: newFlights, hasMoreFlights: hasMore, pageIndex: newPageIndex, totalFlights: total }})
|
||||
|
||||
if (!isUserLoggedIn && flights.length >= 5) {
|
||||
dispatch({ type: 'SET_ALERT', payload: { severity: 'info', message: 'A limited number of flights displayed. Sign in to view all flights.'}})
|
||||
} else {
|
||||
dispatch({ type: 'SET_ALERT', payload: undefined })
|
||||
}
|
||||
} else {
|
||||
dispatch({ type: 'SET_ALERT', payload: { severity: 'info', message: 'No flights found' }})
|
||||
}
|
||||
} catch (error) {
|
||||
const axiosError = error as AxiosError;
|
||||
|
||||
dispatch({
|
||||
type: 'SET_ALERT',
|
||||
payload: { severity: 'error', message: `Loading of flights failed with the following message: ${axiosError.message}`}
|
||||
});
|
||||
} finally {
|
||||
dispatch({ type: 'SET_IS_LOADING', payload: false })
|
||||
}
|
||||
}
|
||||
|
||||
const loadMore = () => {
|
||||
getFlights(state.pageIndex, state.pageSize)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getFlights(state.pageIndex, state.pageSize);
|
||||
}, [])
|
||||
|
||||
const flights: LogbookEntry[] | undefined = logs?.filter((log: LogbookEntry) => {
|
||||
if (log.tracks && log.tracks.length > 0) {
|
||||
return log;
|
||||
}
|
||||
})
|
||||
|
||||
if (flights && flights.length > 0) {
|
||||
dispatch({ type: 'SET_FLIGHTS', payload: flights})
|
||||
|
||||
if (!isUserLoggedIn && flights.length >= 5) {
|
||||
dispatch({ type: 'SET_ALERT', payload: { severity: 'info', message: 'A limited number of flights displayed. Sign in to view all flights.'}})
|
||||
} else {
|
||||
dispatch({ type: 'SET_ALERT', payload: undefined })
|
||||
}
|
||||
} else {
|
||||
dispatch({ type: 'SET_ALERT', payload: { severity: 'info', message: 'No flights found' }})
|
||||
}
|
||||
}, [logs])
|
||||
useEffect(() => {
|
||||
console.log(screenSize)
|
||||
}, [screenSize])
|
||||
|
||||
return (
|
||||
<div className='max-w-screen-lg mx-auto'>
|
||||
<div className={`max-w-screen-lg mx-auto ${screenSize === ScreenSize.SM || screenSize === ScreenSize.MD? 'mr-4 ml-4' : ''}`}>
|
||||
<div className='prose mt-5 mb-5'>
|
||||
<h1>Flights</h1>
|
||||
</div>
|
||||
{!logsLoading && state.alert && (
|
||||
{!state.isLoading && state.alert && (
|
||||
<div>
|
||||
<Alert
|
||||
className='mb-5'
|
||||
@@ -50,14 +83,21 @@ const Flights = () => {
|
||||
</Alert>
|
||||
</div>
|
||||
)}
|
||||
{!logsLoading &&
|
||||
{!state.isLoading &&
|
||||
<div>
|
||||
<LogbookCard logs={state.flights} mode='flights' />
|
||||
<div>
|
||||
<LogbookCard logs={state.flights} mode='flights' />
|
||||
</div>
|
||||
{state.hasMoreFlights &&
|
||||
<div className='flex items-center justify-center mb-5'>
|
||||
<button className='btn btn-link' onClick={loadMore}>Load more</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
{logsLoading && [...Array(5)].map((_element, index) => {
|
||||
{state.isLoading && [...Array(5)].map((_element, index) => {
|
||||
return (
|
||||
<div className='card bg-base-100 border border-base-300 p-2 mb-7'>
|
||||
<div className='card bg-base-100 border border-base-300 p-2 mb-5'>
|
||||
<div className='card-body' key={index}>
|
||||
<div className='skeleton h-10 w-[150px]' />
|
||||
<div className='skeleton h-[350px]' />
|
||||
|
||||
@@ -5,4 +5,8 @@ export interface FlightsState {
|
||||
alert: Alert | undefined;
|
||||
flights: LogbookEntry[];
|
||||
isLoading: boolean;
|
||||
hasMoreFlights: boolean;
|
||||
pageIndex: number;
|
||||
pageSize: number
|
||||
totalFlights: number;
|
||||
}
|
||||
@@ -5,13 +5,17 @@ import { FlightsState } from "./FlightsState.interface";
|
||||
|
||||
type Action =
|
||||
| { type: 'SET_ALERT'; payload: Alert | undefined }
|
||||
| { type: 'SET_FLIGHTS'; payload: LogbookEntry[] }
|
||||
| { type: 'SET_FLIGHTS'; payload: { flights: LogbookEntry[], hasMoreFlights: boolean, pageIndex: number, totalFlights: number } }
|
||||
| { type: 'SET_IS_LOADING'; payload: boolean }
|
||||
|
||||
export const initialState: FlightsState = {
|
||||
alert: undefined,
|
||||
flights: [],
|
||||
isLoading: true
|
||||
isLoading: true,
|
||||
hasMoreFlights: true,
|
||||
pageIndex: 0,
|
||||
pageSize: 5,
|
||||
totalFlights: 0
|
||||
}
|
||||
|
||||
export const reducer = (
|
||||
@@ -28,7 +32,10 @@ export const reducer = (
|
||||
case 'SET_FLIGHTS': {
|
||||
return {
|
||||
...state,
|
||||
flights: action.payload
|
||||
flights: action.payload.flights,
|
||||
hasMoreFlights: action.payload.hasMoreFlights,
|
||||
pageIndex: action.payload.pageIndex,
|
||||
totalFlights: action.payload.totalFlights
|
||||
}
|
||||
}
|
||||
case 'SET_IS_LOADING': {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { LogbookCardProps } from "./LogbookCardProps.interface";
|
||||
import TrackMap from "../trackMap/TrackMap";
|
||||
import { useBreakpoints } from "../../hooks/useBreakpoints/UseBreakpoints";
|
||||
import { ScreenSize } from "../../enums/screenSize";
|
||||
import { useEffect } from "react";
|
||||
|
||||
const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps) => {
|
||||
const { screenSize } = useBreakpoints();
|
||||
|
||||
return (
|
||||
<div>
|
||||
{logs.map((log) => {
|
||||
@@ -9,8 +14,8 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps
|
||||
const formattedDate: string = `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`;
|
||||
|
||||
return (
|
||||
<div className='card bg-base-100 border border-base-300 p-2'>
|
||||
<div className='card-body' key={log.id}>
|
||||
<div className='card bg-base-100 border border-base-300 p-2 mb-5'>
|
||||
<div className={`card-body ${screenSize === ScreenSize.SM || screenSize === ScreenSize.MD ? 'p-2' : ''}`} key={log.id}>
|
||||
<h2 className='card-title font-bold text-2xl'>{formattedDate}</h2>
|
||||
<div>
|
||||
{mode === 'flights' && log.tracks && log.tracks.length > 0 &&
|
||||
@@ -24,10 +29,10 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps
|
||||
}
|
||||
</div>
|
||||
<div className='collapse collapse-arrow bg-base-100 border-base-300 border'>
|
||||
<input type='radio' name='details-accordion' />
|
||||
<input type='checkbox' />
|
||||
<div className='collapse-title font-semibold'>Details</div>
|
||||
<div className='collapse-content'>
|
||||
<div className='grid grid-cols-12 gap-3 mr-[30%] ml-[30%] mt-4 mb-4'>
|
||||
<div className={`grid grid-cols-12 gap-3 ${screenSize === ScreenSize.SM || screenSize === ScreenSize.MD ? 'mr-[5%] ml-[5%]' : 'mr-[30%] ml-[30%]'} mt-4 mb-4`}>
|
||||
<div className='col-span-6 font-bold'>
|
||||
<span>Aircraft Make and Model</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user