From 9a502df48dd5176af31052cc72eabc4bfa50d6df Mon Sep 17 00:00:00 2001 From: Noah Spannbauer Date: Sat, 6 Dec 2025 20:32:07 -0600 Subject: [PATCH] adding daisy ui --- client/src/components/logbook/Logbook.tsx | 215 ++++++++++-------- client/src/components/logbook/columns.tsx | 3 +- .../components/logbookCard/LogbookCard.tsx | 84 +++---- .../logbookDrawer/LogbookDrawer.tsx | 184 ++++++++------- client/src/components/pilots/Pilots.tsx | 119 +++++++--- client/src/components/siteNav/SiteNav.tsx | 55 ++++- client/src/styles.css | 3 +- client/src/tanstack.d.ts | 5 +- 8 files changed, 404 insertions(+), 264 deletions(-) diff --git a/client/src/components/logbook/Logbook.tsx b/client/src/components/logbook/Logbook.tsx index c621c8f..40156bb 100644 --- a/client/src/components/logbook/Logbook.tsx +++ b/client/src/components/logbook/Logbook.tsx @@ -69,13 +69,17 @@ const Logbook: React.FC = () => { id: 'route', header: 'Route of Flight', meta: { - headerAlign: 'center' + className: 'border-l border-base-300', + headerAlign: 'text-center' }, columns: [ { id: 'routeFrom', accessorKey: 'routeFrom', - header: 'From' + header: 'From', + meta: { + className: 'border-l border-base-300', + } }, { id: 'routeTo', @@ -89,8 +93,9 @@ const Logbook: React.FC = () => { accessorKey: 'durationOfFlight', header: 'Duration Of Flight', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + className: 'border-l border-base-300', + headerAlign: 'text-right' }, cell: (info: CellContext) => info.getValue() ? parseFloat(info.getValue() as string).toFixed(1) : '', @@ -99,51 +104,63 @@ const Logbook: React.FC = () => { const notes: ColumnDef = { id: 'notes', accessorKey: 'notes', - header: 'Notes' + header: 'Notes', + meta: { + className: 'border-l border-base-300', + } } const actions: ColumnDef = { id: 'actions', header: 'Actions', meta: { - align: 'center', - headerAlign: 'center' + align: 'text-center', + className: 'border-l border-base-300', + headerAlign: 'text-center' }, cell: (info: CellContext) => { return ( - - - - - - - onOpenCloseDrawer(FormMode.EDIT, info.row.original.id)} - startContent={} - > - Edit - - onOpenCloseDrawer(FormMode.VIEW, info.row.original.id)} - startContent={} - > - View - - - - onDeleteLog(info.row.original.id)} - startContent={} - > - Delete - - - - + + // + // + // + // + // + // + // onOpenCloseDrawer(FormMode.EDIT, info.row.original.id)} + // startContent={} + // > + // Edit + // + // onOpenCloseDrawer(FormMode.VIEW, info.row.original.id)} + // startContent={} + // > + // View + // + // + // + // onDeleteLog(info.row.original.id)} + // startContent={} + // > + // Delete + // + // + // + // ) } } @@ -173,8 +190,8 @@ const Logbook: React.FC = () => { accessorKey: 'singleEngineLand', header: 'Single Engine Land', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' }, cell: (info: CellContext) => info.getValue() ? parseFloat(info.getValue() as string).toFixed(1) : '', @@ -184,7 +201,8 @@ const Logbook: React.FC = () => { id: 'landings', header: 'Landings', meta: { - headerAlign: 'center' + className: 'border-l border-base-300', + headerAlign: 'text-center' }, columns: [ { @@ -193,8 +211,9 @@ const Logbook: React.FC = () => { header: 'Day', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + className: 'border-l border-base-300', + headerAlign: 'text-right' } }, { @@ -203,8 +222,8 @@ const Logbook: React.FC = () => { header: 'Night', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' } } ] @@ -213,7 +232,8 @@ const Logbook: React.FC = () => { id: 'instrument', header: 'Instrument', meta: { - headerAlign: 'center' + className: 'border-l border-base-300', + headerAlign: 'text-center' }, columns: [ { @@ -222,8 +242,9 @@ const Logbook: React.FC = () => { header: 'Actual', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + className: 'border-l border-base-300', + headerAlign: 'text-right' }, cell: (info: CellContext) => info.getValue() ? parseFloat(info.getValue() as string).toFixed(1) : '', @@ -234,8 +255,8 @@ const Logbook: React.FC = () => { header: 'Simulated', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' }, cell: (info: CellContext) => info.getValue() ? parseFloat(info.getValue() as string).toFixed(1) : '' @@ -246,8 +267,8 @@ const Logbook: React.FC = () => { header: 'Approaches', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' } }, { @@ -256,8 +277,8 @@ const Logbook: React.FC = () => { header: 'Holds', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' } }, { @@ -266,8 +287,8 @@ const Logbook: React.FC = () => { header: 'Nav/Track', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' } } ] @@ -276,7 +297,8 @@ const Logbook: React.FC = () => { id: 'experienceTraining', header: 'Type of pilot experience or training', meta: { - headerAlign: 'center' + className: 'border-l border-base-300', + headerAlign: 'text-center' }, columns: [ { @@ -285,8 +307,9 @@ const Logbook: React.FC = () => { header: 'Ground Training Received', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + className: 'border-l border-base-300', + headerAlign: 'text-right' }, cell: (info: CellContext) => info.getValue() ? parseFloat(info.getValue() as string).toFixed(1) : '' @@ -297,8 +320,8 @@ const Logbook: React.FC = () => { header: 'Flight Training Received', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' }, cell: (info: CellContext) => info.getValue() ? parseFloat(info.getValue() as string).toFixed(1) : '' @@ -309,8 +332,8 @@ const Logbook: React.FC = () => { header: 'Cross Country', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' }, cell: (info: CellContext) => info.getValue() ? parseFloat(info.getValue() as string).toFixed(1) : '' @@ -321,8 +344,8 @@ const Logbook: React.FC = () => { header: 'Night', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' }, cell: (info: CellContext) => info.getValue() ? parseFloat(info.getValue() as string).toFixed(1) : '' @@ -333,8 +356,8 @@ const Logbook: React.FC = () => { header: 'Solo', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' }, cell: (info: CellContext) => info.getValue() ? parseFloat(info.getValue() as string).toFixed(1) : '' @@ -345,8 +368,8 @@ const Logbook: React.FC = () => { header: 'Pilot In Command', footer: (info: HeaderContext) => columnTotal(info) > 0 ? columnTotal(info).toFixed(1) : '', meta: { - align: 'right', - headerAlign: 'right' + align: 'text-right', + headerAlign: 'text-right' }, cell: (info: CellContext) => info.getValue() ? parseFloat(info.getValue() as string).toFixed(1) : '' @@ -531,22 +554,22 @@ const Logbook: React.FC = () => { )} {!state.isLoading && ( -
+
{state.entries.length > 0 && screenSize !== ScreenSize.SM && ( -
- - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { +
+
+ + {table.getHeaderGroups().map((headerGroup, headerGroupIndex) => ( + + {headerGroup.headers.map((header, headerIndex) => { return ( ); })} @@ -587,7 +612,7 @@ const Logbook: React.FC = () => { })} - + {table.getFooterGroups().map((footerGroup, index) => { if (index === 0) { return ( @@ -597,14 +622,16 @@ const Logbook: React.FC = () => { ); })} diff --git a/client/src/components/logbook/columns.tsx b/client/src/components/logbook/columns.tsx index 37315ce..5d21d56 100644 --- a/client/src/components/logbook/columns.tsx +++ b/client/src/components/logbook/columns.tsx @@ -48,7 +48,8 @@ const route: ColumnDef = { id: 'route', header: 'Route of Flight', meta: { - headerAlign: 'center' + headerAlign: 'center', + className: 'border-l border-base-400' }, columns: [ { diff --git a/client/src/components/logbookCard/LogbookCard.tsx b/client/src/components/logbookCard/LogbookCard.tsx index fd3316b..e3d5f6e 100644 --- a/client/src/components/logbookCard/LogbookCard.tsx +++ b/client/src/components/logbookCard/LogbookCard.tsx @@ -1,5 +1,6 @@ import { LogbookCardProps } from "./LogbookCardProps.interface"; import TrackMap from "../trackMap/TrackMap"; +import { Button, Collapse, CollapseContent, CollapseTitle } from '@noahspan/noahspan-components' const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps) => { return ( @@ -9,10 +10,10 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps const formattedDate: string = `${date.getMonth()}/${date.getDate()}/${date.getFullYear()}`; return ( -
-
+
+

{formattedDate}

-
+
{mode === 'flights' && log.tracks && log.tracks.length > 0 &&
} -
-
Details
-
-
-
- Aircraft Make and Model -
-
- {log.aircraftMakeModel} -
-
- Route From -
-
- {log.routeFrom} -
-
- Route To -
-
- {log.routeTo} -
-
- Duration Of Flight -
-
- {log.durationOfFlight} -
- {log.notes && - <> -
- Notes -
-
- {log.notes} -
- - } +
+
+ +
Details
+
+
+
+ Aircraft Make and Model
+
+ {log.aircraftMakeModel} +
+
+ Route From +
+
+ {log.routeFrom} +
+
+ Route To +
+
+ {log.routeTo} +
+
+ Duration Of Flight +
+
+ {log.durationOfFlight} +
+ {log.notes && + <> +
+ Notes +
+
+ {log.notes} +
+ + }
diff --git a/client/src/components/logbookDrawer/LogbookDrawer.tsx b/client/src/components/logbookDrawer/LogbookDrawer.tsx index c2a6f78..2242c40 100644 --- a/client/src/components/logbookDrawer/LogbookDrawer.tsx +++ b/client/src/components/logbookDrawer/LogbookDrawer.tsx @@ -75,99 +75,117 @@ const LogbookDrawer = ({ onOpenClose }: LogbookDrawerProps) => { return (
- - - } - isOpen={logbookContext.state.isDrawerOpen} - onClose={onCancel} + // closeButton={ + // + // } + // isOpen={logbookContext.state.isDrawerOpen} + // onClose={onCancel} > -
- -
- - {`${logbookContext.state.formMode.toString().toLowerCase().charAt(0).toUpperCase() + logbookContext.state.formMode.toString().slice(1).toLowerCase()} Entry`} - -
- {logbookContext.state.formAlert && ( -
- - logbookContext.dispatch({ type: 'SET_FORM_ALERT', payload: undefined }) - } - color={logbookContext.state.formAlert.severity} - title={logbookContext.state.formAlert.message} - /> -
- )} - - - - Time -
- } - > - - - {logbookContext.state.formMode !== FormMode.ADD && - {}} checked={logbookContext.state.isDrawerOpen} /> +
+ +
+ + +

+ {`${logbookContext.state.formMode.toString().toLowerCase().charAt(0).toUpperCase() + logbookContext.state.formMode.toString().slice(1).toLowerCase()} Entry`} +

+ {/* {logbookContext.state.formAlert && ( +
+ + logbookContext.dispatch({ type: 'SET_FORM_ALERT', payload: undefined }) + } + color={logbookContext.state.formAlert.severity} + title={logbookContext.state.formAlert.message} + /> +
+ )} */} + + {/*
+ +
+ +
+ +
+ +
*/} + {/* */} + {/* - - Tracks + + Time
} > - + - } - - - {activeTab !== 'tracks' && - -
-
-
} - startContent={} - onPress={onCancel} > - {logbookContext.state.formMode.toString() !== FormMode.VIEW ? 'Cancel' : 'Close'} - - {logbookContext.state.formMode.toString() !== FormMode.VIEW && ( - - )} -
+ + + } */}
- - } - - - - + {activeTab !== 'tracks' && +
+
+
+ + {logbookContext.state.formMode.toString() !== FormMode.VIEW && ( + + )} +
+
+
+ } + + +
+
+
) } diff --git a/client/src/components/pilots/Pilots.tsx b/client/src/components/pilots/Pilots.tsx index 03bd22e..d731ab8 100644 --- a/client/src/components/pilots/Pilots.tsx +++ b/client/src/components/pilots/Pilots.tsx @@ -12,7 +12,9 @@ import { ScreenSize } from '../../enums/screenSize'; import { useBreakpoints } from '../../hooks/useBreakpoints/UseBreakpoints'; import { Alert, Button, Dropdown, DropdownItem, DropdownSection, Table, TableHeader, TableBody, TableColumn, TableRow, TableCell, DropdownTrigger, DropdownMenu } from '@heroui/react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faEllipsisVertical, faPen, faEye, faTrash, faPlus } from '@fortawesome/free-solid-svg-icons' +import { faEllipsisVertical, faPen, faEye, faTrash, faPlus } from '@fortawesome/free-solid-svg-icons'; +import { CellContext, ColumnDef, flexRender, getCoreRowModel, getPaginationRowModel, HeaderContext, useReactTable } from '@tanstack/react-table'; +import { Pilot } from './Pilot.interface'; const Pilots: React.FC = () => { const [state, dispatch] = useReducer(reducer, initialState); @@ -27,6 +29,8 @@ const Pilots: React.FC = () => { `api/pilots` ); + console.log(response) + if (response.data.length > 0) { dispatch({ type: 'SET_PILOTS', payload: response.data }); @@ -115,14 +119,19 @@ const Pilots: React.FC = () => { }); }; - const columns = [ + const columns: ColumnDef[]= [ { id: 'name', - name: 'Name' + accessorKey: 'name', + header: 'Name' }, { id: 'actions', - name: 'Actions' + header: 'Actions', + meta: { + align: 'text-center', + headerAlign: 'text-center' + } } ] @@ -174,6 +183,19 @@ const Pilots: React.FC = () => { } } + const textAlignment = { + center: 'text-center', + left: 'text-start', + right: 'text-end' + }; + + const table = useReactTable({ + data: state.pilots, + columns: columns, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel() + }); + useEffect(() => { if (!state.isFormOpen) { getPilots(); @@ -188,14 +210,14 @@ const Pilots: React.FC = () => {
{userRole === UserRole.WRITE && - + }
{!state.isLoading && state.alert && ( @@ -209,31 +231,62 @@ const Pilots: React.FC = () => { />
)} -
+
{state.pilots.length > 0 && screenSize !== ScreenSize.SM && -
{header.isPlaceholder ? null : ( -
+
{flexRender( header.column.columnDef.header, header.getContext() @@ -572,13 +595,15 @@ const Logbook: React.FC = () => { {row.getVisibleCells().map((cell) => { return (
*]:z-1 [&>*]:relative outline-solid outline-transparent data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 before:pointer-events-none before:content-[''] before:absolute before:z-0 before:inset-0 before:opacity-0 data-[selected=true]:before:opacity-100 group-data-[disabled=true]/tr:text-foreground-300 group-data-[disabled=true]/tr:cursor-not-allowed before:bg-default/60 data-[selected=true]:text-default-foreground first:before:rounded-s-lg last:before:rounded-e-lg text-start`} + className={`py-2 px-3 relative align-middle whitespace-normal text-small font-normal [&>*]:z-1 [&>*]:relative outline-solid outline-transparent data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 before:pointer-events-none before:content-[''] before:absolute before:z-0 before:inset-0 before:opacity-0 data-[selected=true]:before:opacity-100 group-data-[disabled=true]/tr:text-foreground-300 group-data-[disabled=true]/tr:cursor-not-allowed before:bg-default/60 data-[selected=true]:text-default-foreground first:before:rounded-s-lg last:before:rounded-e-lg text-start`} key={cell.id} > - {flexRender( - cell.column.columnDef.cell, - cell.getContext() - )} +
+ {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} +
- {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.footer, - header.getContext() - )} +
+ {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.footer, + header.getContext() + ) + } +
- - {(column) => ( - - {column.name} - - )} - - - {(item) => ( - - {(columnKey => ( - - {renderCell(item, columnKey)} - - ))} - - )} - -
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + ); + })} + + ))} + + + <> + {table.getRowModel().rows.map((row) => { + return ( + + {row.getVisibleCells().map((cell) => { + return ( + + ); + })} + + ); + })} + + +
+ {header.isPlaceholder ? null : ( +
+ {flexRender( + header.column.columnDef.header, + header.getContext() + )} + {/* {header.column.getCanFilter() ? ( +
+ +
+ ) : null} */} +
+ )} +
*]:z-1 [&>*]:relative outline-solid outline-transparent data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 before:pointer-events-none before:content-[''] before:absolute before:z-0 before:inset-0 before:opacity-0 data-[selected=true]:before:opacity-100 group-data-[disabled=true]/tr:text-foreground-300 group-data-[disabled=true]/tr:cursor-not-allowed before:bg-default/60 data-[selected=true]:text-default-foreground first:before:rounded-s-lg last:before:rounded-e-lg text-start`} + key={cell.id} + > + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} +
} {state.pilots.length > 0 && screenSize === ScreenSize.SM && diff --git a/client/src/components/siteNav/SiteNav.tsx b/client/src/components/siteNav/SiteNav.tsx index c45a983..d2cd4a7 100644 --- a/client/src/components/siteNav/SiteNav.tsx +++ b/client/src/components/siteNav/SiteNav.tsx @@ -7,7 +7,7 @@ import { Avatar, Button, Link, Navbar, NavbarBrand, NavbarContent, NavbarItem, D import httpClient from '../../httpClient/httpClient' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faPlane, faSignIn, faSignOut } from '@fortawesome/free-solid-svg-icons' -import { useLocation } from 'react-router-dom'; +import { NavLink, useLocation } from 'react-router-dom'; const SiteNav = () => { const [userPhoto, setUserPhoto] = useState(); @@ -58,8 +58,8 @@ const SiteNav = () => { try { const userProfile = await getUserProfile(); const userPhoto = await getUserPhoto(); - - setUserPhoto(userPhoto); + console.log(userPhoto) + // setUserPhoto(userPhoto); appContext.dispatch({ type: 'SET_USER_PROFILE', @@ -80,7 +80,7 @@ const SiteNav = () => { return (
-
+
@@ -99,11 +99,17 @@ const SiteNav = () => {
  • Item 3
  • - daisyUI + +
      -
    • Item 1
    • + {/*
    • Item 1
    • Parent @@ -113,11 +119,42 @@ const SiteNav = () => {
    -
  • Item 3
  • +
  • Item 3
  • */} + {pages.length > 0 && pages.map((page, index) => { + return ( +
  • {page.name}
  • + ) + })}
    -
    - Button +
    + {!isUserLoggedIn && + + } + {isUserLoggedIn && +
    +
    +
    + {userPhoto && +
    + +
    + } + {!userPhoto && +
    + NS +
    + } +
    +
    + +
    + }
    // diff --git a/client/src/styles.css b/client/src/styles.css index 624f9bc..2e37768 100644 --- a/client/src/styles.css +++ b/client/src/styles.css @@ -1,5 +1,5 @@ @import "tailwindcss"; -@plugin "@tailwindcss/typography"; +@plugin "daisyui"; @plugin "daisyui/theme" { name: "lofi"; default: true; @@ -34,6 +34,7 @@ --depth: 0; --noise: 0; } +@plugin "@tailwindcss/typography"; body { background-color: #f5f5f5; diff --git a/client/src/tanstack.d.ts b/client/src/tanstack.d.ts index 69174fb..20aa39d 100644 --- a/client/src/tanstack.d.ts +++ b/client/src/tanstack.d.ts @@ -3,8 +3,9 @@ import '@tanstack/react-table'; /* eslint-disable */ declare module '@tanstack/react-table' { interface ColumnMeta { - align?: 'left' | 'center' | 'right'; - headerAlign?: 'left' | 'center' | 'right'; + align?: 'text-left' | 'text-center' | 'text-right'; + className?: string; + headerAlign?: 'text-left' | 'text-center' | 'text-right'; } } /* eslint-enable */