Repository: rak517/Epigram
Pull request #29: EP-13 공용 Header 컴포넌트 구현
Author: login: CJewon
Labels: name: Priority: Medium :bookmark:
description: 우선순위 보통
name: Type: Feature ✨
description: 기능 개발
Created: 2025-03-12T02:08:23Z | Merged: 2025-03-14T07:05:39Z

## ❓이슈
- close #7 

## :writing_hand: Description

<!-- 어떤 내용의 PR인지 작성해주세요. (ex. 메인 페이지 레이아웃 작업) -->
<!-- ⚠️ PR에는 해당 PR의 제목에 해당하는 내용만 들어가 있어야 합니다!  -->
공용 Header 컴포넌트에 관한 PR입니다.
하나의 컴포넌트로 구현하려고 했으나 추후 기능적인 요소에서 각 페이지의 header마다 기능이 많이 달라질것이라 판단되어 2가지 header 컴포넌트로 만들었습니다.

1. 랜딩페이지, 로그인 페이지 공용 Header 컴포넌트
2. 로그인이 된 상태에서 Main페이지의 Header 컴포넌트

위 두 가지를 기준으로 컴포넌트로 만들었으며, 1번 같은 경우, showIcon이라는 boolean 타입의 props로 로그인 유무를 전달받아 각 상황에 맞게 header가 변경됩니다.

storybook이나 추가해야할 부분이 있다면 글로 남겨주시면 검토 후 수정하겠습니다. 감사합니다.

