regionals
This commit is contained in:
269
test.js
Normal file
269
test.js
Normal file
@@ -0,0 +1,269 @@
|
||||
import PocketBase from "pocketbase";
|
||||
import * as xlsx from "xlsx";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
import { createTeamsService } from "./src/lib/pocketbase/services/teams.ts";
|
||||
import { createPlayersService } from "./src/lib/pocketbase/services/players.ts";
|
||||
import { createMatchesService } from "./src/lib/pocketbase/services/matches.ts";
|
||||
import { createTournamentsService } from "./src/lib/pocketbase/services/tournaments.ts";
|
||||
|
||||
const POCKETBASE_URL = "http://127.0.0.1:8090";
|
||||
const EXCEL_FILE_PATH = "./Teams-2.xlsx";
|
||||
|
||||
const ADMIN_EMAIL = "kyle.yohler@gmail.com";
|
||||
const ADMIN_PASSWORD = "xj44aqz9CWrNNM0o";
|
||||
|
||||
// --- Helpers ---
|
||||
async function createPlayerIfMissing(playersService, nameColumn, idColumn) {
|
||||
const playerId = idColumn?.trim();
|
||||
if (playerId) return playerId;
|
||||
|
||||
let firstName, lastName;
|
||||
if (!nameColumn || !nameColumn.trim()) {
|
||||
firstName = `Player_${nanoid(4)}`;
|
||||
lastName = "(Regional)";
|
||||
} else {
|
||||
const parts = nameColumn.trim().split(" ");
|
||||
firstName = parts[0];
|
||||
lastName = parts[1] || "(Regional)";
|
||||
}
|
||||
|
||||
const newPlayer = await playersService.createPlayer({ first_name: firstName, last_name: lastName });
|
||||
return newPlayer.id;
|
||||
}
|
||||
|
||||
async function handleTeamsSheet(rows, teamsService, playersService, pb, tournamentIdMap = {}) {
|
||||
console.log(`📥 Importing ${rows.length} teams...`);
|
||||
const teamIdMap = {}; // spreadsheet ID -> PocketBase ID
|
||||
|
||||
for (const [i, row] of rows.entries()) {
|
||||
try {
|
||||
const spreadsheetTeamId = row["ID"]?.toString().trim();
|
||||
if (!spreadsheetTeamId) {
|
||||
console.warn(`⚠️ [${i + 1}] Team row missing spreadsheet ID, skipping.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const p1Id = await createPlayerIfMissing(playersService, row["P1 Name"], row["P1 ID"]);
|
||||
const p2Id = await createPlayerIfMissing(playersService, row["P2 Name"], row["P2 ID"]);
|
||||
|
||||
let name = row["Name"]?.trim();
|
||||
if (!name) {
|
||||
const p1First = row["P1 Name"]?.split(" ")[0] || "Player1";
|
||||
const p2First = row["P2 Name"]?.split(" ")[0] || "Player2";
|
||||
name = `${p1First} and ${p2First}`;
|
||||
console.warn(`⚠️ [${i + 1}] No team name found. Using generated name: ${name}`);
|
||||
}
|
||||
|
||||
const existing = await pb.collection("teams").getFullList({
|
||||
filter: `name = "${name}"`,
|
||||
fields: "id",
|
||||
});
|
||||
|
||||
if (existing.length > 0) {
|
||||
console.log(`ℹ️ [${i + 1}] Team "${name}" already exists, skipping.`);
|
||||
teamIdMap[spreadsheetTeamId] = existing[0].id;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there's a tournament for this team, get its PB ID
|
||||
const tournamentSpreadsheetId = row["Tournament ID"]?.toString().trim();
|
||||
const tournamentId = tournamentSpreadsheetId ? tournamentIdMap[tournamentSpreadsheetId] : undefined;
|
||||
|
||||
const teamInput = {
|
||||
name,
|
||||
primary_color: row.primary_color || "",
|
||||
accent_color: row.accent_color || "",
|
||||
logo: row.logo || "",
|
||||
players: [p1Id, p2Id],
|
||||
tournament: tournamentId, // single tournament relation,
|
||||
private: true
|
||||
};
|
||||
|
||||
const team = await teamsService.createTeam(teamInput);
|
||||
teamIdMap[spreadsheetTeamId] = team.id;
|
||||
|
||||
console.log(`✅ [${i + 1}] Created team: ${team.name} with players: ${[p1Id, p2Id].join(", ")}`);
|
||||
|
||||
// Add the team to the tournament's "teams" relation
|
||||
if (tournamentId) {
|
||||
await pb.collection("tournaments").update(tournamentId, {
|
||||
"teams+": [team.id],
|
||||
});
|
||||
console.log(`✅ Added team "${team.name}" to tournament ${tournamentId}`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`❌ [${i + 1}] Failed to create team: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
return teamIdMap;
|
||||
}
|
||||
|
||||
|
||||
async function handleTournamentSheet(rows, tournamentsService, teamIdMap, pb) {
|
||||
console.log(`📥 Importing ${rows.length} tournaments...`);
|
||||
const tournamentIdMap = {};
|
||||
const validFormats = ["double_elim", "single_elim", "groups", "swiss", "swiss_bracket"];
|
||||
|
||||
for (const [i, row] of rows.entries()) {
|
||||
try {
|
||||
const spreadsheetId = row["ID"]?.toString().trim();
|
||||
if (!spreadsheetId) {
|
||||
console.warn(`⚠️ [${i + 1}] Tournament missing spreadsheet ID, skipping.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!row["Name"]) {
|
||||
console.warn(`⚠️ [${i + 1}] Tournament name missing, skipping.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const format = validFormats.includes(row["Format"]) ? row["Format"] : "double_elim";
|
||||
|
||||
// Convert start_time to ISO datetime string
|
||||
let startTime = null;
|
||||
if (row["Start Time"]) {
|
||||
try {
|
||||
startTime = new Date(row["Start Time"]).toISOString();
|
||||
} catch (e) {
|
||||
console.warn(`⚠️ [${i + 1}] Invalid start time format, using null`);
|
||||
}
|
||||
}
|
||||
|
||||
const tournamentInput = {
|
||||
name: row["Name"],
|
||||
start_time: startTime,
|
||||
format,
|
||||
regional: true,
|
||||
teams: Object.values(teamIdMap), // Add all created teams
|
||||
};
|
||||
|
||||
const tournament = await tournamentsService.createTournament(tournamentInput);
|
||||
tournamentIdMap[spreadsheetId] = tournament.id;
|
||||
|
||||
console.log(`✅ [${i + 1}] Created tournament: ${tournament.name} with ${Object.values(teamIdMap).length} teams`);
|
||||
} catch (err) {
|
||||
console.error(`❌ [${i + 1}] Failed to create tournament: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
return tournamentIdMap;
|
||||
}
|
||||
|
||||
|
||||
async function handleMatchesSheet(rows, matchesService, teamIdMap, tournamentIdMap, pb) {
|
||||
console.log(`📥 Importing ${rows.length} matches...`);
|
||||
|
||||
const tournamentMatchesMap = {};
|
||||
|
||||
for (const [i, row] of rows.entries()) {
|
||||
try {
|
||||
const homeId = teamIdMap[row["Home ID"]];
|
||||
const awayId = teamIdMap[row["Away ID"]];
|
||||
const tournamentId = tournamentIdMap[row["Tournament ID"]];
|
||||
|
||||
if (!homeId || !awayId || !tournamentId) {
|
||||
console.warn(`⚠️ [${i + 1}] Could not find mapping for Home, Away, or Tournament, skipping.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// --- Ensure the teams are linked to the tournament ---
|
||||
for (const teamId of [homeId, awayId]) {
|
||||
const team = await pb.collection("teams").getOne(teamId, { fields: "tournaments" });
|
||||
const tournaments = team.tournaments || [];
|
||||
if (!tournaments.includes(tournamentId)) {
|
||||
// Add tournament to team
|
||||
await pb.collection("teams").update(teamId, { "tournaments+": [tournamentId] });
|
||||
// Add team to tournament
|
||||
await pb.collection("tournaments").update(tournamentId, { "teams+": [teamId] });
|
||||
console.log(`✅ Linked team ${team.name} to tournament ${tournamentId}`);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Create match ---
|
||||
const data = {
|
||||
tournament: tournamentId,
|
||||
home: homeId,
|
||||
away: awayId,
|
||||
home_cups: Number(row["Home cups"] || 0),
|
||||
away_cups: Number(row["Away cups"] || 0),
|
||||
status: "ended",
|
||||
lid: i+1
|
||||
};
|
||||
|
||||
const match = await matchesService.createMatch(data);
|
||||
console.log(`✅ [${i + 1}] Created match ID: ${match.id}`);
|
||||
|
||||
if (!tournamentMatchesMap[tournamentId]) tournamentMatchesMap[tournamentId] = [];
|
||||
tournamentMatchesMap[tournamentId].push(match.id);
|
||||
} catch (err) {
|
||||
console.error(`❌ [${i + 1}] Failed to create match: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Update each tournament with the created match IDs
|
||||
for (const [tournamentId, matchIds] of Object.entries(tournamentMatchesMap)) {
|
||||
try {
|
||||
await pb.collection("tournaments").update(tournamentId, { "matches+": matchIds });
|
||||
console.log(`✅ Updated tournament ${tournamentId} with ${matchIds.length} matches`);
|
||||
} catch (err) {
|
||||
console.error(`❌ Failed to update tournament ${tournamentId} with matches: ${err.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- Main Import ---
|
||||
export async function importExcel() {
|
||||
const pb = new PocketBase(POCKETBASE_URL);
|
||||
await pb.admins.authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
|
||||
|
||||
const teamsService = createTeamsService(pb);
|
||||
const playersService = createPlayersService(pb);
|
||||
const tournamentsService = createTournamentsService(pb);
|
||||
const matchesService = createMatchesService(pb);
|
||||
|
||||
const workbook = xlsx.readFile(EXCEL_FILE_PATH);
|
||||
|
||||
let teamIdMap = {};
|
||||
let tournamentIdMap = {};
|
||||
|
||||
// Process sheets in correct order: Tournaments -> Teams -> Matches
|
||||
const sheetOrder = ["tournament", "tournaments", "teams", "matches"];
|
||||
const processedSheets = new Set();
|
||||
|
||||
for (const sheetNamePattern of sheetOrder) {
|
||||
for (const sheetName of workbook.SheetNames) {
|
||||
if (processedSheets.has(sheetName)) continue;
|
||||
if (sheetName.toLowerCase() !== sheetNamePattern) continue;
|
||||
|
||||
const worksheet = workbook.Sheets[sheetName];
|
||||
const rows = xlsx.utils.sheet_to_json(worksheet);
|
||||
|
||||
console.log(`\n📘 Processing sheet: ${sheetName}`);
|
||||
|
||||
switch (sheetName.toLowerCase()) {
|
||||
case "teams":
|
||||
teamIdMap = await handleTeamsSheet(rows, teamsService, playersService, pb, tournamentIdMap);
|
||||
break;
|
||||
case "tournament":
|
||||
case "tournaments":
|
||||
tournamentIdMap = await handleTournamentSheet(rows, tournamentsService, teamIdMap, pb);
|
||||
break;
|
||||
case "matches":
|
||||
await handleMatchesSheet(rows, matchesService, teamIdMap, tournamentIdMap, pb);
|
||||
break;
|
||||
default:
|
||||
console.log(`⚠️ No handler found for sheet '${sheetName}', skipping.`);
|
||||
}
|
||||
|
||||
processedSheets.add(sheetName);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("\n🎉 All sheets imported successfully!");
|
||||
}
|
||||
|
||||
// --- Run ---
|
||||
importExcel().catch(console.error);
|
||||
Reference in New Issue
Block a user