Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into feature/#47/projectForm
  • Loading branch information
이종혁 committed Feb 29, 2024
2 parents 6a51b44 + b9ac03d commit 1bfa230
Show file tree
Hide file tree
Showing 9 changed files with 424 additions and 7 deletions.
7 changes: 2 additions & 5 deletions package-lock.json

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

2 changes: 2 additions & 0 deletions src/mocks/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { rest } from "msw"

import { searchHandlers } from "@components/Search/mocks"

import allProjectHandlers from "@pages/HomePage/mocks"
import { projectDetailHandlers } from "@pages/ProjectDetailPage/mocks"

import { postEmailLogin } from "./auth/postEmailLogin.mock"
Expand Down Expand Up @@ -29,6 +30,7 @@ export const handlers = [
}),
...projectDetailHandlers,
...searchHandlers,
...allProjectHandlers,
postEmailRefresh,
postEmailLogin,
]
122 changes: 121 additions & 1 deletion src/pages/HomePage/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,125 @@
import { ChangeEvent, useState } from "react"
import { Link } from "react-router-dom"

import {
Box,
Button,
Center,
Checkbox,
Container,
Grid,
GridItem,
HStack,
Select,
Skeleton,
Spacer,
Stack,
} from "@chakra-ui/react"

import ProjectCard from "@components/ProjectCard/ProjectCard"

import Banner from "./components/Banner/Banner"
import useAllProjectQuery from "./hooks/queries/useAllProjectQuery"

type SelectType = "default" | "likeCount" | "viewCount"

const HomePage = () => {
return <div>HomePage</div>
const [isDeploy, setIsDeploy] = useState(false)
const [selectedOption, setSelectedOption] = useState<SelectType>("default")

// 프로젝트 전체 목록 조회
const { allProjectList, isAllProjectLoading } = useAllProjectQuery()

const projectList = allProjectList?.projects.filter((project) =>
isDeploy ? project.isDeploy : project,
)

const handleSelect = (e: ChangeEvent<HTMLSelectElement>) => {
const value = e.target.value as SelectType
setSelectedOption(value)
}
return (
<>
{/* 임시로 다섯개 잘라서 넣었습니다*/}
{isAllProjectLoading ? (
<Skeleton height="52rem" />
) : (
<Banner bannerList={allProjectList?.projects.slice(0, 5)} />
)}
<Container maxW="80%">
<Stack marginTop="15rem">
<HStack spacing={5}>
<Spacer />
<Checkbox
paddingRight="0.3rem"
onChange={() => setIsDeploy(!isDeploy)}>
출시 서비스만 보기
</Checkbox>
<Select
width="10rem"
variant="outline"
marginRight="1rem"
onChange={handleSelect}
value={selectedOption}>
<option value="default">최신순</option>
<option value="likeCount">인기순</option>
<option value="viewCount">조회순</option>
</Select>
</HStack>
<Grid
templateColumns="repeat(4, 1fr)"
gap={4}>
{isAllProjectLoading ? (
<>
<Skeleton
height="20rem"
borderRadius="1rem"
/>
<Skeleton
height="20rem"
borderRadius="1rem"
/>
<Skeleton
height="20rem"
borderRadius="1rem"
/>
<Skeleton
height="20rem"
borderRadius="1rem"
/>
</>
) : (
projectList?.map((project) => (
<GridItem key={project.id}>
<Link to={`/project/${project.id}`}>
<ProjectCard
imgUrl={project.thumbnailUrl}
viewCount={project.viewCount}
heartCount={project.likeCount}
isFullHeart={project.isLiked}
title={project.name}
content={project.subName}
/>
</Link>
</GridItem>
))
)}
</Grid>
<Center marginTop="2rem">
<Button
width="8rem"
height="3rem"
backgroundColor="blue.100"
color="white">
더보기
</Button>
</Center>
</Stack>
<Box height="20rem" />
</Container>
{/* 푸터 들어갈 자리 */}
</>
)
}

export default HomePage
26 changes: 26 additions & 0 deletions src/pages/HomePage/components/Banner/Banner.style.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Swiper } from "swiper/react"

import styled from "styled-components"

export const CustomSwiper = styled(Swiper)`
.swiper-button-prev,
.swiper-button-next {
opacity: 0;
border-radius: 10rem;
color: white;
&:hover {
opacity: 0.8;
transition: 0.2s ease-out;
}
&:after {
font-size: 2.2rem !important;
font-weight: 600 !important;
}
}
.swiper-pagination-bullet {
background: ${({ theme }) => theme.yellow[100]} !important;
}
`
75 changes: 75 additions & 0 deletions src/pages/HomePage/components/Banner/Banner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Link, useNavigate } from "react-router-dom"

import {
HStack,
Heading,
Image,
Spacer,
Stack,
Text,
useTheme,
} from "@chakra-ui/react"
import { AllProject } from "api-models"
import "swiper/css"
import "swiper/css"
import "swiper/css/navigation"
import "swiper/css/pagination"
import { Autoplay, Navigation, Pagination } from "swiper/modules"
import { SwiperSlide } from "swiper/react"

import { CustomSwiper } from "./Banner.style"

interface bannerListProps {
bannerList: AllProject[] | undefined
}

const Banner = ({ bannerList }: bannerListProps) => {
const navigate = useNavigate()
const theme = useTheme()

return (
<CustomSwiper
theme={theme.colors}
modules={[Navigation, Pagination, Autoplay]}
navigation
pagination={{ clickable: true }}
style={{ height: "52rem" }}
autoplay={{ delay: 5000, disableOnInteraction: false }}>
{bannerList?.map((project) => (
<SwiperSlide
style={{
backgroundColor: `${theme.colors.blue[100]}`,
color: "white",
}}
key={project.id}>
<HStack height="90%">
<Image
src={project.thumbnailUrl}
alt="projectImg"
height="90%"
marginTop="4rem"
borderRadius="5rem"
marginLeft="13rem"
cursor="pointer"
onClick={() => navigate(`/project/${project.id}`)}
/>
<Spacer />
<Stack
marginRight="13rem"
textAlign="right">
<Link to={`/project/${project.id}`}>
<Text
fontSize="xl"
padding="1rem">
{project.subName}
</Text>
<Heading>{project.name}</Heading>
</Link>
</Stack>
</HStack>
</SwiperSlide>
))}
</CustomSwiper>
)
}
export default Banner
18 changes: 18 additions & 0 deletions src/pages/HomePage/hooks/queries/useAllProjectQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useQuery } from "@tanstack/react-query"

import { getAllProjects } from "@/api/project/getAllProjects"

const useAllProjectQuery = () => {
const { data, isLoading, refetch } = useQuery({
queryKey: ["projects"],
queryFn: () => getAllProjects(),
})

return {
allProjectList: data,
isAllProjectLoading: isLoading,
refetchAllProject: refetch,
}
}

export default useAllProjectQuery
13 changes: 13 additions & 0 deletions src/pages/HomePage/mocks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { rest } from "msw"

import { ENDPOINTS } from "@constants/endPoints"

import { mockData } from "./mockData"

const allProjectHandlers = [
rest.get(ENDPOINTS.GET_ALL_PROJECTS, (_, res, ctx) => {
return res(ctx.status(200), ctx.json(mockData))
}),
]

export default allProjectHandlers
Loading

0 comments on commit 1bfa230

Please sign in to comment.