feat: modernized web application

This commit is contained in:
2026-03-31 15:21:08 +09:00
parent f7019403c4
commit b5a1c08024
47 changed files with 1569 additions and 103 deletions

View File

@@ -0,0 +1,34 @@
import style from '@/styles/web.module.scss';
export default function AboutPage() {
return (
<div className={style.guideBody}>
<h2>About</h2>
<hr />
<div className={style.aboutNoticeBlock}>
<br />
<p>
Covid-19
</p>
<p>
Switch版0
</p>
<p>
使
</p>
<p></p>
<p>
</p>
<p></p>
<div className={style.sheepAbout} />
<div className={style.aboutContactBox}>
<a href="https://forms.gle/Dn4p7cFEPLK1zcTz5" rel="noopener noreferrer" target="_blank">
&nbsp;
</a>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,15 @@
import { NextResponse } from 'next/server';
import { getArchiveItems } from '@/lib/data';
export const dynamic = 'force-dynamic';
export async function GET() {
try {
const data = await getArchiveItems();
return NextResponse.json(data);
} catch (e) {
console.error(e);
return NextResponse.json([], { status: 500 });
}
}

View File

@@ -0,0 +1,15 @@
import { NextResponse } from 'next/server';
import { getContactItems } from '@/lib/data';
export const dynamic = 'force-dynamic';
export async function GET() {
try {
const data = await getContactItems();
return NextResponse.json(data);
} catch (e) {
console.error(e);
return NextResponse.json([], { status: 500 });
}
}

View File

@@ -0,0 +1,15 @@
import { NextResponse } from 'next/server';
import { getGuideItems } from '@/lib/data';
export const dynamic = 'force-dynamic';
export async function GET() {
try {
const data = await getGuideItems();
return NextResponse.json(data);
} catch (e) {
console.error(e);
return NextResponse.json([], { status: 500 });
}
}

View File

@@ -0,0 +1,23 @@
import { NextResponse } from 'next/server';
import { getPlayersForTournament } from '@/lib/data';
export const dynamic = 'force-dynamic';
type RouteContext = {
params: Promise<{ key: string }>;
};
export async function GET(_request: Request, context: RouteContext) {
try {
const { key } = await context.params;
const data = await getPlayersForTournament(key);
if (data === null) {
return NextResponse.json({ error: 'Tournament not found' }, { status: 404 });
}
return NextResponse.json(data);
} catch (e) {
console.error(e);
return NextResponse.json([], { status: 500 });
}
}

View File

@@ -0,0 +1,15 @@
import { NextResponse } from 'next/server';
import { getAllPlayers } from '@/lib/data';
export const dynamic = 'force-dynamic';
export async function GET() {
try {
const data = await getAllPlayers();
return NextResponse.json(data);
} catch (e) {
console.error(e);
return NextResponse.json([], { status: 500 });
}
}

View File

@@ -0,0 +1,9 @@
import { ArchiveVideoList } from '@/components/ArchiveVideoList';
import { getArchiveItems } from '@/lib/data';
export const dynamic = 'force-dynamic';
export default async function ArchivePage() {
const items = await getArchiveItems();
return <ArchiveVideoList items={items} />;
}

View File

@@ -0,0 +1,9 @@
import { ContactList } from '@/components/ContactList';
import { getContactItems } from '@/lib/data';
export const dynamic = 'force-dynamic';
export default async function ContactPage() {
const items = await getContactItems();
return <ContactList items={items} />;
}

View File

@@ -0,0 +1,17 @@
body {
margin: 0;
font-family: var(--font-mplus), -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
html,
body {
min-height: 100%;
}

View File

@@ -0,0 +1,9 @@
import { GuideVideoList } from '@/components/GuideVideoList';
import { getGuideItems } from '@/lib/data';
export const dynamic = 'force-dynamic';
export default async function GuidePage() {
const items = await getGuideItems();
return <GuideVideoList items={items} />;
}

46
nextjs/src/app/layout.tsx Normal file
View File

@@ -0,0 +1,46 @@
import type { Metadata, Viewport } from 'next';
import { Indie_Flower, M_PLUS_Rounded_1c } from 'next/font/google';
import type { ReactNode } from 'react';
import { I18nProvider } from '@/components/I18nProvider';
import { SiteLayout } from '@/components/SiteLayout';
import 'semantic-ui-css/semantic.min.css';
import './globals.css';
const indieFlower = Indie_Flower({
weight: '400',
subsets: ['latin'],
variable: '--font-indie',
display: 'swap',
});
const mPlusRounded = M_PLUS_Rounded_1c({
weight: ['400', '700'],
subsets: ['latin'],
variable: '--font-mplus',
display: 'swap',
adjustFontFallback: false,
});
export const metadata: Metadata = {
title: 'キャサリン faito crab',
description: 'キャサリン faito crab',
manifest: '/manifest.json',
};
export const viewport: Viewport = {
themeColor: '#ff2d7c',
};
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="ja" className={`${indieFlower.variable} ${mPlusRounded.variable}`}>
<body>
<I18nProvider>
<SiteLayout>{children}</SiteLayout>
</I18nProvider>
</body>
</html>
);
}

View File

@@ -0,0 +1,7 @@
export default function NotFound() {
return (
<div>
<p>404</p>
</div>
);
}

34
nextjs/src/app/page.tsx Normal file
View File

@@ -0,0 +1,34 @@
import style from '@/styles/web.module.scss';
export default function HomePage() {
return (
<div className={style.mainBody}>
<div className={style.evojapan2025} />
<div className={style.padding} />
<div className={style.evojapan2023kaisaikettei} />
<div className={style.padding} />
<div className={style.group}>
<div className={style.evojapan2023catherinetonamel}>
<a href="https://tonamel.com/competition/VD6y8" rel="noopener noreferrer" target="_blank">
&nbsp;
</a>
</div>
<div className={style.evojapan2023catherinefullbodytonamel}>
<a href="https://tonamel.com/competition/dgdQ9" rel="noopener noreferrer" target="_blank">
&nbsp;
</a>
</div>
</div>
<div className={style.padding} />
<div className={style.twitchHome}>
<a
href="https://www.twitch.tv/catherine_faito_crab"
rel="noopener noreferrer"
target="_blank"
>
&nbsp;
</a>
</div>
</div>
);
}

View File

@@ -0,0 +1,9 @@
import { PlayersList } from '@/components/PlayersList';
import { getAllPlayers } from '@/lib/data';
export const dynamic = 'force-dynamic';
export default async function PlayersPage() {
const players = await getAllPlayers();
return <PlayersList players={players} />;
}

View File

@@ -0,0 +1,19 @@
import { notFound } from 'next/navigation';
import { PlayersList } from '@/components/PlayersList';
import { getPlayersForTournament } from '@/lib/data';
export const dynamic = 'force-dynamic';
type PageProps = {
params: Promise<{ tournament_key: string }>;
};
export default async function TournamentPlayersPage({ params }: PageProps) {
const { tournament_key } = await params;
const players = await getPlayersForTournament(tournament_key);
if (players === null) {
notFound();
}
return <PlayersList players={players} />;
}

View File

@@ -0,0 +1,9 @@
import style from '@/styles/web.module.scss';
export default function ScoreboardPage() {
return (
<div className={style.mainBody}>
<div className={style.scoreboardImage} />
</div>
);
}

View File

@@ -0,0 +1,7 @@
export default function TournamentsPage() {
return (
<div>
<p>Tournaments</p>
</div>
);
}