adding load more button to flights page (#114)

This commit was merged in pull request #114.
This commit is contained in:
2026-03-21 10:43:44 -05:00
committed by GitHub
parent 477469831f
commit a9abb5863c
9 changed files with 473 additions and 69 deletions

View File

@@ -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]' />

View File

@@ -5,4 +5,8 @@ export interface FlightsState {
alert: Alert | undefined;
flights: LogbookEntry[];
isLoading: boolean;
hasMoreFlights: boolean;
pageIndex: number;
pageSize: number
totalFlights: number;
}

View File

@@ -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': {

View File

@@ -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>