Compare commits
10 Commits
96-switch-
...
101-upgrad
| Author | SHA1 | Date | |
|---|---|---|---|
| 20b910b015 | |||
| 8d166983f1 | |||
| 4ad53f99c1 | |||
| 819e632d8e | |||
| 5100a93659 | |||
| a4fdd93ede | |||
| 1e1b1f7c97 | |||
| 96b6754f29 | |||
| 952b9a806b | |||
| 42bc48c1df |
6
.github/workflows/deploy.yaml
vendored
6
.github/workflows/deploy.yaml
vendored
@@ -23,13 +23,13 @@ jobs:
|
||||
- name: Log in to Azure
|
||||
uses: azure/login@v2
|
||||
with:
|
||||
client-id: ${{ vars.VITE_CLIENT_ID }}
|
||||
client-id: ${{ vars.AZURE_CLIENT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant-id: ${{ vars.VITE_TENANT_ID }}
|
||||
tenant-id: ${{ vars.AZURE_TENANT_ID }}
|
||||
|
||||
- name: Azure CLI script
|
||||
uses: azure/cli@v2
|
||||
with:
|
||||
azcliversion: latest
|
||||
inlineScript: |
|
||||
az containerapp update --name ${{ inputs.app_name }}-${{ inputs.environment_name }} --resource-group noahspan-flying --image docker.io/noahspan/${{ inputs.app_name }}:${{ inputs.version_number }}
|
||||
az containerapp update --name ${{ inputs.app_name }}-${{ inputs.environment_name }} --container-name ${{ inputs.app_name }} --resource-group noahspan --image docker.io/noahspan/${{ inputs.app_name }}:${{ inputs.version_number }}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "api",
|
||||
"version": "2.0.0-alpha-1",
|
||||
"version": "2.0.0-alpha-3",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -30,14 +30,8 @@ import { join } from 'path';
|
||||
isGlobal: true,
|
||||
load: [configuration]
|
||||
}),
|
||||
// HealthModule,
|
||||
HealthModule,
|
||||
LogModule,
|
||||
PilotModule,
|
||||
ServeStaticModule.forRoot({
|
||||
rootPath: join(__dirname, '../..', 'client', 'dist')
|
||||
}),
|
||||
TrackModule,
|
||||
TypeOrmModule.forRoot(dataSourceOptions),
|
||||
MsGraphModule.registerAsync({
|
||||
inject: [ConfigService],
|
||||
imports: [ConfigModule],
|
||||
@@ -48,7 +42,13 @@ import { join } from 'path';
|
||||
tenantId: configService.get<string>('tenantId')
|
||||
}
|
||||
}
|
||||
})
|
||||
}),
|
||||
PilotModule,
|
||||
ServeStaticModule.forRoot({
|
||||
rootPath: join(__dirname, '../..', 'client', 'dist')
|
||||
}),
|
||||
TrackModule,
|
||||
TypeOrmModule.forRoot(dataSourceOptions)
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
|
||||
@@ -37,11 +37,10 @@ export class LogController {
|
||||
@Param('id') id: string,
|
||||
): Promise<LogEntity> {
|
||||
try {
|
||||
console.log(id)
|
||||
return await this.logService.find(id);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
console.log(error)
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
@@ -50,11 +49,10 @@ export class LogController {
|
||||
@Public()
|
||||
async findAll(): Promise<LogEntity[]> {
|
||||
try {
|
||||
console.log('blah')
|
||||
return await this.logService.findAll();
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
console.log(error)
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
@@ -67,7 +65,7 @@ export class LogController {
|
||||
return await this.logService.create(logDto);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
console.log(error)
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
@@ -79,12 +77,10 @@ export class LogController {
|
||||
@Body() logDto: LogDto
|
||||
): Promise<UpdateResult> {
|
||||
try {
|
||||
console.log(id)
|
||||
console.log(logDto)
|
||||
return await this.logService.update(id, logDto);
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
console.log(error)
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
@@ -97,7 +93,6 @@ export class LogController {
|
||||
try {
|
||||
return await this.logService.delete(id);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
const customError = error as CustomError;
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
|
||||
@@ -43,7 +43,7 @@ export class PilotController {
|
||||
return await this.pilotService.findAll();
|
||||
} catch (error) {
|
||||
const customError = error as CustomError;
|
||||
console.log(error)
|
||||
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
@@ -55,10 +55,9 @@ export class PilotController {
|
||||
|
||||
return await this.pilotService.create(pilotDto);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
// const customError = error as CustomError;
|
||||
const customError = error as CustomError;
|
||||
|
||||
// throw new HttpException(customError.message, customError.statusCode);
|
||||
throw new HttpException(customError.message, customError.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ export class PilotInterceptor implements NestInterceptor {
|
||||
};
|
||||
})
|
||||
}
|
||||
console.log(req.headers.authorization)
|
||||
|
||||
if (req.headers.authorization) {
|
||||
const authHeader = req.headers.authorization;
|
||||
const token = authHeader && authHeader.split(' ')[1];
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
BLAH BLAH
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "client",
|
||||
"private": true,
|
||||
"version": "2.0.0-alpha-1",
|
||||
"version": "2.0.0-alpha-3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -14,16 +14,20 @@
|
||||
"@fortawesome/fontawesome-svg-core": "^7.1.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^7.1.0",
|
||||
"@fortawesome/react-fontawesome": "^3.1.0",
|
||||
"@heroui/react": "^3.0.0-beta.2",
|
||||
"@heroui/styles": "^3.0.0-beta.2",
|
||||
"@noahspan/noahspan-components": "^2.0.0-alpha-14",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@tailwindcss/vite": "^4.1.13",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"axios": "^1.7.2",
|
||||
"daisyui": "^5.1.10",
|
||||
"dotenv": "^16.4.7",
|
||||
"framer-motion": "^12.23.24",
|
||||
"leaflet": "^1.9.4",
|
||||
"oidc-spa": "^7.2.4",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-hook-form": "^7.51.4",
|
||||
"react-leaflet": "^4",
|
||||
"react-leaflet-kml": "^2.1.2",
|
||||
|
||||
@@ -3,22 +3,20 @@ import Flights from './components/flights/Flights';
|
||||
import Logbook from './components/logbook/Logbook';
|
||||
import Pilots from './components/pilots/Pilots';
|
||||
import SiteNav from './components/siteNav/SiteNav';
|
||||
import { HeroUIProvider } from '@heroui/react';
|
||||
import { useHref, useNavigate } from 'react-router-dom';
|
||||
import './styles.css';
|
||||
|
||||
const App = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<HeroUIProvider navigate={navigate} useHref={useHref}>
|
||||
<>
|
||||
<SiteNav />
|
||||
<Routes>
|
||||
<Route path='/' element={<Flights />} />
|
||||
<Route path="/logbook" element={<Logbook />} />
|
||||
<Route path="/pilots" element={<Pilots />} />
|
||||
</Routes>
|
||||
</HeroUIProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ import { createReactOidc } from "oidc-spa/react";
|
||||
|
||||
export const { OidcProvider, useOidc, getOidc } = createReactOidc(async () => ({
|
||||
issuerUri: `https://login.microsoftonline.com/${import.meta.env.VITE_TENANT_ID}/v2.0`,
|
||||
clientId: import.meta.env.VITE_CLIENT_APP_ID,
|
||||
homeUrl: import.meta.env.BASE_URL,
|
||||
scopes: ['email', 'openid', 'profile', `api://${import.meta.env.VITE_API_APP_ID}/user_impersonation`],
|
||||
clientId: import.meta.env.VITE_CLIENT_ID,
|
||||
homeUrl: import.meta.env.VITE_BASE_URL,
|
||||
scopes: ['email', 'openid', 'profile', `api://${import.meta.env.VITE_CLIENT_ID}/user_impersonation`],
|
||||
autoLogin: false,
|
||||
postLoginRedirectUrl: '/',
|
||||
noIframe: true
|
||||
|
||||
@@ -12,6 +12,7 @@ const Flights = () => {
|
||||
const { logs, logsLoading } = useLogs();
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
const flights: LogbookEntry[] | undefined = logs?.filter((log: LogbookEntry) => {
|
||||
if (log.tracks && log.tracks.length > 0) {
|
||||
return log;
|
||||
@@ -25,10 +26,6 @@ const Flights = () => {
|
||||
dispatch({ type: 'SET_ALERT', payload: { severity: 'default', message: 'No flights found' }})
|
||||
}
|
||||
}, [logs])
|
||||
|
||||
useEffect(() => {
|
||||
console.log(logsLoading)
|
||||
}, [logsLoading])
|
||||
|
||||
return (
|
||||
<div className='max-w-screen-lg mx-auto'>
|
||||
|
||||
@@ -508,7 +508,6 @@ const Logbook: React.FC<unknown> = () => {
|
||||
onPress={() => onOpenCloseDrawer(FormMode.ADD)}
|
||||
startContent={<FontAwesomeIcon icon={faAdd} />}
|
||||
data-testid="pilot-add-button"
|
||||
data-theme="lofi"
|
||||
>
|
||||
Add Entry
|
||||
</Button>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Accordion, AccordionItem, Card, CardBody, CardHeader } from '@heroui/react'
|
||||
import { Accordion, AccordionItem, Card, CardContent, CardHeader } from '@heroui/react'
|
||||
import { LogbookCardProps } from "./LogbookCardProps.interface";
|
||||
import TrackMap from "../trackMap/TrackMap";
|
||||
|
||||
@@ -6,7 +6,6 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps
|
||||
return (
|
||||
<div>
|
||||
{logs.map((log) => {
|
||||
console.log(log)
|
||||
const date = new Date(log.date);
|
||||
const formattedDate: string = `${date.getMonth()}/${date.getDate()}/${date.getFullYear()}`;
|
||||
|
||||
@@ -16,7 +15,7 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps
|
||||
<CardHeader>
|
||||
<h2 className='font-bold text-2xl'>{formattedDate}</h2>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<CardContent>
|
||||
{mode === 'flights' && log.tracks && log.tracks.length > 0 &&
|
||||
<div className='mb-5'>
|
||||
<TrackMap
|
||||
@@ -26,8 +25,8 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
<Accordion variant='bordered'>
|
||||
<AccordionItem key='1' title='Details'>
|
||||
<Accordion variant='surface'>
|
||||
<AccordionItem key='1'>
|
||||
<div className='grid grid-cols-12 gap-3 mr-[30%] ml-[30%] mt-4 mb-4'>
|
||||
<div className='col-span-6 font-bold'>
|
||||
<span>Aircraft Make and Model</span>
|
||||
@@ -67,7 +66,7 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
|
||||
</CardBody>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -48,7 +48,6 @@ const LogbookDrawer = ({ onOpenClose }: LogbookDrawerProps) => {
|
||||
};
|
||||
|
||||
const onSubmit = async (data: unknown) => {
|
||||
console.log(data)
|
||||
try {
|
||||
logbookContext.dispatch({ type: 'SET_IS_FORM_LOADING', payload: true });
|
||||
|
||||
@@ -103,36 +102,35 @@ const LogbookDrawer = ({ onOpenClose }: LogbookDrawerProps) => {
|
||||
</div>
|
||||
)}
|
||||
<Tabs
|
||||
color='default'
|
||||
fullWidth={true}
|
||||
onSelectionChange={onSelectedKeyChanged}
|
||||
selectedKey={activeTab as string}
|
||||
variant='solid'
|
||||
>
|
||||
<Tab
|
||||
key='time'
|
||||
title={
|
||||
<div className="flex items-center space-x-2">
|
||||
<Tabs.ListContainer>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab
|
||||
id='time'
|
||||
>
|
||||
<FontAwesomeIcon icon={faClock} />
|
||||
<span>Time</span>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<LogForm />
|
||||
</Tab>
|
||||
{logbookContext.state.formMode !== FormMode.ADD &&
|
||||
<Tab
|
||||
key='tracks'
|
||||
title={
|
||||
<div className="flex items-center space-x-2">
|
||||
Time
|
||||
<Tabs.Indicator />
|
||||
</Tabs.Tab>
|
||||
{logbookContext.state.formMode !== FormMode.ADD &&
|
||||
<Tabs.Tab
|
||||
id='tracks'
|
||||
>
|
||||
<FontAwesomeIcon icon={faMapLocationDot} />
|
||||
<span>Tracks</span>
|
||||
</div>
|
||||
Tracks
|
||||
<Tabs.Indicator />
|
||||
</Tabs.Tab>
|
||||
}
|
||||
>
|
||||
<TracksForm />
|
||||
</Tab>
|
||||
}
|
||||
</Tabs.List>
|
||||
</Tabs.ListContainer>
|
||||
<Tabs.Panel id='time'>
|
||||
<LogForm />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel id='tracks'>
|
||||
<TracksForm />
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
</DrawerBody>
|
||||
{activeTab !== 'tracks' &&
|
||||
@@ -140,24 +138,24 @@ const LogbookDrawer = ({ onOpenClose }: LogbookDrawerProps) => {
|
||||
<div className='grid grid-cols-12 gap-3'>
|
||||
<div className='col-span-12 justify-self-end self-center'>
|
||||
<Button
|
||||
disabled={
|
||||
isDisabled={
|
||||
logbookContext.state.isFormDisabled && logbookContext.state.formMode.toString() !== FormMode.VIEW
|
||||
? logbookContext.state.isFormDisabled
|
||||
: false
|
||||
}
|
||||
startContent={<FontAwesomeIcon icon={faXmark} />}
|
||||
onPress={onCancel}
|
||||
>
|
||||
<FontAwesomeIcon icon={faXmark} />
|
||||
{logbookContext.state.formMode.toString() !== FormMode.VIEW ? 'Cancel' : 'Close'}
|
||||
</Button>
|
||||
{logbookContext.state.formMode.toString() !== FormMode.VIEW && (
|
||||
<Button
|
||||
className='ml-[10px]'
|
||||
color='primary'
|
||||
disabled={logbookContext.state.isFormDisabled}
|
||||
startContent={<FontAwesomeIcon icon={faSave} />}
|
||||
isDisabled={logbookContext.state.isFormDisabled}
|
||||
type="submit"
|
||||
variant='primary'
|
||||
>
|
||||
<FontAwesomeIcon icon={faSave} />
|
||||
Save
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { UserRole } from '../../enums/userRole';
|
||||
import httpClient from '../../httpClient/httpClient'
|
||||
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 { Alert, Button, Dropdown, Table, TableHeader, TableBody, TableColumn, TableRow, TableCell } from '@heroui/react'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faEllipsisVertical, faPen, faEye, faTrash, faPlus } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
@@ -50,7 +50,6 @@ const Pilots: React.FC<unknown> = () => {
|
||||
};
|
||||
|
||||
const onOpenClosePilotForm = async (mode: FormMode, pilotId?: string) => {
|
||||
console.log(pilotId)
|
||||
switch (mode) {
|
||||
case FormMode.ADD:
|
||||
case FormMode.EDIT:
|
||||
@@ -134,38 +133,40 @@ const Pilots: React.FC<unknown> = () => {
|
||||
case 'actions': {
|
||||
return (
|
||||
<Dropdown>
|
||||
<DropdownTrigger>
|
||||
<Button isIconOnly variant='light' size='lg'>
|
||||
<Dropdown.Trigger>
|
||||
<Button isIconOnly size='lg'>
|
||||
<FontAwesomeIcon icon={faEllipsisVertical} />
|
||||
</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu>
|
||||
<DropdownSection showDivider>
|
||||
<DropdownItem
|
||||
key='edit'
|
||||
onPress={() => onOpenClosePilotForm(FormMode.EDIT, pilot.id)}
|
||||
startContent={<FontAwesomeIcon icon={faPen} />}
|
||||
>
|
||||
Edit
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
key='view'
|
||||
onPress={() => onOpenClosePilotForm(FormMode.VIEW, pilot.id)}
|
||||
startContent={<FontAwesomeIcon icon={faEye} />}
|
||||
>
|
||||
View
|
||||
</DropdownItem>
|
||||
</DropdownSection>
|
||||
<DropdownSection>
|
||||
<DropdownItem
|
||||
key='Delete'
|
||||
onPress={() => onDeletePilot(pilot.id)}
|
||||
startContent={<FontAwesomeIcon icon={faTrash} />}
|
||||
</Dropdown.Trigger>
|
||||
<Dropdown.Popover>
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Section>
|
||||
<Dropdown.Item
|
||||
key='edit'
|
||||
onPress={() => onOpenClosePilotForm(FormMode.EDIT, pilot.id)}
|
||||
>
|
||||
Delete
|
||||
</DropdownItem>
|
||||
</DropdownSection>
|
||||
</DropdownMenu>
|
||||
<FontAwesomeIcon icon={faPen} />
|
||||
Edit
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
key='view'
|
||||
onPress={() => onOpenClosePilotForm(FormMode.VIEW, pilot.id)}
|
||||
>
|
||||
<FontAwesomeIcon icon={faEye} />
|
||||
View
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Section>
|
||||
<Dropdown.Section>
|
||||
<Dropdown.Item
|
||||
key='Delete'
|
||||
onPress={() => onDeletePilot(pilot.id)}
|
||||
>
|
||||
<FontAwesomeIcon icon={faTrash} />
|
||||
Delete
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Section>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown.Popover>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -101,16 +101,11 @@ const TracksForm = () => {
|
||||
}, [logbookContext.state.selectedLogId])
|
||||
|
||||
useEffect(() => {
|
||||
console.log(logbookContext.state.formMode)
|
||||
if (logbookContext.state.formMode === FormMode.VIEW) {
|
||||
dispatch({ type: 'SET_IS_DISABLED', payload: true });
|
||||
}
|
||||
}, [logbookContext.state.formMode]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(state.isDisabled)
|
||||
}, [state.isDisabled])
|
||||
|
||||
return (
|
||||
<div className='grid grid-cols-12 gap-3'>
|
||||
{state.tracks.length > 0 &&
|
||||
@@ -125,7 +120,7 @@ const TracksForm = () => {
|
||||
return (
|
||||
<>
|
||||
<div className='col-span-10'>
|
||||
<Input isDisabled={state.isDisabled} key={index} type='text' value={filename}/>
|
||||
<Input disabled={state.isDisabled} key={index} type='text' value={filename}/>
|
||||
</div>
|
||||
<div className='col-span-2'>
|
||||
<Button isDisabled={state.isDisabled} key={index} isIconOnly onPress={() => onDeleteTrack(track.id, filename, index)}><FontAwesomeIcon icon={faTrash} /></Button>
|
||||
|
||||
9
client/src/globals.css
Normal file
9
client/src/globals.css
Normal file
@@ -0,0 +1,9 @@
|
||||
@import "tailwindcss";
|
||||
@import "@heroui/styles";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export const useBreakpoints = () => {
|
||||
switch (true) {
|
||||
case width < 640: {
|
||||
size = ScreenSize.SM;
|
||||
console.log('small')
|
||||
|
||||
break;
|
||||
}
|
||||
case width >= 640: {
|
||||
@@ -42,14 +42,10 @@ export const useBreakpoints = () => {
|
||||
const onWindowResize = () => {
|
||||
const width: number = window.innerWidth;
|
||||
const newScreenSize: ScreenSize = getWindowSize(width);
|
||||
console.log(newScreenSize)
|
||||
|
||||
setScreenSize(newScreenSize);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log(windowWidth)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
onWindowResize()
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import AppContextProvider from './context/appContext/AppContextProvider.tsx';
|
||||
import LogbookContextProvider from './context/logbookContext/LogbookContextProvider.tsx'
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { OidcProvider } from './auth/oidcConfig.ts';
|
||||
import './globals.css';
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
<OidcProvider>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
@import "tailwindcss";
|
||||
@plugin './hero.ts';
|
||||
/* Note: You may need to change the path to fit your project structure */
|
||||
@source '../../node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}';
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@theme inline {
|
||||
--color-primary: #000000;
|
||||
}
|
||||
|
||||
|
||||
3
client/src/vite-env.d.ts
vendored
3
client/src/vite-env.d.ts
vendored
@@ -1,10 +1,9 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_API_URL: string;
|
||||
readonly VITE_BASE_URL: string;
|
||||
readonly VITE_CLIENT_ID: string;
|
||||
readonly VITE_TENANT_ID: string;
|
||||
readonly VITE_REDIRECT_URL: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
|
||||
@@ -19,7 +19,7 @@ export default defineConfig({
|
||||
target: 'http://localhost:3000',
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
// rewrite: (path) => path.replace(/^\/api/, '')
|
||||
rewrite: (path) => path.replace(/^\/api/, '')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
38
infrastructure/.terraform.lock.hcl
generated
38
infrastructure/.terraform.lock.hcl
generated
@@ -1,6 +1,25 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hashicorp/azuread" {
|
||||
version = "3.7.0"
|
||||
hashes = [
|
||||
"h1:+DHwtiYCOYEhLMot5KQ0hm+zopmUJwPJ/gJiXVfdNOs=",
|
||||
"zh:01114beb07eb8415a563ca80a513e7fd11fd6f0670bdd960e9092e58464ab2b7",
|
||||
"zh:1460c790ca28cc11c3efd4abec076fc5cdd4ae1cc654a45c69e10ca064e0a611",
|
||||
"zh:161b6dd82cf279e7ac7a31c404f2ace491a5a9e7ec382ace91de2fd18f8c190b",
|
||||
"zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7",
|
||||
"zh:2eff0bea92c48be0221863ebf7752f491232088f4ec3cbe4da2ebf9f478fed1f",
|
||||
"zh:69a689198fcac054da30fea6a8abce2f12b667f6f327c9bb388f2c307ee782fd",
|
||||
"zh:6f5acf42d71a2f5157c54e67b2db9b080c4ebb27b812112c0c84241e66d94803",
|
||||
"zh:8e0a58ff2c21aff372c66c679db48578be48e99f5cf6727f082cf4b629dbda6c",
|
||||
"zh:9c88cc06ba7ee1f6e6b43af7e223c4d107fb77e5a984f1441fffb00c3693537f",
|
||||
"zh:e8656e8143baac71029857c72899f8503cede41f2559c89ce29d21c0436c96fc",
|
||||
"zh:e8e21913956a3f043c0e65cc95278bdc82f62ff33fd75a56b1919bd63fd14f8a",
|
||||
"zh:f7f213dd61d1c75b8397d97660cf329870a241e88ec6e0dc07c60725d975252e",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/azurerm" {
|
||||
version = "4.40.0"
|
||||
constraints = "4.40.0"
|
||||
@@ -20,3 +39,22 @@ provider "registry.terraform.io/hashicorp/azurerm" {
|
||||
"zh:f6fd85bfca8516f9f3840acc3f0e5e335f6195b66231c2db05c0fb43dd8aebe1",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/random" {
|
||||
version = "3.7.2"
|
||||
hashes = [
|
||||
"h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=",
|
||||
"zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f",
|
||||
"zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc",
|
||||
"zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab",
|
||||
"zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3",
|
||||
"zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212",
|
||||
"zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34",
|
||||
"zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967",
|
||||
"zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d",
|
||||
"zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62",
|
||||
"zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,16 @@ locals {
|
||||
prod = "flying-prod"
|
||||
}
|
||||
|
||||
app_reg_name = {
|
||||
test = "noahspan-flying-test"
|
||||
prod = "noahspan-flying-prod"
|
||||
}
|
||||
|
||||
app_reg_federated_identity_credential_subject = {
|
||||
test = "repo:noahspannbauer/noahspan-flying:environment:test"
|
||||
prod = "repo:noahspannbauer/noahspan-flying:environment:prod"
|
||||
}
|
||||
|
||||
container_image = {
|
||||
test = "noahspan/flying-app:v2.0.0-alpha"
|
||||
prod = "noahspan/flying-app:v2.0.0-alpha"
|
||||
|
||||
@@ -2,6 +2,14 @@ output "app_name" {
|
||||
value = local.app_name[var.environment]
|
||||
}
|
||||
|
||||
output "app_reg_name" {
|
||||
value = local.app_reg_name[var.environment]
|
||||
}
|
||||
|
||||
output "app_reg_federated_identity_credential_subject" {
|
||||
value = local.app_reg_federated_identity_credential_subject[var.environment]
|
||||
}
|
||||
|
||||
output "container_image" {
|
||||
value = local.container_image[var.environment]
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
# data "azuread_application" "app_registration" {
|
||||
# provider = azuread.external_tenant
|
||||
# display_name = module.environment.app_reg_name
|
||||
# }
|
||||
|
||||
resource "azurerm_container_app" "container_app" {
|
||||
name = module.environment.app_name
|
||||
container_app_environment_id = data.azurerm_container_app_environment.container_app_environment.id
|
||||
@@ -60,7 +65,7 @@ resource "azurerm_container_app" "container_app" {
|
||||
|
||||
container {
|
||||
cpu = 0.25
|
||||
image = "noahspan/flying-app:v2.0.0-alpha"
|
||||
image = "noahspan/flying:19615036250"
|
||||
memory = "0.5Gi"
|
||||
name = "flying"
|
||||
|
||||
@@ -71,7 +76,7 @@ resource "azurerm_container_app" "container_app" {
|
||||
|
||||
env {
|
||||
name = "CLIENT_ID"
|
||||
secret_name = "client-id"
|
||||
value = var.CLIENT_ID
|
||||
}
|
||||
|
||||
env {
|
||||
@@ -81,7 +86,7 @@ resource "azurerm_container_app" "container_app" {
|
||||
|
||||
env {
|
||||
name = "TENANT_ID"
|
||||
value = var.TENANT_ID
|
||||
value = var.EXTERNAL_TENANT_ID
|
||||
}
|
||||
|
||||
env {
|
||||
@@ -144,11 +149,6 @@ resource "azurerm_container_app" "container_app" {
|
||||
value = azurerm_storage_account.storage_account.primary_connection_string
|
||||
}
|
||||
|
||||
secret {
|
||||
name = "client-id"
|
||||
value = var.CLIENT_ID
|
||||
}
|
||||
|
||||
secret {
|
||||
name = "client-secret"
|
||||
value = var.CLIENT_SECRET
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
||||
}
|
||||
|
||||
provider "random" {}
|
||||
@@ -6,6 +6,14 @@ terraform {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "4.40.0"
|
||||
}
|
||||
|
||||
azuread = {
|
||||
source = "hashicorp/azuread"
|
||||
}
|
||||
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
}
|
||||
}
|
||||
|
||||
backend "remote" {
|
||||
|
||||
@@ -21,6 +21,10 @@ variable "RESOURCE_GROUP_NAME" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "EXTERNAL_TENANT_ID" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "TENANT_ID" {
|
||||
type = string
|
||||
}
|
||||
|
||||
2772
package-lock.json
generated
2772
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "@noahspan/flying",
|
||||
"version": "2.0.0-alpha-1",
|
||||
"version": "2.0.0-alpha-3",
|
||||
"scripts": {
|
||||
"start": "concurrently 'npm run start:azure -w api' 'wait-on tcp:0.0.0.0:7071 && npm run dev -w app'",
|
||||
"start": "node api/dist/main",
|
||||
"format": "prettier --write \"**/src/**/*.ts\" \"**/test/**/*.ts\"",
|
||||
"lint": "npm run lint -w api && npm run lint -w app",
|
||||
"prepare": "husky || true",
|
||||
@@ -12,20 +12,15 @@
|
||||
"build": "turbo run build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||
"@typescript-eslint/parser": "^7.2.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.6",
|
||||
"husky": "^9.0.11",
|
||||
"lint-staged": "^15.2.2",
|
||||
"prettier": "3.2.5",
|
||||
"rimraf": "^6.0.1",
|
||||
"turbo": "^2.5.6",
|
||||
"wait-on": "^7.2.0"
|
||||
"prettier": "3.2.5"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*": "prettier --write \"**/src/**/*.ts\" \"**/test/**/*.ts\" --ignore-unknown"
|
||||
@@ -35,10 +30,5 @@
|
||||
"client",
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"@heroui/react": "^2.8.5",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"daisyui": "^5.1.10",
|
||||
"framer-motion": "^12.23.24"
|
||||
}
|
||||
"packageManager": "npm@9.8.1"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user