Skip to content

Commit

Permalink
Merge pull request #25 from Strong-Potato/7-feat-create-detail-page-m…
Browse files Browse the repository at this point in the history
…arkup

7 feat create detail page markup
  • Loading branch information
JeongMin83 authored Jan 6, 2024
2 parents b78c306 + 6401706 commit 39282a8
Show file tree
Hide file tree
Showing 40 changed files with 2,687 additions and 569 deletions.
1,925 changes: 1,363 additions & 562 deletions package-lock.json

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions public/mockServiceWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ self.addEventListener("message", async function (event) {
return client.id !== clientId;
});

// Unregister itself when there are no more clients
if (remainingClients.length === 0) {
self.registration.unregister();
}
Expand All @@ -87,18 +88,25 @@ self.addEventListener("message", async function (event) {
self.addEventListener("fetch", function (event) {
const { request } = event;

// Bypass navigation requests.
if (request.mode === "navigate") {
return;
}

// Opening the DevTools triggers the "only-if-cached" request
// that cannot be handled by the worker. Bypass such requests.
if (request.cache === "only-if-cached" && request.mode !== "same-origin") {
return;
}

// Bypass all requests when there are no active clients.
// Prevents the self-unregistered worked from handling requests
// after it's been deleted (still remains active until the next reload).
if (activeClientIds.size === 0) {
return;
}

// Generate unique request ID.
const requestId = crypto.randomUUID();
event.respondWith(handleRequest(event, requestId));
});
Expand All @@ -107,6 +115,9 @@ async function handleRequest(event, requestId) {
const client = await resolveMainClient(event);
const response = await getResponse(event, client, requestId);

// Send back the response clone for the "response:*" life-cycle events.
// Ensure MSW is active and ready to handle the message, otherwise
// this message will pend indefinitely.
if (client && activeClientIds.has(client.id)) {
(async function () {
const responseClone = response.clone();
Expand All @@ -133,6 +144,10 @@ async function handleRequest(event, requestId) {
return response;
}

// Resolve the main client for the given event.
// Client that issues a request doesn't necessarily equal the client
// that registered the worker. It's with the latter the worker should
// communicate with during the response resolving phase.
async function resolveMainClient(event) {
const client = await self.clients.get(event.clientId);

Expand All @@ -146,39 +161,55 @@ async function resolveMainClient(event) {

return allClients
.filter((client) => {
// Get only those clients that are currently visible.
return client.visibilityState === "visible";
})
.find((client) => {
// Find the client ID that's recorded in the
// set of clients that have registered the worker.
return activeClientIds.has(client.id);
});
}

async function getResponse(event, client, requestId) {
const { request } = event;

// Clone the request because it might've been already used
// (i.e. its body has been read and sent to the client).
const requestClone = request.clone();

function passthrough() {
const headers = Object.fromEntries(requestClone.headers.entries());

// Remove internal MSW request header so the passthrough request
// complies with any potential CORS preflight checks on the server.
// Some servers forbid unknown request headers.
delete headers["x-msw-intention"];

return fetch(requestClone, { headers });
}

// Bypass mocking when the client is not active.
if (!client) {
return passthrough();
}

// Bypass initial page load requests (i.e. static assets).
// The absence of the immediate/parent client in the map of the active clients
// means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
// and is not ready to handle requests.
if (!activeClientIds.has(client.id)) {
return passthrough();
}

// Bypass requests with the explicit bypass header.
// Such requests can be issued by "ctx.fetch()".
const mswIntention = request.headers.get("x-msw-intention");
if (["bypass", "passthrough"].includes(mswIntention)) {
return passthrough();
}

// Notify the client that a request has been intercepted.
const requestBuffer = await request.arrayBuffer();
const clientMessage = await sendToClient(
client,
Expand Down Expand Up @@ -237,6 +268,10 @@ function sendToClient(client, message, transferrables = []) {
}

async function respondWithMock(response) {
// Setting response status code to 0 is a no-op.
// However, when responding with a "Response.error()", the produced Response
// instance will have status code set to 0. Since it's not possible to create
// a Response instance with status code 0, handle that use-case separately.
if (response.status === 0) {
return Response.error();
}
Expand Down
29 changes: 29 additions & 0 deletions src/components/Detail/BottomFixedBtn/BottomFixedBtn.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
@use "@/sass" as *;

.container {
position: fixed;
bottom: 24px;
padding: 0 24px;

width: 100%;
max-width: 45rem;
z-index: 5;

&__wrapper {
display: flex;
justify-content: center;
align-items: center;

width: 100%;
height: 4.8rem;

border-radius: 1.6rem;

cursor: pointer;

span {
color: $neutral0;
@include typography(button);
}
}
}
18 changes: 18 additions & 0 deletions src/components/Detail/BottomFixedBtn/BottomFixedBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import styles from "./BottomFixedBtn.module.scss";

function BottomFixedBtn() {
return (
<div className={styles.container}>
<div
className={styles.container__wrapper}
style={{
backgroundColor: "#2388FF",
}}
>
<span>이 장소 후보로 등록하기</span>
</div>
</div>
);
}

export default BottomFixedBtn;
9 changes: 9 additions & 0 deletions src/components/Detail/Contents/Contents.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@use "@/sass" as *;

.container {
margin-top: 12px;
padding-bottom: 40px;
&__tab {
@include typography(button);
}
}
46 changes: 46 additions & 0 deletions src/components/Detail/Contents/Contents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Tab, TabList, TabPanel, TabPanels, Tabs } from "@chakra-ui/react";

import styles from "./Contents.module.scss";

import Information from "./Information/Information";
import Reviews from "./Reviews/Reviews";

function Contents() {
return (
<Tabs isFitted className={styles.container}>
<TabList>
<Tab
fontSize="1.4rem"
fontWeight="700"
lineHeight="2.2rem"
color="#CDCFD0"
borderColor="#fff"
_selected={{ color: "#1D2433", borderColor: "#2388FF" }}
>
상품정보
</Tab>
<Tab
fontSize="1.4rem"
fontWeight="700"
lineHeight="2.2rem"
color="#CDCFD0"
borderColor="#fff"
_selected={{ color: "#1D2433", borderColor: "#2388FF" }}
>
리뷰
</Tab>
</TabList>

<TabPanels>
<TabPanel padding="0">
<Information />
</TabPanel>
<TabPanel padding="0">
<Reviews />
</TabPanel>
</TabPanels>
</Tabs>
);
}

export default Contents;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@use "@/sass" as *;

.container {
margin: 20px 0;
padding-bottom: 40px;

border-bottom: 12px solid $neutral100;

&__title {
padding: 8px 20px;
margin-bottom: 16px;

@include typography(titleMedium);
}

&__contents {
margin-top: 16px;
padding: 0 20px;

display: flex;
flex-direction: column;
gap: 12px;

&__item {
display: flex;
align-items: center;
gap: 12px;

@include typography(tabLabel);

a {
text-decoration-line: underline;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { AiOutlineLink } from "react-icons/ai";
import { FaRegClock } from "react-icons/fa";
import { IoMdCall } from "react-icons/io";
import { MdPlace } from "react-icons/md";

import styles from "./BasicInformation.module.scss";

import Map from "./Map/Map";

function BasicInformation() {
return (
<div className={styles.container}>
<div className={styles.container__title}>기본정보</div>
<Map />
<div className={styles.container__contents}>
<div className={styles.container__contents__item}>
<MdPlace color="#979C9E" fontSize="2.4rem" />
<span>경기도 양평군 양평읍 백안리 9 </span>
</div>
<div className={styles.container__contents__item}>
<IoMdCall color="#979C9E" fontSize="2.4rem" />
<a href="#">031-771-1234</a>
</div>
<div className={styles.container__contents__item}>
<AiOutlineLink color="#979C9E" fontSize="2.4rem" />
<a href="#">공식 홈페이지 바로가기 </a>
</div>
<div className={styles.container__contents__item}>
{/* 시계 아이콘 다름 */}
<FaRegClock color="#979C9E" fontSize="2.4rem" />
<span>매일 09:00~18:00</span>
</div>
</div>
</div>
);
}

export default BasicInformation;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.container {
width: 100%;
height: 149px;

display: flex;
justify-content: center;
align-items: center;

background-color: #efefef;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import styles from "./Map.module.scss";

function Map() {
return <div className={styles.container}>지도</div>;
}

export default Map;
Empty file.
15 changes: 15 additions & 0 deletions src/components/Detail/Contents/Information/Information.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import BasicInformation from "./BasicInformation/BasicInformation";
import Others from "./Others/Others";
import ShortReviews from "./ShortReveiws/ShortReviews";

function Information() {
return (
<div>
<BasicInformation />
<ShortReviews />
<Others />
</div>
);
}

export default Information;
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@use "@/sass" as *;

.container {
display: flex;
flex-direction: column;
gap: 8px;

cursor: pointer;

&__image {
width: 14.4rem;
height: 14.4rem;
border-radius: 1.6rem;
}

&__contents {
h4 {
@include typography(titleSmall);
}

p {
color: $neutral400;
@include typography(captionSmall);
}

&__reviews {
display: flex;
align-items: center;

&__star {
display: inline;
font-size: 1.6rem;
color: $etc0;
}

&__point {
color: #1d2433;
@include typography(captionSmall);
margin-right: 4px;
}

&__reviewsCount {
color: $neutral400;
@include typography(captionSmall);
}
}
}
}
Loading

0 comments on commit 39282a8

Please sign in to comment.