Skip to content

Conversation

@jaeml06
Copy link
Contributor

@jaeml06 jaeml06 commented Aug 31, 2025

🚩 연관 이슈

closed #355

📝 작업 내용

주의

  • 현재 MainSection은 아직 써니가 무엇으로 채울지 고민하고 있어서 이 부분은 수정을 제외했습니다.
  • 아직 템플릿 제출 링크가 없습니다. 이부분도 콜리가 완성하는대로 추가하도록 하겠습니다.
  • 일단 한번 확인을 받고 싶어서 올린 것이니 급하게 리뷰할 필요는 없습니다.

일단 1차적으로 UI 구현이나 구현에 미흡한점이 있는지 평가해주시면 감사하겠습니다.

수정 파일

  • ScrollHint : 스크롤 유도 컴포넌트
  • TemplateSelection : 템플릿 섹션
    • TamplateList : 템플릿 레이아웃 컴포넌트
    • TemplateCard: 각 템플릿 카드
    • TamplateApplicationSection : 템플릿 신청하기 영역
  • TimeTableSection : 시간표 설정 설명 영역
  • TimerSection : 타이머 설명 영역
  • TableSection : 홈 | 설정 설명 영역
  • ReviewSection : 리뷰 영역
  • ReportSection : 버그 및 리포트 영역

메인 페이지를 써니의 디자인 시안에 맞게 변경

  • 메인 페이지에 하단 스크롤 유도 컴포넌트 추가
2025-08-31.8.18.55.mov

토론 템플릿 섹션 추가

브라우저 너비에 따라 3열과 2로 변경됩니다.

  return (
    <div
      className={[
        'grid gap-5',
        // 2열, lg에서 3열
        'grid-cols-2 lg:grid-cols-3',
      ].join(' ')}
    >
      {data.map((t) => (
        <TemplateCard key={t.title} {...t} />
      ))}
    </div>
  );

3열 표시

image image

2열 표시

image image

🏞️ 스크린샷 (선택)

전체 이미지

screencapture-localhost-3000-home-2025-08-31-20_24_28

🗣️ 리뷰 요구사항 (선택)

제 환경에서는 문제 없이 동작하는 것 처럼 보입니다. 한번씩 본인들 환경에서 확인해주세요

Summary by CodeRabbit

  • New Features

    • 랜딩에 템플릿 선택 섹션 추가: 카드형 템플릿 목록, 그룹별 템플릿 및 원클릭 "토론하기" 링크 제공
    • 템플릿 신청 섹션 추가(외부 신청 링크 오픈)
    • 하단 스크롤 유도 애니메이션 힌트 추가
  • Style

    • 랜딩 하단 섹션 재배치: 표/리뷰/리포트 구역을 개별 컨테이너로 분리, 리뷰는 다크 배경
    • 시간표·타이머·테이블 섹션 이미지·문구·레이아웃 전면 업데이트
    • 리뷰 섹션 폭 제한 및 버튼 중앙 정렬 개선
  • Chores

    • 공유 템플릿 상수·타입 추가 및 템플릿 공유 URL/신청 URL 등록

@coderabbitai
Copy link

coderabbitai bot commented Aug 31, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

랜딩 페이지 레이아웃을 재구성하고 ScrollHint 및 TemplateSelection(템플릿 리스트/카드/신청) 컴포넌트를 추가했으며, 타임테이블·타이머·테이블·리뷰 섹션의 에셋·문구·레이아웃을 교체·조정하고 DebateTemplate 타입과 DEBATE_TEMPLATE 상수를 도입했다.

Changes

Cohort / File(s) Summary
Landing page composition
src/page/LandingPage/LandingPage.tsx
MainSection 뒤에 ScrollHintTemplateSelection 삽입; TimeTable/Timer/Table/Review/Report 섹션을 별도 래퍼(배경 분리)로 재구성, 렌더 순서 유지.
Scroll hint
src/page/LandingPage/components/ScrollHint.tsx
최상단에서 하단에 고정되는 스크롤 유도 컴포넌트 추가(스크롤 리스너, visible 상태, aria-hidden 반영).
Template feature (types, constants, components)
src/type/type.ts, src/constants/debate_template.ts, src/page/LandingPage/components/TemplateSelection.tsx, .../TemplateList.tsx, .../TemplateCard.tsx, .../TemplateApplicationSection.tsx
DebateTemplate 타입 추가, 정적 템플릿 데이터(DEBATE_TEMPLATE) 및 createTableShareUrl 기반 공유 링크 도입, TemplateSelection/TemplateList/TemplateCard/TemplateApplicationSection 컴포넌트 추가.
Landing sections refresh
src/page/LandingPage/components/TimeTableSection.tsx, .../TimerSection.tsx, .../TableSection.tsx, .../ReviewSection.tsx
신규 에셋으로 교체, 문구 및 레이아웃 재구성(섹션별 이미지·텍스트 배치 변경). ReviewSection: 폭 제약 및 버튼 중앙 정렬로 레이아웃 조정.
URLs constant
src/constants/urls.ts
LANDING_URLS.TEMPLATE_REGISTER_URL 추가.

Sequence Diagram(s)

sequenceDiagram
  participant U as 사용자
  participant LP as LandingPage
  participant SH as ScrollHint
  U->>LP: 페이지 열기
  LP->>SH: 마운트(topThreshold)
  SH->>SH: window.scrollY 초기 검사
  alt scrollY <= threshold
    SH-->>U: 힌트 표시 (visible, aria-hidden=false)
  else
    SH-->>U: 힌트 숨김 (aria-hidden=true)
  end
  U-->>SH: 스크롤 이벤트
  SH->>SH: 가시성 업데이트
Loading
sequenceDiagram
  participant U as 사용자
  participant TL as TemplateList
  participant TC as TemplateCard
  participant B as 브라우저
  U->>TL: 템플릿 그리드 확인
  TL->>TC: 카드 렌더링 (데이터 바인딩)
  U->>TC: "토론하기" 클릭
  TC->>B: action.href로 이동 (공유 URL 열기)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Assessment against linked issues

