From ab304a469bfa69413f654d70ab0a9350df04f8d1 Mon Sep 17 00:00:00 2001 From: Noah Spannbauer Date: Wed, 20 Aug 2025 21:04:32 -0500 Subject: [PATCH] switching to sqlite --- .github/workflows/main.yaml | 44 +++--- api/package.json | 2 +- api/src/file/file.service.ts | 1 - api/src/log/interceptors/log.interceptor.ts | 15 +- api/src/log/log.dto.ts | 2 - api/src/log/log.service.ts | 6 +- api/src/track/track.controller.ts | 77 +++------- api/src/track/track.service.ts | 89 ++++++----- app/package.json | 2 +- app/src/components/flights/Flights.tsx | 3 +- .../components/logTrackMaps/LogTrackMaps.tsx | 19 +-- .../LogTrackMapsProps.interface.ts | 4 +- app/src/components/logTracks/LogTracks.tsx | 142 ++++++++++-------- .../logTracks/LogTracksProps.interface.ts | 2 +- .../logTracks/LogTracksState.interface.ts | 2 +- app/src/components/logTracks/reducer.ts | 2 +- app/src/components/logbook/ILogbookEntry.ts | 5 +- app/src/components/logbook/Logbook.tsx | 6 +- app/src/components/logbook/columns.tsx | 17 ++- .../components/logbookCard/LogbookCard.tsx | 23 +-- 20 files changed, 231 insertions(+), 232 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 40a9e70..b2f1a5b 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -19,17 +19,17 @@ jobs: version_number: ${{ github.run_id }} secrets: inherit - deploy-api: - name: deploy-api - needs: - - changes - - build-api - uses: ./.github/workflows/deploy.yaml - with: - app_name: flying-api - environment_name: test - version_number: ${{ github.run_id }} - secrets: inherit + # deploy-api: + # name: deploy-api + # needs: + # - changes + # - build-api + # uses: ./.github/workflows/deploy.yaml + # with: + # app_name: flying-api + # environment_name: test + # version_number: ${{ github.run_id }} + # secrets: inherit build-app: if: ${{ needs.changes.outputs.app == 'true' }} @@ -42,14 +42,14 @@ jobs: version_number: ${{ github.run_id }} secrets: inherit - deploy-app: - name: deploy-app - needs: - - changes - - build-app - uses: ./.github/workflows/deploy.yaml - with: - app_name: flying-app - environment_name: test - version_number: ${{ github.run_id }} - secrets: inherit + # deploy-app: + # name: deploy-app + # needs: + # - changes + # - build-app + # uses: ./.github/workflows/deploy.yaml + # with: + # app_name: flying-app + # environment_name: test + # version_number: ${{ github.run_id }} + # secrets: inherit diff --git a/api/package.json b/api/package.json index 77c46ea..3de2be7 100644 --- a/api/package.json +++ b/api/package.json @@ -1,6 +1,6 @@ { "name": "api", - "version": "1.4.0", + "version": "2.0.0-alpha", "description": "", "author": "", "private": true, diff --git a/api/src/file/file.service.ts b/api/src/file/file.service.ts index 52e6d88..9ae05fa 100644 --- a/api/src/file/file.service.ts +++ b/api/src/file/file.service.ts @@ -38,7 +38,6 @@ import { ConfigService } from '@nestjs/config'; } async uploadFile(file: Express.Multer.File, containerName: string, logId: string): Promise { - console.log(file) this.containerName = containerName; const blockBlobClient = await this.getBlobClient(`${logId}/${file.originalname}`); diff --git a/api/src/log/interceptors/log.interceptor.ts b/api/src/log/interceptors/log.interceptor.ts index ef95f79..5e1de72 100644 --- a/api/src/log/interceptors/log.interceptor.ts +++ b/api/src/log/interceptors/log.interceptor.ts @@ -1,23 +1,24 @@ import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common'; import { Observable, map } from 'rxjs'; +import { LogEntity } from '../log.entity'; export class LogInterceptor implements NestInterceptor { intercept(context: ExecutionContext, handler: CallHandler): Observable { const req = context.switchToHttp().getRequest(); const authHeader = req.headers.authorization; const token = authHeader && authHeader.split(' ')[1]; - console.log(token) if (!token) { return handler.handle().pipe( - map((data) => { + map((data: LogEntity[]) => { + if (data.length) { - const logs = data.map((log) => { + const logs = data.map((log: LogEntity) => { return { - partitionKey: log.partitionKey, - rowKey: log.rowKey, - pilotId: log.pilotId, - pilotName: log.pilotName, + id: log.id, + pilot: { + name: log.pilot.name + }, date: log.date, aircraftMakeModel: log.aircraftMakeModel, routeFrom: log.routeFrom, diff --git a/api/src/log/log.dto.ts b/api/src/log/log.dto.ts index b5e986c..ff3a5fb 100644 --- a/api/src/log/log.dto.ts +++ b/api/src/log/log.dto.ts @@ -1,5 +1,4 @@ import { PilotEntity } from "src/pilot/pilot.entity"; -import { TrackEntity } from "src/track/track.entity"; export class LogDto { pilotId: string; @@ -26,5 +25,4 @@ export class LogDto { pilotInCommand?: number; notes?: string; pilot?: PilotEntity; - tracks?: TrackEntity[]; } diff --git a/api/src/log/log.service.ts b/api/src/log/log.service.ts index 77b2135..2638688 100644 --- a/api/src/log/log.service.ts +++ b/api/src/log/log.service.ts @@ -20,12 +20,14 @@ export class LogService { where: { id: id }, relations: ['pilot', 'tracks'] }); - console.log(logEntity); + return logEntity; } async findAll(): Promise { - return await this.logRepository.find(); + return await this.logRepository.find({ + relations: ['pilot', 'tracks'] + }); } async create(logDto: LogDto): Promise { diff --git a/api/src/track/track.controller.ts b/api/src/track/track.controller.ts index 946044a..7ec1a35 100644 --- a/api/src/track/track.controller.ts +++ b/api/src/track/track.controller.ts @@ -29,7 +29,7 @@ export class TrackController { ) {} // @Get('id') - // async fin(@Param('id') id: string): Promise { + // async find(@Param('id') id: string): Promise { // try { // return await this.trackService.find(id); // } catch (error) { @@ -39,21 +39,22 @@ export class TrackController { // } // } - // @Get() - // async findAdd(): Promise { - // try { - // return await this.trackService.findAll(); - // } catch (error) { - // const customError = error as CustomError; + @Get(':logId') + async findAll(@Param('logId') logId: string): Promise { + try { + return await this.trackService.findAll(logId); + } catch (error) { + const customError = error as CustomError; - // throw new HttpException(customError.message, customError.statusCode) - // } - // } + throw new HttpException(customError.message, customError.statusCode); + } + } + @UseGuards(AuthGuard) @Post(':logId/:order') + @UseInterceptors(FileInterceptor('file')) async create(@Param('logId') logId: string, @Param('order') order: number, @UploadedFile() file: Express.Multer.File): Promise { try { - console.log(file) return await this.trackService.create(logId, order, file); } catch (error) { const customError = error as CustomError; @@ -62,21 +63,12 @@ export class TrackController { } } - // @Put(':id') - // async update(@Param('id') id: string, @Body() trackDto: TrackDto): Promise { - // try { - // return await this.trackService.update(id, trackDto); - // } catch (error) { - // const customError = error as CustomError; - - // throw new HttpException(customError.message, customError.statusCode) - // } - // } - + @UseGuards(AuthGuard) @Delete(':id') - async delete(@Param('id') id: string): Promise { + async delete(@Param('id') id: string, @Query('fileName') fileName: string, @Query('logId') logId: string): Promise { try { - return await this.trackService.delete(id); + + return await this.trackService.delete(id, logId, fileName); } catch (error) { const customError = error as CustomError; @@ -84,37 +76,10 @@ export class TrackController { } } - @UseGuards(AuthGuard) - @Post(':partitionKey/:rowKey/track') - @UseInterceptors(FileInterceptor('file')) - async createTrack(@Param('rowKey') rowKey: string, @UploadedFile() file: Express.Multer.File) { + @Get(':logId/:fileName') + async downloadTrack(@Param('logId') logId: string, @Param('fileName') fileName: string): Promise { try { - const containerName = 'tracks'; - const url = await this.fileService.uploadFile(file, containerName, rowKey); - - return { url } - } catch (error) { - const customError = error as CustomError; - - throw new HttpException(customError.message, customError.statusCode); - } - } - - @Get(':partitionKey/:rowKey/track') - async downloadTrack(@Param('rowKey') rowKey: string, @Query('fileName') fileName: string): Promise { - const containerName = 'tracks'; - const downloadedFile: string = await this.fileService.downloadFile(containerName, rowKey, fileName) - - return downloadedFile; - } - - @UseGuards(AuthGuard) - @Delete(':partitionKey/:rowKey/track') - async deleteTrack(@Param('rowKey') rowKey: string, @Query('fileName') fileName: string): Promise { - try { - const containerName = 'tracks'; - - return await this.fileService.deleteFile(containerName, rowKey, fileName) + return await this.trackService.downloadTrackFile(logId, fileName); } catch (error) { const customError = error as CustomError; @@ -127,7 +92,3 @@ export class TrackController { - - - - diff --git a/api/src/track/track.service.ts b/api/src/track/track.service.ts index d04365f..9b6a9d7 100644 --- a/api/src/track/track.service.ts +++ b/api/src/track/track.service.ts @@ -10,32 +10,51 @@ import { FileService } from "src/file/file.service"; @Injectable() export class TrackService { + private readonly containerName: string = 'tracks' + constructor( @InjectRepository(TrackEntity) private readonly trackRepository: Repository, private readonly fileService: FileService, private readonly logService: LogService ) {} - // async find(id: string): Promise { - // return await this.trackRepository.findOneBy({ id }); - // } + async find(id: string): Promise { + try { + return await this.trackRepository.findOneBy({ id }); + } catch (error) { + throw new CustomError('Track not found', 'Not found', 404) + } + } - // async findAll(logId: string): Promise { - // try { - // await this.trackRepository.findOneBy({ }) - // } catch (error) { + async findAll(logId: string): Promise { + try { + const logEntity: LogEntity = await this.logService.find(logId); - // } - - // } + if (logEntity) { + console.log(logEntity) + const tracks = await this.trackRepository.find({ + where: { log: + { + id: logEntity.id + } + }, + }) + + console.log(tracks) + return tracks; + } + } catch (error) { + console.log(error) + throw new CustomError('Tracks not found', 'Not found', 404); + } + } async create(logId: string, order: number, file: Express.Multer.File): Promise { try { const logEntity: LogEntity = await this.logService.find(logId); if (logEntity) { - const containerName = 'tracks'; - const url = await this.fileService.uploadFile(file, containerName, logId); + const url = await this.fileService.uploadFile(file, this.containerName, logId); const track = this.trackRepository.create({ log: logEntity, order: order, @@ -52,37 +71,31 @@ export class TrackService { } } - // async update(id: string, track: TrackDto): Promise { - // return await this.trackRepository.update(id, track); - // } - - async delete(id: string): Promise { + async update(id: string, track: TrackDto): Promise { try { - - } catch (error) { - + return await this.trackRepository.update(id, track); + } catch(error) { + throw error } - return await this.trackRepository.delete({ id }); } - // async createTrack() + async delete(id: string, logId: string, fileName: string): Promise { + try { + await this.fileService.deleteFile(this.containerName, logId, fileName); - // async downloadTrack(): Promise { - // const containerName = 'tracks'; - // const downloadedFile: string = await this.fileService.downloadFile(containerName, rowKey, fileName); + return await this.trackRepository.delete({ id }); + } catch (error) { + throw error + } + } - // return downloadedFile; - // } + async downloadTrackFile(logId: string, fileName: string): Promise { + try { + const downloadedFile: string = await this.fileService.downloadFile(this.containerName, logId, fileName); - // async deleteTrack(): Promsie { - // try { - // const containerName = 'tracks'; - - // return await this.fileService.deleteFile(containerName, rowKey, fileName) - // } catch (error) { - // const customError = error as CustomError; - - // throw customError; - // } - // } + return downloadedFile; + } catch (error) { + throw error + } + } } \ No newline at end of file diff --git a/app/package.json b/app/package.json index 0de4fe4..5641498 100644 --- a/app/package.json +++ b/app/package.json @@ -1,7 +1,7 @@ { "name": "app", "private": true, - "version": "1.4.0", + "version": "2.0.0-alpha", "type": "module", "scripts": { "dev": "vite", diff --git a/app/src/components/flights/Flights.tsx b/app/src/components/flights/Flights.tsx index 05ad37e..28aecb1 100644 --- a/app/src/components/flights/Flights.tsx +++ b/app/src/components/flights/Flights.tsx @@ -10,8 +10,9 @@ const Flights = () => { const isMedium = useMediaQuery(theme.breakpoints.up('md')); useEffect(() => { + console.log(logs) const flights: ILogbookEntry[] | undefined = logs?.filter((log: ILogbookEntry) => { - if (log.tracks && JSON.parse(log.tracks).length > 0) { + if (log.tracks && log.tracks.length > 0) { return log; } }) diff --git a/app/src/components/logTrackMaps/LogTrackMaps.tsx b/app/src/components/logTrackMaps/LogTrackMaps.tsx index 4d88efc..a960716 100644 --- a/app/src/components/logTrackMaps/LogTrackMaps.tsx +++ b/app/src/components/logTrackMaps/LogTrackMaps.tsx @@ -12,24 +12,25 @@ import 'swiper/css'; import './LogTrackMaps.css'; import 'leaflet/dist/leaflet.css'; -const LogTrackMaps = ({ rowKey, trackUrls }: LogTrackMapsProps) => { - const [tracks, setTracks] = useState([]) +const LogTrackMaps = ({ logId, tracks }: LogTrackMapsProps) => { + const [kmls, setKmls] = useState([]) const httpClient: AxiosInstance = useHttpClient(); const { getAccessToken } = useAccessToken(); const isAuthenticated = useIsAuthenticated(); useEffect(() => { + console.log(tracks) const getTracks = async () => { const convertedTracks: any[] = [] - for (const trackUrl of trackUrls) { - const trackUrlSplit = trackUrl.split('/') + for (const track of tracks) { + const trackUrlSplit = track.url.split('/') const filename = trackUrlSplit[trackUrlSplit.length - 1]; const config = isAuthenticated ? { headers: { Authorization: await getAccessToken() } } : {}; const response: AxiosResponse = await httpClient.get( - `api/logs/log/${rowKey}/track?fileName=${filename}`, + `api/tracks/${logId}/${filename}`, config ); const kml = new DOMParser().parseFromString(response.data, 'text/xml') @@ -37,11 +38,11 @@ const LogTrackMaps = ({ rowKey, trackUrls }: LogTrackMapsProps) => { convertedTracks.push(kml); } - setTracks(convertedTracks) + setKmls(convertedTracks) } getTracks(); - }, [trackUrls]) + }, [tracks]) return ( { attribution='© OpenStreetMap contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> - {tracks.length > 0 && tracks.map((track) => ( - + {kmls.length > 0 && kmls.map((kml) => ( + ))} ); diff --git a/app/src/components/logTrackMaps/LogTrackMapsProps.interface.ts b/app/src/components/logTrackMaps/LogTrackMapsProps.interface.ts index 96ed5ef..acab4a0 100644 --- a/app/src/components/logTrackMaps/LogTrackMapsProps.interface.ts +++ b/app/src/components/logTrackMaps/LogTrackMapsProps.interface.ts @@ -1,4 +1,4 @@ export interface LogTrackMapsProps { - rowKey: string; - trackUrls: string[]; + logId: string; + tracks: {id: string; order: number; url: string}[]; } \ No newline at end of file diff --git a/app/src/components/logTracks/LogTracks.tsx b/app/src/components/logTracks/LogTracks.tsx index 74fd0d1..d572692 100644 --- a/app/src/components/logTracks/LogTracks.tsx +++ b/app/src/components/logTracks/LogTracks.tsx @@ -11,7 +11,7 @@ import ConfirmationDialog from "../confirmationDialog/ConfirmationDialog"; import { initialState, reducer } from "./reducer"; import LogTrackMaps from "../logTrackMaps/LogTrackMaps"; -const LogTracks = ({ isDrawerOpen, mode, onOpenClose, selectedRowKey }: LogTracksProps) => { +const LogTracks = ({ isDrawerOpen, mode, onOpenClose, selectedLogId }: LogTracksProps) => { const [state, dispatch] = useReducer(reducer, initialState) const httpClient: AxiosInstance = useHttpClient(); const { getAccessToken } = useAccessToken(); @@ -27,50 +27,49 @@ const LogTracks = ({ isDrawerOpen, mode, onOpenClose, selectedRowKey }: LogTrack return config } - const getLog = async (): Promise => { - const logResponse: AxiosResponse = await httpClient.get( - `api/logs/${selectedRowKey}`, - await getConfig() - ); - const logData: ILogbookEntry = logResponse.data; + // const getLog = async (): Promise => { + // const logResponse: AxiosResponse = await httpClient.get( + // `api/tracks/${selectedLogId}`, + // await getConfig() + // ); + // const logData: ILogbookEntry = logResponse.data; - return logData - } + // return logData + // } - const handleFileUpload = async (event: React.ChangeEvent) => { - try { - dispatch({ type: 'SET_IS_LOADING', payload: true}) + // const handleFileUpload = async (event: React.ChangeEvent, order: number) => { + // try { + // dispatch({ type: 'SET_IS_LOADING', payload: true}) - const file = event.target.files![0] - const formData = new FormData(); - const config = await getConfig(); - const formDataConfig = { - headers: { - ...config.headers, - 'Content-Type': 'multipart/form-data' - } - } + // const file = event.target.files![0] + // const formData = new FormData(); + // const config = await getConfig(); + // const formDataConfig = { + // headers: { + // ...config.headers, + // 'Content-Type': 'multipart/form-data' + // } + // } - formData.append('file', file); + // formData.append('file', file); - const uploadResponse: AxiosResponse = await httpClient.post(`api/logs/log/${selectedRowKey}/track`, formData, formDataConfig); - const uploadUrl = uploadResponse.data.url; - const log = await getLog(); - const tracks: string[] = log.tracks ? JSON.parse(log.tracks!) : []; + // const uploadResponse: AxiosResponse = await httpClient.post(`api/tracks/${selectedLogId}/${order}`, formData, formDataConfig); + // const uploadUrl = uploadResponse.data.url; + // const tracks: string[] = log.tracks ? JSON.parse(log.tracks!) : []; - tracks.push(uploadUrl) - log.tracks = JSON.stringify(tracks); - await httpClient.put(`api/logs/log/${selectedRowKey}`, log, config); + // tracks.push(uploadUrl) + // log.tracks = JSON.stringify(tracks); + // await httpClient.put(`api/logs/log/${selectedRowKey}`, log, config); - const updatedLog = await getLog(); + // const updatedLog = await getLog(); - dispatch({ type: 'SET_TRACKS', payload: JSON.parse(updatedLog.tracks!) }) - } catch (error) { - console.log(error) - } finally { - dispatch({ type: 'SET_IS_LOADING', payload: false }); - } - } + // dispatch({ type: 'SET_TRACKS', payload: JSON.parse(updatedLog.tracks!) }) + // } catch (error) { + // console.log(error) + // } finally { + // dispatch({ type: 'SET_IS_LOADING', payload: false }); + // } + // } const onCancel = () => { onOpenClose(FormMode.CANCEL) @@ -80,41 +79,54 @@ const LogTracks = ({ isDrawerOpen, mode, onOpenClose, selectedRowKey }: LogTrack dispatch({ type: 'SET_ON_DELETE_TRACK', payload: { isConfirmDialogOpen: true, selectedTrack: { fileName: fileName, index: index }}}) } - const onConfirmDialogConfirm = async () => { - try { - const config = await getConfig(); + // const onConfirmDialogConfirm = async () => { + // try { + // const config = await getConfig(); - await httpClient.delete(`api/logs/log/${selectedRowKey}/track?fileName=${state.selectedTrack!.fileName}`, config); + // await httpClient.delete(`api/logs/log/${selectedRowKey}/track?fileName=${state.selectedTrack!.fileName}`, config); - const log = await getLog(); - const tracks: string[] = JSON.parse(log.tracks!); + // const log = await getLog(); + // const tracks: string[] = JSON.parse(log.tracks!); - tracks.splice(state.selectedTrack!.index, 1); - log.tracks = JSON.stringify(tracks); - await httpClient.put(`api/logs/log/${selectedRowKey}`, log, config); + // tracks.splice(state.selectedTrack!.index, 1); + // log.tracks = JSON.stringify(tracks); + // await httpClient.put(`api/logs/log/${selectedRowKey}`, log, config); - const updatedLog = await getLog(); + // const updatedLog = await getLog(); - dispatch({ type: 'SET_TRACKS', payload: JSON.parse(updatedLog.tracks!) }) - dispatch({ type: 'SET_IS_CONFIRM_DIALOG_OPEN', payload: false }) - } catch (error) { - console.log(error); - } - } + // dispatch({ type: 'SET_TRACKS', payload: JSON.parse(updatedLog.tracks!) }) + // dispatch({ type: 'SET_IS_CONFIRM_DIALOG_OPEN', payload: false }) + // } catch (error) { + // console.log(error); + // } + // } const onConfirmDialogCancel = async () => { dispatch({ type: 'SET_IS_CONFIRM_DIALOG_OPEN', payload: false }) } - useEffect(() => { - const updateTracks = async () => { - const log = await getLog(); + // useEffect(() => { + // const updateTracks = async () => { + // const log = await getLog(); - dispatch({ type: 'SET_TRACKS', payload: JSON.parse(log.tracks!) }); - } + // dispatch({ type: 'SET_TRACKS', payload: log.tracks! }); + // } - updateTracks(); - }, []) + // updateTracks(); + // }, []) + + useEffect(() => { + if (isDrawerOpen) { + console.log(selectedLogId) + const getTracks = async () => { + const tracks = await httpClient.get(`api/tracks/${selectedLogId}`); + + console.log(tracks); + } + + getTracks(); + } + }, [isDrawerOpen]) return ( } {!state.isLoading && state.tracks.length > 0 && state.tracks.map((track, index) => { - const trackSplit = track.split('/') + const trackSplit = track.url.split('/') const filename = trackSplit[trackSplit.length - 1]; return ( @@ -181,17 +193,17 @@ const LogTracks = ({ isDrawerOpen, mode, onOpenClose, selectedRowKey }: LogTrack variant='contained' > Upload Track - + {/* */} )} } {mode === FormMode.VIEW && - + } - {state.isConfirmDialogOpen && ( + {/* {state.isConfirmDialogOpen && ( - )} + )} */} ) diff --git a/app/src/components/logTracks/LogTracksProps.interface.ts b/app/src/components/logTracks/LogTracksProps.interface.ts index b7b8483..26ead5b 100644 --- a/app/src/components/logTracks/LogTracksProps.interface.ts +++ b/app/src/components/logTracks/LogTracksProps.interface.ts @@ -4,5 +4,5 @@ export interface LogTracksProps { isDrawerOpen: boolean; mode: FormMode; onOpenClose: (mode: FormMode) => void; - selectedRowKey: string | undefined; + selectedLogId: string | undefined; } \ No newline at end of file diff --git a/app/src/components/logTracks/LogTracksState.interface.ts b/app/src/components/logTracks/LogTracksState.interface.ts index 6c2984c..616d984 100644 --- a/app/src/components/logTracks/LogTracksState.interface.ts +++ b/app/src/components/logTracks/LogTracksState.interface.ts @@ -6,5 +6,5 @@ export interface LogTracksState { fileName: string, index: number } | undefined; - tracks: string[]; + tracks: { id: string; order: number; url: string; }[]; } \ No newline at end of file diff --git a/app/src/components/logTracks/reducer.ts b/app/src/components/logTracks/reducer.ts index ca9d6f5..f7fb3d9 100644 --- a/app/src/components/logTracks/reducer.ts +++ b/app/src/components/logTracks/reducer.ts @@ -5,7 +5,7 @@ type Action = | { type: 'SET_IS_CONFORM_DIALOG_LOADING'; payload: boolean } | { type: 'SET_IS_LOADING'; payload: boolean } | { type: 'SET_ON_DELETE_TRACK'; payload: { isConfirmDialogOpen: boolean, selectedTrack: { fileName: string, index: number } }} - | { type: 'SET_TRACKS'; payload: string[] }; + | { type: 'SET_TRACKS'; payload: { id: string; order: number; url: string }[] }; export const initialState: LogTracksState = { isConfirmDialogOpen: false, diff --git a/app/src/components/logbook/ILogbookEntry.ts b/app/src/components/logbook/ILogbookEntry.ts index d19edac..6aba050 100644 --- a/app/src/components/logbook/ILogbookEntry.ts +++ b/app/src/components/logbook/ILogbookEntry.ts @@ -1,7 +1,6 @@ export interface ILogbookEntry { id: string; - pilotId: string; - pilotName: string; + pilot: string; date: string; aircraftMakeModel: string; aircraftIdentity: string; @@ -23,6 +22,6 @@ export interface ILogbookEntry { night: number | null; solo: number | null; pilotInCommand: number | null; - tracks: string | undefined; + tracks: {id: string; order: number; url: string}[]; notes: string; } diff --git a/app/src/components/logbook/Logbook.tsx b/app/src/components/logbook/Logbook.tsx index 8a071fb..c2c11a3 100644 --- a/app/src/components/logbook/Logbook.tsx +++ b/app/src/components/logbook/Logbook.tsx @@ -53,7 +53,7 @@ const Logbook: React.FC = () => { accessorKey: 'tracks', header: 'Tracks', cell: (info: any) => { - if (info.row.original.tracks && JSON.parse(info.row.original.tracks).length > 0) { + if (info.row.original.tracks.length > 0) { return ( onOpenCloseTracks(FormMode.VIEW, info.row.original.rowKey)}> ) @@ -70,7 +70,7 @@ const Logbook: React.FC = () => { : {}; const response: AxiosResponse = await httpClient.get(`api/logs`, config); const entries: ILogbookEntry[] = response.data; - + console.log(entries) entries.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()) if (response.data.length > 0) { @@ -299,7 +299,7 @@ const Logbook: React.FC = () => { isDrawerOpen={state.isTracksOpen} mode={state.tracksMode} onOpenClose={(mode) => onOpenCloseTracks(mode)} - selectedRowKey={state.selectedLogId} + selectedLogId={state.selectedLogId} /> } diff --git a/app/src/components/logbook/columns.tsx b/app/src/components/logbook/columns.tsx index 7d0bbbf..97767d0 100644 --- a/app/src/components/logbook/columns.tsx +++ b/app/src/components/logbook/columns.tsx @@ -19,14 +19,25 @@ const columnTotal = (info: HeaderContext): number => { const pilotName: ColumnDef = { id: 'pilotName', - accessorKey: 'pilotName', + accessorKey: 'pilot', header: 'Pilot', - footer: 'PAGE TOTALS' + footer: 'PAGE TOTALS', + cell: (info: CellContext) => { + const pilot: any = info.getValue(); + + return pilot.name + } } const date: ColumnDef = { id: 'date', accessorKey: 'date', - header: 'Date' + header: 'Date', + cell: (info: CellContext) => { + const date = new Date(info.getValue() as string); + const formattedDate = `${date.getMonth()}/${date.getDate()}/${date.getFullYear()}` + + return formattedDate; + } } const aircraftMakeModel: ColumnDef = { id: 'aircraftMakeModel', diff --git a/app/src/components/logbookCard/LogbookCard.tsx b/app/src/components/logbookCard/LogbookCard.tsx index 3cbea20..05e7495 100644 --- a/app/src/components/logbookCard/LogbookCard.tsx +++ b/app/src/components/logbookCard/LogbookCard.tsx @@ -8,14 +8,15 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps return ( {logs.map((log) => { - console.log(log) + const date = new Date(log.date); + const formattedDate: string = `${date.getMonth()}/${date.getDate()}/${date.getFullYear()}`; + return ( - + : null} - subheader={log.pilotName} - title={log.date} + action={mode === 'logbook' ? : null} + title={formattedDate} slotProps={{ subheader: { fontSize: '16px' @@ -27,11 +28,11 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps /> - {mode === 'flights' && log.tracks && JSON.parse(log.tracks).length > 0 && + {mode === 'flights' && log.tracks && log.tracks.length > 0 && } @@ -59,13 +60,13 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps {log.durationOfFlight} - {mode === 'logbook' && log.tracks && JSON.parse(log.tracks).length > 0 && + {mode === 'logbook' && log.tracks && log.tracks.length > 0 && <> Tracks - {JSON.parse(log.tracks).map((track: string) => { - const trackSplit = track.split('/') + {log.tracks.map((track: { id: string; order: number; url: string}) => { + const trackSplit = track.url.split('/') const filename = trackSplit[trackSplit.length - 1]; return (