Refactoring

This commit is contained in:
2025-01-17 20:38:24 -06:00
parent 540b38de30
commit ab56211602
68 changed files with 3201 additions and 2616 deletions

18
app/Dockerfile Normal file
View File

@@ -0,0 +1,18 @@
ARG VITE_API_URL
ARG VITE_CLIENT_ID
ARG VITE_TENANT_ID
ARG VITE_REDIRECT_URL
FROM --platform=linux/amd64 node:18-alpine
WORKDIR /app
COPY ./dist ./dist
ENV NODE_ENV=production
RUN npm i -g serve
EXPOSE 8080
CMD [ "serve", "-s", "dist", "-p", "8080" ]

View File

@@ -1,24 +1,20 @@
{
"name": "@noahspan/flying-client",
"name": "@noahspan/flying-app",
"private": true,
"version": "0.1.10",
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
"preview": "vite preview",
"serve": "serve -s dist"
},
"dependencies": {
"@azure/msal-browser": "^3.17.0",
"@azure/msal-react": "^2.0.19",
"@fortawesome/fontawesome-svg-core": "^6.5.2",
"@fortawesome/free-regular-svg-icons": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"@noahspan/noahspan-components": "^0.8.9",
"axios": "^1.7.2",
"framer-motion": "^11.1.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.4",
@@ -29,9 +25,6 @@
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"tailwindcss": "^3.4.3",
"typescript": "^5.2.2",
"vite": "^5.2.0"
},

View File

@@ -1,6 +0,0 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
};

View File

