diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index ecdc497..0000000 --- a/.eslintrc +++ /dev/null @@ -1,26 +0,0 @@ -{ - "extends": [ - "react-app" - ], - "plugins": [ - "prettier", - "react-hooks" - ], - "rules": { - "prettier/prettier": [ - "error", - { - "singleQuote": true - } - ], - "react-hooks/rules-of-hooks": "error", - "react-hooks/exhaustive-deps": "warn", - "quotes": [ - 2, - "single", - { - "avoidEscape": true - } - ] - } -} \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..2d718fd --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,31 @@ +module.exports = { + env: { + browser: true, + commonjs: true, + es2021: true, + }, + // extends: ['plugin:react/recommended'], + overrides: [], + parserOptions: { + sourceType: "module", + ecmaFeatures: { + jsx: true, + modules: true, + ecmaVersion: 12, + }, + }, + // plugins: ['react'], + rules: { + // quotes: [2, 'single', { allowTemplateLiterals: true }], + // 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', + "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off", + "no-restricted-syntax": "off", + "comma-dangle": "off", + "no-unused-vars": "warn", + "no-underscore-dangle": "off", + "react/jsx-filename-extension": "off", + "react/function-component-definition": "off", + "react/react-in-jsx-scope": "off", + "react/prop-types": "off", + }, +}; diff --git a/package.json b/package.json index 68645e4..a976f6b 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,13 @@ "version": "0.1.0", "private": true, "dependencies": { - "@date-io/date-fns": "^1.3.13", + "@emotion/react": "^11.10.6", + "@emotion/styled": "^11.10.6", "@material-ui/core": "^4.9.0", "@material-ui/pickers": "^3.2.10", + "@mui/icons-material": "^5.11.11", + "@mui/joy": "^5.0.0-alpha.72", + "@mui/material": "^5.11.14", "@testing-library/jest-dom": "^5.0.2", "@testing-library/react": "^9.4.0", "@testing-library/user-event": "^8.1.0", @@ -14,8 +18,9 @@ "lodash": "^4.17.15", "moment": "^2.24.0", "prop-types": "^15.7.2", - "react": "^16.12.0", - "react-dom": "^16.12.0", + "react": "^18.2.0", + "react-calendar": "^4.1.0", + "react-dom": "^18.2.0", "react-scripts": "3.3.0", "yup": "^0.28.1" }, @@ -46,4 +51,4 @@ "eslint-plugin-react-hooks": "^2.3.0", "prettier": "1.19.1" } -} \ No newline at end of file +} diff --git a/public/imag.png b/public/imag.png new file mode 100644 index 0000000..74b3410 Binary files /dev/null and b/public/imag.png differ diff --git a/src/App.js b/src/App.js index bb41053..fc01115 100644 --- a/src/App.js +++ b/src/App.js @@ -1,14 +1,12 @@ -import React from 'react'; -import MaterialLayout from './components/Layout/MaterialLayout'; -import CheckoutPage from './components/CheckoutPage'; +import React from "react"; +import MaterialLayout from "./components/Layout/MaterialLayout"; +import AppointmentForm from "./components/AppointmentForm"; function App() { return ( -
- - - -
+ + + ); } diff --git a/src/components/AppointmentForm/Appointment/index.js b/src/components/AppointmentForm/Appointment/index.js new file mode 100644 index 0000000..5497920 --- /dev/null +++ b/src/components/AppointmentForm/Appointment/index.js @@ -0,0 +1,65 @@ +import React, { useState } from "react"; +import Calendar from "react-calendar"; +import { Typography } from "@material-ui/core"; +import "react-calendar/dist/Calendar.css"; +import Radio from "@mui/material/Radio"; +import RadioGroup from "@mui/material/RadioGroup"; +import FormControlLabel from "@mui/material/FormControlLabel"; + +function Appointment() { + const [value, onChange] = useState(new Date()); + + return ( +
+ + +
+ + } + label="11:30 AM - 2:30 PM EST" + /> + } + label="4:00 PM - 5:30 PM EST" + /> + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque + interdum, diam vel fermentum posuere, enim massa. + +
+
+ ); +} +export default Appointment; diff --git a/src/components/AppointmentForm/ButtonAppBar.js b/src/components/AppointmentForm/ButtonAppBar.js new file mode 100644 index 0000000..88bece6 --- /dev/null +++ b/src/components/AppointmentForm/ButtonAppBar.js @@ -0,0 +1,76 @@ +import * as React from "react"; +import Box from "@mui/material/Box"; +import { makeStyles } from "@material-ui/core/styles"; +import { Button, CircularProgress } from "@material-ui/core"; + +const useStyles = makeStyles((theme) => ({ + backButton: { + backgroundColor: theme.palette.primary.main, + color: theme.palette.primary.contrastText, + "&:hover": { + backgroundColor: theme.palette.primary.dark, + }, + }, + nextButton: { + backgroundColor: theme.palette.primary.main, + color: theme.palette.primary.contrastText, + "& .MuiButton-root.Mui-disabled": { + backgroundColor: theme.palette.primary.dark, + color: theme.palette.primary.contrastText, + }, + "&:hover": { + backgroundColor: theme.palette.primary.dark, + }, + }, +})); + +export default function ButtonAppBar(props) { + const classes = useStyles(); + const { + nextHide, + _handleBack, + isSubmitting, + isNextdisabled, + isLastStep, + } = props; + + return ( + + + + {!nextHide ? ( + + ) : ( + "" + )} + + {isSubmitting && } + + + ); +} diff --git a/src/components/AppointmentForm/Client/ClientInfo/ExistingCustomerAddress.jsx b/src/components/AppointmentForm/Client/ClientInfo/ExistingCustomerAddress.jsx new file mode 100644 index 0000000..0a57224 --- /dev/null +++ b/src/components/AppointmentForm/Client/ClientInfo/ExistingCustomerAddress.jsx @@ -0,0 +1,38 @@ +import React from "react"; +import { Typography } from "@material-ui/core"; +import RadioGroup from "@mui/material/RadioGroup"; +import FormControlLabel from "@mui/material/FormControlLabel"; +import Radio from "@mui/material/Radio"; + +const ExistingCustomerAddress = () => { + return ( +
+ + Address where our team is needed + + + + } + /> + } + /> + +
+ ); +}; + +export default ExistingCustomerAddress; diff --git a/src/components/AppointmentForm/Client/ClientInfo/ExistingCustomerDetail.jsx b/src/components/AppointmentForm/Client/ClientInfo/ExistingCustomerDetail.jsx new file mode 100644 index 0000000..3b93b66 --- /dev/null +++ b/src/components/AppointmentForm/Client/ClientInfo/ExistingCustomerDetail.jsx @@ -0,0 +1,71 @@ +import React, { useEffect, useState } from "react"; +import { Typography } from "@material-ui/core"; +import InputAdornment from "@mui/material/InputAdornment"; +import TextField from "@mui/material/TextField"; +import LocalPhoneOutlinedIcon from "@mui/icons-material/LocalPhoneOutlined"; + +const ExistingCustomerDetail = (props) => { + const { _setClientFormData, setIsNextdisabled } = props; + const [accountPhoneNumber, setAccountPhoneNumber] = useState(""); + + useEffect(() => { + if (accountPhoneNumber === "") { + setIsNextdisabled(true); + } else { + setIsNextdisabled(false); + } + }, [accountPhoneNumber]); + + return ( +
+ + Existing customer + + +
+ + Please enter your account phone number + + + { + setAccountPhoneNumber(event.target.value); + _setClientFormData(event.target.name, event.target.value); + }} + InputProps={{ + startAdornment: ( + + + + ), + }} + /> +
+
+ ); +}; + +export default ExistingCustomerDetail; diff --git a/src/components/AppointmentForm/Client/ClientInfo/NewCustomerAddress.jsx b/src/components/AppointmentForm/Client/ClientInfo/NewCustomerAddress.jsx new file mode 100644 index 0000000..e88c21e --- /dev/null +++ b/src/components/AppointmentForm/Client/ClientInfo/NewCustomerAddress.jsx @@ -0,0 +1,175 @@ +import React from "react"; +import { Typography } from "@material-ui/core"; +import InputLabel from "@mui/material/InputLabel"; +import TextField from "@mui/material/TextField"; +import MenuItem from "@mui/material/MenuItem"; +import FormControl from "@mui/material/FormControl"; +import Select from "@mui/material/Select"; +import Checkbox from "@mui/material/Checkbox"; + +const NewCustomerAddress = () => { + const [state, setState] = React.useState(""); + + const handleChange = (event) => { + setState(event.target.value); + }; + return ( +
+ + Address where our team is needed + + +
+ + Please enter your details below + + + + + +
+ + + state + + +
+ +
+ + +
+ + + {" "} + I own this residence + +
+
+
+
+ ); +}; + +export default NewCustomerAddress; diff --git a/src/components/AppointmentForm/Client/ClientInfo/NewCustomerDetail.jsx b/src/components/AppointmentForm/Client/ClientInfo/NewCustomerDetail.jsx new file mode 100644 index 0000000..3a47343 --- /dev/null +++ b/src/components/AppointmentForm/Client/ClientInfo/NewCustomerDetail.jsx @@ -0,0 +1,86 @@ +import React, { useEffect, useState } from "react"; +import { Typography } from "@material-ui/core"; +import InputAdornment from "@mui/material/InputAdornment"; +import TextField from "@mui/material/TextField"; +import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined"; +import EmailOutlinedIcon from "@mui/icons-material/EmailOutlined"; +import LocalPhoneOutlinedIcon from "@mui/icons-material/LocalPhoneOutlined"; + +const NewCustomerDetail = (props) => { + const { _setClientFormData, setIsNextdisabled } = props; + + useEffect(() => { + setIsNextdisabled(false); + }, []); + return ( +
+ + New customer + + +
+ + Please enter your account phone number + + + + + + ), + }} + /> + + + + ), + }} + /> + + + + ), + }} + /> +
+
+ ); +}; + +export default NewCustomerDetail; diff --git a/src/components/AppointmentForm/Client/CustomerAddress.jsx b/src/components/AppointmentForm/Client/CustomerAddress.jsx new file mode 100644 index 0000000..c4aa6dc --- /dev/null +++ b/src/components/AppointmentForm/Client/CustomerAddress.jsx @@ -0,0 +1,25 @@ +import React, { useEffect, useState } from "react"; +import NewCustomerAddress from "./ClientInfo/NewCustomerAddress"; +import ExistingCustomerAddress from "./ClientInfo/ExistingCustomerAddress"; + +const CustomerAddress = (props) => { + const { customerType, _setClientFormData, setIsNextdisabled } = props; + + return ( + <> + {customerType === "newCustomer" ? ( + + ) : ( + + )} + + ); +}; + +export default CustomerAddress; diff --git a/src/components/AppointmentForm/Client/CustomerDetail.jsx b/src/components/AppointmentForm/Client/CustomerDetail.jsx new file mode 100644 index 0000000..718a681 --- /dev/null +++ b/src/components/AppointmentForm/Client/CustomerDetail.jsx @@ -0,0 +1,34 @@ +import React, { useEffect, useState } from "react"; +import NewCustomerDetail from "./ClientInfo/NewCustomerDetail"; +import ExistingCustomerDetail from "./ClientInfo/ExistingCustomerDetail"; + +const CustomerDetail = (props) => { + const { + customerType, + _setClientFormData, + setIsNextdisabled, + setNextHide, + } = props; + + useEffect(() => { + setNextHide(false); + }, []); + + return ( + <> + {customerType === "newCustomer" ? ( + + ) : ( + + )} + + ); +}; + +export default CustomerDetail; diff --git a/src/components/AppointmentForm/Client/CustomerType.jsx b/src/components/AppointmentForm/Client/CustomerType.jsx new file mode 100644 index 0000000..7582b57 --- /dev/null +++ b/src/components/AppointmentForm/Client/CustomerType.jsx @@ -0,0 +1,42 @@ +import React, { useEffect, useState } from "react"; +import { Typography, Button } from "@material-ui/core"; +export default function CustomerType(props) { + const { setCustomerType, setNextHide, _handleNextStep } = props; + + useEffect(() => { + setNextHide(true); + }, []); + + return ( + +
+ FIX +
+ {/* */} + +
+ + + +
+
+ ); +} diff --git a/src/components/AppointmentForm/Client/index.js b/src/components/AppointmentForm/Client/index.js new file mode 100644 index 0000000..d87d48f --- /dev/null +++ b/src/components/AppointmentForm/Client/index.js @@ -0,0 +1,58 @@ +import React, { useEffect, useState } from "react"; +import CustomerType from "./CustomerType"; +import CustomerDetail from "./CustomerDetail"; +import CustomerAddress from "./CustomerAddress"; + +export default function Client(props) { + const { + clientFormField, + setClientFormField, + clientActiveStep, + _handleNext, + setIsNextdisabled, + setNextHide, + } = props; + const [customerType, setCustomerType] = useState(""); + // const currentValidationSchema = validationSchema[activeStep]; + + function _setClientFormData(keyName, value) { + setClientFormField({ ...clientFormField, [keyName]: value }); + } + + function _renderStepContent(step) { + switch (step) { + case 0: + return ( + + ); + case 1: + return ( + + ); + case 2: + return ( + + ); + default: + return
Not Found
; + } + } + + return ( + {_renderStepContent(clientActiveStep)} + ); +} diff --git a/src/components/AppointmentForm/Confirm/index.js b/src/components/AppointmentForm/Confirm/index.js new file mode 100644 index 0000000..0ede99c --- /dev/null +++ b/src/components/AppointmentForm/Confirm/index.js @@ -0,0 +1,127 @@ +import React from "react"; +import { Grid, Typography } from "@material-ui/core"; +import TodayIcon from "@mui/icons-material/Today"; +import AccessTimeIcon from "@mui/icons-material/AccessTime"; +import PlaceIcon from "@mui/icons-material/Place"; +import LocalPhoneOutlinedIcon from "@mui/icons-material/LocalPhoneOutlined"; +import Checkbox from "@mui/material/Checkbox"; + +export default function Confirm() { + return ( + + + Please review and confirm appointment + + + + +
+ + March 30, 2023 +
+
+ +
+ + 11:30 AM - 2:30 PM EST +
+
+ +
+ + + March 30, 202365 Westington St. Suit 5C, Brooklyn, New York, NY + 11249 + +
+
+ +
+ + 492-990-2789 +
+
+
+ + +
+ + + I accept the{" "} + terms and conditions + +
+
+ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque + interdum, diam vel fermentum posuere, enim massa. + +
+ ); +} diff --git a/src/components/AppointmentForm/Description/AdditionalInfoStep.jsx b/src/components/AppointmentForm/Description/AdditionalInfoStep.jsx new file mode 100644 index 0000000..4a57b8b --- /dev/null +++ b/src/components/AppointmentForm/Description/AdditionalInfoStep.jsx @@ -0,0 +1,60 @@ +import React, { useEffect, useState } from "react"; +import { Typography } from "@material-ui/core"; +import TextField from "@mui/material/TextField"; + +const AdditonalInfoStep = (props) => { + const { _setDescriptionFormData, setIsNextdisabled } = props; + const [AdditionalInfo, setAdditionalInfo] = useState(""); + + const handleChange = (event) => { + setAdditionalInfo(event.target.value); + _setDescriptionFormData("AdditionalInfo", event.target.value); + }; + + useEffect(() => { + if (AdditionalInfo === "") { + setIsNextdisabled(true); + } else { + setIsNextdisabled(false); + } + }, [AdditionalInfo]); + + return ( +
+ + Additional information + + +
+ + Please share any information you'd like about your equipment, project, + or issues you are facing. + +
+
+ +
+
+ ); +}; + +export default AdditonalInfoStep; diff --git a/src/components/AppointmentForm/Description/DiagnosticFeeStep.jsx b/src/components/AppointmentForm/Description/DiagnosticFeeStep.jsx new file mode 100644 index 0000000..effc48f --- /dev/null +++ b/src/components/AppointmentForm/Description/DiagnosticFeeStep.jsx @@ -0,0 +1,65 @@ +import React, { useEffect, useState } from "react"; +import { Typography } from "@material-ui/core"; +import Checkbox from "@mui/material/Checkbox"; + +const DiagnosticFeeStep = (props) => { + const { _setDescriptionFormData, setIsNextdisabled } = props; + const [isChecked, setIschecked] = useState(false); + + useEffect(() => { + if (isChecked) { + setIsNextdisabled(false); + } else { + setIsNextdisabled(true); + } + _setDescriptionFormData("DiagnosticFee", isChecked); + }, [isChecked]); + + return ( +
+ + This visit requires a diagnostic fee of $99 + + +
+ + Pellentesque bibendum sapien at dui accumsan, condimentum cursus + turpis porta. Suspendisse euismod risus nibh, sit amet tristique elit + posuere in. Sed ut lacinia nisl. Sed non leo auctor est porta + fermentum sed eu erat. + +
+
+ setIschecked(!isChecked)} + /> + + I understand there is a $99 diagnostic cost + +
+
+ ); +}; + +export default DiagnosticFeeStep; diff --git a/src/components/AppointmentForm/Description/SystemAgeStep.jsx b/src/components/AppointmentForm/Description/SystemAgeStep.jsx new file mode 100644 index 0000000..7363219 --- /dev/null +++ b/src/components/AppointmentForm/Description/SystemAgeStep.jsx @@ -0,0 +1,141 @@ +import React, { useEffect, useState } from "react"; +import { Typography } from "@material-ui/core"; +/// import { InputField, DatePickerField } from '../../FormFields'; +import Radio from "@mui/joy/Radio"; +import RadioGroup from "@mui/joy/RadioGroup"; +import Sheet from "@mui/joy/Sheet"; +export default function SystemAgeStep(props) { + const { _setDescriptionFormData, setIsNextdisabled } = props; + const [unitLocated, setUnitLocated] = useState(""); + const [systemAge, setSystemAge] = useState(""); + useEffect(() => { + if (systemAge !== "" && unitLocated !== "") { + setIsNextdisabled(false); + } + }, [unitLocated, systemAge]); + + return ( + + + What is the approximate age of your system? + + + + {[ + "Less than 5 years", + "6 to 9 years old", + "10 to 15 years old", + "Not sure", + ].map((value) => ( + + { + _setDescriptionFormData(event.target.name, event.target.value); + setSystemAge(event.target.value); + }} + slotProps={{ + label: ({ checked }) => ({ + sx: { + fontWeight: "lg", + fontSize: "md", + color: checked ? "text.primary" : "text.secondary", + }, + }), + action: ({ checked }) => ({ + sx: (theme) => ({ + ...(checked && { + "--variant-borderWidth": "2px", + "&&": { + // && to increase the specificity to win the base :hover styles + borderColor: theme.vars.palette.primary[500], + }, + }), + }), + }), + }} + /> + + ))} + + + Where is the leaking unit located? + + + {[ + "Attic", + "Upstairs", + "Main floor", + "Basement", + "Garage", + "Outside", + "Other", + ].map((value) => ( + + { + _setDescriptionFormData(event.target.name, event.target.value); + setUnitLocated(event.target.value); + }} + slotProps={{ + label: ({ checked }) => ({ + sx: { + fontWeight: "lg", + fontSize: "md", + color: checked ? "text.primary" : "text.secondary", + }, + }), + action: ({ checked }) => ({ + sx: (theme) => ({ + ...(checked && { + "--variant-borderWidth": "2px", + "&&": { + // && to increase the specificity to win the base :hover styles + borderColor: theme.vars.palette.primary[500], + }, + }), + }), + }), + }} + /> + + ))} + + + ); +} diff --git a/src/components/AppointmentForm/Description/index.js b/src/components/AppointmentForm/Description/index.js new file mode 100644 index 0000000..aec61f6 --- /dev/null +++ b/src/components/AppointmentForm/Description/index.js @@ -0,0 +1,56 @@ +import React, { useEffect, useState } from "react"; +import SystemAgeStep from "./SystemAgeStep"; +import DiagnosticFeeStep from "./DiagnosticFeeStep"; +import AdditionalInfoStep from "./AdditionalInfoStep"; + +export default function Problem(props) { + const { + _handleNext, + descriptionActiveStep, + descriptionFormField, + setDescriptionFormField, + setIsNextdisabled, + setNextHide, + } = props; + + useEffect(() => { + setNextHide(false); + }, []); + + function _setDescriptionFormData(keyName, value) { + setDescriptionFormField({ ...descriptionFormField, [keyName]: value }); + } + + function _renderStepContent(step) { + switch (step) { + case 0: + return ( + + ); + case 1: + return ( + + ); + case 2: + return ( + + ); + default: + return
Not Found
; + } + } + + return ( + {_renderStepContent(descriptionActiveStep)} + ); +} diff --git a/src/components/AppointmentForm/FormModel/appointmentFormModel.js b/src/components/AppointmentForm/FormModel/appointmentFormModel.js new file mode 100644 index 0000000..e927c2e --- /dev/null +++ b/src/components/AppointmentForm/FormModel/appointmentFormModel.js @@ -0,0 +1,52 @@ +export default { + formId: "checkoutForm", + problemFormField: { + service: { + name: "service", + label: "Service*", + requiredErrorMsg: "service name is required", + }, + serviceType: { + name: "serviceType", + label: "Service Type*", + requiredErrorMsg: "service type is required", + }, + serviceIssues: { + name: "serviceIssues", + label: "Service Issues*", + requiredErrorMsg: "service issues is required", + }, + }, + descriptionFormIntialValues: { + systemAge: { + name: "systemAge", + label: "System Age*", + }, + unitLocated: { + name: "unitLocated", + label: "unit Located*", + }, + DiagnosticFee: { + name: "DiagnosticFee", + label: "Diagnostic Fee*", + }, + AdditionalInfo: { + name: "AdditionalInfo", + label: "Additional Info*", + }, + }, + ClientFormIntialValues: { + clientType: { + name: "clientType", + label: "Client Type*", + }, + clientDetail: { + name: "clientDetail", + label: "Client Detail*", + }, + clientAddress: { + name: "clientAddress", + label: "Client Address*", + }, + }, +}; diff --git a/src/components/AppointmentForm/FormModel/formInitialValues.js b/src/components/AppointmentForm/FormModel/formInitialValues.js new file mode 100644 index 0000000..0a80b72 --- /dev/null +++ b/src/components/AppointmentForm/FormModel/formInitialValues.js @@ -0,0 +1,30 @@ +import AppointmentFormModel from "./appointmentFormModel"; +const { + problemFormField: { service, serviceType, serviceIssues }, + descriptionFormIntialValues: { + systemAge, + unitLocated, + DiagnosticFee, + AdditionalInfo, + }, + ClientFormIntialValues: { clientType, clientDetail, clientAddress }, +} = AppointmentFormModel; + +export default { + problemIntialValues: { + [service.name]: "", + [serviceType.name]: "", + [serviceIssues.name]: "", + }, + descriptionIntialValues: { + [systemAge.name]: "", + [unitLocated.name]: "", + [DiagnosticFee.name]: false, + [AdditionalInfo.name]: "", + }, + clientIntialValues: { + [clientType.name]: "", + [clientDetail.name]: "", + [clientAddress.name]: "", + }, +}; diff --git a/src/components/CheckoutPage/FormModel/validationSchema.js b/src/components/AppointmentForm/FormModel/validationSchema.js similarity index 100% rename from src/components/CheckoutPage/FormModel/validationSchema.js rename to src/components/AppointmentForm/FormModel/validationSchema.js diff --git a/src/components/AppointmentForm/Problem/IssuesStep.jsx b/src/components/AppointmentForm/Problem/IssuesStep.jsx new file mode 100644 index 0000000..39baec0 --- /dev/null +++ b/src/components/AppointmentForm/Problem/IssuesStep.jsx @@ -0,0 +1,86 @@ +import React, { useState } from "react"; +import { Typography } from "@material-ui/core"; +import Button from "@mui/material/Button"; +import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight"; + +const IssuesStep = (props) => { + const { _setProblemFormData, _handleNext } = props; + + const faultList = [ + { + id: 1, + label: "No heat", + }, + { + id: 2, + label: "No cooling", + }, + { + id: 3, + label: "Water leak from HVAC unit", + }, + { + id: 4, + label: "Noise", + }, + { + id: 5, + label: "Thermostat", + }, + { + id: 6, + label: "Gas leak", + }, + { + id: 7, + label: "Air quality", + }, + ]; + + return ( +
+ + Heating & Air + +
+ {React.Children.toArray( + faultList.map((item) => ( + + )) + )} +
+
+ ); +}; + +export default IssuesStep; diff --git a/src/components/AppointmentForm/Problem/ServiceStep.jsx b/src/components/AppointmentForm/Problem/ServiceStep.jsx new file mode 100644 index 0000000..6b6c6fe --- /dev/null +++ b/src/components/AppointmentForm/Problem/ServiceStep.jsx @@ -0,0 +1,64 @@ +import React from "react"; +import { Typography } from "@material-ui/core"; +import Radio from "@mui/joy/Radio"; +import RadioGroup from "@mui/joy/RadioGroup"; +import Sheet from "@mui/joy/Sheet"; + +const ServiceStep = (props) => { + const services = ["Plumbing", "Heating & Air", "Electrical"]; + const { _setProblemFormData, _handleNextStep } = props; + + return ( + + + What do you need help with? + + + + {services.map((value) => ( + + { + _setProblemFormData(event.target.name, event.target.value); + _handleNextStep(); + }} + sx={{ flexGrow: 1, flexDirection: "row-reverse" }} + slotProps={{ + action: ({ checked }) => ({ + sx: (theme) => ({ + ...(checked && { + inset: -1, + border: "2px solid", + borderColor: theme.vars.palette.primary[500], + }), + }), + }), + }} + /> + + ))} + + + ); +}; +export default ServiceStep; diff --git a/src/components/AppointmentForm/Problem/ServiceTypeStep.jsx b/src/components/AppointmentForm/Problem/ServiceTypeStep.jsx new file mode 100644 index 0000000..c6d27f0 --- /dev/null +++ b/src/components/AppointmentForm/Problem/ServiceTypeStep.jsx @@ -0,0 +1,70 @@ +import React from "react"; +import { Typography } from "@material-ui/core"; +import Button from "@mui/material/Button"; +import ConstructionIcon from "@mui/icons-material/Construction"; +import EventIcon from "@mui/icons-material/Event"; +import RepeatIcon from "@mui/icons-material/Repeat"; + +const ServiceTypeStep = (props) => { + const { _setProblemFormData, _handleNextStep } = props; + + const serviceTypeList = [ + { + id: 1, + label: "Repair and service", + icon: , + }, + { + id: 2, + label: "New equipment estimate", + icon: , + }, + { + id: 3, + label: "Preventive maintenance", + icon: , + }, + ]; + + return ( +
+ + What type of service do you need? + + +
+ {React.Children.toArray( + serviceTypeList.map((item) => ( + + )) + )} +
+
+ ); +}; + +export default ServiceTypeStep; diff --git a/src/components/AppointmentForm/Problem/index.jsx b/src/components/AppointmentForm/Problem/index.jsx new file mode 100644 index 0000000..6722ca2 --- /dev/null +++ b/src/components/AppointmentForm/Problem/index.jsx @@ -0,0 +1,68 @@ +import React, { useEffect, useState } from "react"; +import { Button } from "@material-ui/core"; +import ServiceStep from "./ServiceStep"; +import ServiceTypeStep from "./ServiceTypeStep"; +import IssuesStep from "./IssuesStep"; +import useStyles from "../styles"; + +export default function Problem(props) { + const { + _handleNext, + problemActiveStep, + setProblemActiveStep, + setProblemFormField, + problemFormField, + } = props; + const classes = useStyles(); + + // const currentValidationSchema = validationSchema[activeStep]; + + function _handleBack() { + setProblemActiveStep(problemActiveStep - 1); + } + + function _setProblemFormData(keyName, value) { + setProblemFormField({ ...problemFormField, [keyName]: value }); + } + + function _renderStepContent(step) { + switch (step) { + case 0: + return ( + + ); + case 1: + return ( + + ); + case 2: + return ( + + ); + default: + return
Not Found
; + } + } + + return ( + + {_renderStepContent(problemActiveStep)} +
+ {problemActiveStep !== 0 && ( + + )} +
+
+ ); +} diff --git a/src/components/AppointmentForm/ReviewOrder/CleintInfo/ExistingCustomerStepone.jsx b/src/components/AppointmentForm/ReviewOrder/CleintInfo/ExistingCustomerStepone.jsx new file mode 100644 index 0000000..53a104b --- /dev/null +++ b/src/components/AppointmentForm/ReviewOrder/CleintInfo/ExistingCustomerStepone.jsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { Typography } from '@material-ui/core'; +//import TextField from '@mui/material/TextField'; +// import Box from '@mui/material/Box'; +// import Input from '@mui/material/Input'; +// import InputLabel from '@mui/material/InputLabel'; +import InputAdornment from '@mui/material/InputAdornment'; +// import FormControl from '@mui/material/FormControl'; +import TextField from '@mui/material/TextField'; +//import AccountCircle from '@mui/icons-material/AccountCircle'; +import LocalPhoneOutlinedIcon from '@mui/icons-material/LocalPhoneOutlined'; + + const ExistingCustomerStepone = () =>{ + return ( +
+ + Existing customer + + +
+ + Please enter your account phone number + + + + + + ), + }} + + /> +
+
+ ); +} + +export default ExistingCustomerStepone; \ No newline at end of file diff --git a/src/components/AppointmentForm/ReviewOrder/CleintInfo/ExistingCustomerSteptwo.jsx b/src/components/AppointmentForm/ReviewOrder/CleintInfo/ExistingCustomerSteptwo.jsx new file mode 100644 index 0000000..dd6d4e3 --- /dev/null +++ b/src/components/AppointmentForm/ReviewOrder/CleintInfo/ExistingCustomerSteptwo.jsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { Typography } from '@material-ui/core'; +//import TextField from '@mui/material/TextField'; +// import Box from '@mui/material/Box'; +// import Input from '@mui/material/Input'; +// import InputLabel from '@mui/material/InputLabel'; +//import InputAdornment from '@mui/material/InputAdornment'; +//import FormControl from '@mui/material/FormControl'; +//import TextField from '@mui/material/TextField'; +//import AccountCircle from '@mui/icons-material/AccountCircle'; +//import LocalPhoneOutlinedIcon from '@mui/icons-material/LocalPhoneOutlined'; +//import { styled } from '@mui/material/styles'; +import RadioGroup, { useRadioGroup } from '@mui/material/RadioGroup'; +import FormControlLabel, { + FormControlLabelProps, +} from '@mui/material/FormControlLabel'; +import Radio from '@mui/material/Radio'; + + const ExistingCustomerSteptwo = () =>{ + return ( +
+ + Address where our team is needed + + + + } /> + } /> + + + +
+ ); +} + +export default ExistingCustomerSteptwo; \ No newline at end of file diff --git a/src/components/AppointmentForm/ReviewOrder/CleintInfo/NewCustomerStepone.jsx b/src/components/AppointmentForm/ReviewOrder/CleintInfo/NewCustomerStepone.jsx new file mode 100644 index 0000000..b1a79d4 --- /dev/null +++ b/src/components/AppointmentForm/ReviewOrder/CleintInfo/NewCustomerStepone.jsx @@ -0,0 +1,75 @@ +import React from 'react'; +import { Typography } from '@material-ui/core'; +//import TextField from '@mui/material/TextField'; +// import Box from '@mui/material/Box'; +// import Input from '@mui/material/Input'; +// import InputLabel from '@mui/material/InputLabel'; +import InputAdornment from '@mui/material/InputAdornment'; +// import FormControl from '@mui/material/FormControl'; +import TextField from '@mui/material/TextField'; +import PersonOutlineOutlinedIcon from '@mui/icons-material/PersonOutlineOutlined'; +import EmailOutlinedIcon from '@mui/icons-material/EmailOutlined'; +//import AccountCircle from '@mui/icons-material/AccountCircle'; +import LocalPhoneOutlinedIcon from '@mui/icons-material/LocalPhoneOutlined'; + + const NewCustomerStepone = () =>{ + return ( +
+ + New customer + + +
+ + Please enter your account phone number + + + + + + ), + }} + /> + + + + ), + }} + /> + + + + ), + }} + /> +
+
+ ); +} + +export default NewCustomerStepone; \ No newline at end of file diff --git a/src/components/AppointmentForm/ReviewOrder/CleintInfo/NewCustomerSteptwo.jsx b/src/components/AppointmentForm/ReviewOrder/CleintInfo/NewCustomerSteptwo.jsx new file mode 100644 index 0000000..6959980 --- /dev/null +++ b/src/components/AppointmentForm/ReviewOrder/CleintInfo/NewCustomerSteptwo.jsx @@ -0,0 +1,139 @@ +import React from 'react'; +import { Typography } from '@material-ui/core'; +//import TextField from '@mui/material/TextField'; +// import Box from '@mui/material/Box'; +// import Input from '@mui/material/Input'; +import InputLabel from '@mui/material/InputLabel'; +// import InputAdornment from '@mui/material/InputAdornment'; +//import FormControl from '@mui/material/FormControl'; +import TextField from '@mui/material/TextField'; +import MenuItem from '@mui/material/MenuItem'; +import FormControl from '@mui/material/FormControl'; +import Select, { SelectChangeEvent } from '@mui/material/Select'; +import Checkbox from '@mui/material/Checkbox'; +// import PersonOutlineOutlinedIcon from '@mui/icons-material/PersonOutlineOutlined'; +// import EmailOutlinedIcon from '@mui/icons-material/EmailOutlined'; +// //import AccountCircle from '@mui/icons-material/AccountCircle'; +// import LocalPhoneOutlinedIcon from '@mui/icons-material/LocalPhoneOutlined'; + + const NewCustomerSteptwo = () =>{ + + const [state, setState] = React.useState(''); + + const handleChange = (event) => { + setState(event.target.value); + }; + return ( +
+ + Address where our team is needed + + +
+ + Please enter your details below + + + + + +
+ + + state + + +
+ +
+ + + +
+ + I own this residence +
+ +
+ +
+
+ ); +} + +export default NewCustomerSteptwo; \ No newline at end of file diff --git a/src/components/AppointmentForm/ReviewOrder/LastStep.jsx b/src/components/AppointmentForm/ReviewOrder/LastStep.jsx new file mode 100644 index 0000000..eafce54 --- /dev/null +++ b/src/components/AppointmentForm/ReviewOrder/LastStep.jsx @@ -0,0 +1,118 @@ +import React from 'react'; +import { Grid,Typography } from '@material-ui/core'; +import TodayIcon from '@mui/icons-material/Today'; +import AccessTimeIcon from '@mui/icons-material/AccessTime'; +import PlaceIcon from '@mui/icons-material/Place'; +import LocalPhoneOutlinedIcon from '@mui/icons-material/LocalPhoneOutlined'; +//import FormGroup from '@mui/material/FormGroup'; +//import FormControlLabel from '@mui/material/FormControlLabel'; +import Checkbox from '@mui/material/Checkbox'; +//import LinkIcon from '@mui/icons-material/Link'; + + +export default function LastStep() { + + return ( + + + Please review and confirm appointment + + + + +
+ + March 30, 2023 +
+
+ +
+ + 11:30 AM - 2:30 PM EST +
+
+ +
+ + March 30, 202365 Westington St. Suit 5C, Brooklyn, +New York, NY 11249 +
+
+ +
+ + 492-990-2789 +
+
+
+ + +
+ +I accept the terms and conditions +
+
+ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum, diam vel fermentum posuere, enim massa. + +{/* + + + + + revolve + + */} +
+ ); +} \ No newline at end of file diff --git a/src/components/CheckoutPage/ReviewOrder/PaymentDetails.jsx b/src/components/AppointmentForm/ReviewOrder/PaymentDetails.jsx similarity index 100% rename from src/components/CheckoutPage/ReviewOrder/PaymentDetails.jsx rename to src/components/AppointmentForm/ReviewOrder/PaymentDetails.jsx diff --git a/src/components/CheckoutPage/ReviewOrder/ProductDetails.jsx b/src/components/AppointmentForm/ReviewOrder/ProductDetails.jsx similarity index 100% rename from src/components/CheckoutPage/ReviewOrder/ProductDetails.jsx rename to src/components/AppointmentForm/ReviewOrder/ProductDetails.jsx diff --git a/src/components/AppointmentForm/ReviewOrder/ResponsiveDatePickers.jsx b/src/components/AppointmentForm/ReviewOrder/ResponsiveDatePickers.jsx new file mode 100644 index 0000000..56666ba --- /dev/null +++ b/src/components/AppointmentForm/ReviewOrder/ResponsiveDatePickers.jsx @@ -0,0 +1,50 @@ +import React, { useState } from 'react'; +import Calendar from 'react-calendar'; +import { Typography } from '@material-ui/core'; +import 'react-calendar/dist/Calendar.css'; +import Radio from '@mui/material/Radio'; +import RadioGroup from '@mui/material/RadioGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; +//import { height } from '@mui/system'; +// import FormControl from '@mui/material/FormControl'; +// import FormLabel from '@mui/material/FormLabel'; + +function ResponsiveDatePickers() { + const [value, onChange] = useState(new Date()); + + return ( +
+ + +
+ + } label="11:30 AM - 2:30 PM EST" /> + } label="4:00 PM - 5:30 PM EST" /> + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum, diam vel fermentum posuere, enim massa. + +
+
+ + + ); +} +export default ResponsiveDatePickers; \ No newline at end of file diff --git a/src/components/AppointmentForm/ReviewOrder/ReviewOrder.jsx b/src/components/AppointmentForm/ReviewOrder/ReviewOrder.jsx new file mode 100644 index 0000000..009b177 --- /dev/null +++ b/src/components/AppointmentForm/ReviewOrder/ReviewOrder.jsx @@ -0,0 +1,34 @@ +import React from 'react'; +//import { useFormikContext } from 'formik'; +import { Typography} from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +// import ProductDetails from './ProductDetails'; +// import ShippingDetails from './ShippingDetails'; +// import PaymentDetails from './PaymentDetails'; + +export default function ReviewOrder() { + //const { values: formValues } = useFormikContext(); + return ( + +
+ + FIX + +
+ {/* */} + +
+ + + +
+
+ ); +} diff --git a/src/components/CheckoutPage/ReviewOrder/ShippingDetails.jsx b/src/components/AppointmentForm/ReviewOrder/ShippingDetails.jsx similarity index 100% rename from src/components/CheckoutPage/ReviewOrder/ShippingDetails.jsx rename to src/components/AppointmentForm/ReviewOrder/ShippingDetails.jsx diff --git a/src/components/CheckoutPage/ReviewOrder/index.js b/src/components/AppointmentForm/ReviewOrder/index.js similarity index 100% rename from src/components/CheckoutPage/ReviewOrder/index.js rename to src/components/AppointmentForm/ReviewOrder/index.js diff --git a/src/components/CheckoutPage/ReviewOrder/styles.js b/src/components/AppointmentForm/ReviewOrder/styles.js similarity index 100% rename from src/components/CheckoutPage/ReviewOrder/styles.js rename to src/components/AppointmentForm/ReviewOrder/styles.js diff --git a/src/components/AppointmentForm/Thanks/index.js b/src/components/AppointmentForm/Thanks/index.js new file mode 100644 index 0000000..665d584 --- /dev/null +++ b/src/components/AppointmentForm/Thanks/index.js @@ -0,0 +1,35 @@ +import React from "react"; +import { Typography } from "@material-ui/core"; +import Button from "@mui/material/Button"; +import ThumbUpIcon from "@mui/icons-material/ThumbUp"; +function Thanks() { + return ( + +
+ + Thank you, appointment created + + +
+ +
+
+
+ ); +} + +export default Thanks; diff --git a/src/components/AppointmentForm/index.js b/src/components/AppointmentForm/index.js new file mode 100644 index 0000000..24e3a03 --- /dev/null +++ b/src/components/AppointmentForm/index.js @@ -0,0 +1,266 @@ +import React, { useState, useEffect } from "react"; +import "./style.css"; +import { + Stepper, + Step, + StepLabel, + Box, + Typography, + Button, +} from "@material-ui/core"; +import { Formik, Form } from "formik"; +import ButtonAppBar from "./ButtonAppBar"; +import Problem from "./Problem"; +import Description from "./Description"; +import Client from "./Client"; +import Appointment from "./Appointment"; +import Confirm from "./Confirm"; +import Thanks from "./Thanks"; +//import validationSchema from "./FormModel/validationSchema"; +import AppointmentFormModel from "./FormModel/appointmentFormModel"; +import formInitialValues from "./FormModel/formInitialValues"; +import { steps, problemSteps, descriptionSteps, clientSteps } from "./steps"; +import useStyles from "./styles"; + +const { formId } = AppointmentFormModel; + +export default function AppointmentForm() { + const classes = useStyles(); + const { + problemIntialValues, + descriptionIntialValues, + clientIntialValues, + } = formInitialValues; + + const [isNextdisabled, setIsNextdisabled] = useState(true); + const [nextHide, setNextHide] = useState(false); + const [problemFormField, setProblemFormField] = useState(problemIntialValues); + const [descriptionFormField, setDescriptionFormField] = useState( + descriptionIntialValues + ); + const [clientFormField, setClientFormField] = useState(clientIntialValues); + // set default step for each + const [activeStep, setActiveStep] = useState(0); + const [problemActiveStep, setProblemActiveStep] = useState(0); + const [descriptionActiveStep, setDescriptionActiveStep] = useState(0); + const [clientActiveStep, setClientActiveStep] = useState(0); + //const currentValidationSchema = validationSchema[activeStep]; + // check last step of each child + const isLastStep = activeStep === steps.length - 1; + const isProblemLastStep = problemActiveStep === problemSteps.length - 1; + const isDescriptionLastStep = + descriptionActiveStep === descriptionSteps.length - 1; + const isClientLastStep = clientActiveStep === clientSteps.length - 1; + + useEffect(() => { + console.log(clientFormField, "clientFormField"); + }, [clientFormField]); + + function _handleNext() { + switch (activeStep) { + case 0: + return _handleProblemNext(); + case 1: + return _handleDescriptionNext(); + case 2: + return _handleClientNext(); + case 3: + return setActiveStep(activeStep + 1); + case 4: + return setActiveStep(activeStep + 1); + default: + return; + } + } + + const _handleProblemNext = () => { + if (isProblemLastStep) { + setActiveStep(activeStep + 1); + } else { + setProblemActiveStep(problemActiveStep + 1); + } + }; + + const _handleDescriptionNext = () => { + if (isDescriptionLastStep) { + setActiveStep(activeStep + 1); + } else { + setDescriptionActiveStep(descriptionActiveStep + 1); + } + }; + + const _handleClientNext = () => { + if (isClientLastStep) { + setActiveStep(activeStep + 1); + } else { + setClientActiveStep(clientActiveStep + 1); + } + }; + + function _handleBack() { + switch (activeStep) { + case 0: + return _handleProblemBack(); + case 1: + return _handleDescriptionBack(); + case 2: + return _handleClientBack(); + case 3: + return setActiveStep(activeStep - 1); + case 4: + return setActiveStep(activeStep - 1); + default: + return; + } + } + + const _handleProblemBack = () => { + if (problemActiveStep !== 0) { + setProblemActiveStep(problemActiveStep - 1); + } + }; + + const _handleDescriptionBack = () => { + if (descriptionActiveStep === 0) { + setActiveStep(activeStep - 1); + } else { + setDescriptionActiveStep(descriptionActiveStep - 1); + } + }; + + const _handleClientBack = () => { + if (clientActiveStep === 0) { + setActiveStep(activeStep - 1); + } else { + setClientActiveStep(clientActiveStep - 1); + } + }; + + function _renderStepContent(step) { + switch (step) { + case 0: + return ( + + ); + case 1: + return ( + + ); + case 2: + return ( + + ); + case 3: + return ; + case 4: + return ; + default: + return ; + } + } + + function _sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + + async function _submitForm(values, actions) { + await _sleep(1000); + // alert(JSON.stringify(values, null, 2)); + actions.setSubmitting(false); + + _handleNext(); + } + + function _handleSubmit(values, actions) { + if (isLastStep) { + _submitForm(values, actions); + } else { + _handleNext(); + actions.setTouched({}); + actions.setSubmitting(false); + } + } + + return ( + + + + CREATE APPOINTMENT + + + + + {steps.map((label) => ( + + {label} + + ))} + + + + {({ isSubmitting }) => ( +
+ {_renderStepContent(activeStep)} + {activeStep !== 0 && activeStep !== steps.length && ( + + )} + + )} +
+
+
+ ); +} diff --git a/src/components/AppointmentForm/steps.js b/src/components/AppointmentForm/steps.js new file mode 100644 index 0000000..e0966c2 --- /dev/null +++ b/src/components/AppointmentForm/steps.js @@ -0,0 +1,19 @@ +export const steps = [ + "PROBLEM", + "DESCRIPTION", + "CLEINT INFO", + "APPOINTMENT", + "CONFIRM", +]; +export const problemSteps = ["Service Select", "Service Type", "Issues Step"]; +export const descriptionSteps = [ + "System Age", + "Diagnostic Fee", + "Additional Info", +]; + +export const clientSteps = [ + "Customer Type", + "Customer Info", + "Customer Address", +]; diff --git a/src/components/AppointmentForm/style.css b/src/components/AppointmentForm/style.css new file mode 100644 index 0000000..4e22948 --- /dev/null +++ b/src/components/AppointmentForm/style.css @@ -0,0 +1,379 @@ +@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;900&display=swap"); + +.makeStyles-paper-2 { + padding: 0px !important; + margin-top: 0px !important; + margin-bottom: 0px !important; +} +.MuiPaper-root { + background-color: #fff !important; +} +/* .MuiTypography-body1 { +font-family: 'Poppins'!important; +font-style: normal!important; +font-weight: 600!important; +font-size: 12px!important; +line-height: 16px!important; +letter-spacing: 0.1em; +text-transform: uppercase; + background-color: #fff; +padding: 13px; +color: black; + +position: relative; +} */ +.makeStyles-root-1 { + width: 560px !important; + margin-left: auto; + margin-right: 0px !important; +} +.MuiStepLabel-root { + flex-direction: column !important; + gap: 9px; +} +.makeStyles-stepper-31 { + padding: 24px 24px 40px !important; + color: black !important; + background: #f5f8fb !important; + border-bottom: 1px solid #dde1eb !important; +} + +.MuiCardContent-root { + font-size: 16px; + font-family: "Poppins"; + color: black; + text-align: center; + padding-top: 50px !important; +} +.MuiStepLabel-label.MuiStepLabel-active { + font-family: "Poppins"; + font-style: normal; + font-weight: 400; + font-size: 11px; + line-height: 16px; + /* identical to box height, or 145% */ + + text-align: center; + letter-spacing: 0.04em; + text-transform: uppercase; + + /* Primary */ + + color: #007bff !important; +} +.MuiStepLabel-label { + font-family: "Poppins" !important; + font-style: normal !important; + font-weight: 400 !important; + font-size: 11px !important; + line-height: 16px !important; + /* identical to box height, or 145% */ + + text-align: center; + letter-spacing: 0.04em !important; + text-transform: uppercase !important; + + /* Headings LIGHT */ + + color: #1f2327 !important; +} +.MuiStepIcon-root.MuiStepIcon-active { + color: white !important; + /* border: 1px solid #00bcd4; */ + border: 1px solid #007bff; + border-radius: 50%; + /* border: #00bcd4; */ +} +.MuiStepIcon-text { + fill: #00bcd4 !important; +} + +#checkoutForm { + background: white; + color: black; + position: relative; +} +.MuiTypography-h6 { + padding: 40px 15px 20px 25px; + font-family: "Poppins" !important; + font-style: normal !important; + font-weight: 600 !important; + font-size: 20px !important; + line-height: 28px !important; + color: #1f2327 !important; +} + +.cardname { + display: grid; + grid-template-columns: auto auto; + width: 100%; + justify-content: center; + gap: 21px; +} +.MuiCard-root { + overflow: hidden; + border-radius: 16px !important; + width: 244px; + height: 116px; + background-color: #fff !important; +} + +.MuiButton-root { + color: black; +} +.MuiPaper-elevation1 { + border: 1px solid #d3d7e1; + box-shadow: none !important; +} +.MuiCardActions-root { + justify-content: center !important; +} +.MuiButton-label { + font-family: "Poppins" !important; + font-style: normal !important; + font-weight: 500 !important; + font-size: 16px !important; + line-height: 20px !important; + letter-spacing: 0px !important; + text-transform: none !important; + text-align: center; +} +.MuiPaper-rounded { + border-radius: none !important; +} +.makeStyles-buttons-32 { + margin-top: 100px !important; +} +.MuiStepConnector-lineHorizontal { + border-top: 1px dashed #4ca2ff !important; +} +.MuiStepConnector-root { + margin-top: -23px !important; +} + +.MuiSvgIcon-root { + font-size: 2rem !important; +} + +.MuiStep-horizontal { + padding-left: 0px !important; + padding-right: 0px !important; +} +.makeStyles-stepper-3 { + padding: 13px 32px 13px !important; + background: #f5f8fb !important; +} +.makeStyles-buttons-4 { + margin-top: 140px; +} +.two-btn { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; +} +.exist { + background: #007bff; + padding: 12px 18px !important; + gap: 6px; + width: 267px; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.15); + border-radius: 500px !important; + color: white !important; +} +.new { + padding: 12px 18px !important; + width: 221px; + background: #edf1f7; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.09); + border-radius: 500px !important; +} +.rectangle { + padding-top: 65px; + padding-bottom: 40px; +} +.MuiTypography-h5 { + width: 100px !important; + display: block !important; + font-family: "Poppins" !important; + font-style: normal !important; + font-weight: 900 !important; + border-radius: 24px 0px !important; + font-size: 32px !important; + line-height: 32px !important; + margin-left: auto !important; + padding-top: 33px !important; + margin-right: auto !important; + text-align: center !important; + border-bottom: 10px solid #4ca2ff; + border-right: 10px solid #4ca2ff; + height: 100px; + color: white; + background: #007bff; +} +.MuiStepIcon-root.MuiStepIcon-completed { + color: #007bff !important; +} + +/* payment form */ + +.css-3hx9vb-JoyRadioGroup-root { + display: grid !important; + grid-template-columns: auto auto auto; + gap: 10px !important; + width: 90% !important; + margin-left: auto !important; + margin-right: auto !important; +} +.css-ycie4v-JoySheet-root { + padding: 8px !important; + text-align: center !important; +} +.css-1fjq3ub-JoyRadio-root { + font-family: "Poppins" !important; +} + +.css-1su2bbo-JoyRadio-label { + font-style: normal !important; + font-weight: 400 !important; + font-size: 16px !important; + color: #1f2327 !important; +} + +.css-1wzowpn-JoyRadio-action { + border-color: #d3d7e1 !important; +} + +/*----*/ + +.css-1ahv6t2-JoyList-root { + display: grid !important; + grid-template-columns: auto auto !important; + width: 95%; + align-items: normal !important; + margin-left: auto auto !important; + gap: 10px; +} + +.css-b5w08v-JoySheet-root { + border-radius: 18px; +} +.css-1obzj18-JoySheet-root { + text-align: center; + box-shadow: none !important; + padding-top: 75px; + max-width: 244px !important; +} + +.css-pfaso8-JoyRadio-label { + font-size: 15px; + font-family: "Poppins"; + color: #1f2327; + line-height: 20px; + font-weight: 500; +} + +/* calender */ + +.react-calendar { + width: 560px !important; + height: 376px !important; + border: none !important; +} +.react-calendar button { + padding: 16px 0px !important; + font-family: "Poppins"; + font-style: normal; + font-weight: 500; + font-size: 16px; + line-height: 16px; +} + +abbr[title] { + text-decoration: none !important; + font-family: "Poppins"; + font-style: normal; + font-weight: 500; + font-size: 12px; + line-height: 12px; +} + +.react-calendar__month-view__weekdays { + text-transform: capitalize !important; +} +.react-calendar__navigation__arrow { + display: none; +} + +.react-calendar__navigation { + height: 70px !important; +} + +.react-calendar__navigation button { + margin-left: 27px !important; + flex-grow: 0 !important; +} + +.react-calendar__navigation__label__labelText { + font-family: "Poppins"; + font-style: normal; + font-weight: 300; + font-size: 32px; + line-height: 40px; + color: #1f2327; +} +.react-calendar__navigation button:hover { + background-color: white !important; +} + +.css-j204z7-MuiFormControlLabel-root { + margin-left: 0px !important; +} + +/* .css-dmmspl-MuiFormGroup-root{ + display: flex!important; + flex-direction: row!important; + padding-top: 16px; + padding-left: 20px; +} */ + +/*---SUCCESS---*/ +.MuiTypography-h4 { + padding-top: 30px; + text-align: center; + font-family: "Poppins" !important; + font-style: normal !important; + font-weight: 600 !important; + font-size: 20px !important; + line-height: 28px !important; + color: #1f2327; +} + +.css-1rwt2y5-MuiButtonBase-root-MuiButton-root { + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.09); + border-radius: 500px !important; + padding: 12px 24px !important; + background-color: white !important; + border: none !important; +} + +.Okay { + color: black; + text-transform: none; + font-family: Poppins; + font-style: normal; + font-weight: 600; + font-size: 18px; + line-height: 24px; +} + +.css-1t8l2tu-MuiInputBase-input-MuiOutlinedInput-input { + font-family: "Poppins"; + font-style: normal; + font-weight: 400; + font-size: 16px; + color: #1f2327; +} +.css-1d3z3hw-MuiOutlinedInput-notchedOutline { + border-radius: 10px !important; +} diff --git a/src/components/CheckoutPage/styles.js b/src/components/AppointmentForm/styles.js similarity index 100% rename from src/components/CheckoutPage/styles.js rename to src/components/AppointmentForm/styles.js diff --git a/src/components/CheckoutPage/CheckoutPage.jsx b/src/components/CheckoutPage/CheckoutPage.jsx deleted file mode 100644 index c1d5df5..0000000 --- a/src/components/CheckoutPage/CheckoutPage.jsx +++ /dev/null @@ -1,127 +0,0 @@ -import React, { useState } from 'react'; -import { - Stepper, - Step, - StepLabel, - Button, - Typography, - CircularProgress -} from '@material-ui/core'; -import { Formik, Form } from 'formik'; - -import AddressForm from './Forms/AddressForm'; -import PaymentForm from './Forms/PaymentForm'; -import ReviewOrder from './ReviewOrder'; -import CheckoutSuccess from './CheckoutSuccess'; - -import validationSchema from './FormModel/validationSchema'; -import checkoutFormModel from './FormModel/checkoutFormModel'; -import formInitialValues from './FormModel/formInitialValues'; - -import useStyles from './styles'; - -const steps = ['Shipping address', 'Payment details', 'Review your order']; -const { formId, formField } = checkoutFormModel; - -function _renderStepContent(step) { - switch (step) { - case 0: - return ; - case 1: - return ; - case 2: - return ; - default: - return
Not Found
; - } -} - -export default function CheckoutPage() { - const classes = useStyles(); - const [activeStep, setActiveStep] = useState(0); - const currentValidationSchema = validationSchema[activeStep]; - const isLastStep = activeStep === steps.length - 1; - - function _sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); - } - - async function _submitForm(values, actions) { - await _sleep(1000); - alert(JSON.stringify(values, null, 2)); - actions.setSubmitting(false); - - setActiveStep(activeStep + 1); - } - - function _handleSubmit(values, actions) { - if (isLastStep) { - _submitForm(values, actions); - } else { - setActiveStep(activeStep + 1); - actions.setTouched({}); - actions.setSubmitting(false); - } - } - - function _handleBack() { - setActiveStep(activeStep - 1); - } - - return ( - - - Checkout - - - {steps.map(label => ( - - {label} - - ))} - - - {activeStep === steps.length ? ( - - ) : ( - - {({ isSubmitting }) => ( -
- {_renderStepContent(activeStep)} - -
- {activeStep !== 0 && ( - - )} -
- - {isSubmitting && ( - - )} -
-
-
- )} -
- )} -
-
- ); -} diff --git a/src/components/CheckoutPage/CheckoutSuccess/CheckoutSuccess.jsx b/src/components/CheckoutPage/CheckoutSuccess/CheckoutSuccess.jsx deleted file mode 100644 index b7f503a..0000000 --- a/src/components/CheckoutPage/CheckoutSuccess/CheckoutSuccess.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { Typography } from '@material-ui/core'; - -function CheckoutSuccess() { - return ( - - - Thank you for your order. - - - Your order number is #2001539. We have emailed your order confirmation, - and will send you an update when your order has shipped. - - - ); -} - -export default CheckoutSuccess; diff --git a/src/components/CheckoutPage/CheckoutSuccess/index.js b/src/components/CheckoutPage/CheckoutSuccess/index.js deleted file mode 100644 index 32bd128..0000000 --- a/src/components/CheckoutPage/CheckoutSuccess/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import CheckoutSuccess from './CheckoutSuccess'; -export default CheckoutSuccess; diff --git a/src/components/CheckoutPage/FormModel/checkoutFormModel.js b/src/components/CheckoutPage/FormModel/checkoutFormModel.js deleted file mode 100644 index 5d1be8c..0000000 --- a/src/components/CheckoutPage/FormModel/checkoutFormModel.js +++ /dev/null @@ -1,71 +0,0 @@ -export default { - formId: 'checkoutForm', - formField: { - firstName: { - name: 'firstName', - label: 'First name*', - requiredErrorMsg: 'First name is required' - }, - lastName: { - name: 'lastName', - label: 'Last name*', - requiredErrorMsg: 'Last name is required' - }, - address1: { - name: 'address1', - label: 'Address Line 1*', - requiredErrorMsg: 'Address Line 1 is required' - }, - address2: { - name: 'address2', - label: 'Address Line 2' - }, - city: { - name: 'city', - label: 'City*', - requiredErrorMsg: 'City is required' - }, - state: { - name: 'state', - label: 'State/Province/Region' - }, - zipcode: { - name: 'zipcode', - label: 'Zipcode*', - requiredErrorMsg: 'Zipcode is required', - invalidErrorMsg: 'Zipcode is not valid (e.g. 70000)' - }, - country: { - name: 'country', - label: 'Country*', - requiredErrorMsg: 'Country is required' - }, - useAddressForPaymentDetails: { - name: 'useAddressForPaymentDetails', - label: 'Use this address for payment details' - }, - nameOnCard: { - name: 'nameOnCard', - label: 'Name on card*', - requiredErrorMsg: 'Name on card is required' - }, - cardNumber: { - name: 'cardNumber', - label: 'Card number*', - requiredErrorMsg: 'Card number is required', - invalidErrorMsg: 'Card number is not valid (e.g. 4111111111111)' - }, - expiryDate: { - name: 'expiryDate', - label: 'Expiry date*', - requiredErrorMsg: 'Expiry date is required', - invalidErrorMsg: 'Expiry date is not valid' - }, - cvv: { - name: 'cvv', - label: 'CVV*', - requiredErrorMsg: 'CVV is required', - invalidErrorMsg: 'CVV is invalid (e.g. 357)' - } - } -}; diff --git a/src/components/CheckoutPage/FormModel/formInitialValues.js b/src/components/CheckoutPage/FormModel/formInitialValues.js deleted file mode 100644 index 8c006cf..0000000 --- a/src/components/CheckoutPage/FormModel/formInitialValues.js +++ /dev/null @@ -1,30 +0,0 @@ -import checkoutFormModel from './checkoutFormModel'; -const { - formField: { - firstName, - lastName, - address1, - city, - zipcode, - country, - useAddressForPaymentDetails, - nameOnCard, - cardNumber, - expiryDate, - cvv - } -} = checkoutFormModel; - -export default { - [firstName.name]: '', - [lastName.name]: '', - [address1.name]: '', - [city.name]: '', - [zipcode.name]: '', - [country.name]: '', - [useAddressForPaymentDetails.name]: false, - [nameOnCard.name]: '', - [cardNumber.name]: '', - [expiryDate.name]: '', - [cvv.name]: '' -}; diff --git a/src/components/CheckoutPage/Forms/AddressForm.jsx b/src/components/CheckoutPage/Forms/AddressForm.jsx deleted file mode 100644 index c48b847..0000000 --- a/src/components/CheckoutPage/Forms/AddressForm.jsx +++ /dev/null @@ -1,130 +0,0 @@ -import React from 'react'; -import { Grid, Typography } from '@material-ui/core'; -import { InputField, CheckboxField, SelectField } from '../../FormFields'; - -const cities = [ - { - value: undefined, - label: 'None' - }, - { - value: '1', - label: 'New York' - }, - { - value: '2', - label: 'Chicago' - }, - { - value: '3', - label: 'Saigon' - } -]; - -const states = [ - { - value: undefined, - label: 'None' - }, - { - value: '11', - label: 'Florida' - }, - { - value: '22', - label: 'Michigan' - }, - { - value: '33', - label: 'Texas' - } -]; - -const countries = [ - { - value: null, - label: 'None' - }, - { - value: '111', - label: 'United States' - }, - { - value: '222', - label: 'Italy' - }, - { - value: '333', - label: 'Vietnam' - } -]; - -export default function AddressForm(props) { - const { - formField: { - firstName, - lastName, - address1, - address2, - city, - state, - zipcode, - country, - useAddressForPaymentDetails - } - } = props; - return ( - - - Shipping address - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); -} diff --git a/src/components/CheckoutPage/Forms/PaymentForm.jsx b/src/components/CheckoutPage/Forms/PaymentForm.jsx deleted file mode 100644 index 387dba8..0000000 --- a/src/components/CheckoutPage/Forms/PaymentForm.jsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react'; -import { Grid, Typography } from '@material-ui/core'; -import { InputField, DatePickerField } from '../../FormFields'; - -export default function PaymentForm(props) { - const { - formField: { nameOnCard, cardNumber, expiryDate, cvv } - } = props; - - return ( - - - Payment method - - - - - - - - - - - - - - - - - ); -} diff --git a/src/components/CheckoutPage/ReviewOrder/ReviewOrder.jsx b/src/components/CheckoutPage/ReviewOrder/ReviewOrder.jsx deleted file mode 100644 index 8308294..0000000 --- a/src/components/CheckoutPage/ReviewOrder/ReviewOrder.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import { useFormikContext } from 'formik'; -import { Typography, Grid } from '@material-ui/core'; -import ProductDetails from './ProductDetails'; -import ShippingDetails from './ShippingDetails'; -import PaymentDetails from './PaymentDetails'; - -export default function ReviewOrder() { - const { values: formValues } = useFormikContext(); - return ( - - - Order summary - - - - - - - - ); -} diff --git a/src/components/CheckoutPage/index.js b/src/components/CheckoutPage/index.js deleted file mode 100644 index 8728a02..0000000 --- a/src/components/CheckoutPage/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import CheckoutPage from './CheckoutPage'; -export default CheckoutPage; diff --git a/src/components/Layout/MaterialLayout.jsx b/src/components/Layout/MaterialLayout.jsx index ffa0477..53111b0 100644 --- a/src/components/Layout/MaterialLayout.jsx +++ b/src/components/Layout/MaterialLayout.jsx @@ -1,11 +1,11 @@ -import React from 'react'; -import { Paper, CssBaseline } from '@material-ui/core'; -import { ThemeProvider } from '@material-ui/core/styles'; +import React from "react"; +import { Paper, CssBaseline } from "@material-ui/core"; +import { ThemeProvider } from "@material-ui/core/styles"; -import Header from '../Header'; -import Footer from '../Footer'; +// import Header from '../Header'; +// import Footer from '../Footer'; -import { theme, useStyle } from './styles'; +import { theme, useStyle } from "./styles"; export default function MaterialLayout(props) { const { children } = props; @@ -14,11 +14,11 @@ export default function MaterialLayout(props) { return ( -
+ {/*
*/}
{children}
-