Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit meal request form #83

Merged
merged 24 commits into from
Aug 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module.exports = {
"react/no-array-index-key": "off",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-static-element-interactions": "off",
"@typescript-eslint/no-unused-vars": "off",
"react/function-component-definition": [
"warn",
{
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/pages/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Button as ChakraButton, Wrap } from "@chakra-ui/react";
import React, { useContext } from "react";
import { useNavigate } from "react-router-dom";

import EditMealRequestForm from "./EditMealRequestForm";

import BackgroundImage from "../../assets/background.png";
import * as Routes from "../../constants/Routes";
import SampleContext from "../../contexts/SampleContext";
Expand Down Expand Up @@ -67,6 +69,7 @@ const Default = (): React.ReactElement => {
/>
<Button text="Edit Team" path={Routes.EDIT_TEAM_PAGE} />
<Button text="Hooks Demo" path={Routes.HOOKS_PAGE} />
<EditMealRequestForm />
</Wrap>
<div style={{ height: "2rem" }} />

Expand Down
315 changes: 315 additions & 0 deletions frontend/src/components/pages/EditMealRequestForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
import {
Button,
Divider,
Flex,
FormControl,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalOverlay,
Text,
useDisclosure,
} from "@chakra-ui/react";
import React, { useState } from "react";

import { Contact } from "../../types/UserTypes";
import { isValidEmail } from "../../utils/ValidationUtils";
import useIsWebView from "../../utils/useIsWebView";
import OnsiteStaffSection from "../common/OnsiteStaffSection";

const PLACEHOLDER_WEB_EXAMPLE_FULL_NAME = "Jane Doe";
const PLACEHOLDER_WEB_EXAMPLE_PHONE_NUMBER = "111-222-3333";
const PLACEHOLDER_WEB_EXAMPLE_EMAIL = "[email protected]";

const PLACEHOLDER_MOBILE_EXAMPLE_FULL_NAME = "Full Name (Jane Doe)";
const PLACEHOLDER_MOBILE_EXAMPLE_EMAIL = "Email ([email protected])";
const PLACEHOLDER_MOBILE_EXAMPLE_PHONE_NUMBER = "Phone Number (111-222-3333)";

const EditMealRequestForm = () => {
const [primaryContact, setPrimaryContact] = useState<Contact>({
name: "",
phone: "",
email: "",
});
const [onsiteInfo, setOnsiteInfo] = useState<Array<Contact>>([
{
name: "",
phone: "",
email: "",
},
]);

const [attemptedSubmit, setAttemptedSubmit] = useState(false);
const isWebView = useIsWebView();
const { isOpen, onOpen, onClose } = useDisclosure();

const initialFocusRef = React.useRef(null);

const getMobileContactSection = (): React.ReactElement => {
return (
<Flex flexDir="column" gap="8px">
<FormControl isRequired mb={6}>
<FormLabel variant="mobile-form-label-bold">
Primary Contact
</FormLabel>
<Flex flexDir="column" gap="8px">
<FormControl
isRequired
isInvalid={attemptedSubmit && primaryContact.name === ""}
>
<Input
variant="mobile-outline"
value={primaryContact.name}
onChange={(e) =>
setPrimaryContact({ ...primaryContact, name: e.target.value })
}
placeholder={PLACEHOLDER_MOBILE_EXAMPLE_FULL_NAME}
/>
</FormControl>
<FormControl
isRequired
isInvalid={attemptedSubmit && primaryContact.phone === ""}
>
<Input
variant="mobile-outline"
type="tel"
value={primaryContact.phone}
onChange={(e) =>
setPrimaryContact({
...primaryContact,
phone: e.target.value,
})
}
placeholder={PLACEHOLDER_MOBILE_EXAMPLE_PHONE_NUMBER}
/>
</FormControl>
<FormControl
isRequired
isInvalid={attemptedSubmit && !isValidEmail(primaryContact.email)}
>
<Input
variant="mobile-outline"
type="email"
value={primaryContact.email}
onChange={(e) =>
setPrimaryContact({
...primaryContact,
email: e.target.value,
})
}
placeholder={PLACEHOLDER_MOBILE_EXAMPLE_EMAIL}
/>
</FormControl>
</Flex>
</FormControl>
</Flex>
);
};

const getWebContactSection = (): React.ReactElement => {
return (
<>
<Text variant="desktop-heading" pt={4} pb={3}>
Contact Information
</Text>

<Flex flexDir="column" gap="24px">
<Flex flexDir="column">
<FormControl
isRequired
isInvalid={attemptedSubmit && primaryContact.name === ""}
>
<FormLabel
variant={{
base: "mobile-form-label-bold",
md: "form-label-bold",
}}
>
Primary contact name
</FormLabel>
<Input
value={primaryContact.name}
placeholder={PLACEHOLDER_WEB_EXAMPLE_FULL_NAME}
onChange={(e) =>
setPrimaryContact({ ...primaryContact, name: e.target.value })
}
/>
</FormControl>
</Flex>

<Flex flexDir="row" gap="24px">
<Flex flexDir="column" w="240px">
<FormControl
isRequired
isInvalid={attemptedSubmit && primaryContact.phone === ""}
mb={6}
>
<FormLabel
variant={{
base: "mobile-form-label-bold",
md: "form-label-bold",
}}
>
Phone number
</FormLabel>
<Input
type="tel"
value={primaryContact.phone}
placeholder={PLACEHOLDER_WEB_EXAMPLE_PHONE_NUMBER}
onChange={(e) =>
setPrimaryContact({
...primaryContact,
phone: e.target.value,
})
}
/>
</FormControl>
</Flex>

<Flex flexDir="column" w="519px">
<FormControl
isRequired
isInvalid={
attemptedSubmit && !isValidEmail(primaryContact.email)
}
>
<FormLabel
variant={{
base: "mobile-form-label-bold",
md: "form-label-bold",
}}
>
Email address
</FormLabel>
<Input
type="email"
value={primaryContact.email}
placeholder={PLACEHOLDER_WEB_EXAMPLE_EMAIL}
onChange={(e) =>
setPrimaryContact({
...primaryContact,
email: e.target.value,
})
}
/>
</FormControl>
</Flex>
</Flex>
</Flex>
</>
);
};

return (
<>
<Button onClick={onOpen}>Edit Meal Request</Button>
<Modal
initialFocusRef={initialFocusRef}
isOpen={isOpen}
onClose={onClose}
>
<ModalOverlay />
<ModalContent
maxWidth={{ base: "100%", md: "900px" }}
padding={{ base: "10px", md: "40px" }}
>
<Text
pb={{ base: 1, md: 5 }}
pl={{ base: 6, md: 6 }}
pt={{ base: 5, md: 8 }}
variant={{ base: "mobile-display-xl", md: "desktop-display-xl" }}
>
Edit Meal Request
</Text>
<ModalCloseButton />
<ModalBody pb={6}>
<Text
variant={{
base: "mobile-heading",
md: "desktop-heading",
}}
>
Meal Information
</Text>

<FormControl mt={3} mb={6} isRequired>
<FormLabel
variant={{
base: "mobile-form-label-bold",
md: "form-label-bold",
}}

// TODO: Hook this up to a state variable
// TODO: Setup correct validation for this
// isInvalid={attemptedSubmit && }
>
Number of meals
</FormLabel>
<Input ref={initialFocusRef} w="200px" placeholder="Ex. 100" />
</FormControl>

<FormControl mt={3} mb={6} isRequired>
<FormLabel
variant={{
base: "mobile-form-label-bold",
md: "form-label-bold",
}}

// TODO: Hook this up to a state variable
// TODO: Setup correct validation for this
// isInvalid={attemptedSubmit && }
>
Dietary restrictions
</FormLabel>
<Input placeholder="Ex. Nut allergy, gluten free" />
</FormControl>

<FormControl mt={3} mb={6} isRequired>
<FormLabel
variant={{
base: "mobile-form-label-bold",
md: "form-label-bold",
}}
// TODO: Hook this up to a state variable
// TODO: Setup correct validation for this
// isInvalid={attemptedSubmit && }
>
Delivery Notes
</FormLabel>
<Input placeholder="Ex. Nut allergy, gluten free" />
<br />
</FormControl>
{isWebView && <Divider />}
{isWebView ? getWebContactSection() : getMobileContactSection()}

<OnsiteStaffSection
onsiteInfo={onsiteInfo}
setOnsiteInfo={setOnsiteInfo}
attemptedSubmit={attemptedSubmit}
/>
</ModalBody>

<ModalFooter>
<Button onClick={onClose} mr={3} variant="outline">
Cancel
</Button>
<Button
colorScheme="blue"
onClick={() => {
setAttemptedSubmit(true);
}}
>
Save
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
};

export default EditMealRequestForm;
18 changes: 18 additions & 0 deletions frontend/src/setupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,21 @@
// "normal .ts file."
// eslint-disable-next-line import/no-extraneous-dependencies
import "@testing-library/jest-dom";

// To fix issue in some tests with not finding "matchMedia"
// https://stackoverflow.com/questions/39830580/jest-test-fails-typeerror-window-matchmedia-is-not-a-function
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
// https://github.com/facebook/create-react-app/issues/10126
Object.defineProperty(window, "matchMedia", {
writable: true,
value: (query: any) => ({

Check warning on line 17 in frontend/src/setupTests.ts

View workflow job for this annotation

GitHub Actions / run-lint

Unexpected any. Specify a different type
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated
removeListener: jest.fn(), // Deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
}),
});
Loading