From 220a22b489332139e7096ced66d61364031e7432 Mon Sep 17 00:00:00 2001 From: Rulu <79538610+hafnium1923@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:05:22 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[FE]=20=ED=8C=80=EB=B0=94=ED=8C=80=20?= =?UTF-8?q?=EB=AA=A8=EB=B0=94=EC=9D=BC=20=EB=B2=84=EC=A0=84=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(#845)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 모바일인지 확인하는 기능 추가 * feat: 모바일 랜딩 화면 * feat: 에러페이지 모바일 대응 * feat: 모바일 전용 templete 구현 * feat: 모바일 네비바, 헤더 스타일 적용 * feat: 모바일 라우트 분할 * feat: 팀 캘린더 임시로 모바일 대응 * refactor: 모바일에서만 헤더 바뀌게 변경 * feat: 팀 채팅 페이지 모바일 대응 * feat: 시작 페이지 모바일 뷰 대응 * refactor: 조인 페이지 확장자 tsx -> ts * feat: 조인 페이지 모바일 뷰 대응 * refactor: 글자 배경색 투명하게 변경 * feat: 생성 페이지 모바일 뷰 대응 * refactor: 확인용 목 데이터 날짜 업데이트 * feat: ics, 데일리 모달 모바일 뷰 대응 * feat: 캘린더 모달 모바일 뷰 대응 * feat: 팀 링크 페이지 모바일 대응 * refactor: 모아보기 페이지 에러에서 404 빼기 * refactor: 유틸 함수 위치 이동, 이름 변경 * refactor: 팀 생성,참가,시작 페이지 배경제거 * refactor: 캘린더 월,일 가운데 정렬 * refactor: 팀피드 팀 채팅으로 변경 * refactor: 팀이름 중앙정렬 * refactor: 팀 공지 상단에 빈공간 없앰 * refactor: 깨지는 UI 수정 및 theme 수정 * refactor: teamSelectPage route 리팩터링 * refactor: 모바일에도 SSE 연결 넣기 * refactor: 오타 수정 * refactor: 기본 화면 위치 변경 --- frontend/src/App.tsx | 26 +++- .../common/Error404/Error404.styled.ts | 1 + .../components/common/Error404/Error404.tsx | 35 ++++- .../components/common/Header/Header.styled.ts | 17 ++- .../src/components/common/Header/Header.tsx | 32 +++-- .../NavigationBar/NavigationBar.styled.ts | 34 ++++- .../common/NavigationBar/NavigationBar.tsx | 32 +++-- .../ImageUploadDrawer.styled.ts | 23 +++- .../ImageUploadDrawer/ImageUploadDrawer.tsx | 4 +- .../feed/NoticeThread/NoticeThread.styled.ts | 16 ++- .../feed/NoticeThread/NoticeThread.tsx | 7 +- .../components/feed/ThreadList/ThreadList.tsx | 2 +- .../link/LinkAddModal/LinkAddModal.styled.ts | 25 +++- .../link/LinkAddModal/LinkAddModal.tsx | 5 +- .../link/LinkTable/LinkTable.styled.ts | 8 +- .../components/link/LinkTable/LinkTable.tsx | 5 +- .../DailyScheduleModal.styled.ts | 9 ++ .../DailyScheduleModal/DailyScheduleModal.tsx | 3 + .../ICalendarModal/ICalendarModal.styled.ts | 32 +++-- .../ICalendarModal/ICalendarModal.tsx | 8 +- .../ScheduleAddModal.styled.ts | 54 +++++--- .../ScheduleAddModal/ScheduleAddModal.tsx | 14 +- .../ScheduleEditModal.styled.ts | 54 +++++--- .../ScheduleEditModal/ScheduleEditModal.tsx | 14 +- .../ScheduleModal/ScheduleModal.styled.ts | 49 ++++++- .../ScheduleModal/ScheduleModal.tsx | 16 ++- .../TeamCalendar/TeamCalendar.tsx | 3 +- .../TimeTableMenu/TimeTableMenu.styled.ts | 4 +- .../TimeTableMenu/TimeTableMenu.tsx | 5 +- .../ServiceCenterModal/ServiceCenterModal.tsx | 9 +- frontend/src/constants/toast.ts | 4 - frontend/src/hooks/thread/useThreadHeight.ts | 8 +- .../M_LandingPage/M_LandingPage.styled.ts | 127 ++++++++++++++++++ .../M_LandingPage/M_LandingPage.tsx | 74 ++++++++++ .../M_PageTemplate/M_PageTemplate.styled.ts | 17 +++ .../M_PageTemplate/M_PageTemplate.tsx | 30 +++++ .../M_TeamSelectPage.styled.ts | 27 ++++ .../M_TeamSelectPage/M_TeamSelectPage.tsx | 30 +++++ frontend/src/mocks/fixtures/schedules.ts | 4 +- frontend/src/mocks/handlers/feed.ts | 8 +- .../src/pages/CreatePage/CreatePage.styled.ts | 18 ++- frontend/src/pages/CreatePage/CreatePage.tsx | 6 +- .../src/pages/Error404Page/Error404Page.tsx | 10 +- ...JoinPage.styled.tsx => JoinPage.styled.ts} | 18 ++- frontend/src/pages/JoinPage/JoinPage.tsx | 6 +- .../src/pages/StartPage/StartPage.styled.ts | 16 ++- frontend/src/pages/StartPage/StartPage.tsx | 6 +- .../TeamCalendarPage/TeamCalendarPage.tsx | 5 +- .../pages/TeamFeedPage/TeamFeedPage.styled.ts | 8 +- .../src/pages/TeamFeedPage/TeamFeedPage.tsx | 7 +- frontend/src/styles/theme.ts | 1 + frontend/src/utils/getIsMobile.ts | 10 ++ 52 files changed, 802 insertions(+), 184 deletions(-) create mode 100644 frontend/src/mobilePages/M_LandingPage/M_LandingPage.styled.ts create mode 100644 frontend/src/mobilePages/M_LandingPage/M_LandingPage.tsx create mode 100644 frontend/src/mobilePages/M_PageTemplate/M_PageTemplate.styled.ts create mode 100644 frontend/src/mobilePages/M_PageTemplate/M_PageTemplate.tsx create mode 100644 frontend/src/mobilePages/M_TeamSelectPage/M_TeamSelectPage.styled.ts create mode 100644 frontend/src/mobilePages/M_TeamSelectPage/M_TeamSelectPage.tsx rename frontend/src/pages/JoinPage/{JoinPage.styled.tsx => JoinPage.styled.ts} (87%) create mode 100644 frontend/src/utils/getIsMobile.ts diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 51f2ecfa0..921601fa7 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -15,23 +15,39 @@ import TeamOverviewPage from '~/pages/TeamOverviewPage/TeamOverviewPage'; import PolicyPage from '~/pages/PolicyPage/PolicyPage'; import Error404Page from '~/pages/Error404Page/Error404Page'; import './App.css'; +import { getIsMobile } from '~/utils/getIsMobile'; +import M_LandingPage from '~/mobilePages/M_LandingPage/M_LandingPage'; +import M_TeamSelectPage from '~/mobilePages/M_TeamSelectPage/M_TeamSelectPage'; +import M_PageTemplate from '~/mobilePages/M_PageTemplate/M_PageTemplate'; const App = () => { + const isMobile = getIsMobile(); + return ( - } /> + {isMobile ? ( + } /> + ) : ( + } /> + )} } /> } /> }> } /> } /> } /> - }> - } /> + + : }> } + path={PATH_NAME.TEAM_SELECT} + element={isMobile ? : } /> + {!isMobile && ( + } + /> + )} } diff --git a/frontend/src/components/common/Error404/Error404.styled.ts b/frontend/src/components/common/Error404/Error404.styled.ts index 9968b4a1b..c43cf84c0 100644 --- a/frontend/src/components/common/Error404/Error404.styled.ts +++ b/frontend/src/components/common/Error404/Error404.styled.ts @@ -51,4 +51,5 @@ export const ErrorTextImage = styled.img` export const errorText = css` font-size: 24px; + white-space: nowrap; `; diff --git a/frontend/src/components/common/Error404/Error404.tsx b/frontend/src/components/common/Error404/Error404.tsx index 73b26eeb4..69925a4d2 100644 --- a/frontend/src/components/common/Error404/Error404.tsx +++ b/frontend/src/components/common/Error404/Error404.tsx @@ -3,6 +3,7 @@ import { error404Image, error404TextImage } from '~/assets/webp'; import Text from '~/components/common/Text/Text'; import BackButton from '~/components/common/BackButton/BackButton'; import { PATH_NAME } from '~/constants/routes'; +import { getIsMobile } from '~/utils/getIsMobile'; interface Error404Props { isLoggedIn: boolean; @@ -10,18 +11,40 @@ interface Error404Props { const Error404 = (props: Error404Props) => { const { isLoggedIn } = props; + const isMobile = getIsMobile(); + const location = window.location.href; return ( - - - 해당 페이지를 찾을 수 없어요! - + {isMobile && location.includes('overview') ? ( + + 모바일에서는 이용할 수 없는 페이지에요! + + ) : ( + <> + + + 해당 페이지를 찾을 수 없어요! + + + )} diff --git a/frontend/src/components/common/Header/Header.styled.ts b/frontend/src/components/common/Header/Header.styled.ts index 07f44a196..78c5aff97 100644 --- a/frontend/src/components/common/Header/Header.styled.ts +++ b/frontend/src/components/common/Header/Header.styled.ts @@ -1,7 +1,7 @@ import { css, styled } from 'styled-components'; import type { HeaderModalType } from '~/components/common/Header/Header'; -export const Header = styled.header` +export const Header = styled.header<{ $isMobile: boolean }>` display: flex; justify-content: space-between; @@ -10,12 +10,20 @@ export const Header = styled.header` padding: 0 14px; border-bottom: 2px solid ${({ theme }) => theme.color.GRAY200}; + + ${({ $isMobile }) => + $isMobile && + css` + height: 110px; + flex-wrap: wrap; + flex-direction: row-reverse; + `} `; export const InnerContainer = styled.div` display: flex; column-gap: 20px; - + width: 100%; & > div { display: flex; align-items: center; @@ -85,6 +93,7 @@ export const notificationButton = css` export const teamPlaceInfoButton = css` display: flex; + flex-direction: column; align-items: center; justify-content: center; @@ -138,3 +147,7 @@ export const teamColorButton = ( opacity: 1; } `; + +export const explainText = css` + font-size: 10px; +`; diff --git a/frontend/src/components/common/Header/Header.tsx b/frontend/src/components/common/Header/Header.tsx index be2703ce8..384039809 100644 --- a/frontend/src/components/common/Header/Header.tsx +++ b/frontend/src/components/common/Header/Header.tsx @@ -16,6 +16,8 @@ import UserInfoModal from '~/components/user/UserInfoModal/UserInfoModal'; import TeamColorEditModal from '~/components/team/TeamColorEditModal/TeamColorEditModal'; import AccountDeleteModal from '~/components/user/AccountDeleteModal/AccountDeleteModal'; import ServiceCenterModal from '~/components/user/ServiceCenterModal/ServiceCenterModal'; +import { getIsMobile } from '~/utils/getIsMobile'; +import Text from '~/components/common/Text/Text'; import { fetchTeamPlaceInviteCode, fetchTeamPlaceMembers } from '~/apis/team'; import { STALE_TIME } from '~/constants/query'; @@ -36,6 +38,9 @@ const Header = () => { } = useTeamPlace(); const navigate = useNavigate(); const { openModal, isModalOpen } = useModal(); + + const isMobile = getIsMobile(); + const queryClient = useQueryClient(); const { userInfo } = useFetchUserInfo(); @@ -83,7 +88,9 @@ const Header = () => { setTeamName(() => value); if (location.pathname === PATH_NAME.TEAM_SELECT) { - navigate(PATH_NAME.TEAM_OVERVIEW); + isMobile + ? navigate(PATH_NAME.TEAM_CALENDAR) + : navigate(PATH_NAME.TEAM_OVERVIEW); } }, /*eslint-disable-next-line*/ @@ -125,14 +132,16 @@ const Header = () => { return ( <> - + - - - + {!isMobile && ( + + + + )}
diff --git a/frontend/src/components/common/NavigationBar/NavigationBar.styled.ts b/frontend/src/components/common/NavigationBar/NavigationBar.styled.ts index 82d8e3e04..1a5d486c9 100644 --- a/frontend/src/components/common/NavigationBar/NavigationBar.styled.ts +++ b/frontend/src/components/common/NavigationBar/NavigationBar.styled.ts @@ -2,21 +2,41 @@ import { styled } from 'styled-components'; import { NavLink } from 'react-router-dom'; import { css } from 'styled-components'; -export const Nav = styled.nav` +export const Nav = styled.nav<{ $isMobile: boolean }>` display: flex; + ${({ $isMobile }) => { + if ($isMobile) + return css` + width: 100%; + height: 60px; + padding: 10px; + `; - width: 70px; - height: 100%; - padding: 14px 0 18px 0; + return css` + width: 70px; + height: 100%; + padding: 14px 0 18px 0; + `; + }} `; -export const MenuContainer = styled.div` +export const MenuContainer = styled.div<{ $isMobile: boolean }>` display: flex; - flex-direction: column; align-items: center; width: 100%; - gap: 30px; + ${({ $isMobile }) => { + if ($isMobile) + return css` + justify-content: space-between; + `; + + return css` + flex-direction: column; + + gap: 30px; + `; + }} `; export const MenuLink = styled(NavLink)` diff --git a/frontend/src/components/common/NavigationBar/NavigationBar.tsx b/frontend/src/components/common/NavigationBar/NavigationBar.tsx index a0bec35f8..8678a33de 100644 --- a/frontend/src/components/common/NavigationBar/NavigationBar.tsx +++ b/frontend/src/components/common/NavigationBar/NavigationBar.tsx @@ -10,33 +10,37 @@ import { import * as S from './NavigationBar.styled'; import Text from '~/components/common/Text/Text'; import Button from '~/components/common/Button/Button'; +import { getIsMobile } from '~/utils/getIsMobile'; const NavigationBar = () => { const navigate = useNavigate(); const location = useLocation(); - + const isMobile = getIsMobile(); const handleTeamAddButtonClick = () => { navigate(PATH_NAME.START, { state: { from: location } }); }; return ( - - - - - 모아보기 - + + + {!isMobile && ( + + + 모아보기 + + )} + - 캘린더 + {!isMobile && 캘린더} - 피드 + {!isMobile && 채팅} - 링크 + {!isMobile && 링크} diff --git a/frontend/src/components/feed/ImageUploadDrawer/ImageUploadDrawer.styled.ts b/frontend/src/components/feed/ImageUploadDrawer/ImageUploadDrawer.styled.ts index 90570d32f..203250698 100644 --- a/frontend/src/components/feed/ImageUploadDrawer/ImageUploadDrawer.styled.ts +++ b/frontend/src/components/feed/ImageUploadDrawer/ImageUploadDrawer.styled.ts @@ -1,19 +1,32 @@ import { styled, css } from 'styled-components'; -export const Container = styled.div<{ $isOpen: boolean }>` +export const Container = styled.div<{ $isOpen: boolean; $isMobile: boolean }>` display: flex; position: absolute; - bottom: 46px; - left: 30px; - width: calc(100% - 60px); + ${({ $isMobile }) => { + if ($isMobile) { + return css` + bottom: 10px; + width: 100%; + `; + } + + return css` + bottom: 46px; + left: 30px; + + width: calc(100% - 60px); + `; + }} + height: 136px; border-radius: 20px 20px 0 0; background: linear-gradient(30deg, #bfc3ff, #eaebff); transition: 0.35s; - transform: translateY(${({ $isOpen }) => ($isOpen ? '-168px' : '0')}); + transform: translateY(${({ $isOpen }) => ($isOpen ? '-163px' : '0')}); `; export const ContentWrapper = styled.div` diff --git a/frontend/src/components/feed/ImageUploadDrawer/ImageUploadDrawer.tsx b/frontend/src/components/feed/ImageUploadDrawer/ImageUploadDrawer.tsx index 46d0c2a2e..a9858142a 100644 --- a/frontend/src/components/feed/ImageUploadDrawer/ImageUploadDrawer.tsx +++ b/frontend/src/components/feed/ImageUploadDrawer/ImageUploadDrawer.tsx @@ -2,6 +2,7 @@ import type { PropsWithChildren } from 'react'; import * as S from './ImageUploadDrawer.styled'; import Button from '~/components/common/Button/Button'; import { CloseBoldIcon } from '~/assets/svg'; +import { getIsMobile } from '~/utils/getIsMobile'; interface ImageUploadDrawerProps { isOpen: boolean; @@ -13,9 +14,10 @@ const ImageUploadDrawer = ( props: PropsWithChildren, ) => { const { isOpen, onClose, children, isUploading } = props; + const isMobile = getIsMobile(); return ( - + {children} {!isUploading && ( diff --git a/frontend/src/components/feed/NoticeThread/NoticeThread.styled.ts b/frontend/src/components/feed/NoticeThread/NoticeThread.styled.ts index 42c510c39..db9aac880 100644 --- a/frontend/src/components/feed/NoticeThread/NoticeThread.styled.ts +++ b/frontend/src/components/feed/NoticeThread/NoticeThread.styled.ts @@ -2,14 +2,17 @@ import { styled, css } from 'styled-components'; import { noticeThreadBackground } from '~/assets/png'; import type { NoticeSize } from '~/types/size'; -export const Container = styled.div<{ $noticeSize: NoticeSize }>` +export const Container = styled.div<{ + $noticeSize: NoticeSize; + $isMobile: boolean; +}>` position: sticky; - top: 0; + top: ${({ $isMobile }) => ($isMobile ? '-4px' : 0)}; left: 0; right: 0; z-index: ${({ theme }) => theme.zIndex.NOTICE}; - padding-top: 10px; + padding-top: ${({ $isMobile }) => ($isMobile ? 0 : '10px')}; background-color: ${({ theme }) => theme.color.GRAY100}; border-bottom: 2px solid ${({ theme }) => theme.color.PRIMARY200}; @@ -32,14 +35,17 @@ export const Container = styled.div<{ $noticeSize: NoticeSize }>` }} `; -export const BackgroundContainer = styled.div<{ $noticeSize: NoticeSize }>` +export const BackgroundContainer = styled.div<{ + $noticeSize: NoticeSize; + $isMobile: boolean; +}>` display: flex; justify-content: space-between; overflow: hidden; height: 100%; - border-radius: 20px 20px 0 0; + border-radius: ${({ $isMobile }) => ($isMobile ? 0 : '20px 20px 0 0')}; background-image: url(${noticeThreadBackground}); background-size: 100%; diff --git a/frontend/src/components/feed/NoticeThread/NoticeThread.tsx b/frontend/src/components/feed/NoticeThread/NoticeThread.tsx index f66568134..76eb77c8d 100644 --- a/frontend/src/components/feed/NoticeThread/NoticeThread.tsx +++ b/frontend/src/components/feed/NoticeThread/NoticeThread.tsx @@ -12,6 +12,7 @@ import { MegaphoneIcon, } from '~/assets/svg'; import * as S from './NoticeThread.styled'; +import { getIsMobile } from '~/utils/getIsMobile'; interface NoticeThreadProps { authorName: string; @@ -23,7 +24,7 @@ interface NoticeThreadProps { const NoticeThread = (props: NoticeThreadProps) => { const { authorName, createdAt, content, images, onClickImage } = props; - + const isMobile = getIsMobile(); const [noticeSize, setNoticeSize] = useState('sm'); const handleExpandMoreClick = () => { @@ -37,8 +38,8 @@ const NoticeThread = (props: NoticeThreadProps) => { }; return ( - - + + { threadPages && threadPages.pages[0].threads.length > 0 && ( - 마지막 스레드 입니다. + 마지막 채팅 입니다. )} {threadPages?.pages diff --git a/frontend/src/components/link/LinkAddModal/LinkAddModal.styled.ts b/frontend/src/components/link/LinkAddModal/LinkAddModal.styled.ts index bd9b6599d..fc2ab4a9a 100644 --- a/frontend/src/components/link/LinkAddModal/LinkAddModal.styled.ts +++ b/frontend/src/components/link/LinkAddModal/LinkAddModal.styled.ts @@ -9,8 +9,13 @@ export const Backdrop = styled.div` height: 100%; `; -export const Container = styled.div<{ $linkSize: LinkSize }>` +export const Container = styled.div<{ + $linkSize: LinkSize; + $isMobile: boolean; +}>` position: fixed; + display: flex; + flex-direction: column; ${({ $linkSize }) => { if ($linkSize === 'md') return css` @@ -27,12 +32,20 @@ export const Container = styled.div<{ $linkSize: LinkSize }>` `; }} - display: flex; - flex-direction: column; + ${({ $isMobile }) => { + if ($isMobile) + return css` + width: 300px; + padding: 10px 26px 20px; + `; - width: 496px; - min-height: 320px; - padding: 20px 30px; + return css` + width: 496px; + min-height: 320px; + padding: 20px 30px; + `; + }} + border-radius: 10px; box-shadow: diff --git a/frontend/src/components/link/LinkAddModal/LinkAddModal.tsx b/frontend/src/components/link/LinkAddModal/LinkAddModal.tsx index d79480256..ea077534a 100644 --- a/frontend/src/components/link/LinkAddModal/LinkAddModal.tsx +++ b/frontend/src/components/link/LinkAddModal/LinkAddModal.tsx @@ -7,6 +7,7 @@ import Input from '~/components/common/Input/Input'; import { useRef } from 'react'; import { useTeamLinkAddModal } from '~/hooks/link/useTeamLinkAddModal'; import type { LinkSize } from '~/types/size'; +import { getIsMobile } from '~/utils/getIsMobile'; interface LinkAddModalProps { linkSize?: LinkSize; @@ -14,7 +15,7 @@ interface LinkAddModalProps { const LinkAddModal = (props: LinkAddModalProps) => { const { linkSize = 'md' } = props; - + const isMobile = getIsMobile(); const linkRef = useRef(null); const { @@ -32,7 +33,7 @@ const LinkAddModal = (props: LinkAddModalProps) => { return ( - + - + {linkTableHeaderValues.map((value) => ( {value} diff --git a/frontend/src/components/team_calendar/DailyScheduleModal/DailyScheduleModal.styled.ts b/frontend/src/components/team_calendar/DailyScheduleModal/DailyScheduleModal.styled.ts index e4eb358b4..c81bcbeee 100644 --- a/frontend/src/components/team_calendar/DailyScheduleModal/DailyScheduleModal.styled.ts +++ b/frontend/src/components/team_calendar/DailyScheduleModal/DailyScheduleModal.styled.ts @@ -104,7 +104,16 @@ export const modalLocation = ( calendarWidth: number, calendarLeft: number, calendarSize: CalendarSize, + isMobile: boolean, ) => { + if (isMobile) + return css` + top: 50%; + left: 50%; + + transform: translate(-50%, -50%); + `; + if (calendarSize === 'md') return css` position: absolute; diff --git a/frontend/src/components/team_calendar/DailyScheduleModal/DailyScheduleModal.tsx b/frontend/src/components/team_calendar/DailyScheduleModal/DailyScheduleModal.tsx index 17706028e..6918157b5 100644 --- a/frontend/src/components/team_calendar/DailyScheduleModal/DailyScheduleModal.tsx +++ b/frontend/src/components/team_calendar/DailyScheduleModal/DailyScheduleModal.tsx @@ -9,6 +9,7 @@ import { useFetchDailySchedules } from '~/hooks/queries/useFetchDailySchedules'; import type { Position, SchedulePosition } from '~/types/schedule'; import { useTeamPlace } from '~/hooks/useTeamPlace'; import type { CalendarSize } from '~/types/size'; +import { getIsMobile } from '~/utils/getIsMobile'; export interface DailyScheduleModalProps { calendarSize?: CalendarSize; @@ -40,6 +41,7 @@ const DailyScheduleModal = (props: DailyScheduleModalProps) => { const { row, column } = position; const { closeModal } = useModal(); const { teamPlaceColor, teamPlaceId } = useTeamPlace(); + const isMobile = getIsMobile(); const { year, month, date } = parseDate(rawDate); const schedules = useFetchDailySchedules(teamPlaceId, year, month, date); @@ -54,6 +56,7 @@ const DailyScheduleModal = (props: DailyScheduleModalProps) => { calendarWidth, calendarLeft, calendarSize, + isMobile, )} > diff --git a/frontend/src/components/team_calendar/ICalendarModal/ICalendarModal.styled.ts b/frontend/src/components/team_calendar/ICalendarModal/ICalendarModal.styled.ts index 87f68823e..585baf5ab 100644 --- a/frontend/src/components/team_calendar/ICalendarModal/ICalendarModal.styled.ts +++ b/frontend/src/components/team_calendar/ICalendarModal/ICalendarModal.styled.ts @@ -1,5 +1,5 @@ import styled, { css } from 'styled-components'; -import type { ICalendarModalProps } from '~/components/team_calendar/ICalendarModal/ICalendarModal'; +import type { CalendarSize } from '~/types/size'; export const Backdrop = styled.div` position: fixed; @@ -10,14 +10,15 @@ export const Backdrop = styled.div` height: 100%; `; -export const Container = styled.div.withConfig({ - shouldForwardProp: (prop) => !['calendarSize'].includes(prop), -})` +export const Container = styled.div<{ + $calendarSize: CalendarSize; + $isMobile: boolean; +}>` position: fixed; display: flex; flex-direction: column; - ${({ calendarSize }) => { - if (calendarSize === 'md') { + ${({ $calendarSize, $isMobile }) => { + if ($calendarSize === 'md' || $isMobile) { return css` top: 50%; left: 50%; @@ -25,7 +26,7 @@ export const Container = styled.div.withConfig({ `; } - if (calendarSize === 'sm') { + if ($calendarSize === 'sm') { return css` top: 25%; left: 14.4%; @@ -33,10 +34,21 @@ export const Container = styled.div.withConfig({ } }} - width: 400px; - min-height: 200px; - padding: 20px; + ${({ $isMobile }) => { + if ($isMobile) + return css` + width: 300px; + min-height: 180px; + padding: 10px 20px; + `; + return css` + width: 400px; + min-height: 200px; + padding: 20px; + `; + }} + border-radius: 8px; box-shadow: 0 0 1px #1b1d1f33, diff --git a/frontend/src/components/team_calendar/ICalendarModal/ICalendarModal.tsx b/frontend/src/components/team_calendar/ICalendarModal/ICalendarModal.tsx index 563ea3430..787f656ac 100644 --- a/frontend/src/components/team_calendar/ICalendarModal/ICalendarModal.tsx +++ b/frontend/src/components/team_calendar/ICalendarModal/ICalendarModal.tsx @@ -11,8 +11,9 @@ import { ClipboardIcon, CloseIcon, QuestionIcon } from '~/assets/svg'; import type { CalendarSize } from '~/types/size'; import * as S from './ICalendarModal.styled'; import { ICALENDAR_USER_GUIDE_URL } from '~/constants/url'; +import { getIsMobile } from '~/utils/getIsMobile'; -export interface ICalendarModalProps { +interface ICalendarModalProps { calendarSize?: CalendarSize; } @@ -21,6 +22,7 @@ const ICalendarModal = (props: ICalendarModalProps) => { const { closeModal } = useModal(); const { showToast } = useToast(); const { teamPlaceId } = useTeamPlace(); + const isMobile = getIsMobile(); const { url } = useFetchICalendarUrl(teamPlaceId); @@ -42,7 +44,7 @@ const ICalendarModal = (props: ICalendarModalProps) => { return ( - + 일정 내보내기 @@ -82,7 +84,7 @@ const ICalendarModal = (props: ICalendarModalProps) => { - + {!isMobile && } 일정 파일(.ics) 경로 diff --git a/frontend/src/components/team_calendar/ScheduleAddModal/ScheduleAddModal.styled.ts b/frontend/src/components/team_calendar/ScheduleAddModal/ScheduleAddModal.styled.ts index fab5b5721..36399fa1e 100644 --- a/frontend/src/components/team_calendar/ScheduleAddModal/ScheduleAddModal.styled.ts +++ b/frontend/src/components/team_calendar/ScheduleAddModal/ScheduleAddModal.styled.ts @@ -9,10 +9,15 @@ export const Backdrop = styled.div` height: 100%; `; -export const Container = styled.div<{ $calendarSize: CalendarSize }>` +export const Container = styled.div<{ + $calendarSize: CalendarSize; + $isMobile: boolean; +}>` + display: flex; + flex-direction: column; position: fixed; - ${({ $calendarSize }) => { - if ($calendarSize === 'md') + ${({ $calendarSize, $isMobile }) => { + if ($calendarSize === 'md' || $isMobile) return css` top: 50%; left: 50%; @@ -25,13 +30,21 @@ export const Container = styled.div<{ $calendarSize: CalendarSize }>` left: 13.5%; `; }} - display: flex; - flex-direction: column; - width: 496px; - min-height: 380px; - padding: 20px 30px; + ${({ $isMobile }) => { + if ($isMobile) + return css` + width: 300px; + padding: 10px 26px 20px; + `; + return css` + width: 496px; + min-height: 380px; + padding: 20px 30px; + `; + }} + border-radius: 10px; box-shadow: 0 0 1px #1b1d1f33, @@ -43,7 +56,7 @@ export const Container = styled.div<{ $calendarSize: CalendarSize }>` display: flex; flex-direction: column; - row-gap: 20px; + row-gap: ${({ $isMobile }) => ($isMobile ? '10px' : '20px')}; } `; @@ -77,24 +90,33 @@ export const CheckboxContainer = styled.div` column-gap: 8px; `; -export const TimeSelectContainer = styled.div` +export const TimeSelectContainer = styled.div<{ $isMobile: boolean }>` display: flex; - align-items: center; width: 100%; - height: 40px; + height: ${({ $isMobile }) => ($isMobile ? '74px' : '40px')}; + + ${({ $isMobile }) => { + if ($isMobile) + return css` + flex-direction: column; + gap: 4px; + `; - column-gap: 10px; + return css` + align-items: center; + `; + }} `; -export const InputWrapper = styled.div` +export const InputWrapper = styled.div<{ $isMobile: boolean }>` display: flex; align-items: center; justify-content: space-between; - width: calc(100% - 100px); + width: ${({ $isMobile }) => !$isMobile && 'calc(100% - 100px)'}; - margin-left: auto; + margin-left: ${({ $isMobile }) => !$isMobile && 'auto'}; `; export const TeamNameContainer = styled.div` diff --git a/frontend/src/components/team_calendar/ScheduleAddModal/ScheduleAddModal.tsx b/frontend/src/components/team_calendar/ScheduleAddModal/ScheduleAddModal.tsx index 70b46b696..33bbb368b 100644 --- a/frontend/src/components/team_calendar/ScheduleAddModal/ScheduleAddModal.tsx +++ b/frontend/src/components/team_calendar/ScheduleAddModal/ScheduleAddModal.tsx @@ -12,6 +12,7 @@ import TimeTableMenu from '~/components/team_calendar/TimeTableMenu/TimeTableMen import { useTeamPlace } from '~/hooks/useTeamPlace'; import { useRef, useEffect } from 'react'; import type { CalendarSize } from '~/types/size'; +import { getIsMobile } from '~/utils/getIsMobile'; interface ScheduleAddModalProps { calendarSize?: CalendarSize; @@ -22,6 +23,7 @@ const ScheduleAddModal = (props: ScheduleAddModalProps) => { const { clickedDate, calendarSize = 'md' } = props; const { closeModal } = useModal(); const { teamPlaceColor, displayName } = useTeamPlace(); + const isMobile = getIsMobile(); const { schedule, isAllDay, @@ -44,7 +46,7 @@ const ScheduleAddModal = (props: ScheduleAddModalProps) => { return ( - + diff --git a/frontend/src/constants/toast.ts b/frontend/src/constants/toast.ts index e804bd9f3..1d27f4402 100644 --- a/frontend/src/constants/toast.ts +++ b/frontend/src/constants/toast.ts @@ -4,8 +4,4 @@ export const TOAST_SUCCESS_MESSAGES = { ADD_SCHEDULE: '일정이 등록되었습니다.', UPDATE_SCHEDULE: '일정이 수정되었습니다.', DELETE_SCHEDULE: '일정이 삭제되었습니다.', - - ADD_THREAD: '스레드가 등록되었습니다.', - UPDATE_THREAD: '스레드가 수정되었습니다.', - DELETE_THREAD: '스레드가 삭제되었습니다.', }; diff --git a/frontend/src/hooks/thread/useThreadHeight.ts b/frontend/src/hooks/thread/useThreadHeight.ts index 48dd6bf13..3bea39e86 100644 --- a/frontend/src/hooks/thread/useThreadHeight.ts +++ b/frontend/src/hooks/thread/useThreadHeight.ts @@ -4,15 +4,15 @@ import { DEFAULT_MAX_THREAD_HEIGHT } from '~/constants/feed'; /** * 《useThreadHeight》 - * 스레드가 확장되어 있는지의 여부를 관리할 수 있고, 이를 바탕으로 스레드가 가져야 하는 높이를 알려줍니다. + * 채팅이 확장되어 있는지의 여부를 관리할 수 있고, 이를 바탕으로 채팅이 가져야 하는 높이를 알려줍니다. * - * @param threadRef - 스레드 컴포넌트의 ref + * @param threadRef - 채팅 컴포넌트의 ref * @param contentRef - 본문의 ref * * @returns shouldShowExpandButton - 확장/축소 버튼을 표시해야하는지의 여부 - * @returns isExpanded - 현재 스레드가 확장 상태인지의 여부 + * @returns isExpanded - 현재 채팅이 확장 상태인지의 여부 * @returns toggleExpandButton - 확장/축소 토글을 위한 함수 - * @returns resultHeight - 스레드가 가져야 하는 높이 + * @returns resultHeight - 채팅이 가져야 하는 높이 */ export const useThreadHeight = ( threadRef: RefObject, diff --git a/frontend/src/mobilePages/M_LandingPage/M_LandingPage.styled.ts b/frontend/src/mobilePages/M_LandingPage/M_LandingPage.styled.ts new file mode 100644 index 000000000..09cfcce20 --- /dev/null +++ b/frontend/src/mobilePages/M_LandingPage/M_LandingPage.styled.ts @@ -0,0 +1,127 @@ +import { styled, css } from 'styled-components'; +import { Link } from 'react-router-dom'; + +export const Container = styled.div` + display: flex; + flex-direction: column; + + width: 100vw; + height: 100vh; +`; + +export const MainContainer = styled.div` + display: flex; + justify-content: center; + align-items: center; + flex-grow: 1; +`; + +export const Main = styled.main` + display: flex; + justify-content: flex-end; + flex-direction: column; + + width: 80vw; + height: 80vh; + + & h2, + & p { + text-align: right; + } +`; + +export const TextContainer = styled.div` + display: flex; + align-items: flex-end; + flex-direction: column; +`; + +export const LandingPageLink = styled(Link)` + display: flex; + align-items: center; + column-gap: 20px; +`; + +export const LoreTextContainer = styled.div` + display: flex; + align-items: flex-end; + flex-direction: column; + + margin-bottom: 60px; +`; + +export const GoogleLoginButtonAppearance = styled.div` + display: flex; + justify-content: space-around; + align-items: center; + + width: 300px; + height: 60px; + + border: 1px solid ${({ theme }) => theme.color.GRAY300}; + border-radius: 12px; + background-color: ${({ theme }) => theme.color.WHITE}; + + box-shadow: 0 12px 20px ${({ theme }) => theme.color.GRAY300}; + transition: 0.25s; + + button &:hover { + transform: translateY(-6px); + } +`; + +export const GoogleLogo = styled.img` + width: 26px; + height: 27px; +`; + +export const mainPrefix = css` + width: fit-content; + + font-size: 30px; + font-weight: 900; + + color: ${({ theme }) => theme.color.BLUE700}; + background-color: ${({ theme }) => theme.color.WHITE_BLUR}; + border-radius: 4px; +`; + +export const mainTitle = css` + width: fit-content; + margin-bottom: 30px; + + font-size: 50px; + font-weight: 900; + + color: ${({ theme }) => theme.color.PURPLE}; + background-color: ${({ theme }) => theme.color.WHITE_BLUR}; + border-radius: 4px; +`; + +export const mainLore = css` + width: fit-content; + + font-size: 20px; + font-weight: 600; + + color: ${({ theme }) => theme.color.BLACK}; + background-color: ${({ theme }) => theme.color.WHITE_BLUR}; + border-radius: 4px; +`; + +export const googleLoginButton = css` + display: flex; + flex-direction: column; + justify-content: end; + + width: 300px; + height: 66px; + margin-left: auto; + padding: 0; +`; + +export const googleLoginText = css` + font-size: 18px; + font-weight: 500; + color: ${({ theme }) => theme.color.GRAY700}; +`; diff --git a/frontend/src/mobilePages/M_LandingPage/M_LandingPage.tsx b/frontend/src/mobilePages/M_LandingPage/M_LandingPage.tsx new file mode 100644 index 000000000..981b7c21a --- /dev/null +++ b/frontend/src/mobilePages/M_LandingPage/M_LandingPage.tsx @@ -0,0 +1,74 @@ +import { useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { fetchGoogleLogin } from '~/apis/auth'; +import { PATH_NAME } from '~/constants/routes'; +import * as S from './M_LandingPage.styled'; +import Button from '~/components/common/Button/Button'; +import IntroCardPile from '~/components/landing/IntroCardPile/IntroCardPile'; +import Text from '~/components/common/Text/Text'; +import { googleLogo } from '~/assets/png'; +import { LOCAL_STORAGE_KEY } from '~/constants/localStorage'; +import LandingHeader from '~/components/common/LandingHeader/LandingHeader'; +import { useToken } from '~/hooks/useToken'; + +const M_LandingPage = () => { + const navigate = useNavigate(); + const { accessToken, resetToken } = useToken(); + + const handleGoogleLogin = async () => { + const { googleLoginUrl } = await fetchGoogleLogin(); + + window.location.href = googleLoginUrl; + }; + + useEffect(() => { + const teamPlaceId = localStorage.getItem(LOCAL_STORAGE_KEY.TEAM_PLACE_ID); + + if (accessToken && teamPlaceId) { + navigate(PATH_NAME.TEAM_SELECT); + return; + } + + if (accessToken) { + resetToken(); + return; + } + }, [navigate]); + + return ( + + + + + + + 쉽고 간단한 팀플 플랫폼, + + + 팀바팀 + + + 팀 프로젝트의 모든 것을 + 팀바팀으로 관리해보세요. + + + + + + + + + ); +}; + +export default M_LandingPage; diff --git a/frontend/src/mobilePages/M_PageTemplate/M_PageTemplate.styled.ts b/frontend/src/mobilePages/M_PageTemplate/M_PageTemplate.styled.ts new file mode 100644 index 000000000..2186de1a4 --- /dev/null +++ b/frontend/src/mobilePages/M_PageTemplate/M_PageTemplate.styled.ts @@ -0,0 +1,17 @@ +import { styled } from 'styled-components'; + +export const PageContainer = styled.div` + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + + overflow: hidden; +`; + +export const PageWrapper = styled.main` + flex: 1; + + height: calc(100vh - 170px); +`; diff --git a/frontend/src/mobilePages/M_PageTemplate/M_PageTemplate.tsx b/frontend/src/mobilePages/M_PageTemplate/M_PageTemplate.tsx new file mode 100644 index 000000000..645a6185a --- /dev/null +++ b/frontend/src/mobilePages/M_PageTemplate/M_PageTemplate.tsx @@ -0,0 +1,30 @@ +import * as S from './M_PageTemplate.styled'; +import NavigationBar from '~/components/common/NavigationBar/NavigationBar'; +import { Outlet } from 'react-router-dom'; +import Header from '~/components/common/Header/Header'; +import { ModalProvider } from '~/components/common/Modal/ModalContext'; +import { useTeamPlace } from '~/hooks/useTeamPlace'; +import { useSSE } from '~/hooks/queries/useSSE'; + +const M_PageTemplate = () => { + const { teamPlaceId } = useTeamPlace(); + + useSSE(teamPlaceId); + + return ( + + +
+ + + + + + + + + + ); +}; + +export default M_PageTemplate; diff --git a/frontend/src/mobilePages/M_TeamSelectPage/M_TeamSelectPage.styled.ts b/frontend/src/mobilePages/M_TeamSelectPage/M_TeamSelectPage.styled.ts new file mode 100644 index 000000000..dacadb904 --- /dev/null +++ b/frontend/src/mobilePages/M_TeamSelectPage/M_TeamSelectPage.styled.ts @@ -0,0 +1,27 @@ +import { styled, css } from 'styled-components'; + +export const Container = styled.div` + display: flex; + justify-content: center; + align-items: center; + + width: 100%; + height: 100%; + + background-color: ${({ theme }) => theme.color.GRAY100}; +`; + +export const PlaceHolder = styled.div` + display: flex; + flex-direction: column; + row-gap: 16px; + + width: 270px; + height: 270px; +`; + +export const placeHolderText = css` + font-size: 30px; + text-align: center; + color: ${({ theme }) => theme.color.GRAY400}; +`; diff --git a/frontend/src/mobilePages/M_TeamSelectPage/M_TeamSelectPage.tsx b/frontend/src/mobilePages/M_TeamSelectPage/M_TeamSelectPage.tsx new file mode 100644 index 000000000..a2b755303 --- /dev/null +++ b/frontend/src/mobilePages/M_TeamSelectPage/M_TeamSelectPage.tsx @@ -0,0 +1,30 @@ +import Text from '~/components/common/Text/Text'; +import * as S from './M_TeamSelectPage.styled'; +import { teamSelectImage } from '~/assets/png'; +import { useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { PATH_NAME } from '~/constants/routes'; +import { LOCAL_STORAGE_KEY } from '~/constants/localStorage'; + +const M_TeamSelectPage = () => { + const navigate = useNavigate(); + + useEffect(() => { + const teamPlaceId = localStorage.getItem(LOCAL_STORAGE_KEY.TEAM_PLACE_ID); + + if (teamPlaceId) navigate(PATH_NAME.TEAM_CALENDAR); + }, [navigate]); + + return ( + + + + + 팀을 선택해 주세요 + + + + ); +}; + +export default M_TeamSelectPage; diff --git a/frontend/src/mocks/fixtures/schedules.ts b/frontend/src/mocks/fixtures/schedules.ts index 6765d89e8..abd221e13 100644 --- a/frontend/src/mocks/fixtures/schedules.ts +++ b/frontend/src/mocks/fixtures/schedules.ts @@ -4,8 +4,8 @@ export const schedules: Schedule[] = [ { id: 0, title: 'test0', - startDateTime: '2023-07-13 00:00', - endDateTime: '2023-07-14 23:59', + startDateTime: '2023-11-13 00:00', + endDateTime: '2023-11-14 23:59', }, { id: 1, diff --git a/frontend/src/mocks/handlers/feed.ts b/frontend/src/mocks/handlers/feed.ts index ff63b966e..b5e09deec 100644 --- a/frontend/src/mocks/handlers/feed.ts +++ b/frontend/src/mocks/handlers/feed.ts @@ -9,7 +9,7 @@ const threads = [...threadData]; const noticeThread = { ...noticeData }; export const feedHandlers = [ - //팀피드 스레드 조회 + //팀채팅 채팅 조회 rest.get( '/api/team-place/:teamPlaceId/feed/threads', async (req, res, ctx) => { @@ -33,7 +33,7 @@ export const feedHandlers = [ }, ), - //팀피드 공지 스레드 조회 + //팀피드 공지 조회 rest.get( '/api/team-place/:teamPlaceId/feed/notice/recent', async (req, res, ctx) => { @@ -48,7 +48,7 @@ export const feedHandlers = [ }, ), - //팀피드 스레드 생성 + //팀피드 채팅 생성 rest.post( '/api/team-place/:teamPlaceId/feed/threads', async (req, res, ctx) => { @@ -108,7 +108,7 @@ export const feedHandlers = [ }, ), - //팀피드 공지 스레드 생성 + //팀피드 공지 채팅 생성 rest.post( '/api/team-place/:teamPlaceId/feed/notice', async (req, res, ctx) => { diff --git a/frontend/src/pages/CreatePage/CreatePage.styled.ts b/frontend/src/pages/CreatePage/CreatePage.styled.ts index e7d5b0c51..2e34e1ae5 100644 --- a/frontend/src/pages/CreatePage/CreatePage.styled.ts +++ b/frontend/src/pages/CreatePage/CreatePage.styled.ts @@ -8,15 +8,25 @@ export const Container = styled.div` height: 100vh; `; -export const MainContainer = styled.main` +export const MainContainer = styled.main<{ $isMobile: boolean }>` display: flex; - justify-content: flex-end; align-items: center; overflow-x: hidden; width: 100%; height: 100%; - padding-right: 120px; + + ${({ $isMobile }) => { + if ($isMobile) + return css` + justify-content: center; + `; + + return css` + justify-content: flex-end; + padding-right: 120px; + `; + }} `; export const InnerContainer = styled.div` @@ -83,7 +93,7 @@ export const inputTitle = css` border: none; border-radius: 14px; - background-color: transparent; + background-color: ${({ theme }) => theme.color.WHITE}; font-size: 24px; `; diff --git a/frontend/src/pages/CreatePage/CreatePage.tsx b/frontend/src/pages/CreatePage/CreatePage.tsx index 56891eb8c..2c75fde09 100644 --- a/frontend/src/pages/CreatePage/CreatePage.tsx +++ b/frontend/src/pages/CreatePage/CreatePage.tsx @@ -8,9 +8,11 @@ import IntroCardPile from '~/components/landing/IntroCardPile/IntroCardPile'; import LandingHeader from '~/components/common/LandingHeader/LandingHeader'; import BackButton from '~/components/common/BackButton/BackButton'; import { PATH_NAME } from '~/constants/routes'; +import { getIsMobile } from '~/utils/getIsMobile'; const CreatePage = () => { const inputRef = useRef(null); + const isMobile = getIsMobile(); const { teamName, @@ -20,7 +22,7 @@ const CreatePage = () => { return ( - + 팀 개설하기 @@ -51,7 +53,7 @@ const CreatePage = () => { - + {!isMobile && } ); diff --git a/frontend/src/pages/Error404Page/Error404Page.tsx b/frontend/src/pages/Error404Page/Error404Page.tsx index 181ca4feb..7d61557b4 100644 --- a/frontend/src/pages/Error404Page/Error404Page.tsx +++ b/frontend/src/pages/Error404Page/Error404Page.tsx @@ -4,10 +4,12 @@ import { PATH_NAME } from '~/constants/routes'; import LandingHeader from '~/components/common/LandingHeader/LandingHeader'; import Error404 from '~/components/common/Error404/Error404'; import { useToken } from '~/hooks/useToken'; +import { getIsMobile } from '~/utils/getIsMobile'; const Error404Page = () => { const [isLoggedIn, setIsLoggedIn] = useState(true); const { accessToken } = useToken(); + const isMobile = getIsMobile(); useEffect(() => { const isLoggedIn = Boolean(accessToken); @@ -18,7 +20,13 @@ const Error404Page = () => { return ( diff --git a/frontend/src/pages/JoinPage/JoinPage.styled.tsx b/frontend/src/pages/JoinPage/JoinPage.styled.ts similarity index 87% rename from frontend/src/pages/JoinPage/JoinPage.styled.tsx rename to frontend/src/pages/JoinPage/JoinPage.styled.ts index 78c16306e..2f6d19d8f 100644 --- a/frontend/src/pages/JoinPage/JoinPage.styled.tsx +++ b/frontend/src/pages/JoinPage/JoinPage.styled.ts @@ -8,15 +8,25 @@ export const Container = styled.div` height: 100vh; `; -export const MainContainer = styled.main` +export const MainContainer = styled.main<{ $isMobile: boolean }>` display: flex; - justify-content: flex-end; align-items: center; overflow-x: hidden; width: 100%; height: 100%; - padding-right: 120px; + + ${({ $isMobile }) => { + if ($isMobile) + return css` + justify-content: center; + `; + + return css` + justify-content: flex-end; + padding-right: 120px; + `; + }} `; export const InnerContainer = styled.div<{ $isLinkClicked: boolean }>` @@ -104,7 +114,7 @@ export const inputTitle = css` border: none; border-radius: 14px; - background-color: transparent; + background-color: ${({ theme }) => theme.color.WHITE}; font-size: 24px; `; diff --git a/frontend/src/pages/JoinPage/JoinPage.tsx b/frontend/src/pages/JoinPage/JoinPage.tsx index e4dbf5b1e..dd9529978 100644 --- a/frontend/src/pages/JoinPage/JoinPage.tsx +++ b/frontend/src/pages/JoinPage/JoinPage.tsx @@ -9,10 +9,12 @@ import { useTeamJoin } from '~/hooks/team/useTeamJoin'; import IntroCardPile from '~/components/landing/IntroCardPile/IntroCardPile'; import LandingHeader from '~/components/common/LandingHeader/LandingHeader'; import BackButton from '~/components/common/BackButton/BackButton'; +import { getIsMobile } from '~/utils/getIsMobile'; const JoinPage = () => { const ref = useRef(null); const inputRef = useRef(null); + const isMobile = getIsMobile(); const navigate = useNavigate(); const { @@ -41,7 +43,7 @@ const JoinPage = () => { return ( - + 팀 참가하기 @@ -93,7 +95,7 @@ const JoinPage = () => { - + {!isMobile && } ); }; diff --git a/frontend/src/pages/StartPage/StartPage.styled.ts b/frontend/src/pages/StartPage/StartPage.styled.ts index 83cd0a84e..eb25f7620 100644 --- a/frontend/src/pages/StartPage/StartPage.styled.ts +++ b/frontend/src/pages/StartPage/StartPage.styled.ts @@ -8,15 +8,25 @@ export const Container = styled.div` height: 100vh; `; -export const MainContainer = styled.main` +export const MainContainer = styled.main<{ $isMobile: boolean }>` display: flex; - justify-content: flex-end; align-items: center; overflow-x: hidden; width: 100%; height: 100%; - padding-right: 120px; + + ${({ $isMobile }) => { + if ($isMobile) + return css` + justify-content: center; + `; + + return css` + justify-content: flex-end; + padding-right: 120px; + `; + }} `; export const InnerContainer = styled.div<{ diff --git a/frontend/src/pages/StartPage/StartPage.tsx b/frontend/src/pages/StartPage/StartPage.tsx index abed2e09b..316bd7755 100644 --- a/frontend/src/pages/StartPage/StartPage.tsx +++ b/frontend/src/pages/StartPage/StartPage.tsx @@ -8,12 +8,14 @@ import { START_TYPE } from '~/constants/team'; import IntroCardPile from '~/components/landing/IntroCardPile/IntroCardPile'; import LandingHeader from '~/components/common/LandingHeader/LandingHeader'; import BackButton from '~/components/common/BackButton/BackButton'; +import { getIsMobile } from '~/utils/getIsMobile'; type StartType = (typeof START_TYPE)[keyof typeof START_TYPE]; const StartPage = () => { const navigate = useNavigate(); const location = useLocation(); + const isMobile = getIsMobile(); const previousPath = location.state?.from?.pathname; const isShowBackButton = previousPath?.includes(PATH_NAME.TEAM_SELECT); @@ -40,7 +42,7 @@ const StartPage = () => { return ( - + @@ -71,7 +73,7 @@ const StartPage = () => { {isShowBackButton && } - + {!isMobile && } ); }; diff --git a/frontend/src/pages/TeamCalendarPage/TeamCalendarPage.tsx b/frontend/src/pages/TeamCalendarPage/TeamCalendarPage.tsx index 5065aad79..dd7ed5346 100644 --- a/frontend/src/pages/TeamCalendarPage/TeamCalendarPage.tsx +++ b/frontend/src/pages/TeamCalendarPage/TeamCalendarPage.tsx @@ -1,10 +1,13 @@ import TeamCalendar from '~/components/team_calendar/TeamCalendar/TeamCalendar'; import * as S from './TeamCalendarPage.styled'; +import { getIsMobile } from '~/utils/getIsMobile'; const TeamCalendarPage = () => { + const isMobile = getIsMobile(); + return ( - + ); }; diff --git a/frontend/src/pages/TeamFeedPage/TeamFeedPage.styled.ts b/frontend/src/pages/TeamFeedPage/TeamFeedPage.styled.ts index 97e7143fd..c5ede931b 100644 --- a/frontend/src/pages/TeamFeedPage/TeamFeedPage.styled.ts +++ b/frontend/src/pages/TeamFeedPage/TeamFeedPage.styled.ts @@ -1,12 +1,12 @@ import { css, styled } from 'styled-components'; -export const Container = styled.div` +export const Container = styled.div<{ $isMobile: boolean }>` overflow: hidden; position: relative; width: 100%; height: 100%; - padding: 20px 30px 30px; + padding: ${({ $isMobile }) => ($isMobile ? 0 : '20px 30px 30px')}; background-color: ${({ theme }) => theme.color.GRAY100}; @@ -64,14 +64,14 @@ export const Textarea = styled.textarea` } `; -export const ButtonContainer = styled.div` +export const ButtonContainer = styled.div<{ $isMobile: boolean }>` display: flex; align-items: center; justify-content: space-between; padding: 0 20px; - border-radius: 0 0 20px 20px; + border-radius: ${({ $isMobile }) => ($isMobile ? 0 : '0 0 20px 20px')}; background-color: ${({ theme }) => theme.color.WHITE}; & > div { diff --git a/frontend/src/pages/TeamFeedPage/TeamFeedPage.tsx b/frontend/src/pages/TeamFeedPage/TeamFeedPage.tsx index daea52647..dce38e14d 100644 --- a/frontend/src/pages/TeamFeedPage/TeamFeedPage.tsx +++ b/frontend/src/pages/TeamFeedPage/TeamFeedPage.tsx @@ -14,6 +14,8 @@ import * as S from './TeamFeedPage.styled'; import { useModal } from '~/hooks/useModal'; import { useState } from 'react'; import type { ThreadImage } from '~/types/feed'; +import { useTeamPlace } from '~/hooks/useTeamPlace'; +import { getIsMobile } from '~/utils/getIsMobile'; interface TeamFeedPageProps { threadSize?: ThreadSize; @@ -21,6 +23,7 @@ interface TeamFeedPageProps { const TeamFeedPage = (props: TeamFeedPageProps) => { const { threadSize = 'md' } = props; + const isMobile = getIsMobile(); const { ref, @@ -59,7 +62,7 @@ const TeamFeedPage = (props: TeamFeedPageProps) => { }; return ( - + {noticeThread && noticeThread.id && ( @@ -120,7 +123,7 @@ const TeamFeedPage = (props: TeamFeedPageProps) => { autoFocus readOnly={isSendingImage} /> - +