initial setup, formik, fields, layout

This commit is contained in:
Jesus Vasquez 2024-03-03 22:09:33 -05:00
parent 765cc0c7cf
commit b23d706180
16 changed files with 578 additions and 53 deletions

View file

@ -2,8 +2,8 @@ import "styles/tailwind.css"
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
<html lang="en" className="h-full">
<body className="h-full">{children}</body>
</html>
)
}

View file

@ -1,62 +1,28 @@
import { Metadata } from "next"
import { Button } from "components/Button/Button"
import { LP_GRID_ITEMS } from "lp-items"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faXmark } from "@fortawesome/free-solid-svg-icons"
import Form from "components/Form"
export const metadata: Metadata = {
title: "Next.js Enterprise Boilerplate",
twitter: {
card: "summary_large_image",
},
openGraph: {
url: "https://next-enterprise.vercel.app/",
images: [
{
width: 1200,
height: 630,
url: "https://raw.githubusercontent.com/Blazity/next-enterprise/main/.github/assets/project-logo.png",
},
],
},
title: "Form Components",
}
export default function Web() {
return (
<>
<section className="bg-white dark:bg-gray-900">
<div className="mx-auto grid max-w-screen-xl px-4 py-8 text-center lg:py-16">
<div className="mx-auto place-self-center">
<h1 className="mb-4 max-w-2xl text-4xl font-extrabold leading-none tracking-tight dark:text-white md:text-5xl xl:text-6xl">
Next.js Enterprise Boilerplate
</h1>
<p className="mb-6 max-w-2xl font-light text-gray-500 dark:text-gray-400 md:text-lg lg:mb-8 lg:text-xl">
Jumpstart your enterprise project with our feature-packed, high-performance Next.js boilerplate!
Experience rapid UI development, AI-powered code reviews, and an extensive suite of tools for a smooth and
enjoyable development process.
</p>
<Button href="https://github.com/Blazity/next-enterprise" className="mr-3">
Get started
</Button>
<Button
href="https://vercel.com/new/git/external?repository-url=https://github.com/Blazity/next-enterprise"
intent="secondary"
>
Deploy Now
</Button>
<section className="flex min-h-full grow items-center justify-center bg-slate-200 p-4">
<div className="max-w-screen-lg grow rounded-3xl bg-white p-8">
{/* Close button */}
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-950 text-white">
<FontAwesomeIcon icon={faXmark} className="h-6 w-6" />
</div>
</div>
</section>
<section className="bg-white dark:bg-gray-900">
<div className="mx-auto max-w-screen-xl px-4 py-8 sm:py-16 lg:px-6">
<div className="justify-center space-y-8 md:grid md:grid-cols-2 md:gap-12 md:space-y-0 lg:grid-cols-3">
{LP_GRID_ITEMS.map((singleItem) => (
<div key={singleItem.title} className="flex flex-col items-center justify-center text-center">
<div className="mb-4 flex h-10 w-10 items-center justify-center rounded-full bg-primary-100 p-1.5 text-blue-700 dark:bg-primary-900 lg:h-12 lg:w-12">
{singleItem.icon}
</div>
<h3 className="mb-2 text-xl font-bold dark:text-white">{singleItem.title}</h3>
<p className="text-gray-500 dark:text-gray-400">{singleItem.description}</p>
</div>
))}
{/* Title */}
<div className="flex justify-center">
<h1 className="border-grey-300 w-fit border-b pb-4 text-3xl text-indigo-900">Document Upload</h1>
</div>
{/* Form layout */}
<div className="flex gap-14">
<Form />
</div>
</div>
</section>

View file

@ -0,0 +1,38 @@
import React from "react"
import SelectInput from "./SelectInput"
import { Utils } from "./Utils"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faClock } from "@fortawesome/free-regular-svg-icons"
// Define a type for your props to improve type-checking
type ClientFieldProps = {
testingCenters: string[]
clients: string[]
}
// Destructure the props in the function parameter
const ClientField: React.FC<ClientFieldProps> = ({ testingCenters, clients }) => {
return (
<div className="flex flex-col gap-4">
{testingCenters.map((testingCenter) => (
<div key={Utils.camelize(testingCenter)} className="flex gap-14 items-center">
<span>{testingCenter}</span>
<div className="flex gap-2 items-center">
<SelectInput name={Utils.camelize(testingCenter)}>
<option value="">Select Client</option>
{clients.map((option: string) => (
<option key={option} value={option}>
{option}
</option>
))}
</SelectInput>
<FontAwesomeIcon icon={faClock}/>
</div>
</div>
))}
</div>
)
}
export default ClientField

View file

@ -0,0 +1,10 @@
import React from "react"
const ErrorMessage = ({ touched, error }: { touched: boolean; error?: string }) => {
if (touched && error) {
return <p className="mt-1">{error}</p>
}
return null
}
export default ErrorMessage

View file

@ -0,0 +1,67 @@
import { useField, useFormikContext } from "formik";
import React, { useRef } from "react";
import ErrorMessage from "./ErrorMessage";
import RequiredAsterisk from "./RequiredAsterisk";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faFile } from "@fortawesome/free-solid-svg-icons";
interface FileInputProps {
label: string;
required?: boolean;
name:string;
}
const FileInput: React.FC<FileInputProps> = ({ label, ...props }) => {
const { required } = props;
const [field, meta] = useField(props);
const { setFieldValue } = useFormikContext();
const fileInputRef = useRef<HTMLInputElement>(null);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { files } = event.target;
const file = files ? files[0] : null;
setFieldValue(props.name, file); // Directly use setFieldValue to update Formik's state
};
const handleClick = () => {
if (fileInputRef.current) {
fileInputRef.current.click();
}
};
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
const files = event.dataTransfer.files;
if (files && files.length > 0) {
const file = files[0];
setFieldValue(props.name, file);
}
};
return (
<div className="mb-4">
<label className="text-md" htmlFor={props.name}>
{label}
<RequiredAsterisk required={required} />
</label>
<div className="drop-area" onClick={handleClick} onDrop={handleDrop} onDragOver={(e) => e.preventDefault()}>
<div>
<FontAwesomeIcon icon={faFile} />
<h4>Drag & Drop Here or Browse</h4>
</div>
<button type="button">Upload Manifest</button>
</div>
<input
type="file"
className="hidden"
ref={fileInputRef}
onChange={handleChange}
/>
<ErrorMessage touched={meta.touched} error={meta.error} />
</div>
);
};
export default FileInput;

