Finished styling the Contact component

This commit is contained in:
zahravaziri
2025-06-05 17:00:07 +03:30
parent d44aa203e0
commit 7065279807
11 changed files with 296 additions and 118 deletions
+35 -115
View File
@@ -1,124 +1,44 @@
import Button from '@/components/uikit/button';
import Head from 'next/head';
import images from '@/assets/images/images';
import InnerPageBanner from '@/components/layout/innerPages/banner';
import ContactMap from '@/components/layout/map';
import ContactForm from '@/components/pages/contact/ContactMeForm';
import TouchUs from '@/components/pages/contact/TouchUs';
import { t } from '@/locales/translates';
import Image from 'next/image';
async function getData() {
await new Promise((resolve) => setTimeout(resolve, 1000));
return { message: 'This data was fetched on the server!' };
}
export default async function Contact() {
const data = await getData();
export default function Contact() {
return (
<div className="flex flex-col items-center justify-center bg-gray-100 px-4 pt-8">
<div className="e flex w-full max-w-5xl flex-col overflow-hidden rounded-lg md:flex-row">
<div className="w-full p-8 md:w-1/2">
<h1 className="mb-4 text-3xl font-bold text-gray-800">
Get in touch with us
</h1>
<p className="mb-6 text-gray-600">
Reach out for any inquiries, support, or feedbackwed love to hear
from you!
</p>
<main className="flex flex-col items-center justify-between">
<InnerPageBanner
title={t('pages_contact_title') as string}
imageSrc={images.blogBanner.src}
/>
<div className="flex flex-col justify-between space-y-4">
<div className="flex items-center">
<div className="mr-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500">
<svg
className="h-6 w-6 text-white"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"
></path>
</svg>
</div>
<div>
<h3 className="font-semibold text-gray-800">Contact</h3>
<p className="text-gray-600">+44 (0) 20 1234 5678</p>
</div>
</div>
<div className="flex items-center">
<div className="mr-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500">
<svg
className="h-6 w-6 text-white"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M16 12h2a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v4a2 2 0 002 2h2m8 0H8m8 0a4 4 0 01-4 4H8m0-8v8m0-8H6a2 2 0 00-2 2v4a2 2 0 002 2h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2"
></path>
</svg>
</div>
<div>
<h3 className="font-semibold text-gray-800">Email</h3>
<p className="text-gray-600">support@mybusiness.com</p>
</div>
</div>
<div className="flex items-center">
<div className="mr-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500">
<svg
className="h-6 w-6 text-white"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M17.657 16.657L12 21.314l-5.657-5.657a8 8 0 1111.314 0zM12 14a2 2 0 100-4 2 2 0 000 4z"
></path>
</svg>
</div>
<div>
<h3 className="font-semibold text-gray-800">Our Address</h3>
<p className="text-gray-600">
123 Business Street, London EC1A 1BB, UK
</p>
</div>
</div>
</div>
<div className="flex w-full flex-col bg-gray-200 pt-4 md:pt-28">
<div className="relative container mx-auto flex w-full flex-col items-stretch overflow-hidden rounded-lg md:flex-row">
<TouchUs />
<ContactForm />
</div>
<div className="w-full rounded-4xl bg-white p-4 md:w-1/2">
<h2 className="mb-6 text-2xl font-bold text-gray-800">Contact me</h2>
<div className="space-y-4">
<input
type="text"
placeholder="Enter your name"
className="w-full rounded-lg border border-gray-300 p-3 focus:ring-2 focus:ring-red-500 focus:outline-none"
/>
<input
type="email"
placeholder="Enter your email"
className="w-full rounded-lg border border-gray-300 p-3 focus:ring-2 focus:ring-red-500 focus:outline-none"
/>
<input
type="tel"
placeholder="Enter your phone"
className="w-full rounded-lg border border-gray-300 p-3 focus:ring-2 focus:ring-red-500 focus:outline-none"
/>
<textarea
placeholder="Write your message"
className="h-32 w-full resize-none rounded-lg border border-gray-300 p-3 focus:ring-2 focus:ring-red-500 focus:outline-none"
></textarea>
<Button className="w-full">Submit Message</Button>
<div className="absolute -bottom-[17.32rem] w-1/2 max-md:hidden md:w-2/5">
<Image
alt="footer-bg"
src={images.factoryVector}
className="h-full w-full object-cover"
/>
</div>
<div className="mt-4 w-full md:mt-28">
<div className="h-64 w-full overflow-hidden rounded-lg bg-gray-200">
<ContactMap />
</div>
</div>
</div>
<div className="mt-4 w-full max-w-5xl">
<div className="h-64 w-full overflow-hidden rounded-lg bg-gray-200"></div>
</div>
</div>
</main>
);
}
+1
View File
@@ -1,6 +1,7 @@
import Footer from '@/components/layout/footer/Footer';
import './globals.css';
import { cookies } from 'next/headers';
import 'leaflet/dist/leaflet.css';
// export const metadata: Metadata = {
// title: 'Create Next App',
+40
View File
@@ -0,0 +1,40 @@
'use client';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
delete (L.Icon.Default.prototype as any)._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl:
'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png',
iconUrl:
'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png',
shadowUrl:
'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png',
});
const ContactMap = () => {
const position: [number, number] = [35.800081, 51.433882];
return (
<div className="h-[400px] w-full overflow-hidden rounded-lg">
<MapContainer
center={position}
zoom={15}
scrollWheelZoom={false}
style={{ height: '100%', width: '100%' }}
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={position}>
<Popup>lastminute.com London Eye</Popup>
</Marker>
</MapContainer>
</div>
);
};
export default ContactMap;
@@ -0,0 +1,22 @@
import Button from '@/components/uikit/button';
import FormField from '@/components/uikit/inputs';
const ContactForm = () => {
return (
<div className="w-full rounded-4xl bg-white p-4 md:w-1/2">
<h2 className="mb-6 text-5xl text-gray-800">
Contact <span className="text-5xl max-md:font-bold"> me</span>
</h2>
<div className="space-y-4">
<FormField type="text" placeholder="Enter your name" />
<FormField type="email" placeholder="Enter your email" />
<FormField type="tel" placeholder="Enter your phone" />
<FormField type="textarea" placeholder="Write your message" />
<Button className="w-full">Submit Message</Button>
</div>
</div>
);
};
export default ContactForm;
+54
View File
@@ -0,0 +1,54 @@
import { Icon } from '@/components/uikit/icons';
const TouchUs = () => {
return (
<div className="w-full p-8 md:w-1/2">
<h1 className="mb-4 text-3xl font-light text-gray-800 md:text-5xl">
Get in touch{' '}
<span className="text-3xl font-light md:text-5xl md:font-bold">
with us
</span>
</h1>
<p className="mb-6 text-base font-normal text-gray-600">
Reach out for any inquiries, support, or feedbackwed love to hear from
you!
</p>
<div className="flex flex-col justify-between space-y-4">
<div className="flex items-center">
<div className="mr-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500">
<Icon name="phone" className="text-white" />
</div>
<div>
<h3 className="font-semibold text-gray-800">Contact</h3>
<p className="text-gray-600">+44 (0) 20 1234 5678</p>
</div>
</div>
<div className="flex items-center">
<div className="mr-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500">
<Icon name="email" className="text-white" />
</div>
<div>
<h3 className="font-semibold text-gray-800">Email</h3>
<p className="text-gray-600">support@mybusiness.com</p>
</div>
</div>
<div className="flex items-center">
<div className="mr-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500">
<Icon name="location" className="text-white" />
</div>
<div>
<h3 className="font-semibold text-gray-800">Our Address</h3>
<p className="text-gray-600">
123 Business Street, London EC1A 1BB, UK
</p>
</div>
</div>
</div>
</div>
);
};
export default TouchUs;
+19
View File
@@ -0,0 +1,19 @@
export const EmailIcon = (props: React.SVGProps<SVGSVGElement>) => (
<svg
width="30"
height="31"
viewBox="0 0 30 31"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M24.5077 4.43604C21.9419 4.43604 19.7814 6.20463 19.1812 8.58676H2.19469C1.62064 8.58676 1.07824 8.80678 0.666211 9.20657L0.664922 9.2078L0.660762 9.21178C0.234668 9.62827 0 10.1857 0 10.7814V24.9747C0 25.5792 0.253008 26.1627 0.693984 26.5756L0.696621 26.5781C1.10455 26.9594 1.63652 27.1694 2.19469 27.1694H22.899C23.4554 27.1694 23.9858 26.9608 24.393 26.5819C24.396 26.5793 24.3988 26.5766 24.4017 26.5738C24.8415 26.1607 25.0936 25.5782 25.0936 24.9747V15.3896C27.8477 15.0962 30 12.7589 30 9.92833C30 6.89991 27.5362 4.43604 24.5077 4.43604ZM2.19469 9.75864H19.0181C19.0164 9.815 19.0155 9.87155 19.0155 9.92833C19.0155 10.9777 19.3113 11.9592 19.8239 12.794L12.9298 19.3109H12.1639L2.06695 9.76649C2.10902 9.76127 2.15168 9.75864 2.19469 9.75864ZM1.17188 10.7814C1.17188 10.7047 1.18025 10.6294 1.19654 10.5564L9.40494 18.3156L1.21734 25.2775C1.18764 25.1809 1.17188 25.0793 1.17188 24.9747V10.7814ZM22.899 25.9975H2.19469C2.18988 25.9975 2.1852 25.9969 2.18045 25.9968L10.2616 19.1254L11.5283 20.3227C11.6371 20.4256 11.7812 20.4828 11.9309 20.4828H13.1629C13.3126 20.4828 13.4566 20.4255 13.5654 20.3227L14.8321 19.1254L22.9139 25.9974C22.9089 25.9974 22.9039 25.9975 22.899 25.9975ZM23.9218 24.9747C23.9218 25.0793 23.9064 25.1811 23.8766 25.2777L15.6887 18.3155L20.5437 13.7262C21.4169 14.6372 22.6 15.2488 23.9218 15.3896V24.9747ZM24.5077 14.2488C22.1254 14.2488 20.1873 12.3106 20.1873 9.92833C20.1873 7.54602 22.1254 5.60792 24.5077 5.60792C26.89 5.60792 28.8281 7.54602 28.8281 9.92833C28.8281 12.3106 26.89 14.2488 24.5077 14.2488Z"
fill="currentColor"
/>
<path
d="M24.7045 8.05176H24.0781C23.7545 8.05176 23.4922 8.31415 23.4922 8.6377C23.4922 8.96125 23.7545 9.22364 24.0781 9.22364H24.1186V11.5669C24.1186 11.8904 24.3809 12.1528 24.7045 12.1528C25.0281 12.1528 25.2904 11.8904 25.2904 11.5669V8.6377C25.2904 8.31409 25.0281 8.05176 24.7045 8.05176Z"
fill="currentColor"
/>
</svg>
);
+4 -1
View File
@@ -10,7 +10,8 @@ import CategoryGhazaghiIcon from './categoryGhazaghiIcon';
import CategoryGhermezIcon from './categoryGhermezIcon';
import categorySemiromIcon from './categorySemiromIcon';
import CategoryZardIcon from './categoryZardIcon';
import { LocationIcon } from './locationIcon';
import { EmailIcon } from './emailIcon';
export const icons = {
close: CloseIcon,
menu: MenuIcon,
@@ -19,6 +20,8 @@ export const icons = {
phone: PhoneIcon,
instagram: InstagramIcon,
showMore: ShowMoreIcon,
location: LocationIcon,
email: EmailIcon,
categoryGhazaghi: CategoryGhazaghiIcon,
categoryGhermez: CategoryGhermezIcon,
categorySemirom: categorySemiromIcon,
@@ -0,0 +1,35 @@
export const LocationIcon = (props: React.SVGProps<SVGSVGElement>) => (
<svg
width="30"
height="31"
viewBox="0 0 30 31"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<mask
id="mask0_4069_10756"
// style="mask-type:luminance"
maskUnits="userSpaceOnUse"
x="0"
y="1"
width="30"
height="30"
>
<path
d="M29.5166 1.28662H0.484375V30.3189H29.5166V1.28662Z"
fill="currentColor"
/>
</mask>
<g mask="url(#mask0_4069_10756)">
<path
d="M15.0006 1.51367C8.87239 1.51367 3.88672 6.49934 3.88672 12.6276C3.88672 15.6046 5.6903 19.4274 9.24731 23.9898C10.877 26.0746 12.6418 28.0501 14.5303 29.9036C14.657 30.0247 14.8254 30.0922 15.0006 30.0922C15.1759 30.0922 15.3443 30.0247 15.471 29.9036C17.3595 28.0501 19.1243 26.0746 20.754 23.9898C24.311 19.4274 26.1146 15.6046 26.1146 12.6276C26.1146 6.49934 21.1289 1.51367 15.0006 1.51367ZM15.0006 28.4542C12.9923 26.4297 5.24762 18.2565 5.24762 12.6276C5.24762 7.24975 9.62281 2.87455 15.0006 2.87455C20.3785 2.87455 24.7536 7.24975 24.7536 12.6276C24.7536 18.2565 17.009 26.4297 15.0006 28.4542Z"
fill="currentColor"
/>
<path
d="M20.45 11.6703L15.46 7.13399C15.3348 7.02013 15.1717 6.95703 15.0024 6.95703C14.8331 6.95703 14.6699 7.02013 14.5447 7.13399L9.55474 11.6703C9.45313 11.7626 9.38185 11.8836 9.35027 12.0173C9.31868 12.1509 9.32829 12.291 9.37781 12.4192C9.42733 12.5472 9.51446 12.6573 9.62773 12.7349C9.741 12.8126 9.87512 12.8542 10.0125 12.8542H10.6929V16.2564C10.6929 16.4368 10.7646 16.61 10.8922 16.7375C11.0198 16.8652 11.1929 16.9369 11.3734 16.9369H13.8683C14.0488 16.9369 14.2218 16.8652 14.3495 16.7375C14.477 16.61 14.5487 16.4368 14.5487 16.2564V14.2151H15.456V16.2564C15.456 16.4368 15.5277 16.61 15.6553 16.7375C15.7829 16.8652 15.956 16.9369 16.1365 16.9369H18.6314C18.8119 16.9369 18.9849 16.8652 19.1126 16.7375C19.2401 16.61 19.3118 16.4368 19.3118 16.2564V12.8542H19.9923C20.1296 12.8542 20.2637 12.8126 20.377 12.7349C20.4903 12.6573 20.5775 12.5472 20.6269 12.4192C20.6765 12.291 20.686 12.1509 20.6545 12.0173C20.6229 11.8836 20.5516 11.7626 20.45 11.6703ZM17.951 12.1737V15.5759H16.8169V13.5347C16.8169 13.3542 16.7452 13.1811 16.6176 13.0535C16.49 12.9259 16.3169 12.8542 16.1365 12.8542H13.8683C13.6878 12.8542 13.5148 12.9259 13.3871 13.0535C13.2596 13.1811 13.1879 13.3542 13.1879 13.5347V15.5759H12.0538V12.1737C12.0538 12.0493 12.0197 11.9273 11.9552 11.8208C11.8907 11.7145 11.7982 11.6277 11.6879 11.5702L15.0024 8.55702L18.3169 11.5702C18.2065 11.6277 18.1141 11.7145 18.0495 11.8208C17.9851 11.9273 17.9509 12.0493 17.951 12.1737Z"
fill="currentColor"
/>
</g>
</svg>
);
+49
View File
@@ -0,0 +1,49 @@
import React from 'react';
type FieldType = 'text' | 'email' | 'tel' | 'number' | 'textarea';
interface FormFieldProps {
type: FieldType;
placeholder?: string;
value?: string;
onChange?: (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => void;
name?: string;
}
const FormField: React.FC<FormFieldProps> = ({
type,
placeholder,
value,
onChange,
name,
}) => {
const commonClass =
'w-full rounded-lg border border-gray-300 p-3 focus:ring-2 focus:ring-red-500 focus:outline-none';
if (type === 'textarea') {
return (
<textarea
name={name}
placeholder={placeholder}
value={value}
onChange={onChange}
className={`h-32 resize-none ${commonClass}`}
/>
);
}
return (
<input
type={type}
name={name}
placeholder={placeholder}
value={value}
onChange={onChange}
className={commonClass}
/>
);
};
export default FormField;