Skip to content

Commit

Permalink
Merge pull request #29 from LikeLion-KNU/feature/#28
Browse files Browse the repository at this point in the history
Feature/#28
  • Loading branch information
Hyoeunkh authored May 19, 2024
2 parents 2fafd1f + 431f057 commit e8288c0
Show file tree
Hide file tree
Showing 20 changed files with 261 additions and 106 deletions.
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@fingerprintjs/fingerprintjs": "^4.3.0",
"@reduxjs/toolkit": "^2.2.4",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@woowa-babble/random-nickname": "^1.0.2",
"axios": "^1.6.8",
"babel-plugin-styled-components": "^2.1.4",
"eslint-config-prettier": "^9.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const App: React.FC = () => {
<Route index path="/" element={<HomePage />} />
<Route path="/timetable" element={<TimeTablePage />}></Route>
<Route path="/booth" element={<BoothListPage />}></Route>
<Route path="/booth/:id" element={<BoothDetailPage />}></Route>
<Route path="/booth/:category/:boothId" element={<BoothDetailPage />} />
<Route path="/guests" element={<SpecialGuestPage />}></Route>
<Route path="/contributors" element={<ContributorPage />}></Route>
</Route>
Expand Down
Binary file modified src/assets/send.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion src/components/display/Booth.styled.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Link } from "react-router-dom";

import { motion } from "framer-motion";
import styled from "styled-components";

Expand All @@ -12,7 +14,7 @@ export const BoothListItem = styled(motion.li)`
background-color: #e9e9fb;
`;

export const BoothLink = styled.a`
export const BoothLink = styled(Link)`
width: 100%;
height: 100%;
Expand Down
6 changes: 3 additions & 3 deletions src/components/display/Booth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ export const Booth: React.FC<IBooth> = ({ index, name, num, likeable, category }

return (
<BoothListItem variants={itemVariants}>
<BoothLink href={`booth/${index + 1}`}>
<Index>{index + 1}</Index>
<BoothLink to={`/booth/${category}/${index}`}>
<Index>{index}</Index>
<Text size="m" weight="bold" variant="#5D5A88">
{name}
</Text>
</BoothLink>
<Heart num={likeAble ? num + 1 : num} likable={likeAble} onClick={handleLikeBtnClick} />
<Heart num={likeAble ? num : num} likable={likeAble} onClick={handleLikeBtnClick} />
</BoothListItem>
);
};
67 changes: 22 additions & 45 deletions src/components/display/BoothInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,17 @@
/* eslint-disable react-hooks/exhaustive-deps */
import React from "react";
import { useState, useRef, useCallback, useEffect } from "react";

import jannaviImage from "@/assets/jannavi.jpg";
import norazoImage from "@/assets/norazo.jpg";
import { IReadBoothByIdResponse } from "@/services/booth/booth.types";

import { Text } from "../typography/Text";
import {
BoothDetail,
BoothImg,
BoothName,
ImgWrapper,
ImgContainer,
InfoWrapper,
DotWrapper,
Dot,
} from "./BoothInfo.styled";
import { Heart } from "./Heart";
import { Booth } from "./Booth";
import { BoothImg, ImgWrapper, ImgContainer, InfoWrapper, DotWrapper, Dot } from "./BoothInfo.styled";

