-
Notifications
You must be signed in to change notification settings - Fork 2
feat: 오고 있는 편지 조회 기능 구현 (mock api) #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
39db01e
bbc8672
7f5b65b
c977fd1
2ba7659
d237181
1203c29
3538dfc
ae5d936
aba9db6
d388591
baa3de7
c3a0b88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import { client } from '@/apis/client'; | ||
|
|
||
| export const fetchIncomingLettersApi = async (token: string) => { | ||
| try { | ||
| const { data } = await client.get('/api/letters?status=delivery', { | ||
| headers: { | ||
| Authorization: `Bearer ${token}`, | ||
| }, | ||
| }); | ||
| console.log('불러온 데이터', data); | ||
| return data; | ||
| } catch (error) { | ||
| console.error('❌오고 있는 편지 목록을 불러오던 중 에러 발생', error); | ||
| throw error; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,24 @@ | ||
| import { useEffect } from 'react'; | ||
|
|
||
| import { useIncomingLettersStore } from '@/stores/incomingLettersStore'; | ||
|
|
||
| import FloatingLetters from './FloatingLetters'; | ||
| import GoToLetterBoard from './GoToLetterBoard'; | ||
| import GoToLetterBox from './GoToLetterBox'; | ||
| import NewLetterModal from './NewLetterModal'; | ||
|
|
||
| const HomeRight = () => { | ||
| //TODO : hasNewLetters 전역으로 상태 관리할지 | ||
| let hasNewLetters = true; | ||
| const { arrivedCount, fetchIncomingLetters } = useIncomingLettersStore(); | ||
| useEffect(() => { | ||
| fetchIncomingLetters(); | ||
| }, []); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오옹 혹시 전역으로 상태 관리하는 이유가 무엇일까요?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 새로 도착한 편지들의 유무/개수를 오고 있는 편지 조회쪽에서 받아와야 해서 전역으로 상태 관리하도록 하였습니다! |
||
|
|
||
| return ( | ||
| <div className="flex h-screen w-full max-w-150 min-w-[300px] flex-shrink-0 grow snap-start flex-col items-center overflow-x-hidden pt-5"> | ||
| {hasNewLetters && <FloatingLetters />} | ||
| {arrivedCount !== 0 && <FloatingLetters />} | ||
| <GoToLetterBox /> | ||
| <GoToLetterBoard /> | ||
| {hasNewLetters && <NewLetterModal />} | ||
| {arrivedCount !== 0 && <NewLetterModal />} | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,9 @@ | ||
| import { useState } from 'react'; | ||
| import { RANDOM_CHEER_LIST } from '../constants'; | ||
|
|
||
| import randomCheerBird from '@/assets/images/random-cheer-bird.png'; | ||
|
|
||
| import { RANDOM_CHEER_LIST } from '../constants'; | ||
|
|
||
| const RandomCheer = () => { | ||
| const getRandomCheer = (): string => { | ||
| const randomIndex = Math.floor(Math.random() * RANDOM_CHEER_LIST.length); | ||
|
|
@@ -11,7 +13,7 @@ const RandomCheer = () => { | |
| const [randomCheer, setRandomCheer] = useState(getRandomCheer()); | ||
|
|
||
| return ( | ||
| <div className="z-30 flex flex-col items-end pr-20"> | ||
| <div className="z-26 mr-20 flex flex-col items-end"> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 테일윈드 z-index 기본 제공값이 0, 10, 20, 30, 40 ,50인걸로 알고 있어요! 그래서 26같은 인덱스는 중괄호 []를 묶어서 z-[26] 이렇게 사용했었는데 이렇게 설정해도 잘 작동되나용?(테일윈드 4.0업데이트 되고 바꼈을 수도 있어성..)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tailwind 4.0 업데이트 후에는 1단위로도 지원한다고 합니다! 다만 무한정 지원하는 건 아니고 속성 별로 허용 범위가 있다고 하네요 |
||
| <div | ||
| className="relative mb-3 w-fit rounded-lg border-1 border-white bg-white px-6 py-[7px] text-center" | ||
| onClick={() => setRandomCheer(getRandomCheer())} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| import { create } from 'zustand'; | ||
|
|
||
| import { fetchIncomingLettersApi } from '@/apis/incomingLetters'; | ||
|
|
||
| interface IncomingLetters { | ||
| letterId: number; | ||
| title: string; | ||
| deliveryStartedAt: string; | ||
| deliveryCompletedAt: string; | ||
| remainingTime: string; | ||
| } | ||
|
|
||
| interface IncomingLettersStore { | ||
| data: IncomingLetters[]; | ||
| arrivedCount: number; | ||
| message: string; | ||
| timestamp: string; | ||
| fetchIncomingLetters: () => void; | ||
| } | ||
|
|
||
| const formatTime = (time: number): string => (time < 10 ? `0${time}` : `${time}`); | ||
|
|
||
| const calculatingRemainingTime = (deliveryCompletedAt: string): string => { | ||
| const completedAt = new Date(deliveryCompletedAt).getTime(); | ||
| const now = new Date().getTime(); | ||
| const diff = completedAt - now; | ||
|
|
||
| if (diff <= 0) return '00:00:00'; | ||
|
|
||
| const hours = Math.floor(diff / (1000 * 60 * 60)); | ||
| const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); | ||
| const seconds = Math.floor((diff % (1000 * 60)) / 1000); | ||
|
|
||
| return `${formatTime(hours)}:${formatTime(minutes)}:${formatTime(seconds)}`; | ||
| }; | ||
|
|
||
| export const useIncomingLettersStore = create<IncomingLettersStore>((set) => ({ | ||
| data: [], | ||
| arrivedCount: 0, | ||
| message: '', | ||
| timestamp: '', | ||
| fetchIncomingLetters: async () => { | ||
| try { | ||
| const token = localStorage.getItem('token') || ''; | ||
| const data = await fetchIncomingLettersApi(token); | ||
|
|
||
| let arrivedCount = 0; | ||
| const updatedLetters = data.data.map((letter: IncomingLetters) => { | ||
| const remainingTime = calculatingRemainingTime(letter.deliveryCompletedAt); | ||
| if (remainingTime === '00:00:00') arrivedCount += 1; // 도착한 편지 카운트 | ||
|
|
||
| return { ...letter, remainingTime }; | ||
| }); | ||
|
|
||
| const inProgressLetters = updatedLetters.filter( | ||
| (letter: IncomingLetters) => letter.remainingTime !== '00:00:00', | ||
| ); | ||
| set({ | ||
| data: inProgressLetters, | ||
| arrivedCount, | ||
| message: data.message, | ||
| timestamp: data.timestamp, | ||
| }); | ||
| } catch (error) { | ||
| console.error('❌오고 있는 편지 목록을 불러오던 중 에러 발생', error); | ||
| } | ||
| }, | ||
| })); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
차후에 로그인 기능 구현하면 header는 일괄적으로 처리해서 나중에 수정하면 더 좋을 것 같아요!
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네 그때 수정하도록 할게요!