Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Empty file removed src/app/(page)/home/.gitkeep
Empty file.
6 changes: 0 additions & 6 deletions src/app/(page)/home/page.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/app/(page)/join/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const disputeTitle = '';
export default function JoinPage() {
const router = useRouter();

const goToMain = () => router.push('/home');
const goToMain = () => router.push('/');

if (currentState === 'error') {
return (
Expand Down
7 changes: 7 additions & 0 deletions src/app/(page)/records/page.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@use '@/styles/abstracts/functions' as fn;

.page {
display: flex;
flex-direction: column;
min-height: 100dvh;
}
19 changes: 14 additions & 5 deletions src/app/(page)/records/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { getServerSession } from 'next-auth'
import { redirect } from 'next/navigation'
import { authOptions } from '@/lib/auth'
import Header from '@/components/layout/Header'
import BottomNavigation from '@/components/layout/BottomNavigation'
import RecordListSection from '@/components/records/RecordListSection'
import styles from './page.module.scss'

export default async function RecordsPage() {
const session = await getServerSession(authOptions)
if (!session) redirect('/login')

export default function RecordsPage() {
return (
<>
<div className={styles.page}>
<Header variant="logo" />
<main>
</main>
</>
<RecordListSection />
<BottomNavigation />
</div>
)
}
4 changes: 0 additions & 4 deletions src/components/calendar/RecordList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ interface DummyItem {
preview: string;
date: string;
categoryGroup: CategoryGroup;
status?: 'progress' | null;
}

const DUMMY_ITEMS: DummyItem[] = [
Expand All @@ -24,15 +23,13 @@ const DUMMY_ITEMS: DummyItem[] = [
preview: '매번 제가 더 많이 내는 것 같아서 억울한 마음이 들었어요.',
date: '2026.06.18',
categoryGroup: 'romance',
status: null,
},
{
id: 2,
title: '팀장님 업무 지시 방식 문제',
preview: '갑작스러운 야근 요청이 너무 잦아서 힘들었어요.',
date: '2026.06.15',
categoryGroup: 'work',
status: null,
},
];

Expand All @@ -53,7 +50,6 @@ export default function RecordList({ selectedDate }: Props) {
preview={item.preview}
date={item.date}
categoryGroup={item.categoryGroup}
status={item.status ?? null}
/>
</li>
))}
Expand Down
77 changes: 77 additions & 0 deletions src/components/records/RecordListSection.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
@use '@/styles/abstracts/functions' as fn;
@use '@/styles/abstracts/variables' as v;
@use '@/styles/abstracts/mixins' as m;

.section {
flex: 1;
display: flex;
flex-direction: column;
padding-bottom: fn.r(80);
}

.filterWrapper {
padding: fn.r(16) fn.r(16) fn.r(8);
border-bottom: 1px solid var(--border-default);
}

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

.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;
}

> article {
border: none;
border-radius: 0;
background-color: transparent;
padding-bottom: 0;

time { display: none; }

> p { margin-bottom: fn.r(8); }
}
}

.cardFooter {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 fn.r(16) fn.r(16);
}

.cardFooterLeft {
display: flex;
align-items: center;
gap: fn.r(8);
}

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

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

.empty {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: v.$font-size-body-s;
color: var(--text-secondary);
padding: fn.r(60) 0;
}
110 changes: 110 additions & 0 deletions src/components/records/RecordListSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
'use client'

import { useState } from 'react'
import Link from 'next/link'
import CategoryFilter, { type Category } from '@/components/ui/CategoryFilter'
import CaseCard from '@/components/ui/CaseCard'
import Avatar from '@/components/ui/Avatar'
import StatusBadge, { type DisputeStatus } from '@/components/ui/StatusBadge'
import type { CategoryGroup } from '@/types/common'
import styles from './RecordListSection.module.scss'

interface RecordItem {
id: string
disputeId: string
title: string
description: string
categoryGroup: CategoryGroup
disputeStatus: DisputeStatus
createdAt: string
profileImageUrl?: string
}

