Skip to content

Commit 3f92c6f

Browse files
rdonigianCarsonF
authored andcommitted
Create Field Zone details page
1 parent ca1789d commit 3f92c6f

File tree

15 files changed

+347
-62
lines changed

15 files changed

+347
-62
lines changed

src/components/FieldZone/CreateFieldZone.tsx

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/components/FieldZone/index.tsx

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/components/form/Lookup/FieldZone/FieldZoneField.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import { DisplayFieldZoneFragment as FieldZone } from '~/common';
2-
import {
3-
CreateFieldZone,
4-
FieldZoneFormValues,
5-
} from '../../../../components/FieldZone';
1+
import { type CreateFieldZone as CreateFieldZoneType } from '~/api/schema.graphql';
2+
import { CreateFieldZone } from '~/scenes/FieldZones/CreateFieldZone/CreateFieldZone';
3+
import { FieldZoneFormValues } from '~/scenes/FieldZones/FieldZoneForm/FieldZoneForm';
4+
import { FieldZoneFormFragment } from '~/scenes/FieldZones/FieldZoneForm/FieldZoneForm.graphql';
65
import { LookupField } from '../LookupField';
76
import { FieldZoneLookupDocument } from './FieldZoneLookup.graphql';
87

98
export const FieldZoneField = LookupField.createFor<
10-
FieldZone,
11-
FieldZoneFormValues
9+
FieldZoneFormFragment,
10+
FieldZoneFormValues<CreateFieldZoneType>
1211
>({
1312
resource: 'FieldZone',
1413
lookupDocument: FieldZoneLookupDocument,
File renamed without changes.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { useMutation } from '@apollo/client';
2+
import { Except } from 'type-fest';
3+
import {
4+
CreateFieldZoneInput,
5+
type CreateFieldZone as CreateFieldZoneType,
6+
} from '~/api/schema.graphql';
7+
import { DisplayFieldZoneFragment } from '~/common';
8+
import {
9+
FieldZoneForm,
10+
FieldZoneFormProps,
11+
} from '../FieldZoneForm/FieldZoneForm';
12+
import { CreateFieldZoneDocument } from './CreateFieldZone.graphql';
13+
14+
type SubmitResult = DisplayFieldZoneFragment;
15+
16+
export type CreateFieldZoneProps = Except<
17+
FieldZoneFormProps<CreateFieldZoneType, SubmitResult>,
18+
'onSubmit'
19+
>;
20+
21+
export const CreateFieldZone = (props: CreateFieldZoneProps) => {
22+
const [createFieldZone] = useMutation(CreateFieldZoneDocument);
23+
24+
return (
25+
<FieldZoneForm<CreateFieldZoneType, SubmitResult>
26+
{...props}
27+
title="Create Field Zone"
28+
onSubmit={async (values) => {
29+
const input: CreateFieldZoneInput = {
30+
fieldZone: {
31+
name: values.fieldZone.name,
32+
directorId: values.fieldZone.director!.id,
33+
},
34+
};
35+
36+
const { data } = await createFieldZone({
37+
variables: { input },
38+
});
39+
return data!.createFieldZone.fieldZone;
40+
}}
41+
/>
42+
);
43+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
query FieldZoneDetail($fieldZoneId: ID!) {
2+
fieldZone(id: $fieldZoneId) {
3+
...DisplayFieldZone
4+
}
5+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import { useQuery } from '@apollo/client';
2+
import { Edit } from '@mui/icons-material';
3+
import { Box, Skeleton, Typography } from '@mui/material';
4+
import { Helmet } from 'react-helmet-async';
5+
import { useParams } from 'react-router-dom';
6+
import { canEditAny } from '~/common';
7+
import { useDialog } from '~/components/Dialog';
8+
import {
9+
DisplaySimpleProperty,
10+
DisplaySimplePropertyProps,
11+
} from '~/components/DisplaySimpleProperty';
12+
import { Link } from '~/components/Routing';
13+
import { Error } from '../../../components/Error';
14+
import { Fab } from '../../../components/Fab';
15+
import { Redacted } from '../../../components/Redacted';
16+
import { EditFieldZone } from '../Edit/EditFieldZone';
17+
import { FieldZoneDetailDocument } from './FieldZoneDetail.graphql';
18+
19+
export const FieldZoneDetail = () => {
20+
const { fieldZoneId = '' } = useParams();
21+
22+
const [editZoneState, editZone] = useDialog();
23+
24+
const { data, error } = useQuery(FieldZoneDetailDocument, {
25+
variables: { fieldZoneId },
26+
});
27+
28+
const fieldZone = data?.fieldZone;
29+
30+
return (
31+
<Box
32+
component="main"
33+
sx={{
34+
flex: 1,
35+
p: 4,
36+
}}
37+
>
38+
<Helmet title={fieldZone?.name.value || undefined} />
39+
<Error error={error}>
40+
{{
41+
NotFound: 'Could not find field zone',
42+
Default: 'Error loading field zone',
43+
}}
44+
</Error>
45+
{!error && (
46+
<Box
47+
sx={{
48+
maxWidth: (theme) => theme.breakpoints.values.md,
49+
display: 'flex',
50+
flexDirection: 'column',
51+
gap: 3,
52+
}}
53+
>
54+
<Box
55+
component="header"
56+
sx={{
57+
flex: 1,
58+
display: 'flex',
59+
}}
60+
>
61+
<Typography
62+
variant="h2"
63+
sx={{
64+
mr: 4,
65+
width: !fieldZone?.name ? '40%' : undefined,
66+
}}
67+
>
68+
{!fieldZone ? (
69+
<Skeleton width="100%" />
70+
) : (
71+
fieldZone.name.value ?? (
72+
<Redacted
73+
info="You don't have permission to view this field zone's name"
74+
width="40%"
75+
/>
76+
)
77+
)}
78+
</Typography>
79+
{canEditAny(fieldZone, true) && (
80+
<Fab
81+
color="primary"
82+
aria-label="edit zone"
83+
onClick={editZone}
84+
loading={!fieldZone}
85+
>
86+
<Edit />
87+
</Fab>
88+
)}
89+
</Box>
90+
<Box
91+
sx={{
92+
display: 'flex',
93+
}}
94+
>
95+
<Typography variant="h4">
96+
{fieldZone ? 'Field Zone' : <Skeleton width={200} />}
97+
</Typography>
98+
</Box>
99+
100+
<DisplayProperty
101+
label="Director"
102+
value={
103+
<Link to={`/users/${fieldZone?.director.value?.id}`}>
104+
{fieldZone?.director.value?.fullName}
105+
</Link>
106+
}
107+
loading={!fieldZone}
108+
/>
109+
</Box>
110+
)}
111+
{fieldZone && <EditFieldZone fieldZone={fieldZone} {...editZoneState} />}
112+
</Box>
113+
);
114+
};
115+
116+
const DisplayProperty = (props: DisplaySimplePropertyProps) =>
117+
!props.value && !props.loading ? null : (
118+
<DisplaySimpleProperty
119+
variant="body1"
120+
{...{ component: 'div' }}
121+
{...props}
122+
loading={
123+
props.loading ? (
124+
<>
125+
<Typography variant="body2">
126+
<Skeleton width="10%" />
127+
</Typography>
128+
<Typography variant="body1">
129+
<Skeleton width="40%" />
130+
</Typography>
131+
</>
132+
) : null
133+
}
134+
LabelProps={{
135+
color: 'textSecondary',
136+
variant: 'body2',
137+
...props.LabelProps,
138+
}}
139+
ValueProps={{
140+
color: 'textPrimary',
141+
...props.ValueProps,
142+
}}
143+
/>
144+
);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './FieldZoneDetail';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
mutation UpdateFieldZone($input: UpdateFieldZoneInput!) {
2+
updateFieldZone(input: $input) {
3+
fieldZone {
4+
...DisplayFieldZone
5+
}
6+
}
7+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { useMutation } from '@apollo/client';
2+
import { useMemo } from 'react';
3+
import { Except, SetRequired } from 'type-fest';
4+
import { UpdateFieldZone, UpdateFieldZoneInput } from '~/api/schema.graphql';
5+
import { DisplayFieldZoneFragment } from '~/common';
6+
import {
7+
FieldZoneForm,
8+
FieldZoneFormProps,
9+
} from '../FieldZoneForm/FieldZoneForm';
10+
import { UpdateFieldZoneDocument } from './EditFieldZone.graphql';
11+
12+
type SubmitResult = DisplayFieldZoneFragment;
13+
export type EditFieldZoneProps = Except<
14+
FieldZoneFormProps<UpdateFieldZone, SubmitResult>,
15+
'onSubmit' | 'initialValues'
16+
>;
17+
export const EditFieldZone = (
18+
props: SetRequired<EditFieldZoneProps, 'fieldZone'>
19+
) => {
20+
const [updateFieldZone] = useMutation(UpdateFieldZoneDocument);
21+
const { fieldZone } = props;
22+
23+
const initialValues = useMemo(
24+
() => ({
25+
fieldZone: {
26+
id: fieldZone.id,
27+
name: fieldZone.name.value,
28+
director: fieldZone.director.value ?? undefined,
29+
},
30+
}),
31+
[fieldZone]
32+
);
33+
34+
return (
35+
<FieldZoneForm<UpdateFieldZone, SubmitResult>
36+
{...props}
37+
title="Edit Field Zone"
38+
initialValues={initialValues}
39+
onSubmit={async ({ fieldZone: values }) => {
40+
const input: UpdateFieldZoneInput = {
41+
fieldZone: {
42+
id: values.id,
43+
name: values.name,
44+
directorId: values.director?.id ?? null,
45+
},
46+
};
47+
48+
const { data } = await updateFieldZone({
49+
variables: { input },
50+
});
51+
return data!.updateFieldZone.fieldZone;
52+
}}
53+
/>
54+
);
55+
};

0 commit comments

Comments
 (0)