Objective Addressed Explanation
메인페이지 디자인 변경 및 섹션 재배치 [#355]
토론 템플릿 추가 (리스트/카드/정적 데이터) [#355]
템플릿 신청 UI 및 외부 폼 링크 추가 [#355]

Possibly related PRs

Suggested labels

design

Suggested reviewers

  • i-meant-to-be
  • useon

Poem

깡총깡총, 새 템플릿이 반짝여요 🥕
아래 화살은 살포시 손짓하고,
카드 하나 누르면 토론장이 반짝!
시간표와 타이머도 새 옷을 입었네,
오늘의 논쟁, 깡충 출발해볼래요?


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45a6e19 and bcfdbab.

📒 Files selected for processing (1)
  • src/constants/debate_template.ts (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#355

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jaeml06 jaeml06 added the feat 기능 개발 label Aug 31, 2025
@jaeml06 jaeml06 requested review from i-meant-to-be and useon August 31, 2025 11:34
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/page/LandingPage/components/TamplateList.tsx (1)

1-22: 파일명에 오타가 있습니다

파일명과 함수명에서 "Template"이 "Tamplate"로 잘못 작성되어 있습니다. 올바른 철자로 수정해야 합니다.

다음과 같이 수정을 권장합니다:

  • 파일명: TamplateList.tsxTemplateList.tsx
  • 인터페이스명: TamplateListPropsTemplateListProps
  • 함수명: TamplateListTemplateList
  • 주석에서 언급된 그리드 설명도 확인이 필요합니다 (Line 12: "작은 화면 1열"이라고 했지만 실제로는 2열로 설정됨)
-interface TamplateListProps {
+interface TemplateListProps {
   data: DebateTemplate[];
 }
-export default function TamplateList({ data }: TamplateListProps) {
+export default function TemplateList({ data }: TemplateListProps) {
   return (
     <div
       className={[
         'grid gap-5',
-        // 작은 화면 1열, md에서 2열, xl에서 3열
+        // 작은 화면 2열, lg에서 3열
         'grid-cols-2 lg:grid-cols-3',
       ].join(' ')}
     >
🧹 Nitpick comments (20)
src/page/LandingPage/components/ReviewSection.tsx (4)

16-19: 헤딩 레벨 정리: h1 다중 사용 대신 h2로 통일 권장

섹션 내부에 h1이 2개 있습니다. 페이지 내 단일 h1 원칙(혹은 섹션 스코프 헤딩 모델 미사용 시)을 고려해 h2로 내리는 편이 접근성/SEO에 안전합니다.

-        <h1>이미 많은 사람들이 디베이트 타이머로</h1>
-        <h1>더 나은 토론환경을 만들고 있어요.</h1>
+        <h2>이미 많은 사람들이 디베이트 타이머로</h2>
+        <h2>더 나은 토론환경을 만들고 있어요.</h2>

26-31: button 기본 type 지정

폼 내 포함될 가능성까지 고려하면 명시적 type="button"이 안전합니다.

-        <button
+        <button
+          type="button"
           className="rounded-full border border-neutral-300 bg-brand px-20 py-2 text-[min(max(0.875rem,1.25vw),1.2rem)] font-medium text-default-black transition-all duration-100 hover:bg-semantic-table hover:text-default-white"
           onClick={onStartWithoutLogin}
         >

27-27: 색상 토큰 일관성

다른 컴포넌트(TemplateCard)에서는 hover 시 text-white를 사용합니다. design token에 text-default-white가 없다면 효과가 적용되지 않을 수 있습니다.

-          className="rounded-full border border-neutral-300 bg-brand px-20 py-2 text-[min(max(0.875rem,1.25vw),1.2rem)] font-medium text-default-black transition-all duration-100 hover:bg-semantic-table hover:text-default-white"
+          className="rounded-full border border-neutral-300 bg-brand px-20 py-2 text-[min(max(0.875rem,1.25vw),1.2rem)] font-medium text-default-black transition-all duration-100 hover:bg-semantic-table hover:text-white"

21-23: key 안정성 확인

key를 review.user로 두셨는데 유저명이 중복될 가능성이 있으면 불안정합니다. 고유 id가 있으면 그 값으로 교체하는 것을 권장합니다.

src/type/type.ts (1)

75-86: 일반명 ‘Action’ 충돌 가능성 최소화 및 외부 재사용성 확보

전역적으로 흔한 이름(Action)은 충돌 여지가 큽니다. 명확한 도메인 접두어를 붙여 export 하면 발견/재사용과 충돌 방지에 유리합니다.

-type Action = {
+export type TemplateAction = {
   label: string; // 좌측에 표시할 토론 형식 이름 (예: "CEDA 토론")
   href: string; // 우측 "토론하기" 버튼의 이동 링크
 };
 
 export type DebateTemplate = {
   title: string; // 제목 (예: "서방정토")
   subtitle?: string; // 서브 제목 (예: "서강대")
   logoSrc?: string; // 로고 이미지
-  actions: Action[];
+  actions: TemplateAction[];
   className?: string; // 카드의 추가 className이 필요하면 사용
 };

추가로, 기존 코드가 Action을 직접 import하지 않는다면 호환성 이슈는 없습니다. 만약 있다면 해당 사용처 타입만 TemplateAction으로 교체하면 됩니다.

src/page/LandingPage/components/TemplateCard.tsx (3)

15-16: Tailwind ring-3는 기본 스케일에 없음

기본 Tailwind에서는 ring, ring-1, ring-2, ring-4, ring-8만 제공됩니다. 커스텀 설정이 없다면 ring-3는 미적용됩니다. ring-2로 조정 권장.

-        'ring-3 ring-brand/20',
+        'ring-2 ring-brand/20',

21-22: 불필요한 공백 문자 정리

className 문자열 앞 공백은 의미가 없습니다. 사소하지만 일관성 차원에서 제거 권장.

-      <div className=" flex justify-between">
+      <div className="flex justify-between">

43-64: action key와 링크 동작 확인

  • key를 label+index로 구성하셨는데, label이 동일한 항목이 섞일 수 있으면 index 의존 키는 재정렬 시 리렌더 비용을 늘릴 수 있습니다. 가능하면 고유 id/slug 사용 권장.
  • href가 외부 공유 URL(새 탭 열기 의도)이라면 target/rel 지정 검토 바람. 내부 라우팅이면 현재 형태 유지.
-          <li key={`${a.label}-${i}`}>
+          <li key={`${a.label}-${i}`}> {/* 고유 id가 있다면 해당 id를 사용하세요 */}
@@
-              <a
-                href={a.href}
+              <a
+                href={a.href}
+                /* 외부 링크라면 아래 속성 추가 */
+                /* target="_blank" rel="noopener noreferrer" */
                 className={[
src/page/LandingPage/components/TamplateApplicationSection.tsx (3)

5-6: 모바일 반응형 레이아웃 보완

현재 항상 가로 정렬입니다. 작은 화면에서 이미지와 텍스트가 비좁게 붙을 수 있어 세로 스택 후 md부터 가로 전환을 권장합니다.

-    <section className="flex flex-row justify-between gap-1">
+    <section className="flex flex-col-reverse items-center gap-6 md:flex-row md:justify-between">

13-24: 외부 이동은 a 태그가 접근성/SEO에 유리

window.open을 버튼 onClick으로 처리하기보다 a 태그 + target/rel 사용이 표준적입니다.

-        <button
-          onClick={() =>
-            window.open(
-              LANDING_URLS.REPORT_FORM_URL,
-              '_blank',
-              'noopener,noreferrer',
-            )
-          }
-          className="rounded-full border border-neutral-300 bg-neutral-200 px-9 py-2 text-[min(max(0.875rem,1.25vw),1.2rem)] font-medium text-default-black transition-all duration-100 hover:bg-brand"
-        >
-          신청하기
-        </button>
+        <a
+          href={LANDING_URLS.REPORT_FORM_URL}
+          target="_blank"
+          rel="noopener noreferrer"
+          className="rounded-full border border-neutral-300 bg-neutral-200 px-9 py-2 text-[min(max(0.875rem,1.25vw),1.2rem)] font-medium text-default-black transition-all duration-100 hover:bg-brand"
+        >
+          신청하기
+        </a>

26-26: img 대체 텍스트 개선

"section501"은 의미 없는 alt입니다. 장식 이미지면 alt=""로, 의미가 있으면 콘텐츠 설명으로 교체하세요. 또한 모바일 폭 대응을 위해 폭 클래스 보완을 권장합니다.

-      <img src={section501} alt="section501" className="w-[30%]" />
+      <img src={section501} alt="" className="w-10/12 max-w-[520px] md:w-[30%]" />
src/page/LandingPage/components/TemplateSelection.tsx (1)

1-3: 이름 오타(Tamplate → Template) 정비 제안

컴포넌트/파일/상수명이 혼재되어 검색성과 유지보수가 떨어집니다. 일괄 리네이밍을 권장합니다. (별도 PR로 진행해도 좋습니다)

-import { DEBATE_TAMPLATE } from '../../../constants/debate_tamplate';
-import TamplateApplicationSection from './TamplateApplicationSection';
-import TamplateList from './TamplateList';
+import { DEBATE_TAMPLATE } from '../../../constants/debate_tamplate'; // 상수/파일도 후속 PR에서 *template*으로 교체 권장
+import TemplateApplicationSection from './TemplateApplicationSection';
+import TemplateList from './TemplateList';

아래 사용처도 동일하게 교체 필요:

-      <TamplateList data={DEBATE_TAMPLATE.ONE} />
+      <TemplateList data={DEBATE_TAMPLATE.ONE} />
@@
-      <TamplateList data={DEBATE_TAMPLATE.TWO} />
+      <TemplateList data={DEBATE_TAMPLATE.TWO} />
@@
-      <TamplateList data={DEBATE_TAMPLATE.THREE} />
-      <TamplateApplicationSection />
+      <TemplateList data={DEBATE_TAMPLATE.THREE} />
+      <TemplateApplicationSection />
src/page/LandingPage/components/TableSection.tsx (1)

17-19: 접근성 개선을 위한 제안

제목에 <br /> 태그를 사용하여 줄바꿈을 하고 있는데, 스크린 리더 사용자나 반응형 디자인 관점에서 더 나은 방법이 있습니다.

CSS를 활용한 반응형 줄바꿈을 고려해보세요:

-          토론 정보 <br />
-          관리 및 기록
+          <span className="block sm:inline">토론 정보</span>
+          <span className="block sm:inline"> 관리 및 기록</span>

또는 모바일에서만 줄바꿈되도록:

-          토론 정보 <br />
-          관리 및 기록
+          토론 정보<br className="sm:hidden" /> 관리 및 기록
src/page/LandingPage/LandingPage.tsx (1)

9-10: import 순서 정리 권장

새로 추가된 컴포넌트 import들의 순서를 일관성 있게 정리하면 가독성이 향상됩니다.

 import useLandingPageHandlers from './hooks/useLandingPageHandlers';
+import ScrollHint from './components/ScrollHint';
 import TemplateSelection from './components/TemplateSelection';
-import ScrollHint from './components/ScrollHint';
src/page/LandingPage/components/ScrollHint.tsx (1)

24-59: 주석 처리된 코드 정리 권장

대량의 주석 처리된 코드가 있습니다. 이전 구현을 참고용으로 남겨둔 것 같지만, 코드 가독성을 위해 제거하는 것을 권장합니다.

Git 히스토리에서 이전 구현을 확인할 수 있으므로, 주석 처리된 코드는 제거해도 좋을 것 같습니다:

-    // <div
-    //   className={`
-    //     pointer-events-none fixed inset-x-0 bottom-10 flex justify-center
-    //     transition-all duration-300
-    //     ${visible ? 'translate-y-0 opacity-100' : 'translate-y-2 opacity-0'}
-    //   `}
-    //   aria-hidden={!visible}
-    // >
-    //   <div
-    //     className={`
-    //       pointer-events-auto flex items-center gap-2 rounded-full
-    //       bg-default-white/90 px-4 py-2 text-[min(max(0.85rem,1.2vw),1rem)] font-medium shadow-[0_6px_18px_rgba(0,0,0,0.12)]
-    //       ring-1
-    //       ring-black/5 backdrop-blur
-    //       transition-colors hover:bg-default-white
-    //     `}
-    //   >
-    //     <svg
-    //       width="18"
-    //       height="18"
-    //       viewBox="0 0 24 24"
-    //       className="animate-bounce"
-    //       aria-hidden
-    //     >
-    //       <path
-    //         d="M6 9l6 6 6-6"
-    //         fill="none"
-    //         stroke="currentColor"
-    //         strokeWidth="2"
-    //         strokeLinecap="round"
-    //         strokeLinejoin="round"
-    //       />
-    //     </svg>
-    //     아래로 스크롤
-    //   </div>
-    // </div>
src/constants/debate_tamplate.ts (1)

16-258: 템플릿 데이터 구조 개선 제안

  • 템플릿 메타데이터와 인코딩된 URL을 분리해 관리하세요 (예: TEMPLATE_METADATA + ENCODED_URL_DATA)
  • 각 항목이 DebateTemplate 타입과 일치하는지 확인해 타입 안전성을 강화하세요
  • 인코딩된 URL이 올바르게 생성·동작하는지 유효성을 점검하세요 (현재 파일 내 createTableShareUrl(encodeData: string)는 로컬로 정의되어 import.meta.env.VITE_SHARE_BASE_URL를 사용합니다)
src/page/LandingPage/components/TimeTableSection.tsx (1)

8-9: 섹션 컨테이너 폭/정렬 일관화 제안

TimerSection과 다르게 폭 제한/중앙 정렬이 없어 레이아웃 점프가 발생할 수 있습니다. 아래처럼 공통 컨테이너 규칙을 맞추는 것을 권장합니다.

-    <section id="section1" className="flex flex-col gap-24">
+    <section id="section1" className="mx-auto flex w-[95%] max-w-[1226px] flex-col gap-24 md:w-[64%]">
src/page/LandingPage/components/TimerSection.tsx (3)

10-11: 섹션 폭 규칙 검토

w-[95%]와 md:w-[64%] 사용은 의도일 수 있으나, TimeTableSection과 불일치합니다. 두 섹션의 컨테이너 폭·정렬을 통일해주세요(예: 공용 래퍼 컴포넌트).


17-20: 헤딩 내 줄바꿈
최소화

문맥상 줄바꿈은 스타일로 제어하는 편이 번역/접근성에 안전합니다.

-        <h2 className="mt-4 text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
-          원하는 때에 <br />
-          작전시간 사용하기
-        </h2>
+        <h2 className="mt-4 text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
+          <span className="block sm:inline">원하는 때에</span> 작전시간 사용하기
+        </h2>

50-53: 헤딩 내
최소화(가독성/번역 고려)

동일 맥락으로 줄바꿈을 스타일로 제어하는 편이 안전합니다.

-        <h2 className="mt-4 text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
-          키보드 방향키로 <br />더 편리한 조작
-        </h2>
+        <h2 className="mt-4 text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
+          <span className="block sm:inline">키보드 방향키로</span> 더 편리한 조작
+        </h2>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1f8c384 and 89ae5c4.

⛔ Files ignored due to path filters (25)
  • src/assets/landing/bell_setting.png is excluded by !**/*.png
  • src/assets/landing/bottom_arrow.png is excluded by !**/*.png
  • src/assets/landing/debate_info_setting.png is excluded by !**/*.png
  • src/assets/landing/key_info.png is excluded by !**/*.png
  • src/assets/landing/table_list.png is excluded by !**/*.png
  • src/assets/landing/timebox_add_button.png is excluded by !**/*.png
  • src/assets/landing/timebox_step.png is excluded by !**/*.png
  • src/assets/landing/timebox_step_button.png is excluded by !**/*.png
  • src/assets/landing/timeout_button.png is excluded by !**/*.png
  • src/assets/landing/timer.png is excluded by !**/*.png
  • src/assets/landing/timer_operation_time.png is excluded by !**/*.png
  • src/assets/landing/timer_timebased.png is excluded by !**/*.png
  • src/assets/landing/two_timer.png is excluded by !**/*.png
  • src/assets/template_logo/government.png is excluded by !**/*.png
  • src/assets/template_logo/han_alm.png is excluded by !**/*.png
  • src/assets/template_logo/hantomak.png is excluded by !**/*.png
  • src/assets/template_logo/igam.png is excluded by !**/*.png
  • src/assets/template_logo/jungseonto.png is excluded by !**/*.png
  • src/assets/template_logo/kogito.png is excluded by !**/*.png
  • src/assets/template_logo/kondae_time.png is excluded by !**/*.png
  • src/assets/template_logo/nogotte.png is excluded by !**/*.png
  • src/assets/template_logo/osansi.png is excluded by !**/*.png
  • src/assets/template_logo/seobangjeongto.png is excluded by !**/*.png
  • src/assets/template_logo/todallae.png is excluded by !**/*.png
  • src/assets/template_logo/visual.png is excluded by !**/*.png
📒 Files selected for processing (12)
  • src/constants/debate_tamplate.ts (1 hunks)
  • src/page/LandingPage/LandingPage.tsx (3 hunks)
  • src/page/LandingPage/components/ReviewSection.tsx (2 hunks)
  • src/page/LandingPage/components/ScrollHint.tsx (1 hunks)
  • src/page/LandingPage/components/TableSection.tsx (2 hunks)
  • src/page/LandingPage/components/TamplateApplicationSection.tsx (1 hunks)
  • src/page/LandingPage/components/TamplateList.tsx (1 hunks)
  • src/page/LandingPage/components/TemplateCard.tsx (1 hunks)
  • src/page/LandingPage/components/TemplateSelection.tsx (1 hunks)
  • src/page/LandingPage/components/TimeTableSection.tsx (1 hunks)
  • src/page/LandingPage/components/TimerSection.tsx (2 hunks)
  • src/type/type.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
src/page/LandingPage/components/TemplateSelection.tsx (3)
src/page/LandingPage/components/TamplateList.tsx (1)
  • TamplateList (7-21)
src/constants/debate_tamplate.ts (1)
  • DEBATE_TAMPLATE (16-258)
src/page/LandingPage/components/TamplateApplicationSection.tsx (1)
  • TamplateApplicationSection (3-29)
src/page/LandingPage/components/TamplateApplicationSection.tsx (1)
src/constants/urls.ts (1)
  • LANDING_URLS (1-7)
src/page/LandingPage/LandingPage.tsx (3)
src/page/LandingPage/components/ScrollHint.tsx (1)
  • ScrollHint (8-75)
src/page/LandingPage/components/TemplateSelection.tsx (1)
  • TemplateSelection (5-21)
src/page/LandingPage/components/ReviewSection.tsx (1)
  • ReviewSection (8-35)
src/page/LandingPage/components/TamplateList.tsx (2)
src/type/type.ts (1)
  • DebateTemplate (80-86)
src/page/LandingPage/components/TemplateCard.tsx (1)
  • TemplateCard (3-68)
src/page/LandingPage/components/TemplateCard.tsx (1)
src/type/type.ts (1)
  • DebateTemplate (80-86)
src/constants/debate_tamplate.ts (1)
src/util/arrayEncoding.ts (1)
  • createTableShareUrl (23-29)
🔇 Additional comments (8)
src/page/LandingPage/components/TamplateList.tsx (1)

16-18: title 대신 고유 식별자를 key로 사용하거나, title의 유니크 보장을 확인하세요.

  • 동적 데이터에 동일한 title이 있을 경우 React key 중복으로 UI 재렌더링 오류가 발생할 수 있습니다.
  • 데이터 소스에서 title 중복 여부를 검증하거나, 각 항목에 id 같은 고유 필드를 추가해 key로 사용하도록 변경하세요.
src/page/LandingPage/components/TableSection.tsx (2)

1-2: LGTM!

새로운 디자인에 맞춰 이미지 에셋을 적절히 교체했습니다.


24-28: 콘텐츠 일관성 확인

제목이 "토론 기본정보 설정"으로, 설명이 "시간표 이름부터 주제까지!"로 변경되었습니다. 이미지와 텍스트 내용이 실제 기능과 일치하는지 확인이 필요합니다.

src/page/LandingPage/LandingPage.tsx (2)

32-35: LGTM!

새로운 ScrollHint와 TemplateSelection 컴포넌트가 적절한 위치에 배치되어 있고, 주석도 명확합니다.


50-58: 레이아웃 구조 개선

세 개의 별도 wrapper div로 섹션들을 분리한 구조가 잘 구성되어 있습니다. 각각 다른 배경색으로 시각적 구분도 명확합니다.

src/page/LandingPage/components/ScrollHint.tsx (3)

4-6: 타입 정의가 적절합니다

ScrollHintProps 타입에서 topThreshold에 기본값과 주석이 잘 설정되어 있습니다.


11-21: 스크롤 이벤트 처리 로직 검토

useEffect 내의 스크롤 이벤트 처리 로직이 적절하게 구현되어 있습니다. passive 옵션과 cleanup 함수도 올바르게 설정되어 있습니다.


68-72: 이미지 접근성 개선

이미지의 alt 텍스트와 스타일링이 적절하게 설정되어 있습니다.

Comment on lines 1 to 15
import government from '../assets/template_logo/government.png';
import igam from '../assets/template_logo/igam.png';
import kondae_time from '../assets/template_logo/kondae_time.png';
import han_alm from '../assets/template_logo/han_alm.png';
import todallae from '../assets/template_logo/todallae.png';
import jungseonto from '../assets/template_logo/jungseonto.png';
import visual from '../assets/template_logo/visual.png';
import hantomak from '../assets/template_logo/hantomak.png';
import seobangjeongto from '../assets/template_logo/seobangjeongto.png';
import osansi from '../assets/template_logo/osansi.png';
import nogotte from '../assets/template_logo/nogotte.png';
import kogito from '../assets/template_logo/kogito.png';
function createTableShareUrl(encodeData: string): string {
return `${import.meta.env.VITE_SHARE_BASE_URL}/share?data=${encodeData}`;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

파일명과 상수명 오타 수정 필요

파일명과 export하는 상수명에서 "Template"이 "Tamplate"로 잘못 작성되어 있습니다.

다음과 같이 수정해야 합니다:

  • 파일명: debate_tamplate.tsdebate_template.ts
  • 상수명: DEBATE_TAMPLATEDEBATE_TEMPLATE
-export const DEBATE_TAMPLATE = {
+export const DEBATE_TEMPLATE = {

또한 이 변경사항은 이 상수를 사용하는 다른 파일들에도 영향을 미치므로 전체 프로젝트에서 일괄 수정이 필요합니다.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/constants/debate_tamplate.ts (lines 1-15) the filename and exported
constant use the misspelled "tamplate"/"TAMPLATE"; rename the file to
src/constants/debate_template.ts and rename the exported identifier from
DEBATE_TAMPLATE to DEBATE_TEMPLATE, update the internal symbol declarations
accordingly, and then update all import sites across the project to reference
the new filename and constant name; ensure your VCS moves/renames the file (not
a delete+create) to preserve history and run a global search-replace for the old
identifier and path to avoid missing usages.

Comment on lines 13 to 15
function createTableShareUrl(encodeData: string): string {
return `${import.meta.env.VITE_SHARE_BASE_URL}/share?data=${encodeData}`;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

환경 변수 사용 확인

createTableShareUrl 함수에서 import.meta.env.VITE_SHARE_BASE_URL 환경 변수를 사용하고 있습니다. 이 환경 변수가 올바르게 설정되어 있는지 확인이 필요합니다.

다음 스크립트로 환경 변수 설정을 확인해보겠습니다:


🏁 Script executed:

#!/bin/bash
# Description: VITE_SHARE_BASE_URL 환경 변수 사용처 확인

# .env 파일들에서 VITE_SHARE_BASE_URL 변수 확인
echo "=== .env 파일들에서 VITE_SHARE_BASE_URL 확인 ==="
fd "\.env" -t f --exec grep -H "VITE_SHARE_BASE_URL" {} \; 2>/dev/null

echo -e "\n=== 코드에서 VITE_SHARE_BASE_URL 사용처 확인 ==="
rg "VITE_SHARE_BASE_URL" --type ts --type tsx -C 2

Length of output: 328


다음 스크립트로 다시 확인해보겠습니다:


🏁 Script executed:

#!/bin/bash
# Description: VITE_SHARE_BASE_URL 환경 변수 설정 및 사용처 재확인

echo "=== .env* 파일들에서 VITE_SHARE_BASE_URL 확인 ==="
grep -R "VITE_SHARE_BASE_URL" .env* 2>/dev/null

echo -e "\n=== 코드에서 VITE_SHARE_BASE_URL 사용처 확인 (.ts, .tsx) ==="
rg -n -C2 VITE_SHARE_BASE_URL --glob "*.ts" --glob "*.tsx" .

Length of output: 1533


VITE_SHARE_BASE_URL 환경 변수 정의 누락
import.meta.env.VITE_SHARE_BASE_URL가 src/constants/debate_tamplate.ts, src/hooks/useTableShare.tsx, src/page/LandingPage/hooks/useLandingPageHandlers.ts 등에서 사용 중이나 .env* 파일에서 정의가 확인되지 않습니다. .env.*(예: .env.development, .env.production)에 해당 변수를 추가하거나 배포 환경 변수 설정을 검증해 주세요.

🤖 Prompt for AI Agents
In src/constants/debate_tamplate.ts around lines 13-15, the code reads
import.meta.env.VITE_SHARE_BASE_URL but that env var is not defined in any
.env.* files; add VITE_SHARE_BASE_URL=<your_share_base_url> to your
.env.development, .env.production (and any other env files used), ensure the
variable name keeps the VITE_ prefix so Vite exposes it, commit/update
.env.example or README with the new variable, and verify CI/deployment env
settings include VITE_SHARE_BASE_URL and restart the dev server after changes.

Comment on lines +23 to +24
<img src={timer} alt="section301" className="flex w-1/2" />
<div className="flex w-1/2 flex-col items-center gap-4">
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

이미지 alt·lazy/async 권장

“section301”은 의미가 없어 접근성에 취약합니다. 지연 로딩으로 성능 개선도 권장합니다.

-        <img src={timer} alt="section301" className="flex w-1/2" />
+        <img
+          src={timer}
+          alt="타이머 메인 화면"
+          loading="lazy"
+          decoding="async"
+          className="w-full md:w-1/2"
+        />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<img src={timer} alt="section301" className="flex w-1/2" />
<div className="flex w-1/2 flex-col items-center gap-4">
<img
src={timer}
alt="타이머 메인 화면"
loading="lazy"
decoding="async"
className="w-full md:w-1/2"
/>
<div className="flex w-1/2 flex-col items-center gap-4">
🤖 Prompt for AI Agents
In src/page/LandingPage/components/TimerSection.tsx around lines 23-24, the img
uses a non-descriptive alt ("section301") and lacks lazy/async loading; replace
the alt with a meaningful, concise description of the image content (e.g.,
"countdown timer showing X" or similar accurate text for screen readers) and
enable deferred loading by adding loading="lazy" and decoding="async" (or switch
to Next/Image with appropriate priority if using Next.js) so the image is
accessible and performance-friendly.

Comment on lines 23 to 38
<img src={timer} alt="section301" className="flex w-1/2" />
<div className="flex w-1/2 flex-col items-center gap-4">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
토론자가 작전시간을
<br />
요청하면{' '}
<img
src={timeoutButton}
alt="작전시간 사용"
className="inline-block h-[1.8rem] align-middle"
style={{ transform: 'translateY(-0.1em)' }}
/>{' '}
<br />
버튼을 눌러 시간을 사용해요
</h3>
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

헤딩(h3) 내부 인라인 이미지 제거/비노출 처리

헤딩 안의 이미지(아이콘)는 스크린리더에 중복 정보를 전달할 수 있습니다. 텍스트만 두거나 이미지를 비노출 처리하세요.

-          <h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
-            토론자가 작전시간을
-            <br />
-            요청하면{' '}
-            <img
-              src={timeoutButton}
-              alt="작전시간 사용"
-              className="inline-block h-[1.8rem] align-middle"
-              style={{ transform: 'translateY(-0.1em)' }}
-            />{' '}
-            <br />
-            버튼을 눌러 시간을 사용해요
-          </h3>
+          <h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
+            토론자가 작전시간을 요청하면 버튼을 눌러 시간을 사용해요
+          </h3>

(아이콘을 유지하려면 본문 단락에 alt="" aria-hidden="true"로 별도 배치 권장)

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<img src={timer} alt="section301" className="flex w-1/2" />
<div className="flex w-1/2 flex-col items-center gap-4">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
토론자가 작전시간을
<br />
요청하면{' '}
<img
src={timeoutButton}
alt="작전시간 사용"
className="inline-block h-[1.8rem] align-middle"
style={{ transform: 'translateY(-0.1em)' }}
/>{' '}
<br />
버튼을 눌러 시간을 사용해요
</h3>
</div>
<img src={timer} alt="section301" className="flex w-1/2" />
<div className="flex w-1/2 flex-col items-center gap-4">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
토론자가 작전시간을 요청하면 버튼을 눌러 시간을 사용해요
</h3>
</div>
🤖 Prompt for AI Agents
In src/page/LandingPage/components/TimerSection.tsx around lines 23 to 38, the
h3 currently contains an inline <img> which can create redundant information for
screen readers; remove the image from inside the heading and either keep only
the text or move the visual icon out of the h3 into a non-heading inline element
(e.g., a span/div immediately after the h3) and mark the image as decorative by
setting alt="" and aria-hidden="true" so it is ignored by assistive tech.

Comment on lines 40 to 47
<div className="flex flex-row items-center justify-center gap-8 px-4">
<div className="flex w-1/2 flex-col items-center gap-4">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
작전시간이 나타나면
<br /> 원하는 시간을 입력하세요!
</h3>
</div>
<img src={timerOperationTime} alt="section302" className="flex w-1/2" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

반응형 방향 전환 및 alt 보강

모바일에서 2열 강제는 축소를 유발합니다. md 이상에서 가로 배치하고 alt를 구체화하세요.

-      <div className="flex flex-row items-center justify-center gap-8 px-4">
-        <div className="flex w-1/2 flex-col items-center gap-4">
+      <div className="flex flex-col items-center justify-center gap-8 px-4 md:flex-row">
+        <div className="flex w-full flex-col items-center gap-4 md:w-1/2">
           <h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
             작전시간이 나타나면
             <br /> 원하는 시간을 입력하세요!
           </h3>
         </div>
-        <img src={timerOperationTime} alt="section302" className="flex w-1/2" />
+        <img
+          src={timerOperationTime}
+          alt="작전시간 입력 UI"
+          loading="lazy"
+          decoding="async"
+          className="w-full md:w-1/2"
+        />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="flex flex-row items-center justify-center gap-8 px-4">
<div className="flex w-1/2 flex-col items-center gap-4">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
작전시간이 나타나면
<br /> 원하는 시간을 입력하세요!
</h3>
</div>
<img src={timerOperationTime} alt="section302" className="flex w-1/2" />
<div className="flex flex-col items-center justify-center gap-8 px-4 md:flex-row">
<div className="flex w-full flex-col items-center gap-4 md:w-1/2">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
작전시간이 나타나면
<br /> 원하는 시간을 입력하세요!
</h3>
</div>
<img
src={timerOperationTime}
alt="작전시간 입력 UI"
loading="lazy"
decoding="async"
className="w-full md:w-1/2"
/>
</div>
🤖 Prompt for AI Agents
In src/page/LandingPage/components/TimerSection.tsx around lines 40 to 47, the
current layout forces two columns on all screen sizes and uses a vague img alt;
change the container and children to be column-first and switch to row at md
breakpoint (e.g., container: flex flex-col md:flex-row items-center
justify-center gap-8 px-4), set child widths to full on mobile and half on md
(e.g., w-full md:w-1/2) so it stacks on small screens and becomes two-column at
md+, and replace the img alt with a descriptive string in Korean that explains
the image content (for example describing the timer UI/operation) to improve
accessibility.

<div>
<div className="relative inline-block text-[min(max(0.875rem,1.5vw),1.4rem)] font-semibold">
<span className="relative z-10">시간표 설정 화면</span>
<span className="relative z-10">시간표 설정화면</span>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

라벨 표기 어색한 띄어쓰기

“시간표 설정화면” → “시간표 설정 화면”이 자연스럽습니다.

-          <span className="relative z-10">시간표 설정화면</span>
+          <span className="relative z-10">시간표 설정 화면</span>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<span className="relative z-10">시간표 설정화면</span>
<span className="relative z-10">시간표 설정 화면</span>
🤖 Prompt for AI Agents
In src/page/LandingPage/components/TimeTableSection.tsx around line 11, the
label text "시간표 설정화면" has awkward spacing; change it to "시간표 설정 화면" to use
natural Korean spacing. Update the span content to the corrected string and run
a quick UI/text check to ensure line breaks or CSS don't rejoin the words.

Comment on lines +18 to +21
<div className="flex flex-row items-center justify-center gap-8 px-4">
<img src={timeboxStep} alt="section301" className="flex w-1/2" />
<img src={timeboxButtons} alt="section301" className="flex w-1/3" />
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

모바일 가독성·접근성 개선(반응형 방향/alt/지연로딩)

  • 모바일에서 2열 강제는 과도한 축소를 유발합니다. md 이상에서만 가로 배치하세요.
  • alt="section301"은 의미가 없습니다. 묘사형 alt 또는 장식이면 alt="".
  • 이미지 lazy/async로 LCP 이외 지연 로딩.
-      <div className="flex flex-row items-center justify-center gap-8 px-4">
-        <img src={timeboxStep} alt="section301" className="flex w-1/2" />
-        <img src={timeboxButtons} alt="section301" className="flex w-1/3" />
+      <div className="flex flex-col items-center justify-center gap-8 px-4 md:flex-row">
+        <img
+          src={timeboxStep}
+          alt="시간표 단계 안내 화면"
+          loading="lazy"
+          decoding="async"
+          className="w-full md:w-1/2"
+        />
+        <img
+          src={timeboxButtons}
+          alt="시간표 단계별 버튼 모음"
+          loading="lazy"
+          decoding="async"
+          className="w-full md:w-1/3"
+        />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="flex flex-row items-center justify-center gap-8 px-4">
<img src={timeboxStep} alt="section301" className="flex w-1/2" />
<img src={timeboxButtons} alt="section301" className="flex w-1/3" />
</div>
<div className="flex flex-col items-center justify-center gap-8 px-4 md:flex-row">
<img
src={timeboxStep}
alt="시간표 단계 안내 화면"
loading="lazy"
decoding="async"
className="w-full md:w-1/2"
/>
<img
src={timeboxButtons}
alt="시간표 단계별 버튼 모음"
loading="lazy"
decoding="async"
className="w-full md:w-1/3"
/>
</div>
🤖 Prompt for AI Agents
In src/page/LandingPage/components/TimeTableSection.tsx around lines 18-21, the
current two-column layout forces excessive shrink on mobile and both img tags
use a non-descriptive alt and no lazy loading; update the container classes so
the images stack vertically on small screens and switch to horizontal only at md
(e.g., flex-col on small, md:flex-row), replace alt="section301" with meaningful
descriptive alt text for the primary informative image (or alt="" if purely
decorative) and provide an appropriate alt for the other image, and add
loading="lazy" and decoding="async" to images that are not critical LCP (keep
the LCP image eager or add fetchPriority="high") so non-LCP assets load
deferred.

Comment on lines +23 to +30
<h2 className="text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
시간표 추가
</h2>
<img
src={timeboxAddButton}
alt="시간표 추가 버튼"
className="h-[min(max(1.7rem,3vw),2.7rem)] w-auto"
/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

헤딩 계층(A11y) 및 아이콘 대체텍스트

  • 섹션 내 보조 타이틀은 h3가 적절합니다.
  • 옆의 버튼 이미지는 장식에 가깝다면 스크린리더 제외 처리.
-        <h2 className="text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
+        <h3 className="text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
           시간표 추가
-        </h2>
+        </h3>
         <img
           src={timeboxAddButton}
-          alt="시간표 추가 버튼"
+          alt=""
+          aria-hidden="true"
           className="h-[min(max(1.7rem,3vw),2.7rem)] w-auto"
         />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<h2 className="text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
시간표 추가
</h2>
<img
src={timeboxAddButton}
alt="시간표 추가 버튼"
className="h-[min(max(1.7rem,3vw),2.7rem)] w-auto"
/>
<h3 className="text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
시간표 추가
</h3>
<img
src={timeboxAddButton}
alt=""
aria-hidden="true"
className="h-[min(max(1.7rem,3vw),2.7rem)] w-auto"
/>
🤖 Prompt for AI Agents
In src/page/LandingPage/components/TimeTableSection.tsx around lines 23 to 30,
change the section heading from an h2 to an h3 to preserve correct heading
hierarchy for the section, and treat the adjacent button image as decorative by
removing non-empty alt text and marking it hidden from assistive technology
(e.g., set alt="" and add aria-hidden="true" or role="presentation"); if the
image is inside an interactive element ensure the interactive element has
accessible label text (aria-label or visually-hidden text) instead of relying on
the image alt.

Comment on lines +32 to +43
<div className="flex flex-row items-center justify-center gap-8 px-4">
<img src={twoTimer} alt="section302" className="flex w-1/2" />
<div className="flex w-1/2 flex-col items-center gap-4">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
두가지 타이머
</h3>
<p className="text-[min(max(0.875rem,1.5vw),1.4rem)] font-medium text-neutral-600">
일반형과 자유토론형 타이머로,
<br />
다양한 토론 방식을 지원해요.
</p>
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

반응형 방향 전환 및 카피 띄어쓰기

  • 모바일 세로, md 이상 가로 배치 권장.
  • “두가지” → “두 가지”.
-      <div className="flex flex-row items-center justify-center gap-8 px-4">
-        <img src={twoTimer} alt="section302" className="flex w-1/2" />
-        <div className="flex w-1/2 flex-col items-center gap-4">
+      <div className="flex flex-col items-center justify-center gap-8 px-4 md:flex-row">
+        <img
+          src={twoTimer}
+          alt="두 가지 타이머 화면"
+          loading="lazy"
+          decoding="async"
+          className="w-full md:w-1/2"
+        />
+        <div className="flex w-full flex-col items-center gap-4 md:w-1/2">
           <h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
-            두가지 타이머
+            두 가지 타이머
           </h3>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="flex flex-row items-center justify-center gap-8 px-4">
<img src={twoTimer} alt="section302" className="flex w-1/2" />
<div className="flex w-1/2 flex-col items-center gap-4">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
두가지 타이머
</h3>
<p className="text-[min(max(0.875rem,1.5vw),1.4rem)] font-medium text-neutral-600">
일반형과 자유토론형 타이머로,
<br />
다양한 토론 방식을 지원해요.
</p>
</div>
<div className="flex flex-col items-center justify-center gap-8 px-4 md:flex-row">
<img
src={twoTimer}
alt="두 가지 타이머 화면"
loading="lazy"
decoding="async"
className="w-full md:w-1/2"
/>
<div className="flex w-full flex-col items-center gap-4 md:w-1/2">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
가지 타이머
</h3>
<p className="text-[min(max(0.875rem,1.5vw),1.4rem)] font-medium text-neutral-600">
일반형과 자유토론형 타이머로,
<br />
다양한 토론 방식을 지원해요.
</p>
</div>
🤖 Prompt for AI Agents
In src/page/LandingPage/components/TimeTableSection.tsx around lines 32 to 43,
the layout should be vertical on mobile and horizontal from md up and the copy
needs spacing: change the container classes from "flex flex-row items-center
justify-center gap-8 px-4" to "flex flex-col md:flex-row items-center
justify-center gap-8 px-4" and update child sizing from fixed halves to
responsive widths (e.g., img class to "w-full md:w-1/2" and the text wrapper to
"w-full md:w-1/2") so they stack on small screens and sit side-by-side on md+,
and change the heading text "두가지 타이머" to "두 가지 타이머" (add the space). Ensure any
line-breaks or spacing in the paragraph still render correctly with the
responsive layout.

Comment on lines +45 to 57
<div className="flex flex-row items-center justify-center gap-8 px-4">
<div className="flex w-1/2 flex-col items-center gap-4">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
종소리 설정
</h3>
<p className="text-[min(max(0.875rem,1.5vw),1.4rem)] font-medium text-neutral-600">
시간에 따른 종소리를 내마음대로
<br />
커스터마이징 할 수 있어요.
</p>
</div>
<img src={bellSetting} alt="section302" className="flex w-1/2" />
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

텍스트 품질·접근성(띄어쓰기/외래어·alt/lazy)

  • “내마음대로” → “내 마음대로”.
  • “커스터마이징 할 수 있어요.” → “커스터마이징할 수 있어요.” 또는 “사용자 지정할 수 있어요.”(권장).
  • alt 구체화 및 lazy/async.
-      <div className="flex flex-row items-center justify-center gap-8 px-4">
-        <div className="flex w-1/2 flex-col items-center gap-4">
+      <div className="flex flex-col items-center justify-center gap-8 px-4 md:flex-row">
+        <div className="flex w-full flex-col items-center gap-4 md:w-1/2">
           <h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
             종소리 설정
           </h3>
           <p className="text-[min(max(0.875rem,1.5vw),1.4rem)] font-medium text-neutral-600">
-            시간에 따른 종소리를 내마음대로
+            시간에 따른 종소리를 내 마음대로
             <br />
-            커스터마이징 할 수 있어요.
+            사용자 지정할 수 있어요.
           </p>
         </div>
-        <img src={bellSetting} alt="section302" className="flex w-1/2" />
+        <img
+          src={bellSetting}
+          alt="종소리 설정 화면"
+          loading="lazy"
+          decoding="async"
+          className="w-full md:w-1/2"
+        />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="flex flex-row items-center justify-center gap-8 px-4">
<div className="flex w-1/2 flex-col items-center gap-4">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
종소리 설정
</h3>
<p className="text-[min(max(0.875rem,1.5vw),1.4rem)] font-medium text-neutral-600">
시간에 따른 종소리를 내마음대로
<br />
커스터마이징 있어요.
</p>
</div>
<img src={bellSetting} alt="section302" className="flex w-1/2" />
</div>
<div className="flex flex-col items-center justify-center gap-8 px-4 md:flex-row">
<div className="flex w-full flex-col items-center gap-4 md:w-1/2">
<h3 className="text-[min(max(1.1rem,1.75vw),1.8rem)] font-semibold">
종소리 설정
</h3>
<p className="text-[min(max(0.875rem,1.5vw),1.4rem)] font-medium text-neutral-600">
시간에 따른 종소리를 마음대로
<br />
사용자 지정할 있어요.
</p>
</div>
<img
src={bellSetting}
alt="종소리 설정 화면"
loading="lazy"
decoding="async"
className="w-full md:w-1/2"
/>
</div>
🤖 Prompt for AI Agents
In src/page/LandingPage/components/TimeTableSection.tsx around lines 45 to 57,
fix Korean spacing and accessibility: change “내마음대로” to “내 마음대로” and replace
“커스터마이징 할 수 있어요.” with either “커스터마이징할 수 있어요.” or preferably “사용자 지정할 수 있어요.”,
and improve the img element by providing a more descriptive alt (e.g., “시간별 종소리
설정 일러스트” or similar) and enable lazy loading (add loading="lazy" or switch to an
image component that supports async/lazy loading).

Copy link
Contributor

@i-meant-to-be i-meant-to-be left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

빠른 구현 고생하셨습니다! 리뷰 몇 가지 있어 확인해주시면 감사하겠습니당

</h1>
<h2 className="mt-4 text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
원하는 때에 <br />
작전시간 사용하기
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

대안: 띄어쓰기 추가

'작전 시간'으로 작성하면 더 깔끔해 보일 듯합니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
src/page/LandingPage/components/TemplateSelection.tsx (5)

5-5: 컴포넌트 반환 타입 명시로 타입 안정성 강화

반환 타입을 명시해 TS 추론 흔들림을 방지하세요.

-export default function TemplateSelection() {
+export default function TemplateSelection(): JSX.Element {

14-16: 구분선 div → hr로 시맨틱/접근성 개선

시맨틱 태그(hr) 사용 및 aria-hidden 처리로 스크린리더 노이즈를 줄이는 것이 좋습니다.

-      <div className="mx-auto h-px w-11/12 bg-neutral-200" /> {/* 구분선 */}
+      <hr className="mx-auto w-11/12 border-0 border-t border-neutral-200" aria-hidden="true" />
-      <div className="mx-auto h-px w-11/12 bg-neutral-200" />
+      <hr className="mx-auto w-11/12 border-0 border-t border-neutral-200" aria-hidden="true" />

13-17: 반복 렌더링 DRY: 배열 map으로 단순화

중복 코드를 제거하면 유지보수가 쉬워집니다. Fragment key를 위해 react에서 Fragment import가 필요합니다.

-      <TamplateList data={DEBATE_TEMPLATE.ONE} />
-      <hr className="mx-auto w-11/12 border-0 border-t border-neutral-200" aria-hidden="true" />
-      <TamplateList data={DEBATE_TEMPLATE.TWO} />
-      <hr className="mx-auto w-11/12 border-0 border-t border-neutral-200" aria-hidden="true" />
-      <TamplateList data={DEBATE_TEMPLATE.THREE} />
+      {[
+        DEBATE_TEMPLATE.ONE,
+        DEBATE_TEMPLATE.TWO,
+        DEBATE_TEMPLATE.THREE,
+      ].map((group, idx, arr) => (
+        <Fragment key={idx}>
+          <TamplateList data={group} />
+          {idx < arr.length - 1 && (
+            <hr
+              className="mx-auto w-11/12 border-0 border-t border-neutral-200"
+              aria-hidden="true"
+            />
+          )}
+        </Fragment>
+      ))}

추가: 파일 상단에 아래 import가 필요합니다.

import { Fragment } from 'react';

7-12: 섹션-헤딩 연계로 접근성 향상(aria-labelledby 연결)

섹션이 어떤 헤딩에 의해 라벨링되는지 명시하면 내비게이션 보조기기에 유리합니다.

-    <section id="template-selection" className="flex flex-col gap-12">
+    <section id="template-selection" aria-labelledby="template-selection-heading" className="flex flex-col gap-12">
       <div>
-        <h2 className="mt-4 text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
+        <h2 id="template-selection-heading" className="mt-4 text-left text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
           다양한 토론 템플릿을 원클릭으로 만나보세요!
         </h2>
       </div>

1-3: Tamplate → Template 네이밍 통일 권장
파일 전반에 걸쳐 Tamplate(오탈자) 표기가 발견됩니다. 기능 안정성 유지를 위해 이번 PR에는 그대로 두고, 다음 PR에서 일괄 리네이밍을 진행해주세요.

# Tamplate 및 debate_tamplate 사용 위치 확인
rg -nP '\b(?:Tamplate|debate_tamplate)\b' -C1 --glob '*.{ts,tsx}'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 47ec083 and 86ff327.

📒 Files selected for processing (2)
  • src/constants/debate_tamplate.ts (1 hunks)
  • src/page/LandingPage/components/TemplateSelection.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/constants/debate_tamplate.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/page/LandingPage/components/TemplateSelection.tsx (3)
src/page/LandingPage/components/TamplateList.tsx (1)
  • TamplateList (7-21)
src/constants/debate_tamplate.ts (1)
  • DEBATE_TEMPLATE (22-264)
src/page/LandingPage/components/TamplateApplicationSection.tsx (1)
  • TamplateApplicationSection (3-29)
🔇 Additional comments (1)
src/page/LandingPage/components/TemplateSelection.tsx (1)

7-7: id 중복 없음 확인됨

전체 .tsx 파일에서 id="template-selection"가 한 번만 사용됨을 확인했습니다.

Copy link
Contributor

@i-meant-to-be i-meant-to-be left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했습니다. 빠른 반영 감사합니다, 치코!
작성한 리뷰 2건은 기술적인 내용은 아니라 승인 남겨요. 바쁘셨을 것 같은데 짬 내서 작업 쳐내주시느라 고생하셨습니다 😭

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

권장: 스펠링 수정

아래처럼 스펠링을 수정하는 게 좋아 보여요:

  • 파일 이름 TamplateApplicationSection.tsx > TemplateApplicationSection.tsx
  • 함수 이름 TamplateApplicationSection > TemplateApplicationSection

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했어요. 감사합니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

권장: 스펠링 수정

아래처럼 스펠링을 수정하는 게 좋아 보여요:

  • 파일 이름 TamplateList.tsx > TemplateList.tsx
  • 함수 이름 TamplateList> TemplateList

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다

Copy link
Contributor

@useon useon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

치코 ! 바쁘신데 빠르게 구현해 주셔서 감사합니다 !! 몇 가지 리뷰를 남겼어요 ~!!! PR에 잘 설명해 주셔서 이해하기 더 쉬웠어요 !!!!! 반응형으로 3개에서 2개 되는 것도 너무 좋네요 짱짱 ~!!!! 👍

{/* 홈 설정 */}
<TableSection onLogin={handleTableSectionLoginButtonClick} />
</div>
<div className="flex w-full flex-col items-center bg-black py-48">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 홈설정에 리뷰가 원래 함께 들어가 있었는데 이번에 바뀌면서 분리를 한 것이군요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 기존에는 배경색이 둘다 같아서 같이 두었는데 이번에 배경색이 변경되면서 분리되었습니다

@@ -0,0 +1,75 @@
// src/page/LandingPage/components/ScrollHint.tsx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 경로 주석을 달아놓은 이유가 궁금해요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gpt의 잔재... 아마 아이콘 변경해달라고 하면서 추가했나봅니다. 삭제하겠습니다.

// </svg>
// 아래로 스크롤
// </div>
// </div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 주석은 왜 남겨놓으셨나용?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아직 스크롤 디자인 확정나지 않아서 일단 주석처리했습니다. 회의를 통해 확정이 나왔으니 지우도록 하겠습니다.

<img src={section302} alt="section302" className="flex w-1/2" />
</div>

<div className="flex flex-col items-center justify-center gap-1 text-[min(max(1.25rem,2.75vw),2.5rem)] font-bold">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

바꾸는 김에 로그인해 주세요.로 띄어쓰기 해주면 좋을 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다

@@ -0,0 +1,29 @@
import section501 from '../../../assets/landing/section5-1.png';
import { LANDING_URLS } from '../../../constants/urls';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 사이에 엔터 하나만 있으면 좋을 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 사이라는 것이 요 사이라는 건가요? 일단 import문과 컴포넌트 선언문 사이에 엔터를 추가하긴 했습니다.

템플릿 신청하기
</p>
<p className="text-[min(max(0.875rem,1.25vw),1.2rem)] text-neutral-400">
새로운 템플릿도 신청해볼까요?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것도 신청해 볼까요?로 띄어쓰기 살짝만 수정해 주세오!!!!!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

topThreshold?: number; //최상단 판정 임계값 (px)
};

export default function ScrollHint({ topThreshold = 10 }: ScrollHintProps) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

width가 700 px인 경우에는 아래와 같이 스크롤 유도 컴포넌트와 글자가 겹치게 되네요 .. 😂 스크롤 유도 컴포넌트를 없애거나 아니면 스크롤 유도 컴포넌트 다음에 다음 요소가 뜨도록 높이 조정이 필요할 것 같아요
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 회의에서 배경을 지정해서 스크롤 유도 컴포넌트를 위로 띄우는 방식으로 결정을 했었습니다.
image

대충 이런 느낌입니다.


{/* 액션 리스트 */}
<ul className="mt-5 flex flex-col gap-1">
{actions.map((a, i) => (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a나 i 보다는 action, index 이렇게 구체적으로 명시하는 것은 어떨까요 ?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했습니다.

].join(' ')}
>
{data.map((t) => (
<TemplateCard key={t.title} {...t} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

템플릿을 간단하게 t라고 적은 것 같은데 ...t 이렇게 적는 것보다는 그냥 template를 명시하는 것이 더 명확하게 읽힐 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 수정했습니다

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/constants/debate_template.ts (5)

14-16: 동일 명칭 함수로 인한 혼동 가능성 — 목적을 명확히 주석으로 구분하세요.

util/arrayEncoding.ts의 createTableShareUrl(원본 객체를 받아 인코딩 수행)과 이름이 같아 오토임포트/코드 탐색 시 혼동 여지가 큽니다. 최소한 주석으로 “이미 인코딩된 문자열을 받는다”는 점을 명시하세요. (함수명 변경은 선택)

주석 예시:

+/**
+ * 이미 URL-safe 하게 인코딩된 문자열(encodedData)을 받아 공유 링크를 생성합니다.
+ * raw 데이터를 인코딩하는 util/arrayEncoding.ts의 동명 함수와 목적이 다릅니다.
+ */

23-89: 빈 문자열 subtitle은 생략 권장.

subtitle이 선택 필드이므로 '' 대신 필드 자체를 생략하면 렌더링 분기와 타입 의미가 더 명확합니다. (아래는 대표 1건 예시)

       {
         title: '산업통상자원부',
-        subtitle: '',
         logoSrc: government,

1-13: 자산 변수 네이밍 통일(사소한 니트픽).

snake_case 변수(kondae_time, han_alm 등)는 camelCase(kondaeTime, hanAlm)로 통일하면 코드 일관성이 좋아집니다. 현재 파일 내 참조가 많으므로 우선순위 낮게 점진 적용을 권장합니다.


22-264: 불변 상수 및 타입 정확성 강화 (as const + satisfies)
const assertion과 satisfies를 활용해 오탈자나 프로퍼티 누락 시 즉시 오류를 검출할 수 있습니다. TS 4.9 이상(현재 5.7.2) 지원됩니다.

src/constants/debate_template.ts 수정:

-export const DEBATE_TEMPLATE: DebateTemplateList = {
+export const DEBATE_TEMPLATE = {
   /* 내용 동일 */
-};
+} as const satisfies DebateTemplateList;

17-21: 의미 있는 카테고리 키 리팩터링 제안
DEBATE_TEMPLATE 인터페이스의 ONE/TWO/THREE 대신 소비 코드에서 직관적인 키(예: governmentAndOrgs, universityClubs, localGovAndAlliances 등)를 사용하세요. 변경 시 아래 소비처도 함께 업데이트가 필요합니다:

  • src/page/LandingPage/components/TemplateSelection.tsx:13 (DEBATE_TEMPLATE.ONE)
  • src/page/LandingPage/components/TemplateSelection.tsx:15 (DEBATE_TEMPLATE.TWO)
  • src/page/LandingPage/components/TemplateSelection.tsx:17 (DEBATE_TEMPLATE.THREE)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 86ff327 and b5bf70f.

📒 Files selected for processing (3)
  • src/constants/debate_template.ts (1 hunks)
  • src/page/LandingPage/components/TableSection.tsx (2 hunks)
  • src/page/LandingPage/components/TemplateSelection.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/page/LandingPage/components/TemplateSelection.tsx
  • src/page/LandingPage/components/TableSection.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
src/constants/debate_template.ts (2)
src/util/arrayEncoding.ts (1)
  • createTableShareUrl (23-29)
src/type/type.ts (1)
  • DebateTemplate (80-86)
🔇 Additional comments (1)
src/constants/debate_template.ts (1)

22-264: 액션 링크: target/rel 속성 확인
Action 타입에 target/rel 필드가 정의되어 있지 않습니다. 렌더러에서 공유 링크에 대해 기본적으로 target="_blank" 및 rel="noopener" (또는 rel="noopener noreferrer")가 적용되는지 직접 확인하세요.

Comment on lines +14 to +16
function createTableShareUrl(encodeData: string): string {
return `${import.meta.env.VITE_SHARE_BASE_URL}/share?data=${encodeData}`;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

[중요] 환경변수 미설정 시 잘못된 링크 생성 가능 — 가드 추가 및 URL API로 안전하게 조립하세요.

VITE_SHARE_BASE_URL가 비어 있으면 href가 "undefined/share?data=…"로 생성됩니다. URL API를 사용해 베이스/슬래시 처리도 안전하게 해주세요.

적용 예시:

-function createTableShareUrl(encodeData: string): string {
-  return `${import.meta.env.VITE_SHARE_BASE_URL}/share?data=${encodeData}`;
-}
+const SHARE_BASE_URL = import.meta.env.VITE_SHARE_BASE_URL as string | undefined;
+
+function createTableShareUrl(encodedData: string): string {
+  // dev/test 안전 가드: 베이스가 없으면 상대경로로 폴백
+  if (!SHARE_BASE_URL) {
+    return `/share?data=${encodedData}`;
+  }
+  const url = new URL('/share', SHARE_BASE_URL);
+  url.searchParams.set('data', encodedData);
+  return url.toString();
+}

다음 스크립트로 .env* 파일에 VITE_SHARE_BASE_URL이 정의되어 있는지 확인해 주세요.


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "[.env*에서 VITE_SHARE_BASE_URL 검색]"
rg -n --glob ".env*" --hidden --no-ignore "VITE_SHARE_BASE_URL" || echo "없음"

Length of output: 345


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "[.env* 파일 찾기]"
find . -maxdepth 2 -type f -name ".env*" || echo "env 파일이 없습니다"

echo "[.env* 파일에서 VITE_SHARE_BASE_URL 검색]"
find . -maxdepth 2 -type f -name ".env*" -print0 | xargs -0 rg -n "VITE_SHARE_BASE_URL" || echo "없음"

Length of output: 555


VITE_SHARE_BASE_URL 가드 추가 및 URL API 활용
import.meta.env.VITE_SHARE_BASE_URL가 비어 있으면 “undefined/share?…” 형태의 잘못된 링크가 생성됩니다. URL API로 베이스/슬래시 처리를 안전하게 수행하고, 환경변수가 없을 땐 /share?data=…로 폴백하세요.

- function createTableShareUrl(encodeData: string): string {
-   return `${import.meta.env.VITE_SHARE_BASE_URL}/share?data=${encodeData}`;
- }
+ const SHARE_BASE_URL = import.meta.env.VITE_SHARE_BASE_URL;
+
+ function createTableShareUrl(encodedData: string): string {
+   if (!SHARE_BASE_URL) {
+     return `/share?data=${encodedData}`;
+   }
+   const url = new URL('/share', SHARE_BASE_URL);
+   url.searchParams.set('data', encodedData);
+   return url.toString();
+ }

적용 필요 위치:

  • src/constants/debate_template.ts:14-16
  • src/hooks/useTableShare.tsx:14
  • src/page/LandingPage/hooks/useLandingPageHandlers.ts:18
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function createTableShareUrl(encodeData: string): string {
return `${import.meta.env.VITE_SHARE_BASE_URL}/share?data=${encodeData}`;
}
// src/constants/debate_template.ts
const SHARE_BASE_URL = import.meta.env.VITE_SHARE_BASE_URL;
function createTableShareUrl(encodedData: string): string {
if (!SHARE_BASE_URL) {
return `/share?data=${encodedData}`;
}
const url = new URL('/share', SHARE_BASE_URL);
url.searchParams.set('data', encodedData);
return url.toString();
}

@jaeml06 jaeml06 requested a review from useon September 5, 2025 15:11
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (7)
src/page/LandingPage/components/TemplateApplicationSection.tsx (3)

6-6: 모바일 반응형·접근성(시맨틱)·외부링크(보안)·이미지 성능 소폭 개선 제안

한 번에 정리된 제안입니다: 섹션에 heading 연계, 모바일 스택 정렬, 로 외부 링크 열기, 이미지 lazy 로딩/대체텍스트 정리.

-    <section className="flex flex-row justify-between gap-1">
+    <section
+      aria-labelledby="template-apply-heading"
+      className="flex flex-col items-center justify-between gap-6 md:flex-row"
+    >

-        <p className="text-[min(max(1.2rem,2vw),2.3rem)] font-semibold">
-          템플릿 신청하기
-        </p>
+        <h2
+          id="template-apply-heading"
+          className="text-[min(max(1.2rem,2vw),2.3rem)] font-semibold"
+        >
+          템플릿 신청하기
+        </h2>

-        <button
-          onClick={() =>
-            window.open(
-              LANDING_URLS.REPORT_FORM_URL,
-              '_blank',
-              'noopener,noreferrer',
-            )
-          }
-          className="rounded-full border border-neutral-300 bg-neutral-200 px-9 py-2 text-[min(max(0.875rem,1.25vw),1.2rem)] font-medium text-default-black transition-all duration-100 hover:bg-brand"
-        >
-          신청하기
-        </button>
+        <a
+          href={LANDING_URLS.REPORT_FORM_URL}
+          target="_blank"
+          rel="noopener noreferrer"
+          className="rounded-full border border-neutral-300 bg-neutral-200 px-9 py-2 text-[min(max(0.875rem,1.25vw),1.2rem)] font-medium text-default-black transition-all duration-100 hover:bg-brand"
+        >
+          신청하기
+        </a>

-      <img src={section501} alt="section501" className="w-[30%]" />
+      <img
+        src={section501}
+        alt=""
+        className="w-full max-w-[420px] md:w-[30%] h-auto"
+        loading="lazy"
+        decoding="async"
+        aria-hidden="true"
+      />

메모:

  • 외부 링크는 a + target/_blank + rel 조합이 기본기라 유지보수/보안/접근성 모두에 유리합니다.
  • alt가 장식 이미지라면 빈 문자열이 적절합니다(스크린리더 무시). 의미가 있다면 구체적인 대체텍스트로 바꿔주세요.

Also applies to: 8-13, 14-25, 27-27


8-13: 카피 국제화(i18n) 대응 여지

고정 한글 문자열은 국제화 리소스로 분리해두면 향후 다국어 확장 시 변경 범위가 줄어듭니다.

Also applies to: 24-24


1-1: 이미지 포맷 최적화 검토

가능하면 PNG 대신 WebP/AVIF 소스도 제공( 혹은 빌드타임 변환)해 LCP/전송량을 낮추는 것을 권장합니다.

src/page/LandingPage/components/TemplateList.tsx (4)

1-1: 타입 전용 import, 불변 Props, prop 명 명확화 제안

  • 타입만 가져오는 경우 import type로 전환해 트리셰이킹/빌드 최적화.
  • 외부에서 전달되는 배열은 수정 불가하도록 ReadonlyArray로 선언.
  • data 대신 도메인 의미가 드러나는 templates로 명명.
-import { DebateTemplate } from '../../../type/type';
+import type { DebateTemplate } from '../../../type/type';

-interface TemplateListProps {
-  data: DebateTemplate[];
-}
+interface TemplateListProps {
+  templates: ReadonlyArray<DebateTemplate>;
+}

-export default function TemplateList({ data }: TemplateListProps) {
+export default function TemplateList({ templates }: TemplateListProps) {
-      {data.map((template) => (
+      {templates.map((template) => (

Also applies to: 4-6, 7-7, 12-12


10-10: 불필요한 JSX 중괄호 제거

리터럴 문자열엔 중괄호 불필요합니다.

-      className={'grid grid-cols-2 gap-5 lg:grid-cols-3'} // 2열, lg에서 3열
+      className="grid grid-cols-2 gap-5 lg:grid-cols-3" // 2열, lg에서 3열

12-15: 빈 목록(0개) 렌더링 처리

템플릿이 비어 있을 때의 사용자 피드백(문구/스켈레톤)을 추가하면 UX가 좋아집니다. 현재 코드 기준으로 바로 적용 가능한 예시는 아래와 같습니다.

-      {data.map((template) => (
-        <TemplateCard key={template.title} {...template} />
-      ))}
+      {data.length === 0 ? (
+        <p className="col-span-full text-center text-neutral-500">
+          템플릿이 없습니다.
+        </p>
+      ) : (
+        data.map((template) => (
+          <TemplateCard key={template.title} {...template} />
+        ))
+      )}

12-14: 고유 id 도입 권장 (옵션)

현재 모든 template.title 값이 유니크하여 key 충돌 우려는 없으나, 향후 데이터 변경 및 재정렬 시 안정적인 렌더링을 위해 id 필드를 도입하고 key로 사용하는 것을 권장합니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b5bf70f and 03b0848.

📒 Files selected for processing (6)
  • src/page/LandingPage/components/ScrollHint.tsx (1 hunks)
  • src/page/LandingPage/components/TableSection.tsx (3 hunks)
  • src/page/LandingPage/components/TemplateApplicationSection.tsx (1 hunks)
  • src/page/LandingPage/components/TemplateCard.tsx (1 hunks)
  • src/page/LandingPage/components/TemplateList.tsx (1 hunks)
  • src/page/LandingPage/components/TemplateSelection.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/page/LandingPage/components/TemplateCard.tsx
  • src/page/LandingPage/components/ScrollHint.tsx
  • src/page/LandingPage/components/TemplateSelection.tsx
  • src/page/LandingPage/components/TableSection.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
src/page/LandingPage/components/TemplateApplicationSection.tsx (1)
src/constants/urls.ts (1)
  • LANDING_URLS (1-7)
src/page/LandingPage/components/TemplateList.tsx (2)
src/type/type.ts (1)
  • DebateTemplate (80-86)
src/page/LandingPage/components/TemplateCard.tsx (1)
  • TemplateCard (3-68)
🔇 Additional comments (1)
src/page/LandingPage/components/TemplateApplicationSection.tsx (1)

4-30: 초기 구현 전반 LGTM

기본 레이아웃/카피/링크 연동 모두 무난합니다. 아래는 접근성/반응형/미세 성능 개선 위주의 제안입니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/constants/urls.ts (1)

7-7: 용어 정합성(REGISTER vs SUBMIT) 팀 가이드와 일치하는지 재확인 권장

PR 설명에서 “템플릿 제출 링크”라고 표기되어 있어, 키를 TEMPLATE_SUBMISSION_URL(또는 TEMPLATE_SUBMIT_URL)처럼 명사형/일관 용어로 맞추는 방안도 고려해볼 수 있습니다. 지금 그대로도 문제는 없으므로 선택 사항입니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03b0848 and 9335929.

📒 Files selected for processing (3)
  • src/constants/debate_template.ts (1 hunks)
  • src/constants/urls.ts (1 hunks)
  • src/page/LandingPage/components/TemplateApplicationSection.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/page/LandingPage/components/TemplateApplicationSection.tsx
  • src/constants/debate_template.ts
🔇 Additional comments (2)
src/constants/urls.ts (2)

7-7: LGTM — 새 템플릿 제출 URL 상수 추가가 일관적입니다.

키 네이밍과 _URL 접미사, as const 사용까지 기존 패턴과 잘 맞습니다.


7-7: 검증 완료: 외부 링크 안전 조치 적용됨
TemplateApplicationSection의 window.open 호출에 이미 'noopener,noreferrer'가 포함되어 있고, 템플릿 제출용 <a> 태그 사용처도 없습니다.

Copy link
Contributor

@useon useon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 요청한 부분 반영 확인했습니다 꼼꼼하게 반영해 주셔서 감사해요오 ~ !!!! 바로 어프루브 ,,ㅎㅎ

@jaeml06 jaeml06 merged commit af2e52b into develop Sep 6, 2025
1 of 2 checks passed
@jaeml06 jaeml06 deleted the feat/#355 branch September 6, 2025 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 메인페이지 디자인 변경 , 토론 템플릿 추가

4 participants