diff --git a/src/api/client/cookie.ts b/src/api/client/cookie.ts index a932eb70..f050c2c0 100644 --- a/src/api/client/cookie.ts +++ b/src/api/client/cookie.ts @@ -15,7 +15,7 @@ export const setCookie = ( const { path = '/', secure = true, - sameSite = 'Strict', + sameSite = 'Lax', // Strict에서 Lax로 변경: 외부 사이트에서 redirect 시 쿠키 전송 허용 maxAge = 86400, // 1일 httpOnly = false, } = options; diff --git a/src/app/(admin)/admin/sales-management/payment-refund/page.tsx b/src/app/(admin)/admin/sales-management/payment-refund/page.tsx index 14a7adb8..c13efa10 100644 --- a/src/app/(admin)/admin/sales-management/payment-refund/page.tsx +++ b/src/app/(admin)/admin/sales-management/payment-refund/page.tsx @@ -26,6 +26,7 @@ const PAYMENT_HISTORY_TYPE_MAP: Record< } > = { PAYMENT_REQUESTED: { label: '결제대기', color: 'blue' }, + PAYMENT_WAITING_FOR_DEPOSIT: { label: '입금대기', color: 'blue' }, PAYMENT_SUCCESS: { label: '결제완료', color: 'green' }, PAYMENT_FAILED: { label: '결제실패', color: 'red' }, PAYMENT_CANCELED: { label: '결제취소', color: 'red' }, diff --git a/src/app/(service)/(my)/payment-management/page.tsx b/src/app/(service)/(my)/payment-management/page.tsx index cb067c97..76164e3b 100644 --- a/src/app/(service)/(my)/payment-management/page.tsx +++ b/src/app/(service)/(my)/payment-management/page.tsx @@ -33,6 +33,7 @@ const TRANSACTION_TYPE_MAP: Record< } > = { PAYMENT_REQUESTED: { label: '결제대기', color: 'blue' }, + PAYMENT_WAITING_FOR_DEPOSIT: { label: '입금대기', color: 'blue' }, PAYMENT_SUCCESS: { label: '결제완료', color: 'green' }, PAYMENT_FAILED: { label: '결제실패', color: 'red' }, PAYMENT_CANCELED: { label: '결제취소', color: 'red' }, diff --git a/src/app/(service)/payment/complete/page.tsx b/src/app/(service)/payment/complete/page.tsx deleted file mode 100644 index 2a6def22..00000000 --- a/src/app/(service)/payment/complete/page.tsx +++ /dev/null @@ -1,126 +0,0 @@ -'use client'; - -import Image from 'next/image'; -import { useRouter } from 'next/navigation'; -import PageContainer from '@/components/layout/page-container'; -import Button from '@/components/ui/button'; - -interface PaymentResult { - orderName: string; - productAmount: number; - paymentMethod: string; - totalAmount: number; -} - -// ✅ 가데이터 -const MOCK_PAYMENT_RESULT: PaymentResult = { - orderName: '1일코테문풀 인증 챌린지', - productAmount: 35000, - paymentMethod: '카드결제', - totalAmount: 35000, -}; - -export default function PaymentCompletePage() { - const router = useRouter(); - const data = MOCK_PAYMENT_RESULT; - - const formatKRW = (n: number) => `${n.toLocaleString('ko-KR')}원`; - - return ( - -
- {/* 아이콘 */} -
-
- success -
-
- - {/* 타이틀 */} -
-

- 스터디 수강 신청이 완료되었습니다. -

-

- 수강/학습 내역과 결제 내역은 마이페이지에서 확인하실 수 있습니다. -

-
- - {/* 정보 카드 */} -
-
- - -
결제 정보
- - - -
- - - - -
- - {/* 버튼 */} -
- - - -
-
-
- - ); -} - -function Row({ - label, - value, - bold, - strong, -}: { - label: string; - value: string; - bold?: boolean; - strong?: boolean; -}) { - return ( -
-
- {label} -
-
- {value} -
-
- ); -} diff --git a/src/components/card/mission-card.tsx b/src/components/card/mission-card.tsx index 17ebb103..50a23763 100644 --- a/src/components/card/mission-card.tsx +++ b/src/components/card/mission-card.tsx @@ -1,6 +1,8 @@ 'use client'; +import dayjs from 'dayjs'; import { ComponentProps } from 'react'; + import { MissionListResponse } from '@/api/openapi/models'; import Badge from '@/components/ui/badge'; import Button from '@/components/ui/button'; @@ -42,9 +44,8 @@ const STATUS_CONFIG = { function formatDate(dateString?: string) { if (!dateString) return ''; - const date = new Date(dateString); - return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; + return dayjs(dateString).format('YYYY-MM-DD'); } function getDeadlineInfo(endDate?: string): { @@ -53,15 +54,13 @@ function getDeadlineInfo(endDate?: string): { } | null { if (!endDate) return null; - const now = new Date(); - const end = new Date(endDate); - end.setHours(23, 59, 59, 999); + const now = dayjs(); + const end = dayjs(endDate).endOf('day'); - const diffMs = end.getTime() - now.getTime(); - if (diffMs < 0) return null; + if (end.isBefore(now)) return null; - const diffHours = diffMs / (1000 * 60 * 60); - const diffDays = Math.ceil(diffMs / (1000 * 60 * 60 * 24)); + const diffHours = end.diff(now, 'hour'); + const diffDays = Math.ceil(end.diff(now, 'day', true)); if (diffHours <= 24) { return { text: '오늘 제출 마감', isUrgent: true }; diff --git a/src/components/contents/homework-detail-content.tsx b/src/components/contents/homework-detail-content.tsx index 67df9c41..2f3a103c 100644 --- a/src/components/contents/homework-detail-content.tsx +++ b/src/components/contents/homework-detail-content.tsx @@ -10,7 +10,6 @@ import type { import Avatar from '@/components/ui/avatar'; import Button from '@/components/ui/button'; import MoreMenu from '@/components/ui/dropdown/more-menu'; -import { useUserStore } from '@/stores/useUserStore'; import ConfirmDeleteModal from '@/features/study/group/ui/confirm-delete-modal'; import { useDeleteHomework, @@ -22,6 +21,7 @@ import { useUpdatePeerReview, } from '@/hooks/queries/peer-review-api'; import { useIsLeader } from '@/stores/useLeaderStore'; +import { useUserStore } from '@/stores/useUserStore'; import DeleteHomeworkModal from '../modals/delete-homework-modal'; import EditHomeworkModal from '../modals/edit-homework-modal'; diff --git a/src/components/pages/group-study-list-page.tsx b/src/components/pages/group-study-list-page.tsx index 69ea9aaf..717a09f4 100644 --- a/src/components/pages/group-study-list-page.tsx +++ b/src/components/pages/group-study-list-page.tsx @@ -14,11 +14,11 @@ import StudyFilter, { import StudySearch from '@/components/filtering/study-search'; import PageContainer from '@/components/layout/page-container'; import Button from '@/components/ui/button'; +import { useAuth } from '@/hooks/common/use-auth'; import { useGetStudies } from '@/hooks/queries/study-query'; import GroupStudyFormModal from '../../features/study/group/ui/group-study-form-modal'; import GroupStudyPagination from '../../features/study/group/ui/group-study-pagination'; import GroupStudyList from '../lists/group-study-list'; -import { useAuth } from '@/hooks/common/use-auth'; const PAGE_SIZE = 15; diff --git a/src/components/pages/premium-study-list-page.tsx b/src/components/pages/premium-study-list-page.tsx index d6f61a9f..0d88fb46 100644 --- a/src/components/pages/premium-study-list-page.tsx +++ b/src/components/pages/premium-study-list-page.tsx @@ -17,8 +17,8 @@ import PremiumStudyList from '@/components/premium/premium-study-list'; import PremiumStudyPagination from '@/components/premium/premium-study-pagination'; import Button from '@/components/ui/button'; import GroupStudyFormModal from '@/features/study/group/ui/group-study-form-modal'; -import { useGetStudies } from '@/hooks/queries/study-query'; import { useAuth } from '@/hooks/common/use-auth'; +import { useGetStudies } from '@/hooks/queries/study-query'; const PAGE_SIZE = 15; diff --git a/src/components/summary/study-info-summary.tsx b/src/components/summary/study-info-summary.tsx index 854c0f89..0283c116 100644 --- a/src/components/summary/study-info-summary.tsx +++ b/src/components/summary/study-info-summary.tsx @@ -132,7 +132,6 @@ export default function SummaryStudyInfo({ data }: Props) { }; const isApplyDisabled = - !isLoggedIn || isLeader || myApplicationStatus?.status !== 'NONE' || groupStudyStatus !== 'RECRUITING' || diff --git a/src/features/auth/model/use-auth-mutation.ts b/src/features/auth/model/use-auth-mutation.ts index 13c37587..4506540b 100644 --- a/src/features/auth/model/use-auth-mutation.ts +++ b/src/features/auth/model/use-auth-mutation.ts @@ -6,8 +6,8 @@ import { useRouter } from 'next/navigation'; import { deleteCookie, getCookie } from '@/api/client/cookie'; import { logout, signUp, uploadProfileImage } from '@/features/auth/api/auth'; import { hashValue } from '@/utils/hash'; -import { useUserStore } from '../../../stores/useUserStore'; import { SignUpRequest, SignUpResponse } from './types'; +import { useUserStore } from '../../../stores/useUserStore'; // 회원가입 요청 커스텀 훅 export const useSignUpMutation = () => { diff --git a/src/features/my-page/ui/my-study-info-card.tsx b/src/features/my-page/ui/my-study-info-card.tsx index 8ece3fe2..6ccd6258 100644 --- a/src/features/my-page/ui/my-study-info-card.tsx +++ b/src/features/my-page/ui/my-study-info-card.tsx @@ -1,3 +1,4 @@ +import dayjs from 'dayjs'; import Image from 'next/image'; import Link from 'next/link'; import { IoMdPeople } from 'react-icons/io'; @@ -5,7 +6,6 @@ import { LuDot } from 'react-icons/lu'; import Badge from '@/components/ui/badge'; import Button from '@/components/ui/button'; import { MemberStudyItem } from '@/features/study/group/api/group-study-types'; -import { formatYYYYMMDD } from '@/utils/time'; interface MyStudyInfoCardProps extends MemberStudyItem { type: 'GROUP_STUDY'; @@ -22,8 +22,8 @@ export default function MyStudyInfoCard({ studyRole, title, }: MyStudyInfoCardProps) { - const startDate = formatYYYYMMDD(startTime, 'dot'); - const endDate = endTime ? formatYYYYMMDD(endTime, 'dot') : null; + const startDate = dayjs(startTime).format('YYYY.MM.DD'); + const endDate = endTime ? dayjs(endTime).format('YYYY.MM.DD') : null; return (
  • diff --git a/src/middleware.ts b/src/middleware.ts index e9f9a8cf..b55d6617 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -118,7 +118,7 @@ export async function middleware(request: NextRequest) { // 갱신 성공 response.cookies.set('accessToken', newAccessToken, { secure: true, - sameSite: 'strict', + sameSite: 'lax', // strict에서 lax로 변경: 외부 사이트에서 redirect 시 쿠키 전송 허용 path: '/', }); } else { @@ -156,6 +156,7 @@ export const config = { '/my-study', '/my-study-review', '/sign-up', + '/payment/:path*', // 결제 관련 모든 경로 '/admin/:path*', ], }; diff --git a/src/mocks/homework-mock-data.ts b/src/mocks/homework-mock-data.ts new file mode 100644 index 00000000..e89391be --- /dev/null +++ b/src/mocks/homework-mock-data.ts @@ -0,0 +1,426 @@ +import type { + HomeworkResponseDto, + EvaluationResponse, + PeerReviewResponse, + MissionResponseDto, + MissionListResponse, + GradeDto, +} from '@/api/openapi/models'; + +// Mock 평가 등급 데이터 +export const mockEvaluationGrades: GradeDto[] = [ + { code: 'A_PLUS', label: 'A+', score: 95, orderNum: 1 }, + { code: 'A_MINUS', label: 'A-', score: 90, orderNum: 2 }, + { code: 'B_PLUS', label: 'B+', score: 85, orderNum: 3 }, + { code: 'B_MINUS', label: 'B-', score: 80, orderNum: 4 }, + { code: 'C_PLUS', label: 'C+', score: 75, orderNum: 5 }, + { code: 'C_MINUS', label: 'C-', score: 70, orderNum: 6 }, + { code: 'F', label: 'F', score: 0, orderNum: 7 }, +]; + +// Mock 피어 리뷰 데이터 +export const mockPeerReviews: PeerReviewResponse[] = [ + { + peerReviewId: 1, + homeworkId: 1, + reviewerId: 2, + reviewerNickname: '김철수', + reviewerProfileImage: { + resizedImages: [ + { + resizedImageUrl: '/profile-default.svg', + }, + ], + }, + comment: + '과제 내용이 정말 잘 정리되어 있네요! 특히 핵심 개념을 명확하게 설명한 부분이 좋았습니다.', + createdAt: '2026-01-07T10:30:00', + updatedAt: '2026-01-07T10:30:00', + updated: false, + }, + { + peerReviewId: 2, + homeworkId: 1, + reviewerId: 3, + reviewerNickname: '박영희', + reviewerProfileImage: { + resizedImages: [ + { + resizedImageUrl: '/profile-default.svg', + }, + ], + }, + comment: + '코드 예제가 이해하기 쉬웠어요. 다음에는 더 복잡한 케이스도 다뤄보면 좋을 것 같습니다!', + createdAt: '2026-01-07T14:20:00', + updatedAt: '2026-01-07T14:20:00', + updated: false, + }, +]; + +// Mock 평가 데이터 +export const mockEvaluation: EvaluationResponse = { + evaluationId: 1, + homeworkId: 1, + grade: { + gradeCode: 'A_PLUS', + gradeLabel: 'A+', + gradeScore: 95, + }, + comment: + '과제를 매우 성실하게 수행했습니다. 개념 이해도가 높고 코드 품질도 우수합니다. 계속 이런 식으로 학습하면 좋은 결과가 있을 것입니다!', + createdAt: '2026-01-07T09:00:00', + updatedAt: '2026-01-07T09:00:00', + updated: false, +}; + +// Mock 숙제 상세 데이터 +export const mockHomeworkDetail: HomeworkResponseDto = { + homeworkId: 1, + submitterId: 1, + submitterNickname: '홍길동', + submitterProfileImage: { + resizedImages: [ + { + resizedImageUrl: '/profile-default.svg', + }, + ], + }, + submitted: true, + submissionTime: '2026-01-06T23:45:00', + homeworkContent: { + textContent: `이번 주 학습 내용을 정리했습니다. + +1. React Hooks의 기본 개념 + - useState: 상태 관리를 위한 기본 훅 + - useEffect: 사이드 이펙트 처리 + - useContext: 전역 상태 관리 + +2. Custom Hooks 작성 + - 재사용 가능한 로직 분리 + - 컴포넌트 간 로직 공유 + +3. 실습 내용 + - Todo 앱 만들기 + - API 호출 및 데이터 페칭 + - 에러 핸들링 구현 + +배운 내용을 바탕으로 간단한 프로젝트를 만들어보았고, 많은 것을 배울 수 있었습니다.`, + optionalContent: { + link: 'https://github.com/example/react-hooks-practice', + }, + }, + evaluation: undefined, // 초기에는 평가 없음 + peerReviews: mockPeerReviews, +}; + +// 평가 완료된 숙제 데이터 +export const mockHomeworkWithEvaluation: HomeworkResponseDto = { + ...mockHomeworkDetail, + evaluation: mockEvaluation, +}; + +// Mock 미션 목록 데이터 +export const mockMissions: MissionListResponse[] = [ + { + missionId: 1, + weekNum: 1, + title: 'React Hooks 학습', + startDate: '2026-01-01', + endDate: '2026-01-07', + status: 'IN_PROGRESS', + maxEvaluationCount: 10, + evaluatedCount: 2, + }, + { + missionId: 2, + weekNum: 2, + title: 'TypeScript 기초', + startDate: '2026-01-08', + endDate: '2026-01-14', + status: 'NOT_STARTED', + maxEvaluationCount: 10, + evaluatedCount: 0, + }, + { + missionId: 3, + weekNum: 0, + title: 'JavaScript ES6+ 복습', + startDate: '2025-12-25', + endDate: '2025-12-31', + status: 'ENDED', + maxEvaluationCount: 10, + evaluatedCount: 10, + }, +]; + +// Mock 미션 상세 데이터 +export const mockMissionDetail: MissionResponseDto = { + missionId: 1, + weekNum: 1, + missionTitle: 'React Hooks 학습', + missionGuide: `이번 주는 React Hooks에 대해 학습합니다. + +[학습 목표] +1. useState, useEffect, useContext 이해하기 +2. Custom Hooks 만들어보기 +3. 실전 프로젝트에 적용하기 + +[제출 방법] +- 학습한 내용을 정리하여 제출해주세요 +- 실습한 코드를 GitHub에 올리고 링크를 첨부해주세요 +- 최소 100자 이상 작성해주세요`, + missionStartDate: '2026-01-01', + missionEndDate: '2026-01-07', + status: 'IN_PROGRESS', + currentHomeworkSubmissionCount: 8, + maxHomeworkSubmissionCount: 10, + homeworks: [ + { + homeworkId: 1, + submitterId: 1, + submitterNickname: '홍길동', + submitterProfileImage: { + resizedImages: [{ resizedImageUrl: '/profile-default.svg' }], + }, + submissionTime: '2026-01-06T23:45:00', + homeworkStatus: 'EVALUATION_COMPLETED', + evaluation: { + evaluationGradeLabel: 'A+', + }, + }, + { + homeworkId: 2, + submitterId: 2, + submitterNickname: '김철수', + submitterProfileImage: { + resizedImages: [{ resizedImageUrl: '/profile-default.svg' }], + }, + submissionTime: '2026-01-06T20:30:00', + homeworkStatus: 'SUBMITTED', + }, + { + homeworkId: 3, + submitterId: 3, + submitterNickname: '박영희', + submitterProfileImage: { + resizedImages: [{ resizedImageUrl: '/profile-default.svg' }], + }, + submissionTime: '2026-01-06T18:15:00', + homeworkStatus: 'SUBMITTED', + }, + { + homeworkId: 4, + submitterId: 4, + submitterNickname: '이민수', + submitterProfileImage: { + resizedImages: [{ resizedImageUrl: '/profile-default.svg' }], + }, + submissionTime: '2026-01-06T22:00:00', + homeworkStatus: 'EVALUATION_COMPLETED', + evaluation: { + evaluationGradeLabel: 'B+', + }, + }, + { + homeworkId: 5, + submitterId: 5, + submitterNickname: '정수현', + submitterProfileImage: { + resizedImages: [{ resizedImageUrl: '/profile-default.svg' }], + }, + submissionTime: '2026-01-07T01:20:00', + homeworkStatus: 'SUBMITTED', + }, + { + homeworkId: undefined, + submitterId: 6, + submitterNickname: '최지원', + submitterProfileImage: { + resizedImages: [{ resizedImageUrl: '/profile-default.svg' }], + }, + submissionTime: undefined, + homeworkStatus: 'NOT_SUBMITTED', + }, + { + homeworkId: 7, + submitterId: 7, + submitterNickname: '강태영', + submitterProfileImage: { + resizedImages: [{ resizedImageUrl: '/profile-default.svg' }], + }, + submissionTime: '2026-01-06T16:45:00', + homeworkStatus: 'SUBMITTED', + }, + { + homeworkId: 8, + submitterId: 8, + submitterNickname: '윤서진', + submitterProfileImage: { + resizedImages: [{ resizedImageUrl: '/profile-default.svg' }], + }, + submissionTime: '2026-01-07T02:10:00', + homeworkStatus: 'SUBMITTED', + }, + { + homeworkId: undefined, + submitterId: 9, + submitterNickname: '임하늘', + submitterProfileImage: { + resizedImages: [{ resizedImageUrl: '/profile-default.svg' }], + }, + submissionTime: undefined, + homeworkStatus: 'NOT_SUBMITTED', + }, + { + homeworkId: 10, + submitterId: 10, + submitterNickname: '송민재', + submitterProfileImage: { + resizedImages: [{ resizedImageUrl: '/profile-default.svg' }], + }, + submissionTime: '2026-01-06T21:30:00', + homeworkStatus: 'SUBMITTED', + }, + ], +}; + +// Mock 데이터를 localStorage에 저장하고 관리하는 헬퍼 함수들 +export const getMockHomework = (homeworkId: number): HomeworkResponseDto => { + const stored = localStorage.getItem(`homework_${homeworkId}`); + if (stored) { + return JSON.parse(stored); + } + + // 미션 목록 데이터와 동기화: homeworkId 1과 4는 평가 완료 상태 + if (homeworkId === 1 || homeworkId === 4) { + return { + ...mockHomeworkDetail, + homeworkId, + submitterId: homeworkId, + submitterNickname: homeworkId === 1 ? '홍길동' : '이민수', + evaluation: + homeworkId === 1 + ? mockEvaluation + : { + evaluationId: 2, + homeworkId: 4, + grade: { + gradeCode: 'B_PLUS', + gradeLabel: 'B+', + gradeScore: 85, + }, + comment: + '과제를 잘 수행했습니다. 기본 개념은 잘 이해하고 있으나, 조금 더 깊이 있는 학습이 필요합니다.', + createdAt: '2026-01-07T10:00:00', + updatedAt: '2026-01-07T10:00:00', + updated: false, + }, + }; + } + + // 기본 mock 데이터 반환 (평가 없음) + return { + ...mockHomeworkDetail, + homeworkId, + submitterId: homeworkId, + submitterNickname: `테스트유저${homeworkId}`, + }; +}; + +export const saveMockHomework = (homework: HomeworkResponseDto) => { + localStorage.setItem( + `homework_${homework.homeworkId}`, + JSON.stringify(homework), + ); +}; + +export const getMockPeerReviews = ( + homeworkId: number, +): PeerReviewResponse[] => { + const stored = localStorage.getItem(`peerReviews_${homeworkId}`); + if (stored) { + return JSON.parse(stored); + } + + return mockPeerReviews; +}; + +export const saveMockPeerReviews = ( + homeworkId: number, + peerReviews: PeerReviewResponse[], +) => { + localStorage.setItem( + `peerReviews_${homeworkId}`, + JSON.stringify(peerReviews), + ); +}; + +export const addMockPeerReview = ( + homeworkId: number, + newReview: Omit< + PeerReviewResponse, + 'peerReviewId' | 'createdAt' | 'updatedAt' + >, +): PeerReviewResponse => { + const existing = getMockPeerReviews(homeworkId); + const newId = Math.max(...existing.map((r) => r.peerReviewId || 0), 0) + 1; + const review: PeerReviewResponse = { + ...newReview, + peerReviewId: newId, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + updated: false, + }; + saveMockPeerReviews(homeworkId, [...existing, review]); + + return review; +}; + +export const updateMockPeerReview = ( + peerReviewId: number, + comment: string, +): PeerReviewResponse | null => { + // 모든 숙제의 피어 리뷰를 순회하며 찾기 + const keys = Object.keys(localStorage).filter((k) => + k.startsWith('peerReviews_'), + ); + for (const key of keys) { + const reviews: PeerReviewResponse[] = JSON.parse( + localStorage.getItem(key) || '[]', + ); + const index = reviews.findIndex((r) => r.peerReviewId === peerReviewId); + if (index !== -1) { + reviews[index] = { + ...reviews[index], + comment, + updatedAt: new Date().toISOString(), + updated: true, + }; + localStorage.setItem(key, JSON.stringify(reviews)); + + return reviews[index]; + } + } + + return null; +}; + +export const deleteMockPeerReview = (peerReviewId: number): boolean => { + const keys = Object.keys(localStorage).filter((k) => + k.startsWith('peerReviews_'), + ); + for (const key of keys) { + const reviews: PeerReviewResponse[] = JSON.parse( + localStorage.getItem(key) || '[]', + ); + const filtered = reviews.filter((r) => r.peerReviewId !== peerReviewId); + if (filtered.length !== reviews.length) { + localStorage.setItem(key, JSON.stringify(filtered)); + + return true; + } + } + + return false; +}; diff --git a/src/widgets/home/header.tsx b/src/widgets/home/header.tsx index 9d3e215d..5c5da095 100644 --- a/src/widgets/home/header.tsx +++ b/src/widgets/home/header.tsx @@ -1,5 +1,6 @@ import Image from 'next/image'; import Link from 'next/link'; +import HeaderNav from '@/components/layout/header-nav'; import NotificationDropdown from '@/components/modals/notification-dropdown'; import Button from '@/components/ui/button'; import { getUserProfileInServer } from '@/entities/user/api/get-user-profile.server'; @@ -7,7 +8,6 @@ import HeaderUserDropdown from '@/features/auth/ui/header-user-dropdown'; import LoginModal from '@/features/auth/ui/login-modal'; import { getServerCookie } from '@/utils/server-cookie'; import { isNumeric } from '@/utils/validation'; -import HeaderNav from '@/components/layout/header-nav'; export default async function Header() { const memberIdStr = await getServerCookie('memberId');