renaming app directory

This commit is contained in:
2025-02-23 14:55:13 -06:00
parent 5f26c48aba
commit e3f20617e9
43 changed files with 3 additions and 3 deletions

View File

@@ -0,0 +1,354 @@
import { useEffect, useReducer } from 'react';
import {
Alert,
Button,
Drawer,
Grid,
Icon,
IconButton,
IconName,
TextField,
Typography
} from '@noahspan/noahspan-components';
import { useForm, Controller, FormProvider } from 'react-hook-form';
import { initialState, reducer } from './reducer';
import { ProjectFormProps } from './ProjectFormProps.interface';
import { FormMode } from '../../enums/formMode';
import { useIsAuthenticated } from '@azure/msal-react';
import { useAccessToken } from '../../hooks/accessToken/UseAccessToken';
import { useHttpClient } from '../../hooks/httpClient/UseHttpClient';
import { AxiosError, AxiosInstance, AxiosResponse } from 'axios';
const ProjectForm = ({ isDrawerOpen, mode, onOpenClose, projectId }: ProjectFormProps) => {
const [state, dispatch] = useReducer(reducer, initialState);
const httpClient: AxiosInstance = useHttpClient();
const { getAccessToken } = useAccessToken();
const isAuthenticated = useIsAuthenticated();
const defaultValues = {
partitionKey: 'project',
rowKey: '',
title: '',
subTitle: '',
iconName: '',
summary: '',
repoName: '',
siteUrl: '',
order: ''
}
const methods = useForm({
defaultValues: defaultValues
});
const watchRepoName = methods.watch(['repoName'])
const onCancel = () => {
methods.reset(defaultValues);
dispatch({ type: 'SET_IS_DISABLED', payload: false });
onOpenClose(FormMode.CANCEL);
};
const onSubmit = async (data: unknown) => {
console.log(data)
try {
dispatch({ type: 'SET_IS_LOADING', payload: true });
const accessToken: string = await getAccessToken();
if (!projectId) {
await httpClient.post(`api/projects`, data, {
headers: {
Authorization: accessToken
}
});
} else {
await httpClient.put(`api/projects/project/${projectId}`, data, {
headers: {
Authorization: accessToken
}
});
}
methods.reset(defaultValues);
dispatch({ type: 'SET_IS_DISABLED', payload: false });
onOpenClose(FormMode.CANCEL);
} catch (error) {
const axiosError = error as AxiosError;
dispatch({ type: 'SET_ERROR', payload: axiosError.message });
} finally {
dispatch({ type: 'SET_IS_LOADING', payload: false });
}
};
useEffect(() => {
if (watchRepoName.length > 0) {
methods.setValue('rowKey', watchRepoName[0])
}
}, [watchRepoName])
useEffect(() => {
if (mode === FormMode.VIEW) {
dispatch({ type: 'SET_IS_DISABLED', payload: true });
}
}, [mode]);
useEffect(() => {
const getProject = async () => {
try {
dispatch({ type: 'SET_IS_LOADING', payload: true });
const config = isAuthenticated
? { headers: { Authorization: await getAccessToken() } }
: {};
const response: AxiosResponse = await httpClient.get(
`api/projects/project/${projectId}`,
config
);
const entry = response.data;
methods.reset(entry);
} catch (error) {
const axiosError = error as AxiosError;
dispatch({ type: 'SET_ERROR', payload: axiosError.message });
} finally {
dispatch({ type: 'SET_IS_LOADING', payload: false });
}
};
if (projectId && isDrawerOpen) {
getProject();
}
}, [projectId]);
return (
<Drawer
open={isDrawerOpen}
anchor='right'
PaperProps={{
sx: {
padding: '30px',
width: '33%'
}
}}
>
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
<Grid container spacing={2}>
<Grid size={11}>
<Typography variant='h4'>{`${mode.toString().toLowerCase().charAt(0).toUpperCase() + mode.toString().slice(1).toLowerCase()} Project`}</Typography>
</Grid>
<Grid display="flex" justifyContent="right" size={1}>
<IconButton onClick={onCancel}>
<Icon iconName={IconName.XMARK} />
</IconButton>
</Grid>
{state.error && (
<Grid display="flex" justifyContent="center" size={12}>
<Alert
onClose={() =>
dispatch({ type: 'SET_ERROR', payload: undefined })
}
severity="error"
sx={{ width: '100%' }}
>
{state.error}
</Alert>
</Grid>
)}
<Grid alignItems="center" display="flex" size={4}>
<Typography variant="body1">Order</Typography>
</Grid>
<Grid size={8}>
<Controller
name="order"
control={methods.control}
render={({ field: { onChange, value } }) => (
<TextField
disabled={state.isDisabled}
error={methods.formState.errors.siteUrl ? true : false}
fullWidth
helperText={
methods.formState.errors.siteUrl
? methods.formState.errors.siteUrl.message?.toString()
: undefined
}
onChange={onChange}
value={value}
/>
)}
/>
</Grid>
<Grid alignItems="center" display="flex" size={4}>
<Typography variant="body1">Title</Typography>
</Grid>
<Grid size={8}>
<Controller
name="title"
control={methods.control}
render={({ field: { onChange, value } }) => (
<TextField
disabled={state.isDisabled}
error={methods.formState.errors.title ? true : false}
fullWidth
helperText={
methods.formState.errors.title
? methods.formState.errors.title.message?.toString()
: undefined
}
onChange={onChange}
value={value}
/>
)}
/>
</Grid>
<Grid alignItems="center" display="flex" size={4}>
<Typography variant="body1">Sub Title</Typography>
</Grid>
<Grid size={8}>
<Controller
name="subTitle"
control={methods.control}
render={({ field: { onChange, value } }) => (
<TextField
disabled={state.isDisabled}
error={methods.formState.errors.siteUrl ? true : false}
fullWidth
helperText={
methods.formState.errors.siteUrl
? methods.formState.errors.siteUrl.message?.toString()
: undefined
}
onChange={onChange}
value={value}
/>
)}
/>
</Grid>
<Grid alignItems="center" display="flex" size={4}>
<Typography variant="body1">Icon Name</Typography>
</Grid>
<Grid size={8}>
<Controller
name="iconName"
control={methods.control}
render={({ field: { onChange, value } }) => (
<TextField
disabled={state.isDisabled}
error={methods.formState.errors.iconName ? true : false}
fullWidth
helperText={
methods.formState.errors.iconName
? methods.formState.errors.iconName.message?.toString()
: undefined
}
onChange={onChange}
value={value}
/>
)}
/>
</Grid>
<Grid alignItems="center" display="flex" size={4}>
<Typography variant="body1">Repo Name</Typography>
</Grid>
<Grid size={8}>
<Controller
name="repoName"
control={methods.control}
render={({ field: { onChange, value } }) => (
<TextField
disabled={state.isDisabled}
error={methods.formState.errors.repoName ? true : false}
fullWidth
helperText={
methods.formState.errors.repoName
? methods.formState.errors.repoName.message?.toString()
: undefined
}
onChange={onChange}
value={value}
/>
)}
/>
</Grid>
<Grid alignItems="center" display="flex" size={4}>
<Typography variant="body1">Site URL</Typography>
</Grid>
<Grid size={8}>
<Controller
name="siteUrl"
control={methods.control}
render={({ field: { onChange, value } }) => (
<TextField
disabled={state.isDisabled}
error={methods.formState.errors.siteUrl ? true : false}
fullWidth
helperText={
methods.formState.errors.siteUrl
? methods.formState.errors.siteUrl.message?.toString()
: undefined
}
onChange={onChange}
value={value}
/>
)}
/>
</Grid>
<Grid alignItems="center" display="flex" size={4}>
<Typography variant="body1">Summary</Typography>
</Grid>
<Grid size={8}>
<Controller
name="summary"
control={methods.control}
render={({ field: { onChange, value } }) => (
<TextField
disabled={state.isDisabled}
error={methods.formState.errors.summary ? true : false}
fullWidth
helperText={
methods.formState.errors.summary
? methods.formState.errors.summary.message?.toString()
: undefined
}
multiline
maxRows={5}
onChange={onChange}
value={value}
/>
)}
/>
</Grid>
<Grid display="flex" gap={2} justifyContent="right" size={12}>
<Button
disabled={
state.isDisabled && mode.toString() !== FormMode.VIEW
? state.isDisabled
: false
}
startIcon={<Icon iconName={IconName.XMARK} />}
variant="outlined"
onClick={onCancel}
size="small"
>
{mode.toString() !== FormMode.VIEW ? 'Cancel' : 'Close'}
</Button>
{mode.toString() !== FormMode.VIEW && (
<Button
disabled={state.isDisabled}
startIcon={<Icon iconName={IconName.SAVE} />}
size="small"
type="submit"
variant="contained"
>
Save
</Button>
)}
</Grid>
</Grid>
</form>
</FormProvider>
</Drawer>
)
}
export default ProjectForm;

View File

@@ -0,0 +1,8 @@
import { FormMode } from "../../enums/formMode";
export interface ProjectFormProps {
projectId?: string;
isDrawerOpen: boolean;
mode: FormMode;
onOpenClose: (mode: FormMode) => void;
}

View File

@@ -0,0 +1,5 @@
export interface ProjectFormState {
error: string | undefined;
isDisabled: boolean;
isLoading: boolean;
}

View File

@@ -0,0 +1,41 @@
import { ProjectFormState } from "./ProjectFormState.interface"
type Action =
| { type: 'SET_ERROR'; payload: string | undefined }
| { type: 'SET_IS_DISABLED'; payload: boolean }
| { type: 'SET_IS_LOADING'; payload: boolean }
export const initialState: ProjectFormState = {
error: undefined,
isDisabled: false,
isLoading: true,
};
export const reducer = (
state: ProjectFormState,
action: Action
): ProjectFormState => {
switch (action.type) {
case 'SET_ERROR': {
return {
...state,
error: action.payload
};
}
case 'SET_IS_DISABLED': {
return {
...state,
isDisabled: action.payload
};
}
case 'SET_IS_LOADING': {
return {
...state,
isLoading: action.payload
};
}
default: {
return state;
}
}
};