Merge branch 'master' of http://192.168.1.163:3000/mikhail_lanskikh/baraha-town
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import { useState } from "react";
|
||||
import Button from "../ui/Button";
|
||||
import Input from "../ui/Input";
|
||||
import { Link } from "react-router";
|
||||
|
||||
const INTERESTS = ["Retail", "Office", "Residential"] as const;
|
||||
|
||||
function Feedback() {
|
||||
const [interests, setInterests] = useState<(typeof INTERESTS)[number][]>([]);
|
||||
|
||||
function handleInterestClick(interest: (typeof INTERESTS)[number]) {
|
||||
if (interests.includes(interest)) {
|
||||
setInterests((prev) => prev.filter((i) => i !== interest));
|
||||
} else {
|
||||
setInterests((prev) => [...prev, interest]);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="2xl:grid max-2xl:space-y-8 grid-cols-2 2xl:gap-[1.111vw]">
|
||||
<h2 className="2xl:h2 md:h3 text-2xl max-md:leading-[110%] md:max-2xl:max-w-[63.021vw] max-md:max-w-[328px] [font-family:New_York_Medium]">
|
||||
Enquire about joining this thriving community at the heart of Abu Hamour
|
||||
by contacting a member of our sales team today
|
||||
</h2>
|
||||
|
||||
<form className="2xl:space-y-[1.667vw] space-y-6 row-span-2">
|
||||
<Input
|
||||
label="Full Name"
|
||||
id="fullname"
|
||||
placeholder="Enter your full name"
|
||||
/>
|
||||
<div className="flex max-md:flex-col 2xl:gap-[1.667vw] gap-6">
|
||||
<Input
|
||||
label="Email"
|
||||
id="email"
|
||||
type="email"
|
||||
placeholder="Enter your email"
|
||||
/>
|
||||
<Input label="Phone Number" id="phone" type="tel" placeholder="" />
|
||||
</div>
|
||||
<div className="2xl:space-y-[0.833vw] space-y-3">
|
||||
<p className="text-m">What are you interested in?</p>
|
||||
<div className="flex 2xl:gap-[0.833vw] gap-3">
|
||||
{INTERESTS.map((interest) => (
|
||||
<Button
|
||||
key={interest}
|
||||
variant={interests.includes(interest) ? "cta" : "primary"}
|
||||
size="large"
|
||||
type="button"
|
||||
onClick={() => handleInterestClick(interest)}
|
||||
>
|
||||
{interest}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<Input
|
||||
label="Message"
|
||||
id="message"
|
||||
placeholder="Enter your message here"
|
||||
isTextArea
|
||||
maxLength={180}
|
||||
/>
|
||||
<Button
|
||||
variant="cta"
|
||||
size="large"
|
||||
type="submit"
|
||||
className="w-full"
|
||||
onClick={(e) => e.preventDefault()}
|
||||
>
|
||||
Send Message
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
<div className="md:grid items-end md:row-start-2 md:grid-cols-3 2xl:gap-y-[2.222vw] gap-y-8 2xl:gap-x-[1.111vw] gap-x-4 max-md:space-y-6 max-md:max-w-[213px]">
|
||||
<div className="2xl:space-y-[0.556vw] space-y-2">
|
||||
<p className="text-s opacity-60">Address</p>
|
||||
<p className="text-s">Mesaimeer Street, Abu Hamour, Doha-Qata</p>
|
||||
</div>
|
||||
<div className="2xl:space-y-[0.556vw] space-y-2">
|
||||
<p className="text-s opacity-60">Management Office</p>
|
||||
<p className="text-s">
|
||||
Sabah Al Ahmad Corridor, Abu Hamour, Doha, Qatar
|
||||
</p>
|
||||
</div>
|
||||
<div className="2xl:space-y-[0.556vw] space-y-2 md:col-start-1">
|
||||
<p className="text-s opacity-60">Email Address:</p>
|
||||
<Link
|
||||
target="_blank"
|
||||
className="text-s text-[#F47F52]"
|
||||
to="mailto:info@barahatown.com"
|
||||
>
|
||||
info@barahatown.com
|
||||
</Link>
|
||||
</div>
|
||||
<div className="2xl:space-y-[0.556vw] space-y-2">
|
||||
<p className="text-s opacity-60">Leasing Department:</p>
|
||||
<Link
|
||||
target="_blank"
|
||||
className="text-s text-[#F47F52]"
|
||||
to="tel:+97450254555"
|
||||
>
|
||||
+974 5025 4555
|
||||
</Link>
|
||||
</div>
|
||||
<div className="2xl:space-y-[0.556vw] space-y-2">
|
||||
<p className="text-s opacity-60">Call Center:</p>
|
||||
<Link
|
||||
target="_blank"
|
||||
className="text-s text-[#F47F52]"
|
||||
to="tel:+97444421073"
|
||||
>
|
||||
+974 4442 1073
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Feedback;
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Link } from "react-router";
|
||||
import Button from "../ui/Button";
|
||||
import FacebookIcon from "./icons/FacebookIcon";
|
||||
import YoutubeIcon from "./icons/YoutubeIcon";
|
||||
import InstagramIcon from "./icons/InstagramIcon";
|
||||
import TwitterIcon from "./icons/TwitterIcon";
|
||||
import WhatsappIcon from "./icons/WhatsappIcon";
|
||||
|
||||
function Socials() {
|
||||
return (
|
||||
<div className="md:grid flex flex-col 2xl:grid-cols-2 2xl:gap-[2.222vw] gap-8">
|
||||
<div className="flex 2xl:gap-[0.556vw] gap-2">
|
||||
<Link target="_blank" to="https://google.com">
|
||||
<Button variant="primary" size="small">
|
||||
<div className="2xl:size-[1.111vw] size-4">
|
||||
<FacebookIcon />
|
||||
</div>
|
||||
</Button>
|
||||
</Link>
|
||||
<Link target="_blank" to="/">
|
||||
<Button variant="primary" size="small">
|
||||
<div className="2xl:size-[1.111vw] size-4">
|
||||
<YoutubeIcon />
|
||||
</div>
|
||||
</Button>
|
||||
</Link>
|
||||
<Link target="_blank" to="/">
|
||||
<Button variant="primary" size="small">
|
||||
<div className="2xl:size-[1.111vw] size-4">
|
||||
<InstagramIcon />
|
||||
</div>
|
||||
</Button>
|
||||
</Link>
|
||||
<Link target="_blank" to="/">
|
||||
<Button variant="primary" size="small">
|
||||
<div className="2xl:size-[1.111vw] size-4">
|
||||
<TwitterIcon />
|
||||
</div>
|
||||
</Button>
|
||||
</Link>
|
||||
<Link target="_blank" to="/">
|
||||
<Button variant="primary" size="small">
|
||||
<div className="2xl:size-[1.111vw] size-4">
|
||||
<WhatsappIcon />
|
||||
</div>
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex max-md:flex-col justify-between md:items-center gap-2 md:col-start-2">
|
||||
<Link className="text-s opacity-60" to={"/"}>
|
||||
Terms of Use
|
||||
</Link>
|
||||
<Link className="text-s opacity-60" to={"/"}>
|
||||
Privacy Policy
|
||||
</Link>
|
||||
<Link className="text-s opacity-60" to={"/"}>
|
||||
Copyrights © 2025 Baraha Town
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Socials;
|
||||
@@ -25,13 +25,12 @@ export default function ComunityCard({
|
||||
{icon}
|
||||
</span>
|
||||
<div className="flex flex-col 2xl:gap-[0.556vw] md:gap-[1.042vw] gap-[2.222vw]">
|
||||
<span
|
||||
className="2xl:number md:number h3 font-[font-family:New_York_Large]
|
||||
"
|
||||
>
|
||||
<span className="2xl:number md:number h3 [font-family:New_York_Large] font-medium">
|
||||
{number}
|
||||
</span>
|
||||
<p className="2xl:text-s md:text-s caption font-[Poppins]">{text}</p>
|
||||
<p className="2xl:text-s md:text-s caption font-[Poppins] font-medium max-md:max-w-[90%]">
|
||||
{text}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
function ChevronDownIcon() {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M19.54 8.04a.65.65 0 0 1 .92.92l-8 8a.65.65 0 0 1-.92 0l-8-8a.65.65 0 0 1 .92-.92L12 15.58z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChevronDownIcon;
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,12 @@
|
||||
function InstagramIcon() {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M11.984 4.001c2.173-.004 2.448.005 3.3.042.85.037 1.432.171 1.942.368.526.203.973.476 1.418.92s.72.89.925 1.415c.2.509.335 1.088.375 1.94.04.854.05 1.126.055 3.298s-.005 2.445-.042 3.3c-.037.85-.171 1.432-.368 1.94a3.9 3.9 0 0 1-.92 1.42 3.9 3.9 0 0 1-1.415.925c-.509.199-1.087.335-1.94.375s-1.126.05-3.298.055-2.447-.005-3.298-.042-1.433-.172-1.942-.368a3.9 3.9 0 0 1-1.419-.92 3.9 3.9 0 0 1-.925-1.415c-.2-.508-.336-1.09-.376-1.94-.042-.854-.05-1.126-.055-3.298s.004-2.447.042-3.298c.038-.852.171-1.434.368-1.944a3.9 3.9 0 0 1 .92-1.418c.443-.445.89-.72 1.415-.924.508-.2 1.09-.336 1.94-.376.854-.042 1.126-.05 3.298-.055m.003 1.443c-2.135.005-2.388.013-3.232.053-.78.037-1.203.167-1.484.277a2.5 2.5 0 0 0-.92.601 2.5 2.5 0 0 0-.596.92c-.108.283-.24.707-.273 1.486-.037.844-.044 1.097-.04 3.233.005 2.135.013 2.388.053 3.231.037.78.169 1.203.278 1.486.146.372.319.64.6.918.281.279.547.453.92.597.248.095.603.206 1.21.255l.277.017c.844.036 1.096.045 3.233.04s2.389-.012 3.232-.052c.78-.037 1.203-.169 1.485-.279.373-.145.64-.318.918-.6.28-.28.453-.546.597-.92.109-.283.238-.707.273-1.486.037-.843.043-1.097.04-3.233-.004-2.135-.013-2.388-.053-3.231-.037-.78-.168-1.203-.278-1.485a2.5 2.5 0 0 0-.601-.918 2.5 2.5 0 0 0-.92-.597c-.283-.11-.707-.239-1.486-.273-.844-.037-1.098-.044-3.233-.04m.005 2.449a4.108 4.108 0 1 1 .017 8.216 4.108 4.108 0 0 1-.017-8.216m.523 1.49a2.667 2.667 0 1 0-1.028 5.234 2.667 2.667 0 0 0 1.028-5.234m3.745-2.62a.962.962 0 0 1 .682 1.637.961.961 0 1 1-.682-1.637"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default InstagramIcon;
|
||||
@@ -0,0 +1,12 @@
|
||||
function TwitterIcon() {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="m12.542 9.66 3.766-4.16h2.289l-5 5.518L19.5 18.5h-4.639l-3.614-4.535L7.091 18.5H4.8l5.362-5.894L4.5 5.5h4.759zm2.952 7.51h1.265L8.566 6.743H7.181z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default TwitterIcon;
|
||||
@@ -0,0 +1,12 @@
|
||||
function WhatsappIcon() {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M12.033 4a7.93 7.93 0 0 1 5.636 2.325A7.86 7.86 0 0 1 20 11.935c-.002 4.37-3.576 7.927-7.967 7.927h-.003a8 8 0 0 1-3.806-.964L4 20l1.13-4.11a7.9 7.9 0 0 1-1.064-3.962C4.068 7.557 7.642 4 12.033 4m.003 1.34c-3.652 0-6.622 2.955-6.624 6.589 0 1.245.35 2.457 1.013 3.506l.157.25-.669 2.431 2.506-.654.241.143c1.017.6 2.182.918 3.37.918h.003c3.65 0 6.62-2.956 6.622-6.59a6.54 6.54 0 0 0-1.937-4.662 6.6 6.6 0 0 0-4.682-1.931M9.595 8.273c.122.006.286-.045.447.34.166.397.564 1.372.614 1.471.05.1.083.216.017.348s-.1.214-.2.33c-.099.115-.208.259-.297.347-.1.1-.204.206-.088.405.116.198.516.847 1.107 1.372.76.675 1.402.884 1.6.983.2.1.317.083.432-.05a11 11 0 0 0 .63-.776c.133-.198.265-.166.448-.1.182.067 1.16.545 1.36.645v-.001c.199.1.331.149.38.231.05.083.051.48-.114.943-.166.463-.962.884-1.344.941a2.74 2.74 0 0 1-1.254-.078c-.29-.091-.66-.213-1.135-.417-1.997-.858-3.3-2.86-3.4-2.991-.1-.133-.812-1.074-.813-2.049s.514-1.455.697-1.653a.73.73 0 0 1 .53-.248c.134 0 .267.001.383.007"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default WhatsappIcon;
|
||||
@@ -0,0 +1,12 @@
|
||||
function YoutubeIcon() {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M12 6c.003 0 5.629 0 7.032.358.775.198 1.385.778 1.592 1.516C21 9.211 21 12 21 12s0 2.79-.376 4.126c-.207.738-.817 1.318-1.592 1.516C17.63 18 12.003 18 12 18c0 0-5.628 0-7.032-.358-.775-.198-1.385-.778-1.592-1.516C3 14.789 3 12 3 12s0-2.789.376-4.126c.207-.738.817-1.318 1.592-1.516C6.372 6 12 6 12 6m-1.84 8.532L14.862 12 10.16 9.468z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default YoutubeIcon;
|
||||
@@ -75,7 +75,7 @@ function NavMenu() {
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="md:hidden p-1 space-y-1 rounded-2xl bg-[#F0EDE6] fixed left-1/2 -translate-x-1/2 bottom-[75px] w-[177px]"
|
||||
className="md:hidden p-1 space-y-1 rounded-2xl bg-[#F0EDE6] fixed z-10 left-1/2 -translate-x-1/2 bottom-[75px] w-[177px]"
|
||||
>
|
||||
<MenuLink
|
||||
highlighted={false}
|
||||
|
||||
@@ -12,14 +12,21 @@ import CulinaryExperienceAccordeonContent from "../about/accordeons/CulinaryExpe
|
||||
import CentralPlazaAccordeonContent from "../about/accordeons/CentralPlazaAccordeonContent";
|
||||
import LifestyleLivingAccordeonContent from "../about/accordeons/LifestyleLivingAccordeonContent";
|
||||
import ContemporaryOfficesAccordeonContent from "../about/accordeons/ContemporaryOfficesAccordeonContent";
|
||||
import Feedback from "../Feedback";
|
||||
import Socials from "../Socials";
|
||||
|
||||
export default function About() {
|
||||
export default function AboutPage() {
|
||||
return (
|
||||
<section className="2xl:space-y-[8.333vw] md:space-y-[10.417vw] space-y-[22.222vw] bg-[#F7F6F3]">
|
||||
<AboutHero />
|
||||
<AboutBaraha />
|
||||
<BuildingCommunities />
|
||||
<Accordeons />
|
||||
<div className="2xl:p-[2.778vw_2.778vw_6.667vw] md:p-[24px_24px_96px] p-[16px_16px_88px] !pt-0 2xl:space-y-[2.222vw] space-y-8">
|
||||
<Feedback />
|
||||
<hr className="w-full border-[#ECE8DF] 2xl:border-[0.069vw] border-[1px] col-span-full" />
|
||||
<Socials />
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -122,7 +129,7 @@ function BuildingCommunities() {
|
||||
<ComunityCard
|
||||
icon={<ShopIcon />}
|
||||
number="356"
|
||||
text="Text"
|
||||
text="Retail / F & B stores"
|
||||
className=""
|
||||
/>
|
||||
<ComunityCard
|
||||
|
||||
@@ -1,68 +1,12 @@
|
||||
import { useState } from "react";
|
||||
import Button from "../../ui/Button";
|
||||
import Input from "../../ui/Input";
|
||||
|
||||
const INTERESTS = ["Retail", "Office", "Residential"] as const;
|
||||
import Feedback from "../Feedback";
|
||||
import Socials from "../Socials";
|
||||
|
||||
function ContactsPage() {
|
||||
const [interests, setInterests] = useState<(typeof INTERESTS)[number][]>([]);
|
||||
|
||||
function handleInterestClick(interest: (typeof INTERESTS)[number]) {
|
||||
if (interests.includes(interest)) {
|
||||
setInterests((prev) => prev.filter((i) => i !== interest));
|
||||
} else {
|
||||
setInterests((prev) => [...prev, interest]);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="2xl:p-[2.778vw_2.778vw_6.667vw] md:p-[24px_24px_96px] p-[16px_16px_88px]">
|
||||
<div className="2xl:grid grid-cols-2 2xl:gap-[1.111vw]">
|
||||
<h2 className="2xl:h2 md:h3 text-2xl max-md:leading-[110%] md:max-2xl:max-w-[63.021vw] max-md:max-w-[328px] [font-family:New_York_Medium]">
|
||||
Enquire about joining this thriving community at the heart
|
||||
of Abu Hamour by contacting a member of our sales team today
|
||||
</h2>
|
||||
<form className="2xl:space-y-[1.667vw] space-y-6">
|
||||
<Input
|
||||
label="Full Name"
|
||||
id="fullname"
|
||||
placeholder="Enter your full name"
|
||||
/>
|
||||
<div className="flex 2xl:gap-[1.667vw]">
|
||||
<Input label="Email" id="email" placeholder="Enter your email" />
|
||||
<Input
|
||||
label="Phone Number"
|
||||
id="phone"
|
||||
placeholder="Enter your phone number"
|
||||
/>
|
||||
</div>
|
||||
<div className="2xl:space-y-[0.833vw] space-y-3">
|
||||
<p className="text-m">What are you interested in?</p>
|
||||
<div className="flex 2xl:gap-[0.833vw] gap-3">
|
||||
{INTERESTS.map((interest) => (
|
||||
<Button
|
||||
variant={interests.includes(interest) ? "cta" : "primary"}
|
||||
size="large"
|
||||
type="button"
|
||||
onClick={() => handleInterestClick(interest)}
|
||||
>
|
||||
{interest}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<Input
|
||||
label="Message"
|
||||
id="message"
|
||||
placeholder="Enter your message here"
|
||||
isTextArea
|
||||
maxLength={180}
|
||||
/>
|
||||
<Button variant="cta" size="large" type="submit" className="w-full">
|
||||
Send Message
|
||||
</Button>
|
||||
</form>
|
||||
</div>
|
||||
<div className="2xl:p-[2.778vw_2.778vw_6.667vw] md:p-[24px_24px_96px] p-[16px_16px_88px] 2xl:space-y-[2.222vw] space-y-8">
|
||||
<Feedback />
|
||||
<hr className="w-full border-[#ECE8DF] 2xl:border-[0.069vw] border-[1px] col-span-full" />
|
||||
<Socials />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
+8
-8
@@ -10,19 +10,19 @@ body {
|
||||
|
||||
@layer utilities {
|
||||
.button-l {
|
||||
@apply 2xl:text-[1.111vw] text-base leading-[115%] tracking-[-4%];
|
||||
@apply 2xl:text-[1.111vw] text-base leading-[115%];
|
||||
}
|
||||
|
||||
.button-m {
|
||||
@apply 2xl:text-[0.972vw] text-sm leading-[115%] tracking-[-4%];
|
||||
@apply 2xl:text-[0.972vw] text-sm leading-[115%];
|
||||
}
|
||||
|
||||
.button-s {
|
||||
@apply 2xl:text-[0.833vw] text-xs leading-[115%] tracking-[-4%];
|
||||
@apply 2xl:text-[0.833vw] text-xs leading-[115%];
|
||||
}
|
||||
|
||||
.h1 {
|
||||
@apply 2xl:text-[5.556vw] md:text-[10.417vw] text-[22.222vw] leading-[90%] tracking-[-4%];
|
||||
@apply 2xl:text-[5.556vw] md:text-[10.417vw] text-[22.222vw] leading-[90%];
|
||||
}
|
||||
|
||||
.h2 {
|
||||
@@ -30,19 +30,19 @@ body {
|
||||
}
|
||||
|
||||
.h3 {
|
||||
@apply 2xl:text-[2.222vw] md:text-[4.167vw] text-[8.889vw] leading-[110%] tracking-[-4%];
|
||||
@apply 2xl:text-[2.222vw] md:text-[4.167vw] text-[8.889vw] leading-[110%];
|
||||
}
|
||||
|
||||
.number {
|
||||
@apply 2xl:text-[4.444vw] md:text-[8.333vw] text-[8.889vw] md:leading-[100%] leading-[110%] tracking-[-4%];
|
||||
@apply 2xl:text-[4.444vw] text-[64px] md:leading-[100%] leading-[110%];
|
||||
}
|
||||
|
||||
.text-m {
|
||||
@apply 2xl:text-[1.111vw] md:text-[2.083vw] text-[4.444vw] 2xl:leading-[120%] leading-[130%] tracking-[-4%];
|
||||
@apply 2xl:text-[1.111vw] text-base 2xl:leading-[120%] leading-[130%];
|
||||
}
|
||||
|
||||
.text-s {
|
||||
@apply 2xl:text-[0.972vw] md:text-[1.823vw] text-[3.889vw] leading-[130%] tracking-[-4%];
|
||||
@apply 2xl:text-[0.972vw] text-sm leading-[130%];
|
||||
}
|
||||
|
||||
.caption {
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ import { createRoot } from "react-dom/client";
|
||||
import "./index.css";
|
||||
import { createBrowserRouter, RouterProvider } from "react-router";
|
||||
import DefaultLayout from "./components/layouts/DefaultLayout.tsx";
|
||||
import About from "./components/pages/AboutPage.tsx";
|
||||
import AboutPage from "./components/pages/AboutPage.tsx";
|
||||
import ContactsPage from "./components/pages/ContactsPage.tsx";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
@@ -19,7 +19,7 @@ const router = createBrowserRouter([
|
||||
},
|
||||
{
|
||||
path: "/about",
|
||||
element: <About />,
|
||||
element: <AboutPage />,
|
||||
},
|
||||
{
|
||||
path: "/contacts",
|
||||
|
||||
+85
-6
@@ -1,6 +1,23 @@
|
||||
import InputMask from "@mona-health/react-input-mask";
|
||||
import clsx from "clsx";
|
||||
import { useState } from "react";
|
||||
import ChevronDownIcon from "../components/icons/ChevronDownIcon";
|
||||
import Button from "./Button";
|
||||
import { useClickAway } from "@uidotdev/usehooks";
|
||||
|
||||
interface CountryCode {
|
||||
code: string;
|
||||
mask: string;
|
||||
flag: string;
|
||||
}
|
||||
|
||||
const COUNTRY_CODES: CountryCode[] = [
|
||||
{ code: "+974", mask: "9999 9999", flag: "🇶🇦" },
|
||||
{ code: "+971", mask: "99 999 9999", flag: "🇦🇪" },
|
||||
{ code: "+1", mask: "999 999 99 99", flag: "🇺🇸" },
|
||||
{ code: "+44", mask: "9999 999999", flag: "🇬🇧" },
|
||||
{ code: "+7", mask: "999 999 99 99", flag: "🇷🇺" },
|
||||
];
|
||||
|
||||
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
label: string;
|
||||
@@ -19,12 +36,20 @@ function Input({
|
||||
mask,
|
||||
isTextArea = false,
|
||||
maxLength,
|
||||
type,
|
||||
...props
|
||||
}: InputProps) {
|
||||
const [textValue, setTextValue] = useState("");
|
||||
const [selectedCountry, setSelectedCountry] = useState(0);
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||
|
||||
const ref = useClickAway<HTMLDivElement>(() => setIsDropdownOpen(false));
|
||||
|
||||
const isPhoneInput = type === "tel";
|
||||
const currentMask = isPhoneInput ? COUNTRY_CODES[selectedCountry].mask : mask;
|
||||
|
||||
return (
|
||||
<div className="2xl:space-y-[0.833vw] space-y-3">
|
||||
<div className="2xl:space-y-[0.833vw] space-y-3 w-full">
|
||||
<label htmlFor={id} className="text-m select-none">
|
||||
{label}
|
||||
</label>
|
||||
@@ -48,14 +73,68 @@ function Input({
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<InputMask mask={mask}>
|
||||
<input
|
||||
type="text"
|
||||
) : isPhoneInput ? (
|
||||
<div
|
||||
className={clsx(
|
||||
"flex items-center bg-[#F0EDE6] 2xl:rounded-[0.833vw] rounded-xl 2xl:ring-[0.069vw] ring-1 ring-transparent transition-[box-shadow] 2xl:py-[0.278vw] py-1 2xl:pr-[1.389vw] pr-5 2xl:pl-[0.278vw] pl-1 focus-within:ring-[#F47F52]",
|
||||
isError && "ring-[#E12E25]"
|
||||
)}
|
||||
>
|
||||
<div className="relative">
|
||||
<Button
|
||||
variant="primary"
|
||||
type="button"
|
||||
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
|
||||
className="flex items-center 2xl:gap-[0.417vw] gap-1.5 2xl:px-[0.833vw] px-3 2xl:py-[0.833vw] py-3 hover:bg-black hover:bg-opacity-5 2xl:rounded-[0.833vw] rounded-xl transition-colors"
|
||||
>
|
||||
{COUNTRY_CODES[selectedCountry].code}
|
||||
<div className="2xl:size-[1.111vw] size-4">
|
||||
<ChevronDownIcon />
|
||||
</div>
|
||||
</Button>
|
||||
{isDropdownOpen && (
|
||||
<div
|
||||
ref={ref}
|
||||
className="absolute top-full left-0 mt-1 bg-[#F0EDE6] 2xl:rounded-[0.833vw] rounded-xl shadow-lg z-20 2xl:p-[0.278vw] p-1 2xl:space-y-[0.278vw] space-y-1 min-w-[120px]"
|
||||
>
|
||||
{COUNTRY_CODES.map((country, index) => (
|
||||
<Button
|
||||
key={country.code}
|
||||
variant="primary"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setSelectedCountry(index);
|
||||
setIsDropdownOpen(false);
|
||||
}}
|
||||
className={clsx(
|
||||
"w-full flex items-center 2xl:gap-[0.556vw] gap-2 2xl:px-[0.833vw] px-3 2xl:py-[0.556vw] py-2 hover:bg-black hover:bg-opacity-5 transition-colors text-left button-m",
|
||||
index === selectedCountry && "bg-black bg-opacity-5"
|
||||
)}
|
||||
>
|
||||
<span>{country.flag}</span>
|
||||
<span>{country.code}</span>
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<InputMask
|
||||
mask={currentMask}
|
||||
{...props}
|
||||
id={id}
|
||||
alwaysShowMask
|
||||
placeholder={currentMask}
|
||||
className="bg-transparent text-m flex-1 placeholder:text-m outline-none placeholder:text-opacity-60"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<InputMask mask={currentMask}>
|
||||
<input
|
||||
{...props}
|
||||
type={type}
|
||||
id={id}
|
||||
className={clsx(
|
||||
"bg-[#F0EDE6] text-m placeholder:text-m outline-none transition-[box-shadow] placeholder:text-opacity-60 2xl:rounded-[0.833vw] rounded-xl 2xl:px-[1.389vw] 2xl:ring-[0.069vw] ring-1 px-5 2xl:py-[1.007vw] ring-transparent py-[14.5px] focus:!ring-[#F47F52]",
|
||||
"bg-[#F0EDE6] text-m w-full placeholder:text-m outline-none transition-[box-shadow] placeholder:text-opacity-60 2xl:rounded-[0.833vw] rounded-xl 2xl:px-[1.389vw] 2xl:ring-[0.069vw] ring-1 px-5 2xl:py-[1.007vw] ring-transparent py-[14.5px] focus:!ring-[#F47F52]",
|
||||
isError && "ring-[#E12E25]"
|
||||
)}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user