diff --git a/capy_discord/exts/profile/profile.py b/capy_discord/exts/profile/profile.py index 1504860..bcf248f 100644 --- a/capy_discord/exts/profile/profile.py +++ b/capy_discord/exts/profile/profile.py @@ -8,6 +8,7 @@ from capy_discord.ui.forms import ModelModal from capy_discord.ui.views import BaseView +from capy_discord.utils.embeds import error_embed, info_embed, success_embed from ._schemas import UserProfileSchema @@ -74,14 +75,14 @@ async def handle_edit_action(self, interaction: discord.Interaction, action: str current_profile = self.profiles.get(user_id) if action == "create" and current_profile: - await interaction.response.send_message( - "You already have a profile! Use `/profile action:update` to edit it.", ephemeral=True + embed = error_embed( + "Profile Exists", "You already have a profile! Use `/profile action:update` to edit it." ) + await interaction.response.send_message(embed=embed, ephemeral=True) return if action == "update" and not current_profile: - await interaction.response.send_message( - "You don't have a profile yet! Use `/profile action:create` first.", ephemeral=True - ) + embed = error_embed("No Profile", "You don't have a profile yet! Use `/profile action:create` first.") + await interaction.response.send_message(embed=embed, ephemeral=True) return # Convert Pydantic model to dict for initial data if it exists @@ -102,9 +103,8 @@ async def handle_show_action(self, interaction: discord.Interaction) -> None: profile = self.profiles.get(interaction.user.id) if not profile: - await interaction.response.send_message( - "You haven't set up a profile yet! Use `/profile action:create`.", ephemeral=True - ) + embed = error_embed("No Profile", "You haven't set up a profile yet! Use `/profile action:create`.") + await interaction.response.send_message(embed=embed, ephemeral=True) return embed = self._create_profile_embed(interaction.user, profile) @@ -115,7 +115,8 @@ async def handle_delete_action(self, interaction: discord.Interaction) -> None: profile = self.profiles.get(interaction.user.id) if not profile: - await interaction.response.send_message("You don't have a profile to delete.", ephemeral=True) + embed = error_embed("No Profile", "You don't have a profile to delete.") + await interaction.response.send_message(embed=embed, ephemeral=True) return view = ConfirmDeleteView() @@ -131,9 +132,11 @@ async def handle_delete_action(self, interaction: discord.Interaction) -> None: # [DB CALL]: Delete profile del self.profiles[interaction.user.id] self.log.info("Deleted profile for user %s", interaction.user) - await interaction.followup.send("✅ Your profile has been deleted.", ephemeral=True) + embed = success_embed("Profile Deleted", "Your profile has been deleted.") + await interaction.followup.send(embed=embed, ephemeral=True) else: - await interaction.followup.send("❌ Profile deletion cancelled.", ephemeral=True) + embed = info_embed("Cancelled", "Profile deletion cancelled.") + await interaction.followup.send(embed=embed, ephemeral=True) async def _handle_profile_submit(self, interaction: discord.Interaction, profile: UserProfileSchema) -> None: """Process the valid profile submission.""" @@ -143,7 +146,8 @@ async def _handle_profile_submit(self, interaction: discord.Interaction, profile self.log.info("Updated profile for user %s", interaction.user) embed = self._create_profile_embed(interaction.user, profile) - await interaction.response.send_message(content="✅ Profile updated successfully!", embed=embed, ephemeral=True) + success = success_embed("Profile Updated", "Your profile has been updated successfully!") + await interaction.response.send_message(embeds=[success, embed], ephemeral=True) def _create_profile_embed(self, user: discord.User | discord.Member, profile: UserProfileSchema) -> discord.Embed: """Helper to build the profile display embed.""" diff --git a/capy_discord/utils/embeds.py b/capy_discord/utils/embeds.py new file mode 100644 index 0000000..ac8a303 --- /dev/null +++ b/capy_discord/utils/embeds.py @@ -0,0 +1,102 @@ +"""Standard embed utilities for consistent message styling.""" + +import discord + +STATUS_ERROR = discord.Color.red() +STATUS_SUCCESS = discord.Color.green() +STATUS_INFO = discord.Color.blue() +STATUS_WARNING = discord.Color.yellow() +STATUS_IMPORTANT = discord.Color.gold() +STATUS_UNMARKED = discord.Color.light_grey() +STATUS_IGNORED = discord.Color.greyple() + + +def error_embed(title: str, description: str) -> discord.Embed: + """Create an error status embed. + + Args: + title: The title of the embed. + description: The description of the embed. + + Returns: + discord.Embed: The created embed. + """ + return discord.Embed(title=title, description=description, color=STATUS_ERROR) + + +def success_embed(title: str, description: str) -> discord.Embed: + """Create a success status embed. + + Args: + title: The title of the embed. + description: The description of the embed. + + Returns: + discord.Embed: The created embed. + """ + return discord.Embed(title=title, description=description, color=STATUS_SUCCESS) + + +def info_embed(title: str, description: str) -> discord.Embed: + """Create an info status embed. + + Args: + title: The title of the embed. + description: The description of the embed. + + Returns: + discord.Embed: The created embed. + """ + return discord.Embed(title=title, description=description, color=STATUS_INFO) + + +def warning_embed(title: str, description: str) -> discord.Embed: + """Create a warning status embed. + + Args: + title: The title of the embed. + description: The description of the embed. + + Returns: + discord.Embed: The created embed. + """ + return discord.Embed(title=title, description=description, color=STATUS_WARNING) + + +def important_embed(title: str, description: str) -> discord.Embed: + """Create an important status embed. + + Args: + title: The title of the embed. + description: The description of the embed. + + Returns: + discord.Embed: The created embed. + """ + return discord.Embed(title=title, description=description, color=STATUS_IMPORTANT) + + +def unmarked_embed(title: str, description: str) -> discord.Embed: + """Create an unmarked status embed. + + Args: + title: The title of the embed. + description: The description of the embed. + + Returns: + discord.Embed: The created embed. + """ + return discord.Embed(title=title, description=description, color=STATUS_UNMARKED) + + +def ignored_embed(title: str, description: str) -> discord.Embed: + """Create an ignored status embed. + + Args: + title: The title of the embed. + description: The description of the embed. + + Returns: + discord.Embed: The created embed. + """ + return discord.Embed(title=title, description=description, color=STATUS_IGNORED) diff --git a/tests/capy_discord/utils/test_embeds.py b/tests/capy_discord/utils/test_embeds.py new file mode 100644 index 0000000..2dd2d85 --- /dev/null +++ b/tests/capy_discord/utils/test_embeds.py @@ -0,0 +1,90 @@ +"""Tests for the embed utility functions.""" + +import discord + +from capy_discord.utils.embeds import ( + error_embed, + ignored_embed, + important_embed, + info_embed, + success_embed, + unmarked_embed, + warning_embed, +) + + +def test_error_embed(): + """Test the error_embed helper function.""" + title = "Error Title" + description = "Error Description" + embed = error_embed(title, description) + + assert embed.title == title + assert embed.description == description + assert embed.color == discord.Color.red() + + +def test_success_embed(): + """Test the success_embed helper function.""" + title = "Success Title" + description = "Success Description" + embed = success_embed(title, description) + + assert embed.title == title + assert embed.description == description + assert embed.color == discord.Color.green() + + +def test_info_embed(): + """Test the info_embed helper function.""" + title = "Info Title" + description = "Info Description" + embed = info_embed(title, description) + + assert embed.title == title + assert embed.description == description + assert embed.color == discord.Color.blue() + + +def test_warning_embed(): + """Test the warning_embed helper function.""" + title = "Warning Title" + description = "Warning Description" + embed = warning_embed(title, description) + + assert embed.title == title + assert embed.description == description + assert embed.color == discord.Color.yellow() + + +def test_important_embed(): + """Test the important_embed helper function.""" + title = "Important Title" + description = "Important Description" + embed = important_embed(title, description) + + assert embed.title == title + assert embed.description == description + assert embed.color == discord.Color.gold() + + +def test_unmarked_embed(): + """Test the unmarked_embed helper function.""" + title = "Unmarked Title" + description = "Unmarked Description" + embed = unmarked_embed(title, description) + + assert embed.title == title + assert embed.description == description + assert embed.color == discord.Color.light_grey() + + +def test_ignored_embed(): + """Test the ignored_embed helper function.""" + title = "Ignored Title" + description = "Ignored Description" + embed = ignored_embed(title, description) + + assert embed.title == title + assert embed.description == description + assert embed.color == discord.Color.greyple()