Skip to content

Commit

Permalink
Merge pull request #11 from coconut-thisABLE/refactor/detail/add-detail
Browse files Browse the repository at this point in the history
Refactor/detail/add detail
  • Loading branch information
seohyun319 authored Nov 20, 2022
2 parents 876eca6 + 7311160 commit e8f4556
Show file tree
Hide file tree
Showing 12 changed files with 390 additions and 31 deletions.
63 changes: 63 additions & 0 deletions components/common/FacilitiesIcons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import Image from 'next/image'
import styled from '@emotion/styled'
import { PlaceInfoType } from '../../types'

type FacilitiesIconsType = {
place: PlaceInfoType
size: number
hasDescription?: boolean
}

type IconImageType = {
src: string
description: string
}

// 시설 정보 아이콘 뷰
const FacilitiesIcons = ({
place,
size,
hasDescription = false,
}: FacilitiesIconsType) => {
const IconImage = ({ src, description }: IconImageType) => (
<IconWrapper hasDescription={hasDescription}>
<Image src={src} width={size} height={size} alt={description} />
{hasDescription && <DescriptionText>{description}</DescriptionText>}
</IconWrapper>
)

return (
<IconsSection>
{place.isToiletExists && (
<IconImage src="/images/toilet.svg" description="장애인 화장실" />
)}
{place.isChargerExists && (
<IconImage src="/images/charger.svg" description="휠체어 충전기" />
)}
{place.isElevatorExists && (
<IconImage src="/images/elevator.svg" description="엘리베이터" />
)}
{place.isSlopeExists && (
<IconImage src="/images/slope.svg" description="슬로프" />
)}
</IconsSection>
)
}

const IconsSection = styled.section`
display: flex;
margin-top: 0.5rem;
justify-content: flex-end;
`
const IconWrapper = styled.div<{ hasDescription: boolean }>`
margin: 0 ${({ hasDescription }) => (hasDescription ? 0.4 : 0.1)}rem;
display: flex;
flex-direction: column;
align-items: center;
`
const DescriptionText = styled.div`
margin-top: 0.4rem;
font-size: 0.7rem;
`

export default FacilitiesIcons
32 changes: 8 additions & 24 deletions components/common/PlaceInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import Image from 'next/image'
import Link from 'next/link'
import styled from '@emotion/styled'
import { PlaceInfoType } from '../../types'
import { conceptColors } from './BaseLayout'
import Text from './Text'
import FacilitiesIcons from './FacilitiesIcons'

const PlaceInfo = ({ place }: { place: PlaceInfoType }) => {
const IconImage = ({ src }: { src: string }) => (
<IconWrapper>
<Image src={src} width={30} height={30} />
</IconWrapper>
)

return (
<Link href={`detail/${place._id}`}>
<PlaceInfoContainer>
Expand All @@ -29,20 +23,16 @@ const PlaceInfo = ({ place }: { place: PlaceInfoType }) => {
<Text color="#b0b0b0" size={0.8}>
{place.address}
</Text>
<IconsSection>
{place.isToiletExists && <IconImage src="/images/toilet.svg" />}
{place.isChargerExists && <IconImage src="/images/charger.svg" />}
{place.isElevatorExists && <IconImage src="/images/elevator.svg" />}
{place.isSlopeExists && <IconImage src="/images/slope.svg" />}
</IconsSection>
<FacilitiesIcons place={place} size={30} />
</PlaceInfoContainer>
</Link>
)
}

const PlaceInfoContainer = styled.div`
margin: 0.2rem;
div {
div,
p {
margin-bottom: 0.2rem;
}
`
Expand All @@ -55,17 +45,11 @@ const NameTypeSection = styled.section`
display: flex;
flex-wrap: wrap;
align-items: center;
div:last-child {
margin-left: 0.4rem;
p:first-of-type {
margin-right: 0.4rem;
}
`
const IconsSection = styled.section`
display: flex;
margin-top: 0.5rem;
justify-content: flex-end;
`
const IconWrapper = styled.div`
margin: 0 0.1rem;
`

export { NameTypeSection }

export default PlaceInfo
4 changes: 3 additions & 1 deletion components/common/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ const Text = ({ children, color, size = 1, bold }: TextType) => {
)
}

