Skip to content

Commit

Permalink
Merge branch 'main' into epic/FE-32--search-page
Browse files Browse the repository at this point in the history
  • Loading branch information
imsoohyeok authored Aug 3, 2024
2 parents 90079d0 + c8b6af4 commit 25849cd
Show file tree
Hide file tree
Showing 27 changed files with 678 additions and 19 deletions.
Empty file.
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions public/icon/menu-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions public/icon/user-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions public/icon/x-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/apis/epigramComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ export const getEpigramComments = async (params: CommentRequestType): Promise<Co
}
};

export const getMyEpigramComments = async (params: CommentRequestType): Promise<CommentResponseType> => {
const { id, ...restParams } = params;
const response = await httpClient.get(`/users/${id}/comments`, {
params: restParams,
});
return response.data;
};

export const postComment = async (commentData: PostCommentRequest) => {
const response = await httpClient.post('/comments', commentData);
return response.data;
Expand Down
43 changes: 41 additions & 2 deletions src/apis/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { EpigramRequestType } from '@/schema/epigram';
import { CommentRequestType } from '@/schema/comment';
import { GetMonthlyEmotionLogsRequestType } from '@/schema/emotion';
import { GetEpigramsParamsType } from '@/schema/epigrams';
import { getMe, getUser } from './user';
import { getMe, getUser, getMyContentCount } from './user';
import { getEpigram } from './epigram';
import { getEpigramComments } from './epigramComment';
import { getEpigramComments, getMyEpigramComments } from './epigramComment';
import getMonthlyEmotionLogs from './emotion';
import getEpigrams from './getEpigrams';

Expand All @@ -20,6 +20,45 @@ const queries = createQueryKeyStore({
queryKey: [request],
queryFn: () => getUser(request),
}),
getMyContentCount: (request: GetUserRequestType) => ({
queryKey: ['getMyContentCount', request],
queryFn: () => getMyContentCount(request),
}),
},
// NOTE: Epigram 관련 query함수
epigram: {
getEpigram: (request: EpigramRequestType) => ({
queryKey: ['epigram', request.id, request],
queryFn: () => {
if (request.id === undefined) {
throw new Error('Epigram ID가 제공되지 않았습니다.');
}
return getEpigram(request);
},
enabled: request.id !== undefined,
}),
},
epigramComment: {
getComments: (request: CommentRequestType) => ({
queryKey: ['epigramComments', request],
queryFn: () => getEpigramComments(request),
}),
getMyComments: (request: CommentRequestType) => ({
queryKey: ['myEpigramComments', request],
queryFn: () => getMyEpigramComments(request),
}),
},
emotion: {
getMonthlyEmotionLogs: (request: GetMonthlyEmotionLogsRequestType) => ({
queryKey: ['getMonthlyEmotionLogs', request],
queryFn: () => getMonthlyEmotionLogs(request),
}),
},
epigrams: {
getEpigrams: (request: GetEpigramsParamsType) => ({
queryKey: ['getEpigrams', request],
queryFn: () => getEpigrams(request),
}),
},
// NOTE: Epigram 관련 query함수
epigram: {
Expand Down
16 changes: 15 additions & 1 deletion src/apis/user.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { GetUserResponseType, GetUserRequestType, PatchMeRequestType, PostPresignedUrlRequestType, PostPresignedUrlResponseType } from '@/schema/user';
import type { GetUserResponseType, GetUserRequestType, PatchMeRequestType, PostPresignedUrlRequestType, PostPresignedUrlResponseType, GetMyContentCountType } from '@/schema/user';
import httpClient from '.';

export const getMe = async (): Promise<GetUserResponseType> => {
Expand All @@ -23,3 +23,17 @@ export const createPresignedUrl = async (request: PostPresignedUrlRequestType):
const response = await httpClient.post('/images/upload', formData);
return response.data;
};

export const getMyContentCount = async (request: GetUserRequestType): Promise<GetMyContentCountType> => {
const { id } = request;

// 에피그램 카운트
const epigram = await httpClient.get(`/epigrams`, { params: { limit: 1, cursor: 0, writerId: id } });

// 댓글 카운트
const comment = await httpClient.get(`/users/${id}/comments`, { params: { limit: 1, cursor: 0 } });

const response = { epigramCount: epigram.data.totalCount, commentCount: comment.data.totalCount };

return response;
};
63 changes: 63 additions & 0 deletions src/components/Header/NewHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { useState } from 'react';
import { useRouter } from 'next/router';
import Image from 'next/image';
import { useQuery } from '@tanstack/react-query';
import queries from '@/apis/queries';
import LOGO_ICON from '../../../public/epigram-icon.png';
import PROFILE_ICON from '../../../public/icon/user-icon.svg';
import MENU_ICON from '../../../public/icon/menu-icon.svg';
import Sidebar from './SideBar';

export default function NewHeader() {
const router = useRouter();
const [isSidebarOpen, setIsSidebarOpen] = useState(false);

const { data, isLoading, error } = useQuery(queries.user.getMe());

const handleNavigateTo = (path: string) => {
router.push(path);
};

const getNickName = () => {
if (isLoading) {
return '로딩 중...';
}
if (error) {
return '에러 발생';
}
return data?.nickname || '김코드';
};

return (
<div className='w-full px-6 py-4 bg-white border-b border-line-100 flex items-center gap-2.5 lg:px-[120px] md:px-[72px] md:h-[60px] lg:h-20 md:py-[19px] lg:py-[26px]'>
<div className='flex justify-between items-center w-full md:w-[744px] lg:w-[1920px]'>
<div className='flex items-center gap-3 md:gap-6 lg:gap-9'>
<div className='flex items-center gap-3'>
<button type='button' onClick={() => setIsSidebarOpen(!isSidebarOpen)} className='md:hidden'>
<Image className='w-5 h-5 lg:w-9 lg:h-9' src={MENU_ICON} alt='menu' />
</button>
<button type='button' onClick={() => handleNavigateTo('/epigrams')} className='flex items-center gap-1'>
<Image className='w-6 h-6 lg:w-9 lg:h-9' src={LOGO_ICON} alt='logo' />
<span className='text-black-700 text-6 lg:text-[26px] font-montserrat leading-6 font-bold'>Epigram</span>
</button>
</div>
<div className='hidden md:flex items-center gap-6'>
<button type='button' onClick={() => handleNavigateTo('/feed')}>
<div className='text-center text-black-600 text-sm lg:text-base font-semibold font-pretendard leading-normal'>피드</div>
</button>
<button type='button' onClick={() => handleNavigateTo('/search')}>
<div className='text-center text-black-600 text-sm lg:text-base font-semibold font-pretendard leading-normal'>검색</div>
</button>
</div>
</div>
<button type='button' onClick={() => handleNavigateTo('/mypage')} className='flex items-center gap-1.5'>
<div className='w-4 h-4 lg:w-6 lg:h-6 relative'>
<Image src={PROFILE_ICON} alt='프로필 이미지' />
</div>
<div className='text-gray-300 text-[13px] lg:text-sm font-medium font-pretendard leading-snug'>{getNickName()}</div>
</button>
</div>
<Sidebar isOpen={isSidebarOpen} toggleSidebar={() => setIsSidebarOpen(false)} />
</div>
);
}
42 changes: 42 additions & 0 deletions src/components/Header/SideBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import Image from 'next/image';
import { useRouter } from 'next/router';
import X_ICON from '../../../public/icon/x-icon.svg';

interface SidebarProps {
isOpen: boolean;
toggleSidebar: () => void;
}

function Sidebar({ isOpen, toggleSidebar }: SidebarProps) {
const router = useRouter();

const handleNavigateTo = (path: string) => {
router.push(path);
toggleSidebar();
};

if (!isOpen) {
return null;
}

return (
<div className='absolute top-0 left-0 h-full w-[220px] bg-white shadow-lg z-50'>
<div className='h-[54px] px-4 py-2.5 bg-white border-b border-[#f2f2f2] flex items-center justify-end'>
<button type='button' onClick={toggleSidebar}>
<Image className='w-6 h-6' src={X_ICON} alt='사이드바 닫기' />
</button>
</div>
<div className='flex flex-col'>
<button type='button' className='w-full px-5 py-6 bg-white text-left' onClick={() => handleNavigateTo('/feed')}>
<div className='text-[#373737] text-base font-medium font-pretendard leading-relaxed'>피드</div>
</button>
<button type='button' className='w-full px-5 py-6 bg-white text-left' onClick={() => handleNavigateTo('/search')}>
<div className='text-[#373737] text-base font-medium font-pretendard leading-relaxed'>검색</div>
</button>
</div>
</div>
);
}

export default Sidebar;
7 changes: 7 additions & 0 deletions src/hooks/useCommentsHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import quries from '@/apis/queries';
import { CommentRequestType } from '@/schema/comment';
import { useQuery } from '@tanstack/react-query';

const useCommentsHook = (requset: CommentRequestType) => useQuery(quries.epigramComment.getMyComments(requset));

export default useCommentsHook;
7 changes: 7 additions & 0 deletions src/hooks/useGetMyContentHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import quries from '@/apis/queries';
import { GetUserRequestType } from '@/schema/user';
import { useQuery } from '@tanstack/react-query';

const useGetMyContentHook = (requset: GetUserRequestType) => useQuery(quries.user.getMyContentCount(requset));

export default useGetMyContentHook;
2 changes: 1 addition & 1 deletion src/pageLayout/About/AboutPageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import StartButton from './StartButton';
function AboutLayout() {
return (
<>
<Header icon='' isLogo insteadOfLogo='' isProfileIcon={false} isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<Header icon='search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<main className='w-full h-[3000px] lg:h-[5000px] relative bg-slate-100'>
<section className='absolute w-full h-[676px] lg:h-[900px] left-0 bg-stripes'>
<div className='absolute left-1/2 transform -translate-x-1/2 top-[200px] lg:top-[320px] flex-col justify-start items-center gap-12 inline-flex'>
Expand Down
5 changes: 2 additions & 3 deletions src/pageLayout/Epigram/AddEpigram.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { KeyboardEvent, useCallback, useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import Header from '@/components/Header/Header';
import NewHeader from '@/components/Header/NewHeader';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
Expand Down Expand Up @@ -106,7 +106,7 @@ function AddEpigram() {

return (
<>
<Header icon='search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<NewHeader />
<div className='border-t-2 w-full flex flex-col justify-center items-center'>
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit)} className='flex flex-col justify-center item-center gap-6 lg:gap-8 w-[312px] md:w-[384px] lg:w-[640px] py-6'>
Expand Down Expand Up @@ -259,7 +259,6 @@ function AddEpigram() {
</form>
</Form>
</div>

<AlertDialog open={isAlertOpen} onOpenChange={setIsAlertOpen}>
<AlertDialogContent className='bg-white'>
<AlertDialogHeader>
Expand Down
4 changes: 2 additions & 2 deletions src/pageLayout/Epigrams/MainLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import Header from '@/components/Header/Header';
import NewHeader from '@/components/Header/NewHeader';
import TodayEpigram from '@/components/main/TodayEpigram';
import TodayEmotion from '@/components/main/TodayEmotion';
import RecentEpigrams from '@/components/main/RecentEpigram';
Expand All @@ -9,7 +9,7 @@ import FAB from '@/components/main/FAB';
function MainLayout() {
return (
<>
<Header icon='search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<NewHeader />
<main className='w-full min-h-screen bg-background-100 flex flex-col items-center'>
<div className='w-[360px] flex flex-col items-center gap-6 mt-10 mb-40'>
<section className='mt-10'>
Expand Down
4 changes: 2 additions & 2 deletions src/pageLayout/Feed/FeedPageLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from 'react';
import Header from '@/components/Header/Header';
import NewHeader from '@/components/Header/NewHeader';
import FAB from '@/components/main/FAB';
import EpigramFeed from './EpigramFeed';
import AddEpigramFAB from './AddEpigramFAB';

function FeedLayout() {
return (
<>
<Header icon='search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<NewHeader />
<main className='w-full h-auto flex-col justify-start items-center gap-[72px] inline-flex bg-blue-200'>
<div className='w-[312px] md:w-[600px] lg:w-[1200px] h-auto flex-col justify-center items-center gap-14 inline-flex'>
<div className='self-stretch'>
Expand Down
40 changes: 40 additions & 0 deletions src/pageLayout/MypageLayout/EmotionMonthlyLogs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useMonthlyEmotionLogs } from '@/hooks/useGetEmotion';
import { Emotion } from '@/types/emotion';
import { useEffect, useState } from 'react';
import Calendar from '../../user/ui-calendar/Calendar';
import Chart from '../../user/ui-chart/Chart';

interface EmotionMonthlyLogsProps {
userId: number;
}

export default function EmotionMonthlyLogs({ userId }: EmotionMonthlyLogsProps) {
// 현재 날짜를 상태로 관리
const [currentDate, setCurrentDate] = useState<Date>(new Date());

// 감정 달력 객체 상태 추가
const [emotionRequest, setEmotionRequest] = useState<Emotion>({
userId,
year: currentDate.getFullYear(),
month: currentDate.getMonth() + 1,
});

// '월'이 변경될 때마다 request 업데이트
useEffect(() => {
setEmotionRequest({
userId,
year: currentDate.getFullYear(),
month: currentDate.getMonth() + 1,
});
}, [currentDate]);

// 월별 감정 로그 조회
const { data: monthlyEmotionLogs = [] } = useMonthlyEmotionLogs(emotionRequest);

return (
<div className='pb-[110px]'>
<Calendar currentDate={currentDate} setCurrentDate={setCurrentDate} monthlyEmotionLogs={monthlyEmotionLogs} />
<Chart monthlyEmotionLogs={monthlyEmotionLogs} />
</div>
);
}
Loading

0 comments on commit 25849cd

Please sign in to comment.