Merge branch 'master' into nested-country-managers

This commit is contained in:
Joao Ramos
2024-02-15 00:11:33 +00:00
17 changed files with 371 additions and 77 deletions

View File

@@ -16,13 +16,16 @@
"axios": "^1.5.1", "axios": "^1.5.1",
"clsx": "^2.0.0", "clsx": "^2.0.0",
"currency-symbol-map": "^5.1.0", "currency-symbol-map": "^5.1.0",
"daisyui": "^4.6.3",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"moment": "^2.29.4", "moment": "^2.29.4",
"next": "13.5.4", "next": "13.5.4",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",
"react-hook-form": "^7.50.1",
"react-icons": "^4.11.0", "react-icons": "^4.11.0",
"react-string-replace": "^1.1.1", "react-string-replace": "^1.1.1",
"react-toastify": "^10.0.4",
"sharp": "^0.32.6" "sharp": "^0.32.6"
}, },
"devDependencies": { "devDependencies": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@@ -1,6 +1,5 @@
import About from "@/templates/About"; import ContactUs from "@/templates/ContactUs";
import ComingSoon from "@/templates/ComingSoon";
export default function Page() { export default function Page() {
return <ComingSoon page="/contact" language="ar" />; return <ContactUs page="/contact" language="ar" />;
} }

View File

@@ -1,6 +1,5 @@
import About from "@/templates/About"; import ContactUs from "@/templates/ContactUs";
import ComingSoon from "@/templates/ComingSoon";
export default function Page() { export default function Page() {
return <ComingSoon page="/contact" language="en" />; return <ContactUs page="/contact" language="en" />;
} }

View File

@@ -1,28 +0,0 @@
/* eslint-disable @next/next/no-img-element */
import Link from "next/link";
import {BsInstagram, BsTwitter} from "react-icons/bs";
import {BiLogoFacebook} from "react-icons/bi";
import Navbar from "@/components/Navbar";
import PricingTable from "@/components/PricingTable";
import Footer from "@/components/Footer";
export default function Home() {
return (
<main className="h-screen w-full bg-white text-mti-black flex flex-col">
<Navbar currentPage="/join" language="en" />
<section className="w-full relative bg-white py-20 lg:py-48 px-8 flex flex-col items-center text-center gap-4">
<h2 className="text-3xl font-bold">Available Packages</h2>
<div className="flex flex-col gap-1">
<span className="max-w-lg">
Once the payment process is complete, you will receive a code via e-mail to register to the application.
</span>
<span className="max-w-lg">(Or have time added to your account, if already registered with the given e-mail).</span>
<PricingTable />
</div>
</section>
<Footer language="en" />
</main>
);
}

View File

@@ -1,6 +1,7 @@
/* eslint-disable @next/next/no-page-custom-font */ /* eslint-disable @next/next/no-page-custom-font */
import clsx from "clsx"; import clsx from "clsx";
import "./globals.css"; import "./globals.css";
import "react-toastify/dist/ReactToastify.css";
import type {Metadata} from "next"; import type {Metadata} from "next";
import {Inter} from "next/font/google"; import {Inter} from "next/font/google";
import {Almarai} from "next/font/google"; import {Almarai} from "next/font/google";
@@ -26,9 +27,6 @@ export default function RootLayout({children}: {children: React.ReactNode}) {
httpEquiv="Content-Security-Policy-Report-Only" httpEquiv="Content-Security-Policy-Report-Only"
content="default-src 'self' *.stripe.com *.encoach.com staging.encoach.com localhost" content="default-src 'self' *.stripe.com *.encoach.com staging.encoach.com localhost"
/> />
<script async src="https://js.stripe.com/v3/pricing-table.js" />
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
<link href="https://fonts.googleapis.com/css2?family=Almarai:wght@300;400;700;800&display=swap" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css2?family=Almarai:wght@300;400;700;800&display=swap" rel="stylesheet" />

View File

@@ -1,23 +0,0 @@
"use client";
import {Elements} from "@stripe/react-stripe-js";
import {loadStripe} from "@stripe/stripe-js";
const stripePromise = loadStripe(process.env.STRIPE_KEY || "");
export default function PricingTable() {
return (
<Elements stripe={stripePromise}>
<stripe-pricing-table id="pricing" pricing-table-id={process.env.STRIPE_PRICING_TABLE} publishable-key={process.env.STRIPE_KEY} />
</Elements>
);
}
// If using TypeScript, add the following snippet to your file as well.
declare global {
namespace JSX {
interface IntrinsicElements {
"stripe-pricing-table": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
}
}
}

189
src/templates/ContactUs.tsx Normal file
View File

@@ -0,0 +1,189 @@
"use client";
import React from "react";
import { useForm, SubmitHandler, Controller } from "react-hook-form";
import Footer from "@/components/Footer";
import Navbar from "@/components/Navbar";
import Title from "@/components/Title";
import translation from "@/translation/contactus.json";
import Image from "next/image";
import { toast, ToastContainer } from "react-toastify";
type FormValues = {
name: string;
email: string;
description: string;
subject: string;
type: "feedback" | "bug" | "help" | "";
};
interface Props {
language: "en" | "ar";
page: string;
}
const ErrorMessage = ({ message }: { message: string }) => (
<div className="w-full">
<span className="text-mti-red">{message}</span>
</div>
);
export default function App({ language, page }: Props) {
const selectOptions = [
{
label: translation.feedback[language],
value: "feedback",
},
{
label: translation.bug[language],
value: "bug",
},
{
label: translation.help[language],
value: "help",
},
];
const { register, control, handleSubmit, formState } = useForm<FormValues>({
defaultValues: {
name: "",
email: "",
description: "",
subject: "",
type: "",
},
});
const { errors, isDirty, isValid } = formState;
const onSubmit: SubmitHandler<FormValues> = async (data) => {
try {
const response = await fetch(`https://platform.encoach.com/api/tickets`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
reporter: {
name: data.name,
email: data.email,
},
subject: data.subject,
type: data.type,
reportedFrom: window.location.href,
status: "submitted",
date: new Date().toISOString(),
description: data.description,
}),
});
if (response.status === 200) {
const data = await response.json();
// Pass data to the page via props
if (data.ok) {
toast.success(translation.ticketSuccess[language]);
return;
}
}
} catch (err) {}
toast.error(translation.ticketError[language]);
};
return (
<>
<ToastContainer />
<main
className="text-mti-black flex h-screen w-full flex-col bg-white"
dir={language === "ar" ? "rtl" : "ltr"}
>
<Navbar currentPage={page} language={language} />
<section className="w-full bg-mti-purple text-white text-center p-8 md:p-16">
<div className="w-full h-full flex flex-col items-center justify-center">
<Title>{translation.title[language]}</Title>
</div>
</section>
<section className="w-full bg-white text-center p-8 md:p-16 flex justify-center items-center gap-32">
<form
onSubmit={handleSubmit(onSubmit)}
className="form-control items-center gap-2 text-mti-black flex flex-col w-96"
>
<input
id="name"
type="text"
placeholder={translation.name[language]}
{...register("name", { required: true })}
className="input input-bordered md:w-full sm:w-1/2 max-w-md"
/>
{errors.name && errors.name.type === "required" && (
<ErrorMessage message={translation.fieldRequired[language]} />
)}
<input
id="email"
placeholder={translation.email[language]}
type="text"
{...register("email", { required: true, pattern: /^\S+@\S+$/i })}
className="input input-bordered md:w-full sm:w-1/2 max-w-md"
/>
{errors.email && errors.email.type === "required" && (
<ErrorMessage message={translation.fieldRequired[language]} />
)}
{errors.email && errors.email.type === "pattern" && (
<ErrorMessage message={translation.invalidEmail[language]} />
)}
<input
id="subject"
placeholder={translation.subject[language]}
type="text"
{...register("subject", { required: true })}
className="input input-bordered md:w-full sm:w-1/2 max-w-md"
/>
{errors.subject && errors.subject.type === "required" && (
<ErrorMessage message={translation.fieldRequired[language]} />
)}
<select
id="type"
{...register("type", { required: true })}
className="select select-bordered md:w-full sm:w-1/2 max-w-md"
>
<option value="" disabled>
{translation.selectType[language]}
</option>
{selectOptions.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
{errors.type && errors.type.type === "required" && (
<ErrorMessage message={translation.fieldRequired[language]} />
)}
<textarea
id="description"
placeholder={translation.description[language]}
{...register("description", { required: true })}
className="textarea textarea-bordered md:w-full sm:w-1/2 max-w-md"
rows={5}
/>
{errors.description && errors.description.type === "required" && (
<ErrorMessage message={translation.fieldRequired[language]} />
)}
<input
type="submit"
className="btn"
disabled={!isDirty || !isValid}
value={translation.submit[language]}
/>
</form>
<div className="flex flex-col">
<Image
src="/person_laptop_focus.jpg"
alt="Contact Us"
width={500}
height={340}
className="rounded-xl"
/>
</div>
</section>
<Footer language={language} />
</main>
</>
);
}

