diff --git a/deploy-commands.js b/deploy-commands.js index 687ff38..f7cb6c3 100644 --- a/deploy-commands.js +++ b/deploy-commands.js @@ -86,6 +86,31 @@ const commands = [ .setName("list_subscriptions") .setDescription("List all game subscriptions for this server") .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + new SlashCommandBuilder() + .setName("findteam") + .setDescription("Find a team by name") + .addStringOption((option) => + option + .setName("teamname") + .setDescription("The team name to search for") + .setRequired(true) + ) + .addStringOption((option) => + option + .setName("game") + .setDescription("Filter by game") + .setRequired(false) + .addChoices( + { name: "Big Ballers VR", value: "Big Ballers VR" }, + { name: "Blacktop Hoops", value: "Blacktop Hoops" }, + { name: "Breachers", value: "Breachers" }, + { name: "Echo Arena", value: "Echo Arena" }, + { name: "Echo Combat", value: "Echo Combat" }, + { name: "Gun Raiders", value: "Gun Raiders" }, + { name: "Nock", value: "Nock" }, + { name: "VAIL", value: "VAIL" } + ) + ), ]; const rest = new REST({ version: "10" }).setToken(process.env.DISCORD_TOKEN); diff --git a/src/commands/CommandHandler.js b/src/commands/CommandHandler.js index 756f4a1..198b720 100644 --- a/src/commands/CommandHandler.js +++ b/src/commands/CommandHandler.js @@ -34,6 +34,9 @@ class CommandHandler { case 'list_subscriptions': await this.subscriptionCommands.handleListSubscriptions(interaction); break; + case 'findteam': + await this.handleFindTeam(interaction); + break; default: await interaction.editReply({ content: '❌ Unknown command', @@ -217,6 +220,55 @@ class CommandHandler { } } + async handleFindTeam(interaction) { + try { + const teamName = interaction.options.getString('teamname'); + const gameFilter = interaction.options.getString('game'); + + const teamData = await this.playerService.findTeamByName(teamName, gameFilter); + if (!teamData || !teamData.success || !teamData.teams || teamData.teams.length === 0) { + await interaction.editReply({ + content: '❌ No teams found matching your search criteria.', + }); + return; + } + + const embed = EmbedBuilders.createTeamEmbed(teamData.teams); + + // Create buttons for each team + const rows = teamData.teams.slice(0, 5).map(team => { + return new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setLabel(`🔵 View ${team.name} (${team.game_mode})`) + .setStyle(ButtonStyle.Link) + .setURL(`${this.playerService.baseUrl}/teams/${team.id}`), + ); + }); + + // Add Discord join button in a separate row + rows.push( + new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setLabel('🟡 Join Discord') + .setStyle(ButtonStyle.Link) + .setURL('https://discord.gg/j3DKVATPGQ') + ) + ); + + await interaction.editReply({ + embeds: [embed], + components: rows, + }); + } catch (error) { + this.logger.error('Error in handleFindTeam:', { + error: error.message, + teamname: interaction.options.getString('teamname'), + timestamp: new Date().toISOString() + }); + throw error; + } + } + createActionRow(username) { return new ActionRowBuilder().addComponents( new ButtonBuilder() diff --git a/src/services/PlayerService.js b/src/services/PlayerService.js index 98e6ffd..82e7ce9 100644 --- a/src/services/PlayerService.js +++ b/src/services/PlayerService.js @@ -69,6 +69,38 @@ class PlayerService { getStatsUrl(username) { return `${this.baseUrl}/profile/${username}/stats`; } + + async findTeamByName(teamName, gameFilter = null) { + try { + console.log(`Fetching team data for: ${teamName}${gameFilter ? ` in ${gameFilter}` : ''}`); + const url = `${this.baseUrl}/api/get_team_data_by_name/${encodeURIComponent(teamName)}`; + console.log(`API URL: ${url}`); + + const response = await axios.get(url, { + timeout: 5000 + }); + + console.log('API Response:', JSON.stringify(response.data, null, 2)); + + if (response.data && response.data.success) { + // Filter teams by game if gameFilter is provided + if (gameFilter && response.data.teams) { + response.data.teams = response.data.teams.filter( + team => team.game_name.toLowerCase() === gameFilter.toLowerCase() + ); + } + } + + return response.data; + } catch (error) { + console.error('Error fetching team data:', { + message: error.message, + response: error.response?.data, + status: error.response?.status + }); + return null; + } + } } module.exports = PlayerService; \ No newline at end of file diff --git a/src/utils/embedBuilders.js b/src/utils/embedBuilders.js index 3eb0b3e..ba7c262 100644 --- a/src/utils/embedBuilders.js +++ b/src/utils/embedBuilders.js @@ -208,6 +208,76 @@ class EmbedBuilders { .setURL('https://discord.gg/j3DKVATPGQ') ); } + + static createTeamEmbed(teams) { + const embed = new EmbedBuilder() + .setTitle(`Teams Found`) + .setColor('#0099ff'); + + if (!teams || teams.length === 0) { + embed.setDescription('No teams found'); + return embed; + } + + // Sort teams by date created (newest first) + teams.sort((a, b) => new Date(b.date_created) - new Date(a.date_created)); + + teams.forEach((team, index) => { + // Add team header + embed.addFields({ + name: `${index + 1}. ${team.name} - ${team.game_name} (${team.game_mode})`, + value: '\u200B' + }); + + // Add team stats + const statsFields = []; + if (team.matches) statsFields.push(`Matches: ${team.matches}`); + if (team.wins) statsFields.push(`Wins: ${team.wins}`); + if (team.losses) statsFields.push(`Losses: ${team.losses}`); + if (team.forfeits) statsFields.push(`Forfeits: ${team.forfeits}`); + + const winRate = team.matches > 0 + ? ((parseInt(team.wins) / parseInt(team.matches)) * 100).toFixed(1) + : 0; + + if (statsFields.length > 0) { + embed.addFields({ + name: 'Stats', + value: `${statsFields.join(' | ')} | Win Rate: ${winRate}%`, + inline: false + }); + } + + // Add team members + if (team.players && team.players.length > 0) { + const playerList = team.players + .map(player => `- ${player.username} (${player.position})`) + .join('\n'); + + embed.addFields({ + name: 'Players', + value: playerList, + inline: false + }); + } + + // Add team creation date + if (team.date_created) { + embed.addFields({ + name: 'Created', + value: new Date(team.date_created).toLocaleDateString(), + inline: true + }); + } + + // Add separator between teams + if (index < teams.length - 1) { + embed.addFields({ name: '\u200B', value: '\u200B' }); + } + }); + + return embed; + } } module.exports = EmbedBuilders; \ No newline at end of file