Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

메인페이지 구현 #11

Merged
merged 13 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 124 additions & 92 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

Binary file added src/assets/MesloLGS-NF-Bold.ttf
Binary file not shown.
20 changes: 20 additions & 0 deletions src/components/display/ButtonList.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import styled from "styled-components";

export const ButtonListContainer = styled.div`
display: flex;
flex-direction: column;
gap: 1.5rem;
padding: 1.5rem;

border: 1px solid #d4d2e3;
border-radius: 24px;

button {
}

button > div {
display: flex;
align-items: center;
justify-content: center;
}
`;
60 changes: 60 additions & 0 deletions src/components/display/ButtonList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { FaRegBell } from "react-icons/fa";
import { GoPeople } from "react-icons/go";
import { IoMapOutline } from "react-icons/io5";
import { LuCalendarDays } from "react-icons/lu";
import { PiMicrophoneStage } from "react-icons/pi";
import { useNavigate } from "react-router-dom";

import { Button } from "@/components/forms/Button";
import { Text } from "@/components/typography/Text";

import { ButtonListContainer } from "./ButtonList.styled";

export const ButtonList = () => {
const navigate = useNavigate();

return (
<ButtonListContainer>
<Button width="auto" variant="purple" onClick={() => navigate("/booth")}>
<div>
<IoMapOutline size={22} style={{ marginRight: "10px" }} />
<Text size="m" weight="bold" variant="white">
부스 별 지도
</Text>
</div>
</Button>
<Button width="auto" variant="purple" onClick={() => navigate("/guests")}>
<div>
<PiMicrophoneStage size={22} style={{ marginRight: "10px" }} />
<Text size="m" weight="bold" variant="white">
Special Guest
</Text>
</div>
</Button>
<Button width="auto" variant="purple" onClick={() => navigate("/timetable")}>
<div>
<LuCalendarDays size={22} style={{ marginRight: "10px" }} />
<Text size="m" weight="bold" variant="white">
이벤트 일정
</Text>
</div>
</Button>
<Button width="auto" variant="purple" onClick={() => navigate("/contributors")}>
<div>
<GoPeople size={22} style={{ marginRight: "10px" }} />
<Text size="m" weight="bold" variant="white">
만든이들
</Text>
</div>
</Button>
<Button width="auto" variant="red" onClick={() => window.open("https://instagram.com/knu_ch", "_blank")}>
<div>
<FaRegBell size={22} style={{ marginRight: "10px" }} />
<Text size="m" weight="bold" variant="white">
총학 Hotline
</Text>
</div>
</Button>
</ButtonListContainer>
);
};
19 changes: 19 additions & 0 deletions src/components/display/Countdown.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import styled from "styled-components";

export const CountdownContainer = styled.div`
display: flex;
flex-direction: column;

font-family: "MesloLGS NF Bold", monospace;
font-size: 2rem;
color: #333;
text-align: center;
padding: 30px 60px;

span {
margin-bottom: 1rem;
}

border: 1px solid #d4d2e3;
border-radius: 24px;
`;
40 changes: 40 additions & 0 deletions src/components/display/Countdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Text } from "@/components/typography/Text";

import { useCountdown } from "@/hooks/useCountdown";

import { CountdownContainer } from "./Countdown.styled";

interface ICountdown {
targetDate: Date;
}

export const Countdown: React.FC<ICountdown> = ({ targetDate }) => {
const displayTime = useCountdown(targetDate);

const dateOptions: Intl.DateTimeFormatOptions = {
year: "numeric",
month: "2-digit",
day: "2-digit",
};
const timeOptions: Intl.DateTimeFormatOptions = {
hour: "2-digit",
minute: "2-digit",

hour12: false,
};

return (
<CountdownContainer>
<Text size="l" weight="bold" variant="darkpurple">
축제까지 남은 시간
</Text>
<Text size="xl" weight="bold" variant="lightpurple">
{displayTime}
</Text>
<Text size="m" weight="normal" variant="darkpurple">
UTC+9 | {targetDate.toLocaleDateString("ko-KR", dateOptions)}{" "}
{targetDate.toLocaleTimeString("en-US", timeOptions)}
</Text>
</CountdownContainer>
);
};
1 change: 1 addition & 0 deletions src/components/forms/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const Button = styled.button<IButton>`

border: none;
border-radius: 40px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);

color: #fff;
background-color: ${(props) => {
Expand Down
31 changes: 24 additions & 7 deletions src/components/layout/Footer.styled.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
import styled from "styled-components";

export const FooterContainer = styled.footer`
background-color: #b0b0b0;
color: white;
text-align: center;
width: 100%;
padding: 0;
font-size: 0.75rem;
border-radius: 10px 10px 0 0;
padding: 20px 0;

