Skip to content

Commit

Permalink
Merge pull request #71 from softeerbootcamp4th/feature/main-event
Browse files Browse the repository at this point in the history
[Feature] main event 라우팅, 타이머, ref 오류 수정
  • Loading branch information
leve68 authored Aug 14, 2024
2 parents 89a1808 + 027de0f commit 7423cc7
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/components/common/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const Button = ({
onClick={onClick}
disabled={!isEnabled}
>
<p className="font-kia-signature-bold text-title-4">
<p className="whitespace-pre font-kia-signature-bold text-title-4">
{isEnabled ? defaultText : disabledText}
</p>
{isEnabled && (
Expand Down
34 changes: 18 additions & 16 deletions src/hooks/useAnimation.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useRef } from "react";

interface UseAnimationProps {
export interface UseAnimationProps {
startKeyframes: Keyframe[];
cancelKeyframes?: Keyframe[];
afterStartKeyframes?: Keyframe[];
Expand Down Expand Up @@ -52,25 +52,27 @@ const useAnimation = <T extends Element>({
const animationRef = useRef<Animation | null>(null);

const startAnimation = async () => {
if (elementRef.current) {
animationRef.current = elementRef.current.animate(
startKeyframes,
startOptions,
);
if (animationRef.current && afterStartKeyframes && elementRef.current) {
await animationRef.current.finished;
elementRef.current.animate(afterStartKeyframes, afterStartOptions);
}
const element = elementRef.current;
if (!element) return;

const animation = element.animate(startKeyframes, startOptions);
animationRef.current = animation;

if (afterStartKeyframes.length > 0) {
await animation.finished;
element.animate(afterStartKeyframes, afterStartOptions);
}
};

const stopAnimation = () => {
if (animationRef.current && elementRef.current) {
animationRef.current = elementRef.current.animate(
cancelKeyframes,
cancelOptions ?? startOptions,
);
}
const element = elementRef.current;
const animation = animationRef.current;
if (!element || !animation) return;

animationRef.current = element.animate(
cancelKeyframes,
cancelOptions ?? startOptions,
);
};

return { elementRef, animationRef, startAnimation, stopAnimation };
Expand Down
11 changes: 7 additions & 4 deletions src/pages/mainPage/InfoScreen/InfoScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { ForwardedRef, forwardRef } from "react";
import OutsideSection from "./OutsideSection";
import InsideSection from "./InsideSection";
import VideoSection from "./VideoSection";
Expand All @@ -7,9 +7,12 @@ import ConvenienceSection from "./ConvenienceSection";
import ColorSection from "./ColorSection";
import PerformanceSection from "./PerformanceSection";

const InfoScreen = () => {
const InfoScreen = (
props: React.HTMLProps<HTMLDivElement>,
ref: ForwardedRef<HTMLDivElement>,
) => {
return (
<div>
<div ref={ref}>
<VideoSection />
<OutsideSection />
<InsideSection />
Expand All @@ -21,4 +24,4 @@ const InfoScreen = () => {
);
};

export default InfoScreen;
export default forwardRef(InfoScreen);
2 changes: 1 addition & 1 deletion src/pages/mainPage/InfoScreen/VideoSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const VideoSection = () => {
</video>
<div
ref={textRef}
className={`absolute top-[100vh] z-10 h-screen w-screen snap-start flex-col gap-500 bg-black/50 flex-center ${isShown ? "opacity-100" : "opacity-0"} transition-opacity duration-1000`}
className={`absolute top-[100vh] z-10 h-screen w-screen snap-start snap-always flex-col gap-500 bg-black/50 flex-center ${isShown ? "opacity-100" : "opacity-0"} transition-opacity duration-1000`}
>
<div className="font-kia-signature-bold text-8xl text-gray-100">
The 2025 Seltos
Expand Down
8 changes: 5 additions & 3 deletions src/pages/mainPage/MainPage.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React from "react";
import React, { useRef } from "react";
import NavigationBar from "./NavigationBar/NavigationBar";
import MainScreen from "./MainScreen/MainScreen";
import NotificationScreen from "./NotificationScreen/NotificationScreen";
import InfoScreen from "./InfoScreen/InfoScreen";

const MainPage = () => {
const infoRef = useRef<HTMLDivElement>(null);

return (
<div className="h-screen w-screen snap-y snap-mandatory overflow-scroll scroll-auto">
<MainScreen />
<InfoScreen />
<MainScreen ref={infoRef} />
<InfoScreen ref={infoRef} />
<NotificationScreen />
<NavigationBar />
</div>
Expand Down
38 changes: 25 additions & 13 deletions src/pages/mainPage/MainScreen/FCFSEventSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ForwardedRef, forwardRef } from "react";
import React, { ForwardedRef, forwardRef, useState } from "react";
import Timer from "./Timer";
import EventHeader from "../../../components/mainPage/MainScreen/EventHeader";
import Button from "../../../components/common/Button/Button";
Expand All @@ -9,31 +9,37 @@ import {
FCFS_PERIOD_INFO,
FCFS_TIPS,
} from "../../../constants/EventData";
import { useNavigate } from "react-router";
import { useAppContext } from "../../../providers/AppProvider";

interface FCFSEventSectionProps {
isVisible: boolean;
onInfoClick: () => void;
}

const FCFSEventSection = (
{ isVisible }: FCFSEventSectionProps,
{ isVisible, onInfoClick }: FCFSEventSectionProps,
ref: ForwardedRef<HTMLDivElement>,
) => {
const navigate = useNavigate();
const { isAuth, isFCFSEnd } = useAppContext();

return (
<div
className={`h-screen w-screen snap-start flex-col transition-all duration-200 flex-center ${!isVisible && "opacity-0"}`}
className={`relative flex h-screen w-screen snap-start snap-always flex-col items-center justify-around transition-all duration-200 ${!isVisible && "opacity-0"}`}
ref={ref}
>
<img
src={e1Gift}
alt="Event"
className="pointer-events-none absolute z-10 h-[5.75rem] w-[3.375rem] translate-x-[16rem] translate-y-20"
/>
<EventHeader
title={FCFS_EVENT_DATA.TITLE}
description={FCFS_EVENT_DATA.DESCRIPTION}
/>
<div className="flex h-[30rem] flex-col justify-between">
<div className="flex min-h-[30rem] flex-1 flex-col items-end justify-between">
<Timer />
<img
src={e1Gift}
alt="Event"
className="pointer-events-none z-10 h-[5.75rem] w-[3.375rem] -translate-y-12 translate-x-60"
/>
</div>
<div className="h-[16.375rem] gap-4 text-gray-50 flex-center">
<div className="flex h-full w-[26.5rem] flex-col gap-4 text-body-1-regular">
Expand Down Expand Up @@ -72,7 +78,10 @@ const FCFSEventSection = (
{tip.TEXT}
</div>
{tip.BUTTON_TEXT && (
<button className="text-body-2-regular text-gray-200">
<button
className="text-body-2-regular text-gray-200"
onClick={onInfoClick}
>
{tip.BUTTON_TEXT}
</button>
)}
Expand All @@ -81,10 +90,13 @@ const FCFSEventSection = (
</div>
</div>
<Button
onClick={() => {}}
onClick={() => {
isAuth ? navigate("event1") : navigate("auth-modal");
}}
size="big"
isEnabled={true}
defaultText="참여하기"
isEnabled={!isFCFSEnd}
defaultText={isAuth ? "퀴즈풀기" : "본인인증하고\n참여하기"}
disabledText={"이벤트가 마감되었습니다.\n다음 이벤트를 참여해주세요"}
/>
</div>
</div>
Expand Down
24 changes: 21 additions & 3 deletions src/pages/mainPage/MainScreen/MainScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import React, { useEffect, useRef, useState } from "react";
import React, {
ForwardedRef,
forwardRef,
useEffect,
useRef,
useState,
} from "react";
import EventSelectSection from "./EventSelectSection";
import GlowBackground from "../../../components/common/GlowBackground/GlowBackground";
import FCFSEventSection from "./FCFSEventSection";
import RandomEventSection from "./RandomEventSection";
import mainCar from "../../../assets/images/mainCar.png";

const MainScreen = () => {
const MainScreen = (
props: React.HTMLProps<HTMLDivElement>,
ref: ForwardedRef<HTMLDivElement>,
) => {
const FCFSRef = useRef<HTMLDivElement>(null);
const RandomRef = useRef<HTMLDivElement>(null);
const SectionRef = useRef<HTMLDivElement>(null);
Expand All @@ -16,6 +25,14 @@ const MainScreen = () => {
random: false,
});

const onInfoClick = () => {
if (ref) {
(ref as React.RefObject<HTMLDivElement>).current?.scrollIntoView({
behavior: "smooth",
});
}
};

const onFCFSClick = () => {
FCFSRef.current?.scrollIntoView({ behavior: "smooth" });
};
Expand Down Expand Up @@ -114,6 +131,7 @@ const MainScreen = () => {
<FCFSEventSection
ref={FCFSRef}
isVisible={isSectionVisible.fcfs}
onInfoClick={onInfoClick}
></FCFSEventSection>
<RandomEventSection
ref={RandomRef}
Expand All @@ -124,4 +142,4 @@ const MainScreen = () => {
);
};

export default MainScreen;
export default forwardRef(MainScreen);
8 changes: 6 additions & 2 deletions src/pages/mainPage/MainScreen/RandomEventSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
RANDOM_PRIZE_INFO,
RANDOM_STEPS,
} from "../../../constants/EventData";
import { useNavigate } from "react-router";

interface RandomEventSectionProps {
isVisible: boolean;
Expand All @@ -20,10 +21,11 @@ const RandomEventSection = (
ref: ForwardedRef<HTMLDivElement>,
) => {
const images = [e2Gift1, e2Gift2, e2Gift3];
const navigate = useNavigate();

return (
<div
className={`h-screen w-screen snap-start flex-col transition-all duration-200 flex-center ${!isVisible && "opacity-0"}`}
className={`flex h-screen w-screen snap-start snap-always flex-col items-center justify-around transition-all duration-200 ${!isVisible && "opacity-0"}`}
ref={ref}
>
<EventHeader
Expand Down Expand Up @@ -81,7 +83,9 @@ const RandomEventSection = (
</div>

<Button
onClick={() => {}}
onClick={() => {
navigate("event2/0");
}}
size="big"
isEnabled={true}
defaultText="참여하기"
Expand Down
33 changes: 32 additions & 1 deletion src/pages/mainPage/MainScreen/Timer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
import React from "react";

const Timer = () => {
return <div>Timer</div>;
return (
<div className="relative h-[13rem] w-[54rem] flex-center">
<div className="relative h-full w-full overflow-hidden rounded-full">
<div
className="absolute inset-0"
style={{
background:
"linear-gradient(93.7deg, #505861 0%, #4B7C83 33.5%, #1B3F72 66.5%, #F2F2F2 100%)",
WebkitBackgroundClip: "border-box",
backgroundClip: "border-box",
padding: "1px",
}}
>
<div className="relative h-full w-full rounded-full bg-gray-950 flex-center">
{/* 타이머 텍스트 */}
<span
className="text-[8rem]"
style={{
backgroundImage:
"linear-gradient(93.7deg, #505861 0%, #4B7C83 33.5%, #1B3F72 66.5%, #F2F2F2 100%)",
WebkitBackgroundClip: "text",
backgroundClip: "text",
color: "transparent",
}}
>
00:00:00
</span>
</div>
</div>
</div>
</div>
);
};

export default Timer;

0 comments on commit 7423cc7

Please sign in to comment.