Skip to content

Commit

Permalink
Merge pull request #41 from kkkkkSE/refactor/reflect-code-reviews
Browse files Browse the repository at this point in the history
[style] 코드 스타일 변경 등 코드 리뷰 반영
  • Loading branch information
kkkkkSE authored Jul 25, 2023
2 parents 0e7317d + a8c2288 commit dae264d
Show file tree
Hide file tree
Showing 46 changed files with 236 additions and 121 deletions.
3 changes: 3 additions & 0 deletions fixtures/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const VALID_ACCESS_TOKEN = 'VALIDACCESSTOKEN';

export const VALID_REFRESH_TOKEN = 'VALIDREFRESHTOKEN';
2 changes: 2 additions & 0 deletions fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import company from './company';
import customer from './customer';
import messages from './messages';
import page from './page';
import * as constants from './constants';

export default {
company,
Expand All @@ -16,4 +17,5 @@ export default {
messages,
autoReplies,
page,
constants,
};
9 changes: 5 additions & 4 deletions src/components/chat/ChatList.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { screen } from '@testing-library/react';

import fixtures from '../../../fixtures';

import { render } from '../../test-helper';
Expand All @@ -7,7 +8,7 @@ import ChatList from './ChatList';

const context = describe;

const mockFetchData = {
const mockQueryData = {
isLoading: false,
data: {
pages: [{
Expand All @@ -17,7 +18,7 @@ const mockFetchData = {
},
};

jest.mock('../../hooks/useFetchChatList', () => () => mockFetchData);
jest.mock('../../hooks/useChatListInfiniteQuery', () => () => mockQueryData);

jest.mock('react-intersection-observer', () => ({
useInView: () => [],
Expand All @@ -33,7 +34,7 @@ describe('<CahtList />', () => {

context('empty chat list', () => {
beforeEach(() => {
mockFetchData.data.pages[0].chatRooms = [];
mockQueryData.data.pages[0].chatRooms = [];
});

it('render empty message', () => {
Expand All @@ -45,7 +46,7 @@ describe('<CahtList />', () => {

context('when loading', () => {
beforeEach(() => {
mockFetchData.isLoading = true;
mockQueryData.isLoading = true;
});

it('render loading message', () => {
Expand Down
16 changes: 7 additions & 9 deletions src/components/chat/ChatList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useInView } from 'react-intersection-observer';

import { useNavigate } from 'react-router-dom';

import useFetchChatList from '../../hooks/useFetchChatList';
import { DYNAMIC_ROUTES } from '../../constants/routes';

import useChatListInfiniteQuery from '../../hooks/useChatListInfiniteQuery';
import useLoginUserStore from '../../hooks/useLoginUserStore';

import { ChatRoomSummary } from '../../types';
Expand All @@ -12,11 +12,9 @@ import ChatListRow from './ChatListRow';
export default function ChatList() {
const navigate = useNavigate();

const [ref, inView] = useInView();

const [{ userType }] = useLoginUserStore();

const { isLoading, data } = useFetchChatList(userType, inView);
const { ref, isLoading, data } = useChatListInfiniteQuery(userType);

if (!data) {
return <p>데이터를 불러올 수 없습니다.</p>;
Expand All @@ -28,20 +26,20 @@ export default function ChatList() {

const { pages } = data;

if (!pages[0].chatRooms.length) {
if (pages[0].chatRooms.length === 0) {
return <p>진행중인 대화가 없습니다.</p>;
}

const handleClickChatRoom = (id: number) => {
navigate(`/chatrooms/${id}`);
navigate(DYNAMIC_ROUTES.CHATROOM(id));
};

return (
<div>
<ul>
{pages.map((page) => page.chatRooms.map((chatRoom: ChatRoomSummary) => (
<ChatListRow
key={chatRoom.id + chatRoom.receiverName}
key={chatRoom.id}
chatRoom={chatRoom}
handleClickChatRoom={handleClickChatRoom}
/>
Expand Down
25 changes: 14 additions & 11 deletions src/components/chat/ChatListRow.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import styled from 'styled-components';

import { ChatRoomSummary } from '../../types';
import displayUnreadCount from '../../utils/chat/displayUnreadCount';

import formatDateAuto from '../../utils/date/formatDateAuto';

Expand All @@ -14,28 +15,30 @@ interface ChatListRowProps {
export default function ChatListRow({
chatRoom, handleClickChatRoom,
}: ChatListRowProps) {
const displayUnreadCount = (count: number) => {
if (count > 999) return <span>+999</span>;
if (count > 0) return <span>{count}</span>;
return null;
};
const {
receiverName, receiverImageUrl, lastMessage, lastMessageDate, unreadMessageCount,
} = chatRoom;

const unreadCount = displayUnreadCount(unreadMessageCount);

return (
<Container onClick={() => handleClickChatRoom(chatRoom.id)}>
<div>
<ProfileImage
src={chatRoom.receiverImageUrl}
alt={chatRoom.receiverName}
src={receiverImageUrl}
alt={receiverName}
/>
</div>
<div>
<div>
<b>{chatRoom.receiverName}</b>
<p>{chatRoom.lastMessage}</p>
<b>{receiverName}</b>
<p>{lastMessage}</p>
</div>
<div>
<small>{formatDateAuto(chatRoom.lastMessageDate)}</small>
{displayUnreadCount(chatRoom.unreadMessageCount)}
<small>{formatDateAuto(lastMessageDate)}</small>
{unreadCount && (
<span>{unreadCount}</span>
)}
</div>
</div>
</Container>
Expand Down
1 change: 1 addition & 0 deletions src/components/chat/message/ChatDate.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { screen } from '@testing-library/react';

import { render } from '../../../test-helper';

import ChatDate from './ChatDate';
Expand Down
1 change: 0 additions & 1 deletion src/components/chat/message/MessageInput.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/jsx-props-no-spreading */
import React, { useRef } from 'react';

import { Controller, useForm } from 'react-hook-form';
Expand Down
7 changes: 4 additions & 3 deletions src/components/layout/ContentLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import styled from 'styled-components';

import NavigationBar from '../ui/NavigationBar';

interface ContentLayoutProps {
enableBack?: boolean;
page: string;
pageHeader: string;
children: React.ReactNode;
testId?: string;
}

export default function ContentLayout({
enableBack = false,
page,
pageHeader,
children,
testId = undefined,
}: ContentLayoutProps) {
return (
<Container data-testid={testId}>
<NavigationBar enableBack={enableBack}>{page}</NavigationBar>
<NavigationBar enableBack={enableBack}>{pageHeader}</NavigationBar>
{children}
</Container>
);
Expand Down
7 changes: 4 additions & 3 deletions src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import { NavLink } from 'react-router-dom';

import styled from 'styled-components';

import { apiService } from '../../services/ApiService';

import useLoginUserStore from '../../hooks/useLoginUserStore';

import profileIcon from '../../assets/image/icon/profile-icon.png';
import profileListIcon from '../../assets/image/icon/profile-list-icon.png';
import chatListIcon from '../../assets/image/icon/chat-list-icon.png';
import accountIcon from '../../assets/image/icon/account-icon.png';
import logoutIcon from '../../assets/image/icon/logout-icon.png';

import { apiService } from '../../services/ApiService';
import useLoginUserStore from '../../hooks/useLoginUserStore';

export default function Header() {
const [, store] = useLoginUserStore();

Expand Down
4 changes: 3 additions & 1 deletion src/components/layout/PostLoginLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { Outlet, useNavigate } from 'react-router-dom';

import styled from 'styled-components';

import { STATIC_ROUTES } from '../../constants/routes';

import useAccessToken from '../../hooks/useAccessToken';
import useCheckLoginUser from '../../hooks/useCheckLoginUser';
import useLoginUserStore from '../../hooks/useLoginUserStore';
Expand All @@ -23,7 +25,7 @@ export default function PostLoginLayout() {
if (!accessToken) {
store.reset();

navigate('/');
navigate(STATIC_ROUTES.HOME);
}
}, [accessToken]);

Expand Down
8 changes: 4 additions & 4 deletions src/components/ui/ErrorMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import styled from 'styled-components';

type ErrorMessageProps = {
children: string;
children: React.ReactNode;
};
function ErrorMessage({ children }: ErrorMessageProps) {
return (
<StyledErrorMessage>
<Container>
{children}
</StyledErrorMessage>
</Container>
);
}

export default ErrorMessage;

const StyledErrorMessage = styled.p`
const Container = styled.p`
${(props) => props.theme.texts.regular.small}
color: ${(props) => props.theme.colors.accent.default};
padding-block: 1.2rem;
Expand Down
9 changes: 7 additions & 2 deletions src/components/ui/NavigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@ import backIcon from '../../assets/image/icon/back-icon.png';

interface NavigationBar {
enableBack?: boolean;
children: string;
children: React.ReactNode;
}

function NavigationBar({
enableBack = false,
children,
}: NavigationBar) {
const navigate = useNavigate();

const handleClickBack = () => {
navigate(-1);
};

return (
<Container>
{enableBack && (
<button
type="button"
onClick={() => navigate(-1)}
onClick={handleClickBack}
>
<img src={backIcon} alt="이전 페이지" />
</button>
Expand Down
8 changes: 3 additions & 5 deletions src/components/ui/TextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import React, { forwardRef, useCallback } from 'react';

import styled from 'styled-components';

interface TextareaProps {
interface TextAreaProps {
value: string;
placeholder?: string;
maxLength?: number;
onChange: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
onKeyPress?: (event: React.KeyboardEvent<HTMLTextAreaElement>) => void;
}

const TextArea = forwardRef<HTMLTextAreaElement, TextareaProps>(({
const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(({
value, placeholder, maxLength, onKeyPress, onChange,
}, ref) => {
const handleResizeHeight = useCallback(() => {
Expand All @@ -28,9 +28,7 @@ const TextArea = forwardRef<HTMLTextAreaElement, TextareaProps>(({
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
handleResizeHeight();

if (onChange) {
onChange(event);
}
onChange?.(event);
};

return (
Expand Down
6 changes: 1 addition & 5 deletions src/components/ui/TextBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@ export default function TextBox({
readOnly = false,
}: TextBoxProps) {
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (!onChange) {
return;
}

onChange(event.target.value);
onChange?.(event.target.value);
};

return (
Expand Down
25 changes: 25 additions & 0 deletions src/constants/apiPaths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const PLURAL_USER_TYPES : Record<string, string> = {
company: 'companies',
customer: 'customers',
};

export const STATIC_API_PATHS = {
OPEN_PROFILES: '/companies',
AUTO_REPLIES_BY_CUSTOMER: '/auto-replies',
AUTO_REPLIES_BY_COMPANY: '/company/auto-replies',
REISSUE_TOKEN: '/token',
LOGOUT: '/logout',
UPLOAD_PROFILE_IMAGE: '/files?folder=profile',
};

export const DYNAMIC_API_PATHS = {
LOGIN: (type: string) => `/${type}/session`,
CHANGE_PASSWORD: (type: string) => `/${PLURAL_USER_TYPES[type]}/me/password`,
SIGN_UP: (type: string) => `/${PLURAL_USER_TYPES[type]}`,
SELF_ACCOUNT: (type: string) => `/${PLURAL_USER_TYPES[type]}/me`,
CHATROOMS: (type: string) => `/${type}/chatrooms`,
CHATROOM: (type: string, id: number) => `/${type}/chatrooms/${id}`,
OPEN_PROFILE: (id: number) => `/companies/${id}`,
AUTO_REPLIES_FOR_CUSTOMER: (id: number) => `/auto-replies/${id}`,
AUTO_REPLIES_FOR_COMPANY: (id: number) => `/company/auto-replies/${id}`,
};
5 changes: 5 additions & 0 deletions src/constants/localStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// eslint-disable-next-line import/prefer-default-export
export const LOCAL_STORAGE_KEYS = {
ACCESS_TOKEN: 'accessToken',
USER_TYPE: 'userType',
};
4 changes: 4 additions & 0 deletions src/constants/reactQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// eslint-disable-next-line import/prefer-default-export
export const QUERY_KEY = {
CHAT_LIST: ['chatList'],
};
20 changes: 20 additions & 0 deletions src/constants/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const STATIC_ROUTES = {
HOME: '/',
LOGIN: '/login',
SIGN_UP: '/sign-up',
CHATROOMS: '/chatrooms',
MY_PROFILE: '/profile',
EDIT_MY_PROFILE: '/profile/edit',
AUTO_REPLIES: '/auto-replies',
OPEN_PROFILES: '/open-profiles',
ACCOUNT: '/account',
DELETE_ACCOUNT: '/account/delete',
CONFIRM_DELETE_ACCOUNT: '/account/delete/confirm',
CHANGE_PASSWORD: '/account/change-password',
};

export const DYNAMIC_ROUTES = {
CHATROOM: (id: number) => `/chatrooms/${id}`,
OPEN_PROFILE: (id: number) => `/open-profiles/${id}`,
EDIT_AUTO_REPLIY: (id: number) => `/auto-replies/${id}`,
};
4 changes: 3 additions & 1 deletion src/hooks/useAccessToken.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useLocalStorage } from 'usehooks-ts';

import { LOCAL_STORAGE_KEYS } from '../constants/localStorage';

export default function useAccessToken() {
const [accessToken, setAccessToken] = useLocalStorage('accessToken', '');
const [accessToken, setAccessToken] = useLocalStorage(LOCAL_STORAGE_KEYS.ACCESS_TOKEN, '');

return { accessToken, setAccessToken };
}
Loading

0 comments on commit dae264d

Please sign in to comment.