diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..c530a17
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,25 @@
+name: Lint
+on:
+ push:
+ branches: ["main"]
+ pull_request:
+ workflow_dispatch:
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4.2.1
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+
+ - name: Install Dependencies
+ run: npm i
+
+ - name: Prettier
+ run: npm run prettier:check
+
+ - name: Lint
+ run: npm run lint
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1 @@
+{}
diff --git a/package-lock.json b/package-lock.json
index 2110291..79e0bd5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"name": "doctor-man",
"version": "0.1.0",
"dependencies": {
+ "clsx": "^2.1.1",
"next": "14.2.20",
"react": "^18",
"react-dom": "^18"
@@ -18,9 +19,56 @@
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.20",
+ "postcss": "^8.4.49",
+ "postcss-nesting": "^13.0.1",
+ "prettier": "^3.4.2",
"typescript": "^5"
}
},
+ "node_modules/@csstools/selector-resolve-nested": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz",
+ "integrity": "sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.0.0"
+ }
+ },
+ "node_modules/@csstools/selector-specificity": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz",
+ "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.0.0"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
@@ -1042,6 +1090,14 @@
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
},
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -1080,6 +1136,18 @@
"node": ">= 8"
}
},
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@@ -3051,6 +3119,33 @@
}
}
},
+ "node_modules/next/node_modules/postcss": {
+ "version": "8.4.31",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -3306,9 +3401,10 @@
}
},
"node_modules/postcss": {
- "version": "8.4.31",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
- "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "version": "8.4.49",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
+ "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -3324,14 +3420,54 @@
}
],
"dependencies": {
- "nanoid": "^3.3.6",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/postcss-nesting": {
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz",
+ "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "dependencies": {
+ "@csstools/selector-resolve-nested": "^3.0.0",
+ "@csstools/selector-specificity": "^5.0.0",
+ "postcss-selector-parser": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz",
+ "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==",
+ "dev": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -3341,6 +3477,21 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/prettier": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
+ "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@@ -4230,6 +4381,12 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
diff --git a/package.json b/package.json
index 2fb8b93..5573408 100644
--- a/package.json
+++ b/package.json
@@ -6,19 +6,25 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
- "lint": "next lint"
+ "lint": "next lint",
+ "prettier:check": "prettier . --check",
+ "prettier:fix": "prettier . --write"
},
"dependencies": {
+ "clsx": "^2.1.1",
+ "next": "14.2.20",
"react": "^18",
- "react-dom": "^18",
- "next": "14.2.20"
+ "react-dom": "^18"
},
"devDependencies": {
- "typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
- "eslint-config-next": "14.2.20"
+ "eslint-config-next": "14.2.20",
+ "postcss": "^8.4.49",
+ "postcss-nesting": "^13.0.1",
+ "prettier": "^3.4.2",
+ "typescript": "^5"
}
}
diff --git a/postcss.config.json b/postcss.config.json
new file mode 100644
index 0000000..55620f8
--- /dev/null
+++ b/postcss.config.json
@@ -0,0 +1,3 @@
+{
+ "plugins": ["postcss-nesting"]
+}
diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx
deleted file mode 100644
index a0204d7..0000000
--- a/src/app/about/page.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-const Page = () => {
- return (
-
About Page
- )
-}
-
-export default Page;
diff --git a/src/app/favicon.ico b/src/app/favicon.ico
index 718d6fe..3b4d69d 100644
Binary files a/src/app/favicon.ico and b/src/app/favicon.ico differ
diff --git a/src/app/globals.css b/src/app/globals.css
index e69de29..fdca90f 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -0,0 +1,91 @@
+:root {
+ --color-gray-98: hsl(0deg 0% 98%);
+ --color-gray-90: hsl(0deg 0% 90%);
+ --color-gray-80: hsl(0deg 0% 80%);
+ --color-gray-70: hsl(0deg 0% 70%);
+ --color-gray-40: hsl(0deg 0% 40%);
+ --color-gray-30: hsl(0deg 0% 30%);
+ --color-gray-20: hsl(0deg 0% 20%);
+ --color-gray-16: hsl(0deg 0% 16%);
+ --color-gray-12: hsl(0deg 0% 12%);
+ --color-gray-10: hsl(0deg 0% 10%);
+
+ --color-default-background: var(--color-gray-10);
+ --color-default-foreground: var(--color-gray-98);
+
+ --color-primary: hsl(120deg 50% 48%);
+ --color-primary-fade: hsl(120deg 50% 96%);
+ --color-primary-lighter: hsl(120deg 50% 52%);
+ --color-primary-darker: hsl(120deg 50% 44%);
+ --color-primary-opposite: var(--color-gray-10);
+
+ --border-radius: 0.875rem;
+
+ --full-width: 75rem;
+ --full-width-padding-inline: calc(max(100% - var(--full-width), 2rem) / 2);
+
+ --animation-duration-fast: 0.1s;
+ --animation-duration-normal: 0.5s;
+ --animation-duration-slow: 1s;
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+
+ margin: 0;
+ padding: 0;
+}
+
+html {
+ color-scheme: dark;
+}
+
+input,
+label,
+select,
+textarea,
+button,
+fieldset,
+legend,
+datalist,
+output,
+option,
+optgroup {
+ font: inherit;
+}
+
+ul {
+ list-style: none;
+}
+
+p {
+ color: var(--color-gray-80);
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+body {
+ background-color: var(--color-default-background);
+ color: var(--color-default-foreground);
+
+ display: grid;
+ grid-template-rows: auto 1fr auto;
+
+ min-block-size: 100vh;
+ min-block-size: 100dvh;
+
+ > * {
+ padding-inline: var(--full-width-padding-inline);
+ }
+
+ .tagline {
+ background-color: var(--color-gray-16);
+ padding-block: 1rem;
+ text-align: center;
+ }
+}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index b0cafe0..c9c45b6 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,11 +1,17 @@
+import { ReactElement } from "react";
+
import type { Metadata } from "next";
-import { Vazirmatn } from 'next/font/google'
+import { Vazirmatn } from "next/font/google";
+
+import FooterComponent from "@/components/footer/footer.component";
+import HeaderComponent from "@/components/header/header.component";
+
import "./globals.css";
const vazirmatn = Vazirmatn({
- subsets: ['latin','arabic'],
- display: 'swap',
-})
+ subsets: ["latin", "arabic"],
+ display: "swap",
+});
export const metadata: Metadata = {
title: "دکتر من",
@@ -16,11 +22,16 @@ export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
-}>) {
+}>): ReactElement {
return (
- {children}
+
+ {children}
+
+ نوبت دهی پزشکی، سامانه نوبت دهی اینترنتی بیمارستان و پزشکان
+
+
);
diff --git a/src/app/page.module.css b/src/app/page.module.css
index e69de29..e837406 100644
--- a/src/app/page.module.css
+++ b/src/app/page.module.css
@@ -0,0 +1,45 @@
+.home {
+ display: grid;
+ justify-items: center;
+ align-content: center;
+ gap: 2rem;
+
+ min-block-size: 100%;
+
+ grid-template-columns: minmax(0, 1fr);
+
+ h1 {
+ display: inline-flex;
+ align-items: center;
+ gap: 1rem;
+
+ font-size: 2.5rem;
+
+ svg {
+ font-size: 1.5em;
+ }
+ }
+
+ .history {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 1rem;
+
+ .title {
+ }
+
+ > ul {
+ display: flex;
+ gap: 1rem;
+
+ > li {
+ background-color: var(--color-gray-20);
+
+ padding: 0.25rem 0.75rem;
+
+ border-radius: 999rem;
+ }
+ }
+ }
+}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 5896916..d22a43f 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,35 +1,26 @@
-type Post = {
- id: number;
- title: string;
-}
+import { ReactElement } from "react";
+
+import GlobalSearchBoxComponent from "@/components/global-search-box/global-search-box.component";
-export default async function Home() {
- const res = await fetch("https://jsonplaceholder.org/posts", {
- cache: "no-store"
- });
+import MyDoctorLogo from "@/logo/my-doctor.logo";
- const posts: Post[] = await res.json();
+import styles from "./page.module.css";
- return (
-
- به سامانه نوبتدهی دکترمن خوش آمدید.
-
- لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و
- متون بلکه روزنامه
- و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف
- بهبود ابزارهای کاربردی می باشد.
- کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد
- تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی و فرهنگ پیشرو در زبان
- فارسی ایجاد کرد.
- در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها و شرایط سخت تایپ به پایان رسد
- وزمان مورد نیاز شامل حروفچینی دستاوردهای اصلی و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد
- استفاده قرار گیرد.
-
-
- {posts.map((post: Post) => (
- {post.title}
- ))}
-
-
- );
+export default function Home(): ReactElement {
+ return (
+
+ );
}
diff --git a/src/assets/logo/certificate.svg b/src/assets/logo/certificate.svg
new file mode 100644
index 0000000..0876d71
--- /dev/null
+++ b/src/assets/logo/certificate.svg
@@ -0,0 +1,11 @@
+
+icon
+
+
+
+
+
+
diff --git a/src/assets/logo/enamad.svg b/src/assets/logo/enamad.svg
new file mode 100644
index 0000000..732c7d3
--- /dev/null
+++ b/src/assets/logo/enamad.svg
@@ -0,0 +1,17 @@
+
+ icon
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/logo/idk.svg b/src/assets/logo/idk.svg
new file mode 100644
index 0000000..f74858d
--- /dev/null
+++ b/src/assets/logo/idk.svg
@@ -0,0 +1,22 @@
+
+icon
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/logo/logo.svg b/src/assets/logo/logo.svg
new file mode 100644
index 0000000..02568c6
--- /dev/null
+++ b/src/assets/logo/logo.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/components/footer/footer.component.tsx b/src/components/footer/footer.component.tsx
new file mode 100644
index 0000000..3f907ca
--- /dev/null
+++ b/src/components/footer/footer.component.tsx
@@ -0,0 +1,51 @@
+import { ReactElement } from "react";
+
+import Image from "next/image";
+import Link from "next/link";
+
+import {
+ certificatesMenu,
+ certificatesMenuType,
+ socialsMenu,
+ socialsMenuType,
+} from "@/constant/footer/menu";
+
+import styles from "./footer.module.css";
+
+export default function FooterComponent(): ReactElement {
+ return (
+
+ );
+}
diff --git a/src/components/footer/footer.module.css b/src/components/footer/footer.module.css
new file mode 100644
index 0000000..dd67f40
--- /dev/null
+++ b/src/components/footer/footer.module.css
@@ -0,0 +1,51 @@
+.footer {
+ background-color: var(--color-gray-12);
+
+ display: grid;
+ grid-template-areas: "writings visuals" "copy copy";
+ column-gap: 1rem;
+ row-gap: 2rem;
+
+ padding-block: 1rem;
+
+ .writings {
+ grid-area: writings;
+
+ .logo {
+ margin-block-end: 0.25rem;
+
+ font-size: 2rem;
+ font-weight: 700;
+ }
+ }
+
+ .visuals {
+ grid-area: visuals;
+
+ display: grid;
+ justify-items: center;
+ gap: 1rem;
+
+ .certificates {
+ display: flex;
+ gap: 2rem;
+ }
+
+ .socials {
+ display: flex;
+ gap: 1rem;
+
+ > li {
+ a {
+ font-size: 1.5rem;
+ }
+ }
+ }
+ }
+
+ .copy {
+ grid-area: copy;
+
+ text-align: center;
+ }
+}
diff --git a/src/components/global-search-box/global-search-box.component.tsx b/src/components/global-search-box/global-search-box.component.tsx
new file mode 100644
index 0000000..775ccb6
--- /dev/null
+++ b/src/components/global-search-box/global-search-box.component.tsx
@@ -0,0 +1,27 @@
+import { ReactElement } from "react";
+
+import MingcuteSearchLine from "@/icons/MingcuteSearchLine";
+import MingcuteLocationLine from "@/icons/MingcuteLocationLine";
+
+import styles from "./global-search-box.module.css";
+
+export default function GlobalSearchBoxComponent(): ReactElement {
+ return (
+
+
+
+
+
+
+
+
+
+ همه شهرها
+
+
+
+ );
+}
diff --git a/src/components/global-search-box/global-search-box.module.css b/src/components/global-search-box/global-search-box.module.css
new file mode 100644
index 0000000..ca1269f
--- /dev/null
+++ b/src/components/global-search-box/global-search-box.module.css
@@ -0,0 +1,75 @@
+.global-search-box {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+
+ inline-size: min(50rem, 100%);
+
+ padding-inline: 1rem;
+
+ border: 1px solid var(--color-gray-20);
+ border-radius: 999rem;
+
+ .prefix {
+ display: grid;
+ align-items: center;
+
+ font-size: 1.5rem;
+ }
+
+ input {
+ flex: 1 1 0;
+
+ background-color: transparent;
+
+ padding: 1rem;
+
+ border: none;
+
+ min-inline-size: 0;
+
+ &:focus {
+ outline: none;
+ }
+ }
+
+ .divider {
+ background-color: var(--color-gray-20);
+
+ block-size: 2em;
+ inline-size: 1px;
+ }
+
+ .suffix {
+ button {
+ background-color: transparent;
+
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+
+ padding: 0.5rem 0.5rem;
+
+ border: none;
+ border-radius: var(--border-radius);
+
+ cursor: pointer;
+
+ svg {
+ font-size: 1.5em;
+ }
+
+ &:hover {
+ background-color: var(--color-gray-16);
+ }
+ }
+ }
+
+ &:focus-within {
+ border-color: var(--color-primary);
+
+ .prefix {
+ color: var(--color-primary);
+ }
+ }
+}
diff --git a/src/components/header/header.component.tsx b/src/components/header/header.component.tsx
new file mode 100644
index 0000000..34802a9
--- /dev/null
+++ b/src/components/header/header.component.tsx
@@ -0,0 +1,39 @@
+"use client";
+
+import { ReactElement } from "react";
+
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+
+import clsx from "clsx";
+
+import { menu, menuType } from "@/constant/header/menu";
+import styles from "./header.module.css";
+
+export default function HeaderComponent(): ReactElement {
+ const pathname = usePathname();
+
+ return (
+
+
+
+ {menu.map((item: menuType, index: number) => {
+ const title = item.title;
+ const href = item.href;
+ return (
+
+
+ {title}
+
+
+ );
+ })}
+
+
+ ورود | ثبتنام
+
+ );
+}
diff --git a/src/components/header/header.module.css b/src/components/header/header.module.css
new file mode 100644
index 0000000..b0bf77d
--- /dev/null
+++ b/src/components/header/header.module.css
@@ -0,0 +1,42 @@
+.header {
+ display: flex;
+ align-items: center;
+ gap: 2rem;
+
+ padding-block: 1rem;
+
+ nav {
+ > ul {
+ display: flex;
+ gap: 2rem;
+
+ > li {
+ a {
+ &.active {
+ color: var(--color-primary);
+ }
+ }
+ }
+ }
+ }
+
+ .cta {
+ background-color: transparent;
+ color: var(--color-primary);
+
+ margin-inline-start: auto;
+ padding: 0.5rem 1rem;
+
+ border: 1px solid currentcolor;
+ border-radius: var(--border-radius);
+
+ font-weight: 700;
+
+ cursor: pointer;
+
+ &:hover {
+ background-color: var(--color-primary);
+ color: var(--color-primary-opposite);
+ }
+ }
+}
diff --git a/src/constant/footer/menu.ts b/src/constant/footer/menu.ts
new file mode 100644
index 0000000..69668e6
--- /dev/null
+++ b/src/constant/footer/menu.ts
@@ -0,0 +1,45 @@
+import { StaticImport } from "next/dist/shared/lib/get-img-props";
+
+import MingcuteTelegramFill from "@/icons/MingcuteTelegramFill";
+import MingcuteLinkedinFill from "@/icons/MingcuteLinkedinFill";
+import MingcuteYoutubeFill from "@/icons/MingcuteYoutubeFill";
+
+import certificateLogo from "@/assets/logo/certificate.svg";
+import enamadLogo from "@/assets/logo/enamad.svg";
+import idkLogo from "@/assets/logo/idk.svg";
+
+export const socialsMenu = [
+ {
+ imgComponent: MingcuteTelegramFill,
+ alt: "تلگرام",
+ href: "https://t.me/Codective",
+ },
+ {
+ imgComponent: MingcuteLinkedinFill,
+ alt: "لینکدین",
+ href: "https://www.linkedin.com/in/bijanprogrammer/",
+ },
+ {
+ imgComponent: MingcuteYoutubeFill,
+ alt: "یوتیوب",
+ href: "https://www.youtube.com/@BijanProgrammer",
+ },
+];
+
+export type socialsMenuType = {
+ imgComponent: React.ComponentType;
+ alt: string;
+ href: string;
+};
+
+export const certificatesMenu = [
+ { svgSrc: idkLogo, alt: "IDK Logo", href: "#" },
+ { svgSrc: certificateLogo, alt: "Certificate Logo", href: "#" },
+ { svgSrc: enamadLogo, alt: "Enamad Logo", href: "#" },
+];
+
+export type certificatesMenuType = {
+ svgSrc: string | StaticImport;
+ alt: string;
+ href: string;
+};
diff --git a/src/constant/header/menu.ts b/src/constant/header/menu.ts
new file mode 100644
index 0000000..15c49ef
--- /dev/null
+++ b/src/constant/header/menu.ts
@@ -0,0 +1,7 @@
+export const menu = [
+ { title: "خانه", href: "" },
+ { title: "جستجو", href: "search" },
+ { title: "پزشکان", href: "doctors" },
+];
+
+export type menuType = Record;
diff --git a/src/icons/MingcuteLinkedinFill.tsx b/src/icons/MingcuteLinkedinFill.tsx
new file mode 100644
index 0000000..8d883a1
--- /dev/null
+++ b/src/icons/MingcuteLinkedinFill.tsx
@@ -0,0 +1,22 @@
+import React, { SVGProps } from "react";
+
+export function MingcuteLinkedinFill(props: SVGProps) {
+ return (
+
+
+
+
+
+
+ );
+}
+export default MingcuteLinkedinFill;
diff --git a/src/icons/MingcuteLocationLine.tsx b/src/icons/MingcuteLocationLine.tsx
new file mode 100644
index 0000000..8f570dc
--- /dev/null
+++ b/src/icons/MingcuteLocationLine.tsx
@@ -0,0 +1,22 @@
+import { SVGProps } from "react";
+
+export function MingcuteLocationLine(props: SVGProps) {
+ return (
+
+
+
+
+
+
+ );
+}
+export default MingcuteLocationLine;
diff --git a/src/icons/MingcuteSearchLine.tsx b/src/icons/MingcuteSearchLine.tsx
new file mode 100644
index 0000000..9d92090
--- /dev/null
+++ b/src/icons/MingcuteSearchLine.tsx
@@ -0,0 +1,22 @@
+import { SVGProps } from "react";
+
+export function MingcuteSearchLine(props: SVGProps) {
+ return (
+
+
+
+
+
+
+ );
+}
+export default MingcuteSearchLine;
diff --git a/src/icons/MingcuteTelegramFill.tsx b/src/icons/MingcuteTelegramFill.tsx
new file mode 100644
index 0000000..8c3ab69
--- /dev/null
+++ b/src/icons/MingcuteTelegramFill.tsx
@@ -0,0 +1,22 @@
+import React, { SVGProps } from "react";
+
+export function MingcuteTelegramFill(props: SVGProps) {
+ return (
+
+
+
+
+
+
+ );
+}
+export default MingcuteTelegramFill;
diff --git a/src/icons/MingcuteYoutubeFill.tsx b/src/icons/MingcuteYoutubeFill.tsx
new file mode 100644
index 0000000..b3c45e0
--- /dev/null
+++ b/src/icons/MingcuteYoutubeFill.tsx
@@ -0,0 +1,22 @@
+import React, { SVGProps } from "react";
+
+export function MingcuteYoutubeFill(props: SVGProps) {
+ return (
+
+
+
+
+
+
+ );
+}
+export default MingcuteYoutubeFill;
diff --git a/src/logo/my-doctor.logo.tsx b/src/logo/my-doctor.logo.tsx
new file mode 100644
index 0000000..2ee1568
--- /dev/null
+++ b/src/logo/my-doctor.logo.tsx
@@ -0,0 +1,30 @@
+import { SVGProps } from "react";
+
+export function MyDoctorLogo(props: SVGProps) {
+ return (
+
+
+
+
+
+ );
+}
+export default MyDoctorLogo;