Commit 8d4d9105 by Ravindra Kanojiya

updated form

1 parent 528e0554
import FadeInStagger from "@/components/FadeInStagger"; import FadeInStagger from "@/components/FadeInStagger";
import { useRouter } from "next/router";
import React from "react"; import React from "react";
import { Col, Container, Row } from "react-bootstrap"; import { Col, Container, Row } from "react-bootstrap";
import axios from "axios";
import { useForm } from "react-hook-form";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
export const Contact = () => { export const Contact = () => {
/* ---------------- VALIDATION SCHEMA ---------------- */
const schema = yup.object({
name: yup.string().required("Full name is required"),
email: yup
.string()
.email("Enter a valid email address")
.required("Email is required"),
phone: yup
.string()
.matches(/^[0-9]{10}$/, "Phone number must be 10 digits")
.required("Phone number is required"),
message: yup.string().required("Message is required"),
consent: yup.boolean().oneOf([true], "You must accept the terms"),
});
const router = useRouter();
const {
register,
handleSubmit,
watch,
formState: { errors, isSubmitting, isValid },
reset,
} = useForm({
resolver: yupResolver(schema),
mode: "onChange", // important for button enable/disable
});
const onSubmit = async (data) => {
try {
const payload = {
data: {
// FormSource: "Contact Form",
Name: data.name,
Email: data.email,
MobileNumber: data.phone,
Message: data.message,
},
};
await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/website-leads`,
payload,
);
reset();
router.push("/thankyou");
} catch (error) {
console.error(error);
alert("Failed to submit form. Please try again.");
}
};
return ( return (
<> <>
<section className="contact_sec"> <section className="contact_sec">
...@@ -14,85 +74,115 @@ export const Contact = () => { ...@@ -14,85 +74,115 @@ export const Contact = () => {
<h2 className="heading">Lets Connect</h2> <h2 className="heading">Lets Connect</h2>
<p>Create your Dream space together, Visit Us Today!</p> <p>Create your Dream space together, Visit Us Today!</p>
</FadeInStagger> </FadeInStagger>
<form action="" className="let-connect-form"> <form
<Row> className="let-connect-form"
<Col md={6} className="mb-3"> onSubmit={handleSubmit(onSubmit)}
<div className="mb-1">Name</div> noValidate
<div> >
<input <Row>
type="text" <Col md={6} className="mb-3">
placeholder="Type here" <div className="mb-1">Name</div>
name="name" <div>
className="inputField nameInput" <input
/> type="text"
</div> placeholder="Type here"
</Col> name="name"
<Col md={6} className="mb-3"> className="inputField nameInput"
<div className="mb-1">Mobile Number</div> {...register("name")}
<div> />
<input {errors.name && (
type="text" <p className="error">{errors.name.message}</p>
placeholder="Type here" )}
name="Mobile Number" </div>
className="inputField nameInput" </Col>
/> <Col md={6} className="mb-3">
</div> <div className="mb-1">Mobile Number</div>
</Col> <div>
</Row> <input
<Row> type="text"
<Col md={12} className="mb-3"> placeholder="Type here"
<div className="mb-1">Email Address</div> name="Mobile Number"
<div> className="inputField nameInput"
<input {...register("phone")}
type="text" />
placeholder="Type here" {errors.phone && (
name="Email Address" <p className="error">{errors.phone.message}</p>
className="inputField nameInput" )}
/> </div>
</div> </Col>
</Col> </Row>
</Row> <Row>
<Row> <Col md={12} className="mb-3">
<Col md={12} className="mb-3"> <div className="mb-1">Email Address</div>
<div className="mb-1">Message</div> <div>
<div> <input
<textarea type="text"
rows="5" placeholder="Type here"
type="text" name="Email Address"
placeholder="Type here" className="inputField nameInput"
name="name" {...register("email")}
className="inputField nameInput" />
/> {errors.email && (
</div> <p className="error">{errors.email.message}</p>
</Col> )}
</Row> </div>
<Row> </Col>
<Col className="mb-3"> </Row>
<Row>
<Col md={12} className="mb-3">
<div className="mb-1">Message</div>
<div>
<textarea
rows="5"
type="text"
placeholder="Type here"
name="name"
className="inputField nameInput"
{...register("message")}
/>
{errors.message && (
<p className="error">{errors.message.message}</p>
)}
</div>
</Col>
</Row>
<Row>
<Col className="mb-3">
<div className="form-check"> <div className="form-check">
<input <input
className="form-check-input" className="form-check-input"
type="checkbox" type="checkbox"
value=""
id="checkChecked" id="checkChecked"
{...register("consent")}
/> />
<label className="form-check-label" for="checkChecked"> <label
className="form-check-label"
htmlFor="checkChecked"
>
I accept the processing of my personal data for I accept the processing of my personal data for
traditional and automated direct marketing purposes. traditional and automated direct marketing purposes.
</label> </label>
</div> </div>
</Col> {errors.consent && (
</Row> <p className="error">{errors.consent.message}</p>
<Row> )}
<Col className="mb-3"> </Col>
<div className="d-flex gap-3"> </Row>
<button className="btn3">Submit <i className="fa-solid fa-arrow-right"></i></button> <Row>
</div> <Col className="mb-3">
</Col> <div className="d-flex gap-3">
</Row> <button
</form> type="submit"
className="btn3"
disabled={!watch("consent") || isSubmitting}
>
{isSubmitting ? "Submitting..." : "Submit"} <i className="fa-solid fa-arrow-right"></i>
</button>
</div>
</Col>
</Row>
</form>
</div> </div>
</Col> </Col>
</Row> </Row>
</Container> </Container>
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@fancyapps/ui": "^5.0.36", "@fancyapps/ui": "^5.0.36",
"@hookform/resolvers": "^5.2.2",
"@reduxjs/toolkit": "^2.3.0", "@reduxjs/toolkit": "^2.3.0",
"@studio-freight/lenis": "^1.0.42", "@studio-freight/lenis": "^1.0.42",
"axios": "^1.7.7", "axios": "^1.7.7",
...@@ -26,7 +27,8 @@ ...@@ -26,7 +27,8 @@
"react-hook-form": "^7.56.3", "react-hook-form": "^7.56.3",
"react-paginate": "^8.2.0", "react-paginate": "^8.2.0",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
"swiper": "^11.2.6" "swiper": "^11.2.6",
"yup": "^1.7.1"
} }
}, },
"node_modules/@babel/runtime": { "node_modules/@babel/runtime": {
...@@ -46,6 +48,18 @@ ...@@ -46,6 +48,18 @@
"integrity": "sha512-GMygQzp1MBTFNTT6AzpbL6pXTD6bTxwjmmpI1fe8Ozmmiseu8/g82Sudl1YhcbZmS4bJgaBOF5THDFGpXQ1fDw==", "integrity": "sha512-GMygQzp1MBTFNTT6AzpbL6pXTD6bTxwjmmpI1fe8Ozmmiseu8/g82Sudl1YhcbZmS4bJgaBOF5THDFGpXQ1fDw==",
"license": "SEE LICENSE IN LICENSE.md" "license": "SEE LICENSE IN LICENSE.md"
}, },
"node_modules/@hookform/resolvers": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.2.tgz",
"integrity": "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==",
"license": "MIT",
"dependencies": {
"@standard-schema/utils": "^0.3.0"
},
"peerDependencies": {
"react-hook-form": "^7.55.0"
}
},
"node_modules/@next/env": { "node_modules/@next/env": {
"version": "14.2.35", "version": "14.2.35",
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.35.tgz", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.35.tgz",
...@@ -1012,6 +1026,12 @@ ...@@ -1012,6 +1026,12 @@
"react": ">=0.14.0" "react": ">=0.14.0"
} }
}, },
"node_modules/property-expr": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
"integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==",
"license": "MIT"
},
"node_modules/proxy-from-env": { "node_modules/proxy-from-env": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
...@@ -1317,11 +1337,35 @@ ...@@ -1317,11 +1337,35 @@
"node": ">= 4.7.0" "node": ">= 4.7.0"
} }
}, },
"node_modules/tiny-case": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
"license": "MIT"
},
"node_modules/toposort": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
"license": "MIT"
},
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.8.1", "version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
}, },
"node_modules/type-fest": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=12.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/uncontrollable": { "node_modules/uncontrollable": {
"version": "7.2.1", "version": "7.2.1",
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz",
...@@ -1356,6 +1400,18 @@ ...@@ -1356,6 +1400,18 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/yup": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz",
"integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==",
"license": "MIT",
"dependencies": {
"property-expr": "^2.0.5",
"tiny-case": "^1.0.3",
"toposort": "^2.0.2",
"type-fest": "^2.19.0"
}
} }
} }
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
}, },
"dependencies": { "dependencies": {
"@fancyapps/ui": "^5.0.36", "@fancyapps/ui": "^5.0.36",
"@hookform/resolvers": "^5.2.2",
"@reduxjs/toolkit": "^2.3.0", "@reduxjs/toolkit": "^2.3.0",
"@studio-freight/lenis": "^1.0.42", "@studio-freight/lenis": "^1.0.42",
"axios": "^1.7.7", "axios": "^1.7.7",
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
"react-hook-form": "^7.56.3", "react-hook-form": "^7.56.3",
"react-paginate": "^8.2.0", "react-paginate": "^8.2.0",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
"swiper": "^11.2.6" "swiper": "^11.2.6",
"yup": "^1.7.1"
} }
} }
import Link from "next/link";
import React from "react";
const thankyouPage = () => {
return (
<>
<div className="thank-you-wrapper">
<div className="thank-you-box">
<h1 className="head01">
Thank <span>You!</span>
</h1>
<p>
Your request has been submitted successfully.
<br />
Our team will get back to you shortly.
</p>
{/* <Link href="/" className="btn-home">
Go Back to Home
</Link> */}
<div className="text-center">
<Link href="/" className="btn3">Go Back to Home <i className="fa-solid fa-arrow-right"></i></Link>
</div>
</div>
</div>
<style jsx>{`
.thank-you-wrapper {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #f7f7f7;
padding: 20px;
}
.thank-you-box {
background: #ffffff;
padding: 40px;
border-radius: 8px;
text-align: center;
max-width: 445px;
width: 100%;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}
h1 {
margin-bottom: 10px;
}
p {
color: #555;
font-size: 16px;
line-height: 1.5;
margin-bottom: 25px;
}
.btn-home {
display: inline-block;
text-decoration: none;
background: #2e7d32;
color: #fff;
padding: 10px 22px;
border-radius: 4px;
font-size: 14px;
transition: background 0.3s ease;
}
.btn-home:hover {
background: #256628;
}
`}</style>
</>
);
};
export default thankyouPage;
...@@ -865,6 +865,19 @@ h2.heading>p{ ...@@ -865,6 +865,19 @@ h2.heading>p{
.explore-swiper .swiperbtn1 { .explore-swiper .swiperbtn1 {
top: 40%; top: 40%;
} }
.error {
color: #e63946;
font-size: 12px;
margin-top: 4px;
}
/* Disabled state */
.btn3:disabled {
background-color: #cccccc; /* grey background */
color: #666666; /* darker grey text */
cursor: not-allowed;
opacity: 0.7;
}
@media only screen and (max-width: 1023px) { @media only screen and (max-width: 1023px) {
} }
/* ===== Mobile ===== */ /* ===== Mobile ===== */
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!