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
17 changes: 17 additions & 0 deletions src/app/message/chat/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { TabNavigation } from '@/components/shared';

const SOCIAL_TABS = [
{ label: '팔로잉', value: 'following' },
{ label: '메세지', value: 'chat' },
];

export default function ChatPage() {
return (
<div className='min-h-screen bg-[#F1F5F9]'>
<TabNavigation basePath='/message' tabs={SOCIAL_TABS} />
<section className='flex w-full flex-col gap-4 px-4 py-4'>
<h2 className='text-h2-bold'>채팅 페이지</h2>
</section>
</div>
);
}
38 changes: 38 additions & 0 deletions src/app/message/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FollowingList, FollowingSearch } from '@/components/pages/message';
import { TabNavigation } from '@/components/shared';

const SOCIAL_TABS = [
{ label: '팔로잉', value: 'following' },
{ label: '메세지', value: 'chat' },
];

const FOLLOWING_LIST = [
{
id: 1,
name: '신짱구',
profileImage: '',
profileMessage: '안녕하세요 신짱구입니다',
},
{
id: 2,
name: '신짱구',
profileImage: '',
profileMessage: '안녕하세요 신짱구입니다',
},
{
id: 3,
name: '신짱구',
profileImage: '',
profileMessage: '안녕하세요 신짱구입니다',
},
];

export default function FollowingPage() {
return (
<div className='min-h-screen bg-[#F1F5F9]'>
<TabNavigation basePath='/message' tabs={SOCIAL_TABS} />
<FollowingSearch />
<FollowingList items={FOLLOWING_LIST} />
</div>
);
}
6 changes: 3 additions & 3 deletions src/components/pages/message/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import FollowingCard from './message-followingCard';

export { FollowingCard };
export { FollowingCard } from './message-following-card';
export { FollowingList } from './message-following-list';
export { FollowingSearch } from './message-following-search';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Meta, StoryObj } from '@storybook/nextjs';

import FollowingCard from '.';
import { FollowingCard } from '.';

const meta = {
title: 'Components/Following Card',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { fireEvent, render, screen } from '@testing-library/react';

import FollowingCard from '.';
import { FollowingCard } from '.';

describe('FollowingCard 컴포넌트 테스트', () => {
const defaultProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface FollowingCardProps {
onMessageClick?: () => void;
}

const FollowingCard = ({
export const FollowingCard = ({
name,
profileImage,
profileMessage,
Expand Down Expand Up @@ -67,5 +67,3 @@ const FollowingCard = ({
</div>
);
};

export default FollowingCard;
32 changes: 32 additions & 0 deletions src/components/pages/message/message-following-list/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { render, screen } from '@testing-library/react';

import { FollowingList } from '.';

const TEST_ITEMS = [
{
name: '신짱구',
profileImage: 'http://test.com',
profileMessage: '안녕하세요 신짱구입니다',
},
{
name: '김맹구',
profileImage: 'http://test.com',
profileMessage: '안녕하세요 김맹구입니다',
},

{
name: '흰둥이',
profileImage: 'http://test.com',
profileMessage: '안녕하세요 흰둥이입니다',
},
];

describe('Following List 컴포넌트 테스트', () => {
test('모든 아이템이 렌더링 되는지 테스트', () => {
render(<FollowingList items={TEST_ITEMS} />);

TEST_ITEMS.forEach((item) => {
expect(screen.getByText(item.name)).toBeInTheDocument();
});
});
});
30 changes: 30 additions & 0 deletions src/components/pages/message/message-following-list/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use client';

import { FollowingCard } from '../message-following-card';

interface FollowingItem {
id: number;
name: string;
profileImage: string;
profileMessage: string;
}

interface FollowingListProps {
items: FollowingItem[];
}

export const FollowingList = ({ items }: FollowingListProps) => {
return (
<div>
{items.map((item) => (
<FollowingCard
key={item.id}
name={item.name}
profileImage={item.profileImage}
profileMessage={item.profileMessage}
type='following'
/>
))}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { fireEvent, render, screen } from '@testing-library/react';

import { ModalProvider } from '@/components/ui';

import { FollowingSearch } from '.';

describe('Following Search 테스트', () => {
test('Following Search 렌더링 테스트', () => {
render(
<ModalProvider>
<FollowingSearch />
</ModalProvider>,
);

expect(screen.getByText('팔로우 추가')).toBeInTheDocument();
});

test('팔로우 추가 클릭 시 모달 생성', () => {
render(
<ModalProvider>
<FollowingSearch />
</ModalProvider>,
);

expect(screen.queryByText('팔로우 할 닉네임을 입력하세요')).toBeNull();

fireEvent.click(screen.getByText('팔로우 추가'));

expect(screen.getByText('팔로우 할 닉네임을 입력하세요')).toBeInTheDocument();
});
});
54 changes: 54 additions & 0 deletions src/components/pages/message/message-following-search/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
'use client';
import { Icon } from '@/components/icon';
import { Button, ModalContent, ModalTitle, useModal } from '@/components/ui';

const FollowerModal = () => {
const { close } = useModal();

const handleConfirm = () => {
// 유저 팔로우 기능 ...
console.log('팔로우 성공');
close();
};

// 모달 모양 바뀌면 적용하기!
return (
<ModalContent>
<ModalTitle className='mb-3'>팔로우 할 닉네임을 입력하세요</ModalTitle>
<input
className='text-text-sm-medium mb-3 w-full rounded-3xl bg-gray-100 px-4 py-2.5 text-gray-800'
placeholder='nickname'
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleConfirm();
}
}}
/>

<div className='flex w-full flex-row gap-2'>
<Button size='sm' variant='tertiary' onClick={close}>
취소
</Button>
<Button size='sm' onClick={handleConfirm}>
팔로우
</Button>
</div>
</ModalContent>
);
};

export const FollowingSearch = () => {
const { open } = useModal();
return (
<div
className='flex items-center gap-5 px-5 py-4 transition-all hover:cursor-pointer hover:opacity-80'
onClick={() => open(<FollowerModal />)}
>
<div className='rounded-full border-2 border-dashed border-gray-400 bg-gray-100 p-2'>
<Icon id='plus' className='size-6 text-gray-700' />
</div>

<span className='text-text-md-bold'>팔로우 추가</span>
</div>
);
};