Skip to content

Commit

Permalink
feat: (#740) 최근 알림 읽기 api, hook 생성 및 적용
Browse files Browse the repository at this point in the history
- 비회원인 경우 알림 툴팁, 사이드가 안열리도록 조치
- 비회원인 경우 알림 툴팁, 사이드 버튼을 눌러도 api 통신되지 않도록 조치
  • Loading branch information
chsua committed Oct 14, 2023
1 parent 0fa00d8 commit b19fa5b
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 10 deletions.
4 changes: 4 additions & 0 deletions frontend/src/api/userInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ export const updateUserInfo = async (userInfo: UpdateUserInfoRequest) => {
await patchFetch<UpdateUserInfoRequest>(`${BASE_URL}/members/me/detail`, userInfo);
};

export const readLatestAlarm = async () => {
await patchFetch('/members/me/check-alarm');
};

export const logoutUser = async () => {
await fetch('/auth/logout', { method: 'DELETE', credentials: 'include' });
};
9 changes: 5 additions & 4 deletions frontend/src/components/common/NarrowMainHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MouseEvent, useContext } from 'react';
import { MouseEvent } from 'react';
import { useNavigate } from 'react-router-dom';

import { AuthContext, useToggle } from '@hooks';
import { useToggle } from '@hooks';

import { PATH } from '@constants/path';

Expand All @@ -15,18 +15,19 @@ import * as S from './style';
interface NarrowMainHeaderProps {
handleCategoryOpenClick: () => void;
handleAlarmOpenClick: () => void;
isAlarmActive?: boolean;
}

export default function NarrowMainHeader({
handleCategoryOpenClick,
handleAlarmOpenClick,
isAlarmActive,
}: NarrowMainHeaderProps) {
const {
isOpen: isSearchInputOpen,
openComponent: openSearchInput,
closeComponent: closeSearchInput,
} = useToggle();
const isActive = useContext(AuthContext).loggedInfo.userInfo?.hasLatestAlarm;

const navigate = useNavigate();

Expand All @@ -49,7 +50,7 @@ export default function NarrowMainHeader({
<IconButton category="category" onClick={handleCategoryOpenClick} />
<LogoButton content="icon" onClick={movePostListPage} />
<IconButton category="search" onClick={openSearchInput} />
<AlarmIconButton isActive={isActive ?? false}>
<AlarmIconButton isActive={isAlarmActive ?? false}>
<IconButton category="alarm" onClick={handleAlarmOpenClick} />
</AlarmIconButton>
<IconButton category="ranking" onClick={moveRankingPage} />
Expand Down
18 changes: 15 additions & 3 deletions frontend/src/components/common/WideHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useNavigate } from 'react-router-dom';

import { AuthContext, useToggle } from '@hooks';

import { useReadLatestAlarm } from '@hooks/query/user/useReadLastestAlarm';

import { PATH } from '@constants/path';

import AlarmIconButton from '../ActiveContainer';
Expand All @@ -24,7 +26,10 @@ export default function WideHeader() {
const navigate = useNavigate();
const { isOpen, openComponent, closeComponent } = useToggle();
const toolTipRef = useRef<HTMLDivElement | null>(null);
const isActive = useContext(AuthContext).loggedInfo.userInfo?.hasLatestAlarm;
const loggedInfo = useContext(AuthContext).loggedInfo;
const isAlarmActive = loggedInfo.userInfo?.hasLatestAlarm;

const { mutate } = useReadLatestAlarm();

const movePostListPage = () => {
navigate('/');
Expand All @@ -34,6 +39,13 @@ export default function WideHeader() {
navigate(PATH.RANKING);
};

const handleToolTipOpen = () => {
if (!loggedInfo.isLoggedIn) return;

openComponent();
mutate();
};

const handleToolTipClick = (e: MouseEvent<HTMLDivElement>) => {
const targetElement = e.target;
targetElement === toolTipRef.current && closeComponent();
Expand All @@ -46,8 +58,8 @@ export default function WideHeader() {
</S.LogoWrapper>
<S.Wrapper>
<SearchBar size="sm" />
<AlarmIconButton isActive={isActive ?? false}>
<IconButton category="alarm" onClick={openComponent} />
<AlarmIconButton isActive={isAlarmActive ?? false}>
<IconButton category="alarm" onClick={handleToolTipOpen} />
</AlarmIconButton>
<IconButton category="ranking" onClick={moveRankingPage} />
</S.Wrapper>
Expand Down
21 changes: 21 additions & 0 deletions frontend/src/hooks/query/user/useReadLastestAlarm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { readLatestAlarm } from '@api/userInfo';

import { QUERY_KEY } from '@constants/queryKey';

export const useReadLatestAlarm = () => {
const queryClient = useQueryClient();

const { mutate } = useMutation({
mutationFn: async () => await readLatestAlarm(),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [QUERY_KEY.USER_INFO] });
},
onError: () => {
//추후 토스트 처리
},
});

return { mutate };
};
19 changes: 16 additions & 3 deletions frontend/src/pages/HomePage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { CSSProperties, Suspense } from 'react';
import { CSSProperties, Suspense, useContext } from 'react';

import { useToggle } from '@hooks';
import { AuthContext, useToggle } from '@hooks';

import { useReadLatestAlarm } from '@hooks/query/user/useReadLastestAlarm';
import { useDrawer } from '@hooks/useDrawer';

import ErrorBoundary from '@pages/ErrorBoundary';
Expand Down Expand Up @@ -45,13 +46,25 @@ export default function HomePage() {

const { isOpen: isBannerOpen, closeComponent: closeBanner } = useToggle(true);

const loggedInfo = useContext(AuthContext).loggedInfo;
const isAlarmActive = loggedInfo.userInfo?.hasLatestAlarm;
const { mutate } = useReadLatestAlarm();

const handleToolTipOpen = () => {
if (!loggedInfo.isLoggedIn) return;

openAlarmDrawer();
mutate();
};

return (
<Layout isSidebarVisible={true} isMobileDefaultHeaderVisible={false}>
<S.Container>
<S.HeaderWrapper>
<NarrowMainHeader
handleCategoryOpenClick={openCategoryDrawer}
handleAlarmOpenClick={openAlarmDrawer}
handleAlarmOpenClick={handleToolTipOpen}
isAlarmActive={isAlarmActive ?? false}
/>
</S.HeaderWrapper>
{isBannerOpen && (
Expand Down

0 comments on commit b19fa5b

Please sign in to comment.