Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a36094e
๐Ÿ’„ UI: ๋งˆ์ดํŽ˜์ด์ง€ UI ์ˆ˜์ • #76
Head-ddy Feb 13, 2025
92155d2
โœจ feat: ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ ๋ณ€๊ฒฝ (์ด๋ฏธ์ง€ ์ˆ˜์ • api ํ•„์š”) #76
Head-ddy Feb 13, 2025
84943c3
โœจ feat: ์ตœ๊ทผ ๋ณธ ๊ฟ€ํŒ ๊ธฐ๋Šฅ (์ €์žฅ๋œ ๊ฟ€ํŒ ํŽ˜์ด์ง€๊นŒ์ง€๋งŒ ์ถ”๊ฐ€๋จ/๋ฉ”์ธ, ๋งค๊ฑฐ์ง„ ๋“ฑ๋“ฑ handleCardClick ์ถ”๊ฐ€์ˆ˜์ •โ€ฆ
Head-ddy Feb 13, 2025
91ccfc3
โœจ feat: ๋ฌดํ•œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ํ•ด๊ฒฐ #76
Head-ddy Feb 16, 2025
9db1c0d
Merge branch 'develop' of https://github.com/UMC-Master/frontend intoโ€ฆ
Head-ddy Feb 16, 2025
6a72cf2
๐Ÿ“ฆ package: InfiniteQuery ์ถ”๊ฐ€ #76
Head-ddy Feb 16, 2025
0811ba9
โœจ feat: getSavedTips api ์ถ”๊ฐ€ (์•„์ง ์—๋Ÿฌ ํ•ด๊ฒฐX) #76
Head-ddy Feb 16, 2025
ffd10df
โœจ feat: useSaveTipList ์ฟผ๋ฆฌ ์ด์šฉํ•ด์„œ ๋ฌดํ•œ์Šคํฌ๋กค ์ถ”๊ฐ€ ์‹œ๋„ #76
Head-ddy Feb 16, 2025
28835fc
โœจ feat: api ์—ฐ๊ฒฐ ์ค‘ #76
Head-ddy Feb 16, 2025
50fd8e3
โœจ feat: tip ํ˜•์‹ ํ†ต์ผ #76
Head-ddy Feb 16, 2025
592e461
โœจ feat: ์นด์นด์˜ค ๊ณต์œ ํ•˜๊ธฐ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ #76
Head-ddy Feb 16, 2025
cc59dfd
โœจ feat: getTipDetail api, useTipDetail ์ถ”๊ฐ€ #76
Head-ddy Feb 16, 2025
b10555d
โœจ feat: dummydata ์‚ญ์ œ ํ›„ api ์—ฐ๊ฒฐ ์‹œ๋„ #76
Head-ddy Feb 16, 2025
1b1477d
โœจ feat: comment get, post, put, delete api ์ถ”๊ฐ€ #76
Head-ddy Feb 16, 2025
6062280
โœจ feat: ์ข‹์•„์š”์™€ ๋ถ๋งˆํฌ ํ† ๊ธ€ api ์ถ”๊ฐ€ #76
minzee09 Feb 17, 2025
2c85a8e
โœจ feat: ์ข‹์•„์š”์™€ ๋ถ๋งˆํฌ mutation ์ถ”๊ฐ€ #76
minzee09 Feb 17, 2025
4d8e9c7
๐Ÿ’„ UI: ํ† ๊ธ€ ๋ฒ„ํŠผ๋“ค ์ปดํฌ๋„ŒํŠธํ™” #76
minzee09 Feb 17, 2025
b3a8c2b
โ™ป๏ธ refactor: ์ปดํฌ๋„ŒํŠธํ™” ๋ฐ˜์˜ #76
minzee09 Feb 17, 2025
150b187
๐Ÿ’„ UI: ๊ฟ€ํŒ ์ƒ์„ธ ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ #76
minzee09 Feb 17, 2025
001a38f
โ™ป๏ธ refactor: ์ €์žฅ ์œ„์น˜ ๋ณ€๊ฒฝ #76
minzee09 Feb 17, 2025
e7660d9
โœจ feat: ์ €์žฅ ๊ฟ€ํŒ ๋ฐ˜ํ™˜๊ฐ’ ์ˆ˜์ • #76
minzee09 Feb 17, 2025
fd3eab5
๐Ÿ’„ UI: modify width #76
minzee09 Feb 17, 2025
c028fe9
๐Ÿ’„ UI: remove text #76
minzee09 Feb 17, 2025
374cd73
โœจ feat: ์ €์žฅํ•œ ๊ฟ€ํŒ api ์—ฐ๊ฒฐ #76
minzee09 Feb 17, 2025
016b031
โœจ feat: ์นด์นด์˜ค ๊ณต์œ ํ•˜๊ธฐ ๊ธฐ๋Šฅ ์˜ค๋ฅ˜ ์ˆ˜์ • [#76]
Head-ddy Feb 18, 2025
2da2c19
๐Ÿ’„ UI: cursor pointer ์ถ”๊ฐ€ [#76]
Head-ddy Feb 20, 2025
6ccb4d1
โœจ feat: ์ด๋ฉ”์ผ ์ž…๋ ฅ ํผ api ์ˆ˜์ • #76
Head-ddy Feb 20, 2025
949fb71
โœจ feat: ์ข‹์•„์š” ๋ฐ ์ €์žฅ ์—ฌ๋ถ€ ์ €์žฅ #76
minzee09 Feb 20, 2025
6d237ce
๐Ÿ’ฌ comment: ์ฃผ์„ ์‚ญ์ œ #76
minzee09 Feb 20, 2025
d2855de
โ™ป๏ธ refactor: DTO ์ˆ˜์ •์‚ฌํ•ญํ•ญ ๋ฐ˜์˜ #76
minzee09 Feb 20, 2025
d53bceb
โœจ feat: ๋Œ“๊ธ€ api ์—ฐ๊ฒฐ #76
minzee09 Feb 20, 2025
738c853
โœจ feat: ๋Œ“๊ธ€ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ #76
minzee09 Feb 20, 2025
2ceb053
๐Ÿ› bug: ์นด์นด์˜ค ๊ณต์œ  #76
minzee09 Feb 20, 2025
2aee74e
โœจ feat: ์ธํ„ฐํŽ˜์ด์Šค ์†์„ฑ ๋ฐ˜์˜ #76
minzee09 Feb 20, 2025
26027e7
๐Ÿ› bug: ํƒ€์ž… ์—๋Ÿฌ ํ•ด๊ฒฐ #76
minzee09 Feb 20, 2025
7805e5c
โ™ป๏ธ refactor: ๋Œ“๊ธ€ ์ธํ„ฐํŽ˜์ด์Šค ์ ์šฉ #76
minzee09 Feb 20, 2025
ea55d65
โœจ feat: ํšŒ์›๊ฐ€์ž… api ์—ฐ๊ฒฐ #76
Head-ddy Feb 20, 2025
13991e3
โœจ feat: userStore updateProfile ์ถ”๊ฐ€ #76
Head-ddy Feb 20, 2025
508bc63
Merge branch 'develop' into feat/#76-Feature-PageApi
Head-ddy Feb 20, 2025
86fe454
โœจ feat: ์˜ค๋ฅ˜ ์ˆ˜์ • #76
Head-ddy Feb 20, 2025
b72562b
๋ณต์ œ ๋ฌธ์„œ ์‚ญ์ œ
Head-ddy Feb 20, 2025
3230c75
โœจ feat: ํšŒ์›๊ฐ€์ž… ์˜ค๋ฅ˜ ์ˆ˜์ •์ค‘ #76
Head-ddy Feb 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions umc-master/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<script src="https://t1.kakaocdn.net/kakao_js_sdk/2.7.4/kakao.min.js" crossorigin="anonymous"></script>
</head>
<body>
<div id="root"></div>
Expand Down
4 changes: 2 additions & 2 deletions umc-master/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
},
"dependencies": {
"@fortawesome/fontawesome-free": "^6.7.2",
"@tanstack/react-query": "^5.65.0",
"@tanstack/react-query-devtools": "^5.65.0",
"@tanstack/react-query": "^5.66.3",
"@tanstack/react-query-devtools": "^5.66.3",
"@types/node": "^22.10.5",
"@types/styled-components": "^5.1.34",
"axios": "^1.7.9",
Expand Down
13 changes: 9 additions & 4 deletions umc-master/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ import { ThemeProvider } from 'styled-components';
import GlobalStyle from '@styles/globalStyle.ts';
import theme from '@styles/theme.ts';
import Router from './router/routes.tsx';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

function App() {
return (
<ThemeProvider theme={theme}>
<GlobalStyle />
<Router />
</ThemeProvider>
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={theme}>
<GlobalStyle />
<Router />
</ThemeProvider>
</QueryClientProvider>
);
}

Expand Down
38 changes: 38 additions & 0 deletions umc-master/src/apis/authApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// import axiosInstance from '@apis/axios-instance';

// interface UserSignup {
// email: string;
// password: string;
// nickname: string;
// hashtags: string[];
// }

// export const postSignup = async ({ email, password, nickname, hashtags } : UserSignup) => {
// const { data } = await axiosInstance.post(`/signup`, {
// email,
// password,
// nickname,
// hashtags,
// });
// return data;
// };

import axios from 'axios';

export const postSignup = async () => {
try {
const response = await axios.post('https://api.hmaster.shop/api/v1/signup', {
email: 'ekos555@naver.com',
password: 'asfa1234!@',
nickname: 'rael',
hashtags: ['๋ด„', 'ํŒจ์…˜', '์ฒญ์†Œ', '์š”๋ฆฌ', '์žฌํ™œ์šฉ', '์ฃผํƒ']
}, {
headers: {
'Content-Type': 'application/json'
}
});
console.log('ํšŒ์›๊ฐ€์ž… ์„ฑ๊ณต:', response.data);
} catch (error) {
console.error('ํšŒ์›๊ฐ€์ž… ์˜ค๋ฅ˜:', error);
}
};
4 changes: 3 additions & 1 deletion umc-master/src/apis/axios-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ axiosInstance.interceptors.response.use(
useTokenStore.getState().clearTokens();

// ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
window.location.href = RoutePaths.LOGIN;
if (window.location.pathname !== RoutePaths.LOGIN) {
window.location.href = RoutePaths.LOGIN;
}

return Promise.reject(refreshError);
}
Expand Down
46 changes: 46 additions & 0 deletions umc-master/src/apis/commentApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import axiosInstance from './axios-instance';

export const getComments = async (tipId: number) => {
try {
const { data } = await axiosInstance.get('/comments');
return data.result.filter((comment: any) => comment.tips_id === tipId);
} catch (error: any) {
console.error('๋Œ“๊ธ€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์‹คํŒจ:', error);
throw new Error('๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
};

export const addComment = async (tipId: string, comment: string) => {
try {
const { data } = await axiosInstance.post(`/tips/${tipId}/comments`, {
comment,
});
return data;
} catch (error: any) {
console.error('๋Œ“๊ธ€ ์ถ”๊ฐ€ ์‹คํŒจ:', error);
throw new Error('๋Œ“๊ธ€ ์ถ”๊ฐ€์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
};

export const editComment = async (tipId: string, commentId: string, newComment: string) => {
try {
const { data } = await axiosInstance.put(`/tips/${tipId}/comments/${commentId}`, {
comment: newComment,
});
return data;
} catch (error: any) {
console.error('๋Œ“๊ธ€ ์ˆ˜์ • ์‹คํŒจ:', error);
throw new Error('๋Œ“๊ธ€ ์ˆ˜์ •์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
};

export const deleteComment = async (tipId: string, commentId: string) => {
try {
const { data } = await axiosInstance.delete(`/tips/${tipId}/comments/${commentId}`);
return data;
} catch (error: any) {
console.error('๋Œ“๊ธ€ ์‚ญ์ œ ์‹คํŒจ:', error);
throw new Error('๋Œ“๊ธ€ ์‚ญ์ œ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
};
59 changes: 59 additions & 0 deletions umc-master/src/apis/queries/useCommentMutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { getComments, addComment, editComment, deleteComment } from '@apis/commentApi';
import { useUserStore } from '@store/userStore';
export interface Comment {
comment_id: number;
user: {
user_id: number;
nickname: string;
profileImageUrl?: string | null;
};
comment: string;
created_at: string;
}

export const useAddComment = (tipId: number) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (comment: string) => addComment(tipId.toString(), comment),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['comments', tipId] });
},
});
};

export const useDeleteComment = (tipId: number) => {
const queryClient = useQueryClient();
const { user } = useUserStore();
return useMutation({
mutationFn: async (commentId: number) => {
const comments: Comment[] = await getComments(tipId);
const comment = comments.find((c) => c.comment_id === commentId);
if (comment?.user.user_id !== user?.user_id) {
throw new Error('๋ณธ์ธ์˜ ๋Œ“๊ธ€๋งŒ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.');
}
return deleteComment(tipId.toString(), commentId.toString());
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['comments', tipId] });
},
});
};

export const useUpdateComment = (tipId: number) => {
const queryClient = useQueryClient();
const { user } = useUserStore();
return useMutation({
mutationFn: async ({ commentId, newComment }: { commentId: number; newComment: string }) => {
const comments: Comment[] = await getComments(tipId);
const comment = comments.find((c) => c.comment_id === commentId);
if (comment?.user.user_id !== user?.user_id) {
throw new Error('๋ณธ์ธ์˜ ๋Œ“๊ธ€๋งŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.');
}
return editComment(tipId.toString(), commentId.toString(), newComment);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['comments', tipId] });
},
});
};
9 changes: 9 additions & 0 deletions umc-master/src/apis/queries/useCommentQueries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useQuery } from '@tanstack/react-query';
import { getComments } from '@apis/commentApi';