### 스토리북 이미지
![스크린샷 2025-03-12 110455](https://github.com/user-attachments/assets/168a8b12-6895-4130-9c11-c42a7a249a55)
![스크린샷 2025-03-12 110524](https://github.com/user-attachments/assets/f1d200f5-18be-4cce-a501-a626132ffc17)


## :white_check_mark: Checklist

### PR

<!-- 작성중인 PR인 경우, Draft 모드로 생성해주세요. -->

- [x] Branch Convention 확인
  > `feat/*` 기능 구현, `fix/*` 버그 수정, `refactor/*` 개선
- [x] Base Branch 확인
- [x] 적절한 Label 지정
- [x] Assignee 및 Reviewer 지정

### Test

- [x] 로컬 작동 확인

### Additional Notes

<!-- 추가 사항이 있을 경우, Todo list를 작성해주세요. -->

- [x] (없음)


Linked issue #7: [EP-13] Feat: [공용] 헤더 컴포넌트 구현
### 🎟️ 상위 작업 (에픽 키)

EP-11

### 📝 상세 내용 (Description)

[공용] 헤더 컴포넌트 구현에 관한 이슈입니다.

### ✅ 체크리스트 (Tasks)

- [x] 헤더 UI 구현
- [x] 각 요소 별 클릭시 URL 이동 구현
- [x] 브라우저 화면 너비에 따른 반응형 처리


### 📄 참고 자료

<img width="801" alt="Image" src="https://github.com/user-attachments/assets/26eb68b4-a839-492d-84fe-ed52c5048a22" />

Diff:
diff --git a/.gitignore b/.gitignore
index 365486f6..0d2cf532 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,4 +51,5 @@ node_modules/
 
 # custom
 .swc
-/storybook-static
\ No newline at end of file
+/storybook-static
+.vscode
\ No newline at end of file
diff --git a/src/assets/icons/hamburgerMenuIcon.svg b/src/assets/icons/hamburgerMenuIcon.svg
new file mode 100644
index 00000000..0453091a
--- /dev/null
+++ b/src/assets/icons/hamburgerMenuIcon.svg
@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect x="3" y="6" width="18" height="2" rx="1" fill="#C4C4C4"/>
+<rect x="3" y="11" width="18" height="2" rx="1" fill="#C4C4C4"/>
+<rect x="3" y="16" width="18" height="2" rx="1" fill="#C4C4C4"/>
+</svg>
diff --git a/src/assets/icons/searchIcon.svg b/src/assets/icons/searchIcon.svg
new file mode 100644
index 00000000..b35280c5
--- /dev/null
+++ b/src/assets/icons/searchIcon.svg
@@ -0,0 +1,4 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M9.16667 15.8333C12.8486 15.8333 15.8333 12.8486 15.8333 9.16667C15.8333 5.48477 12.8486 2.5 9.16667 2.5C5.48477 2.5 2.5 5.48477 2.5 9.16667C2.5 12.8486 5.48477 15.8333 9.16667 15.8333Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M17.5 17.5L13.875 13.875" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
diff --git a/src/assets/icons/userIconDark.svg b/src/assets/icons/userIconDark.svg
new file mode 100644
index 00000000..223019b3
--- /dev/null
+++ b/src/assets/icons/userIconDark.svg
@@ -0,0 +1,4 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M16.6668 17.5V15.8333C16.6668 14.9493 16.3156 14.1014 15.6905 13.4763C15.0654 12.8512 14.2176 12.5 13.3335 12.5H6.66683C5.78277 12.5 4.93493 12.8512 4.30981 13.4763C3.68469 14.1014 3.3335 14.9493 3.3335 15.8333V17.5" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M9.99984 9.16667C11.8408 9.16667 13.3332 7.67428 13.3332 5.83333C13.3332 3.99238 11.8408 2.5 9.99984 2.5C8.15889 2.5 6.6665 3.99238 6.6665 5.83333C6.6665 7.67428 8.15889 9.16667 9.99984 9.16667Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
diff --git a/src/assets/icons/userIconLight.svg b/src/assets/icons/userIconLight.svg
new file mode 100644
index 00000000..946195cc
--- /dev/null
+++ b/src/assets/icons/userIconLight.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M13.3337 14V12.6667C13.3337 11.9594 13.0527 11.2811 12.5526 10.781C12.0525 10.281 11.3742 10 10.667 10H5.33366C4.62641 10 3.94814 10.281 3.44804 10.781C2.94794 11.2811 2.66699 11.9594 2.66699 12.6667V14" stroke="#DEDEDE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M7.99967 7.33333C9.47243 7.33333 10.6663 6.13943 10.6663 4.66667C10.6663 3.19391 9.47243 2 7.99967 2C6.52692 2 5.33301 3.19391 5.33301 4.66667C5.33301 6.13943 6.52692 7.33333 7.99967 7.33333Z" stroke="#DEDEDE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<circle cx="8.5" cy="4.5" r="2.5" fill="#DEDEDE"/>
+<path d="M4 10H12L13.5 14.75H2.5L4 10Z" fill="#DEDEDE"/>
+</svg>
diff --git a/src/assets/images/headerLogo.svg b/src/assets/images/headerLogo.svg
new file mode 100644
index 00000000..bde7a717
--- /dev/null
+++ b/src/assets/images/headerLogo.svg
@@ -0,0 +1,5 @@
+<svg width="102" height="26" viewBox="0 0 102 26" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M20.1807 8.73365L13.4242 5.44873C13.2566 5.36721 13.0617 5.36286 12.8905 5.43683L5.262 8.73365L12.863 12.4292C13.0494 12.5198 13.2681 12.5146 13.45 12.4151L20.1807 8.73365Z" fill="#2B2B2B"/>
+<path d="M5.262 8.73365L12.863 12.4292C13.0494 12.5198 13.2681 12.5146 13.45 12.4151L20.1807 8.73365L13.4242 5.44873C13.2566 5.36721 13.0617 5.36286 12.8905 5.43683L5.262 8.73365ZM5.262 8.73365C5.262 8.73365 4.85682 9.75408 4.82321 10.4403C4.78165 11.289 5.262 12.5736 5.262 12.5736M20.1807 12.5736L13.45 16.2551C13.2681 16.3546 13.0494 16.3598 12.863 16.2692L5.262 12.5736M5.262 12.5736C5.262 12.5736 4.82321 13.8574 4.82321 14.707C4.82321 15.5566 5.262 16.8403 5.262 16.8403L12.863 20.5359C13.0494 20.6265 13.2681 20.6212 13.45 20.5218L20.1807 16.8403" stroke="#2B2B2B" stroke-width="1.92" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M32.868 11.96H37.86V14.68H32.868V11.96ZM33.124 16.152H38.724V19H29.412V7.8H38.516V10.648H33.124V16.152ZM45.9056 19.16C45.1483 19.16 44.519 19 44.0176 18.68C43.527 18.3493 43.1643 17.8533 42.9296 17.192C42.695 16.52 42.5776 15.6667 42.5776 14.632C42.5776 13.576 42.6843 12.7173 42.8976 12.056C43.1216 11.384 43.479 10.888 43.9696 10.568C44.4603 10.248 45.1056 10.088 45.9056 10.088C46.6736 10.088 47.3776 10.2747 48.0176 10.648C48.6576 11.0107 49.1696 11.5333 49.5536 12.216C49.9376 12.888 50.1296 13.6933 50.1296 14.632C50.1296 15.5707 49.9376 16.3813 49.5536 17.064C49.1696 17.736 48.6576 18.2533 48.0176 18.616C47.3776 18.9787 46.6736 19.16 45.9056 19.16ZM40.0656 22.104V10.248H43.5056V11.432L43.5216 14.632L43.6816 17.832V22.104H40.0656ZM45.0416 16.344C45.3083 16.344 45.5483 16.28 45.7616 16.152C45.975 16.024 46.1456 15.832 46.2736 15.576C46.4016 15.32 46.4656 15.0053 46.4656 14.632C46.4656 14.248 46.4016 13.928 46.2736 13.672C46.1456 13.416 45.975 13.224 45.7616 13.096C45.5483 12.968 45.3083 12.904 45.0416 12.904C44.775 12.904 44.535 12.968 44.3216 13.096C44.1083 13.224 43.9376 13.416 43.8096 13.672C43.6816 13.928 43.6176 14.248 43.6176 14.632C43.6176 15.0053 43.6816 15.32 43.8096 15.576C43.9376 15.832 44.1083 16.024 44.3216 16.152C44.535 16.28 44.775 16.344 45.0416 16.344ZM51.2688 19V10.248H54.8848V19H51.2688ZM53.0768 9.544C52.4154 9.544 51.8874 9.368 51.4928 9.016C51.0981 8.664 50.9008 8.22667 50.9008 7.704C50.9008 7.18133 51.0981 6.744 51.4928 6.392C51.8874 6.04 52.4154 5.864 53.0768 5.864C53.7381 5.864 54.2661 6.02933 54.6608 6.36C55.0554 6.69067 55.2528 7.11733 55.2528 7.64C55.2528 8.19467 55.0554 8.65333 54.6608 9.016C54.2661 9.368 53.7381 9.544 53.0768 9.544ZM60.9355 22.264C60.0715 22.264 59.2608 22.1733 58.5035 21.992C57.7462 21.8107 57.0955 21.5387 56.5515 21.176L57.7675 18.712C58.1088 18.9787 58.5408 19.1867 59.0635 19.336C59.5968 19.496 60.0982 19.576 60.5675 19.576C61.3142 19.576 61.8475 19.416 62.1675 19.096C62.4875 18.7867 62.6475 18.3387 62.6475 17.752V17.016L62.8075 14.296L62.8235 11.576V10.248H66.2635V17.256C66.2635 18.952 65.7942 20.2107 64.8555 21.032C63.9168 21.8533 62.6102 22.264 60.9355 22.264ZM60.2315 18.52C59.4955 18.52 58.8075 18.3493 58.1675 18.008C57.5275 17.656 57.0102 17.1653 56.6155 16.536C56.2208 15.9067 56.0235 15.16 56.0235 14.296C56.0235 13.432 56.2208 12.6853 56.6155 12.056C57.0102 11.4267 57.5275 10.9413 58.1675 10.6C58.8075 10.2587 59.4955 10.088 60.2315 10.088C60.9888 10.088 61.6075 10.2373 62.0875 10.536C62.5782 10.8347 62.9408 11.2987 63.1755 11.928C63.4102 12.5467 63.5275 13.336 63.5275 14.296C63.5275 15.256 63.4102 16.0507 63.1755 16.68C62.9408 17.2987 62.5782 17.7627 62.0875 18.072C61.6075 18.3707 60.9888 18.52 60.2315 18.52ZM61.1915 15.704C61.4795 15.704 61.7355 15.6453 61.9595 15.528C62.1835 15.4107 62.3595 15.2453 62.4875 15.032C62.6155 14.8187 62.6795 14.5733 62.6795 14.296C62.6795 14.008 62.6155 13.7627 62.4875 13.56C62.3595 13.3467 62.1835 13.1867 61.9595 13.08C61.7355 12.9627 61.4795 12.904 61.1915 12.904C60.9142 12.904 60.6582 12.9627 60.4235 13.08C60.1995 13.1867 60.0182 13.3467 59.8795 13.56C59.7515 13.7627 59.6875 14.008 59.6875 14.296C59.6875 14.5733 59.7515 14.8187 59.8795 15.032C60.0182 15.2453 60.1995 15.4107 60.4235 15.528C60.6582 15.6453 60.9142 15.704 61.1915 15.704ZM67.8625 19V10.248H71.3025V12.888L70.7425 12.136C71.0092 11.4533 71.4358 10.9413 72.0225 10.6C72.6092 10.2587 73.3132 10.088 74.1345 10.088V13.288C73.9745 13.2667 73.8305 13.2507 73.7025 13.24C73.5852 13.2293 73.4625 13.224 73.3345 13.224C72.7905 13.224 72.3425 13.368 71.9905 13.656C71.6492 13.9333 71.4785 14.4187 71.4785 15.112V19H67.8625ZM79.971 19V17.448L79.715 17.032V14.088C79.715 13.6613 79.5817 13.336 79.315 13.112C79.059 12.888 78.6377 12.776 78.051 12.776C77.6563 12.776 77.2563 12.84 76.851 12.968C76.4457 13.0853 76.099 13.2507 75.811 13.464L74.659 11.08C75.171 10.76 75.7843 10.5147 76.499 10.344C77.2137 10.1733 77.9123 10.088 78.595 10.088C80.099 10.088 81.2617 10.424 82.083 11.096C82.915 11.768 83.331 12.8347 83.331 14.296V19H79.971ZM77.491 19.16C76.7763 19.16 76.179 19.0373 75.699 18.792C75.219 18.5467 74.8563 18.2213 74.611 17.816C74.3657 17.4 74.243 16.9413 74.243 16.44C74.243 15.8747 74.387 15.3947 74.675 15C74.963 14.6053 75.4003 14.3067 75.987 14.104C76.5843 13.9013 77.3363 13.8 78.243 13.8H80.067V15.544H78.819C78.435 15.544 78.1523 15.608 77.971 15.736C77.8003 15.8533 77.715 16.0347 77.715 16.28C77.715 16.4827 77.7897 16.6533 77.939 16.792C78.099 16.92 78.3123 16.984 78.579 16.984C78.8243 16.984 79.0483 16.92 79.251 16.792C79.4643 16.6533 79.619 16.44 79.715 16.152L80.179 17.224C80.0403 17.8747 79.747 18.36 79.299 18.68C78.851 19 78.2483 19.16 77.491 19.16ZM96.4778 10.088C97.1391 10.088 97.7311 10.2267 98.2538 10.504C98.7871 10.7707 99.2031 11.192 99.5018 11.768C99.8111 12.344 99.9658 13.0907 99.9658 14.008V19H96.3498V14.632C96.3498 14.088 96.2591 13.704 96.0778 13.48C95.8964 13.2453 95.6618 13.128 95.3738 13.128C95.1604 13.128 94.9684 13.1813 94.7978 13.288C94.6271 13.3947 94.4884 13.5653 94.3818 13.8C94.2858 14.024 94.2378 14.3333 94.2378 14.728V19H90.6218V14.632C90.6218 14.088 90.5364 13.704 90.3658 13.48C90.1951 13.2453 89.9551 13.128 89.6458 13.128C89.4324 13.128 89.2404 13.1813 89.0698 13.288C88.8991 13.3947 88.7604 13.5653 88.6538 13.8C88.5578 14.024 88.5098 14.3333 88.5098 14.728V19H84.8938V10.248H88.3338V12.76L87.6298 12.056C87.9604 11.3947 88.4031 10.904 88.9578 10.584C89.5124 10.2533 90.1311 10.088 90.8138 10.088C91.5818 10.088 92.2591 10.2907 92.8458 10.696C93.4431 11.0907 93.8431 11.72 94.0458 12.584L92.9418 12.408C93.2618 11.6827 93.7258 11.1173 94.3338 10.712C94.9524 10.296 95.6671 10.088 96.4778 10.088Z" fill="#2B2B2B"/>
+</svg>
diff --git a/src/components/.gitkeep b/src/components/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/components/ui/Field/Base.tsx b/src/components/ui/Field/Base.tsx
new file mode 100644
index 00000000..7b91fd1c
--- /dev/null
+++ b/src/components/ui/Field/Base.tsx
@@ -0,0 +1,30 @@
+import { cn } from '@/utils/cn';
+import { cva } from 'class-variance-authority';
+import { LabelHTMLAttributes, PropsWithChildren } from 'react';
+
+export function BaseItem({ children }: PropsWithChildren) {
+  return <div className='grid gap-1'>{children}</div>;
+}
+
+export function BaseLabel({ required, children, className, ...props }: PropsWithChildren<LabelHTMLAttributes<HTMLLabelElement> & { required?: boolean }>) {
+  return (
+    <label className={cn('text-black-600 text-md inline-flex items-center gap-1 font-semibold md:text-lg lg:gap-1.5 lg:text-xl', className)} {...props}>
+      {children}
+      {required && <span className='text-error flex items-center pt-1.5 text-lg font-medium lg:text-2xl'>*</span>}
+    </label>
+  );
+}
+
+export function BaseError({ children }: PropsWithChildren) {
+  return <div className='text-error md:text-md text-xs lg:text-lg'>{children}</div>;
+}
+
+export const baseFieldClassName = cva('rounded-lg w-full px-4 h-11 lg:h-[64px]  text-black-950 placeholder-blue-400 text-lg lg:text-xl focus-visible:outline-none read-only:text-blue-400', {
+  variants: {
+    variant: {
+      default: 'bg-background-100',
+      outlined: 'border border-blue-300 bg-transparent',
+    },
+  },
+});
+export const BASE_ERROR_CLASSNAME = 'border border-error';
diff --git a/src/components/ui/Field/Input.tsx b/src/components/ui/Field/Input.tsx
new file mode 100644
index 00000000..4db6dc4a
--- /dev/null
+++ b/src/components/ui/Field/Input.tsx
@@ -0,0 +1,27 @@
+import { cn } from '@/utils/cn';
+import { InputHTMLAttributes, Ref, useId } from 'react';
+import { BaseError, BaseItem, BaseLabel, BASE_ERROR_CLASSNAME, baseFieldClassName } from './Base';
+import { BaseField } from './types';
+import { VariantProps } from 'class-variance-authority';
+
+export type InputProps = BaseField &
+  InputHTMLAttributes<HTMLInputElement> &
+  VariantProps<typeof baseFieldClassName> & {
+    ref?: Ref<HTMLInputElement>;
+  };
+
+export default function Input({ label, error, variant = 'default', className, ref, ...props }: InputProps) {
+  const id = useId();
+
+  return (
+    <BaseItem>
+      {label && (
+        <BaseLabel required={props.required} htmlFor={id}>
+          {label}
+        </BaseLabel>
+      )}
+      <input id={id} className={cn(baseFieldClassName({ variant, className }), error && BASE_ERROR_CLASSNAME)} ref={ref} {...props} />
+      {error && <BaseError>{error}</BaseError>}
+    </BaseItem>
+  );
+}
diff --git a/src/components/ui/Field/index.tsx b/src/components/ui/Field/index.tsx
new file mode 100644
index 00000000..ba9fe7eb
--- /dev/null
+++ b/src/components/ui/Field/index.tsx
@@ -0,0 +1 @@
+export * from './Input';
diff --git a/src/components/ui/Field/types.ts b/src/components/ui/Field/types.ts
new file mode 100644
index 00000000..c1e4d8c9
--- /dev/null
+++ b/src/components/ui/Field/types.ts
@@ -0,0 +1,4 @@
+export type BaseField = {
+  label?: string;
+  error?: string;
+};
diff --git a/src/components/ui/header/LandingHeader.tsx b/src/components/ui/header/LandingHeader.tsx
new file mode 100644
index 00000000..e925aee2
--- /dev/null
+++ b/src/components/ui/header/LandingHeader.tsx
@@ -0,0 +1,35 @@
+'use client';
+import Image from 'next/image';
+import headerLogo from '@/assets/images/headerLogo.svg';
+import userIconDark from '@/assets/icons/userIconDark.svg';
+import searchIcon from '@/assets/icons/searchIcon.svg';
+import Link from 'next/link';
+
+export interface LandingHeaderProps {
+  showIcon?: boolean;
+}
+
+export default function LandingHeader({ showIcon = false }: LandingHeaderProps) {
+  if (showIcon) {
+    return (
+      <header className='border-b-line-100 fixed flex w-full items-center justify-between border-b bg-white px-6 py-2 md:h-[60px] md:px-[72px] md:py-3 xl:h-20 xl:px-[120px] xl:py-4'>
+        <Link href={'/search'}>
+          <Image src={searchIcon} alt='검색 아이콘' className='xl:w-9' />
+        </Link>
+        <Link href={'/'}>
+          <Image src={headerLogo} alt='헤더 로고' className='h-[36px] w-[119px] xl:h-12 xl:w-[172px]' />
+        </Link>
+        <Link href={'/mypage'}>
+          <Image src={userIconDark} alt='유저 아이콘' className='xl:w-9' />
+        </Link>
+      </header>
+    );
+  }
+  return (
+    <header className='border-b-line-100 fixed flex w-full items-center justify-center border-b bg-white py-3.5 md:h-[60px] xl:h-20'>
+      <Link href={'/'} className='flex items-center justify-center'>
+        <Image src={headerLogo} alt='헤더 로고' className='xl:h-9 xl:w-[131px]' />
+      </Link>
+    </header>
+  );
+}
diff --git a/src/components/ui/header/MainHeader.tsx b/src/components/ui/header/MainHeader.tsx
new file mode 100644
index 00000000..b3f85168
--- /dev/null
+++ b/src/components/ui/header/MainHeader.tsx
@@ -0,0 +1,28 @@
+import Image from 'next/image';
+import menuIcon from '@/assets/icons/hamburgerMenuIcon.svg';
+import headerLogo from '@/assets/images/headerLogo.svg';
+import userIconLight from '@/assets/icons/userIconLight.svg';
+import Link from 'next/link';
+
+export default function MainHeader() {
+  return (
+    <header className='border-b-line-100 fixed flex w-full items-center justify-between border-b-[1px] bg-white px-6 py-[13px] md:px-[72px] md:py-[17px] xl:px-[120px] xl:py-[22px]'>
+      <div className='flex items-center justify-center gap-3 md:gap-6 xl:gap-9'>
+        <Image src={menuIcon} alt='메뉴 아이콘' className='md:hidden'></Image>
+        <Link href={'/'}>
+          <Image src={headerLogo} alt='헤더 로고' className='xl:h-9 xl:w-[131px]'></Image>
+        </Link>
+        <Link href={'/epigrams'} className='text-black-600 hidden leading-[26px] font-semibold md:block'>
+          피드
+        </Link>
+        <Link href={'/search'} className='text-black-600 hidden leading-[26px] font-semibold md:block'>
+          검색
+        </Link>
+      </div>
+      <Link href={'/myapage'} className='flex gap-1.5'>
+        <Image src={userIconLight} alt='유저 아이콘'></Image>
+        <p className='xl:text-md text-sm font-medium text-gray-300'>김코드</p>
+      </Link>
+    </header>
+  );
+}
diff --git a/src/stories/.gitkeep b/src/stories/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/stories/Field/Input/index.stories.tsx b/src/stories/Field/Input/index.stories.tsx
new file mode 100644
index 00000000..c9a8c9a6
--- /dev/null
+++ b/src/stories/Field/Input/index.stories.tsx
@@ -0,0 +1,67 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import { cn } from '@/utils/cn';
+import Input from '@/components/ui/Field/Input';
+import { Pretendard } from '@/fonts';
+
+const meta: Meta<typeof Input> = {
+  title: 'Field/Input',
+  component: Input,
+  tags: ['autodocs'],
+  parameters: {
+    layout: 'centered',
+  },
+  decorators: [
+    (Story) => (
+      <div className={cn('flex items-center justify-center rounded-2xl bg-white', Pretendard.className)}>
+        <Story />
+      </div>
+    ),
+  ],
+  argTypes: {
+    variant: {
+      options: ['default', 'outlined'],
+      control: { type: 'select' },
+    },
+    label: { control: 'text' },
+    error: { control: 'text' },
+    placeholder: { control: 'text' },
+    required: { control: 'boolean' },
+  },
+};
+
+export default meta;
+type Story = StoryObj<typeof Input>;
+
+export const Default: Story = {
+  args: {
+    label: '이메일',
+    placeholder: '이메일을 입력해주세요.',
+    className: 'w-full',
+  },
+};
+
+export const Outlined: Story = {
+  args: {
+    label: '이메일',
+    placeholder: '이메일을 입력하세요',
+    variant: 'outlined',
+  },
+};
+
+export const WithError: Story = {
+  args: {
+    label: '이메일',
+    placeholder: '이메일을 입력해주세요.',
+    error: '유효하지 않은 이메일 형식입니다.',
+    className: '',
+  },
+};
+
+export const WithRequired: Story = {
+  args: {
+    label: '이메일',
+    placeholder: '이메일을 입력해주세요.',
+    className: '',
+    required: true,
+  },
+};
diff --git a/src/stories/header/LandingHeader.stories.tsx b/src/stories/header/LandingHeader.stories.tsx
new file mode 100644
index 00000000..094c48ad
--- /dev/null
+++ b/src/stories/header/LandingHeader.stories.tsx
@@ -0,0 +1,39 @@
+import LandingHeader from '@/components/ui/header/LandingHeader';
+import { Meta, StoryObj } from '@storybook/react';
+
+const meta: Meta<typeof LandingHeader> = {
+  title: 'Header/LandingHeader',
+  component: LandingHeader,
+  tags: ['autodocs'],
+  parameters: {
+    backgrounds: {
+      default: 'homeBackgroundColor',
+      values: [
+        { name: 'light', value: '#ffffff' },
+        { name: 'homeBackgroundColor', value: '#f5f7fa' },
+      ],
+    },
+  },
+  decorators: [
+    (Story) => (
+      <div className='bg-[#ffffff]'>
+        <Story></Story>
+      </div>
+    ),
+  ],
+  argTypes: {
+    showIcon: {
+      control: { type: 'boolean' },
+    },
+  },
+};
+
+export default meta;
+
+type Story = StoryObj<typeof LandingHeader>;
+
+export const Default: Story = {
+  args: {
+    showIcon: false,
+  },
+};
diff --git a/src/stories/header/MainHeader.stories.tsx b/src/stories/header/MainHeader.stories.tsx
new file mode 100644
index 00000000..37926cb2
--- /dev/null
+++ b/src/stories/header/MainHeader.stories.tsx
@@ -0,0 +1,34 @@
+import MainHeader from '@/components/ui/header/MainHeader';
+import { Meta, StoryObj } from '@storybook/react';
+
+const meta: Meta<typeof MainHeader> = {
+  title: 'Header/MainHeader',
+  component: MainHeader,
+  tags: ['autodocs'],
+  parameters: {
+    backgrounds: {
+      default: 'homeBackgroundColor',
+      values: [
+        { name: 'light', value: '#ffffff' },
+        { name: 'homeBackgroundColor', value: '#f5f7fa' },
+      ],
+    },
+  },
+  decorators: [
+    (Story) => (
+      <div className='bg-white'>
+        <Story></Story>
+      </div>
+    ),
+  ],
+};
+
+export default meta;
+
+type Story = StoryObj<typeof MainHeader>;
+
+export const Default: Story = {
+  args: {
+    title: '메인 헤더',
+  },
+};


Reviews:
user: login: ToKyun02
body: 작업하시느라 고생하셨습니다.

Main과 Landing Header 높이가 각각 달라서 통일하셨으면 좋겠습니다!

Figma 시안처럼 80px로 맞춰도 될 것 같습니다!

추가로, Dev브랜치를 rebase안하고 브랜치 push하셔서 성락님 작업 파일도 같이 PR 변경사항에 찍히게 되는데, 이 부분은 다음에 고려해주시면 될 것 같아요 ㅎㅎ

코멘트 사항 반영하시면 승인하겠습니다!
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:34:15Z
user: login: CJewon
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:40:25Z
user: login: pss7
body: 코드 깔끔하게 잘 구현하신 것 같아요!
고생하셨습니다~
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T00:59:03Z
user: login: ToKyun02
body: 두가지 고쳐야 될 부분 있어서 코멘트 남깁니다!

1. bg color 설정
배경 컬러 설정이 안되어있어서 하단 이미지처럼 보이게됩니다, 수정 부탁드립니다
![image](https://github.com/user-attachments/assets/20206980-f892-493d-a5a7-badadf308c4e)

2, 중복된 className
랜딩 header의 classname이 중복되는데, 이 부분 고쳐주시면 될 것 같습니다.
```js
xl:px-[72px] xl:px-[120px]
```
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T05:22:27Z
user: login: CJewon
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T06:33:47Z
user: login: CJewon
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T06:35:03Z
user: login: CJewon
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T06:35:36Z
user: login: ToKyun02
body: 랜딩페이지 부분만 돌려두면 될 것 같습니다!
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-14T07:02:20Z

Review comments:
path: src/app/page.tsx
user: login: ToKyun02
body: 테스트 용으로 쓰신 것 같은데, 원래 랜딩페이지로 돌려주시면 감사하겠습니다!
created_at: 2025-03-12T09:32:44Z
author_association: COLLABORATOR
path: src/app/page.tsx
user: login: CJewon
body: 넵 수정하겠습니다
created_at: 2025-03-12T09:40:25Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,28 @@
+import Image from 'next/image';
+import menuIcon from '@/assets/icons/hamburgerMenuIcon.svg';
+import headerLogo from '@/assets/images/headerLogo.svg';
+import userIconLight from '@/assets/icons/userIconLight.svg';
+import Link from 'next/link';
+
+export default function MainHeader() {
+  return (
+    <header className='border-b-line-100 flex items-center justify-between border-b-[1px] px-6 py-[13px] md:px-[72px] md:py-[17px] xl:px-[120px] xl:py-[22px]'>
+      <div className='flex gap-3 md:gap-6 xl:gap-9'>
+        <Image src={menuIcon} alt='메뉴 아이콘' className='md:hidden'></Image>
+        <Link href={'/'}>
+          <Image src={headerLogo} alt='헤더 로고' className='xl:h-9 xl:w-[131px]'></Image>
+        </Link>
+        <Link href={'/epigrams'} className='text-black-600 hidden leading-[26px] font-semibold md:block'>
+          피드
+        </Link>
+        <Link href={'/search'} className='text-black-600 hidden leading-[26px] font-semibold md:block'>
+          검색
+        </Link>
+      </div>
+      <Link href={'/myapage'} className='flex gap-1.5'>
+        <Image src={userIconLight} alt='유저 아이콘'></Image>
+        <p className='text-[13px] leading-[22px] font-medium text-gray-300 xl:text-[14px] xl:leading-3.5'>김코드</p>
path: src/components/ui/header/MainHeader.tsx
user: login: ToKyun02
body: `text-[13px] leading-[22px]` 보단 `text-sm`이 더 적절할 것 같습니다!
마찬가지로 `xl:text-[14px] xl:leading-3.5` 보단 `xl:text-md`가 적절한 것 같습니다!
created_at: 2025-03-12T09:40:52Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,35 @@
+'use client';
+import Image from 'next/image';
+import headerLogo from '@/assets/images/headerLogo.svg';
+import userIconDark from '@/assets/icons/userIconDark.svg';
+import searchIcon from '@/assets/icons/searchIcon.svg';
+import Link from 'next/link';
+
+export interface LandingHeaderProps {
+  showIcon?: boolean;
+}
+
+export default function LandingHeader({ showIcon = false }: LandingHeaderProps) {
+  if (showIcon) {
+    return (
+      <header className='border-b-line-100 flex items-center justify-between border-b-[1px] px-6 py-2 md:px-[72px] md:py-3 xl:px-[120px] xl:py-4'>
+        <Link href={'/search'}>
+          <Image src={searchIcon} alt='검색 아이콘' className='xl:w-9' />
+        </Link>
+        <Link href={'/'}>
+          <Image src={headerLogo} alt='헤더 로고' className='h-[36px] w-[119px] xl:h-12 xl:w-[172px]' />
+        </Link>
+        <Link href={'/mypage'}>
+          <Image src={userIconDark} alt='유저 아이콘' className='xl:w-9' />
+        </Link>
+      </header>
+    );
+  }
+  return (
+    <header className='items-between border-b-line-100 flex justify-center border-b-[1px] py-[13px]'>
path: src/components/ui/header/LandingHeader.tsx
user: login: ToKyun02
body: `border-b-[1px]`할 필요 없이 `border-b`자체가 1px입니다! 참고해주시면 될 것 같아요.

padding의 경우 홀수 단위로 주신 이유가 있으실까요? 보통 2나 4의 배수 단위로 많이해서요 ㅎㅎ
created_at: 2025-03-12T09:42:15Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,39 @@
+import LandingHeader from '@/components/ui/header/LandingHeader';
+import { Meta, StoryObj } from '@storybook/react';
+
+const meta: Meta<typeof LandingHeader> = {
+  title: 'Header/LandingHeader',
+  component: LandingHeader,
+  tags: ['autodocs'],
+  parameters: {
+    backgrounds: {
+      default: 'homeBackgroundColor',
+      values: [
+        { name: 'light', value: '#ffffff' },
+        { name: 'homeBackgroundColor', value: '#f5f7fa' },
+      ],
+    },
+  },
+  decorators: [
+    (Story) => (
+      <div className='bg-[#ffffff]'>
path: src/stories/header/LandingHeader.stories.tsx
user: login: ToKyun02
body: bg-white로 해도 될 것 같습니다!
created_at: 2025-03-12T09:42:49Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,28 @@
+import Image from 'next/image';
+import menuIcon from '@/assets/icons/hamburgerMenuIcon.svg';
+import headerLogo from '@/assets/images/headerLogo.svg';
+import userIconLight from '@/assets/icons/userIconLight.svg';
+import Link from 'next/link';
+
+export default function MainHeader() {
+  return (
+    <header className='border-b-line-100 flex items-center justify-between border-b-[1px] px-6 py-[13px] md:px-[72px] md:py-[17px] xl:px-[120px] xl:py-[22px]'>
+      <div className='flex gap-3 md:gap-6 xl:gap-9'>
+        <Image src={menuIcon} alt='메뉴 아이콘' className='md:hidden'></Image>
+        <Link href={'/'}>
+          <Image src={headerLogo} alt='헤더 로고' className='xl:h-9 xl:w-[131px]'></Image>
+        </Link>
+        <Link href={'/epigrams'} className='text-black-600 hidden leading-[26px] font-semibold md:block'>
+          피드
+        </Link>
+        <Link href={'/search'} className='text-black-600 hidden leading-[26px] font-semibold md:block'>
+          검색
+        </Link>
+      </div>
+      <Link href={'/myapage'} className='flex gap-1.5'>
+        <Image src={userIconLight} alt='유저 아이콘'></Image>
+        <p className='text-[13px] leading-[22px] font-medium text-gray-300 xl:text-[14px] xl:leading-3.5'>김코드</p>
path: src/components/ui/header/MainHeader.tsx
user: login: CJewon
body: 넵 수정하겠습니다
created_at: 2025-03-14T06:33:47Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,39 @@
+import LandingHeader from '@/components/ui/header/LandingHeader';
+import { Meta, StoryObj } from '@storybook/react';
+
+const meta: Meta<typeof LandingHeader> = {
+  title: 'Header/LandingHeader',
+  component: LandingHeader,
+  tags: ['autodocs'],
+  parameters: {
+    backgrounds: {
+      default: 'homeBackgroundColor',
+      values: [
+        { name: 'light', value: '#ffffff' },
+        { name: 'homeBackgroundColor', value: '#f5f7fa' },
+      ],
+    },
+  },
+  decorators: [
+    (Story) => (
+      <div className='bg-[#ffffff]'>
path: src/stories/header/LandingHeader.stories.tsx
user: login: CJewon
body: 넵 수정했습니다 !
created_at: 2025-03-14T06:35:03Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,35 @@
+'use client';
+import Image from 'next/image';
+import headerLogo from '@/assets/images/headerLogo.svg';
+import userIconDark from '@/assets/icons/userIconDark.svg';
+import searchIcon from '@/assets/icons/searchIcon.svg';
+import Link from 'next/link';
+
+export interface LandingHeaderProps {
+  showIcon?: boolean;
+}
+
+export default function LandingHeader({ showIcon = false }: LandingHeaderProps) {
+  if (showIcon) {
+    return (
+      <header className='border-b-line-100 flex items-center justify-between border-b-[1px] px-6 py-2 md:px-[72px] md:py-3 xl:px-[120px] xl:py-4'>
+        <Link href={'/search'}>
+          <Image src={searchIcon} alt='검색 아이콘' className='xl:w-9' />
+        </Link>
+        <Link href={'/'}>
+          <Image src={headerLogo} alt='헤더 로고' className='h-[36px] w-[119px] xl:h-12 xl:w-[172px]' />
+        </Link>
+        <Link href={'/mypage'}>
+          <Image src={userIconDark} alt='유저 아이콘' className='xl:w-9' />
+        </Link>
+      </header>
+    );
+  }
+  return (
+    <header className='items-between border-b-line-100 flex justify-center border-b-[1px] py-[13px]'>
path: src/components/ui/header/LandingHeader.tsx
user: login: CJewon
body: 피그마 시안을 보니 13px이였는데 제가 다시 한번 확인해보고 수정하도록 하겠습니다
created_at: 2025-03-14T06:35:36Z
author_association: COLLABORATOR

PR comments:
user: login: vercel[bot]
created_at: 2025-03-12T02:08:28Z
body: [vc]: #qDRDh7qqUD2OVFfT7a78dUrZwP46Yg4E0J3qMeS7Oy8=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJlcGlncmFtIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6ImVwaWdyYW0tZ2l0LWZlYXQtZXAtMTNoZWFkZXItY29tcG9uZW50LXJhazUxN3MtcHJvamVjdHMudmVyY2VsLmFwcCJ9LCJpbnNwZWN0b3JVcmwiOiJodHRwczovL3ZlcmNlbC5jb20vcmFrNTE3cy1wcm9qZWN0cy9lcGlncmFtLzNYR29ZeXJoTFNOOGFrVDVvZFNEeERqWXpacksiLCJwcmV2aWV3VXJsIjoiZXBpZ3JhbS1naXQtZmVhdC1lcC0xM2hlYWRlci1jb21wb25lbnQtcmFrNTE3cy1wcm9qZWN0cy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIiwicm9vdERpcmVjdG9yeSI6bnVsbH1dfQ==
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **epigram** | ✅ Ready ([Inspect](https://vercel.com/rak517s-projects/epigram/3XGoYyrhLSN8akT5odSDxDjYzZrK)) | [Visit Preview](https://epigram-git-feat-ep-13header-component-rak517s-projects.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/epigram-git-feat-ep-13header-component-rak517s-projects.vercel.app?via=pr-comment-feedback-link) | Mar 14, 2025 7:03am |


author_association: NONE
user: login: ToKyun02
created_at: 2025-03-13T02:09:42Z
body: 헤더에 포지션이 fixed나 sticky가 아니라서 스크롤 내릴 경우엔 안 보일 것 같습니다!

이 부분도 리팩토링 하시면 좋을 것 같슴다
author_association: COLLABORATOR