Skip to content

Commit

Permalink
Merge pull request #87 from softeerbootcamp4th/feature/13-fcfs
Browse files Browse the repository at this point in the history
[feat, fix, refactor] 선착순 안내 경품 섹션 추가, 각종 버그 수정
  • Loading branch information
darkdulgi authored Aug 12, 2024
2 parents 0fb43db + 5f60e08 commit 0636436
Show file tree
Hide file tree
Showing 54 changed files with 554 additions and 373 deletions.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added public/images/fcfs_prize1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/fcfs_prize2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/fcfs_prize3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/fcfs_prize4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/fcfs_prize5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/interactionBackdrop.webp
Binary file not shown.
32 changes: 18 additions & 14 deletions src/comment/autoScrollCarousel/useAutoCarousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ function useAutoCarousel(speed = 1) {
const [isControlled, setIsControlled] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const timestamp = useRef(null);
const dragging = useRef(false);
const prevDragState = useRef({ x: 0, mouseX: 0, prevMouseX: 0 });
const momentum = useRef(speed);
const raf = useRef(null);
Expand Down Expand Up @@ -55,10 +54,20 @@ function useAutoCarousel(speed = 1) {
};
}, [isControlled, animate]);

// 드래그 시작 함수
const onDragStart = useCallback(
({ x }) => {
setIsControlled(true);
setIsHovered(true);
prevDragState.current.x = position;
prevDragState.current.mouseX = x;
prevDragState.current.prevMouseX = x;
},
[position],
);

// 드래그 도중 함수
const onDrag = useCallback(({ x: mouseX }) => {
if (!dragging.current) return;

// 새로운 포지션 계산
let newPos =
prevDragState.current.x - mouseX + prevDragState.current.mouseX;
Expand All @@ -75,13 +84,15 @@ function useAutoCarousel(speed = 1) {

// 드래그 종료 함수
const onDragEnd = useCallback((e) => {
if (!dragging.current) return;
dragging.current = false;
setIsControlled(false);
if (e.pointerType === "touch") setIsHovered(false);
}, []);

useMountDragEvent(onDrag, onDragEnd);
const { onPointerDown } = useMountDragEvent({
onDragStart,
onDrag,
onDragEnd,
});

return {
position,
Expand All @@ -93,14 +104,7 @@ function useAutoCarousel(speed = 1) {
onMouseLeave() {
setIsHovered(false);
},
onPointerDown(e) {
setIsControlled(true);
setIsHovered(true);
dragging.current = true;
prevDragState.current.x = position;
prevDragState.current.mouseX = e.clientX;
prevDragState.current.prevMouseX = e.clientX;
},
onPointerDown,
},
};
}
Expand Down
1 change: 1 addition & 0 deletions src/comment/commentForm/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ function CommentForm() {
setButtonFetchState("error");
})
.finally(() => {
setErrorMessage("");
clearTimeout(timeout);
});

Expand Down
2 changes: 1 addition & 1 deletion src/comment/mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const handlers = [
const token = request.headers.get("authorization");

if (token === null) return HttpResponse.json({ submitted: false });
return HttpResponse.json({ submitted: true });
return HttpResponse.json({ submitted: false });
}),
];

Expand Down
46 changes: 35 additions & 11 deletions src/common/Button.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,48 @@
function getButtonStyle(styleType, backdrop, isSubmit) {
switch (`${backdrop}-${styleType}`) {
case "light-ghost":
return `bg-white text-black shadow-[0_0_0_2px_inset_currentColor]
active:bg-neutral-50 active:text-neutral-400
hover:bg-neutral-50
disabled:text-neutral-200 ${isSubmit ? "group-[:invalid]:text-neutral-200" : ""}`;
case "dark-filled":
return `bg-white text-black
active:bg-blue-800
hover:bg-blue-400
disabled:bg-neutral-500
${isSubmit ? "group-[:invalid]:bg-neutral-500" : ""}`;
case "dark-ghost":
return `text-white shadow-[0_0_0_2px_inset_currentColor]
active:text-blue-800
hover:bg-blue-900 hover:text-blue-400
disabled:text-neutral-500 ${isSubmit ? "group-[:invalid]:text-neutral-500" : ""}`;
case "light-filled":
default:
return `bg-black text-white
active:bg-neutral-700 active:text-neutral-200
hover:bg-neutral-700
disabled:bg-neutral-600 disabled:text-neutral-400
${isSubmit ? "group-[:invalid]:bg-neutral-600 group-[:invalid]:text-neutral-400" : ""}`;
}
}