View File

@@ -33,7 +33,7 @@ const Element = ({date, label, isEven, language, Icon}: ElementProps) => {
<span className={clsx("w-64 text-mti-purple-light font-semibold text-lg", isEven && "text-right")}>{date}</span> <span className={clsx("w-64 text-mti-purple-light font-semibold text-lg", isEven && "text-right")}>{date}</span>
</div> </div>
<div className={clsx("flex items-center gap-8 md:hidden", language === "ar" && "flex-row-reverse text-right")}> <div className={clsx("flex items-center gap-8 md:hidden")}>
<div className="h-16 w-16 rounded-full bg-mti-purple-dark flex items-center justify-center text-white border-white border-4 drop-shadow"> <div className="h-16 w-16 rounded-full bg-mti-purple-dark flex items-center justify-center text-white border-white border-4 drop-shadow">
<Icon className="h-6 w-6" /> <Icon className="h-6 w-6" />
</div> </div>
@@ -75,9 +75,9 @@ export default function History({language}: Props) {
</div> </div>
<div <div
className={clsx( className={clsx(
"w-2 h-[89%] bg-mti-purple-light absolute md:left-1/2 md:-translate-x-1/2 top-1/2 -translate-y-1/2 rounded-full", "w-2 h-[89%] bg-mti-purple-light absolute top-1/2 -translate-y-1/2 rounded-full",
language === "en" && "left-1/2 -translate-x-[148px]", language === "en" && "left-1/2 -translate-x-[148px] md:left-1/2 md:-translate-x-1/2",
language === "ar" && "right-1/2 translate-x-[148px]", language === "ar" && "right-1/2 translate-x-[148px] md:right-1/2 md:translate-x-1/2",
)} )}
/> />
</div> </div>

View File

@@ -79,7 +79,7 @@ export default function Home({language}: Props) {
<Title>{translation.learn_ai.title[language]}</Title> <Title>{translation.learn_ai.title[language]}</Title>
<p className="max-w-lg text-base">{translation.learn_ai.description[language]}</p> <p className="max-w-lg text-base">{translation.learn_ai.description[language]}</p>
</div> </div>
<Link href="/join"> <Link href="/price">
<button className="bg-mti-purple-light hover:bg-mti-purple text-white rounded-xl px-8 py-4 transition ease-in-out duration-300 shadow"> <button className="bg-mti-purple-light hover:bg-mti-purple text-white rounded-xl px-8 py-4 transition ease-in-out duration-300 shadow">
{translation.learn_more[language]} {translation.learn_more[language]}
</button> </button>

View File

@@ -21,6 +21,28 @@ interface Package {
} }
export default function Page({language}: {language: "en" | "ar"}) { export default function Page({language}: {language: "en" | "ar"}) {
const getDurationUnit = (duration: number, durationUnitSingular: string, durationUnitPlural: string) => {
if(duration >= 2 && duration <= 10) {
return durationUnitPlural;
}
return durationUnitSingular;
}
const durationAndDurationUnitParser = (duration: number, duration_unit: DurationUnit) => {
if(language === 'ar') {
switch (duration_unit) {
case "days":
return `${duration} ${getDurationUnit(duration, translation.days.singular[language], translation.days.plural[language])}`;
case "weeks":
return `${duration} ${getDurationUnit(duration, translation.weeks.singular[language], translation.weeks.plural[language])}`;
case "months":
return `${duration} ${getDurationUnit(duration, translation.months.singular[language], translation.months.plural[language])}`;
}
}
return `${duration} ${capitalize(duration === 1 ? duration_unit.slice(0, duration_unit.length - 1) : duration_unit)}`;
}
const [payments, setPayments] = React.useState<Package[]>([]); const [payments, setPayments] = React.useState<Package[]>([]);
const getData = async () => { const getData = async () => {
// Fetch data from external API // Fetch data from external API
@@ -50,8 +72,7 @@ export default function Page({language}: {language: "en" | "ar"}) {
<div className="flex flex-col items-start mb-2"> <div className="flex flex-col items-start mb-2">
<Image src="/logo_title.png" alt="EnCoach's Logo" width={32} height={32} /> <Image src="/logo_title.png" alt="EnCoach's Logo" width={32} height={32} />
<span className="font-semibold text-xl"> <span className="font-semibold text-xl">
EnCoach - {p.duration}{" "} {translation.encoach[language]} - {durationAndDurationUnitParser(p.duration, p.duration_unit)}
{capitalize(p.duration === 1 ? p.duration_unit.slice(0, p.duration_unit.length - 1) : p.duration_unit)}
</span> </span>
</div> </div>
<div className="flex flex-col gap-2 items-start w-full"> <div className="flex flex-col gap-2 items-start w-full">

View File

@@ -0,0 +1,58 @@
{
"title": {
"en": "Submit a ticket",
"ar": "تحدث إلينا "
},
"name": {
"en": "Name",
"ar": "الإسم"
},
"email": {
"en": "Email",
"ar": "البريد الإلكتروني"
},
"subject": {
"en": "Subject",
"ar": "الموضوع"
},
"submit": {
"en": "Submit",
"ar": "أرسل"
},
"selectType": {
"en": "Select Type",
"ar": "أختر النوع"
},
"description": {
"en": "Description",
"ar": "الوصف"
},
"feedback": {
"en": "Feedback",
"ar": "تغذية راجعة"
},
"bug": {
"en": "Bug",
"ar": "بلاغ عن مشكلة"
},
"help": {
"en": "Help",
"ar": "طلب مساعدة"
},
"fieldRequired": {
"en": "This field is required",
"ar": "هذا الحقل إلزامي"
},
"invalidEmail": {
"en": "Invalid email",
"ar": "بريد إلكتروني خطأ"
},
"ticketSuccess": {
"en": "Ticket submitted successfully!",
"ar": "تم إرسال ملاحظتكم بنجاح"
},
"ticketError": {
"en": "Failed to submit the ticket!",
"ar": "فشل في إرسال الملاحظات"
}
}

View File

@@ -57,10 +57,6 @@
"description": { "description": {
"en": "Our algorithms provide speedy results and evaluate the test, providing a brief feedback on areas that are strong and the areas where improvement is needed. So there is no need to pay a hefty amount to a tutor and spend hours upon hours to review your performance. With EnCoach, you receive the evaluation within seconds.", "en": "Our algorithms provide speedy results and evaluate the test, providing a brief feedback on areas that are strong and the areas where improvement is needed. So there is no need to pay a hefty amount to a tutor and spend hours upon hours to review your performance. With EnCoach, you receive the evaluation within seconds.",
"ar": "خوارزمياتنا توفر نتائج وتقييم سريع للاختبار، وتقدم ملاحظات موجزًة على الجوانب التي تتميز بها والجوانب التي تحتاج إلى تحسين. لذا ليس هناك حاجة لدفع مبلغ ضخم لمدرس وقضاء ساعات وساعات في مراجعة أدائك. مع إنكوتش، ستتلقى التقييم في غضون ثوانٍ." "ar": "خوارزمياتنا توفر نتائج وتقييم سريع للاختبار، وتقدم ملاحظات موجزًة على الجوانب التي تتميز بها والجوانب التي تحتاج إلى تحسين. لذا ليس هناك حاجة لدفع مبلغ ضخم لمدرس وقضاء ساعات وساعات في مراجعة أدائك. مع إنكوتش، ستتلقى التقييم في غضون ثوانٍ."
},
"join": {
"en": "Join",
"ar": "انضم"
} }
}, },
"learn_more": { "learn_more": {
@@ -121,4 +117,4 @@
"en": "Accreditation", "en": "Accreditation",
"ar": "الاعتمادات الأكاديمية" "ar": "الاعتمادات الأكاديمية"
} }
} }

View File

@@ -28,7 +28,7 @@
"ar": "منصة انكوتش" "ar": "منصة انكوتش"
}, },
"join": { "join": {
"en": "Join", "en": "Sign up",
"ar": "انضم إلينا" "ar": "انضم إلينا"
}, },
"country_manager": { "country_manager": {

View File

@@ -1,6 +1,6 @@
{ {
"joinus": { "joinus": {
"en": "Join us", "en": "Sign up",
"ar": "انضم إلينا" "ar": "انضم إلينا"
}, },
"title": { "title": {
@@ -22,5 +22,39 @@
"packageIncludesC": { "packageIncludesC": {
"en": "Allow yourself to correctly prepare for the exam", "en": "Allow yourself to correctly prepare for the exam",
"ar": "امنح نفسك الفرصة للتحضير بشكل صحيح للإختبار" "ar": "امنح نفسك الفرصة للتحضير بشكل صحيح للإختبار"
},
"days": {
"singular": {
"en": "Day",
"ar": "يوم"
},
"plural": {
"en": "Days",
"ar": "أيام"
}
},
"weeks": {
"singular": {
"en": "Week",
"ar": "أسبوع"
},
"plural": {
"en": "Weeks",
"ar": "أسابيع"
}
},
"months": {
"singular": {
"en": "Month",
"ar": "شهر"
},
"plural": {
"en": "Months",
"ar": "شهور"
}
},
"encoach": {
"en": "EnCoach",
"ar": "إنكوتش"
} }
} }

View File

@@ -76,6 +76,9 @@ const config: Config = {
}, },
}, },
}, },
plugins: [], plugins: [require("daisyui")],
daisyui: {
themes: ["light"],
}
}; };
export default config; export default config;

