Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Banner 컴포넌트, 공지사항 페이지 구현 #572

Merged
merged 4 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions frontend/src/components/common/Banner/Banner.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Meta, StoryObj } from '@storybook/react';

import Banner from '.';

const meta: Meta<typeof Banner> = {
component: Banner,
};

export default meta;
type Story = StoryObj<typeof Banner>;

export const Primary: Story = {
render: () => (
<Banner
title="이것은 배너에 포함될 제목입니다."
content="그리고 이것은 배너에 포함될 내용입니다."
handleClose={() => {}}
path="/"
/>
),
};
24 changes: 24 additions & 0 deletions frontend/src/components/common/Banner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import cancel from '@assets/x_mark_black.svg';

import * as S from './style';

interface BannerProps {
title: string;
content: string;
handleClose: () => void;
path: string;
}
export default function Banner({ title, content, handleClose, path }: BannerProps) {
return (
<S.Wrapper>
<S.IconImage src={cancel} alt="배너 닫기" onClick={handleClose} />
<S.Content>
<S.Title aria-label="배너 제목">{title}</S.Title>
<S.Description aria-label="배너 내용">{content}</S.Description>
</S.Content>
<S.MovePageLink to={path} aria-label="세부 페이지로 이동">
자세히
</S.MovePageLink>
</S.Wrapper>
);
}
84 changes: 84 additions & 0 deletions frontend/src/components/common/Banner/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Link } from 'react-router-dom';

import { styled } from 'styled-components';

import { theme } from '@styles/theme';

export const Wrapper = styled.div`
display: grid;
grid-template-columns: 1fr 8fr 3fr;
align-items: center;
justify-items: center;
gap: 4px;

width: 100%;
height: 60px;
border-radius: 7px;

background-color: #f1eae7;

@media (min-width: ${theme.breakpoint.sm}) {
grid-template-columns: 1fr 6fr 3fr;
margin: 0 8px;
}

@media (max-width: ${theme.breakpoint.sm}) {
border-radius: 0px;
}
`;

export const IconImage = styled.img`
width: 18px;
height: 18px;

justify-self: center;
`;

export const Content = styled.div`
display: flex;
flex-direction: column;
justify-content: start;
align-items: start;
justify-self: start;

@media (min-width: ${theme.breakpoint.sm}) {
margin-left: 20px;
}
`;

export const Title = styled.span`
font-size: 16px;
font-weight: 600;

@media (max-width: ${theme.breakpoint.sm}) {
font-size: 13px;
}
`;

export const Description = styled.span`
font-size: 14px;

@media (max-width: ${theme.breakpoint.sm}) {
font-size: 12px;
}
`;

export const MovePageLink = styled(Link)`
justify-self: center;

width: 60%;
height: 50%;
border-radius: 8px;
padding-top: 7px;

color: white;
background-color: var(--header);

font-size: 12px;
text-decoration: none;
text-align: center;

@media (max-width: ${theme.breakpoint.sm}) {
width: 70%;
}
`;
16 changes: 16 additions & 0 deletions frontend/src/components/post/PostListPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { Suspense } from 'react';

import { useDrawer } from '@hooks/useDrawer';
import { useToggle } from '@hooks/useToggle';

import ErrorBoundary from '@pages/ErrorBoundary';

import AddButton from '@components/common/AddButton';
import Banner from '@components/common/Banner';
import Dashboard from '@components/common/Dashboard';
import Drawer from '@components/common/Drawer';
import NarrowMainHeader from '@components/common/NarrowMainHeader';
import Skeleton from '@components/common/Skeleton';
import UpButton from '@components/common/UpButton';
import PostList from '@components/post/PostList';

import { APP_LAUNCH_EVENT } from '@constants/announcement';
import { PATH } from '@constants/path';

import { smoothScrollToTop } from '@utils/scrollToTop';
Expand All @@ -20,12 +23,25 @@ import * as S from './style';