const StyledText = styled.div<TextType>`
export const StyledText = styled.p<TextType>`
color: ${({ color }) => color};
font-size: ${({ size }) => size}rem;
font-weight: ${({ bold }) => bold && 'bold'};
margin-block-start: 0;
margin-block-end: 0;
`

export default Text
54 changes: 54 additions & 0 deletions components/common/ToggleView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { useState } from 'react'
import { styled } from '@mui/material/styles'
import MuiAccordion, { AccordionProps } from '@mui/material/Accordion'
import AccordionDetails from '@mui/material/AccordionDetails'
import MuiAccordionSummary, {
AccordionSummaryProps,
} from '@mui/material/AccordionSummary'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'

type ToggleViewType = {
children: React.ReactNode
title: string
}

const ToggleView = ({ children, title }: ToggleViewType) => {
const [isExpanded, setIsExpanded] = useState<boolean>(false)

return (
<Accordion
expanded={isExpanded}
onChange={() => setIsExpanded(!isExpanded)}
>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
{title}
</AccordionSummary>
<AccordionDetails>{children}</AccordionDetails>
</Accordion>
)
}

const Accordion = styled((props: AccordionProps) => (
<MuiAccordion disableGutters elevation={0} {...props} />
))(() => ({
border: 'none',
}))

const AccordionSummary = styled((props: AccordionSummaryProps) => (
<MuiAccordionSummary {...props} />
))(() => ({
flexDirection: 'row-reverse',
minHeight: '0px',
'& .MuiAccordionSummary-expandIconWrapper': {
transform: 'rotate(-90deg)',
},
'& .MuiAccordionSummary-expandIconWrapper.Mui-expanded': {
transform: 'rotate(0deg)',
},
'& .MuiAccordionSummary-content': {
margin: '0.4rem',
flexGrow: 'inherit',
},
}))

export default ToggleView
74 changes: 74 additions & 0 deletions components/detail/ChargerInfoToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import styled from '@emotion/styled'
import { chargerDetail } from '../../data'
import Text from '../common/Text'
import ToggleView from '../common/ToggleView'

const ChargerInfoToggle = () => {
const charger = chargerDetail.data

type ChargerInfoType = {
title: string
data: string
}

const ChargerInfoList: ChargerInfoType[] = [
{
title: '설치 장소',
data: charger.instllcdesc,
},
{
title: '공기 주입 가능',
data: charger.airinjectoryn,
},
{
title: '휴대전화 충전',
data: charger.moblphonchrstnyn,
},
{ title: '동시 사용 가능 대수', data: charger.smtmuseco },
{
title: '평일 운영 시간',
data: `${charger.weekdayoperopenhhmm} ~ ${charger.weekdayopercolsehhmm}`,
},
{
title: '토요일 운영 시간',
data: `${charger.satoperoperopenhhmm} ~ ${charger.satoperclosehhmm}`,
},
{
title: '공휴일 운영 시간',
data: `${charger.holidayoperopenhhmm} ~ ${charger.holidaycloseopenhhmm}`,
},
{ title: '시설명', data: charger.fcltynm },
{ title: '관리기관명', data: charger.institutionnm },
{ title: '관리기관 번호', data: charger.institutionphonenumber },
{ title: '데이터 기준 일자', data: charger.referencedate },
]

return (
<ChargerInfoToggleSection>
<ToggleView title="휠체어 충전기 세부 정보 보기">
{ChargerInfoList.map((chargerInfo: ChargerInfoType, index: number) => (
<ChargerInfoWrapper key={index}>
<Text bold>{chargerInfo.title}</Text>
<ChargerDataText>{chargerInfo.data}</ChargerDataText>
</ChargerInfoWrapper>
))}
</ToggleView>
</ChargerInfoToggleSection>
)
}

const ChargerInfoToggleSection = styled.section`
display: flex;
justify-content: center;
margin: 1rem 0;
`
const ChargerInfoWrapper = styled.div`
display: flex;
justify-content: space-between;
margin: 0.1rem;
`
const ChargerDataText = styled.div`
margin-left: 3rem;
`

export default ChargerInfoToggle
64 changes: 64 additions & 0 deletions components/detail/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import Link from 'next/link'
import styled from '@emotion/styled'
import { placeDetail, reviewAverageCount } from '../../data'
import { PlaceInfoType } from '../../types'
import FacilitiesIcons from '../common/FacilitiesIcons'
import { NameTypeSection } from '../common/PlaceInfo'
import Text, { StyledText } from '../common/Text'
import ChargerInfoToggle from './ChargerInfoToggle'

const Detail = () => {
const place: PlaceInfoType = placeDetail.response
// TODO: 동적 id와 실데이터 연결

return (
<DetailContainer>
<Link href={`/`}>◀ 뒤로 가기</Link>
{/* TODO: 모바일 환경에서는 /list (리스트로 가기) */}
<DetailInfoSection>
<NameTypeSection>
<Text size={1.2} bold>
{place.name}
</Text>
<Text color="#00B8E0" size={0.8}>
{place.locationType}
</Text>
</NameTypeSection>
<AddressText color="#b0b0b0" size={0.8}>
{place.address}
</AddressText>
{reviewAverageCount && (
<ReviewAverageCountSection>
{reviewAverageCount.average}
<Text>
(리뷰 <b>{reviewAverageCount.count}</b>
개)
</Text>
</ReviewAverageCountSection>
)}
<FacilitiesIcons place={place} size={50} hasDescription />
</DetailInfoSection>
<ChargerInfoToggle />
{/* <ReviewPage locationId={id} /> */}
</DetailContainer>
)
}

const DetailContainer = styled.article`
margin-top: 0.4rem;
`
const DetailInfoSection = styled.section`
display: flex;
flex-direction: column;
align-items: center;
margin: 0.4rem 0;
`
const AddressText = styled(StyledText)`
margin-top: 0.4rem;
`
const ReviewAverageCountSection = styled.section`
display: flex;
margin: 1rem 0;
`

export default Detail
Loading

0 comments on commit e8f4556

Please sign in to comment.