View file

@ -0,0 +1,57 @@
import { useField } from "formik"
import React from "react"
import ErrorMessage from "./ErrorMessage"
import RequiredAsterisk from "./RequiredAsterisk"
import * as RadioGroup from "@radix-ui/react-radio-group"
const RadioGroupField = ({
name,
label,
options,
...props
}: {
name: string
label: string
options: string[]
[x: string]: any // Allow any other props
}) => {
const { required, ...restProps } = props
const [field, meta, helpers] = useField({ ...restProps, name })
const handleChange = (value: string) => {
helpers.setValue(value)
}
return (
<div className="mb-4">
<label className="text-md" htmlFor={label}>
{label}
</label>
<RequiredAsterisk required={required} />
<RadioGroup.Root
className="flex gap-3"
value={field.value}
onValueChange={handleChange}
aria-label={label}
>
{options.map((option) => (
<div className="flex items-center" key={option}>
<RadioGroup.Item
className="hover:bg-violet3 h-[25px] w-[25px] cursor-default rounded-full border bg-white outline-none focus:shadow-[0_0_0_2px]"
value={option}
id={`${name}-${option}`}
>
<RadioGroup.Indicator className="relative flex h-full w-full items-center justify-center after:block after:h-[11px] after:w-[11px] after:rounded-[50%] after:bg-violet-400 after:content-['']" />
</RadioGroup.Item>
<label className="pl-[15px] text-[15px] leading-none" htmlFor={`${name}-${option}`}>
{option}
</label>
</div>
))}
</RadioGroup.Root>
<ErrorMessage touched={meta.touched} error={meta.error} />
</div>
)
}
export default RadioGroupField

View file

@ -0,0 +1,7 @@
import React from "react"
const RequiredAsterisk = ({ required }: { required?: boolean }) => {
return required ? <span className="text-sm"> *</span> : null
}
export default RequiredAsterisk

View file

