Skip to content

Commit 7def66f

Browse files
authored
Merge pull request #153 from School-of-Company/feat/slogan
feat: slogan 날짜 설정
2 parents 830cbfc + f96020e commit 7def66f

5 files changed

Lines changed: 49 additions & 71 deletions

File tree

src/entities/slogan/lib/formReducer.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { SloganFormValues } from "../model/schema";
22

33
export interface FormState {
44
formValues: SloganFormValues;
5-
isValid: boolean;
65
isSubmitted: boolean;
76
isSubmitting: boolean;
87
sloganLength: number;
@@ -15,7 +14,6 @@ export type FormAction =
1514
| { type: "UPDATE_DESCRIPTION"; value: string; length: number }
1615
| { type: "SET_SUBMITTING"; value: boolean }
1716
| { type: "SET_SUBMITTED"; value: boolean }
18-
| { type: "SET_VALID"; value: boolean }
1917
| { type: "SELECT_SCHOOL"; schoolName: string };
2018

2119
export const initialFormState: FormState = {
@@ -28,7 +26,6 @@ export const initialFormState: FormState = {
2826
classroom: "",
2927
phone_number: "",
3028
},
31-
isValid: false,
3229
isSubmitted: false,
3330
isSubmitting: false,
3431
sloganLength: 0,
@@ -63,8 +60,6 @@ export const formReducer = (state: FormState, action: FormAction): FormState =>
6360
return { ...state, isSubmitting: action.value };
6461
case "SET_SUBMITTED":
6562
return { ...state, isSubmitted: action.value };
66-
case "SET_VALID":
67-
return { ...state, isValid: action.value };
6863
default:
6964
return state;
7065
}

src/entities/slogan/lib/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export interface SloganFormSchoolData {
2020

2121
export interface UseSloganFormReturn {
2222
state: FormState;
23+
isValid: boolean;
2324
handlers: SloganFormHandlers;
2425
schoolData: SloganFormSchoolData;
2526
}

src/entities/slogan/lib/useSloganForm.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useReducer, useCallback, useMemo, useEffect } from "react";
3+
import { useReducer, useCallback, useMemo } from "react";
44
import { formReducer, initialFormState } from "./formReducer";
55
import { sloganSchema, SloganFormValues } from "../model/schema";
66
import { handleSloganFormSubmit } from "./handleSloganFormSubmit";
@@ -13,13 +13,7 @@ const SCHOOL_SEARCH_DELAY = 200;
1313
export const useSloganForm = (): UseSloganFormReturn => {
1414
const [state, dispatch] = useReducer(formReducer, initialFormState);
1515

16-
const isValid = useMemo(() => {
17-
return sloganSchema.safeParse(state.formValues).success;
18-
}, [state.formValues]);
19-
20-
useEffect(() => {
21-
dispatch({ type: "SET_VALID", value: isValid });
22-
}, [isValid]);
16+
const isValid = sloganSchema.safeParse(state.formValues).success;
2317

2418
const normalizedSchoolName = useMemo(
2519
() => state.formValues.school.replace(/\s+/g, ""),
@@ -77,6 +71,7 @@ export const useSloganForm = (): UseSloganFormReturn => {
7771

7872
return {
7973
state,
74+
isValid,
8075
handlers: {
8176
handleSloganChange,
8277
handleDescriptionChange,

src/widgets/main/SloganSecondSection/index.tsx

Lines changed: 43 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,79 @@
11
import React from "react";
2-
// import { useRouter } from "next/navigation";
3-
import PrizeItem from "@/entities/home/ui/PrizeItem";
2+
import { useRouter } from "next/navigation";
3+
// import PrizeItem from "@/entities/home/ui/PrizeItem";
44
import SloganMarquee from "@/entities/home/ui/SloganMarquee";
5-
// import Button from "@/shared/ui/Button";
5+
import Button from "@/shared/ui/Button";
66
import { cn } from "@/shared/utils/cn";
77
import { SectionTitle } from "@/shared/ui/SectionTitle";
8-
// import { formatDate } from "@/shared/utils/formatDate";
8+
import { formatDate } from "@/shared/utils/formatDate";
99

10-
const PRIZES = [
11-
{
12-
rank: "2등",
13-
bg: "bg-gray-400",
14-
emoji: "광주SW마이스터고 2학년 ",
15-
desc: "허O서",
16-
slogan: '"광주의 빛나는, 또 빛날 별들의 향연"',
17-
},
18-
{
19-
rank: "1등",
20-
bg: "bg-yellow-300",
21-
emoji: "전대사대부고 2학년 ",
22-
desc: "김O은",
23-
slogan: '"세상의 무대 위, 광탈페! 너의 꿈이 시작되는 순간!"',
24-
},
25-
{
26-
rank: "3등",
27-
bg: "bg-orange-700",
28-
emoji: "빛고을고 2학년 ",
29-
desc: "최O원",
30-
slogan: '"재능이 피어나는 시간, 가능성이 자라는 무대"',
31-
},
32-
];
10+
const SLOGAN_YEAR = 2026;
3311

34-
// const SLOGAN_START = new Date("2025-05-26T00:00:00+09:00");
35-
// const SLOGAN_END = new Date("2025-05-30T17:59:59+09:00");
12+
const SLOGAN_START = new Date(`${SLOGAN_YEAR}-05-04T00:00:00+09:00`);
13+
const SLOGAN_END = new Date(`${SLOGAN_YEAR}-05-08T17:59:59+09:00`);
3614

3715
const SloganSecondSection = () => {
38-
// const R = useRouter();
16+
const router = useRouter();
3917

40-
// const isSloganPeriod = React.useMemo(() => {
41-
// const now = new Date();
42-
// return now >= SLOGAN_START && now <= SLOGAN_END;
43-
// }, []);
18+
const [isSloganPeriod, setIsSloganPeriod] = React.useState(false);
4419

45-
// const submissionPeriodText = React.useMemo(() => {
46-
// const startText = formatDate(SLOGAN_START);
47-
// const endText = formatDate(SLOGAN_END);
48-
// return `공모기간 : 2025.${startText}~${endText} 18:00까지`;
49-
// }, []);
20+
React.useEffect(() => {
21+
const checkPeriod = () => {
22+
const now = new Date();
23+
setIsSloganPeriod(now >= SLOGAN_START && now <= SLOGAN_END);
24+
};
25+
26+
checkPeriod();
27+
const timer = setInterval(checkPeriod, 60000);
28+
29+
return () => clearInterval(timer);
30+
}, []);
31+
32+
const submissionPeriodText = React.useMemo(() => {
33+
const startText = formatDate(SLOGAN_START);
34+
const endText = formatDate(SLOGAN_END);
35+
return `공모기간 : ${SLOGAN_YEAR}.${startText}~${endText} 18:00까지`;
36+
}, []);
5037

5138
return (
5239
<section id="SloganSecondSection" className={cn("w-full mt-[3.5rem] mobile:mt-20 text-center")}>
5340
<SectionTitle
54-
title="2025 광탈페 슬로건"
41+
title={`${SLOGAN_YEAR} 광탈페 슬로건`}
5542
description={
5643
<>
5744
<span className="text-black text-body2b">
5845
세상의 무대 위, 광탈페! 너의 꿈이 시작되는 순간!
5946
</span>
6047
<span className={cn("block")}>
61-
2025년 모두가 주인공이 되는 광주학생탈렌트페스티벌의 꿈의 무대가 펼쳐집니다.
48+
{SLOGAN_YEAR} 모두가 주인공이 되는 광주학생탈렌트페스티벌의 꿈의 무대가 펼쳐집니다.
6249
</span>
6350
</>
6451
}
6552
/>
6653

6754
<SloganMarquee />
6855

69-
<div className={cn("flex flex-col items-center p-6 bg-white my-30")}>
56+
{/* <div className={cn("flex flex-col items-center p-6 bg-white my-30")}>
7057
<div className={cn("flex justify-center items-center gap-[40px]")}>
7158
<PrizeItem key={PRIZES[1].rank} {...PRIZES[1]} />
7259
<PrizeItem key={PRIZES[0].rank} {...PRIZES[0]} />
7360
<PrizeItem key={PRIZES[2].rank} {...PRIZES[2]} />
7461
</div>
75-
</div>
76-
{/*
77-
<Button
78-
onClick={() => R.push("/slogan")}
79-
className={cn("my-[24px] mobile:mb-[12px] px-28")}
80-
isDisabled={!isSloganPeriod}
81-
>
82-
<span className={cn("text-body2b mobile:text-body3b flex items-center gap-10")}>
83-
{isSloganPeriod ? "슬로건 공모하러가기" : "공모기간이 아닙니다"} <span>➔</span>
84-
</span>
85-
</Button>
62+
</div> */}
63+
<Button
64+
type="button"
65+
onClick={() => router.push("/slogan")}
66+
className={cn("my-[24px] mobile:mb-[12px] px-28")}
67+
disabled={!isSloganPeriod}
68+
>
69+
<span className={cn("text-body2b mobile:text-body3b flex items-center gap-10")}>
70+
{isSloganPeriod ? "슬로건 공모하러가기" : "공모기간이 아닙니다"} <span></span>
71+
</span>
72+
</Button>
8673

87-
<div className={cn("text-caption1r mobile:text-caption2r text-gray-400")}>
88-
{submissionPeriodText}
89-
</div> */}
74+
<div className={cn("text-caption1r mobile:text-caption2r text-gray-400")}>
75+
{submissionPeriodText}
76+
</div>
9077
</section>
9178
);
9279
};

src/widgets/slogan/ui/SloganFormContainer/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import PersonalInfoInputs from "@/entities/slogan/ui/PersonalInfoInputs";
1111
import { useSloganForm } from "@/entities/slogan/lib/useSloganForm";
1212

1313
export default function SloganFormContainer() {
14-
const { state, handlers, schoolData } = useSloganForm();
14+
const { state, isValid, handlers, schoolData } = useSloganForm();
1515

1616
if (state.isSubmitted) {
1717
return <SloganFormSuccess />;
@@ -56,7 +56,7 @@ export default function SloganFormContainer() {
5656
/>
5757
</div>
5858
</div>
59-
<Button type="submit" disabled={!state.isValid || state.isSubmitting}>
59+
<Button type="submit" disabled={!isValid || state.isSubmitting}>
6060
응모하기
6161
</Button>
6262
</form>

0 commit comments

Comments
 (0)