export default function PostListPage() {
const { drawerRef, closeDrawer, openDrawer } = useDrawer('left');
const { TITLE, CONTENT } = APP_LAUNCH_EVENT;

const { isOpen: isBannerOpen, closeComponent: closeBanner } = useToggle(true);

return (
<S.Container>
<S.HeaderWrapper>
<NarrowMainHeader handleMenuOpenClick={openDrawer} />
</S.HeaderWrapper>
{isBannerOpen && (
<S.BannerWrapper>
<Banner
title={TITLE}
content={CONTENT}
handleClose={closeBanner}
path={PATH.ANNOUNCEMENT}
/>
</S.BannerWrapper>
)}
<S.DrawerWrapper>
<Drawer handleDrawerClose={closeDrawer} placement="left" width="225px" ref={drawerRef}>
<Dashboard />
Expand Down
10 changes: 8 additions & 2 deletions frontend/src/components/post/PostListPage/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { styled } from 'styled-components';
import { theme } from '@styles/theme';

export const Container = styled.div`
padding-top: 55px;
padding-top: 40px;
position: relative;

@media (min-width: ${theme.breakpoint.sm}) {
padding-top: 0px;
padding-top: 10px;
}
`;

Expand All @@ -27,6 +27,12 @@ export const HeaderWrapper = styled.div`
}
`;

export const BannerWrapper = styled.div`
width: 100%;

margin-bottom: 10px;
`;

export const DrawerWrapper = styled.div`
@media (min-width: ${theme.breakpoint.sm}) {
display: none;
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/constants/announcement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const APP_LAUNCH_EVENT = {
TITLE: '🎉보투게더 출시 기념 이벤트 진행 중',
CONTENT: '이벤트 참여하면 상품을 받을 수 있다고?',
CONTENT_DETAIL: '',
};
1 change: 1 addition & 0 deletions frontend/src/constants/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const BASE_PATH = {
ADMIN: '/admin',
SEARCH: '/search',
RANKING: '/ranking',
ANNOUNCEMENT: '/announcements',
};

export const PATH = {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/hooks/useToggle.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState } from 'react';

export const useToggle = () => {
const [isOpen, setIsOpen] = useState(false);
export const useToggle = (isInitialOpen = false) => {
const [isOpen, setIsOpen] = useState(isInitialOpen);

const openComponent = () => {
setIsOpen(true);
Expand Down
77 changes: 77 additions & 0 deletions frontend/src/pages/Announcement/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { useNavigate } from 'react-router-dom';

import IconButton from '@components/common/IconButton';
import Layout from '@components/common/Layout';
import NarrowTemplateHeader from '@components/common/NarrowTemplateHeader';
import SquareButton from '@components/common/SquareButton';

import { APP_LAUNCH_EVENT } from '@constants/announcement';

import * as S from './style';

export default function Announcement() {
const navigate = useNavigate();
const { TITLE } = APP_LAUNCH_EVENT;

return (
<Layout isSidebarVisible={false}>
<S.HeaderWrapper>
<NarrowTemplateHeader>
<IconButton
category="back"
onClick={() => {
navigate(-1);
}}
/>
</NarrowTemplateHeader>
</S.HeaderWrapper>
<S.Wrapper>
<S.Title>{TITLE}</S.Title>
<S.MainWrapper>
<S.Content>
안녕하세요, 보투게더(VoTogether)는 우아한테크코스에서 진행한 프로젝트로, 투표 중심의
커뮤니티 플랫폼입니다! <br></br>
<br></br>🤷‍♂️: 돈이 부족한 취준생인데 알바를 병행하는게 좋을까요, 최대한 절약하는게
좋을까요? <br></br>🤷‍♀️: 요즘 체력이 떨어지는데 어떤 운동을 시작하면 좋을까요? <br></br>
🤷‍♂️: 오늘의 점심 메뉴는 뭐가 좋을까?
<h3>다 함께, 즐겁게, 심플하게! 보투게더를 이용해 보세요!</h3> <br></br>
<strong>✅ 보투게더(VoTogether)</strong>는 투표를 통해 의견을 공유하고, 일상의 재미를
발견하는 커뮤니티 서비스예요. <br></br> <br></br>
<strong>
🖋 고민이 있으신가요? 글을 써보세요!
<br></br>
😆 심심하신가요? 투표를 해보세요! <br></br>❔ 궁금하신가요? 관심사를 탐색해 보세요!
</strong>
<br></br>
<br></br>
보투게더는 사람들의 다양한 주제로 질문하고 답변하면서, 사람들의 반응을 확인할 수 있다는
점에서 특별해요. <br></br> 자, 이제 보투게더를 이용할 준비되셨나요? 😆😃<br></br>
나의 이야기가 우리의 이야기가 되는 공간, 보투게더에서 우리 함께해요! 👍 <br></br>
보투게더의 탄생🥳을 함께 축하하고 기념하기 위해, 오늘 출시 이벤트를 진행하고 있어요!
출시 이벤트에서 다음 내역을 달성해주신 이용자 분들께는 기프티콘 등 소정 상품🎁을
증정하고 있어요✨😆 <br></br>
<br></br>
<strong>
⭐ 게시글을 가장 많이 작성🖋️해주신 이용자! <br></br>⭐ 작성한 게시글에 가장 많은
투표✅를 해주신 이용자! <br></br>⭐ 최고 인기글🔥을 작성하신 이용자!
</strong>
<br></br>
<br></br>
(이벤트 기간은 9월 13일(수)~9월 26일(화)이며, 상품 수령 대상자 명단은 공지사항
카테고리에서 확인 가능합니다🙂)
</S.Content>
<S.ButtonWrapper>
<SquareButton
theme="fill"
onClick={() => {
navigate('/');
}}
>
홈으로 가기
</SquareButton>
</S.ButtonWrapper>
</S.MainWrapper>
</S.Wrapper>
</Layout>
);
}
65 changes: 65 additions & 0 deletions frontend/src/pages/Announcement/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { styled } from 'styled-components';

import { theme } from '@styles/theme';

export const Wrapper = styled.div`
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: 30px;

padding-top: 55px;
position: relative;

@media (min-width: 768px) {
padding-top: 20px;
}

@media (min-width: ${theme.breakpoint.sm}) {
padding-top: 20px;
}
`;

export const HeaderWrapper = styled.div`
width: 100%;

position: fixed;

z-index: ${theme.zIndex.header};

@media (min-width: ${theme.breakpoint.sm}) {
display: none;
}
`;

export const MainWrapper = styled.section`
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: start;
gap: 20px;

width: 90%;
`;

export const Title = styled.h1`
width: 90%;
margin-top: 20px;

font-size: 20px;
font-weight: bold;
`;

export const Content = styled.p`
font: var(--text-body);
`;

export const ButtonWrapper = styled.div`
display: flex;

width: 100%;
height: 50px;

padding: 8px;
`;
6 changes: 6 additions & 0 deletions frontend/src/routes/router.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createBrowserRouter } from 'react-router-dom';

import Announcement from '@pages/Announcement';
import Login from '@pages/auth/Login';
import Redirection from '@pages/auth/Redirection';
import Error from '@pages/Error';
Expand Down Expand Up @@ -144,6 +145,11 @@ const router = createBrowserRouter([
element: <Ranking />,
errorElement: <Error />,
},
{
path: PATH.ANNOUNCEMENT,
element: <Announcement />,
errorElement: <Error />,
},
{
path: '*',
element: <NotFound />,
Expand Down
Loading