Skip to content

Commit

Permalink
Merge pull request #645 from sopt-makers/develop
Browse files Browse the repository at this point in the history
프로덕션 배포
  • Loading branch information
100Gyeon authored Dec 9, 2023
2 parents b7992c0 + 9ca9038 commit 3d98042
Show file tree
Hide file tree
Showing 44 changed files with 2,002 additions and 433 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@hookform/resolvers": "^2.9.10",
"@nanostores/react": "^0.7.1",
"@sentry/nextjs": "^7.51.0",
"@sopt-makers/colors": "^2.2.0",
"@sopt-makers/colors": "^3.0.0",
"@sopt-makers/playground-common": "^1.4.2",
"@stitches/react": "^1.2.8",
"@tanstack/react-query": "^4.10.3",
Expand Down
37 changes: 19 additions & 18 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import type { AppProps } from 'next/app';
import Script from 'next/script';
import { useRouter } from 'next/router';
import React, { useEffect } from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { styled, theme } from 'stitches.config';
import '../styles/globals.css';
import { crewToken, playgroundToken } from '@/stores/tokenStore';
import { fetchMyProfile } from '@api/user';
import Header from '@components/header/Header';
import { GTM_ID, pageview } from '@utils/gtm';
import { setAccessTokens } from '@components/util/auth';
import Loader from '@components/loader/Loader';
import ChannelService from '@utils/ChannelService';
import { fetchMyProfile } from '@api/user';
import { OverlayProvider } from '@hooks/useOverlay/OverlayProvider';
import SEO from '@components/seo/SEO';
import { crewToken, playgroundToken } from '@/stores/tokenStore';
import { setAccessTokens } from '@components/util/auth';
import { OverlayProvider } from '@hooks/useOverlay/OverlayProvider';
import useScrollRestoration from '@hooks/useScrollRestoration';
import { useStore } from '@nanostores/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import ChannelService from '@utils/ChannelService';
import { GTM_ID, pageview } from '@utils/gtm';
import type { AppProps } from 'next/app';
import { useRouter } from 'next/router';
import Script from 'next/script';
import React, { useEffect } from 'react';
import { styled, theme } from 'stitches.config';
import { ampli } from '../src/ampli';
import '../styles/globals.css';

setAccessTokens();