View File

@@ -623,6 +623,11 @@ clsx@^2.0.0:
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b"
integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==
clsx@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb"
integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==
color-convert@^2.0.1: color-convert@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
@@ -677,6 +682,14 @@ cross-spawn@^7.0.2:
shebang-command "^2.0.0" shebang-command "^2.0.0"
which "^2.0.1" which "^2.0.1"
css-selector-tokenizer@^0.8:
version "0.8.0"
resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz#88267ef6238e64f2215ea2764b3e2cf498b845dd"
integrity sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==
dependencies:
cssesc "^3.0.0"
fastparse "^1.1.2"
cssesc@^3.0.0: cssesc@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@@ -687,11 +700,26 @@ csstype@^3.0.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
culori@^3:
version "3.3.0"
resolved "https://registry.yarnpkg.com/culori/-/culori-3.3.0.tgz#e33530adbd124d53bd6550394397e695eaaed739"
integrity sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==
currency-symbol-map@^5.1.0: currency-symbol-map@^5.1.0:
version "5.1.0" version "5.1.0"
resolved "https://registry.yarnpkg.com/currency-symbol-map/-/currency-symbol-map-5.1.0.tgz#59531fbe977ba95e8d358e90e3c9e9053efb75ad" resolved "https://registry.yarnpkg.com/currency-symbol-map/-/currency-symbol-map-5.1.0.tgz#59531fbe977ba95e8d358e90e3c9e9053efb75ad"
integrity sha512-LO/lzYRw134LMDVnLyAf1dHE5tyO6axEFkR3TXjQIOmMkAM9YL6QsiUwuXzZAmFnuDJcs4hayOgyIYtViXFrLw== integrity sha512-LO/lzYRw134LMDVnLyAf1dHE5tyO6axEFkR3TXjQIOmMkAM9YL6QsiUwuXzZAmFnuDJcs4hayOgyIYtViXFrLw==
daisyui@^4.6.3:
version "4.6.3"
resolved "https://registry.yarnpkg.com/daisyui/-/daisyui-4.6.3.tgz#440a87305e2e7ca1b03498bba262481961cfad4c"
integrity sha512-0Y8G0EwO1aQlvhasDuUAYH35XCK/808dwYdkT4VqQ2kqtErcd/MFaHqK4CGhXwf6PWsWImmIpotFehWkUrlxnw==
dependencies:
css-selector-tokenizer "^0.8"
culori "^3"
picocolors "^1"
postcss-js "^4"
damerau-levenshtein@^1.0.8: damerau-levenshtein@^1.0.8:
version "1.0.8" version "1.0.8"
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
@@ -1158,6 +1186,11 @@ fast-levenshtein@^2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
fastparse@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
fastq@^1.6.0: fastq@^1.6.0:
version "1.15.0" version "1.15.0"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a"
@@ -2074,7 +2107,7 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
picocolors@^1.0.0: picocolors@^1, picocolors@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
@@ -2103,7 +2136,7 @@ postcss-import@^15.1.0:
read-cache "^1.0.0" read-cache "^1.0.0"
resolve "^1.1.7" resolve "^1.1.7"
postcss-js@^4.0.1: postcss-js@^4, postcss-js@^4.0.1:
version "4.0.1" version "4.0.1"
resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2"
integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==
@@ -2225,6 +2258,11 @@ react-dom@^18:
loose-envify "^1.1.0" loose-envify "^1.1.0"
scheduler "^0.23.0" scheduler "^0.23.0"
react-hook-form@^7.50.1:
version "7.50.1"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.50.1.tgz#f6aeb17a863327e5a0252de8b35b4fc8990377ed"
integrity sha512-3PCY82oE0WgeOgUtIr3nYNNtNvqtJ7BZjsbxh6TnYNbXButaD5WpjOmTjdxZfheuHKR68qfeFnEDVYoSSFPMTQ==
react-icons@^4.11.0: react-icons@^4.11.0:
version "4.11.0" version "4.11.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.11.0.tgz#4b0e31c9bfc919608095cc429c4f1846f4d66c65" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.11.0.tgz#4b0e31c9bfc919608095cc429c4f1846f4d66c65"
@@ -2240,6 +2278,13 @@ react-string-replace@^1.1.1:
resolved "https://registry.yarnpkg.com/react-string-replace/-/react-string-replace-1.1.1.tgz#8413a598c60e397fe77df3464f2889f00ba25989" resolved "https://registry.yarnpkg.com/react-string-replace/-/react-string-replace-1.1.1.tgz#8413a598c60e397fe77df3464f2889f00ba25989"
integrity sha512-26TUbLzLfHQ5jO5N7y3Mx88eeKo0Ml0UjCQuX4BMfOd/JX+enQqlKpL1CZnmjeBRvQE8TR+ds9j1rqx9CxhKHQ== integrity sha512-26TUbLzLfHQ5jO5N7y3Mx88eeKo0Ml0UjCQuX4BMfOd/JX+enQqlKpL1CZnmjeBRvQE8TR+ds9j1rqx9CxhKHQ==
react-toastify@^10.0.4:
version "10.0.4"
resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-10.0.4.tgz#6ecdbbf923a07fc45850e69b0566efc7bf733283"
integrity sha512-etR3RgueY8pe88SA67wLm8rJmL1h+CLqUGHuAoNsseW35oTGJEri6eBTyaXnFKNQ80v/eO10hBYLgz036XRGgA==
dependencies:
clsx "^2.1.0"
react@^18: react@^18:
version "18.2.0" version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"