@ -0,0 +1,24 @@
import { useField } from "formik"
import React from "react"
import ErrorMessage from "./ErrorMessage"
import RequiredAsterisk from "./RequiredAsterisk"
const SelectInput = ({ label, ...props }: { label?: string; name: string; [x: string]: any }) => {
const { required, ...restProps } = props
const [field, meta] = useField(restProps)
return (
<div className="">
{label && (
<label className="text-md" htmlFor={props.id || props.name}>
{label}
</label>
)}
<RequiredAsterisk required={required} />
<select className="h-10 w-full rounded-lg border px-3 text-base shadow-sm" {...field} {...restProps} />
<ErrorMessage touched={meta.touched} error={meta.error} />
</div>
)
}
export default SelectInput

View file

@ -0,0 +1,20 @@
import React from "react"
const StatusField = ({
label,
statusLabel,
statusColor,
}: {
label: string
statusLabel: string
statusColor: string
}) => {
return (
<div>
<h4>{label}</h4>
<span className={statusColor}>{statusLabel}</span>
</div>
)
}
export default StatusField

View file

@ -0,0 +1,38 @@
import { useField } from "formik";
import React, { useState } from "react";
import ErrorMessage from "./ErrorMessage";
import RequiredAsterisk from "./RequiredAsterisk";
import * as SwitchPrimitive from "@radix-ui/react-switch";
const ToggleField = ({
children,
...props
}: {
children: React.ReactNode;
} & React.InputHTMLAttributes<HTMLInputElement>) => {
const { required, ...restProps } = props;
const [field, meta] = useField({ ...(restProps as { name: string }), type: "checkbox" });
const [checked, setChecked] = useState(false);
return (
<div className="">
<label className="flex items-center gap-2">
{children}
<RequiredAsterisk required={required} />
</label>
<SwitchPrimitive.Root
className="relative h-[25px] w-[42px] cursor-default rounded-full bg-black shadow-[0_2px_10px] outline-none focus:shadow-[0_0_0_2px] focus:shadow-black"
checked={checked}
onCheckedChange={(isChecked) => {
setChecked(isChecked);
field.onChange({ target: { name: field.name, value: isChecked } });
}}
>
<SwitchPrimitive.Thumb className="block h-[21px] w-[21px] translate-x-0.5 rounded-full bg-white shadow-[0_2px_2px] shadow-black transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[19px]" />
</SwitchPrimitive.Root>
<ErrorMessage touched={meta.touched} error={meta.error} />
</div>
);
};
export default ToggleField;

10
components/Form/Utils.ts Normal file
View file

@ -0,0 +1,10 @@
export class Utils {
//Function to convert strings to camel case
static camelize = (str: string) => {
return str
.replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) {
return index === 0 ? word.toLowerCase() : word.toUpperCase()
})
.replace(/\s+/g, "")
}
}

0
components/Form/data.tsx Normal file
View file

172
components/Form/index.tsx Normal file
View file

