Skip to content

Commit

Permalink
댓글-입력중-Navbar를-숨기는로직-변경 (#73)
Browse files Browse the repository at this point in the history
* Minor : Adornment 컴포넌트 커서 포인터로 변경

* Refactor : 전역 컨텍스트 삭제, Event capture 로 대체

* FIX : 브라우저 기본동작 제거

* Refactor : 반복되는 Interface 분리

* Refactor : 반복되는 Interface 분리

* Minor : Hashtag Key 변경

* New : PostList-Api-V2적용
  • Loading branch information
jobkaeHenry authored Dec 5, 2023
1 parent a51d9cd commit 5f69086
Show file tree
Hide file tree
Showing 14 changed files with 120 additions and 84 deletions.
2 changes: 1 addition & 1 deletion client/src/app/(logoutOnly)/auth/signup/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const layout = ({ children }: layoutProps) => {
return (
<SignupPageContext.Provider value={{ formData, setFormData, disableBtn, setDisableBtn }}>
<Container sx={{ px: { xs: 0, sm: 4 } }} maxWidth={"lg"}>
<Paper component={'form'}
<Paper
sx={{
display: "flex",
flexDirection: "column",
Expand Down
26 changes: 15 additions & 11 deletions client/src/app/(logoutOnly)/auth/signup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default function SignUpPage() {
const [doubleCheckPassword, setDoubleCheckPassword] = useState<string>("");

const { mutateAsync: signupHandler } = useSignupMutation();

const submitHandler = useCallback(async (data: SignupRequirement) => {
try {
await signupHandler(data);
Expand Down Expand Up @@ -99,7 +100,7 @@ export default function SignUpPage() {
>
<TextField
name="passwordcheck"
autoComplete="new-password"
autoComplete="off"
label="비밀번호"
type="password"
value={doubleCheckPassword}
Expand Down Expand Up @@ -161,16 +162,19 @@ export default function SignUpPage() {
variant="determinate"
value={(currentIndex / (totalPageNum - 1)) * 100}
/>
{MultistepForm}
<FixedBottomCTA
onClick={() => {
!isLastStep ? next() : submitHandler(formData);
}}
size="large"
disabled={disableBtn}
>
{!isLastStep ? "다음" : "투파이아 시작하기"}
</FixedBottomCTA>
<form onSubmit={(e)=>{
e.preventDefault()
!isLastStep ? next() : submitHandler(formData);
}}>
{MultistepForm}
<FixedBottomCTA
type='submit'
size="large"
disabled={disableBtn}
>
{!isLastStep ? "다음" : "투파이아 시작하기"}
</FixedBottomCTA>
</form>
</>
);
}
9 changes: 2 additions & 7 deletions client/src/components/Navigation/NavigationBar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
"use client";
import { BottomNavigation, BottomNavigationAction, Paper } from "@mui/material";
import { BottomNavigation, BottomNavigationAction } from "@mui/material";

import HomeIcon from "~/assets/icons/HomeIcon.svg";
import SearchIcon from "~/assets/icons/SearchIcon.svg";
import PostIcon from "~/assets/icons/PostIcon.svg";
import BeverageIcon from "~/assets/icons/BeverageIcon.svg";
import { useGlobalNavbarVisibility } from "@/store/useGlobalNavbarVisibility";

import HOME, {
MY_PROFILE,
Expand All @@ -24,8 +23,6 @@ const NavigationBar = () => {
const path = usePathname();
const { data: userInfo } = useMyInfoQuery();

const isVisible = useGlobalNavbarVisibility(({ isVisible }) => isVisible);

const NavbarData = useMemo(
() => [
{
Expand Down Expand Up @@ -55,7 +52,7 @@ const NavigationBar = () => {
],
[userInfo]
);
return isVisible ? (
return (
<BottomNavigation value={path} showLabels sx={BtnStyle}>
{NavbarData.map(({ label, href, iconComponent, ...others }) => {
return (
Expand All @@ -71,8 +68,6 @@ const NavigationBar = () => {
);
})}
</BottomNavigation>
) : (
<></>
);
};

Expand Down
2 changes: 1 addition & 1 deletion client/src/components/post/PostCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const PostCard = ({
<Card sx={{ display: "flex", gap: 2, p: 2 }}>
<Link href={USER_PAGE(createdBy)}>
<UserAvatar
src={profileImgUrls[0]}
src={profileImgUrls[0]?.attachUrl}
fallback={String(id)[0].toUpperCase()}
/>
</Link>
Expand Down
10 changes: 5 additions & 5 deletions client/src/components/post/PostCardList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,26 @@ function PostCardList(props: UseGetPostListQueryInterface) {
headers: { Authorization: getTokenFromLocalStorage() },
});

const { searchKeyword, searchUserNos } = props;
const { searchKeyword, searchUserNos, sort } = props;

const { ref, inView } = useInView();
useEffect(() => {
if (hasNextPage && inView) fetchNextPage();
}, [inView, hasNextPage]);

const hasResult = useMemo(
() => data && data.pages[0].list.length > 0,
() => data && data.pages[0].content.length > 0,
[data]
);

return (
<postcardContext.Provider value={{ searchKeyword, searchUserNos }}>
<postcardContext.Provider value={{ searchKeyword, searchUserNos, sort }}>
<div>
{hasResult &&
isSuccess &&
// 검색결과가 있을시
data?.pages.map((page) =>
page.list.map((post) => <PostCard {...post} key={post.postNo} />)
page.content.map((post) => <PostCard {...post} key={post.postNo} />)
)}
{isSuccess && !hasResult && (
// 검색결과 없을 시
Expand All @@ -56,7 +56,7 @@ function PostCardList(props: UseGetPostListQueryInterface) {
)}
{/* 로딩창 */}
{isFetchingNextPage || isLoading ? (
<PostCardSkeleton />
<PostCardSkeleton />
) : (
// 인터섹션옵저버
<div style={{ height: 60 }} ref={ref}></div>
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/post/PostHashtagList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ const PostHashTagList = ({ tags, ...others }: TagListInterface) => {
}}
{...others}
>
{tags.map((tag) => (
<Link href={SEARCH_BY_KEYWORD(tag)} key={tag}>
{tags.map((tag,i) => (
<Link href={SEARCH_BY_KEYWORD(tag)} key={i}>
<Typography
component={"span"}
variant={"label"}
Expand Down
13 changes: 4 additions & 9 deletions client/src/components/post/detail/PostCommentInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@
import { InputAdornment, Paper, TextField } from "@mui/material";
import { useCallback, useContext, useState } from "react";
import SubmitCommentIcon from "@/assets/icons/comment/SubmitCommentIcon.svg";
import { useGlobalNavbarVisibility } from "@/store/useGlobalNavbarVisibility";
import PostDetailPageContext from "@/store/post/PostDetailPageContext";
import useNewPostCommentMutation from "@/queries/post/comment/useNewPostCommentMutation";

const PostCommentInput = () => {
const setIsShowingNavbar = useGlobalNavbarVisibility(
({ setIsVisible }) => setIsVisible
);
const { data: currentData } = useContext(PostDetailPageContext);
const [isEditing, setIsEditing] = useState(false);
const [inputValue, setInputValue] = useState("");
Expand All @@ -33,22 +29,21 @@ const PostCommentInput = () => {
border: "1px solid",
borderColor: "gray.secondary",
position: "fixed",
bottom: isEditing ? 0 : "44px",
bottom: isEditing ? 0 : 56,
borderRadius: 1.5,
left: 0,
right: 0,
p: 2,
pb: isEditing ? 2 : 3.5,
zIndex: 2,
}}
elevation={0}
>
<TextField
fullWidth
onFocus={() => {
setIsShowingNavbar(false);
setIsEditing(true);
}}
onBlur={() => {
setIsShowingNavbar(true);
setIsEditing(false);
}}
size="small"
Expand All @@ -64,7 +59,7 @@ const PostCommentInput = () => {
position="end"
onClick={(e) => {
e.stopPropagation();
submitHandler(inputValue)
submitHandler(inputValue);
}}
sx={{
color: inputValue.length > 0 ? "primary.main" : "text.disabled",
Expand Down
7 changes: 7 additions & 0 deletions client/src/const/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ const theme = createTheme({
elevation: 0,
},
},
MuiInputAdornment:{
styleOverrides:{
root:{
cursor:'pointer'
}
}
}
},
});

Expand Down
60 changes: 36 additions & 24 deletions client/src/queries/post/useGetPostListInfiniteQuery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query";
import { PostInterface } from "@/types/post/PostInterface";
import { AxiosRequestConfig } from "axios";
import getTokenFromLocalStorage from "@/utils/getTokenFromLocalStorage";
import { POST_LIST } from "@/const/serverPath";
import { POST_LIST_V2 } from "@/const/serverPath";
import useAxiosPrivate from "@/hooks/useAxiosPrivate";
import Pagenated from "@/types/Pagenated";

export interface UseGetPostListQueryInterface extends GetPostListOptions {
initialData?: AugmentedGetPostListResponse;
Expand All @@ -15,12 +16,14 @@ export const useGetPostListInfiniteQuery = ({
size,
searchKeyword,
searchUserNos,
sort,
headers,
}: UseGetPostListQueryInterface) => {
return useInfiniteQuery({
queryKey: getPostListInfiniteQueryKey.byKeyword({
keyword: searchKeyword,
userNo: searchUserNos,
searchKeyword,
searchUserNos,
sort
}),

queryFn: async ({ pageParam = 0 }) =>
Expand All @@ -29,6 +32,7 @@ export const useGetPostListInfiniteQuery = ({
size,
searchKeyword,
searchUserNos,
sort,
headers: headers?.Authorization
? headers
: { Authorization: getTokenFromLocalStorage() },
Expand All @@ -54,20 +58,14 @@ export const useGetPostListInfiniteQuery = ({
export interface GetPostListOptions {
page?: number;
size?: number;
sort?: string;
searchKeyword?: string;
searchUserNos?: string;
}
/**
* 실제 서버에서 응답해주는 값
*/
export interface GetPostListResponse {
list: PostInterface[];
totalCount: number;
}
/**
* 서버응답값 + 무한스크롤을 위해 증강된 값
*/
export interface AugmentedGetPostListResponse extends GetPostListResponse {
export interface AugmentedGetPostListResponse extends Pagenated<PostInterface> {
currentPage: number;
hasNextPage: boolean;
}
Expand All @@ -77,32 +75,46 @@ export const getPostListQueryFn = async ({
size = 10,
searchKeyword,
searchUserNos,
sort,
headers,
}: GetPostListOptions & {
headers?: AxiosRequestConfig<any>["headers"];
}): Promise<AugmentedGetPostListResponse> => {
const axiosPrivate = useAxiosPrivate()
const { data } = await axiosPrivate.get<GetPostListResponse>(POST_LIST, {
baseURL: process.env.NEXT_PUBLIC_BASE_URL,
params: { page, size, searchKeyword, searchUserNos },
headers,
});
const axiosPrivate = useAxiosPrivate();
const { data } = await axiosPrivate.get<Pagenated<PostInterface>>(
POST_LIST_V2,
{
baseURL: process.env.NEXT_PUBLIC_BASE_URL,
params: {
page,
size,
searchKeyword,
searchUserNos,
sort: sort ?? "lastModifiedDate,desc",
},
headers,
}
);
return {
...data,
currentPage: page,
hasNextPage: data.totalCount / ((page + 1) * size) > 1,
hasNextPage: data.totalElements / ((page + 1) * size) > 1,
};
};

export interface PostListInfiniteQueryKey {
keyword?: string;
userNo?: string;
}
// export interface PostListInfiniteQueryKey {
// keyword?: string;
// userNo?: string;
// }

export const getPostListInfiniteQueryKey = {
all: ["posts"] as const,
byKeyword: ({ keyword, userNo }: PostListInfiniteQueryKey) =>
["posts", { keyword, userNo }] as const,
byKeyword: ({
searchKeyword,
searchUserNos,
sort,
}: Omit<GetPostListOptions, "page" | "size">) =>
["posts", { searchKeyword, searchUserNos, sort }] as const,
};

/**
Expand Down
4 changes: 3 additions & 1 deletion client/src/store/post/PostCardContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { createContext } from "react";
export interface PostcardContextInterface {
searchKeyword?: string;
searchUserNos?: string;
sort?: string;
}
/**
* 현재 보고있는 페이지의 컨텍스트
* 현재 보고있는 페이지의 컨텍스트
* (검색,유저페이지,메인페이지의 글 리스트가 같은 쿼리를 바라보고있으므로,
* 적절한 Invalidation을 위한 쿼리키를 추출하기 위해 사용됨)
*/
export const postcardContext = createContext<PostcardContextInterface>({
searchKeyword: undefined,
searchUserNos: undefined,
sort: undefined,
});
15 changes: 0 additions & 15 deletions client/src/store/useGlobalNavbarVisibility.ts

This file was deleted.

Loading

0 comments on commit 5f69086

Please sign in to comment.