From 706527980780df9badb073aeb690274b0f0adfb6 Mon Sep 17 00:00:00 2001 From: zahravaziri Date: Thu, 5 Jun 2025 17:00:07 +0330 Subject: [PATCH] Finished styling the Contact component --- package-lock.json | 35 +++- package.json | 4 +- src/app/contact-us/page.tsx | 150 ++++-------------- src/app/layout.tsx | 1 + src/components/layout/map/index.tsx | 40 +++++ .../pages/contact/ContactMeForm.tsx | 22 +++ src/components/pages/contact/TouchUs.tsx | 54 +++++++ src/components/uikit/icons/emailIcon.tsx | 19 +++ src/components/uikit/icons/index.tsx | 5 +- src/components/uikit/icons/locationIcon.tsx | 35 ++++ src/components/uikit/inputs/index.tsx | 49 ++++++ 11 files changed, 296 insertions(+), 118 deletions(-) create mode 100644 src/components/layout/map/index.tsx create mode 100644 src/components/pages/contact/ContactMeForm.tsx create mode 100644 src/components/pages/contact/TouchUs.tsx create mode 100644 src/components/uikit/icons/emailIcon.tsx create mode 100644 src/components/uikit/icons/locationIcon.tsx create mode 100644 src/components/uikit/inputs/index.tsx diff --git a/package-lock.json b/package-lock.json index 2a58f62..3b96c41 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,11 @@ "version": "0.1.0", "dependencies": { "axios": "^1.9.0", + "leaflet": "^1.9.4", "next": "15.3.3", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "react-leaflet": "^5.0.0" }, "devDependencies": { "@eslint/eslintrc": "^3", @@ -914,6 +916,17 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@react-leaflet/core": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz", + "integrity": "sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ==", + "license": "Hippocratic-2.1", + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -4023,6 +4036,12 @@ "node": ">=0.10" } }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "license": "BSD-2-Clause" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4989,6 +5008,20 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, + "node_modules/react-leaflet": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz", + "integrity": "sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw==", + "license": "Hippocratic-2.1", + "dependencies": { + "@react-leaflet/core": "^3.0.0" + }, + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", diff --git a/package.json b/package.json index 1a89825..e9b6247 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,11 @@ }, "dependencies": { "axios": "^1.9.0", + "leaflet": "^1.9.4", "next": "15.3.3", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "react-leaflet": "^5.0.0" }, "devDependencies": { "@eslint/eslintrc": "^3", diff --git a/src/app/contact-us/page.tsx b/src/app/contact-us/page.tsx index 13e9fc1..98ca9ba 100644 --- a/src/app/contact-us/page.tsx +++ b/src/app/contact-us/page.tsx @@ -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 ( -
-
-
-

- Get in touch with us -

-

- Reach out for any inquiries, support, or feedback—we’d love to hear - from you! -

+
+ -
-
-
- - - -
-
-

Contact

-

+44 (0) 20 1234 5678

-
-
- -
-
- - - -
-
-

Email

-

support@mybusiness.com

-
-
- -
-
- - - -
-
-

Our Address

-

- 123 Business Street, London EC1A 1BB, UK -

-
-
-
+
+
+ +
- -
-

Contact me

-
- - - - - - +
+ footer-bg +
+
+
+
- -
-
-
-
+
); } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b5ba582..3d8d2b4 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -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', diff --git a/src/components/layout/map/index.tsx b/src/components/layout/map/index.tsx new file mode 100644 index 0000000..a9045e8 --- /dev/null +++ b/src/components/layout/map/index.tsx @@ -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 ( +
+ + + + lastminute.com London Eye + + +
+ ); +}; + +export default ContactMap; diff --git a/src/components/pages/contact/ContactMeForm.tsx b/src/components/pages/contact/ContactMeForm.tsx new file mode 100644 index 0000000..e2b6dde --- /dev/null +++ b/src/components/pages/contact/ContactMeForm.tsx @@ -0,0 +1,22 @@ +import Button from '@/components/uikit/button'; +import FormField from '@/components/uikit/inputs'; + +const ContactForm = () => { + return ( +
+

+ Contact me +

+
+ + + + + + +
+
+ ); +}; + +export default ContactForm; diff --git a/src/components/pages/contact/TouchUs.tsx b/src/components/pages/contact/TouchUs.tsx new file mode 100644 index 0000000..50d219c --- /dev/null +++ b/src/components/pages/contact/TouchUs.tsx @@ -0,0 +1,54 @@ +import { Icon } from '@/components/uikit/icons'; + +const TouchUs = () => { + return ( +
+

+ Get in touch{' '} + + with us + +

+

+ Reach out for any inquiries, support, or feedback—we’d love to hear from + you! +

+ +
+
+
+ +
+
+

Contact

+

+44 (0) 20 1234 5678

+
+
+ +
+
+ +
+
+

Email

+

support@mybusiness.com

+
+
+ +
+
+ +
+
+

Our Address

+

+ 123 Business Street, London EC1A 1BB, UK +

+
+
+
+
+ ); +}; + +export default TouchUs; diff --git a/src/components/uikit/icons/emailIcon.tsx b/src/components/uikit/icons/emailIcon.tsx new file mode 100644 index 0000000..ab73fef --- /dev/null +++ b/src/components/uikit/icons/emailIcon.tsx @@ -0,0 +1,19 @@ +export const EmailIcon = (props: React.SVGProps) => ( + + + + +); diff --git a/src/components/uikit/icons/index.tsx b/src/components/uikit/icons/index.tsx index 6565ad9..e580736 100644 --- a/src/components/uikit/icons/index.tsx +++ b/src/components/uikit/icons/index.tsx @@ -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, diff --git a/src/components/uikit/icons/locationIcon.tsx b/src/components/uikit/icons/locationIcon.tsx new file mode 100644 index 0000000..0249a88 --- /dev/null +++ b/src/components/uikit/icons/locationIcon.tsx @@ -0,0 +1,35 @@ +export const LocationIcon = (props: React.SVGProps) => ( + + + + + + + + + +); diff --git a/src/components/uikit/inputs/index.tsx b/src/components/uikit/inputs/index.tsx new file mode 100644 index 0000000..ec1f15c --- /dev/null +++ b/src/components/uikit/inputs/index.tsx @@ -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, + ) => void; + name?: string; +} + +const FormField: React.FC = ({ + 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 ( +