small changes to UI/UX

This commit is contained in:
DeSqBlocki
2026-08-27 21:35:06 +02:00
parent e3dbb11e12
commit 995a2317b9
2 changed files with 448 additions and 139 deletions
+444 -139
View File
@@ -7,7 +7,11 @@ const {
const { const {
reconcileUserAchievements, reconcileUserAchievements,
reconcileAllAchievements, reconcileAllAchievements,
auditProfileData grantMaintenanceReward,
getMaintenanceRewardStatus,
auditProfileData,
DEFAULT_MAINTENANCE_REWARD_ID,
DEFAULT_MAINTENANCE_REWARD_AMOUNT
} = require( } = require(
"../../utils/profileMaintenance" "../../utils/profileMaintenance"
); );
@@ -67,6 +71,69 @@ module.exports = {
.setDescription( .setDescription(
"Audit stored profile statistics for inconsistencies" "Audit stored profile statistics for inconsistencies"
) )
)
.addSubcommand(
subcommand =>
subcommand
.setName(
"maintenance-reward"
)
.setDescription(
"Grant an idempotent maintenance reward to stored profile users"
)
.addStringOption(
option =>
option
.setName(
"reward-id"
)
.setDescription(
`Unique reward ID; defaults to ${DEFAULT_MAINTENANCE_REWARD_ID}`
)
)
.addIntegerOption(
option =>
option
.setName(
"amount"
)
.setDescription(
`Cookies per player; defaults to ${DEFAULT_MAINTENANCE_REWARD_AMOUNT}`
)
.setMinValue(
1
)
)
.addBooleanOption(
option =>
option
.setName(
"dry-run"
)
.setDescription(
"Preview recipients without granting Cookies"
)
)
)
.addSubcommand(
subcommand =>
subcommand
.setName(
"maintenance-status"
)
.setDescription(
"Show maintenance reward claim status"
)
.addStringOption(
option =>
option
.setName(
"reward-id"
)
.setDescription(
`Reward ID; defaults to ${DEFAULT_MAINTENANCE_REWARD_ID}`
)
)
), ),
async execute( async execute(
@@ -98,31 +165,87 @@ module.exports = {
}); });
if ( try {
subcommand === if (
"reconcile" subcommand ===
) { "reconcile"
const user = ) {
interaction.options.getUser( const user =
"user" interaction.options.getUser(
); "user"
);
const dryRun = const dryRun =
interaction.options.getBoolean( interaction.options.getBoolean(
"dry-run" "dry-run"
) ?? false; ) ?? false;
if (user) { if (user) {
const result = const result =
await reconcileUserAchievements({ await reconcileUserAchievements({
guildId:
interaction.guildId,
userId:
user.id,
dryRun
});
return interaction.editReply({
embeds: [
new EmbedBuilder()
.setTitle(
"🛠️ Profile Reconciliation"
)
.setDescription(
`${dryRun ? "Dry run for" : "Reconciled"} ${user}.`
)
.addFields(
{
name:
"New unlocks",
value:
`**${result.unlocked}**`,
inline:
true
},
{
name:
"Definitions checked",
value:
`**${result.checked}**`,
inline:
true
},
{
name:
"Event-only skipped",
value:
`**${result.skippedEventOnly}**`,
inline:
true
}
)
]
});
}
const summary =
await reconcileAllAchievements({
guildId: guildId:
interaction.guildId, interaction.guildId,
userId:
user.id,
dryRun dryRun
}); });
@@ -134,35 +257,35 @@ module.exports = {
"🛠️ Profile Reconciliation" "🛠️ Profile Reconciliation"
) )
.setDescription( .setDescription(
`${dryRun ? "Dry run for" : "Reconciled"} ${user}.` `${dryRun ? "Dry run completed" : "Reconciliation completed"} for stored profile users.`
) )
.addFields( .addFields(
{
name:
"Users",
value:
`**${summary.users}**`,
inline:
true
},
{ {
name: name:
"New unlocks", "New unlocks",
value: value:
`**${result.unlocked}**`, `**${summary.unlocked}**`,
inline: inline:
true true
}, },
{ {
name: name:
"Definitions checked", "Event-only checks skipped",
value: value:
`**${result.checked}**`, `**${summary.skippedEventOnly}**`,
inline:
true
},
{
name:
"Event-only skipped",
value:
`**${result.skippedEventOnly}**`,
inline: inline:
true true
@@ -173,152 +296,334 @@ module.exports = {
} }
const summary = if (
await reconcileAllAchievements({ subcommand ===
guildId: "maintenance-reward"
interaction.guildId, ) {
const rewardId =
interaction.options.getString(
"reward-id"
)
??
DEFAULT_MAINTENANCE_REWARD_ID;
dryRun
const amount =
interaction.options.getInteger(
"amount"
)
??
DEFAULT_MAINTENANCE_REWARD_AMOUNT;
/*
* Safer admin default:
*
* If omitted, maintenance-reward previews
* instead of paying immediately.
*
* Pass dry-run:false explicitly to execute.
*/
const dryRun =
interaction.options.getBoolean(
"dry-run"
)
??
true;
const summary =
await grantMaintenanceReward({
guildId:
interaction.guildId,
rewardId,
amount,
dryRun
});
return interaction.editReply({
embeds: [
new EmbedBuilder()
.setTitle(
dryRun
? "🧪 Maintenance Reward Dry Run"
: "🎁 Maintenance Reward"
)
.setDescription(
dryRun
? "No Cookies were granted. Run again with `dry-run:false` to execute this reward."
: `Maintenance compensation **${rewardId}** has been processed.`
)
.addFields(
{
name:
"Reward ID",
value:
`\`${summary.rewardId}\``,
inline:
false
},
{
name:
"Per player",
value:
`**${summary.amount.toLocaleString()} 🍪**`,
inline:
true
},
{
name:
"Stored profiles",
value:
`**${summary.users}**`,
inline:
true
},
{
name:
dryRun
? "Would receive"
: "Granted",
value:
`**${dryRun ? summary.eligible : summary.granted}**`,
inline:
true
},
{
name:
"Already claimed",
value:
`**${summary.alreadyClaimed}**`,
inline:
true
},
{
name:
"Failed",
value:
`**${summary.failed}**`,
inline:
true
}
)
]
}); });
}
if (
subcommand ===
"maintenance-status"
) {
const rewardId =
interaction.options.getString(
"reward-id"
)
??
DEFAULT_MAINTENANCE_REWARD_ID;
const status =
await getMaintenanceRewardStatus({
guildId:
interaction.guildId,
rewardId
});
return interaction.editReply({
embeds: [
new EmbedBuilder()
.setTitle(
"🎁 Maintenance Reward Status"
)
.addFields(
{
name:
"Reward ID",
value:
`\`${status.rewardId}\``,
inline:
false
},
{
name:
"Default amount",
value:
`**${status.amount.toLocaleString()} 🍪**`,
inline:
true
},
{
name:
"Stored profiles",
value:
`**${status.users}**`,
inline:
true
},
{
name:
"Claimed",
value:
`**${status.claimed}**`,
inline:
true
},
{
name:
"Remaining",
value:
`**${status.remaining}**`,
inline:
true
}
)
]
});
}
const audit =
await auditProfileData(
interaction.guildId
);
const issuePreview =
audit.issues
.slice(
0,
10
)
.join(
"\n"
);
return interaction.editReply({ return interaction.editReply({
embeds: [ embeds: [
new EmbedBuilder() new EmbedBuilder()
.setTitle( .setTitle(
"🛠️ Profile Reconciliation" "🔎 Profile Data Audit"
)
.setDescription(
`${dryRun ? "Dry run completed" : "Reconciliation completed"} for stored profile users.`
) )
.addFields( .addFields(
{ {
name: name:
"Users", "Stats documents",
value: value:
`**${summary.users}**`, `**${audit.statDocuments}**`,
inline: inline:
true true
}, },
{ {
name: name:
"New unlocks", "Achievement documents",
value: value:
`**${summary.unlocked}**`, `**${audit.achievementDocuments}**`,
inline: inline:
true true
}, },
{ {
name: name:
"Event-only checks skipped", "Active achievements",
value: value:
`**${summary.skippedEventOnly}**`, `**${audit.activeAchievements}**`,
inline:
true
},
{
name:
"Global badges",
value:
`**${audit.badgeDocuments}** (${audit.claimedBadges} claimed)`,
inline:
true
},
{
name:
"Orphan achievement docs",
value:
`**${audit.orphanAchievementDocs}**`,
inline:
true
},
{
name:
"Issues",
value:
`**${audit.issueCount}**`,
inline: inline:
true true
} }
) )
.setDescription(
issuePreview
? `First issues:\n${issuePreview}`
: "No structural inconsistencies found."
)
] ]
}); });
} }
catch (error) {
const audit = console.error(
await auditProfileData( `[ProfileAdmin] ${subcommand} failed:`,
interaction.guildId error
); );
const issuePreview = return interaction.editReply({
audit.issues embeds: [
.slice( new EmbedBuilder()
0, .setTitle(
10 "❌ Profile Admin Error"
) )
.join( .setDescription(
"\n" "The maintenance action failed. Check the bot logs for details."
); )
]
});
return interaction.editReply({ }
embeds: [
new EmbedBuilder()
.setTitle(
"🔎 Profile Data Audit"
)
.addFields(
{
name:
"Stats documents",
value:
`**${audit.statDocuments}**`,
inline:
true
},
{
name:
"Achievement documents",
value:
`**${audit.achievementDocuments}**`,
inline:
true
},
{
name:
"Active achievements",
value:
`**${audit.activeAchievements}**`,
inline:
true
},
{
name:
"Global badges",
value:
`**${audit.badgeDocuments}** (${audit.claimedBadges} claimed)`,
inline:
true
},
{
name:
"Orphan achievement docs",
value:
`**${audit.orphanAchievementDocs}**`,
inline:
true
},
{
name:
"Issues",
value:
`**${audit.issueCount}**`,
inline:
true
}
)
.setDescription(
issuePreview
? `First issues:\n${issuePreview}`
: "No structural inconsistencies found."
)
]
});
} }
}; };
+4
View File
@@ -2929,6 +2929,10 @@ function formatCategoryName(
"🏅 Other", "🏅 Other",
activity: activity:
"📅 Activity", "📅 Activity",
vault:
"🏦 Vault",
victim:
"🎯 Victim",
}; };
return labels[category] ?? return labels[category] ??