function Button({
styleType,
children,
type = "button",
className,
backdrop = "light",
className = "",
...otherProps
}) {
const isSubmit = !(type === "reset" || type === "button");

const filledStyle = `bg-black text-white active:bg-neutral-700 active:text-neutral-200
hover:bg-neutral-700 disabled:bg-neutral-600 disabled:text-neutral-400
${isSubmit ? "group-[:invalid]:bg-neutral-600 group-[:invalid]:text-neutral-400" : ""}`;

const ghostStyle = `bg-white text-black shadow-[0_0_0_2px_inset_currentColor]
active:bg-neutral-50 active:text-neutral-400 hover:bg-neutral-50
disabled:text-neutral-200 ${isSubmit ? "group-[:invalid]:text-neutral-200" : ""}`;

const defaultStyle = `px-6 py-4 text-body-m font-bold text-center
const defaultPadding = /([\s:]+p[tblrxyse]?-|^p[tblrxyse]?-)/.test(className)
? ""
: "px-6 py-4";
const defaultStyle = `${defaultPadding} text-body-m font-bold text-center
disabled:cursor-default ${isSubmit ? "group-[:invalid]:cursor-default" : ""}`;

const typedStyle = styleType === "filled" ? filledStyle : ghostStyle;
const typedStyle = getButtonStyle(styleType, backdrop, isSubmit);
return (
<button
className={`${defaultStyle} ${typedStyle} ${className}`}
Expand Down
15 changes: 15 additions & 0 deletions src/common/ResetButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Button from "./Button.jsx";
import RefreshIcon from "./assets/refresh.svg?react";

export default function ResetButton({ onClick }) {
return (
<Button
onClick={onClick}
styleType="ghost"
backdrop="dark"
className="p-1 xl:p-2"
>
<RefreshIcon />
</Button>
);
}
2 changes: 1 addition & 1 deletion public/icons/refresh.svg → src/common/assets/refresh.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export const TOKEN_ID = "AWESOME_ORANGE_ACCESS_TOKEN";

// scroll section constants
export const INTERACTION_SECTION = 1;
export const DETAIL_SECTION = 2;
export const COMMENT_SECTION = 3;
export const FCFS_SECTION = 4;
55 changes: 42 additions & 13 deletions src/common/useMountDragEvent.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,62 @@
import { useEffect } from "react";
import { useState, useRef, useEffect, useCallback } from "react";
import throttleRaf from "@/common/throttleRaf.js";

function useMountDragEvent(dragging, dragEnd) {
function useMountDragEvent({
onDragStart: userDragStart,
onDrag,
onDragEnd: userDragEnd,
} = {}) {
const [dragState, setDragState] = useState(false);
const isDragging = useRef(false);

useEffect(() => {
const onPointerMove = throttleRaf((e) => {
if (e.pointerType === "touch") return;
if (!isDragging.current) return;
const { clientX, clientY } = e;
dragging({ x: clientX, y: clientY });
onDrag({ x: clientX, y: clientY });
});
const onTouchMove = throttleRaf((e) => {
const { clientX, clientY } = e.touches[0];
dragging({ x: clientX, y: clientY });
if (!isDragging.current) return;
onDrag({ x: clientX, y: clientY });
});
const onDragEnd = (e) => {
if (!isDragging.current) return;
isDragging.current = false;
setDragState(false);
userDragEnd?.(e);
};

window.addEventListener("pointermove", onPointerMove);
window.addEventListener("pointerup", dragEnd);
window.addEventListener("pointercancel", dragEnd);
window.addEventListener("pointerup", onDragEnd);
window.addEventListener("pointercancel", onDragEnd);
window.addEventListener("touchmove", onTouchMove);
window.addEventListener("touchend", dragEnd);
window.addEventListener("touchcancel", dragEnd);
window.addEventListener("touchend", onDragEnd);
window.addEventListener("touchcancel", onDragEnd);
return () => {
window.removeEventListener("pointermove", onPointerMove);
window.removeEventListener("pointerup", dragEnd);
window.removeEventListener("pointercancel", dragEnd);
window.removeEventListener("pointerup", onDragEnd);
window.removeEventListener("pointercancel", onDragEnd);
window.removeEventListener("touchmove", onTouchMove);
window.removeEventListener("touchend", dragEnd);
window.removeEventListener("touchcancel", dragEnd);
window.removeEventListener("touchend", onDragEnd);
window.removeEventListener("touchcancel", onDragEnd);
};
}, [dragging, dragEnd]);
}, [onDrag, userDragEnd]);

const onPointerDown = useCallback(
(e) => {
isDragging.current = true;
setDragState(true);
userDragStart?.({ x: e.clientX, y: e.clientY });
},
[userDragStart],
);

return {
onPointerDown,
dragState,
};
}

export default useMountDragEvent;
10 changes: 5 additions & 5 deletions src/detailInformation/content.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@
{
"title": "485km\n주행거리에 여유를 더하다",
"description": "더 뉴 아이오닉 5는 84.0kWh의 4세대 배터리 셀을 탑재하여 보다 여유있는 장거리 주행이 가능합니다.\n4세대 배터리 셀은 기존 모델(77.4kWh)과 비교해 배터리 용량이 개선되었고, 에너지 밀도도 670Wh/L로 높아졌습니다.\n새로워진 배터리 셀과 함께 더 뉴 아이오닉 5는 1회 충전으로 최대 485km까지 주행할 수 있습니다.",
"img": "/detail_distance.png",
"img": "/images/detail_distance.png",
"tabName": "주행거리"
},
{
"title": "690만원\n전기차 보조금과 함께 경제적으로",
"description": "더 뉴 아이오닉 5의 뛰어난 성능과 합리적인 가격으로 최대 690만원의 국비 보조금을 혜택을 누릴 수 있습니다.\n에너지 밀도와 재활용 가치가 높은 4세대 배터리를 탑재하여 성능보조금 100%를 지원 받을 수 있으며\n더 뉴 아이오닉 5만의 혁신적인 기술과 충전 인프라로 추가적인 경제적 혜택을 제공받을 수 있습니다.",
"img": "/detail_money.png",
"img": "/images/detail_money.png",
"tabName": "보조금"
},
{
"title": "V2L\n언제 어디서나 편리하게",
"description": "더 뉴 아이오닉 5는 차량 외부로 전력을 공급할 수 있는 V2L 기능을 통해 새로운 전동화 경험을 제공합니다.\n야외활동 시 여러가지 외부환경에서도 다양한 전자기기 사용이 가능합니다.\n또한 2열 시트 하단의 실내 V2L을 사용하여 차량 내부에서도 배터리 걱정 없는 전자기기 사용이 가능합니다.",
"img": "/detail_V2L.png",
"img": "/images/detail_V2L.png",
"tabName": "V2L"
},
{
"title": "18분\n초급속 충전 경험을 선사하다",
"description": "더 뉴 아이오닉 5는 350kW 급속 충전기 사용 시 18분 이내에 배터리 용량의 10%에서 80%까지 충전이 가능합니다.\n배터리 용량이 늘어났음에도 기존과 동일하거나 더 빠른 속도로 차량을 충전할 수 있습니다.\n또한 다양한 EV 충전 솔루션과 충전 서비스를 통해 차별화된 충전 경험을 제공합니다.",
"img": "/detail_electric.png",
"img": "/images/detail_electric.png",
"tabName": "충전시간"
},
{
"title": "유니버설 아일랜드\n실내공간을 자유자재로",
"description": "더 뉴 아이오닉 5는 유니버설 아일랜드를 적용해 다양한 상황에 맞는 최적화된 공간 활용성을 제공합니다.\n기존 모델과 달리 더 뉴 아이오닉 5에서는 자주 사용하는 기능을 버튼식으로 배치했으며,\n스마트폰 무선 충전 패드도 상단으로 옮겨 사용 편의성을 높였습니다.",
"img": "/detail_univasal.png",
"img": "/images/detail_univasal.png",
"tabName": "실내공간"
}
]
15 changes: 15 additions & 0 deletions src/eventDescription/EventDescriptionLayout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import EventDetail from "./EventDetail.jsx";

function EventDescriptionLayout({ detail, children }) {
return (
<div className="w-full md:w-[640px] lg:w-full max-w-[1200px] flex flex-col justify-between lg:flex-row gap-16 lg:gap-10 xl:gap-16">
<EventDetail {...detail} />
<div className="flex flex-col gap-10 w-full lg:w-1/2 lg:max-w-[510px]">
<h4 className="text-body-l font-bold text-white">경품 안내</h4>
{children}
</div>
</div>
);
}

export default EventDescriptionLayout;
43 changes: 20 additions & 23 deletions src/eventDescription/EventDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ export default function EventDetail({
howto,
}) {
return (
<div className="flex flex-col">
<span className="text-body-l pb-10 text-neutral-50 font-bold">
상세 안내
</span>
<div className="flex flex-col flex-grow gap-10">
<h4 className="text-body-l text-neutral-50 font-bold">상세 안내</h4>

<div className="flex gap-5">
<div className="grid grid-cols-1 md:grid-cols-[11fr 9fr] gap-5">
<div className="bg-neutral-900 p-6 flex flex-col font-bold">
<span className="text-body-m text-neutral-300">이벤트 기간</span>

Expand All @@ -28,30 +26,29 @@ export default function EventDetail({
</span>

<span className="pt-6 text-body-l text-white font-bold">
{makeHighlight(announceDate, "font-normal text-neutral-300")}
{makeHighlight(announceDate, "font-medium text-neutral-300")}
</span>

<span className="pt-2 text-body-s text-neutral-300">
{announceDateCaption}
</span>
</div>
</div>

<div className="mt-5 p-6 bg-neutral-900 flex flex-col font-bold">
<span className="pb-6 text-body-m text-neutral-300">참여방법</span>

<ul className="flex flex-col gap-2">
{howto.map((description, index) => (
<li key={`howTo-${index}`} className="flex gap-2">
<span className="size-6 flex justify-center items-center bg-neutral-100 text-neutral-900 text-body-s px-2 py-0.5 rounded flex-shrink-0">
{index + 1}
</span>
<p className="text-neutral-400 text-body-m">
{makeHighlight(description, "text-white")}
</p>
</li>
))}
</ul>
<div className="md:col-span-2 p-6 bg-neutral-900 flex flex-col font-bold">
<span className="pb-6 text-body-m text-neutral-300">참여방법</span>

<ul className="flex flex-col gap-2">
{howto.map((description, index) => (
<li key={`howTo-${index}`} className="flex gap-2">
<span className="size-6 flex justify-center items-center bg-neutral-100 text-neutral-900 text-body-s px-2 py-0.5 rounded flex-shrink-0">
{index + 1}
</span>
<p className="text-neutral-400 text-body-m">
{makeHighlight(description, "text-white")}
</p>
</li>
))}
</ul>
</div>
</div>
</div>
);
Expand Down
12 changes: 0 additions & 12 deletions src/fcfs/FcfsDescription.jsx

This file was deleted.

Loading

0 comments on commit 0636436

Please sign in to comment.