Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6eb7ed6
feat: 홈 화면 기본 구조 생성 (헤더, 일기 박스)
wjdalss21 Jun 17, 2026
f98f8f3
feat: Header variant 분리 (logo/title) 및 홈 화면 적용
wjdalss21 Jun 17, 2026
d959392
feat: 사건기록 페이지 생성 및 로고 헤더 적용 (/records)
wjdalss21 Jun 17, 2026
5a6643e
fix: diaryBox 고정 폭을 max-width + width 100%로 반응형 처리
wjdalss21 Jun 17, 2026
a04b781
feat: 감정일기 작성 버튼 /diary/new 네비게이션 연결
wjdalss21 Jun 17, 2026
6ab4d7e
feat: 홈 화면 캐릭터 이미지 교체 및 위치 조정
wjdalss21 Jun 17, 2026
24aed23
fix: 홈 화면 코드래빗 피드백 반영
wjdalss21 Jun 18, 2026
f67c9e9
refactor: 홈 화면 typography 믹신 적용
wjdalss21 Jun 18, 2026
2b194f9
fix: 비로그인 알아보기 박스 위치 수정
wjdalss21 Jun 18, 2026
e5188f7
feat: 홈 화면에 통계 섹션 및 구분선 통합
wjdalss21 Jun 18, 2026
f2154c6
chore: 개발 편의용 로그인 상태 강제 설정 (배포 전 제거 필요)
wjdalss21 Jun 18, 2026
47e7138
feat: 홈 화면 진행중인 사건 섹션 UI 구현
wjdalss21 Jun 18, 2026
a31fe0e
fix: dev 머지 충돌 해결 (ActiveCasesSection 유지)
wjdalss21 Jun 18, 2026
f02cec2
fix: 진행중인 사건 카드 수정 - CaseCard 원본 구조 유지, 좌측 컬러바 제거, Avatar 좌측 배치
wjdalss21 Jun 18, 2026
e92b35f
fix: CaseCard preview 텍스트 컬러 black-700으로 수정
wjdalss21 Jun 18, 2026
804f450
fix: 진행중인 사건 섹션 내 진행중 뱃지 제거
wjdalss21 Jun 18, 2026
fd1b1f3
fix: 진행중인 사건 카드 푸터 레이아웃 및 외곽선 black-700 2px inset 적용
wjdalss21 Jun 18, 2026
8561f05
fix: 진행중인 사건 카드 preview-footer 간격 8px 조정
wjdalss21 Jun 18, 2026
cca1afc
Merge remote-tracking branch 'origin/dev' into feature/homepage-jm
wjdalss21 Jun 18, 2026
2afe223
fix: 코드래빗 리뷰 반영 - 린트, loading/error 상태 처리, onClick li로 이동
wjdalss21 Jun 18, 2026
cff2117
Merge remote-tracking branch 'origin/dev' into feature/homepage-jm
wjdalss21 Jun 18, 2026
28c7139
chore: 홈 화면 캐릭터 이미지 추가
wjdalss21 Jun 18, 2026
200262e
refactor: 홈 페이지를 /home에서 / 루트 경로로 이동
wjdalss21 Jun 18, 2026
692170e
Merge remote-tracking branch 'origin/dev' into feature/homepage-jm
wjdalss21 Jun 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/images/characters/character-home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 4 additions & 61 deletions src/app/(page)/home/page.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,6 @@
import Image from 'next/image'
import Link from 'next/link'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import Header from '@/components/layout/Header'
import StatsCategorySection from '@/components/home/StatsCategorySection'
import styles from './page.module.scss'
import { redirect } from 'next/navigation'

