import discord from redbot.core import commands, Config, app_commands from typing import Optional, TYPE_CHECKING if TYPE_CHECKING: from redbot.core.bot import Red class OrderModal(discord.ui.Modal, title="Commission Order Form"): commission_type = discord.ui.TextInput(label="What type of commission?") payment_status = discord.ui.TextInput(label="Is this a Free or Paid commission?") description = discord.ui.TextInput(label="Description", style=discord.TextStyle.paragraph) questions = discord.ui.TextInput(label="Any questions?", style=discord.TextStyle.paragraph, required=False) def __init__(self, cog: "KofiShop"): super().__init__() self.cog = cog async def on_submit(self, interaction: discord.Interaction): guild = interaction.guild if not guild: return channel_id = await self.cog.config.guild(guild).order_channel() if not channel_id: await interaction.response.send_message("Order channel not set.", ephemeral=True) return channel = guild.get_channel(channel_id) if not isinstance(channel, discord.TextChannel): await interaction.response.send_message("Invalid order channel.", ephemeral=True) return embed = discord.Embed(title=f"New Order from {interaction.user.name}", color=discord.Color.blurple()) embed.add_field(name="Commission Type", value=self.commission_type.value, inline=False) embed.add_field(name="Payment Status", value=self.payment_status.value, inline=False) embed.add_field(name="Description", value=self.description.value, inline=False) if self.questions.value: embed.add_field(name="Questions", value=self.questions.value, inline=False) await channel.send(embed=embed) await interaction.response.send_message("Your order has been submitted!", ephemeral=True) class ReviewModal(discord.ui.Modal, title="Shop Review"): item_name = discord.ui.TextInput(label="What item/commission are you reviewing?") rating = discord.ui.TextInput(label="Rating (out of 10)", max_length=2) review_text = discord.ui.TextInput(label="Your Review", style=discord.TextStyle.paragraph, max_length=1000) def __init__(self, cog: "KofiShop"): super().__init__() self.cog = cog async def on_submit(self, interaction: discord.Interaction): guild = interaction.guild if not guild: return channel_id = await self.cog.config.guild(guild).review_channel() if not channel_id: await interaction.response.send_message("Review channel not set.", ephemeral=True) return channel = guild.get_channel(channel_id) if not isinstance(channel, discord.TextChannel): await interaction.response.send_message("Invalid review channel.", ephemeral=True) return embed = discord.Embed(title=f"New Review for {self.item_name.value}", color=discord.Color.gold()) embed.set_author(name=interaction.user.name, icon_url=interaction.user.display_avatar.url) embed.add_field(name="Rating", value=f"{self.rating.value}/10") embed.add_field(name="Review", value=self.review_text.value, inline=False) await channel.send(embed=embed) await interaction.response.send_message("Thank you for your review!", ephemeral=True) class KofiShop(commands.Cog): """ An interactive front-end for a Ko-fi store. """ def __init__(self, bot: "Red"): self.bot = bot self.config = Config.get_conf(self, identifier=1234567894, force_registration=True) default_guild = { "order_channel": None, "review_channel": None, "waitlist_channel": None } self.config.register_guild(**default_guild) @app_commands.command() @app_commands.guild_only() async def order(self, interaction: discord.Interaction): """Place an order for a commission.""" await interaction.response.send_modal(OrderModal(self)) @app_commands.command() @app_commands.guild_only() async def review(self, interaction: discord.Interaction): """Leave a review for a completed commission.""" await interaction.response.send_modal(ReviewModal(self)) @app_commands.command() @app_commands.guild_only() async def waitlist(self, interaction: discord.Interaction, *, item: str): """Add an item to the waitlist.""" guild = interaction.guild if not guild: return channel_id = await self.config.guild(guild).waitlist_channel() if not channel_id: await interaction.response.send_message("Waitlist channel not set.", ephemeral=True) return channel = guild.get_channel(channel_id) if not isinstance(channel, discord.TextChannel): await interaction.response.send_message("Invalid waitlist channel.", ephemeral=True) return embed = discord.Embed(description=f"{item} ིྀ {interaction.user.mention}✧ {interaction.channel.mention if isinstance(interaction.channel, discord.TextChannel) else ''}") await channel.send(embed=embed) await interaction.response.send_message("You have been added to the waitlist!", ephemeral=True) @commands.group(aliases=["kset"]) # type: ignore @commands.guild_only() @commands.admin_or_permissions(manage_guild=True) async def kofiset(self, ctx: commands.Context): """Configure KofiShop settings.""" pass @kofiset.command(name="orderchannel") async def set_order_channel(self, ctx: commands.Context, channel: discord.TextChannel): """Set the channel for new orders.""" if not ctx.guild: return await self.config.guild(ctx.guild).order_channel.set(channel.id) await ctx.send(f"Order channel set to {channel.mention}") @kofiset.command(name="reviewchannel") async def set_review_channel(self, ctx: commands.Context, channel: discord.TextChannel): """Set the channel for new reviews.""" if not ctx.guild: return await self.config.guild(ctx.guild).review_channel.set(channel.id) await ctx.send(f"Review channel set to {channel.mention}") @kofiset.command(name="waitlistchannel") async def set_waitlist_channel(self, ctx: commands.Context, channel: discord.TextChannel): """Set the channel for waitlist notifications.""" if not ctx.guild: return await self.config.guild(ctx.guild).waitlist_channel.set(channel.id) await ctx.send(f"Waitlist channel set to {channel.mention}") async def setup(bot: "Red"): await bot.add_cog(KofiShop(bot))