// TODO: API 연동 시 교체
const DUMMY_RECORDS: RecordItem[] = [
{
id: '1',
disputeId: 'dispute-1',
title: '술주정 사건',
description: '제보자 술을 아주 극혐하는데 남친은 술을 너무 좋아해서 벌어진 사건',
categoryGroup: 'romance',
disputeStatus: 'judged',
createdAt: '2026-06-13',
},
{
id: '2',
disputeId: 'dispute-2',
title: '업무 분배 갈등 사건',
description: '팀장이 특정 팀원에게만 업무를 몰아줘서 발생한 직장 내 갈등 사건',
categoryGroup: 'work',
disputeStatus: 'judged',
createdAt: '2026-06-10',
},
{
id: '3',
disputeId: 'dispute-3',
title: '용돈 갈등 사건',
description: '부모님이 형에게만 용돈을 더 많이 주는 것 같아서 억울한 마음이 든 사건',
categoryGroup: 'family',
disputeStatus: 'closed',
createdAt: '2026-06-05',
},
{
id: '4',
disputeId: 'dispute-4',
title: '약속 파기 사건',
description: '친구가 중요한 약속을 갑자기 취소하고 연락도 잘 안 되어 상처받은 사건',
categoryGroup: 'friend',
disputeStatus: 'judged',
createdAt: '2026-05-28',
},
]

function formatDate(dateStr: string): string {
return dateStr.slice(2, 10)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

export default function RecordListSection() {
const [selectedCategory, setSelectedCategory] = useState<Category>('all')

const filtered = selectedCategory === 'all'
? DUMMY_RECORDS
: DUMMY_RECORDS.filter((r) => r.categoryGroup === selectedCategory)

return (
<section className={styles.section}>
<div className={styles.filterWrapper}>
<CategoryFilter value={selectedCategory} onChange={setSelectedCategory} />
</div>

{filtered.length === 0 ? (
<p className={styles.empty}>진행완료된 사건이 없어요</p>
) : (
<ul className={styles.list}>
{filtered.map((record) => (
<li key={record.id}>
<Link
href={`/disputes/${record.disputeId}`}
className={styles.cardWrapper}
>
<CaseCard
title={record.title}
preview={record.description}
date={formatDate(record.createdAt)}
categoryGroup={record.categoryGroup}
/>
<div className={styles.cardFooter}>
<div className={styles.cardFooterLeft}>
<Avatar src={record.profileImageUrl} alt="참여자" size="s" />
<time className={styles.cardDate}>{formatDate(record.createdAt)}</time>
</div>
<StatusBadge status={record.disputeStatus} />
</div>
</Link>
</li>
))}
</ul>
)}
</section>
)
}
6 changes: 6 additions & 0 deletions src/components/ui/CaseCard.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@
word-break: keep-all;
}

&__footer {
display: flex;
align-items: center;
justify-content: space-between;
}

&__date {
display: block;
font-family: v.$font-family-base;
Expand Down
34 changes: 11 additions & 23 deletions src/components/ui/CaseCard.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
import type { CategoryGroup } from '@/types/common';
import CategoryIcon from './CategoryIcon';
import StatusBadge, { type DisputeStatus } from './StatusBadge';
import styles from './CaseCard.module.scss';

type CaseCardStatus = 'progress' | null;

interface CaseCardProps {
title: string;
preview: string;
date: string;
categoryGroup?: CategoryGroup;
status?: CaseCardStatus;
disputeStatus?: DisputeStatus;
onClick?: () => void;
}

const STATUS_LABEL: Record<string, string> = {
progress: '진행중',
};

export default function CaseCard({
title,
preview,
date,
categoryGroup,
status = null,
onClick,
}: CaseCardProps) {
export default function CaseCard({ title, preview, date, categoryGroup, disputeStatus, onClick }: CaseCardProps) {
return (
<article
className={[
Expand All @@ -43,16 +31,16 @@ export default function CaseCard({
)}
<h3 className={styles.card__title}>{title}</h3>
</div>
{status && (
<span
className={`${styles.card__badge} ${styles[`card__badge--${status}`]}`}
>
{STATUS_LABEL[status]}
</span>
)}
</div>
<p className={styles.card__preview}>{preview}</p>
<time className={styles.card__date}>{date}</time>
{disputeStatus ? (
<div className={styles.card__footer}>
<time className={styles.card__date}>{date}</time>
<StatusBadge status={disputeStatus} />
</div>
) : (
<time className={styles.card__date}>{date}</time>
)}
</article>
);
}
2 changes: 1 addition & 1 deletion src/components/ui/StatusBadge.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styles from './StatusBadge.module.scss';

type DisputeStatus =
export type DisputeStatus =
| 'draft'
| 'waiting_opponent'
| 'opponent_joined'
Expand Down