diff options
Diffstat (limited to 'src/frontend/components/CheckoutForm')
| -rw-r--r-- | src/frontend/components/CheckoutForm/CheckoutForm.styled.ts | 59 | ||||
| -rw-r--r-- | src/frontend/components/CheckoutForm/CheckoutForm.tsx | 202 | ||||
| -rw-r--r-- | src/frontend/components/CheckoutForm/index.ts | 4 |
3 files changed, 265 insertions, 0 deletions
diff --git a/src/frontend/components/CheckoutForm/CheckoutForm.styled.ts b/src/frontend/components/CheckoutForm/CheckoutForm.styled.ts new file mode 100644 index 0000000..c11ebc5 --- /dev/null +++ b/src/frontend/components/CheckoutForm/CheckoutForm.styled.ts @@ -0,0 +1,59 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +import styled from 'styled-components'; +import Button from '../Button'; + +export const CheckoutForm = styled.form``; + +export const StateRow = styled.div` + display: grid; + grid-template-columns: 35% 55%; + gap: 10%; +`; + +export const Title = styled.h1` + margin: 0; + margin-bottom: 24px; +`; + +export const CardRow = styled.div` + display: grid; + grid-template-columns: 35% 35% 20%; + gap: 5%; +`; + +export const SubmitContainer = styled.div` + display: flex; + justify-content: center; + align-items: center; + gap: 20px; + flex-direction: column-reverse; + + ${({ theme }) => theme.breakpoints.desktop} { + flex-direction: row; + justify-content: end; + align-items: center; + margin-top: 67px; + } +`; + +export const CartButton = styled(Button)` + padding: 16px 35px; + font-weight: ${({ theme }) => theme.fonts.regular}; + width: 100%; + + ${({ theme }) => theme.breakpoints.desktop} { + width: inherit; + } +`; + +export const EmptyCartButton = styled(Button)` + font-weight: ${({ theme }) => theme.fonts.regular}; + color: ${({ theme }) => theme.colors.otelRed}; + width: 100%; + + ${({ theme }) => theme.breakpoints.desktop} { + width: inherit; + } +`; diff --git a/src/frontend/components/CheckoutForm/CheckoutForm.tsx b/src/frontend/components/CheckoutForm/CheckoutForm.tsx new file mode 100644 index 0000000..1c8e5c9 --- /dev/null +++ b/src/frontend/components/CheckoutForm/CheckoutForm.tsx @@ -0,0 +1,202 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +import Link from 'next/link'; +import { useCallback, useState } from 'react'; +import { CypressFields } from '../../utils/enums/CypressFields'; +import Input from '../Input'; +import * as S from './CheckoutForm.styled'; + +const currentYear = new Date().getFullYear(); +const yearList = Array.from(new Array(20), (v, i) => i + currentYear); + +export interface IFormData { + email: string; + streetAddress: string; + city: string; + state: string; + country: string; + zipCode: string; + creditCardNumber: string; + creditCardCvv: number; + creditCardExpirationYear: number; + creditCardExpirationMonth: number; +} + +interface IProps { + onSubmit(formData: IFormData): void; +} + +const CheckoutForm = ({ onSubmit }: IProps) => { + const [ + { + email, + streetAddress, + city, + state, + country, + zipCode, + creditCardCvv, + creditCardExpirationMonth, + creditCardExpirationYear, + creditCardNumber, + }, + setFormData, + ] = useState<IFormData>({ + email: 'someone@example.com', + streetAddress: '1600 Amphitheatre Parkway', + city: 'Mountain View', + state: 'CA', + country: 'United States', + zipCode: "94043", + creditCardNumber: '4432-8015-6152-0454', + creditCardCvv: 672, + creditCardExpirationYear: 2030, + creditCardExpirationMonth: 1, + }); + + const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => { + setFormData(formData => ({ + ...formData, + [e.target.name]: e.target.value, + })); + }, []); + + return ( + <S.CheckoutForm + onSubmit={(event: { preventDefault: () => void; }) => { + event.preventDefault(); + onSubmit({ + email, + streetAddress, + city, + state, + country, + zipCode, + creditCardCvv, + creditCardExpirationMonth, + creditCardExpirationYear, + creditCardNumber, + }); + }} + > + <S.Title>Shipping Address</S.Title> + + <Input + label="E-mail Address" + type="email" + id="email" + name="email" + value={email} + required + onChange={handleChange} + /> + <Input + label="Street Address" + type="text" + name="streetAddress" + id="street_address" + value={streetAddress} + onChange={handleChange} + required + /> + <Input + label="Zip Code" + type="text" + name="zipCode" + id="zip_code" + value={zipCode} + onChange={handleChange} + required + /> + <Input label="City" type="text" name="city" id="city" value={city} required onChange={handleChange} /> + + <S.StateRow> + <Input label="State" type="text" name="state" id="state" value={state} required onChange={handleChange} /> + <Input + label="Country" + type="text" + id="country" + placeholder="Country Name" + name="country" + value={country} + onChange={handleChange} + required + /> + </S.StateRow> + + <div> + <S.Title>Payment Method</S.Title> + </div> + + <Input + type="text" + label="Credit Card Number" + id="credit_card_number" + name="creditCardNumber" + placeholder="0000-0000-0000-0000" + value={creditCardNumber} + onChange={handleChange} + required + pattern="\d{4}-\d{4}-\d{4}-\d{4}" + /> + + <S.CardRow> + <Input + label="Month" + name="creditCardExpirationMonth" + id="credit_card_expiration_month" + value={creditCardExpirationMonth} + onChange={handleChange} + type="select" + > + <option value="1">January</option> + <option value="2">February</option> + <option value="3">March</option> + <option value="4">April</option> + <option value="5">May</option> + <option value="6">June</option> + <option value="7">July</option> + <option value="8">August</option> + <option value="9">September</option> + <option value="10">October</option> + <option value="11">November</option> + <option value="12">January</option> + </Input> + <Input + label="Year" + name="creditCardExpirationYear" + id="credit_card_expiration_year" + value={creditCardExpirationYear} + onChange={handleChange} + type="select" + > + {yearList.map(year => ( + <option value={year} key={year}> + {year} + </option> + ))} + </Input> + <Input + label="CVV" + type="password" + id="credit_card_cvv" + name="creditCardCvv" + value={creditCardCvv} + required + pattern="\d{3}" + onChange={handleChange} + /> + </S.CardRow> + + <S.SubmitContainer> + <Link href="/"> + <S.CartButton $type="secondary">Continue Shopping</S.CartButton> + </Link> + <S.CartButton data-cy={CypressFields.CheckoutPlaceOrder} type="submit">Place Order</S.CartButton> + </S.SubmitContainer> + </S.CheckoutForm> + ); +}; + +export default CheckoutForm; diff --git a/src/frontend/components/CheckoutForm/index.ts b/src/frontend/components/CheckoutForm/index.ts new file mode 100644 index 0000000..897f43b --- /dev/null +++ b/src/frontend/components/CheckoutForm/index.ts @@ -0,0 +1,4 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +export { default } from './CheckoutForm'; |
