Skip to content

Commit

Permalink
feat: card-view / list-view toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
FourwingsY committed Nov 22, 2024
1 parent 5647a54 commit fe12080
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 5 deletions.
15 changes: 15 additions & 0 deletions app/icons/CardView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
interface IconProps {
size?: number
color?: string
}
export default function CardView({ size = 32, color = "white" }: IconProps) {
return (
<svg width={size} height={size} viewBox="0 0 64 64" fill="none">
<g stroke={color}>
<rect x="7" y="7" width="50" height="12" rx="3" stroke="black" strokeWidth="4" />
<rect x="7" y="26" width="50" height="12" rx="3" stroke="black" strokeWidth="4" />
<rect x="7" y="45" width="50" height="12" rx="3" stroke="black" strokeWidth="4" />
</g>
</svg>
)
}
20 changes: 20 additions & 0 deletions app/icons/ListView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
interface IconProps {
size?: number
color?: string
}
export default function ListView({ size = 32, color = "white" }: IconProps) {
return (
<svg width={size} height={size} viewBox="0 0 64 64" fill="none">
<g fill={color}>
<rect x="17" y="10" width="39" height="5" />
<rect x="17" y="23" width="39" height="5" />
<rect x="17" y="36" width="39" height="5" />
<rect x="17" y="49" width="39" height="5" />
<circle cx="10.5" cy="12.5" r="3.5" />
<circle cx="10.5" cy="25.5" r="3.5" />
<circle cx="10.5" cy="38.5" r="3.5" />
<circle cx="10.5" cy="51.5" r="3.5" />
</g>
</svg>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default function BuildingDetailSheet({ building: initialData, questId, vi
return (
<RightSheet visible={visible} close={close} title={title} style={{ width: "360px" }}>
{sortedPlaces.map((place) => (
<PlaceCard place={place} questId={questId} key={place.placeId} />
<PlaceCard place={place} questId={questId} key={place.placeId} view="card" />
))}
</RightSheet>
)
Expand Down
14 changes: 12 additions & 2 deletions app/modals/BuildingDetailSheet/BuildingDetailSheet.mobile.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { BasicModalProps } from "@reactleaf/modal"
import { useQueryClient } from "@tanstack/react-query"
import { useAtom } from "jotai"
import { useEffect, useMemo } from "react"
import { useEffect, useMemo, useState } from "react"

import { useQuestBuilding } from "@/lib/apis/api"
import { AppState } from "@/lib/globalAtoms"
import { QuestBuilding, QuestPlace } from "@/lib/models/quest"

import CardView from "@/icons/CardView"
import ListView from "@/icons/ListView"
import Reload from "@/icons/Reload"
import BottomSheet from "@/modals/_template/BottomSheet"

Expand All @@ -22,6 +24,7 @@ export const defaultOverlayOptions = { closeDelay: 200, dim: false }
export default function BuildingDetailSheet({ building: initialData, questId, visible, close }: Props) {
const { data: building } = useQuestBuilding({ questId, buildingId: initialData.buildingId })
const [appState, setAppState] = useAtom(AppState)
const [view, setView] = useState<"list" | "card">("card")
const queryClient = useQueryClient()

useEffect(() => {
Expand All @@ -45,6 +48,10 @@ export default function BuildingDetailSheet({ building: initialData, questId, vi
return [...notConquered, ...conquered].map((p) => building.places.find((b) => b.placeId === p.placeId) || p)
}, [initialData, building])

function toggleView() {
setView((prev) => (prev === "card" ? "list" : "card"))
}

if (!building) return null

const conquered = building.places.filter(isConquered)
Expand All @@ -54,6 +61,9 @@ export default function BuildingDetailSheet({ building: initialData, questId, vi
<small>
정복 완료 {conquered.length} / {building.places.length}
</small>
<S.ViewToggle onClick={toggleView}>
{view === "card" ? <ListView size={24} color="#666" /> : <CardView size={24} color="#666" />}
</S.ViewToggle>
<S.ReloadButton onClick={reloadQuest}>
<Reload size={24} />
</S.ReloadButton>
Expand All @@ -63,7 +73,7 @@ export default function BuildingDetailSheet({ building: initialData, questId, vi
return (
<BottomSheet visible={visible} close={close} title={title} style={{ height: "calc(100vh - 300px)" }}>
{sortedPlaces.map((place) => (
<PlaceCard place={place} questId={questId} key={place.placeId} />
<PlaceCard place={place} questId={questId} key={place.placeId} view={view} />
))}
</BottomSheet>
)
Expand Down
16 changes: 16 additions & 0 deletions app/modals/BuildingDetailSheet/BuildingDetailSheet.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,19 @@ export const ReloadButton = styled("button", {
},
},
})

export const ViewToggle = styled("button", {
base: {
position: "absolute",
top: "50%",
right: 60,
transform: "translateY(-50%)",
padding: 4,
backgroundColor: "transparent",
border: "none",
cursor: "pointer",
"&:hover": {
backgroundColor: "rgba(0, 0, 0, 0.1)",
},
},
})
2 changes: 1 addition & 1 deletion app/modals/BuildingDetailSheet/PlaceCard.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const NotAccessible = styled(ActionButton, {

export const ConquerButton = styled(ActionButton, {
base: {
background: "var(--leaf-primary-60)",
background: "var(--leaf-primary-90)",
color: "white",
},
})
Expand Down
32 changes: 31 additions & 1 deletion app/modals/BuildingDetailSheet/PlaceCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import * as S from "./PlaceCard.style"
interface Props {
place: QuestPlace
questId: string
view: "card" | "list"
onUpdate?: (place: QuestPlace) => void
}
export default function PlaceCard({ place, questId, onUpdate }: Props) {
export default function PlaceCard({ place, questId, view, onUpdate }: Props) {
const [isClosed, setClosed] = useState(place.isClosed)
const [isNotAccessible, setNotAccessible] = useState(place.isNotAccessible)
const visited = place.isConquered || isClosed || isNotAccessible
Expand Down Expand Up @@ -77,6 +78,35 @@ export default function PlaceCard({ place, questId, onUpdate }: Props) {
}
}

if (view === "list") {
return (
<S.PlaceCard style={{ margin: 0, padding: "4px 20px", boxShadow: "none" }}>
<S.Header>
<S.PlaceName>
{place.name}
{place.isConquered && <S.PlaceStatusBadge status="good">정복</S.PlaceStatusBadge>}
{!place.isConquered && !isClosed && place.isClosedExpected && (
<S.PlaceStatusBadge status="warn">폐업추정</S.PlaceStatusBadge>
)}
{isClosed && <S.PlaceStatusBadge status="bad">폐업확인</S.PlaceStatusBadge>}
{isNotAccessible && <S.PlaceStatusBadge status="bad">접근불가</S.PlaceStatusBadge>}
</S.PlaceName>
<S.Buttons>
<S.Button onClick={openNaverMap}>
<Image src={naverMapIcon} alt="네이버 지도" style={{ width: 32, height: 32 }} />
</S.Button>
<S.Button onClick={copyPlaceName}>
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="11" y="5" width="16" height="16" rx="4" stroke="#777" stroke-width="2" />
<rect x="5" y="11" width="16" height="16" rx="4" fill="white" stroke="#777" stroke-width="2" />
</svg>
</S.Button>
</S.Buttons>
</S.Header>
</S.PlaceCard>
)
}

return (
<S.PlaceCard>
<S.Header>
Expand Down

0 comments on commit fe12080

Please sign in to comment.