@@ -19,6 +19,7 @@ const App: React.FC<unknown> = () => {
const response: AxiosResponse = await httpClient.get(
`api/featureFlags?keys=${featureFlagKeys}&label=${import.meta.env.MODE}`
);
console.log(response);
const featureFlags: { key: string; enabled: boolean }[] = response.data;
if (featureFlags.length > 0) {

View File

@@ -1,6 +1,6 @@
import { FormMode } from '../../enums/formMode';
export interface ILogbookEntryFormProps {
export interface ILogFormProps {
entryId?: string;
isDrawerOpen: boolean;
mode: FormMode;

View File

@@ -1,4 +1,4 @@
export interface ILogbookEntryFormState {
export interface ILogFormState {
error: string | undefined;
isDisabled: boolean;
isLoading: boolean;

View File

@@ -17,7 +17,7 @@ import {
XmarkIcon
} from '@noahspan/noahspan-components';
import { useForm, Controller, FormProvider } from 'react-hook-form';
import { ILogbookEntryFormProps } from './ILogbookEntryFormProps';
import { ILogFormProps } from './ILogFormProps';
import { initialState, reducer } from './reducer';
import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';
import { useHttpClient } from '../../hooks/httpClient/UseHttpClient';
@@ -26,7 +26,7 @@ import { useIsAuthenticated } from '@azure/msal-react';
import { FormMode } from '../../enums/formMode';
import { usePilots } from '../../hooks/pilots/UsePilots';
const LogbookEntryForm: React.FC<ILogbookEntryFormProps> = ({
const LogForm: React.FC<ILogFormProps> = ({
entryId,
isDrawerOpen,
mode,
@@ -37,8 +37,6 @@ const LogbookEntryForm: React.FC<ILogbookEntryFormProps> = ({
const { getAccessToken } = useAccessToken();
const isAuthenticated = useIsAuthenticated();
const defaultValues = {
partitionKey: '',
rowKey: '',
pilotId: '',
pilotName: '',
date: null,
@@ -80,13 +78,13 @@ const LogbookEntryForm: React.FC<ILogbookEntryFormProps> = ({
const accessToken: string = await getAccessToken();
if (!entryId) {
await httpClient.post(`api/logbook`, data, {
await httpClient.post(`api/logs`, data, {
headers: {
Authorization: accessToken
}
});
} else {
await httpClient.put(`api/logbook/${entryId}`, data, {
await httpClient.put(`api/logs/${entryId}`, data, {
headers: {
Authorization: accessToken
}
@@ -120,7 +118,7 @@ const LogbookEntryForm: React.FC<ILogbookEntryFormProps> = ({
? { headers: { Authorization: await getAccessToken() } }
: {};
const response: AxiosResponse = await httpClient.get(
`api/logbook/${entryId}`,
`api/logs/${entryId}`,
config
);
const entry = response.data;
@@ -939,4 +937,4 @@ const LogbookEntryForm: React.FC<ILogbookEntryFormProps> = ({
);
};
export default LogbookEntryForm;
export default LogForm;

View File

@@ -1,4 +1,4 @@
import { ILogbookEntryFormState } from './ILogbookEntryFormState';
import { ILogFormState } from './ILogFormState';
type Action =
| { type: 'SET_ERROR'; payload: string | undefined }
@@ -7,7 +7,7 @@ type Action =
| { type: 'SET_PILOT_OPTIONS'; payload: { label: string; value: string }[] }
| { type: 'SET_SELECTED_ENTRY_PILOT_NAME'; payload: string };
export const initialState: ILogbookEntryFormState = {
export const initialState: ILogFormState = {
error: undefined,
isDisabled: false,
isLoading: true,
@@ -16,9 +16,9 @@ export const initialState: ILogbookEntryFormState = {
};
export const reducer = (
state: ILogbookEntryFormState,
state: ILogFormState,
action: Action
): ILogbookEntryFormState => {
): ILogFormState => {
switch (action.type) {
case 'SET_ERROR': {
return {

View File

@@ -1,5 +1,5 @@
import { useEffect, useReducer, useState } from 'react';
import LogbookEntryForm from '../logbookEntryForm/LogbookEntryForm';
import { useEffect, useReducer } from 'react';
import LogForm from '../logForm/LogForm';
import {
Alert,
Box,
@@ -35,10 +35,7 @@ const Logbook: React.FC<unknown> = () => {
const config = isAuthenticated
? { headers: { Authorization: `${token}` } }
: {};
const response: AxiosResponse = await httpClient.get(
`api/logbook`,
config
);
const response: AxiosResponse = await httpClient.get(`api/logs`, config);
dispatch({ type: 'SET_ENTRIES', payload: response.data });
} catch (error) {
@@ -98,7 +95,7 @@ const Logbook: React.FC<unknown> = () => {
? { headers: { Authorization: `${token}` } }
: {};
await httpClient.delete(`api/logbook/${state.selectedEntryId}`, config);
await httpClient.delete(`api/logs/${state.selectedEntryId}`, config);
dispatch({
type: 'SET_DELETE',
@@ -419,7 +416,7 @@ const Logbook: React.FC<unknown> = () => {
)}
</Grid>
{state.isFormOpen && (
<LogbookEntryForm
<LogForm
entryId={state.selectedEntryId}
isDrawerOpen={state.isFormOpen}
mode={state.formMode}

View File

@@ -13,7 +13,7 @@ import {
XmarkIcon
} from '@noahspan/noahspan-components';
import { IPilotFormProps } from './IPilotFormProps';
import axios, { AxiosInstance, AxiosResponse } from 'axios';
import { AxiosError, AxiosInstance, AxiosResponse } from 'axios';
import { useHttpClient } from '../../hooks/httpClient/UseHttpClient';
import { useAccessToken } from '../../hooks/accessToken/UseAcessToken';
import { useIsAuthenticated } from '@azure/msal-react';
@@ -38,8 +38,8 @@ const PilotForm: React.FC<IPilotFormProps> = ({
const { getAccessToken } = useAccessToken();
const isAuthenticated = useIsAuthenticated();
const defaultValues = {
partitionKey: '',
rowKey: '',
partitionKey: 'pilot',
rowKey: 'noah@noahspannbauer.com',
id: '',
name: '',
address: '',
@@ -53,6 +53,7 @@ const PilotForm: React.FC<IPilotFormProps> = ({
defaultValues: defaultValues
});
const [isDisabled, setIsDisabled] = useState<boolean>(false);
const [isError, setIsError] = useState<boolean>(false);
const onPeoplePickerSearch = async (
_event: React.SyntheticEvent,
@@ -105,24 +106,19 @@ const PilotForm: React.FC<IPilotFormProps> = ({
setIsLoading(true);
const accessToken: string = await getAccessToken();
const response: AxiosResponse = await httpClient.post(
`api/pilots`,
data,
{
headers: {
Authorization: accessToken
}
await httpClient.post(`api/pilots`, data, {
headers: {
Authorization: accessToken
}
);
});
if (response) console.log(response);
onOpenClose(FormMode.CANCEL);
} catch (error) {
if (axios.isAxiosError(error)) {
const errResp = error.response;
const axiosError = error as AxiosError;
const responseData = axiosError.response?.data as any;
console.log(errResp?.data.message);
} else {
}
console.log(responseData.message);
} finally {
setIsLoading(false);
}

View File

@@ -39,7 +39,25 @@ const Pilots: React.FC<unknown> = () => {
const [pilotFormMode, setPilotFormMode] = useState<FormMode>(FormMode.CANCEL);
const [selectedPilotId, setSelectedPilotId] = useState<string | undefined>();
const [pilots, setPilots] = useState<Pilot[]>([]);
const onOpenClosePilotForm = (mode: FormMode, pilotId?: string) => {
const getPilots = async (): Promise<Pilot[]> => {
try {
const config = isAuthenticated
? { headers: { Authorization: await getAccessToken() } }
: {};
const response: AxiosResponse = await httpClient.get(
`api/pilots`,
config
);
const pilots: Pilot[] = response.data;
return pilots;
} catch (error) {
throw new Error('broken');
}
};
const onOpenClosePilotForm = async (mode: FormMode, pilotId?: string) => {
switch (mode) {
case FormMode.ADD:
case FormMode.EDIT:
@@ -49,6 +67,9 @@ const Pilots: React.FC<unknown> = () => {
setIsDrawerOpen(true);
break;
case FormMode.CANCEL:
const pilots = await getPilots();
setPilots(pilots);
setPilotFormMode(mode);
setSelectedPilotId(undefined);
setIsDrawerOpen(false);
@@ -73,6 +94,7 @@ const Pilots: React.FC<unknown> = () => {
const onCloseActionMenu = () => {
setAnchorElAction(null);
};
return (
<div>
<IconButton onClick={onOpenActionMenu}>
@@ -124,23 +146,17 @@ const Pilots: React.FC<unknown> = () => {
];
useEffect(() => {
const getPilots = async () => {
const loadPilots = async () => {
try {
const config = isAuthenticated
? { headers: { Authorization: await getAccessToken() } }
: {};
const response: AxiosResponse = await httpClient.get(
`api/pilots`,
config
);
console.log(response.data);
setPilots(response.data);
const pilots = await getPilots();
setPilots(pilots);
} catch (error) {
console.log(error);
}
};
getPilots();
loadPilots();
}, []);
return (

12
app/src/index.html Normal file
View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@@ -1,9 +0,0 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {}
},
darkMode: 'class',
plugins: []
};

View File

@@ -3,5 +3,14 @@ import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()]
plugins: [react()],
preview: {
port: 8080,
strictPort: true
},
server: {
port: 8080,
strictPort: true,
host: '0.0.0.0'
}
});