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

74
nextjs/src/lib/data.ts Normal file
View File

@@ -0,0 +1,74 @@
import type { RowDataPacket } from 'mysql2';
import { getPool } from './db';
import type { IContactQuestion } from '@/models/IContactQuestion';
import type { IGuideItem } from '@/models/IGuideItem';
import type { IPlayerInfo } from '@/models/IPlayerInfo';
let tournamentIdByKeyPromise: Promise<Record<string, number>> | null = null;
async function loadTournamentMap(): Promise<Record<string, number>> {
const pool = getPool();
const [rows] = await pool.query<RowDataPacket[]>(
'SELECT id, tournament_key FROM tournaments'
);
const map: Record<string, number> = {};
for (const row of rows) {
map[row.tournament_key as string] = row.id as number;
}
return map;
}
export async function getTournamentIdByKey(): Promise<Record<string, number>> {
if (!tournamentIdByKeyPromise) {
tournamentIdByKeyPromise = loadTournamentMap();
}
return tournamentIdByKeyPromise;
}
export async function getAllPlayers(): Promise<IPlayerInfo[]> {
const pool = getPool();
const [rows] = await pool.query<RowDataPacket[]>(
`SELECT p.id, p.player_key, p.player_name, p.description, p.image, c.name_id, c.name, c.name_jp
FROM players p
JOIN characters c ON c.id = p.character_id`
);
return rows as IPlayerInfo[];
}
export async function getPlayersForTournament(
tournamentKey: string
): Promise<IPlayerInfo[] | null> {
const tournaments = await getTournamentIdByKey();
const tournamentId = tournaments[tournamentKey];
if (tournamentId === undefined) {
return null;
}
const pool = getPool();
const [rows] = await pool.query<RowDataPacket[]>(
`SELECT p.id, p.player_key, p.player_name, p.description, p.image, c.name_id, c.name, c.name_jp
FROM players p
JOIN player_to_tournament ptt ON p.id = ptt.player_id
JOIN characters c ON c.id = p.character_id
WHERE ptt.tournament_id = ?`,
[tournamentId]
);
return rows as IPlayerInfo[];
}
export async function getGuideItems(): Promise<IGuideItem[]> {
const pool = getPool();
const [rows] = await pool.query<RowDataPacket[]>('SELECT * FROM guide');
return rows as IGuideItem[];
}
export async function getArchiveItems(): Promise<IGuideItem[]> {
const pool = getPool();
const [rows] = await pool.query<RowDataPacket[]>('SELECT * FROM archive');
return rows as IGuideItem[];
}
export async function getContactItems(): Promise<IContactQuestion[]> {
const pool = getPool();
const [rows] = await pool.query<RowDataPacket[]>('SELECT * FROM contact');
return rows as IContactQuestion[];
}

23
nextjs/src/lib/db.ts Normal file
View File

@@ -0,0 +1,23 @@
import mysql from 'mysql2/promise';
function createPool(): mysql.Pool {
const port = process.env.DB_PORT ? parseInt(process.env.DB_PORT, 10) : 3306;
return mysql.createPool({
connectionLimit: 10,
port,
host: process.env.DB_ENDPOINT,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: 'catherine_league',
charset: 'utf8mb4',
});
}
let pool: mysql.Pool | undefined;
export function getPool(): mysql.Pool {
if (!pool) {
pool = createPool();
}
return pool;
}