- 백엔드: FastAPI + SQLAlchemy(async) + PostgreSQL, 별도 워커(APScheduler) - 프론트: React 19 + Vite + TS + Tailwind v4 (기존 UI 이식, API 연동) - docker-compose: db · api · worker · frontend 일괄 실행 - 경기 일정: openfootball 매일 09:00 크롤링 → DB upsert (신규 경기 자동 삽입+예측 생성) - AI 예측: GPT·Claude·Gemini 실 API 매일 생성 → DB 저장 → 조회 (목데이터 제거) - 투표창: 오픈 킥오프 D-2 / 마감 킥오프 1시간 전, lockAt 백엔드 전달→프론트 카운트다운 - 채점/리더보드: docs/SCORING.md 기준 누적 포인트 - crowd: 0 시작, 실제 제출로만 증분 - 구 Next.js/Firebase 파일 제거, README/AGENTS 갱신 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
25 lines
791 B
TypeScript
25 lines
791 B
TypeScript
import { Link, useLocation } from "react-router-dom";
|
|
import type { Lang } from "@/lib/i18n";
|
|
|
|
// KO / EN 토글. 현재 경로 유지 + ?lang 토글.
|
|
export default function LangSwitch({ lang }: { lang: Lang }) {
|
|
const { pathname } = useLocation();
|
|
const href = (l: Lang) => (l === "en" ? `${pathname}?lang=en` : pathname);
|
|
const langs: Lang[] = ["ko", "en"];
|
|
return (
|
|
<div className="flex items-center overflow-hidden rounded-full border border-white/15 text-[11px] font-extrabold">
|
|
{langs.map((l) => (
|
|
<Link
|
|
key={l}
|
|
to={href(l)}
|
|
className={`px-2.5 py-1 transition ${
|
|
lang === l ? "bg-white text-[#14171C]" : "text-white/65"
|
|
}`}
|
|
>
|
|
{l.toUpperCase()}
|
|
</Link>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|