Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions src/commands/admin/team/createteam.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js';
import { TeamService } from '#services/teamService.js';
import { ConfigService } from '#services/configService.js';
import logger from '#utils/logger.js';

export const data = new SlashCommandBuilder()
.setName('create-team')
.setDescription('Create a team')
.addUserOption((option) =>
option.setName('leader').setDescription('The team leader').setRequired(true)
)
.addStringOption((option) =>
option.setName('name').setDescription('The name of the team').setRequired(true)
)
.addStringOption((option) =>
option.setName('description').setDescription('The description of the team').setRequired(false)
);

/**
* @param {ChatInputCommandInteraction} interaction
*/
export async function execute(interaction) {
if (!interaction.member.permissions.has('Administrator')) {
const customRole = await ConfigService.getAdminRole(interaction.guildId);
if (customRole) {
const member = await interaction.guild.members.fetch(interaction.user.id);
if (!member.roles.cache.has(customRole)) {
await interaction.reply('You do not have permission to set the approval channel.');
return;
}
} else {
await interaction.reply('You do not have permission to set the approval channel.');
return;
}
}
const leader = interaction.options.getUser('leader');
const name = interaction.options.getString('name');
const description = interaction.options.getString('description');

try {
await TeamService.createTeam(leader.id, name, description);
await interaction.reply(`Team "${name}" (Leader: ${leader.tag}) created successfully!`);
logger.info(`Team "${name}" created successfully by ${interaction.user.tag}`);
} catch (error) {
await interaction.reply(`Error creating team: ${error.message}`);
logger.error(`Error creating team "${name}" by ${interaction.user.tag}: ${error.message}`);
}
}
73 changes: 73 additions & 0 deletions src/commands/admin/team/editteam.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js';
import { ConfigService } from '#services/configService.js';
import { TeamService } from '#services/teamService.js';
import logger from '#utils/logger.js';

export const data = new SlashCommandBuilder()
.setName('edit-team')
.setDescription('Edit a team')
.addStringOption((option) =>
option
.setName('team')
.setDescription('Select the team to edit')
.setRequired(true)
.setAutocomplete(true)
)
.addUserOption((option) =>
option.setName('leader').setDescription('The team leader').setRequired(false)
)
.addStringOption((option) =>
option.setName('name').setDescription('The name of the team').setRequired(false)
)
.addStringOption((option) =>
option.setName('description').setDescription('The description of the team').setRequired(false)
);

/**
* @param {ChatInputCommandInteraction} interaction
*/
export async function execute(interaction) {
if (!interaction.member.permissions.has('Administrator')) {
const customRole = await ConfigService.getAdminRole(interaction.guildId);
if (customRole) {
const member = await interaction.guild.members.fetch(interaction.user.id);
if (!member.roles.cache.has(customRole)) {
await interaction.reply('You do not have permission to set the approval channel.');
return;
}
} else {
await interaction.reply('You do not have permission to set the approval channel.');
return;
}
}

const teamId = interaction.options.getString('team');
const leaderId = interaction.options.getUser('leader').id;
const name = interaction.options.getString('name');
const description = interaction.options.getString('description');

if (!name && !description && !leaderId) {
await interaction.reply('Please provide at least one field to edit.');
return;
}

try {
const updatedTeam = await TeamService.updateTeam(teamId, leaderId, name, description);
await interaction.reply(`Team ${updatedTeam.name} edited successfully!`);
logger.info(`Team ${updatedTeam.name} ${updatedTeam.id} edited successfully!`);
} catch (error) {
logger.error('Error editing team', error);
await interaction.reply('An error occurred while editing the team.');
}
}

/**
* @param {ChatInputCommandInteraction} interaction
*/
export async function autocomplete(interaction) {
const focusedValue = interaction.options.getFocused();
const events = await TeamService.getTeams();
const filtered = events.filter((event) => event.name.startsWith(focusedValue));
const choices = filtered.map((event) => event).slice(0, 25);
await interaction.respond(choices.map((choice) => ({ name: choice.name, value: choice.id })));
}
124 changes: 124 additions & 0 deletions src/services/teamService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import prisma from '#utils/prisma.js';
import logger from '#utils/logger.js';

export class TeamService {
/**
* Create a new team in the database
* @param {String} leaderId - (Optional) The ID of the team leader
* @param {String} name - The name of the team
* @param {String} description - The description of the team
* @returns {Promise<void>}
*/
static async createTeam(leaderId, name, description) {
// Validate inputs
if (!name || !leaderId) {
throw new Error('Team name and leader id is required');
}
// Create the team
try {
await prisma.team.create({
data: {
name,
description,
leader: {
connect: {
discordId: leaderId,
},
},
},
});
} catch (error) {
logger.error('Error creating team', error.message);
throw error;
}
}

/**
* Get all teams
* @returns {Promise<import('@prisma/client').Team[]>} An array of teams
*/
static async getTeams() {
try {
const teams = await prisma.team.findMany({
orderBy: {
name: 'asc',
},
});
return teams;
} catch (error) {
logger.error('Error getting teams', error);
throw error;
}
}

/**
* Delete a team by ID
* @param {String} teamId - The ID of the team
* @returns {Promise<void>}
*/
static async deleteTeam(teamId) {
try {
await prisma.team.delete({
where: {
id: teamId,
},
});
} catch (error) {
logger.error('Error deleting team', error);
throw error;
}
}

/**
* Get a team by ID
* @param {String} teamId - The ID of the team
* @returns {Promise<import('@prisma/client').Team>} The team object
*/
static async getTeamById(teamId) {
try {
const team = await prisma.team.findUnique({
where: {
id: teamId,
},
});
if (!team) {
throw new Error('Team not found');
}
return team;
} catch (error) {
logger.error('Error getting team by ID', error);
throw error;
}
}
/**
* Update a team by ID
* @param {String} teamId - The ID of the team
* @param {String} leaderId - The ID of the team leader
* @param {Object} data - The data to update
* @returns {Promise<import('@prisma/client').Team>} The updated team object
*/
static async updateTeam(teamId, leaderId, name, description) {
const updateData = {};
try {
if (leaderId) {
updateData.leader = {
connect: {
discordId: leaderId,
},
};
}
if (name) updateData.name = name;
if (description) updateData.description = description;

return await prisma.team.update({
where: {
id: teamId,
},
data: updateData,
});
} catch (error) {
logger.error('Error updating team', error);
throw error;
}
}
}