diff --git a/src/components/ProjectTab/ProjectTab.tsx b/src/components/ProjectTab/ProjectTab.tsx index e51a1f3e..db17967e 100644 --- a/src/components/ProjectTab/ProjectTab.tsx +++ b/src/components/ProjectTab/ProjectTab.tsx @@ -30,6 +30,15 @@ export function ProjectTab({ currentTab, setCurrentTab }: ProjectTabProps) { const tabWrapperCss = css` display: flex; + + ${mediaQuery('mobile')} { + width: 100%; + overflow-x: scroll; + + &::-webkit-scrollbar { + display: none; + } + } `; const tabContainerCss = css` @@ -44,11 +53,6 @@ const tabCss = css` ${theme.typosV2.pretendard.semibold16}; padding: 16px 20px; color: ${theme.colors.grey[300]}; - - ${mediaQuery('mobile')} { - ${theme.typosV2.pretendard.regular14}; - padding: 16px 8px; - } `; const activeTabCss = css` diff --git a/src/components/Thumbnail/Thumbnail.tsx b/src/components/Thumbnail/Thumbnail.tsx index f0495fbd..a544fa51 100644 --- a/src/components/Thumbnail/Thumbnail.tsx +++ b/src/components/Thumbnail/Thumbnail.tsx @@ -65,7 +65,7 @@ export function Thumbnail({ title, subTitle, img, description, links }: Thumbnai const articleCss = css` position: relative; - height: 208px; + height: 220px; max-width: 312px; overflow: hidden; border-radius: 12px; @@ -80,7 +80,7 @@ const articleCss = css` cursor: pointer; } &:hover img { - filter: blur(5px) brightness(0.4); + filter: brightness(0.3); } `; diff --git a/src/features/Main/sections/MainProjectSection.tsx b/src/features/Main/sections/MainProjectSection.tsx index 60215c7c..39a2f0f1 100644 --- a/src/features/Main/sections/MainProjectSection.tsx +++ b/src/features/Main/sections/MainProjectSection.tsx @@ -1,6 +1,203 @@ -/** - * * Main 페이지 프로젝트 section - */ +import { useState } from 'react'; +import { useRouter } from 'next/router'; +import { css } from '@emotion/react'; +import { AnimatePresence, m } from 'framer-motion'; + +import { Icon } from '~/components/Icon/Icon'; +import { Thumbnail } from '~/components/Thumbnail'; +import { Link } from '~/components/Thumbnail/Thumbnail'; +import { staggerHalf } from '~/constant/motion'; +import { PROJECT_LIST } from '~/constant/project'; +import { useCheckWindowSize } from '~/hooks/useCheckWindowSize'; +import { mediaQuery } from '~/styles/media'; +import { theme } from '~/styles/theme'; +import { sliceByPage } from '~/utils/pagination'; + +const FIRST_PAGE = 1; + export const MainProjectSection = () => { - return
Project
; + const router = useRouter(); + const [currentPage, setCurrentPage] = useState(FIRST_PAGE); + const { isTargetSize: isTabletSize } = useCheckWindowSize('tablet'); + const { isTargetSize: isMobileSize } = useCheckWindowSize('mobile'); + + const isMaxCurrentPage = currentPage >= 3; + + const onClickMore = () => { + if (isMaxCurrentPage) { + router.push('/project'); + return; + } + + setCurrentPage(prev => prev + 1); + }; + + return ( +
+
+

프로젝트

+

+ 디프만 멤버 '디퍼(DEEPER)' 들의 + {isMobileSize &&
} + 다양한 프로젝트를 확인해보세요 +

+
+ + + + {sliceByPage(PROJECT_LIST, currentPage, isTabletSize, isMobileSize, 0).map(project => ( + + ))} + + + + +
+ ); +}; + +const sectionCss = (isMaxCurrentPage?: boolean) => css` + position: relative; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + background-color: black; + padding: 140px 0; + gap: 68px; + + ${mediaQuery('tablet')} { + padding: 140px 64px; + } + + ${mediaQuery('mobile')} { + padding: 80px 24px 100px; + } + + ${!isMaxCurrentPage && + css` + &::after { + content: ''; + position: absolute; + + bottom: 140px; + height: 220px; + width: 100%; + background: linear-gradient( + 180deg, + rgba(0, 0, 0, 0) 0%, + rgba(0, 0, 0, 0.4) 14%, + rgba(0, 0, 0, 0.71) 30.75%, + rgba(0, 0, 0, 0.88) 41%, + #000 50%, + #000 100% + ); + + ${mediaQuery('mobile')} { + bottom: 100px; + } + } + `} +`; + +const text = { + wrapperCss: css` + display: flex; + flex-direction: column; + gap: 24px; + color: white; + text-align: center; + `, + + headlineCss: css` + ${theme.typosV2.pretendard.bold44}; + line-height: 150%; + + ${mediaQuery('mobile')} { + ${theme.typosV2.pretendard.bold28}; + line-height: 150%; + } + `, + + descriptionCss: css` + ${theme.typosV2.pretendard.semibold20}; + line-height: 150%; + + ${mediaQuery('mobile')} { + ${theme.typosV2.pretendard.semibold18}; + line-height: 150%; + } + `, +}; + +const projectContainerCss = css` + width: 100%; + max-width: 960px; + margin-top: 36px; + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: repeat(3, 1fr); + gap: 12px; + ${mediaQuery('tablet')} { + grid-template-columns: repeat(2, 1fr); + } + ${mediaQuery('mobile')} { + grid-template-columns: repeat(1, 1fr); + } +`; + +const button = { + containerCss: (isMaxCurrentPage?: boolean) => css` + ${!isMaxCurrentPage && + css` + position: absolute; + bottom: 156px; + `} + + padding: 12px 36px; + border-radius: 100px; + background-color: white; + z-index: 10; + `, + + wrapperCss: css` + display: flex; + gap: 8px; + align-items: center; + color: black; + ${theme.typosV2.pretendard.semibold20}; + line-height: 150%; + + ${mediaQuery('mobile')} { + ${theme.typosV2.pretendard.semibold16}; + line-height: 150%; + } + `, + + iconCss: css` + width: 24px; + height: 24px; + background-color: white; + border-radius: 400px; + `, }; diff --git a/src/features/Main/sections/index.ts b/src/features/Main/sections/index.ts index 4ce64617..2c333f3a 100644 --- a/src/features/Main/sections/index.ts +++ b/src/features/Main/sections/index.ts @@ -5,4 +5,5 @@ export * from './MainReasonSection'; export * from './MainRecruitSection'; export * from './MainResultSection'; export * from './MainScheduleSection'; +export * from './MainSubscribeSection'; export * from './MainSupportSection'; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 495b8195..64a22d3b 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,15 +1,23 @@ +import dynamic from 'next/dynamic'; + import { SEO } from '~/components/SEO'; import { MainBlogSection, MainIntroSection, - MainProjectSection, MainReasonSection, MainRecruitSection, MainResultSection, MainScheduleSection, + MainSubscribeSection, MainSupportSection, } from '~/features/Main/sections'; -import { MainSubscribeSection } from '~/features/Main/sections/MainSubscribeSection'; + +const DynamicMainProjectSection = dynamic( + () => import('~/features/Main/sections').then(({ MainProjectSection }) => MainProjectSection), + { + ssr: false, + } +); export default function Root() { return ( @@ -20,7 +28,7 @@ export default function Root() { - + diff --git a/src/utils/pagination.ts b/src/utils/pagination.ts index fd74346f..4bfc3565 100644 --- a/src/utils/pagination.ts +++ b/src/utils/pagination.ts @@ -8,16 +8,19 @@ export const sliceByPage = ( projects: Project[], page: number, isTabletSize: boolean, - isMobileSize: boolean + isMobileSize: boolean, + startPage?: number ) => { + const initialPage = startPage !== undefined ? startPage : page - 1; + if (isMobileSize) { return projects.slice(0, MOBILE_PAGE_SIZE * page); } if (isTabletSize) { - return projects.slice(TABLET_PAGE_SIZE * (page - 1), TABLET_PAGE_SIZE * page); + return projects.slice(TABLET_PAGE_SIZE * initialPage, TABLET_PAGE_SIZE * page); } - return projects.slice(PC_PAGE_SIZE * (page - 1), PC_PAGE_SIZE * page); + return projects.slice(PC_PAGE_SIZE * initialPage, PC_PAGE_SIZE * page); }; export const getTenUnderProjects = (projects: Project[]) =>