From 3cdfaef94235562ebfc7eef1366c7ec87f6669a2 Mon Sep 17 00:00:00 2001 From: 1tzEmerald Date: Sat, 9 Nov 2024 13:03:41 +0000 Subject: [PATCH] Update profile.js --- Commands/profile.js | 245 +++++++++++++++++++++++++++----------------- 1 file changed, 153 insertions(+), 92 deletions(-) diff --git a/Commands/profile.js b/Commands/profile.js index a25f448..2368525 100644 --- a/Commands/profile.js +++ b/Commands/profile.js @@ -20,35 +20,6 @@ function updateClockedInStatus(profileEmbed, clockedIn) { return profileEmbed; } -function formatSchedule(schedule) { - if (!schedule || Object.keys(schedule).length === 0) return 'No schedule set'; - - const days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']; - return days - .filter(day => schedule[day]) - .map(day => `${day.charAt(0).toUpperCase() + day.slice(1)}: ${schedule[day].start} - ${schedule[day].end}`) - .join('\n'); -} - -function calculateWeeklyHours(schedule) { - if (!schedule) return 0; - - let totalMinutes = 0; - Object.values(schedule).forEach(day => { - if (day && day.start && day.end) { - const [startHour, startMin] = day.start.split(':').map(Number); - const [endHour, endMin] = day.end.split(':').map(Number); - - const startMinutes = startHour * 60 + startMin; - const endMinutes = endHour * 60 + endMin; - - totalMinutes += endMinutes - startMinutes; - } - }); - - return Math.round(totalMinutes / 60 * 10) / 10; // Round to 1 decimal place -} - module.exports = new Command({ name: cmdconfig.Profile.Command, description: cmdconfig.Profile.Description, @@ -64,7 +35,7 @@ module.exports = new Command({ ], async run(interaction) { - await interaction.deferReply({ ephemeral: true }); + await interaction.deferReply({ ephemeral: true }); const userOption = interaction.options.getUser('user'); const viewingUser = userOption || interaction.user; @@ -72,7 +43,7 @@ module.exports = new Command({ const interactionUserId = interaction.user.id; const user = interaction.guild.members.cache.get(viewingUserId); - const { getRole } = interaction.client; + const { getRole, getChannel } = interaction.client; const Staff = await getRole(supportbot.Roles.StaffMember.Staff, interaction.guild); const Admin = await getRole(supportbot.Roles.StaffMember.Admin, interaction.guild); @@ -96,14 +67,12 @@ module.exports = new Command({ profileData = { bio: "", timezone: "", - clockedIn: false, - schedule: {} + clockedIn: false }; fs.writeFileSync(profilePath, JSON.stringify(profileData, null, 2)); } - const { bio, timezone, clockedIn, schedule } = profileData; - const weeklyHours = calculateWeeklyHours(schedule); + const { bio, timezone, clockedIn } = profileData; let profileEmbed = new EmbedBuilder() .setTitle(`${viewingUser.username}'s Profile`) @@ -115,11 +84,7 @@ module.exports = new Command({ ); if (isStaff) { - profileEmbed.addFields( - { name: 'Clocked In Status', value: clockedIn ? '✅ Clocked In' : '❌ Clocked Out', inline: true }, - { name: 'Weekly Hours', value: `${weeklyHours} hours`, inline: true }, // Now inline with Schedule - { name: 'Schedule', value: formatSchedule(schedule), inline: true } - ); + profileEmbed.addFields({ name: 'Clocked In Status', value: clockedIn ? '✅ Clocked In' : '❌ Clocked Out', inline: true }); } const buttonRow = new ActionRowBuilder(); @@ -136,10 +101,6 @@ module.exports = new Command({ new ButtonBuilder() .setCustomId('clockInOut') .setLabel(clockedIn ? 'Clock Out' : 'Clock In') - .setStyle(ButtonStyle.Secondary), - new ButtonBuilder() - .setCustomId('editSchedule') - .setLabel('Edit Schedule') .setStyle(ButtonStyle.Secondary) ); } @@ -157,7 +118,7 @@ module.exports = new Command({ await interaction.editReply({ embeds: [profileEmbed], components: buttonRow.components.length > 0 ? [buttonRow] : [] }); const filter = i => ( - ['editProfile', 'clockInOut', 'viewTicketStats', 'editSchedule'].includes(i.customId) + ['editProfile', 'clockInOut', 'viewTicketStats', 'showOpenTickets', 'backToStats', 'backToProfile'].includes(i.customId) && i.user.id === interactionUserId ); @@ -174,7 +135,8 @@ module.exports = new Command({ .setCustomId('bio') .setLabel('Bio') .setStyle(TextInputStyle.Paragraph) - .setValue(profileData.bio || '') + .setPlaceholder('Enter your bio') + .setValue(String(bio)) .setRequired(false) ), new ActionRowBuilder().addComponents( @@ -182,7 +144,8 @@ module.exports = new Command({ .setCustomId('timezone') .setLabel('Timezone') .setStyle(TextInputStyle.Short) - .setValue(profileData.timezone || '') + .setPlaceholder('Enter your timezone') + .setValue(String(timezone)) .setRequired(false) ) ); @@ -193,6 +156,7 @@ module.exports = new Command({ if (i.customId === 'clockInOut') { profileData.clockedIn = !profileData.clockedIn; fs.writeFileSync(profilePath, JSON.stringify(profileData, null, 2)); + profileEmbed = updateClockedInStatus(profileEmbed, profileData.clockedIn); if (profileData.clockedIn) { clockedInUsers.add(viewingUserId); @@ -200,60 +164,157 @@ module.exports = new Command({ clockedInUsers.delete(viewingUserId); } - profileEmbed = updateClockedInStatus(profileEmbed, profileData.clockedIn); - const updatedRow = new ActionRowBuilder().addComponents( - ...buttonRow.components.map(button => { - if (button.data.custom_id === 'clockInOut') { - return new ButtonBuilder() - .setCustomId('clockInOut') - .setLabel(profileData.clockedIn ? 'Clock Out' : 'Clock In') - .setStyle(ButtonStyle.Secondary); - } - return ButtonBuilder.from(button.data); - }) - ); + const updatedButtonRow = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('editProfile') + .setLabel('Edit Profile') + .setStyle(ButtonStyle.Secondary) + ); - await i.update({ embeds: [profileEmbed], components: [updatedRow] }); + if (isStaff) { + updatedButtonRow.addComponents( + new ButtonBuilder() + .setCustomId('clockInOut') + .setLabel(profileData.clockedIn ? 'Clock Out' : 'Clock In') + .setStyle(ButtonStyle.Secondary) + ); + + if (supportbot.Ticket.ClaimTickets.Enabled) { + updatedButtonRow.addComponents( + new ButtonBuilder() + .setCustomId('viewTicketStats') + .setLabel('View Ticket Stats') + .setStyle(ButtonStyle.Secondary) + ); + } + } + + await i.update({ embeds: [profileEmbed], components: [updatedButtonRow] }); + + let clockedinout = new EmbedBuilder() + .setTitle(profileData.clockedIn ? 'Clocked In!' : 'Clocked Out!') + .setDescription(profileData.clockedIn ? 'You have successfully clocked in.' : 'You have successfully clocked out.') + .setColor(supportbot.Embed.Colours.General) + + await interaction.followUp({ embeds: [clockedinout], ephemeral: true }); } if (i.customId === 'viewTicketStats') { - // Handle ticket stats viewing here - const ticketStatsEmbed = new EmbedBuilder() - .setTitle('Ticket Stats') - .setDescription('Here are your ticket stats...') - .setColor(supportbot.Embed.Colours.General); + const TicketData = JSON.parse(fs.readFileSync("./Data/TicketData.json", "utf8")); + const ticketsClaimed = TicketData.tickets.filter(t => t.claimedBy === viewingUserId); + const ticketsOpen = ticketsClaimed.filter(t => t.open); + const totalTickets = ticketsClaimed.length; - await i.update({ embeds: [ticketStatsEmbed], components: [] }); - } + let totalResponseTime = 0; + let responseCount = 0; - if (i.customId === 'editSchedule') { - const modal = new ModalBuilder() - .setCustomId('editScheduleModal') - .setTitle('Edit Schedule'); - - ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'].forEach(day => { - modal.addComponents( - new ActionRowBuilder().addComponents( - new TextInputBuilder() - .setCustomId(`${day.toLowerCase()}Start`) - .setLabel(`${day} Start Time (HH:mm)`) - .setStyle(TextInputStyle.Short) - .setRequired(false) - .setValue(schedule[day.toLowerCase()]?.start || '') - ), - new ActionRowBuilder().addComponents( - new TextInputBuilder() - .setCustomId(`${day.toLowerCase()}End`) - .setLabel(`${day} End Time (HH:mm)`) - .setStyle(TextInputStyle.Short) - .setRequired(false) - .setValue(schedule[day.toLowerCase()]?.end || '') - ) - ); + ticketsClaimed.forEach(ticket => { + if (ticket.claimedAt && ticket.createdAt) { + const responseTime = new Date(ticket.claimedAt) - new Date(ticket.createdAt); + totalResponseTime += responseTime; + responseCount++; + } }); - await i.showModal(modal); + const averageResponseTime = responseCount ? totalResponseTime / responseCount : 0; + const averageResponseTimeMinutes = Math.round(averageResponseTime / 60000); + + const statsEmbed = new EmbedBuilder() + .setTitle(msgconfig.TicketStats.Title) + .setDescription(`> Ticket stats for <@${viewingUserId}>`) + .setColor(supportbot.Embed.Colours.General) + .addFields( + { name: msgconfig.TicketStats.OpenTickets, value: `${ticketsOpen.length}`, inline: true }, + { name: msgconfig.TicketStats.TotalTickets, value: `${totalTickets}`, inline: true }, + { name: msgconfig.TicketStats.ResponseTime, value: `${averageResponseTimeMinutes} minutes`, inline: false } + ); + + const statsButtonRow = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('showOpenTickets') + .setLabel('Show Open Tickets') + .setStyle(ButtonStyle.Secondary), + new ButtonBuilder() + .setCustomId('backToProfile') + .setLabel('Back to Profile') + .setStyle(ButtonStyle.Secondary) + ); + + await i.update({ embeds: [statsEmbed], components: [statsButtonRow] }); + } + + if (i.customId === 'showOpenTickets') { + const TicketData = JSON.parse(fs.readFileSync("./Data/TicketData.json", "utf8")); + const ticketsOpen = TicketData.tickets.filter(t => t.claimedBy === viewingUserId && t.open); + + const openTicketsEmbed = new EmbedBuilder() + .setTitle('Active Tickets') + .setDescription(ticketsOpen.map(t => `<#${t.id}>`).join('\n') || 'No active tickets.') + .setColor(supportbot.Embed.Colours.General); + + const openTicketsButtonRow = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('backToStats') + .setLabel('Back to Stats') + .setStyle(ButtonStyle.Secondary) + ); + + await i.update({ embeds: [openTicketsEmbed], components: [openTicketsButtonRow] }); + } + + if (i.customId === 'backToStats') { + const TicketData = JSON.parse(fs.readFileSync("./Data/TicketData.json", "utf8")); + const ticketsClaimed = TicketData.tickets.filter(t => t.claimedBy === viewingUserId); + const ticketsOpen = ticketsClaimed.filter(t => t.open); + const totalTickets = ticketsClaimed.length; + + let totalResponseTime = 0; + let responseCount = 0; + + ticketsClaimed.forEach(ticket => { + if (ticket.claimedAt && ticket.createdAt) { + const responseTime = new Date(ticket.claimedAt) - new Date(ticket.createdAt); + totalResponseTime += responseTime; + responseCount++; + } + }); + + const averageResponseTime = responseCount ? totalResponseTime / responseCount : 0; + const averageResponseTimeMinutes = Math.round(averageResponseTime / 60000); + + const statsEmbed = new EmbedBuilder() + .setTitle(msgconfig.TicketStats.Title) + .setDescription(`> Ticket stats for <@${viewingUserId}>`) + .setColor(supportbot.Embed.Colours.General) + .addFields( + { name: msgconfig.TicketStats.OpenTickets, value: `${ticketsOpen.length}`, inline: true }, + { name: msgconfig.TicketStats.TotalTickets, value: `${totalTickets}`, inline: true }, + { name: msgconfig.TicketStats.ResponseTime, value: `${averageResponseTimeMinutes} minutes`, inline: false } + ); + + const statsButtonRow = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('showOpenTickets') + .setLabel('Show Open Tickets') + .setStyle(ButtonStyle.Secondary), + new ButtonBuilder() + .setCustomId('backToProfile') + .setLabel('Back to Profile') + .setStyle(ButtonStyle.Secondary) + ); + + await i.update({ embeds: [statsEmbed], components: [statsButtonRow] }); + } + + if (i.customId === 'backToProfile') { + await i.update({ embeds: [profileEmbed], components: buttonRow.components.length > 0 ? [buttonRow] : [] }); } }); } }); + +module.exports.clockedInUsers = clockedInUsers;