@ -0,0 +1,172 @@
"use client"
import React, { useState } from "react";
//Dependencies
import { Formik, Form } from "formik";
import * as Yup from "yup";
import axios from "axios";
//Input fields
import SelectInput from "./SelectInput";
import RadioGroup from "./RadioGroup";
import FileInput from "./FileInput";
import ToggleField from "./ToggleField";
import StatusField from "./StatusField";
import ClientField from "./ClientField";
interface FormValues {
importName: string;
manifestFile: File | null;
splitSchedule: string;
client: string;
testingCenter: string;
toleranceWindow: boolean;
}
const initialValues: FormValues = {
importName: '',
manifestFile: null,
splitSchedule: '',
client: '',
testingCenter: '',
toleranceWindow: false,
};
const validationSchema = Yup.object({
importName: Yup.string()
.required('Import name is required')
.oneOf(["Import ABC", "Import DEF", "Import GHI"], "Invalid Import Name"),
manifestFile: Yup.mixed()
.required('A file is required')
.nullable(), // Allows for null values, adjust based on your logic for file handling
splitSchedule: Yup.string()
.required('This field is required')
.oneOf(["Yes", "No"], "Invalid Option"),
client: Yup.string()
.required('Client selection is required')
.oneOf(["Single", "Multiple"], "Invalid Client Type"),
testingCenter: Yup.string()
.required('Testing center selection is required'), // Assuming a selection is required
toleranceWindow: Yup.boolean()
.required('Tolerance window selection is required'), // Assuming this is a boolean represented by a toggle
});
const data = {
importNames: ["Import ABC", "Import DEF", "Import GHI"],
splitScheduleOptions: ["Yes", "No"],
clientOptions: ["Single", "Multiple"],
testingCenterOptions: ["testing center 1", "testing center 2", "testing center 3", "testing center 4"],
clientsOptions: ["client 1", "client 2", "client 3"],
};
const FormComponent: React.FC = () => {
const [formSubmitted, setFormSubmitted] = useState(false);
const submitForm = (values: FormValues) => {
return axios.post(
`/api/submitForm`,
{
submissionData: values,
},
{
// options
headers: {
"Content-Type": "application/json"
}
}
);
};
return (
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={async (values, { setSubmitting }) => {
try {
console.log(values);
await submitForm(values);
setFormSubmitted(true);
} catch (error) {
console.error("Error submitting form:", error);
} finally {
setSubmitting(false);
}
}}
>
{formik => (
<Form>
<div className="flex flex-col lg:flex-row gap-4 lg:gap-16">
<div className="flex flex-col grow lg:max-w-[500px]">
<SelectInput
key="importName"
name="importName"
label="Select Import Name:"
required
>
<option value="">Select Import Name:</option>
{data.importNames.map(option => (
<option key={option} value={option}>
{option}
</option>
))}
</SelectInput>
<FileInput
label="Select a manifest that you'd like to import"
name="manifestFile"
required
/>
<StatusField
label="Elapse Data Checking:"
statusLabel="No Elapsed Dates!"
statusColor="text-green-500"
/>
<ToggleField
key="toleranceWindow"
name="toleranceWindow"
required={true}
>Tolerance Window:</ToggleField>
</div>
<div className="flex flex-col grow lg:max-w-[350px]">
<RadioGroup
key="splitSchedule"
name="splitSchedule"
label="Split schedule using social distancing?"
options={data.splitScheduleOptions}
required={true}
/>
<StatusField
label="Location Checking:"
statusLabel="All Available!"
statusColor="text-green-500"
/>
<RadioGroup
key="client"
name="client"
label="Client"
options={data.clientOptions}
required={true}
/>
<ClientField
testingCenters={data.testingCenterOptions}
clients={data.clientsOptions}
/>
</div>
</div>
<button
className="mx-auto mt-4"
type="submit"
disabled={formik.isSubmitting}
>
Submit
</button>
</Form>
)}
</Formik>
)
}
export default FormComponent;

0
components/Form/types.ts Normal file
View file

View file