export default async function HomePage() {
const session = await getServerSession(authOptions)
// TODO: [개발 완료 후 반드시 제거] 개발 편의를 위해 로그인 상태 강제 설정
// 실제 배포 전 아래 줄을 삭제하고 const isLoggedIn = !!session 으로 교체할 것
const isLoggedIn = true
const userName = session?.user?.name ?? '테스트유저'

return (
<div className={styles.page}>
<Header variant="logo" />

<Image
src="/images/characters/character-home.png"
alt="말해부엉 캐릭터"
width={169}
height={138}
className={styles.characterImage}
/>

<main className={styles.container}>
{/* 인사 */}
<section className={styles.greeting}>
<p className={styles.userName}>{isLoggedIn ? `${userName}님` : '안녕하세요'}</p>
<p className={styles.greetingText}>오늘 감정은 어떠신가요?</p>
</section>

{/* 오늘의 일기 박스 */}
<Link href="/diary/new" className={styles.diaryBox} aria-label="감정일기 작성">
<div className={styles.diaryTextGroup}>
<p className={styles.diaryTitle}>오늘의 일기를 적어보세요</p>
<p className={styles.diarySubtitle}>감정일기 작성하러가기</p>
</div>
<span className={styles.diaryButton} aria-hidden="true">+</span>
</Link>

{/* 고민 카테고리 TOP4 */}
<StatsCategorySection />

{/* 구분선 */}
<div className={styles.divider} />

{/* 진행중인 사건(로그인) or 말해부엉 알아보기(비로그인) */}
{!isLoggedIn && (
<Link href="/login" className={styles.introBox} aria-label="말해부엉 알아보기">
<div className={styles.diaryTextGroup}>
<p className={styles.diaryTitle}>말해부엉이 궁금하신가요?</p>
<p className={styles.diarySubtitle}>말해부엉 알아보기</p>
</div>
<span className={styles.introArrow} aria-hidden="true">›</span>
</Link>
)}
</main>
</div>
)
// 홈 페이지가 /에서 서빙되므로 기존 /home 경로 접근 시 리다이렉트
export default function HomeRedirect() {
redirect('/')
}
2 changes: 1 addition & 1 deletion src/app/(page)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function LoginPage() {
<div className={styles.footer}>
<Button
className={styles.kakaoButton}
onClick={() => signIn('kakao', { callbackUrl: '/home' })}
onClick={() => signIn('kakao', { callbackUrl: '/' })}
>
<KakaoIcon />
카카오로 로그인 하기
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@
margin-right: -16px;
}

// 진행중인 사건 섹션 (구분선 아래 gap 20px = container gap 16 + 4)
.activeCasesSection {
margin-top: 4px;
}

// 비로그인 알아보기 박스
.introBox {
display: flex;
Expand Down
103 changes: 65 additions & 38 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,68 @@
import Spinner from '@/components/ui/Spinner';
import Avatar, { AvatarGroup } from '@/components/ui/Avatar';
import Image from 'next/image'
import Link from 'next/link'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import Header from '@/components/layout/Header'
import StatsCategorySection from '@/components/home/StatsCategorySection'
import ActiveCasesSection from '@/components/home/ActiveCasesSection'
import styles from './page.module.scss'

export default async function HomePage() {
const session = await getServerSession(authOptions)
// TODO: [개발 완료 후 반드시 제거] 개발 편의를 위해 로그인 상태 강제 설정
// 실제 배포 전 아래 줄을 삭제하고 const isLoggedIn = !!session 으로 교체할 것
const isLoggedIn = true
Comment on lines +12 to +14

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

하드코딩된 isLoggedIn = true로 인해 비로그인 UI 경로가 테스트 불가

isLoggedIn이 항상 true로 고정되어 있어 Lines 56-64의 비로그인 상태 UI(말해부엉 알아보기 링크)가 절대 렌더링되지 않습니다. 미들웨어의 DEV_BYPASS와 함께 배포 전 반드시 제거해야 합니다.

두 파일의 개발용 우회 로직을 동시에 추적할 수 있도록 하나의 이슈나 체크리스트로 관리하는 것을 권장합니다.

✅ 배포 전 변경 사항
-  // TODO: [개발 완료 후 반드시 제거] 개발 편의를 위해 로그인 상태 강제 설정
-  // 실제 배포 전 아래 줄을 삭제하고 const isLoggedIn = !!session 으로 교체할 것
-  const isLoggedIn = true
+  const isLoggedIn = !!session
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// TODO: [개발 완료 후 반드시 제거] 개발 편의를 위해 로그인 상태 강제 설정
// 실제 배포 전 아래 줄을 삭제하고 const isLoggedIn = !!session 으로 교체할 것
const isLoggedIn = true
const isLoggedIn = !!session
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/page.tsx` around lines 12 - 14, Replace the hardcoded `const
isLoggedIn = true` assignment in the page.tsx file with the actual session-based
logic `const isLoggedIn = !!session` to properly reflect the user's
authentication state. Remove the TODO comments above this line that indicate
this is temporary development code. Additionally, search for similar development
bypass logic such as DEV_BYPASS in middleware files and ensure all temporary
authentication shortcuts are tracked together for removal before deployment.

const userName = session?.user?.name ?? '테스트유저'

export default function RootPage() {
return (
<main style={{ padding: '40px', display: 'flex', flexDirection: 'column', gap: '40px' }}>
<section>
<h2>Spinner</h2>
<Spinner />
</section>
<section>
<h2>Avatar — 기본</h2>
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
<Avatar size="s" />
<Avatar size="m" />
<Avatar size="l" />
<Avatar src="https://i.pravatar.cc/150?img=1" alt="사용자1" size="s" />
<Avatar src="https://i.pravatar.cc/150?img=1" alt="사용자1" size="m" />
<Avatar src="https://i.pravatar.cc/150?img=1" alt="사용자1" size="l" />
</div>
</section>
<section>
<h2>AvatarGroup</h2>
<div style={{ display: 'flex', justifyContent: 'flex-start', gap: '16px' }}>
<AvatarGroup size="s">
<Avatar />
<Avatar />
</AvatarGroup>
<AvatarGroup size="s">
<Avatar src="https://i.pravatar.cc/150?img=1" alt="사용자1" />
<Avatar src="https://i.pravatar.cc/150?img=2" alt="사용자2" />
</AvatarGroup>
<AvatarGroup size="m">
<Avatar src="https://i.pravatar.cc/150?img=1" alt="사용자1" />
<Avatar src="https://i.pravatar.cc/150?img=2" alt="사용자2" />
</AvatarGroup>
</div>
</section>
</main>
);
<div className={styles.page}>
<Header variant="logo" />

<Image
src="/images/characters/character-home.png"
alt="말해부엉 캐릭터"
width={169}
height={138}
className={styles.characterImage}
/>

<main className={styles.container}>
{/* 인사 */}
<section className={styles.greeting}>
<p className={styles.userName}>{isLoggedIn ? `${userName}님` : '안녕하세요'}</p>
<p className={styles.greetingText}>오늘 감정은 어떠신가요?</p>
</section>

{/* 오늘의 일기 박스 */}
<Link href="/diary/new" className={styles.diaryBox} aria-label="감정일기 작성">
<div className={styles.diaryTextGroup}>
<p className={styles.diaryTitle}>오늘의 일기를 적어보세요</p>
<p className={styles.diarySubtitle}>감정일기 작성하러가기</p>
</div>
<span className={styles.diaryButton} aria-hidden="true">+</span>
</Link>

{/* 고민 카테고리 TOP4 */}
<StatsCategorySection />

{/* 구분선 */}
<div className={styles.divider} />

{/* 진행중인 사건(로그인) or 말해부엉 알아보기(비로그인) */}
{isLoggedIn ? (
<div className={styles.activeCasesSection}>
<ActiveCasesSection />
</div>
) : (
<Link href="/login" className={styles.introBox} aria-label="말해부엉 알아보기">
<div className={styles.diaryTextGroup}>
<p className={styles.diaryTitle}>말해부엉이 궁금하신가요?</p>
<p className={styles.diarySubtitle}>말해부엉 알아보기</p>
</div>
<span className={styles.introArrow} aria-hidden="true">›</span>
</Link>
)}
</main>
</div>
)
}
73 changes: 73 additions & 0 deletions src/components/home/ActiveCasesSection.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
@use '@/styles/abstracts/variables' as v;
@use '@/styles/abstracts/mixins' as m;
@use '@/styles/abstracts/functions' as fn;

.section {
display: flex;
flex-direction: column;
gap: fn.r(16);
}

.title {
@include m.text-title-s;

color: v.$color-black-700;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

.list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: fn.r(12);
}

.cardWrapper {
display: flex;
flex-direction: column;
box-shadow: inset 0 0 0 2px v.$color-black-700;
border-radius: fn.r(12);
background-color: var(--bg-surface);
overflow: hidden;
cursor: pointer;

&:active {
opacity: 0.8;
}

// CaseCard(article) 자체 border/background/radius 제거 — wrapper가 카드 역할을 함
> article {
border: none;
border-radius: 0;
background-color: transparent;
padding-bottom: 0;

// 빈 date 태그 공간 제거
time { display: none; }

// preview → footer 간격 8px
> p { margin-bottom: fn.r(8); }
}
}

.cardFooter {
display: flex;
align-items: center;
gap: fn.r(8);
padding: 0 fn.r(16) fn.r(16);
}

.cardDate {
@include m.text-label-s;

color: v.$color-black-400;
}

.empty {
@include m.text-body-s;

color: v.$color-black-400;
text-align: center;
padding: fn.r(24) 0;
}
65 changes: 65 additions & 0 deletions src/components/home/ActiveCasesSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use client'

import { useRouter } from 'next/navigation'
import CaseCard from '@/components/ui/CaseCard'
import Avatar, { AvatarGroup } from '@/components/ui/Avatar'
import { useActiveCases } from '@/hooks/useActiveCases'
import styles from './ActiveCasesSection.module.scss'

function formatDate(isoString: string): string {
return isoString.slice(2, 10)
}

export default function ActiveCasesSection() {
const router = useRouter()
const { data: cases = [], isLoading, isError } = useActiveCases()

if (isLoading) return null

if (isError) return (
<section className={styles.section}>
<h2 className={styles.title}>진행중인 사건</h2>
<p className={styles.empty}>사건 목록을 불러올 수 없어요</p>
</section>
)

return (
<section className={styles.section}>
<h2 className={styles.title}>진행중인 사건</h2>

{cases.length === 0 ? (
<p className={styles.empty}>아직 진행중인 사건이 없어요</p>
) : (
<ul className={styles.list}>
{cases.map((item) => (
<li
key={item.id}
className={styles.cardWrapper}
onClick={() => router.push(`/disputes/${item.id}`)}
>
<CaseCard
title={item.title}
preview={item.description ?? ''}
date=""
categoryGroup={item.categoryGroup}
/>
<div className={styles.cardFooter}>
<AvatarGroup size="s" max={2}>
{item.participants.map((p) => (
<Avatar
key={p.role}
src={p.user.profileImageUrl ?? undefined}
alt={p.user.nickname ?? '참여자'}
size="s"
/>
))}
</AvatarGroup>
<time className={styles.cardDate}>{formatDate(item.createdAt)}</time>
</div>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
</li>
))}
</ul>
)}
</section>
)
}
2 changes: 1 addition & 1 deletion src/components/home/StatsCategorySection.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// 단일 스택 바
.bar {
display: flex;
width: fn.r(346);
width: 100%;
height: fn.r(12);
align-self: center;
overflow: hidden;
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/BottomNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import PersonIcon from '@mui/icons-material/Person';
import styles from './BottomNavigation.module.scss';

const NAV_ITEMS = [
{ href: '/home', label: '홈', Icon: HomeIcon },
{ href: '/', label: '홈', Icon: HomeIcon },
{ href: '/records', label: '사건기록', Icon: MenuBookIcon },
{ href: '/diary', label: '일기', Icon: CalendarMonthIcon },
{ href: '/mypage', label: '마이페이지', Icon: PersonIcon },
Expand All @@ -22,7 +22,7 @@ export default function BottomNavigation() {
<nav className={styles.nav}>
<ul className={styles.nav__list}>
{NAV_ITEMS.map(({ href, label, Icon }) => {
const isActive = pathname.startsWith(href);
const isActive = href === '/' ? pathname === '/' : pathname.startsWith(href);
return (
<li key={href} className={styles.nav__item}>
<Link
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/CaseCard.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
font-size: v.$font-size-body-s;
font-weight: v.$font-weight-regular;
line-height: v.$line-height-body-s;
color: var(--text-secondary);
color: v.$color-black-700;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
Expand Down
Loading