Skip to content

Commit

Permalink
feat: 레이아웃 변경 (#448)
Browse files Browse the repository at this point in the history
* chore: Navbar 숨김에 petDetail, timeline 추가

* chore: 반려 식물 상세 전역 Suspense 사용

* refactor: 뒤로가기 헤더 컴포넌트로 추출

* refactor: BackHeader 적용

* design: 색 transition 추가, user-select none 추가

* chore: BackButton width 추가

* feat: BackHeader 추가

* design: 모두의 정원에 기록하기 버튼 BottomSheet에 추가

* feat: 원하면 일정 px 높이에서 투명할 수 있도록 변경

* feat: 헤더에 그림자 추가

* refactor: 의존성 추가 및 button type 추가

* test: 펫 등록 테스트 구현

---------

Co-authored-by: hozzijeong <[email protected]>
  • Loading branch information
bassyu and hozzijeong authored Oct 19, 2023
1 parent ec911c3 commit af2eff0
Show file tree
Hide file tree
Showing 14 changed files with 199 additions and 108 deletions.
34 changes: 22 additions & 12 deletions frontend/cypress/e2e/petRegister.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,29 +79,39 @@ describe('반려 식물 등록하기', () => {
.click({ force: true })

.get('button[type="button"]')
.first()
.click({ force: true })
.then(($buttons) => {
cy.wrap($buttons[1]).click({ force: true });
})

.get('li[role="menuitem"]')
.first()
.click({ force: true })
.then(($buttons) => {
cy.wrap($buttons[1]).click({ force: true });
})

.get('button[type="button"]')
.first()
.click({ force: true })
.then(($buttons) => {
cy.wrap($buttons[1]).click({ force: true });
})

.get('li[role="menuitem"]')
.last()
.click({ force: true })

.get('button[type="button"]')
.first()
.click({ force: true })
.then(($buttons) => {
cy.wrap($buttons[1]).click({ force: true });
})

.get('li[role="menuitem"]')
.first()
.click({ force: true })
.then(($buttons) => {
cy.wrap($buttons[1]).click({ force: true });
})

.get('button[type="button"]')
.first()
.click({ force: true })
.then(($buttons) => {
cy.wrap($buttons[1]).click({ force: true });
})

.get('li[role="menuitem"]')
.last()
.click({ force: true })
Expand Down
37 changes: 37 additions & 0 deletions frontend/src/components/@common/BackHeader/BackHeader.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import styled from 'styled-components';

export const Wrapper = styled.header<{ $transparent: boolean }>`
position: fixed;
z-index: ${(props) => props.theme.zIndex.fixed};
top: 0;
display: flex;
align-items: center;
width: 100%;
max-width: ${(props) => props.theme.width.pad};
height: 48px;
padding: 0 16px;
background: ${(props) =>
props.$transparent
? `linear-gradient(rgba(0, 0, 0, 0.4), rgba(255, 255, 255, 0))`
: props.theme.color.background};
box-shadow: 0 2px 2px -2px ${(props) => (props.$transparent ? 'transparent' : props.theme.color.gray)};
`;

export const BackButton = styled.button`
position: absolute;
left: 16px;
display: flex;
align-items: center;
width: 22px;
`;

export const TransparentSensor = styled.div<{ $height: `${string}px` }>`
position: absolute;
top: 0;
height: ${(props) => props.$height};
`;
66 changes: 66 additions & 0 deletions frontend/src/components/@common/BackHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useCallback, type PropsWithChildren } from 'react';
import { createPortal } from 'react-dom';
import { useNavigate } from 'react-router-dom';
import { BackButton, TransparentSensor, Wrapper } from './BackHeader.style';
import useToggle from 'hooks/@common/useToggle';
import theme from 'style/theme.style';
import SvgFill from '../SvgIcons/SvgFill';

interface BackHeaderProps extends PropsWithChildren {
transparentHeight?: number;
}

const BackHeader = (props: BackHeaderProps) => {
const { children, transparentHeight } = props;

const navigate = useNavigate();
const { isOn: isTop, on, off } = useToggle(false);

const goBack = () => {
navigate(-1);
};

const intersectionRef = useCallback(
<T extends Element>(instance: T | null) => {
const onChangeIntersection = (isIntersecting: boolean) => {
if (!transparentHeight) return;

if (isIntersecting) {
on();
} else {
off();
}
};

const observer = new IntersectionObserver((entries) => {
entries.forEach(({ isIntersecting }) => {
onChangeIntersection(isIntersecting);
});
});

if (instance) observer.observe(instance);
},
[off, on, transparentHeight]
);

return (
<>
{createPortal(
<TransparentSensor ref={intersectionRef} $height={`${transparentHeight}px`} />,
document.body
)}
<Wrapper $transparent={isTop}>
<BackButton type="button" onClick={goBack}>
<SvgFill
icon="line-arrow-left"
aria-label="뒤로 가기"
color={isTop ? theme.color.background : theme.color.sub}
/>
</BackButton>
{children}
</Wrapper>
</>
);
};

export default BackHeader;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { styled } from 'styled-components';

export const Wrapper = styled.div`
user-select: none;
input {
display: none;
}
Expand All @@ -23,6 +24,8 @@ export const CheckboxLabel = styled.label`
background-color: ${(props) => props.theme.color.grayLight};
border-radius: 8px;
transition: background-color 0.1s, color 0.1s;
input:checked ~ & {
font-weight: 500;
color: white;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,27 @@ const ButtonLink = styled(Link)`
border-radius: 4px;
`;

export const BottomSheet = styled.div`
position: fixed;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
max-width: ${(props) => props.theme.width.pad};
height: 80px;
padding: 0 32px;
padding-top: 16px;
background-image: linear-gradient(
to bottom,
transparent 0%,
${(props) => props.theme.color.background} 30%
);
`;

export const PrimaryLink = styled(ButtonLink)`
color: ${({ theme }) => theme.color.background};
background: ${(props) => props.theme.color.primary};
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/components/petPlant/PetPlantDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
ButtonArea,
TertiaryButton,
TertiaryLink,
BottomSheet,
} from './PetPlantDetail.style';
import useConfirm from 'hooks/@common/useConfirm';
import useDeletePetPlant from 'hooks/queries/petPlant/useDeletePetPlant';
Expand Down Expand Up @@ -189,13 +190,15 @@ const PetPlantDetail = ({ petPlantId }: PetDetailsProps) => {
삭제하기
</TertiaryButton>
</ButtonArea>
</Content>
<BottomSheet>
<PrimaryLink
to={generatePath(URL_PATH.gardenRegisterForm, { id: petPlantId.toString() })}
state={{ nickname, dictionaryPlantName, imageUrl }}
>
모두의 정원에 기록하기
</PrimaryLink>
</Content>
</BottomSheet>
</Wrapper>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ export const Main = styled.main`
margin: 0 auto 100px auto;
`;

export const BackButton = styled.button`
display: flex;
align-items: center;
`;

export const BottomSheet = styled.div`
position: fixed;
bottom: 0;
Expand Down
16 changes: 3 additions & 13 deletions frontend/src/pages/dictionaryPlant/DictionaryPlantDetail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { generatePath, useNavigate, useParams } from 'react-router-dom';
import { Header } from 'pages/petPlant/PetPlantRegister/Form/Form.style';
import BackHeader from 'components/@common/BackHeader';
import Image from 'components/@common/Image';
import PageLogger from 'components/@common/PageLogger';
import SvgFill from 'components/@common/SvgIcons/SvgFill';
import DictionaryPlantContent from 'components/dictionaryPlant/DictionaryPlantContent';
import { BackButton, BottomSheet, Main, PrimaryButton } from './DictionaryPlantDetail.style';
import { BottomSheet, Main, PrimaryButton } from './DictionaryPlantDetail.style';
import useAddToast from 'hooks/@common/useAddToast';
import useCheckSessionId from 'hooks/queries/auth/useCheckSessionId';
import useDictionaryPlantDetail from 'hooks/queries/dictionaryPlant/useDictionaryPlantDetail';
import { URL_PATH } from 'constants/index';
import theme from 'style/theme.style';

const DictionaryPlantDetail = () => {
const { id } = useParams();
Expand All @@ -24,10 +22,6 @@ const DictionaryPlantDetail = () => {

const navigate = useNavigate();

const goBack = () => {
navigate(-1);
};

const goPetPlantRegisterForm = () => {
navigate(generatePath(URL_PATH.petRegisterForm, { id: String(dictionaryPlantId) }));
};
Expand All @@ -48,11 +42,7 @@ const DictionaryPlantDetail = () => {

return (
<PageLogger>
<Header>
<BackButton onClick={goBack}>
<SvgFill icon="line-arrow-left" aria-label="뒤로 가기" color={theme.color.sub} />
</BackButton>
</Header>
<BackHeader transparentHeight={256} />
<Main>
<Image type="wide" src={image} alt={name} size="300px" />
<DictionaryPlantContent {...dictionaryPlantDetail} />
Expand Down
9 changes: 3 additions & 6 deletions frontend/src/pages/petPlant/PetPlantDetails/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { Suspense } from 'react';
import { useParams } from 'react-router-dom';
import Loading from 'pages/@common/Loading';
import BackHeader from 'components/@common/BackHeader';
import PageLogger from 'components/@common/PageLogger';
import PetPlantDetailContent from 'components/petPlant/PetPlantDetail';

const PetPlantDetails = () => {
const { id } = useParams();

return (
<PageLogger>
<Suspense fallback={<Loading />}>
<PetPlantDetailContent petPlantId={Number(id)} />
</Suspense>
<BackHeader transparentHeight={256} />
<PetPlantDetailContent petPlantId={Number(id)} />
</PageLogger>
);
};
Expand Down
23 changes: 0 additions & 23 deletions frontend/src/pages/petPlant/PetPlantRegister/Form/Form.style.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
import { styled } from 'styled-components';

export const Header = styled.header`
position: fixed;
z-index: ${(props) => props.theme.zIndex.fixed};
top: 0;
display: flex;
align-items: center;
width: 100%;
max-width: ${(props) => props.theme.width.pad};
height: 48px;
padding: 0 16px;
background-color: ${(props) => props.theme.color.background + 'aa'};
backdrop-filter: blur(2px);
box-shadow: 0 2px 2px -2px ${(props) => props.theme.color.gray};
`;

export const BackButton = styled.button`
display: flex;
align-items: center;
`;

export const Main = styled.main`
display: flex;
flex-direction: column;
Expand Down
15 changes: 3 additions & 12 deletions frontend/src/pages/petPlant/PetPlantRegister/Form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useNavigate, useParams } from 'react-router-dom';
import BackHeader from 'components/@common/BackHeader';
import Modal from 'components/@common/Modal';
import PageLogger from 'components/@common/PageLogger';
import SvgFill from 'components/@common/SvgIcons/SvgFill';
import SvgStroke from 'components/@common/SvgIcons/SvgStroke';
import DictionaryPlantContent from 'components/dictionaryPlant/DictionaryPlantContent';
import PetPlantRegisterForm from 'components/petPlant/PetPlantRegisterForm';
import { BackButton, DictionaryPlantButton, DictionaryPlantName, Header, Main } from './Form.style';
import { DictionaryPlantButton, DictionaryPlantName, Main } from './Form.style';
import useModal from 'hooks/@common/useModal';
import useCheckSessionId from 'hooks/queries/auth/useCheckSessionId';
import useDictionaryPlantDetail from 'hooks/queries/dictionaryPlant/useDictionaryPlantDetail';
Expand All @@ -17,23 +17,14 @@ const PetPlantRegisterFormPage = () => {
const dictionaryPlantId = Number(id);

useCheckSessionId();
const navigate = useNavigate();

const { data: dictionaryPlantDetail } = useDictionaryPlantDetail(dictionaryPlantId);
const { name, image } = dictionaryPlantDetail;
const { isOpen, open, close, modalRef } = useModal();

const goBack = () => {
navigate(-1);
};

return (
<PageLogger>
<Header>
<BackButton onClick={goBack}>
<SvgFill icon="line-arrow-left" aria-label="뒤로 가기" color={theme.color.sub} />
</BackButton>
</Header>
<BackHeader />
<Main>
<DictionaryPlantName>{name}</DictionaryPlantName>
<DictionaryPlantButton onClick={open}>
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/pages/petPlant/PetPlantRegister/Search/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { DictionaryPlantNameSearchResult } from 'types/dictionaryPlant';
import { useState } from 'react';
import { generatePath, useNavigate } from 'react-router-dom';
import BackHeader from 'components/@common/BackHeader';
import PageLogger from 'components/@common/PageLogger';
import SearchBox from 'components/search/SearchBox';
import { Main, Message, SearchBoxArea } from './Search.style';
Expand All @@ -19,6 +20,7 @@ const PetPlantRegisterSearch = () => {

return (
<PageLogger>
<BackHeader />
<Main>
<Message>어떤 식물을 키우시나요?</Message>
<SearchBoxArea>
Expand Down
Loading

0 comments on commit af2eff0

Please sign in to comment.