Merged in contact-us-form (pull request #5)
Contact us form Approved-by: Tiago Ribeiro
This commit is contained in:
@@ -16,11 +16,13 @@
|
||||
"axios": "^1.5.1",
|
||||
"clsx": "^2.0.0",
|
||||
"currency-symbol-map": "^5.1.0",
|
||||
"daisyui": "^4.6.3",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.4",
|
||||
"next": "13.5.4",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-hook-form": "^7.50.1",
|
||||
"react-icons": "^4.11.0",
|
||||
"react-string-replace": "^1.1.1",
|
||||
"sharp": "^0.32.6"
|
||||
|
||||
BIN
public/person_laptop_focus.jpg
Normal file
BIN
public/person_laptop_focus.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
@@ -1,6 +1,5 @@
|
||||
import About from "@/templates/About";
|
||||
import ComingSoon from "@/templates/ComingSoon";
|
||||
import ContactUs from "@/templates/ContactUs";
|
||||
|
||||
export default function Page() {
|
||||
return <ComingSoon page="/contact" language="ar" />;
|
||||
return <ContactUs page="/contact" language="ar" />;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import About from "@/templates/About";
|
||||
import ComingSoon from "@/templates/ComingSoon";
|
||||
import ContactUs from "@/templates/ContactUs";
|
||||
|
||||
export default function Page() {
|
||||
return <ComingSoon page="/contact" language="en" />;
|
||||
return <ContactUs page="/contact" language="en" />;
|
||||
}
|
||||
|
||||
149
src/templates/ContactUs.tsx
Normal file
149
src/templates/ContactUs.tsx
Normal file
@@ -0,0 +1,149 @@
|
||||
"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";
|
||||
|
||||
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;
|
||||
console.log("formState", formState.isSubmitSuccessful);
|
||||
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
|
||||
console.log(data);
|
||||
return;
|
||||
}
|
||||
} catch (err) {}
|
||||
};
|
||||
|
||||
return (
|
||||
<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>
|
||||
);
|
||||
}
|
||||
50
src/translation/contactus.json
Normal file
50
src/translation/contactus.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"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": "بريد إلكتروني خطأ"
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,9 @@ const config: Config = {
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
plugins: [require("daisyui")],
|
||||
daisyui: {
|
||||
themes: ["light"],
|
||||
}
|
||||
};
|
||||
export default config;
|
||||
|
||||
37
yarn.lock
37
yarn.lock
@@ -677,6 +677,14 @@ cross-spawn@^7.0.2:
|
||||
shebang-command "^2.0.0"
|
||||
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:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||
@@ -687,11 +695,26 @@ csstype@^3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
|
||||
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:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/currency-symbol-map/-/currency-symbol-map-5.1.0.tgz#59531fbe977ba95e8d358e90e3c9e9053efb75ad"
|
||||
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:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
|
||||
@@ -1158,6 +1181,11 @@ fast-levenshtein@^2.0.6:
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
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:
|
||||
version "1.15.0"
|
||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a"
|
||||
@@ -2074,7 +2102,7 @@ path-type@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
||||
|
||||
picocolors@^1.0.0:
|
||||
picocolors@^1, picocolors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||
@@ -2103,7 +2131,7 @@ postcss-import@^15.1.0:
|
||||
read-cache "^1.0.0"
|
||||
resolve "^1.1.7"
|
||||
|
||||
postcss-js@^4.0.1:
|
||||
postcss-js@^4, postcss-js@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2"
|
||||
integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==
|
||||
@@ -2225,6 +2253,11 @@ react-dom@^18:
|
||||
loose-envify "^1.1.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:
|
||||
version "4.11.0"
|
||||
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.11.0.tgz#4b0e31c9bfc919608095cc429c4f1846f4d66c65"
|
||||
|
||||
Reference in New Issue
Block a user