diff --git a/locales/en.json b/locales/en.json index b71ae7f..e8d33f7 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1067,7 +1067,7 @@ "quota-fail": "❌ Quota Not Met", "duty-time-title": "Shift Time - %type", "duty-time-desc": "**Total Shifts:** %count\n**Total Duration:** %duration", - "btn-hist": "View History", + "btn-hist": "View Shift History", "err-no-lb": "ℹ️ No shift data found for **%type**.", "duty-lb-title": "Leaderboard - %type", "duty-lb-desc": "**%lookback Top Shifts**\n\n%lines", @@ -1084,7 +1084,6 @@ "err-not-on": "❌ You are not on a shift.", "err-hist-oth": "❌ You can only view your own history.", "mod-v-all-title": "Confirm: Void All Shifts", - "mod-v-all-lbl": "Type CONFIRM to delete all shift data", "err-conf-fail": "❌ Data deletion confirmation failed. You must type the phrase exactly.", "succ-v-all": "All shift data for <@%user> has been deleted successfully.", "mod-add-t": "Add Duty Time", @@ -1099,25 +1098,25 @@ "err-no-perm": "❌ You do not have permission to do this.", "err-no-mem": "❌ Could not find that member.", "ph-sel-type": "Select a Shift Type", - "msg-sel-type": "👇 Please choose your shift type:", + "msg-sel-type": "👇 Please choose your shift type below:", "err-prof-dis": "❌ Staff Profiles are disabled.", - "err-prof-cfg": "❌ Configuration is missing. Please make sure the message is not empty.", + "err-prof-cfg": "❌ Configuration is missing. Please make sure that the message is not empty.", "err-prof-no-own": "❌ You do not have a staff profile.", - "err-prof-no-tgt": "❌ That user does not have a profile.", - "rev-dis-text": "*Reviews disabled*", + "err-prof-no-tgt": "❌ That user does not have a staff profile.", + "rev-dis-text": "*Reviews are disabled*", "rev-no-rate": "No ratings yet", "stat-offl": "⚫ Offline", "stat-onl": "🟢 Online", "stat-idl": "🟡 Away", "stat-dnd": "🔴 Do Not Disturb", "stat-prof-ond": "⏱️ On duty", - "stat-prof-loa": "🌙 On LoA", - "stat-prof-ra": "⛱️ On RA", - "prof-no-intro": "*No introduction set.*", + "stat-prof-loa": "🌙 On Leave Of Absence (LOA)", + "stat-prof-ra": "⛱️ On Reduced Activity (RA)", + "prof-no-intro": "😕 *This user did not set an introduction.*", "err-prof-empty": "❌ Profile embed is empty.", "err-prof-perm": "❌ You must be a staff member to have a profile.", "prof-edit-title": "Edit Profile", - "prof-edit-nick": "Custom Nickname", + "prof-edit-nick": "Your custom nickname", "prof-edit-intro": "Introduction", "succ-prof-wipe": "✅ Profile wiped for %u.", "succ-prof-upd": "✅ Profile updated!", @@ -1138,7 +1137,7 @@ "succ-del-all": "✅ ALL data has been permanently wiped.", "err-del-time": "⏳ Data deletion timed out.", "succ-del-tgt": "✅ Target data has been permanently wiped.", - "err-gen-no-perm": "❌ You do not have permission.", + "err-gen-no-perm": "❌ You do not have permission to do this.", "err-no-req": "❌ Request not found.", "err-req-hndl": "❌ Request is already %status.", "mod-deny-req": "Deny Request", @@ -1167,8 +1166,8 @@ "log-info-hdr": "%label Information", "general-start": "Start", "general-end": "End", - "log-end-title": "%label ended for %username", - "log-end-desc": "%label ended for %mention.", + "log-end-title": "%username's %label has ended.", + "log-end-desc": "%mention's %label has ended.", "general-started": "Started", "general-ended": "Ended", "log-adj-title": "%label adjusted for %username", @@ -1434,6 +1433,7 @@ "log-duty-log-fail": "[Staff Management] Failed to log duty change (%action): %error", "err-self-infract": "That's not in the code... well, it's more of a guideline anyway. Still no.\n-# You cannot infract yourself", "err-self-promo": "You can't promote yourself through a black hole of audacity and expect it to work.", - "status-expired-auto": "Ended automatically because the status expired." + "status-expired-auto": "Ended automatically because the status expired.", + "label-system": "System" } } diff --git a/modules/staff-management-system/commands/duty.js b/modules/staff-management-system/commands/duty.js index df2c050..45e4a42 100644 --- a/modules/staff-management-system/commands/duty.js +++ b/modules/staff-management-system/commands/duty.js @@ -1035,7 +1035,7 @@ async function handleDutyAdminVoidAll(client, interaction) { new ActionRowBuilder().addComponents( new TextInputBuilder() .setCustomId('confirm') - .setLabel(localize('staff-management-system', 'mod-v-all-lbl')) + .setLabel(localize('staff-management-system', 'mod-del-lbl')) .setStyle(TextInputStyle.Short) .setPlaceholder(confirmPhrase) .setRequired(true) diff --git a/modules/staff-management-system/commands/staff-status.js b/modules/staff-management-system/commands/staff-status.js index e7e7be7..9eb2b69 100644 --- a/modules/staff-management-system/commands/staff-status.js +++ b/modules/staff-management-system/commands/staff-status.js @@ -514,6 +514,7 @@ async function handleStatusEndSubmit(client, interaction, type) { flags: MessageFlags.Ephemeral }); } + await interaction.deferUpdate(); const meta = getStatusMeta(type); const request = await client.models['staff-management-system']['LoaRequest'].findByPk(interaction.customId.split('_')[2]); @@ -574,10 +575,9 @@ async function handleStatusEndSubmit(client, interaction, type) { .setEmoji('📜') .setStyle(ButtonStyle.Secondary) ); - return interaction.reply({ + return interaction.editReply({ embeds: [updatedEmbed.toJSON()], - components: [disabledRow.toJSON()], - flags: MessageFlags.Ephemeral + components: [disabledRow.toJSON()] }); } @@ -662,6 +662,7 @@ async function handleStatusExtendSubmit(client, interaction, type) { flags: MessageFlags.Ephemeral }); } + await interaction.deferUpdate(); const meta = getStatusMeta(type); const request = await client.models['staff-management-system']['LoaRequest'].findByPk(interaction.customId.split('_')[2]); @@ -719,10 +720,9 @@ async function handleStatusExtendSubmit(client, interaction, type) { r: request.reason || localize('staff-management-system', 'info-none') }) }); - return interaction.reply({ + return interaction.editReply({ embeds: [updatedEmbed.toJSON()], - components: interaction.message.components.map(c => c.toJSON()), - flags: MessageFlags.Ephemeral + components: interaction.message.components.map(c => c.toJSON()) }); } diff --git a/modules/staff-management-system/configs/activity-checks.json b/modules/staff-management-system/configs/activity-checks.json index 634c016..9d83f6c 100644 --- a/modules/staff-management-system/configs/activity-checks.json +++ b/modules/staff-management-system/configs/activity-checks.json @@ -29,7 +29,7 @@ "name": "enableActivityChecks", "category": "general", "humanName": "Enable Activity Checks", - "description": "Allows admins to start an activity check to see who is active.", + "description": "Allows admins to start an activity check to see who is active, and also set automatic activity checks.", "type": "boolean", "default": true, "elementToggle": true @@ -69,12 +69,43 @@ { "name": "duration", "description": "The configured duration in hours." + }, + { + "name": "staff-mention", + "description": "Mention of the configured staff role(s)." + }, + { + "name": "supervisor-mention", + "description": "Mention of the configured supervisor role(s)." + }, + { + "name": "management-mention", + "description": "Mention of the configured management role(s)." + }, + { + "name": "initiator", + "description": "The user who iniated the activity check. This will show 'system' if it was an automated check." } ], "default": { - "title": "📋 Staff Activity Check", - "description": "Please click the button below to confirm your activity before %endtime%.", - "color": "#3498db" + "_schema": "v3", + "content": "%staff-mention%", + "embeds": [ + { + "author": { + "name": "Signed, %initiator%" + }, + "title": "📋 Staff Activity Check", + "description": "Please confirm your activity by clicking the button below before %end-time%. This activity check will stay open for %duration% hour(s), and members who do not respond before it ends may be marked as failed unless they qualify for an exception.", + "fields": [ + { + "name": "Quick info overview", + "value": "Ends at: %end-time%\nDuration: %duration% hour(s)" + } + ], + "color": "#3498db" + } + ] } }, { diff --git a/modules/staff-management-system/configs/configuration.json b/modules/staff-management-system/configs/configuration.json index 9b978d2..74f326f 100644 --- a/modules/staff-management-system/configs/configuration.json +++ b/modules/staff-management-system/configs/configuration.json @@ -28,7 +28,7 @@ "name": "supervisorRoles", "category": "roles", "humanName": "Supervisor Roles", - "description": "Roles that can manage other staff members (Approve/Deny/Manage LoA's and RA's, Manage Shifts, promote and infract users).", + "description": "Roles that can manage other staff members (Approve/Deny/Manage LoA's and RA's, Manage Shifts etc.).", "type": "array", "content": "roleID", "default": [] diff --git a/modules/staff-management-system/configs/infractions.json b/modules/staff-management-system/configs/infractions.json index 89a6bc1..1fd941a 100644 --- a/modules/staff-management-system/configs/infractions.json +++ b/modules/staff-management-system/configs/infractions.json @@ -44,11 +44,23 @@ "Under Investigation" ] }, + { + "name": "infractionLogChannel", + "category": "messages", + "humanName": "Infraction Log Channel", + "description": "Where should infractions and suspensions be announced?", + "type": "channelID", + "channelTypes": [ + "GUILD_TEXT", + "GUILD_NEWS" + ], + "default": "" + }, { "name": "enableSuspensions", "category": "suspensions", "humanName": "Enable Suspensions System", - "description": "Suspensions temporarily strip a staff member of their roles.", + "description": "Suspensions temporarily strip a staff member of their roles, and give them back after the specified duration.", "type": "boolean", "default": true }, @@ -137,18 +149,6 @@ ] } }, - { - "name": "infractionLogChannel", - "category": "messages", - "humanName": "Infraction Log Channel", - "description": "Where should infractions and suspensions be announced?", - "type": "channelID", - "channelTypes": [ - "GUILD_TEXT", - "GUILD_NEWS" - ], - "default": "" - }, { "name": "infractionMessage", "category": "messages", diff --git a/modules/staff-management-system/configs/promotions.json b/modules/staff-management-system/configs/promotions.json index 9bb7055..e0a89fd 100644 --- a/modules/staff-management-system/configs/promotions.json +++ b/modules/staff-management-system/configs/promotions.json @@ -19,7 +19,7 @@ "name": "enablePromotions", "category": "logic", "humanName": "Enable Promotions System", - "description": "If disabled, the /staff-management promote command will not work.", + "description": "Enabling this allows staff members to promote users to higher ranks.", "type": "boolean", "default": true, "elementToggle": true @@ -30,7 +30,7 @@ "humanName": "Auto-Add New Role?", "description": "If enabled, the bot will automatically give the user the new rank role. Note: This makes your server prone to raids by promoting someone to a role with more dangerous permissions which can be used to do malicious actions. It is recommended to keep this setting disabled.", "type": "boolean", - "default": true + "default": false }, { "name": "promotionsChannel", diff --git a/modules/staff-management-system/configs/reviews.json b/modules/staff-management-system/configs/reviews.json index b23dd31..6065550 100644 --- a/modules/staff-management-system/configs/reviews.json +++ b/modules/staff-management-system/configs/reviews.json @@ -19,7 +19,7 @@ "name": "enableReviews", "category": "settings", "humanName": "Enable Reviews System", - "description": "Enabling this unlocks the staff review system, allowing users to submit ratings and feedback for staff members.", + "description": "Enabling this unlocks the staff review system, allowing users to submit ratings with feedback for staff members.", "type": "boolean", "default": true }, @@ -39,7 +39,7 @@ "name": "allowSelfRating", "category": "settings", "humanName": "Allow Self-Rating?", - "description": "If enabled, staff can review themselves. This is not recommended to keep a fair ratings system.", + "description": "If enabled, staff can review themselves. This is not recommended to keep a fair review system.", "type": "boolean", "default": false }, @@ -47,7 +47,7 @@ "name": "onlyAllowStaffReview", "category": "settings", "humanName": "Only let users review staff", - "description": "If enabled, only staff members can review other staff members.", + "description": "If enabled, users can only review staff members.", "type": "boolean", "default": true }, @@ -92,7 +92,7 @@ ], "default": { "_schema": "v3", - "content": "%staff%", + "content": "%staff-mention%", "embeds": [ { "title": "🌟 New Staff Rating", diff --git a/modules/staff-management-system/staff-management.js b/modules/staff-management-system/staff-management.js index 9d96d2f..7aa2127 100644 --- a/modules/staff-management-system/staff-management.js +++ b/modules/staff-management-system/staff-management.js @@ -117,6 +117,11 @@ async function issueInfraction(client, interaction, targetMember, type, reason, }); } + const canInfract = checkStaffPermissions(interaction.member, config, 'staff'); + if (!canInfract) return interaction.editReply({ + content: localize('staff-management-system', 'err-gen-no-perm') + }); + if (type.toLowerCase() === 'suspension') { return interaction.editReply({ content: localize('staff-management-system', 'err-use-susp') @@ -250,6 +255,11 @@ async function issueSuspension(client, interaction, targetMember, durationInput, }); } + const canSuspend = checkStaffPermissions(interaction.member, config, 'staff'); + if (!canSuspend) return interaction.editReply({ + content: localize('staff-management-system', 'err-gen-no-perm') + }); + const durationDays = parseDurationToDays(durationInput); if (!durationDays) return interaction.editReply({ @@ -1391,27 +1401,43 @@ async function startActivityCheck(client, interactionOrChannel, isAutomated = fa const durationHours = config.timeframe || 24; const endTime = new Date(Date.now() + durationHours * 60 * 60 * 1000); + const generalConfig = getConfig(client, 'configuration') || {}; - let embedTemplate = typeof config.checkMessage === 'string' - ? JSON.parse(config.checkMessage) - : config.checkMessage; - let msgOpts = await embedTypeV2(embedTemplate, { - '%end-time%': ``, - '%duration%': durationHours.toString() - }); + const formatRoleMentions = (roles) => { + const roleIds = Array.isArray(roles) + ? roles + : (roles ? [roles] : []); - if (msgOpts?.content?.trim() === '') delete msgOpts.content; - msgOpts.components = [ - new ActionRowBuilder() - .addComponents( - new ButtonBuilder() + return roleIds.map(roleId => `<@&${roleId}>`).join(' '); + }; + const initiator = isAutomated + ? localize('staff-management-system', 'label-system') + : interactionOrChannel.user.toString(); + + const responseButtonRow = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() .setCustomId('staff-mgmt_ac-respond') .setLabel(localize('staff-management-system', 'ac-confirm-btn')) .setStyle(ButtonStyle.Success) .setEmoji('✅') - ) - .toJSON() - ]; + ) + .toJSON(); + + let msgOpts = await embedTypeV2(embedTemplate, { + '%end-time%': ``, + '%duration%': durationHours.toString(), + '%staff-mention%': formatRoleMentions(generalConfig.staffRoles), + '%supervisor-mention%': formatRoleMentions(generalConfig.supervisorRoles), + '%management-mention%': formatRoleMentions(generalConfig.managementRoles), + '%initiator%': initiator + }, + { + components: [responseButtonRow] + } + ); + + if (msgOpts?.content?.trim() === '') delete msgOpts.content; try { const checkMessage = await targetChannel.send(msgOpts);