Skip to content
44 changes: 44 additions & 0 deletions src/app/workspaces/[workspaceId]/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// 설정 페이지 라우트 — 활성 탭을 searchParam(?tab=)으로 읽고, 표시에 필요한 데이터를 RSC에서 조회해 주입한다.
// 실 API 전환 시 아래 조회부만 async(Supabase)로 교체하면 되고, 하위 뷰/훅은 그대로 둔다.
import { notFound } from 'next/navigation';
import { getMockWorkspaceById } from '@/entities/workspace';
import {
getMockWorkspaceMembersByWorkspaceId,
mockCurrentWorkspaceMember,
} from '@/entities/workspace-member';
import { SettingsView, parseSettingsTab } from '@/views/settings';

interface WorkspaceSettingsPageProps {
params: Promise<{
workspaceId: string;
}>;
searchParams: Promise<{
tab?: string;
}>;
}

export default async function WorkspaceSettingsPage({
params,
searchParams,
}: WorkspaceSettingsPageProps) {
const { workspaceId } = await params;
const { tab } = await searchParams;
const workspace = getMockWorkspaceById(workspaceId);

if (!workspace) {
notFound();
}

const members = getMockWorkspaceMembersByWorkspaceId(workspaceId);

return (
<SettingsView
workspace={workspace}
workspaceId={workspaceId}
activeTab={parseSettingsTab(tab)}
members={members}
currentUserId={mockCurrentWorkspaceMember.userId}
currentNickname={mockCurrentWorkspaceMember.workspaceNickname}
/>
);
}
6 changes: 5 additions & 1 deletion src/entities/meeting-note/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export { getMockMeetingNotesByWorkspaceId } from './model/mock-meeting-notes-by-workspace';
export type { MeetingNote, MeetingNoteFormValues, MeetingNoteParticipant } from './model/meeting-note.types';
export type {
MeetingNote,
MeetingNoteFormValues,
MeetingNoteParticipant,
} from './model/meeting-note.types';
export { MeetingNoteCard } from './ui/MeetingNoteCard';
22 changes: 15 additions & 7 deletions src/entities/meeting-note/ui/MeetingNoteCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ export function MeetingNoteCard({
<article className="rounded-[24px] border border-[#ebeef7] bg-white px-[22px] py-[21px] shadow-[0_10px_30px_rgba(91,78,232,0.06)] transition hover:border-[rgba(91,78,232,0.16)]">
<div className="flex items-start justify-between gap-6">
<div className="min-w-0">
<h3 className="truncate text-[18px] font-bold tracking-[-0.03em] text-brand-ink">
<h3 className="text-brand-ink truncate text-[18px] font-bold tracking-[-0.03em]">
{meetingNote.title}
</h3>
<p className="mt-[6px] text-[12px] font-medium text-brand-muted">{meetingNote.meetingDate}</p>
<p className="text-brand-muted mt-[6px] text-[12px] font-medium">
{meetingNote.meetingDate}
</p>
</div>

<div className="flex shrink-0 items-center gap-1">
Expand All @@ -61,12 +63,15 @@ export function MeetingNoteCard({
{isExpanded ? (
<div className="mt-3 border-t border-[rgba(91,78,232,0.06)] pt-[17px]">
<div>
<p className="text-[12px] font-bold tracking-[0.3px] text-brand-muted uppercase">
<p className="text-brand-muted text-[12px] font-bold tracking-[0.3px] uppercase">
결정사항
</p>
<ul className="mt-2 space-y-1.5">
{meetingNote.decisions.map((decision) => (
<li key={decision} className="flex items-start gap-2 text-[14px] leading-5 text-brand-ink">
<li
key={decision}
className="text-brand-ink flex items-start gap-2 text-[14px] leading-5"
>
<Check className="mt-[3px] size-[14px] shrink-0 text-[#00c950]" />
<span>{decision}</span>
</li>
Expand All @@ -75,13 +80,16 @@ export function MeetingNoteCard({
</div>

<div className="mt-4">
<p className="text-[12px] font-bold tracking-[0.3px] text-brand-muted uppercase">
<p className="text-brand-muted text-[12px] font-bold tracking-[0.3px] uppercase">
후속 업무
</p>
<ul className="mt-2 space-y-1.5">
{meetingNote.followUpActions.map((actionItem) => (
<li key={actionItem} className="flex items-start gap-2 text-[14px] leading-5 text-brand-ink">
<ArrowRight className="mt-[3px] size-[14px] shrink-0 text-brand-start" />
<li
key={actionItem}
className="text-brand-ink flex items-start gap-2 text-[14px] leading-5"
>
<ArrowRight className="text-brand-start mt-[3px] size-[14px] shrink-0" />
<span>{actionItem}</span>
</li>
))}
Expand Down
3 changes: 0 additions & 3 deletions src/entities/side-project/meeting-note/index.ts

This file was deleted.

29 changes: 0 additions & 29 deletions src/entities/side-project/meeting-note/model/meeting-note.mock.ts

This file was deleted.

This file was deleted.

21 changes: 21 additions & 0 deletions src/entities/workspace-member/config/labels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 멤버의 역할/참여 상태를 UI에 표시하기 위한 한글 라벨과 뱃지 톤 매핑입니다.
import type { WorkspaceMemberRole, WorkspaceMemberStatus } from '../model/workspace-member.types';

// Badge 컴포넌트의 tone 값과 일치시킵니다.
export type BadgeTone = 'brand' | 'neutral' | 'success' | 'warning';

export const WORKSPACE_MEMBER_ROLE_META: Record<
WorkspaceMemberRole,
{ label: string; tone: BadgeTone }
> = {
owner: { label: '팀장', tone: 'brand' },
member: { label: '팀원', tone: 'neutral' },
};

export const WORKSPACE_MEMBER_STATUS_META: Record<
WorkspaceMemberStatus,
{ label: string; tone: BadgeTone }
> = {
joined: { label: '참여 중', tone: 'success' },
invited: { label: '초대됨', tone: 'warning' },
};
11 changes: 10 additions & 1 deletion src/entities/workspace-member/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
// 목업 워크스페이스 멤버 데이터와 타입의 공개 API입니다.
export type { WorkspaceMember } from './model/workspace-member.types';
export type {
WorkspaceMember,
WorkspaceMemberRole,
WorkspaceMemberStatus,
} from './model/workspace-member.types';
export { mockCurrentWorkspaceMember } from './model/mock-current-workspace-member';
export {
getMockWorkspaceMembersByWorkspaceId,
mockWorkspaceMembers,
} from './model/mock-workspace-members';
export {
WORKSPACE_MEMBER_ROLE_META,
WORKSPACE_MEMBER_STATUS_META,
type BadgeTone,
} from './config/labels';
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ export const mockCurrentWorkspaceMember: WorkspaceMember = {
userId: 'user-1',
workspaceNickname: '김민서',
avatarLabel: '김',
email: 'minseo@example.com',
role: 'owner',
status: 'joined',
};
74 changes: 74 additions & 0 deletions src/entities/workspace-member/model/mock-workspace-members.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,70 +7,144 @@ export const mockWorkspaceMembers: WorkspaceMember[] = [
userId: 'user-1',
workspaceNickname: '김지은',
avatarLabel: '김',
email: 'jieun@example.com',
role: 'owner',
status: 'joined',
},
{
workspaceId: 'test',
userId: 'user-2',
workspaceNickname: '박서준',
avatarLabel: '박',
email: 'seojun@example.com',
role: 'member',
status: 'joined',
},
{
workspaceId: 'test',
userId: 'user-3',
workspaceNickname: '이하은',
avatarLabel: '이',
email: 'haeun@example.com',
role: 'member',
status: 'joined',
},
{
workspaceId: 'test',
userId: 'user-4',
workspaceNickname: '최민준',
avatarLabel: '최',
email: 'minjun@example.com',
role: 'member',
status: 'invited',
},
{
workspaceId: 'store-workspace',
userId: 'user-1',
workspaceNickname: '김민서',
avatarLabel: '김',
email: 'minseo@example.com',
role: 'owner',
status: 'joined',
},
{
workspaceId: 'store-workspace',
userId: 'user-2',
workspaceNickname: '이준혁',
avatarLabel: '이',
email: 'junhyeok@example.com',
role: 'member',
status: 'joined',
},
{
workspaceId: 'store-workspace',
userId: 'user-3',
workspaceNickname: '박소연',
avatarLabel: '박',
email: 'soyeon@example.com',
role: 'member',
status: 'invited',
},
{
workspaceId: 'store-workspace',
userId: 'user-4',
workspaceNickname: '최다은',
avatarLabel: '최',
email: 'daeun@example.com',
role: 'member',
status: 'joined',
},
{
workspaceId: 'store-workspace',
userId: 'user-5',
workspaceNickname: '정우진',
avatarLabel: '정',
email: 'woojin@example.com',
role: 'member',
status: 'joined',
},
{
workspaceId: 'store-workspace',
userId: 'user-6',
workspaceNickname: '이서영',
avatarLabel: '이',
email: 'seoyeong@example.com',
role: 'member',
status: 'invited',
},
{
workspaceId: 'team-workspace',
userId: 'user-1',
workspaceNickname: '김민서',
avatarLabel: '김',
email: 'minseo@example.com',
role: 'owner',
status: 'joined',
},
{
workspaceId: 'team-workspace',
userId: 'user-2',
workspaceNickname: '이준혁',
avatarLabel: '이',
email: 'junhyeok@example.com',
role: 'member',
status: 'joined',
},
{
workspaceId: 'team-workspace',
userId: 'user-3',
workspaceNickname: '박소연',
avatarLabel: '박',
email: 'soyeon@example.com',
role: 'member',
status: 'invited',
},
{
workspaceId: 'side-workspace',
userId: 'user-1',
workspaceNickname: '김민서',
avatarLabel: '김',
email: 'minseo@example.com',
role: 'owner',
status: 'joined',
},
{
workspaceId: 'side-workspace',
userId: 'user-2',
workspaceNickname: '정우진',
avatarLabel: '정',
email: 'woojin@example.com',
role: 'member',
status: 'joined',
},
{
workspaceId: 'side-workspace',
userId: 'user-3',
workspaceNickname: '이서영',
avatarLabel: '이',
email: 'seoyeong@example.com',
role: 'member',
status: 'invited',
},
];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
// Supabase 데이터가 연결되기 전까지 사용하는 목업 일정용 워크스페이스 멤버 형태입니다.
export type WorkspaceMemberRole = 'owner' | 'member';

// 워크스페이스 참여 상태: 초대를 수락해 참여 중이거나(joined), 초대만 발송된 상태(invited)입니다.
export type WorkspaceMemberStatus = 'joined' | 'invited';

export interface WorkspaceMember {
workspaceId: string;
userId: string;
workspaceNickname: string;
avatarLabel: string;
role: 'owner' | 'member';
email: string;
role: WorkspaceMemberRole;
status: WorkspaceMemberStatus;
}
3 changes: 3 additions & 0 deletions src/entities/workspace/model/mock-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@ const mockWorkspacesById: Record<string, Workspace> = {
id: 'store-workspace',
name: '카페 그레이 운영',
purpose: 'store-operation',
description: '카페 그레이 매장 운영을 위한 워크스페이스입니다.',
},
'team-workspace': {
id: 'team-workspace',
name: '캡스톤 디자인 팀',
purpose: 'team-project',
description: '캡스톤 디자인 프로젝트 협업 공간입니다.',
},
'side-workspace': {
id: 'side-workspace',
name: 'Fitto 앱 개발팀',
purpose: 'side-project',
description: 'Fitto 앱 사이드 프로젝트 개발팀 워크스페이스입니다.',
},
};

Expand Down
2 changes: 2 additions & 0 deletions src/entities/workspace/model/workspace.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export interface Workspace {
id: string;
name: string;
purpose: WorkspacePurpose;
// 설정 페이지에서 편집하는 워크스페이스 소개 문구입니다. (선택 값)
description?: string;
}

// get_my_workspaces RPC 반환 형태 (내 워크스페이스 목록)
Expand Down
Loading