box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
bottom: 0;
`;

export const TopBorder = styled.div`
height: 1px;
background-color: #d0d0d0;
width: 70%;
margin: 0 auto 20px;
`;

export const Logo = styled.img`
width: 100px;
height: auto;
`;

export const EventName = styled.h3`
margin: 30px 0;
`;

export const LegalLinks = styled.div``;

export const LegalText = styled.p`
margin: 0 0 10px 0;
`;
37 changes: 35 additions & 2 deletions src/components/layout/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,44 @@
import React from "react";

import { FooterContainer } from "@/components/layout/Footer.styled";
import { FooterContainer, Logo, EventName, LegalLinks, TopBorder, LegalText } from "@/components/layout/Footer.styled";
import { Text } from "@/components/typography/Text";

import logo from "@/assets/hapuruna.png";

const Footer: React.FC = () => {
return (
<FooterContainer>
<p>© 2024 LikeLion KNU. All rights reserved.</p>
<TopBorder />
<Logo src={logo} alt="Event Logo" />
<EventName>
<Text size="l" weight="normal" variant="purple">
2024 경북대학교 대동제
</Text>
</EventName>
<LegalLinks>
<LegalText>
<Text size="s" weight="normal" variant="lightpurple">
© 2024 LikeLion
</Text>
<Text size="xs" weight="normal" variant="purple">
&nbsp;|&nbsp;
</Text>
<Text size="s" weight="normal" variant="lightpurple">
All Rights Reserved
</Text>
</LegalText>
<LegalText>
<Text size="xs" weight="normal" variant="lightpurple">
Terms and Conditions
</Text>
<Text size="xs" weight="normal" variant="purple">
&nbsp;|&nbsp;
</Text>
<Text size="xs" weight="normal" variant="lightpurple">
Privacy Policy
</Text>
</LegalText>
</LegalLinks>
</FooterContainer>
);
};
Expand Down
6 changes: 3 additions & 3 deletions src/components/navigation/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ const Navigation: React.FC = () => {
</NavHeader>
<motion.ul initial="closed" animate={show ? "open" : "closed"} variants={listVariants}>
<NavItem variants={itemVariants}>
<NavLink href="#">공지사항</NavLink>
<NavLink href="#">부스 별 지도</NavLink>
</NavItem>
<NavItem variants={itemVariants}>
<NavLink href="#">공연 타임테이블</NavLink>
<NavLink href="#">Special Guest</NavLink>
</NavItem>
<NavItem variants={itemVariants}>
<NavLink href="#">부스 정보</NavLink>
<NavLink href="#">이벤트 일정</NavLink>
</NavItem>
<NavItem variants={itemVariants}>
<NavLink href="#">만든이들</NavLink>
Expand Down
14 changes: 14 additions & 0 deletions src/components/typography/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import styled from "styled-components";
export interface IText {
size: "xs" | "s" | "m" | "l" | "xl" | string;
weight: "bold" | "normal";
variant?: "darkpurple" | "purple" | "white" | "lightpurple";
}

export const Text = styled.span<IText>`
Expand All @@ -24,4 +25,17 @@ export const Text = styled.span<IText>`
return props.size;
}
}};

color: ${(props) => {
switch (props.variant) {
case "darkpurple":
return "#5d5a88";
case "purple":
return "#767494";
case "lightpurple":
return "#adabc3";
case "white":
return "#ffffff";
}
}};
`;
36 changes: 36 additions & 0 deletions src/hooks/useCountdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useState, useEffect } from "react";

const formatTime = (time: number): string => {
return time < 10 ? `0${time}` : time.toString();
};

const calculateTimeLeft = (targetDate: Date) => {
const difference = +targetDate - +new Date();
let timeLeft: Record<string, number> = {};

if (difference > 0) {
timeLeft = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60),
};
}

return timeLeft;
};

export const useCountdown = (targetDate: Date) => {
const [timeLeft, setTimeLeft] = useState<Record<string, number>>(calculateTimeLeft(targetDate));

useEffect(() => {
const timer = setTimeout(() => {
setTimeLeft(calculateTimeLeft(targetDate));
}, 1000);

return () => clearTimeout(timer);
});

const formattedTime = `${formatTime(timeLeft.days * 24 + timeLeft.hours)}:${formatTime(timeLeft.minutes)}:${formatTime(timeLeft.seconds)}`;
return formattedTime;
};
28 changes: 24 additions & 4 deletions src/pages/HomePage.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import styled from "styled-components";

export const PageContainer = styled.div`
width: 100%;
min-height: 100vh;
background-color: white;
display: flex;
flex-direction: column;
Expand All @@ -19,8 +18,29 @@ export const MainContent = styled.div`
position: relative;
`;

export const StyledImage = styled.img`
export const StyledImage = styled.div`
position: relative;
width: 100%;
height: 100%;
object-fit: cover;
height: auto;

img {
width: 100%;
height: auto;
}

button {
position: absolute;
top: 85%;
left: 50%;
transform: translate(-50%, -50%);
}
`;

export const ElementContainer = styled.div`
width: 450px;
margin: 2rem;

div {
margin: 1rem 0;
}
`;
Loading
Loading