from __future__ import annotations import logging import discord from discord import app_commands from discord.ext import commands from tickets import storage from tickets.data import TicketCategory from tickets.ui import AddMemberButton, ClaimButton, CloseButton, PanelCreateButton logger = logging.getLogger("vision") class PanelView(discord.ui.LayoutView): def __init__(self): super().__init__(timeout=None) container = discord.ui.Container() container.add_item( discord.ui.TextDisplay( "## Systeme de tickets\n" "Besoin d'aide ? Creez un ticket et notre equipe vous repondra.\n" "Cliquez sur le bouton ci-dessous pour commencer." ) ) container.add_item(discord.ui.Separator()) container.add_item(discord.ui.ActionRow(PanelCreateButton())) self.add_item(container) class ConfigView(discord.ui.LayoutView): def __init__(self): super().__init__(timeout=None) container = discord.ui.Container() container.add_item(discord.ui.TextDisplay("## Configuration Tickets\nModifications enregistrees.")) self.add_item(container) class AddCategoryModal(discord.ui.Modal, title="Ajouter une categorie"): name = discord.ui.TextInput(label="Nom", max_length=50, required=True) emoji = discord.ui.TextInput(label="Emoji", max_length=10, required=False) description = discord.ui.TextInput( label="Description", max_length=100, required=False, style=discord.TextStyle.paragraph, ) async def on_submit(self, interaction: discord.Interaction): config = storage.get_config(interaction.guild_id) cat_id = self.name.value.lower().replace(" ", "-")[:20] cat = TicketCategory( id=cat_id, name=self.name.value, emoji=self.emoji.value or "", description=self.description.value or "", ) config.categories.append(cat) storage.save_config(config) await interaction.response.send_message(f"Categorie **{cat.name}** ajoutee.", ephemeral=True) class ConfigToggleButton(discord.ui.Button): def __init__(self, enabled: bool): super().__init__( label="Desactiver" if enabled else "Activer", style=discord.ButtonStyle.danger if enabled else discord.ButtonStyle.success, custom_id="ticket_cfg_toggle", ) async def callback(self, interaction: discord.Interaction): config = storage.get_config(interaction.guild_id) config.enabled = not config.enabled storage.save_config(config) await interaction.response.edit_message(view=ConfigView()) class ConfigAddCatButton(discord.ui.Button): def __init__(self): super().__init__(label="Ajouter categorie", style=discord.ButtonStyle.primary, custom_id="ticket_cfg_addcat") async def callback(self, interaction: discord.Interaction): await interaction.response.send_modal(AddCategoryModal()) class ConfigSetStaffButton(discord.ui.Button): def __init__(self): super().__init__(label="Role staff", style=discord.ButtonStyle.secondary, custom_id="ticket_cfg_staff") async def callback(self, interaction: discord.Interaction): view = discord.ui.View(timeout=300) sel = discord.ui.RoleSelect( placeholder="Role staff...", custom_id="ticket_staff_role_select", min_values=1, max_values=1 ) async def _cb(interaction: discord.Interaction): config = storage.get_config(interaction.guild_id) config.staff_role_id = sel.values[0].id storage.save_config(config) await interaction.response.edit_message(content=f"Role staff : {sel.values[0].mention}", view=None) sel.callback = _cb view.add_item(sel) await interaction.response.send_message("Selectionnez le role staff :", view=view, ephemeral=True) class ConfigSetLogButton(discord.ui.Button): def __init__(self): super().__init__(label="Canal logs", style=discord.ButtonStyle.secondary, custom_id="ticket_cfg_log") async def callback(self, interaction: discord.Interaction): view = discord.ui.View(timeout=300) sel = discord.ui.ChannelSelect( placeholder="Canal de logs...", custom_id="ticket_log_channel_select", channel_types=[discord.ChannelType.text], min_values=1, max_values=1, ) async def _cb(interaction: discord.Interaction): config = storage.get_config(interaction.guild_id) config.log_channel_id = sel.values[0].id storage.save_config(config) await interaction.response.edit_message(content=f"Canal de logs : {sel.values[0].mention}", view=None) sel.callback = _cb view.add_item(sel) await interaction.response.send_message("Selectionnez le canal de logs :", view=view, ephemeral=True) class TicketManagementView(discord.ui.LayoutView): def __init__(self): super().__init__(timeout=None) container = discord.ui.Container() container.add_item(discord.ui.ActionRow(ClaimButton(), AddMemberButton(), CloseButton())) self.add_item(container) class TicketSystem(commands.Cog): ticket = app_commands.Group(name="ticket", description="Systeme de tickets") def __init__(self, bot: commands.Bot): self.bot = bot self.bot.add_view(PanelView()) self.bot.add_view(TicketManagementView()) @commands.Cog.listener() async def on_ready(self): logger.info("TicketSystem cog charge") @ticket.command(name="setup", description="Envoyer le panneau de tickets") @app_commands.describe(channel="Canal pour le panneau") @app_commands.checks.has_permissions(manage_guild=True) async def ticket_setup(self, interaction: discord.Interaction, channel: discord.TextChannel): config = storage.get_config(interaction.guild_id) config.enabled = True config.panel_channel_id = channel.id storage.save_config(config) view = PanelView() msg = await channel.send(view=view) config.panel_message_id = msg.id storage.save_config(config) container = discord.ui.Container() container.add_item(discord.ui.TextDisplay(f"## Panneau envoye\nCanal : {channel.mention}\nStatut : Actif")) resp_view = discord.ui.LayoutView() resp_view.add_item(container) await interaction.response.send_message(view=resp_view, ephemeral=True) @ticket.command(name="config", description="Configuration du systeme de tickets") @app_commands.checks.has_permissions(manage_guild=True) async def ticket_config(self, interaction: discord.Interaction): config = storage.get_config(interaction.guild_id) cats = "\n".join(f"- {c.emoji} **{c.name}**" for c in config.categories) or "*Aucune*" staff_line = f"**Role staff :** <@&{config.staff_role_id}>\n" if config.staff_role_id else "" log_line = f"**Canal de logs :** <#{config.log_channel_id}>\n" if config.log_channel_id else "" container = discord.ui.Container() container.add_item( discord.ui.TextDisplay( f"## Configuration Tickets\n" f"**Statut :** {'Actif' if config.enabled else 'Inactif'}\n" f"{staff_line}{log_line}### Categories\n{cats}" ) ) container.add_item(discord.ui.Separator()) container.add_item( discord.ui.ActionRow( ConfigToggleButton(config.enabled), ConfigAddCatButton(), ConfigSetStaffButton(), ConfigSetLogButton(), ) ) view = discord.ui.LayoutView() view.add_item(container) await interaction.response.send_message(view=view, ephemeral=True) async def setup(bot: commands.Bot): await bot.add_cog(TicketSystem(bot))