Expand All @@ -35,6 +36,8 @@ function MyApp({ Component, pageProps }: AppProps) {
const _playgroundToken = useStore(playgroundToken);
const isServiceReady = _crewToken && _playgroundToken;

useScrollRestoration();

useEffect(() => {
router.events.on('routeChangeComplete', pageview);
return () => {
Expand Down Expand Up @@ -137,11 +140,9 @@ const Layout = styled('div', {
minHeight: '100vh',
color: theme.colors.white,
mx: '$auto',
marginTop: '100px',
'@desktop': {
maxWidth: '1260px',
px: '$30',
},
marginTop: '128px',
maxWidth: '1260px',
px: '$30',
'@tablet': {
px: '$20',
},
Expand Down
197 changes: 91 additions & 106 deletions pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,143 +1,128 @@
import { ampli } from '@/ampli';
import { useInfinitePosts, useMutationUpdateLike } from '@api/post/hooks';
import LikeButton from '@components/button/LikeButton';
import FeedItem from '@components/page/meetingDetail/Feed/FeedItem';
import MeetingInfo from '@components/page/meetingDetail/Feed/FeedItem/MeetingInfo';
import MobileFeedListSkeleton from '@components/page/meetingDetail/Feed/Skeleton/MobileFeedListSkeleton';
import FloatingButton from '@components/page/postList/FloatingButton';
import { TabList } from '@components/tabList/TabList';
import { Flex } from '@components/util/layout/Flex';
import { TAKE_COUNT } from '@constants/feed';
import { MasonryInfiniteGrid } from '@egjs/react-infinitegrid';
import { useDisplay } from '@hooks/useDisplay';
import { useIntersectionObserver } from '@hooks/useIntersectionObserver';
import type { NextPage } from 'next';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { styled } from 'stitches.config';
import useModal from '@hooks/useModal';
import { playgroundLink } from '@sopt-makers/playground-common';
import ConfirmModal from '@components/modal/ConfirmModal';
import { TabList } from '@components/tabList/TabList';
import { Flex } from '@components/util/layout/Flex';
import { SSRSafeSuspense } from '@components/util/SSRSafeSuspense';
import { MeetingListOfAll } from '@components/page/meetingList/Grid/List';
import Filter from '@components/page/meetingList/Filter';
import Search from '@components/page/meetingList/Filter/Search';
import GridLayout from '@components/page/meetingList/Grid/Layout';
import CardSkeleton from '@components/page/meetingList/Card/Skeleton';
import PlusIcon from '@assets/svg/plus.svg';
import WriteIcon from '@assets/svg/write.svg';
import { useQueryMyProfile } from '@api/user/hooks';
import NoticeSlider from '@components/page/meetingList/Slider/NoticeSlider/NoticeSlider';
import useNotices from '@api/notice/hooks';
import { ampli } from '@/ampli';

const Home: NextPage = () => {
const { isTablet } = useDisplay();
const router = useRouter();
const { data: me } = useQueryMyProfile();
const { isModalOpened, handleModalOpen, handleModalClose } = useModal();
const { data: notices } = useNotices();

const handleMakeMeeting = () => {
if (!me?.hasActivities) {
handleModalOpen();
return;
const { data: postsData, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfinitePosts(TAKE_COUNT);

const onIntersect: IntersectionObserverCallback = ([{ isIntersecting }]) => {
if (isIntersecting && hasNextPage) {
fetchNextPage();
}
ampli.clickMakeGroup();
router.push('/make');
};
const { setTarget } = useIntersectionObserver({ onIntersect });

const { mutate: mutateLikeInAllPost } = useMutationUpdateLike(TAKE_COUNT);

const handleClickLike =
(postId: number) => (mutateCb: (postId: number) => void) => (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
ampli.clickFeedlistLike({ location: router.pathname });
mutateCb(postId);
};

const renderedPosts = postsData?.pages.map(post => {
if (!post) return;
return (
<Link href={`/post?id=${post?.id}`} key={post?.id}>
<a>
<FeedItem
/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */
/* @ts-ignore */
post={post}
LikeButton={
<LikeButton
isLiked={post.isLiked}
likeCount={post.likeCount}
onClickLike={handleClickLike(post.id)(mutateLikeInAllPost)}
/>
}
HeaderSection={<MeetingInfo meetingInfo={post.meeting} />}
/>
</a>
</Link>
);
});

return (
<>
<div>
<Flex align="start" justify="between">
<TabList text="all" size="big">
<TabList text="feedAll" size="big">
<Link href="/" passHref>
<a
onClick={() => {
ampli.clickNavbarGroup({ menu: '전체 모임' });
}}
>
<TabList.Item text="all">전체 모임</TabList.Item>
<a onClick={() => ampli.clickNavbarGroup({ menu: '피드' })}>
<TabList.Item text="feedAll">모임 피드</TabList.Item>
</a>
</Link>
<Link href="/list" passHref>
<a onClick={() => ampli.clickNavbarGroup({ menu: '전체 모임' })}>
<TabList.Item text="groupAll">전체 모임</TabList.Item>
</a>
</Link>
<Link href="/mine" passHref>
<a
onClick={() => {
ampli.clickNavbarGroup({ menu: '내 모임' });
}}
>
<a onClick={() => ampli.clickNavbarGroup({ menu: '내 모임' })}>
<TabList.Item text="mine">내 모임</TabList.Item>
</a>
</Link>
</TabList>
<SMobileButtonContainer>
<WriteIcon onClick={handleMakeMeeting} className="make-button" />
<Search.Mobile />
</SMobileButtonContainer>
<SMakeMeetingButton onClick={handleMakeMeeting}>
<PlusIcon />
<span>모임 개설하기</span>
</SMakeMeetingButton>
</Flex>
<SNoticeWrapper>
<NoticeSlider notices={notices} />
</SNoticeWrapper>
<SFilterWrapper>
<Filter />
</SFilterWrapper>
<SSRSafeSuspense
fallback={
<GridLayout mobileType="list">
{new Array(6).fill(null).map((_, index) => (
<CardSkeleton key={index} mobileType="list" />
))}
</GridLayout>
}
>
<MeetingListOfAll />
</SSRSafeSuspense>

{isTablet ? (
<SMobileContainer>{renderedPosts}</SMobileContainer>
) : (
<SDesktopContainer align="left" gap={30}>
{renderedPosts}
</SDesktopContainer>
)}
<div ref={setTarget} />

{isFetchingNextPage && isTablet && <MobileFeedListSkeleton count={3} />}
<FloatingButton />
</div>
<ConfirmModal
isModalOpened={isModalOpened}
message={`모임을 개설하려면\n프로필 작성이 필요해요`}
cancelButton="돌아가기"
confirmButton="작성하기"
handleModalClose={handleModalClose}
handleConfirm={() => (window.location.href = `${playgroundLink.memberUpload()}`)}
/>
</>
);
};

export default Home;

const SMakeMeetingButton = styled('button', {
flexType: 'verticalCenter',
padding: '$16 $24 $16 $20',
background: '$gray10',
borderRadius: '16px',
'& > span': {
ml: '$12',
fontAg: '18_bold_100',
color: '$gray950',
},
'@tablet': {
display: 'none',
const SDesktopContainer = styled(MasonryInfiniteGrid, {
marginTop: '$40',
a: {
width: 'calc(calc(100% - 60px) / 3)',
},
});

const SMobileButtonContainer = styled('div', {
display: 'none',
'@tablet': {
flexType: 'verticalCenter',
gap: '16px',
},
svg: {
cursor: 'pointer',
},
});

const SFilterWrapper = styled('div', {
mt: '$40',
mb: '$64',
'@tablet': {
mt: '$32',
mb: '$24',
},
});
const SMobileContainer = styled('div', {
display: 'flex',
flexDirection: 'column',
marginTop: 0,
'& a:not(:first-child)::before': {
content: '',
display: 'none',

const SNoticeWrapper = styled('div', {
mt: '$64',
'@tablet': {
mt: '$28',
'@tablet': {
display: 'block',
width: '100vw',
height: '8px',
marginLeft: 'calc(50% - 50vw)',
background: '$gray800',
},
},
});
Loading

0 comments on commit 3d98042

Please sign in to comment.