export const useComments = (tipId: number) => {
return useQuery({
queryKey: ['comments', tipId],
queryFn: () => getComments(tipId),
});
};
13 changes: 13 additions & 0 deletions umc-master/src/apis/queries/useSaveTipQueries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useInfiniteQuery } from "@tanstack/react-query";
import { getSavedTips } from "@apis/tipApi";

export const useSaveTipList = () => {
return useInfiniteQuery({
queryKey: ["savedTips"],
queryFn: () => getSavedTips(),
initialPageParam: 1,
getNextPageParam: (lastPage, allPages) => {
return lastPage.hasMore ? allPages.length + 1 : undefined;
},
});
};
32 changes: 32 additions & 0 deletions umc-master/src/apis/queries/useTipDetailMutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { toggleLike, toggleBookmark } from '@apis/tipApi';

export const useToggleLike = (tipId: number) => {
const queryClient = useQueryClient();

return useMutation({
mutationFn: () => toggleLike(tipId),
onSuccess: (data) => {
console.log(data.message);
queryClient.invalidateQueries({ queryKey: ['tipDetail', tipId] });
},
onError: (error) => {
console.error('์ข‹์•„์š” ํ† ๊ธ€ ์˜ค๋ฅ˜:', error);
},
});
};

export const useToggleBookmark = (tipId: number) => {
const queryClient = useQueryClient();

return useMutation({
mutationFn: () => toggleBookmark(tipId),
onSuccess: (data) => {
console.log(data.message);
queryClient.invalidateQueries({ queryKey: ['tipDetail', tipId] });
},
onError: (error) => {
console.error('๋ถ๋งˆํฌ ํ† ๊ธ€ ์˜ค๋ฅ˜:', error);
},
});
};
10 changes: 10 additions & 0 deletions umc-master/src/apis/queries/useTipDetailQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { getTipDetail } from '@apis/tipApi';
import { useQuery } from '@tanstack/react-query';

export const useTipDetail = (tipId: number) => {
return useQuery({
queryKey: ['tipDetail', tipId],
queryFn: () => getTipDetail(tipId),
enabled: !!tipId, // tipId๊ฐ€ ์žˆ์„ ๋•Œ๋งŒ ์‹คํ–‰
});
};
30 changes: 29 additions & 1 deletion umc-master/src/apis/tipApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export interface NewPost {
imageUrls: File[];
}

export interface GetSavedParams {
page: number;
}

export const getTips = async ({ pageParam, sorted }: GetTipsParams) => {
const { data } = await axiosInstance.get(`/tips/sorted?page=${pageParam}&limit=5&sort=${sorted}`);
return data;
Expand Down Expand Up @@ -50,4 +54,28 @@ export const createPost = async (newPost: NewPost): Promise<void> => {
}
};

// ๋‹ค๋ฅธ Tips ๊ด€๋ จ API๋“ค...
export const getSavedTips = async () => {
try {
const { data } = await axiosInstance.get(`/users/saved-tips`);
console.log('์ €์žฅ๋œ ๊ฟ€ํŒ API ์‘๋‹ต:', data.result);
return data.result;
} catch (error: any) {
console.error('์ €์žฅ๋œ ๊ฟ€ํŒ API ์—๋Ÿฌ ๋ฐœ์ƒ:', error.response?.status, error.response?.data);
throw new Error(`์ €์žฅ๋œ ๊ฟ€ํŒ API ์š”์ฒญ ์‹คํŒจ: ${error.response?.status}`);
}
};

export const getTipDetail = async (tipId: number) => {
const { data } = await axiosInstance.get(`/tips/${tipId}`);
return data.result;
};

export const toggleLike = async (tipId: number) => {
const response = await axiosInstance.post(`/tips/${tipId}/like`);
return response.data;
};

export const toggleBookmark = async (tipId: number) => {
const response = await axiosInstance.post(`/tips/${tipId}/bookmark`);
return response.data;
};
Binary file added umc-master/src/assets/gray-character.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions umc-master/src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ const CardImageWrapper = styled.div`
`;

const CardImage = styled.img`
min-width: 240px;
width: 100%;
width: 240px;
height: 200px;
object-fit: cover;
`;
19 changes: 16 additions & 3 deletions umc-master/src/components/NavigationBar/NavigationBar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable react/prop-types */
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import LogoImage from '@assets/logo.png';
Expand All @@ -8,6 +8,9 @@ import Typography from '@components/common/typography';
import AlarmIcon from '@assets/icons/alarm.svg?react';
import AlarmModal from '@components/Modal/alarm';
import ProfileModal from '@components/Modal/profile';
import { useUserStore } from '@store/userStore';
import { getUsers } from '@apis/profileApi';
import gray_character from '@assets/gray-character.png';

interface NavigationBarProps {
login: boolean;
Expand All @@ -16,6 +19,12 @@ interface NavigationBarProps {
const NavigationBar: React.FC<NavigationBarProps> = ({ login }) => {
const [isAlarmModalOpen, setIsAlarmModalOpen] = useState(false);
const [isProfileModalOpen, setIsProfileModalOpen] = useState(false);
const { user, fetchUser } = useUserStore();

useEffect(() => {
fetchUser(); // ์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ ์‹œ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
}, []);
getUsers();

const toggleAlarmModal = () => setIsAlarmModalOpen((prev) => !prev);
const toggleProfileModal = () => setIsProfileModalOpen((prev) => !prev);
Expand Down Expand Up @@ -45,7 +54,11 @@ const NavigationBar: React.FC<NavigationBarProps> = ({ login }) => {
{login ? (
<UserSection>
<AlarmIcon onClick={toggleAlarmModal} />
<ProfileImg onClick={toggleProfileModal} />
<ProfileImg
src={user?.profile_image_url || gray_character}
alt="Profile Image"
onClick={toggleProfileModal}
/>
</UserSection>
) : (
<LoginBtn to={RoutePaths.LOGIN}>
Expand Down Expand Up @@ -113,7 +126,7 @@ const UserSection = styled.div`
cursor: pointer;
`;

const ProfileImg = styled.div`
const ProfileImg = styled.img`
width: 40px;
height: 40px;
background: #e0e0e0; /** TODO: ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ */
Expand Down
1 change: 1 addition & 0 deletions umc-master/src/pages/auth/Login_components/InputForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ const StyledCheckbox = styled.input`

const StyledTypography = styled(Typography)`
color: ${({ theme }) => theme.colors.text.gray};
cursor: pointer;
`;

const Options = styled.div`
Expand Down
Loading