diff --git a/src/commands/admin/features.ts b/src/commands/admin/features.ts index a6a282b..e8394c1 100644 --- a/src/commands/admin/features.ts +++ b/src/commands/admin/features.ts @@ -1,5 +1,6 @@ import { createCommand } from "@/lib/utils"; -import { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, MessageFlags } from "discord.js"; +import { SlashCommandBuilder, PermissionFlagsBits, MessageFlags } from "discord.js"; +import { createBaseEmbed } from "@lib/embeds"; import { configManager } from "@/lib/configManager"; import { config, reloadConfig } from "@/lib/config"; import { AuroraClient } from "@/lib/BotClient"; @@ -45,9 +46,7 @@ export const features = createCommand({ const overrides = Object.entries(config.commands) .map(([name, enabled]) => `• **${name}**: ${enabled ? "āœ… Enabled (Override)" : "āŒ Disabled"}`); - const embed = new EmbedBuilder() - .setTitle("Command Features") - .setColor("Blue"); + const embed = createBaseEmbed("Command Features", undefined, "Blue"); // Add fields for each category const sortedCategories = [...categories.keys()].sort(); diff --git a/src/commands/admin/listing.ts b/src/commands/admin/listing.ts index b3bd82a..bb293c3 100644 --- a/src/commands/admin/listing.ts +++ b/src/commands/admin/listing.ts @@ -1,7 +1,6 @@ import { createCommand } from "@/lib/utils"; import { SlashCommandBuilder, - EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, @@ -10,7 +9,7 @@ import { MessageFlags } from "discord.js"; import { inventoryService } from "@/modules/inventory/inventory.service"; -import { createSuccessEmbed, createErrorEmbed } from "@lib/embeds"; +import { createSuccessEmbed, createErrorEmbed, createBaseEmbed } from "@lib/embeds"; import { UserError } from "@/lib/errors"; import { items } from "@/db/schema"; import { ilike, isNotNull, and } from "drizzle-orm"; @@ -54,11 +53,8 @@ export const listing = createCommand({ return; } - const embed = new EmbedBuilder() - .setTitle(`Shop: ${item.name}`) - .setDescription(item.description || "No description available.") + const embed = createBaseEmbed(`Shop: ${item.name}`, item.description || "No description available.", "Green") .addFields({ name: "Price", value: `${item.price} šŸŖ™`, inline: true }) - .setColor("Green") .setThumbnail(item.iconUrl || null) .setImage(item.imageUrl || null) .setFooter({ text: "Click the button below to purchase instantly." }); diff --git a/src/commands/economy/balance.ts b/src/commands/economy/balance.ts index 3785e57..0abc748 100644 --- a/src/commands/economy/balance.ts +++ b/src/commands/economy/balance.ts @@ -1,6 +1,7 @@ import { createCommand } from "@/lib/utils"; -import { SlashCommandBuilder, EmbedBuilder } from "discord.js"; +import { SlashCommandBuilder } from "discord.js"; import { userService } from "@/modules/user/user.service"; +import { createBaseEmbed } from "@lib/embeds"; export const balance = createCommand({ data: new SlashCommandBuilder() @@ -22,10 +23,8 @@ export const balance = createCommand({ const user = await userService.getOrCreateUser(targetUser.id, targetUser.username); - const embed = new EmbedBuilder() - .setAuthor({ name: targetUser.username, iconURL: targetUser.displayAvatarURL() }) - .setDescription(`**Balance**: ${user.balance || 0n} AU`) - .setColor("Yellow"); + const embed = createBaseEmbed(undefined, `**Balance**: ${user.balance || 0n} AU`, "Yellow") + .setAuthor({ name: targetUser.username, iconURL: targetUser.displayAvatarURL() }); await interaction.editReply({ embeds: [embed] }); } diff --git a/src/commands/economy/daily.ts b/src/commands/economy/daily.ts index 54db74f..d80b5e2 100644 --- a/src/commands/economy/daily.ts +++ b/src/commands/economy/daily.ts @@ -1,8 +1,8 @@ import { createCommand } from "@/lib/utils"; -import { SlashCommandBuilder, EmbedBuilder } from "discord.js"; +import { SlashCommandBuilder } from "discord.js"; import { economyService } from "@/modules/economy/economy.service"; -import { createErrorEmbed } from "@lib/embeds"; +import { createErrorEmbed, createSuccessEmbed } from "@lib/embeds"; import { UserError } from "@/lib/errors"; export const daily = createCommand({ @@ -13,16 +13,13 @@ export const daily = createCommand({ try { const result = await economyService.claimDaily(interaction.user.id); - const embed = new EmbedBuilder() - .setTitle("šŸ’° Daily Reward Claimed!") - .setDescription(`You claimed ** ${result.amount}** Astral Units!${result.isWeekly ? `\nšŸŽ‰ **Weekly Bonus!** +${result.weeklyBonus} extra!` : ''}`) + const embed = createSuccessEmbed(`You claimed ** ${result.amount}** Astral Units!${result.isWeekly ? `\nšŸŽ‰ **Weekly Bonus!** +${result.weeklyBonus} extra!` : ''}`, "šŸ’° Daily Reward Claimed!") .addFields( { name: "Streak", value: `šŸ”„ ${result.streak} days`, inline: true }, { name: "Weekly Progress", value: `${"🟩".repeat(result.streak % 7 || 7)}${"⬜".repeat(7 - (result.streak % 7 || 7))} (${result.streak % 7 || 7}/7)`, inline: true }, { name: "Next Reward", value: ` `, inline: true } ) - .setColor("Gold") - .setTimestamp(); + .setColor("Gold"); await interaction.reply({ embeds: [embed] }); diff --git a/src/commands/economy/pay.ts b/src/commands/economy/pay.ts index 56a1d7d..658790e 100644 --- a/src/commands/economy/pay.ts +++ b/src/commands/economy/pay.ts @@ -1,10 +1,10 @@ import { createCommand } from "@/lib/utils"; -import { SlashCommandBuilder, EmbedBuilder, MessageFlags } from "discord.js"; +import { SlashCommandBuilder, MessageFlags } from "discord.js"; import { economyService } from "@/modules/economy/economy.service"; import { userService } from "@/modules/user/user.service"; import { config } from "@/lib/config"; -import { createErrorEmbed } from "@lib/embeds"; +import { createErrorEmbed, createSuccessEmbed } from "@lib/embeds"; import { UserError } from "@/lib/errors"; export const pay = createCommand({ @@ -49,12 +49,7 @@ export const pay = createCommand({ await interaction.deferReply(); await economyService.transfer(senderId, receiverId, amount); - const embed = new EmbedBuilder() - .setTitle("šŸ’ø Transfer Successful") - .setDescription(`Successfully sent ** ${amount}** Astral Units to <@${targetUser.id}>.`) - .setColor("Green") - .setTimestamp(); - + const embed = createSuccessEmbed(`Successfully sent ** ${amount}** Astral Units to <@${targetUser.id}>.`, "šŸ’ø Transfer Successful"); await interaction.editReply({ embeds: [embed], content: `<@${receiverId}>` }); } catch (error: any) { diff --git a/src/commands/economy/trade.ts b/src/commands/economy/trade.ts index ead0ba0..158e931 100644 --- a/src/commands/economy/trade.ts +++ b/src/commands/economy/trade.ts @@ -1,7 +1,7 @@ import { createCommand } from "@/lib/utils"; -import { SlashCommandBuilder, EmbedBuilder, ChannelType, ActionRowBuilder, ButtonBuilder, ButtonStyle, ThreadAutoArchiveDuration, MessageFlags } from "discord.js"; +import { SlashCommandBuilder, ChannelType, ActionRowBuilder, ButtonBuilder, ButtonStyle, ThreadAutoArchiveDuration, MessageFlags } from "discord.js"; import { TradeService } from "@/modules/trade/trade.service"; -import { createErrorEmbed, createWarningEmbed } from "@lib/embeds"; +import { createErrorEmbed, createWarningEmbed, createBaseEmbed } from "@lib/embeds"; export const trade = createCommand({ data: new SlashCommandBuilder() @@ -64,10 +64,7 @@ export const trade = createCommand({ ); // Send Dashboard to Thread - const embed = new EmbedBuilder() - .setTitle("šŸ¤ Trading Session") - .setDescription(`Trade started between ${interaction.user} and ${targetUser}.\nUse the controls below to build your offer.`) - .setColor(0xFFD700) + const embed = createBaseEmbed("šŸ¤ Trading Session", `Trade started between ${interaction.user} and ${targetUser}.\nUse the controls below to build your offer.`, 0xFFD700) .addFields( { name: interaction.user.username, value: "*Empty Offer*", inline: true }, { name: targetUser.username, value: "*Empty Offer*", inline: true } diff --git a/src/commands/inventory/inventory.ts b/src/commands/inventory/inventory.ts index 3ba9894..b5c347f 100644 --- a/src/commands/inventory/inventory.ts +++ b/src/commands/inventory/inventory.ts @@ -1,8 +1,8 @@ import { createCommand } from "@/lib/utils"; -import { SlashCommandBuilder, EmbedBuilder } from "discord.js"; +import { SlashCommandBuilder } from "discord.js"; import { inventoryService } from "@/modules/inventory/inventory.service"; import { userService } from "@/modules/user/user.service"; -import { createWarningEmbed } from "@lib/embeds"; +import { createWarningEmbed, createBaseEmbed } from "@lib/embeds"; export const inventory = createCommand({ data: new SlashCommandBuilder() @@ -35,11 +35,7 @@ export const inventory = createCommand({ return `**${entry.item.name}** x${entry.quantity}`; }).join("\n"); - const embed = new EmbedBuilder() - .setTitle(`${user.username}'s Inventory`) - .setDescription(description) - .setColor("Blue") - .setTimestamp(); + const embed = createBaseEmbed(`${user.username}'s Inventory`, description, "Blue"); await interaction.editReply({ embeds: [embed] }); } diff --git a/src/commands/leveling/leaderboard.ts b/src/commands/leveling/leaderboard.ts index 62d82e1..29ca91f 100644 --- a/src/commands/leveling/leaderboard.ts +++ b/src/commands/leveling/leaderboard.ts @@ -1,9 +1,9 @@ import { createCommand } from "@/lib/utils"; -import { SlashCommandBuilder, EmbedBuilder } from "discord.js"; +import { SlashCommandBuilder } from "discord.js"; import { DrizzleClient } from "@/lib/DrizzleClient"; import { users } from "@/db/schema"; import { desc } from "drizzle-orm"; -import { createWarningEmbed } from "@lib/embeds"; +import { createWarningEmbed, createBaseEmbed } from "@lib/embeds"; export const leaderboard = createCommand({ data: new SlashCommandBuilder() @@ -40,11 +40,7 @@ export const leaderboard = createCommand({ return `${medal} **${user.username}** — ${value}`; }).join("\n"); - const embed = new EmbedBuilder() - .setTitle(isXp ? "šŸ† XP Leaderboard" : "šŸ’° Richest Players") - .setDescription(description) - .setColor("Gold") - .setTimestamp(); + const embed = createBaseEmbed(isXp ? "šŸ† XP Leaderboard" : "šŸ’° Richest Players", description, "Gold"); await interaction.editReply({ embeds: [embed] }); } diff --git a/src/commands/quest/quests.ts b/src/commands/quest/quests.ts index 1a9e736..26573c0 100644 --- a/src/commands/quest/quests.ts +++ b/src/commands/quest/quests.ts @@ -1,7 +1,7 @@ import { createCommand } from "@/lib/utils"; -import { SlashCommandBuilder, EmbedBuilder, MessageFlags } from "discord.js"; +import { SlashCommandBuilder, MessageFlags } from "discord.js"; import { questService } from "@/modules/quest/quest.service"; -import { createWarningEmbed } from "@lib/embeds"; +import { createWarningEmbed, createBaseEmbed } from "@lib/embeds"; export const quests = createCommand({ data: new SlashCommandBuilder() @@ -17,10 +17,7 @@ export const quests = createCommand({ return; } - const embed = new EmbedBuilder() - .setTitle("šŸ“œ Quest Log") - .setColor("Blue") - .setTimestamp(); + const embed = createBaseEmbed("šŸ“œ Quest Log", undefined, "Blue"); userQuests.forEach(entry => { const status = entry.completedAt ? "āœ… Completed" : "In Progress"; diff --git a/src/lib/embeds.ts b/src/lib/embeds.ts index 15cd05c..6e618af 100644 --- a/src/lib/embeds.ts +++ b/src/lib/embeds.ts @@ -1,4 +1,4 @@ -import { EmbedBuilder, Colors } from "discord.js"; +import { Colors, type ColorResolvable, EmbedBuilder } from "discord.js"; /** * Creates a standardized error embed. @@ -55,3 +55,21 @@ export function createInfoEmbed(message: string, title: string = "Info"): EmbedB .setColor(Colors.Blue) .setTimestamp(); } + +/** + * Creates a standardized base embed with common configuration. + * @param title Optional title for the embed. + * @param description Optional description for the embed. + * @param color Optional color for the embed. + * @returns An EmbedBuilder instance with base configuration. + */ +export function createBaseEmbed(title?: string, description?: string, color?: ColorResolvable): EmbedBuilder { + const embed = new EmbedBuilder() + .setTimestamp(); + + if (title) embed.setTitle(title); + if (description) embed.setDescription(description); + if (color) embed.setColor(color); + + return embed; +} diff --git a/src/modules/admin/item_wizard.ts b/src/modules/admin/item_wizard.ts index aad6730..922cf28 100644 --- a/src/modules/admin/item_wizard.ts +++ b/src/modules/admin/item_wizard.ts @@ -2,7 +2,6 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, - EmbedBuilder, ModalBuilder, StringSelectMenuBuilder, TextInputBuilder, @@ -13,6 +12,7 @@ import { import { items } from "@/db/schema"; import { DrizzleClient } from "@/lib/DrizzleClient"; import type { ItemUsageData, ItemEffect } from "@/lib/types"; +import { createBaseEmbed } from "@lib/embeds"; // --- Types --- export interface DraftItem { @@ -66,9 +66,7 @@ export const renderWizard = (userId: string, isDraft = true) => { draftSession.set(userId, draft); } - const embed = new EmbedBuilder() - .setTitle(`šŸ› ļø Item Creator: ${draft.name}`) - .setColor("Blue") + const embed = createBaseEmbed(`šŸ› ļø Item Creator: ${draft.name}`, undefined, "Blue") .addFields( { name: "General", value: `**Type:** ${draft.type}\n**Rarity:** ${draft.rarity}\n**Desc:** ${draft.description}`, inline: true }, { name: "Economy", value: `**Price:** ${draft.price ? `${draft.price} šŸŖ™` : "Not for sale"}`, inline: true }, diff --git a/src/modules/economy/lootdrop.interaction.ts b/src/modules/economy/lootdrop.interaction.ts index b11c182..c13fd4c 100644 --- a/src/modules/economy/lootdrop.interaction.ts +++ b/src/modules/economy/lootdrop.interaction.ts @@ -1,6 +1,6 @@ -import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, EmbedBuilder, ButtonStyle } from "discord.js"; +import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle } from "discord.js"; import { lootdropService } from "./lootdrop.service"; -import { createErrorEmbed } from "@/lib/embeds"; +import { createErrorEmbed, createSuccessEmbed, createBaseEmbed } from "@/lib/embeds"; export async function handleLootdropInteraction(interaction: ButtonInteraction) { if (interaction.customId === "lootdrop_claim") { @@ -17,9 +17,7 @@ export async function handleLootdropInteraction(interaction: ButtonInteraction) const originalEmbed = interaction.message.embeds[0]; if (!originalEmbed) return; - const newEmbed = new EmbedBuilder(originalEmbed.data) - .setDescription(`āœ… Claimed by <@${interaction.user.id}> for **${result.amount} ${result.currency}**!`) - .setColor("#00FF00"); + const newEmbed = createBaseEmbed(originalEmbed.title || "šŸ’° LOOTDROP!", `āœ… Claimed by <@${interaction.user.id}> for **${result.amount} ${result.currency}**!`, "#00FF00"); // Disable button // We reconstruct the button using builders for safety diff --git a/src/modules/economy/lootdrop.service.ts b/src/modules/economy/lootdrop.service.ts index bdaa903..54416d4 100644 --- a/src/modules/economy/lootdrop.service.ts +++ b/src/modules/economy/lootdrop.service.ts @@ -2,6 +2,7 @@ import { Message, TextChannel, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType } from "discord.js"; import { config } from "@/lib/config"; import { economyService } from "./economy.service"; +import { createBaseEmbed } from "@lib/embeds"; import { lootdrops } from "@/db/schema"; import { DrizzleClient } from "@/lib/DrizzleClient"; @@ -91,11 +92,7 @@ class LootdropService { const reward = Math.floor(Math.random() * (max - min + 1)) + min; const currency = config.lootdrop.reward.currency; - const embed = new EmbedBuilder() - .setTitle("šŸ’° LOOTDROP!") - .setDescription(`A lootdrop has appeared! Click the button below to claim **${reward} ${currency}**!`) - .setColor("#FFD700") - .setTimestamp(); + const embed = createBaseEmbed("šŸ’° LOOTDROP!", `A lootdrop has appeared! Click the button below to claim **${reward} ${currency}**!`, "#FFD700"); const claimButton = new ButtonBuilder() .setCustomId("lootdrop_claim") diff --git a/src/modules/trade/trade.interaction.ts b/src/modules/trade/trade.interaction.ts index 9529b29..b149b54 100644 --- a/src/modules/trade/trade.interaction.ts +++ b/src/modules/trade/trade.interaction.ts @@ -3,7 +3,6 @@ import { ModalSubmitInteraction, StringSelectMenuInteraction, type Interaction, - EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, @@ -13,10 +12,11 @@ import { TextInputStyle, ThreadChannel, TextChannel, + EmbedBuilder } from "discord.js"; import { TradeService } from "./trade.service"; import { inventoryService } from "@/modules/inventory/inventory.service"; -import { createErrorEmbed, createWarningEmbed, createSuccessEmbed, createInfoEmbed } from "@lib/embeds"; +import { createErrorEmbed, createWarningEmbed, createSuccessEmbed, createInfoEmbed, createBaseEmbed } from "@lib/embeds"; const EMBED_COLOR = 0xFFD700; // Gold @@ -207,9 +207,7 @@ export async function updateTradeDashboard(interaction: Interaction, threadId: s // Execute Trade try { await TradeService.executeTrade(threadId); - const embed = new EmbedBuilder() - .setTitle("āœ… Trade Completed") - .setColor("Green") + const embed = createBaseEmbed("āœ… Trade Completed", undefined, "Green") .addFields( { name: session.userA.username, value: formatOffer(session.userA), inline: true }, { name: session.userB.username, value: formatOffer(session.userB), inline: true } @@ -246,9 +244,7 @@ export async function updateTradeDashboard(interaction: Interaction, threadId: s } // Build Status Embed - const embed = new EmbedBuilder() - .setTitle("šŸ¤ Trading Session") - .setColor(EMBED_COLOR) + const embed = createBaseEmbed("šŸ¤ Trading Session", undefined, EMBED_COLOR) .addFields( { name: `${session.userA.username} ${session.userA.locked ? 'āœ… (Ready)' : 'āœļø (Editing)'}`,