diff --git a/package-lock.json b/package-lock.json index b326f467..b52b8b47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.50.0", + "@types/lodash": "^4.17.7", "@types/node": "^20.14.10", "@types/qs": "^6.9.15", "@types/react": "^18.3.3", @@ -1936,6 +1937,12 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", + "dev": true + }, "node_modules/@types/node": { "version": "20.14.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", @@ -2915,6 +2922,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/kossnocorp" diff --git a/public/horizen.png b/public/horizen.png new file mode 100644 index 00000000..a64360ec Binary files /dev/null and b/public/horizen.png differ diff --git a/public/icon/grid-icon.svg b/public/icon/grid-icon.svg new file mode 100644 index 00000000..af95c880 --- /dev/null +++ b/public/icon/grid-icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/icon/sort-icon.svg b/public/icon/sort-icon.svg new file mode 100644 index 00000000..d0a92737 --- /dev/null +++ b/public/icon/sort-icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/apis/getRecentComments.ts b/src/apis/getRecentComments.ts index 5f83fcca..53b48b40 100644 --- a/src/apis/getRecentComments.ts +++ b/src/apis/getRecentComments.ts @@ -1,9 +1,10 @@ import type { GetRecentCommentsResponseType } from '@/schema/recentcomment'; import httpClient from './index'; -const getRecentComments = async (limit: number): Promise => { +const getRecentComments = async (cursor: number, limit: number): Promise => { const response = await httpClient.get('/comments', { params: { + cursor, limit, }, }); diff --git a/src/apis/getRecentEpigrams.ts b/src/apis/getRecentEpigrams.ts index a2fb9f52..04db411a 100644 --- a/src/apis/getRecentEpigrams.ts +++ b/src/apis/getRecentEpigrams.ts @@ -1,9 +1,10 @@ import type { GetRecentEpigramsResponseType } from '@/schema/recentEpigram'; import httpClient from './index'; -const getRecentEpigrams = async (limit: number): Promise => { +const getRecentEpigrams = async (cursor: number | null, limit: number): Promise => { const response = await httpClient.get('/epigrams', { params: { + cursor, limit, }, }); diff --git a/src/apis/postGoogleOauth.ts b/src/apis/postGoogleOauth.ts new file mode 100644 index 00000000..66e9e737 --- /dev/null +++ b/src/apis/postGoogleOauth.ts @@ -0,0 +1,11 @@ +import httpClient from '.'; + +const postGoogleOauth = async (code: string) => { + const response = await httpClient.post('/auth/signIn/GOOGLE', { + redirectUri: process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URI, + token: code, + }); + return response.data; +}; + +export default postGoogleOauth; diff --git a/src/apis/postNaverOauth.ts b/src/apis/postNaverOauth.ts new file mode 100644 index 00000000..56434bb0 --- /dev/null +++ b/src/apis/postNaverOauth.ts @@ -0,0 +1,12 @@ +import httpClient from '.'; + +const postNaverOauth = async (code: string, state: string) => { + const response = await httpClient.post('/auth/signIn/NAVER', { + state, + redirectUri: process.env.NEXT_PUBLIC_NAVER_REDIRECT_URI, + token: code, + }); + return response.data; +}; + +export default postNaverOauth; diff --git a/src/components/Card/CommentCard.tsx b/src/components/Card/CommentCard.tsx index 45368d72..9dbdea2e 100644 --- a/src/components/Card/CommentCard.tsx +++ b/src/components/Card/CommentCard.tsx @@ -13,7 +13,7 @@ function CommentCard({ writer, content, createdAt, status }: CommentCardProps) {
- 프로필 이미지 + {`${writer.nickname}의{' '}
diff --git a/src/components/Emotion/EmotionSelector.tsx b/src/components/Emotion/EmotionSelector.tsx index 4375c3ca..57bae69a 100644 --- a/src/components/Emotion/EmotionSelector.tsx +++ b/src/components/Emotion/EmotionSelector.tsx @@ -10,7 +10,12 @@ import EmotionSaveToast from './EmotionSaveToast'; * EmotionSelector 컴포넌트는 여러 개의 EmotionIconCard를 관리하고 * 사용자의 오늘의 감정을 선택하고 저장하고 출력합니다. */ -function EmotionSelector() { + +interface EmotionSelectorProps { + onEmotionSaved: () => void; // Callback for when the emotion is saved +} + +function EmotionSelector({ onEmotionSaved }: EmotionSelectorProps) { // 반응형 디자인을 위한 미디어 쿼리 훅 const isTablet = useMediaQuery('(min-width: 768px) and (max-width: 1024px)'); const isMobile = useMediaQuery('(max-width: 767px)'); @@ -26,6 +31,8 @@ function EmotionSelector() { // 현재 선택된 감정을 관리하는 useState 훅 const [selectedEmotion, setSelectedEmotion] = useState(null); + const [showToast, setShowToast] = useState(false); // State for controlling the toast + // 오늘의 감정을 조회하기 위한 훅 const { data: emotion, error: getError, isLoading: isGetLoading } = useGetEmotion(); // 감정을 저장하기 위한 훅 @@ -49,7 +56,9 @@ function EmotionSelector() { * 감정을 서버에 저장합니다. * @param iconType - 클릭된 감정의 타입 */ + const handleCardClick = async (iconType: EmotionType) => { + let emotionChanged = false; setStates((prevStates) => { const newStates = { ...prevStates }; @@ -63,6 +72,7 @@ function EmotionSelector() { Object.keys(newStates).forEach((key) => { newStates[key as EmotionType] = key === iconType ? 'Clicked' : 'Unclicked'; }); + emotionChanged = true; } return newStates; @@ -71,7 +81,14 @@ function EmotionSelector() { // 오늘의 감정 저장 postEmotionMutation.mutate(iconType, { onSuccess: (_, clickedIconType) => { - setSelectedEmotion(clickedIconType); + if (emotionChanged) { + setSelectedEmotion(clickedIconType); + setShowToast(true); + setTimeout(() => { + setShowToast(false); + onEmotionSaved(); + }, 1000); + } }, onError: (error: unknown) => { // eslint-disable-next-line @@ -103,7 +120,7 @@ function EmotionSelector() { ))}
{/* 감정이 선택되었을 때 토스트 메시지 표시 */} - {selectedEmotion && } + {showToast && selectedEmotion && } ); } diff --git a/src/components/main/FAB.tsx b/src/components/main/FAB.tsx index 740e35d5..2d064dc6 100644 --- a/src/components/main/FAB.tsx +++ b/src/components/main/FAB.tsx @@ -10,7 +10,7 @@ function FAB() {