//zustand 로 refactor 필요
const BoothInfo: React.FC = () => {
const boothdetail =
"멋쟁이사자처럼 주점에서는 노래방 마이크로 김대건이 노래를 하고 춤도 추고 히어로 서사에 대해 설명할 것입니다.";
const boothName = "멋쟁이 사자처럼 주점";
const num = 365;
const boothImg = [jannaviImage, norazoImage, jannaviImage];
interface BoothInfoProps {
boothDetail: IReadBoothByIdResponse;
}

const BoothInfo: React.FC<BoothInfoProps> = ({ boothDetail }) => {
const [currentIndex, setCurrentIndex] = useState(0);
const slideRefs = useRef<(HTMLDivElement | null)[]>([]);

Expand All @@ -44,19 +31,13 @@ const BoothInfo: React.FC = () => {
root: null,
threshold: 0.5,
});

const currentSlideRefs = slideRefs.current;
currentSlideRefs.forEach((slide) => {
if (slide) {
observer.observe(slide);
}
slideRefs.current.forEach((slide) => {
slide && observer.observe(slide);
});

return () => {
currentSlideRefs.forEach((slide) => {
if (slide) {
observer.unobserve(slide);
}
slideRefs.current.forEach((slide) => {
slide && observer.unobserve(slide);
});
};
}, [updateCurrentIndex]);
Expand All @@ -65,29 +46,25 @@ const BoothInfo: React.FC = () => {
<>
<ImgContainer>
<ImgWrapper>
{boothImg.map((src, index) => {
{boothDetail.urls.map((src, index) => {
return <BoothImg key={index} src={src} ref={(el) => (slideRefs.current[index] = el)} />;
})}
</ImgWrapper>
<DotWrapper>
{boothImg.map((_, index) => (
{boothDetail.urls.map((_, index) => (
<Dot key={index} active={index === currentIndex} />
))}
</DotWrapper>
</ImgContainer>

<InfoWrapper>
<BoothName>
<Text size="20px" weight="bold" variant="#3F3A6C">
{boothName}
</Text>
<Heart num={num} likable={true} />
</BoothName>
<BoothDetail>
<Text size="s" weight="normal">
{boothdetail}
</Text>
<hr />
</BoothDetail>
<Booth
index={boothDetail.boothnum}
name={boothDetail.boothName}
num={boothDetail.likes}
likeable={!boothDetail.likable}
category={boothDetail.categori}
/>
</InfoWrapper>
</>
);
Expand Down
17 changes: 8 additions & 9 deletions src/components/display/Comment.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
import { FaRegTrashAlt } from "react-icons/fa";

import { useDeleteable } from "@/services/comment/comment.hooks";
import { IComment } from "@/services/comment/comment.types";

import { Paragraph } from "../typography/Paragraph";
import { Text } from "../typography/Text";
import { CommentContent, CommentInfoWrapper } from "./Comment.styled";
import { IComment } from "./CommentInfo";

//zustand로 refactor 필요

const Comment = ({ name, time, content, deletable }: IComment) => {
export const Comment: React.FC<IComment> = ({ id, name, created, comment, deleteable }) => {
const { handleDeleteBtnClick } = useDeleteable(id);
return (
<>
<CommentContent>
<Text size="m" weight="bold" variant="#3F3A6C">
<CommentInfoWrapper>
{name}
<Text size="xs" weight="normal" variant="#A3A3A3">
{time}
{created}
</Text>
</CommentInfoWrapper>
</Text>
{deletable ? <FaRegTrashAlt color="#3F3A6C" size={"24px"} /> : null}
{deleteable ? <FaRegTrashAlt color="#5d5a88" onClick={handleDeleteBtnClick} /> : null}
</CommentContent>
<Paragraph size="s" weight="normal">
{content}
{comment}
</Paragraph>
</>
);
};

export default Comment;
37 changes: 16 additions & 21 deletions src/components/display/CommentInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,20 @@ import React, { useState } from "react";

import { Pagination } from "@/components/navigation/Pagination";

import { IComment } from "@/services/comment/comment.types";

import { parseCreatedDate } from "@/utils/parseCreatedDate";

import { Text } from "../typography/Text";
import Comment from "./Comment";
import { Comment } from "./Comment";
import { CommentList, CommentWrapper, CommentContainer, Title } from "./CommentInfo.styled";

export interface IComment {
name: string;
time: string;
content: string;
deletable: boolean;
interface CommentInfoProps {
commentsDetail: IComment[];
}

const CommentInfo: React.FC = () => {
const [commentnum] = useState<number>(221);

const comments: IComment[] = [
{ name: "User1", time: "2024-05-13", content: "첫 번째 댓글입니다.", deletable: false },
{ name: "User2", time: "2024-05-14", content: "두 번째 댓글입니다.", deletable: true },
{ name: "User3", time: "2024-05-15", content: "세 번째 댓글입니다.", deletable: false },
];
const CommentInfo: React.FC<CommentInfoProps> = ({ commentsDetail }) => {
const [commentnum] = useState<number>(commentsDetail.length);

return (
<CommentWrapper>
Expand All @@ -33,18 +28,18 @@ const CommentInfo: React.FC = () => {
</Title>
</Text>
<CommentList>
{comments.map((comment, index) => (
<div>
{commentsDetail.map((comment, index) => (
<div key={index}>
<CommentContainer>
<Comment
key={index}
id={comment.id}
name={comment.name}
time={comment.time}
content={comment.content}
deletable={comment.deletable}
created={parseCreatedDate(comment.created)}
comment={comment.comment}
deleteable={comment.deleteable}
/>
</CommentContainer>
<hr />
<hr style={{ marginTop: "15px" }} />
</div>
))}
</CommentList>
Expand Down
3 changes: 3 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module "@woowa-babble/random-nickname" {
export function getRandomNickname(type: string): string;
}
7 changes: 5 additions & 2 deletions src/pages/BoothDetailPage.styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const ContentContainer = styled.form`
border-radius: 30px;
position: relative;
textarea {
input {
color: #5d5a88;
border: none;
padding: 0px 25px;
Expand Down Expand Up @@ -68,6 +68,9 @@ export const SubBtn = styled.button`
justify-content: center;
position: absolute;
right: 10px;
padding: 0;
`;

export const SendImg = styled.img``;
export const SendImg = styled.img`
width: 50%;
`;
29 changes: 25 additions & 4 deletions src/pages/BoothDetailPage.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,39 @@
import React from "react";

import BoothInfo from "@/components/display/BoothInfo";
import CommentInfo from "@/components/display/CommentInfo";
import { Loader } from "@/components/feedback/Loader";

import { DetailPageWrapper, SubBtn, ContentContainer, SendImg, BottomBox } from "@/pages/BoothDetailPage.styled";

import { useBoothDetail } from "@/services/booth/booth.hooks";
import { useComment } from "@/services/comment/comment.hooks";

import sendImg from "@/assets/send.png";

export default function BoothDetailPage() {
const { isPending, boothDetail } = useBoothDetail();
const { isPending: isCommentFetchPending, comments, commentInputRef, handleCommentSubmit } = useComment();

return (
<DetailPageWrapper>
<BoothInfo />
<CommentInfo />
{isPending ? <Loader /> : boothDetail && <BoothInfo boothDetail={boothDetail} />}
{isCommentFetchPending ? <Loader /> : comments && <CommentInfo commentsDetail={comments} />}

<BottomBox>
<ContentContainer>
<textarea placeholder="댓글을 입력해주세요." rows={1}></textarea>
<ContentContainer
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (!commentInputRef.current) return;
if (commentInputRef.current.value === "") return;

console.log(commentInputRef.current.value);
handleCommentSubmit(commentInputRef.current.value);
commentInputRef.current.value = "";
}}
>
<input ref={commentInputRef} placeholder="댓글을 입력해주세요." />
<SubBtn type="submit">
<SendImg src={sendImg} />
</SubBtn>
Expand Down
1 change: 0 additions & 1 deletion src/pages/BoothListPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const listVariants: Variants = {

const BoothListPage: React.FC = () => {
const { isPending, boothList } = useAllBooth();

return (
<>
<TransformWrapper initialScale={0.5} minScale={0.5}>
Expand Down
25 changes: 24 additions & 1 deletion src/services/booth/booth.hooks.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useCallback, useEffect, useState } from "react";
import { useParams } from "react-router-dom";

import { useVisitor } from "@/hooks/useVisitor";

import { boothService } from "./booth.service";
import { IBoothItem } from "./booth.types";
import { IBoothItem, IReadBoothByIdResponse } from "./booth.types";

export const useAllBooth = () => {
const [isPending, setIsPending] = useState<boolean>(false);
Expand Down Expand Up @@ -43,3 +44,25 @@ export const useLikes = (initLikeable: boolean, category: string, boothId: numbe

return { likeable, handleLikeBtnClick };
};

export const useBoothDetail = () => {
const { category, boothId } = useParams();
const { visitorId } = useVisitor();

const [isPending, setIsPending] = useState<boolean>(false);
const [boothDetail, setBoothDetail] = useState<IReadBoothByIdResponse | null>(null);

useEffect(() => {
setIsPending(true);
boothService
.readBoothById(category as string, parseInt(boothId as string), visitorId as string)
.then((data) => {
setBoothDetail(data);
})
.finally(() => {
setIsPending(false);
});
}, [category, boothId, visitorId]);

return { isPending, boothDetail };
};
Loading

0 comments on commit e8288c0

Please sign in to comment.