@ -23,6 +23,11 @@
"coupling-graph": "npx madge --extensions js,jsx,ts,tsx,css,md,mdx ./ --exclude '.next|tailwind.config.js|reset.d.ts|prettier.config.js|postcss.config.js|playwright.config.ts|next.config.js|next-env.d.ts|instrumentation.ts|e2e/|README.md|.storybook/|.eslintrc.js' --image graph.svg"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.1",
"@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@next/bundle-analyzer": "^14.0.3",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-checkbox": "^1.0.4",
@ -48,12 +53,14 @@
"@t3-oss/env-nextjs": "^0.7.1",
"@vercel/otel": "^0.3.0",
"class-variance-authority": "^0.7.0",
"formik": "^2.4.5",
"lodash": "^4.17.21",
"next": "^14.0.3",
"next-compose-plugins": "^2.2.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwind-merge": "^2.0.0",
"yup": "^1.3.3",
"zod": "^3.22.4"
},
"devDependencies": {

111
yarn.lock
View file

@ -1492,6 +1492,46 @@
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9"
integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==
"@fortawesome/fontawesome-common-types@6.5.1":
version "6.5.1"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz#fdb1ec4952b689f5f7aa0bffe46180bb35490032"
integrity sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==
"@fortawesome/fontawesome-svg-core@^6.5.1":
version "6.5.1"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz#9d56d46bddad78a7ebb2043a97957039fcebcf0a"
integrity sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==
dependencies:
"@fortawesome/fontawesome-common-types" "6.5.1"
"@fortawesome/free-brands-svg-icons@^6.5.1":
version "6.5.1"
resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.1.tgz#e948cc02404277cb8ad40fe3573ca75f2830e876"
integrity sha512-093l7DAkx0aEtBq66Sf19MgoZewv1zeY9/4C7vSKPO4qMwEsW/2VYTUTpBtLwfb9T2R73tXaRDPmE4UqLCYHfg==
dependencies:
"@fortawesome/fontawesome-common-types" "6.5.1"
"@fortawesome/free-regular-svg-icons@^6.5.1":
version "6.5.1"
resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz#c98a91d2c9137ed54a7aa2362a916f46503e0627"
integrity sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==
dependencies:
"@fortawesome/fontawesome-common-types" "6.5.1"
"@fortawesome/free-solid-svg-icons@^6.5.1":
version "6.5.1"
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz#737b8d787debe88b400ab7528f47be333031274a"
integrity sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==
dependencies:
"@fortawesome/fontawesome-common-types" "6.5.1"
"@fortawesome/react-fontawesome@^0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz#d90dd8a9211830b4e3c08e94b63a0ba7291ddcf4"
integrity sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==
dependencies:
prop-types "^15.8.1"
"@grpc/grpc-js@^1.7.1":
version "1.9.5"
resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.9.5.tgz#22e283754b7b10d1ad26c3fb21849028dcaabc53"
@ -4945,6 +4985,14 @@
dependencies:
"@types/node" "*"
"@types/hoist-non-react-statics@^3.3.1":
version "3.3.5"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494"
integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/html-minifier-terser@^6.0.0":
version "6.1.0"
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35"
@ -7506,6 +7554,11 @@ deep-is@^0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
deepmerge@^2.1.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
deepmerge@^4.2.2:
version "4.3.1"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
@ -8999,6 +9052,20 @@ form-data@^4.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
formik@^2.4.5:
version "2.4.5"
resolved "https://registry.yarnpkg.com/formik/-/formik-2.4.5.tgz#f899b5b7a6f103a8fabb679823e8fafc7e0ee1b4"
integrity sha512-Gxlht0TD3vVdzMDHwkiNZqJ7Mvg77xQNfmBRrNtvzcHZs72TJppSTDKHpImCMJZwcWPBJ8jSQQ95GJzXFf1nAQ==
dependencies:
"@types/hoist-non-react-statics" "^3.3.1"
deepmerge "^2.1.1"
hoist-non-react-statics "^3.3.0"
lodash "^4.17.21"
lodash-es "^4.17.21"
react-fast-compare "^2.0.1"
tiny-warning "^1.0.2"
tslib "^2.0.0"
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
@ -9543,6 +9610,13 @@ hmac-drbg@^1.0.1:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
hoist-non-react-statics@^3.3.0:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
dependencies:
react-is "^16.7.0"
homedir-polyfill@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
@ -13241,6 +13315,11 @@ prop-types@^15.7.2, prop-types@^15.8.1:
object-assign "^4.1.1"
react-is "^16.13.1"
property-expr@^2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8"
integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
@ -13484,6 +13563,11 @@ react-element-to-jsx-string@^15.0.0:
is-plain-object "5.0.0"
react-is "18.1.0"
react-fast-compare@^2.0.1:
version "2.0.4"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
react-inspector@^6.0.0:
version "6.0.2"
resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-6.0.2.tgz#aa3028803550cb6dbd7344816d5c80bf39d07e9d"
@ -13494,7 +13578,7 @@ react-is@18.1.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67"
integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==
react-is@^16.13.1:
react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@ -14993,6 +15077,11 @@ timers-browserify@^2.0.12:
dependencies:
setimmediate "^1.0.4"
tiny-case@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03"
integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==
tiny-invariant@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
@ -15003,6 +15092,11 @@ tiny-relative-date@^1.3.0:
resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07"
integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A==
tiny-warning@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@ -15037,6 +15131,11 @@ toidentifier@1.0.1:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
toposort@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330"
integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==
totalist@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df"
@ -16074,6 +16173,16 @@ yocto-queue@^1.0.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251"
integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==
yup@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/yup/-/yup-1.3.3.tgz#d2f6020ad1679754c5f8178a29243d5447dead04"
integrity sha512-v8QwZSsHH2K3/G9WSkp6mZKO+hugKT1EmnMqLNUcfu51HU9MDyhlETT/JgtzprnrnQHPWsjc6MUDMBp/l9fNnw==
dependencies:
property-expr "^2.0.5"
tiny-case "^1.0.3"
toposort "^2.0.2"
type-fest "^2.19.0"
zod@^3.22.4:
version "3.22.4"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff"