diff --git a/client/src/api/mypage-api.ts b/client/src/api/mypage-api.ts index 19ef574d..50c08910 100644 --- a/client/src/api/mypage-api.ts +++ b/client/src/api/mypage-api.ts @@ -45,3 +45,20 @@ export const postChangeBlogNameApi = async (body: IBlogInfo) => { return data; }; + +export const getVisitApi = async () => { + const { data } = await defaultInstance.get(`/visit`); + + return data; +}; + +export const useGetVisitQuery = () => { + const { isLoading, error, data } = useQuery([`visit`], () => getVisitApi()); + return { data, isLoading, error }; +}; + +export const postVisitApi = async (body: { blogId: number }) => { + const { data } = await defaultInstance.post(`/visit?blogId=${body.blogId}`); + + return data; +}; diff --git a/client/src/api/readme-api.ts b/client/src/api/readme-api.ts index ae25aa27..6a12ab44 100644 --- a/client/src/api/readme-api.ts +++ b/client/src/api/readme-api.ts @@ -27,9 +27,7 @@ export const usegetblogIdQuery = (params: IBlogIdParams) => { }; export const PutReadMeApi = async (body: IReadMe) => { - const { data } = await defaultInstance.put('/read-me', { - body, - }); + const { data } = await defaultInstance.put('/read-me', body); return data; }; diff --git a/client/src/api/userDetail-api.ts b/client/src/api/userDetail-api.ts index 53c3dc4b..e187da72 100644 --- a/client/src/api/userDetail-api.ts +++ b/client/src/api/userDetail-api.ts @@ -1,5 +1,6 @@ import { useQuery } from '@tanstack/react-query'; import { defaultInstance } from '.'; +import { IUserDetail } from '@/types/dto'; export const GetUserDetailApi = async () => { const { data } = await defaultInstance.get('/user/detail'); @@ -8,7 +9,13 @@ export const GetUserDetailApi = async () => { }; export const useGetUserDetailQuery = () => { - const { isLoading, error, data } = useQuery(['userDetail'], () => GetUserDetailApi()); + const { + isLoading, + error, + data: backendData, + } = useQuery(['userDetail'], () => GetUserDetailApi()); + + const data: IUserDetail = backendData; return { isLoading, error, data }; }; diff --git a/client/src/app/[blogName]/home/[categoryId]/[postId]/page.tsx b/client/src/app/[blogName]/home/[categoryId]/[postId]/page.tsx index f18fbf5b..2fb1c226 100644 --- a/client/src/app/[blogName]/home/[categoryId]/[postId]/page.tsx +++ b/client/src/app/[blogName]/home/[categoryId]/[postId]/page.tsx @@ -48,10 +48,11 @@ import { usegetblogIdQuery } from '@/api/readme-api'; import { AddLikeApi, DeleteWriteApi } from '@/api/write-api'; import { enqueueSnackbar } from 'notistack'; import ThumbUpIcon from '@mui/icons-material/ThumbUp'; +import { postVisitApi } from '@/api/mypage-api'; const page = ({ params }: { params: { blogName: string; categoryId: string; postId: string } }) => { const { data: blogIdData } = usegetblogIdQuery({ blogUrl: params.blogName }); - const [, setBlogId] = useState(); + const [blogId, setBlogId] = useState(); const { data: sidebarData } = useGetSidebarQuery({ blogId: blogIdData }); const { data: postData } = useGetPostQuery({ postId: Number(params.postId) }); const [IntroduceOpen, setIntroduceOpen] = useState(false); @@ -89,6 +90,16 @@ const page = ({ params }: { params: { blogName: string; categoryId: string; post }, }); + const postVisitQuery = useMutation(postVisitApi, { + onSuccess: () => { + queryClient.invalidateQueries(['visit']); + }, + }); + + useEffect(() => { + postVisitQuery.mutate({ blogId: blogId?.blogId ?? 0 }); + }, []); + const ReplyOnClick = () => { const newReplyBody = { postId: Number(params.postId), @@ -345,8 +356,7 @@ const page = ({ params }: { params: { blogName: string; categoryId: string; post diff --git a/client/src/app/[blogName]/home/[categoryId]/[postId]/postId.style.tsx b/client/src/app/[blogName]/home/[categoryId]/[postId]/postId.style.tsx index b8ff05ad..5d2c7fc9 100644 --- a/client/src/app/[blogName]/home/[categoryId]/[postId]/postId.style.tsx +++ b/client/src/app/[blogName]/home/[categoryId]/[postId]/postId.style.tsx @@ -252,8 +252,7 @@ function RepliesComponent({ diff --git a/client/src/app/[blogName]/page.tsx b/client/src/app/[blogName]/page.tsx index 0d840b56..e6f44e73 100644 --- a/client/src/app/[blogName]/page.tsx +++ b/client/src/app/[blogName]/page.tsx @@ -1,73 +1,52 @@ 'use client'; import { useGetSidebarQuery } from '@/api/blog-api'; -import { PutReadMeApi, useGetReadMeQuery, usegetblogIdQuery } from '@/api/readme-api'; +import { useGetReadMeQuery, usegetblogIdQuery } from '@/api/readme-api'; import Button from '@/components/Button/Button'; import DragAndDrop from '@/components/DND/DragAndDrop'; import FootPrintAnimation from '@/components/FootPrint/FootPrintAnimation'; import { ISidebarContent } from '@/types/dto'; -import { Stack, TextField } from '@mui/material'; -import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { Stack } from '@mui/material'; import MDEditor from '@uiw/react-md-editor'; -import { enqueueSnackbar } from 'notistack'; import { useEffect, useState } from 'react'; +import { useRouter } from 'next/navigation'; const Home = ({ params }: { params: { blogName: string } }) => { const [writeList, setWriteList] = useState(); - - //[FIXME: 나중에 blogName blogUrl로 바꾸기] - const [, setBlogId] = useState(); const { data: blogIdData } = usegetblogIdQuery({ blogUrl: params.blogName }); const { data: sidebarData } = useGetSidebarQuery({ blogId: blogIdData }); const { data: readMeData } = useGetReadMeQuery({ blogId: blogIdData }); const [readMe, setReadMe] = useState(''); - const queryClient = useQueryClient(); - - const [content, setContent] = useState(''); - const putReadMeCreateQuery = useMutation(PutReadMeApi, { - onSuccess: () => { - queryClient.invalidateQueries(['readMe']); - enqueueSnackbar({ message: '리드미 페이지가 수정되었습니다.', variant: 'success' }); - }, - onError: () => { - enqueueSnackbar({ message: '리드미 페이지가 수정되지 않았습니다.', variant: 'error' }); - }, - } - ); - - const ReadMeOnClick = () => { - const newReadMeBody = { - content: content, - }; - - putReadMeCreateQuery.mutate(newReadMeBody); - }; + const router = useRouter(); useEffect(() => { setWriteList(sidebarData?.sidebarDtos); setReadMe(readMeData?.body?.content); - setBlogId(blogIdData); - }, [sidebarData, readMeData, blogIdData]); + }, [sidebarData, readMeData]); return ( - + - { - setContent(e.target.value); - }} - /> - - + + + } /> diff --git a/client/src/app/globals.css b/client/src/app/globals.css index 089f6334..5db43b28 100644 --- a/client/src/app/globals.css +++ b/client/src/app/globals.css @@ -14,6 +14,7 @@ html { } .w-md-editor { + color: #000; background-color: transparent !important; --md-editor-box-shadow-color: #d0d7de !important; } diff --git a/client/src/app/mypage/page.tsx b/client/src/app/mypage/page.tsx index a6de42e3..3d36c858 100644 --- a/client/src/app/mypage/page.tsx +++ b/client/src/app/mypage/page.tsx @@ -19,6 +19,7 @@ import { postChangeUserInfoApi, useGetHistoryQuery, useGetMypageQuery, + useGetVisitQuery, } from '@/api/mypage-api'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import Image from 'next/image'; @@ -35,6 +36,7 @@ function page() { const fileInput = useRef(null); const [imageSrc, setImageSrc] = useState(null); const [image, setImage] = useState(''); + const { data } = useGetVisitQuery(); const handleAlignment = (_: React.MouseEvent, newYearWeekToggle: string | null) => { if (newYearWeekToggle !== null) { @@ -345,6 +347,7 @@ function page() { )} + 방문자 수 : {data} ); diff --git a/client/src/app/write/readme/[blogName]/page.tsx b/client/src/app/write/readme/[blogName]/page.tsx new file mode 100644 index 00000000..8af22c90 --- /dev/null +++ b/client/src/app/write/readme/[blogName]/page.tsx @@ -0,0 +1,50 @@ +'use client'; + +import { Stack } from '@mui/material'; +import { useState } from 'react'; +import MDEditor from '@uiw/react-md-editor'; +import '@uiw/react-md-editor/markdown-editor.css'; +import '@uiw/react-markdown-preview/markdown.css'; +import { useUserThemeSSR } from '../../../../../hooks/useRecoilSSR'; +import Button from '@/components/Button/Button'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { PutReadMeApi } from '@/api/readme-api'; +import { useRouter } from 'next/navigation'; + +const ReadMe = ({ params }: { params: { blogName: string } }) => { + const [userTheme] = useUserThemeSSR(); + const [content, setContent] = useState(''); + const queryClient = useQueryClient(); + const router = useRouter(); + + const putReadmeQuery = useMutation(PutReadMeApi, { + onSuccess: () => { + queryClient.invalidateQueries(['readMe']); + router.push(`/${params.blogName}`); + }, + }); + + const readmeSaveOnClick = () => { + const newReadMeBody = { + content: content, + }; + + putReadmeQuery.mutate(newReadMeBody); + }; + + return ( + + + + README + + + + + + ); +}; + +export default ReadMe; diff --git a/client/src/app/write/readme/page.tsx b/client/src/app/write/readme/page.tsx deleted file mode 100644 index ff2a0e0a..00000000 --- a/client/src/app/write/readme/page.tsx +++ /dev/null @@ -1,81 +0,0 @@ -'use client'; - -import { Stack, TextField } from '@mui/material'; -import { useEffect, useState } from 'react'; -import MDEditor from '@uiw/react-md-editor'; -import { ToolBar } from '@/app/write/Write.style'; -import TagList from '@/app/write/TagList'; -import TopButton from '@/app/write/Top/TopButton'; -import BottomButton from '@/app/write/Bottom/BottomButton'; -import { - useTemplateIdSSR, - useTemporaryIdSSR, - useUserThemeSSR, -} from '../../../../hooks/useRecoilSSR'; -import '@uiw/react-md-editor/markdown-editor.css'; -import '@uiw/react-markdown-preview/markdown.css'; -import { WriteProps } from '@/util/useWriteProps'; -import { useGetTemplateDetailQuery, useGetTemporaryDetailQuery } from '@/api/write-api'; - -const Readme = () => { - const [userTheme] = useUserThemeSSR(); - const [title, setTitle] = useState(''); - const [content, setContent] = useState(''); - const [tags, setTags] = useState([]); - const [templateId] = useTemplateIdSSR(); - const [temporaryId] = useTemporaryIdSSR(); - // const [temporaryId, setTemporary] = useTemporaryIdSSR(); - - const { data: templateData, refetch: templateRefetch } = useGetTemplateDetailQuery({ - templateId, - }); - const { data: temporaryData, refetch: temporaryRefetch } = useGetTemporaryDetailQuery({ - temporaryId, - }); - - useEffect(() => { - templateRefetch(); - }, [templateId]); - - useEffect(() => { - temporaryRefetch(); - }, [temporaryId]); - - useEffect(() => { - setTitle(templateData?.title); - setContent(templateData?.content); - setTags(templateData?.hashtags); - }, [templateData]); - - useEffect(() => { - setTitle(temporaryData?.title); - setContent(temporaryData?.content); - setTags(temporaryData?.hashtags); - }, [temporaryData]); - - const writeProps: WriteProps = { - title, - content, - tags, - }; - - return ( - - setTitle(e.target.value)} - variant="standard" - placeholder="제목을 입력해주세요." - /> - - setTags(newValue)} tagArray={tags} /> - - - - - - ); -}; - -export default Readme; diff --git a/client/src/components/Layout/HeaderFriendModal/FriendModal.style.tsx b/client/src/components/Layout/HeaderFriendModal/FriendModal.style.tsx index 00c32838..bc915142 100644 --- a/client/src/components/Layout/HeaderFriendModal/FriendModal.style.tsx +++ b/client/src/components/Layout/HeaderFriendModal/FriendModal.style.tsx @@ -84,10 +84,10 @@ function FriendListComponent({ const [deleteConfirmOpen, setDeleteConFirmOpen] = useState(false); const [isAccept, setIsAccept] = useState(Number); const [acceptConfirmOpen, setAcceptConfirmOpen] = useState(false); - const [refuseConfirmOpen, setRefuseConfirmOpen] = useState(false); + const [refuseConfirmOpen] = useState(false); const putAllowFriendIdCreateQuery = useMutation(PutFriendAllowApi, { onSuccess: () => { - queryClient.invalidateQueries(['friend']) + queryClient.invalidateQueries(['friend']); }, }); const AllowFriendOnClick = () => { @@ -105,10 +105,10 @@ function FriendListComponent({ }, }); - const {data: friendReadData} = useGetFriendReadQuery({ - userId: userId - }) - const [, setReadData] = useState() + const { data: friendReadData } = useGetFriendReadQuery({ + userId: userId, + }); + const [, setReadData] = useState(); const deleteClick = () => { deleteFriendQuery.mutate({ userId: userId }); @@ -123,7 +123,7 @@ function FriendListComponent({ setAnchorEl(null); }; - const {data: introduceData} = useGetIntroduceQuery({ + const { data: introduceData } = useGetIntroduceQuery({ userId: userId, }); const [introduce, setIntroduce] = useState(); @@ -136,14 +136,17 @@ function FriendListComponent({ return ( - - - {nickname} - + + {nickname} + + {relationship === 'friend' ? ( haveNewPost ? ( @@ -169,8 +177,11 @@ function FriendListComponent({ @@ -182,7 +193,9 @@ function FriendListComponent({ - @@ -237,18 +250,21 @@ function FriendListComponent({ alt="profileImage" /> - {introduce?.nickname} + + {introduce?.nickname} + - 친구 {introduce?.friendCount} 명 - 팔로잉 + + 친구 {introduce?.friendCount} 명 + + 팔로잉