Kuby/commandes/ticket/feedback_view.py

147 lines
6.9 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import disnake
from .data.models import TicketData
class FeedbackView(disnake.ui.View):
def __init__(self, bot, storage, ticket: TicketData, staff_rating_only: bool = False):
super().__init__(timeout=86400) # 24h timeout
self.bot = bot
self.storage = storage
self.ticket = ticket
self.rating = 0
self.comment = ""
self.staff_rating_only = staff_rating_only
# Add Select Menu for Rating
self.add_item(RatingSelect())
@disnake.ui.button(label="📝 Laisser un commentaire", style=disnake.ButtonStyle.secondary, custom_id="feedback_comment", row=1)
async def comment_button(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await interaction.response.send_modal(FeedbackModal(self))
@disnake.ui.button(label="✅ Envoyer", style=disnake.ButtonStyle.green, custom_id="feedback_submit", row=1)
async def submit_button(self, button: disnake.ui.Button, interaction: disnake.Interaction):
if self.rating == 0:
await interaction.response.send_message("❌ Veuillez sélectionner une note avant d'envoyer.", ephemeral=True)
return
# Save feedback
self.ticket.rating = self.rating
self.ticket.feedback = self.comment if self.comment else "Aucun commentaire"
self.storage.save_ticket(self.ticket)
# Disable view
for child in self.children:
child.disabled = True
# If this is a staff rating only view, we don't send the normal message
if not self.staff_rating_only:
await interaction.response.edit_message(content="✅ Merci pour votre retour !", view=self, embed=None)
else:
await interaction.response.edit_message(content="✅ Note envoyée !", view=self, embed=None)
# Log feedback if configured
try:
# Reload ticket to ensure we have latest data (especially claimed_by)
# We need to use the channel_id to find the ticket
reloaded_ticket = self.storage.load_ticket(self.ticket.channel_id)
if reloaded_ticket:
self.ticket = reloaded_ticket
print(f"DEBUG: Reloaded ticket {self.ticket.channel_id}. Claimed by: {self.ticket.claimed_by}", flush=True)
else:
print(f"DEBUG: Could not reload ticket {self.ticket.channel_id}", flush=True)
print(f"DEBUG: Feedback submitted for {self.ticket.channel_id}", flush=True)
if self.ticket.claimed_by:
staff_user = self.bot.get_user(self.ticket.claimed_by)
print(f"DEBUG: Staff user from cache: {staff_user}", flush=True)
if not staff_user:
# Try fetching if not in cache
try:
staff_user = await self.bot.fetch_user(self.ticket.claimed_by)
print(f"DEBUG: Staff user fetched: {staff_user}", flush=True)
except Exception as e:
print(f"DEBUG: Failed to fetch staff user: {e}", flush=True)
pass
if staff_user:
# Create feedback embed
embed = disnake.Embed(
title="📝 Nouveau Commentaire Reçu",
description=f"Un utilisateur a laissé un avis sur le ticket #{self.ticket.channel_id}",
color=disnake.Color.gold() if self.rating < 3 else disnake.Color.green(),
timestamp=disnake.utils.utcnow()
)
embed.add_field(
name="Note",
value=f"{'' * self.rating} ({self.rating}/5)",
inline=True
)
# Add user info if possible
user = self.bot.get_user(self.ticket.user_id)
user_name = f"{user.name} ({user.id})" if user else f"Utilisateur {self.ticket.user_id}"
embed.add_field(
name="Utilisateur",
value=user_name,
inline=True
)
feedback_text = self.comment if self.comment else "Aucun commentaire écrit."
embed.add_field(
name="Commentaire",
value=feedback_text,
inline=False
)
try:
await staff_user.send(embed=embed)
print(f"DEBUG: DM sent successfully to {staff_user}", flush=True)
except disnake.Forbidden:
print(f"DEBUG: DM failed - Forbidden (DMs closed)", flush=True)
except Exception as e:
print(f"DEBUG: Error sending feedback DM: {e}", flush=True)
else:
print("DEBUG: Staff user object is None", flush=True)
else:
print("DEBUG: Ticket has no claimed_by value", flush=True)
except Exception as e:
print(f"Error in feedback notification: {e}", flush=True)
class RatingSelect(disnake.ui.Select):
def __init__(self):
options = [
disnake.SelectOption(label="⭐⭐⭐⭐⭐ (Excellent)", value="5", description="Service parfait !"),
disnake.SelectOption(label="⭐⭐⭐⭐ (Très bien)", value="4", description="Très bon service"),
disnake.SelectOption(label="⭐⭐⭐ (Bien)", value="3", description="Correct"),
disnake.SelectOption(label="⭐⭐ (Moyen)", value="2", description="Peut mieux faire"),
disnake.SelectOption(label="⭐ (Mauvais)", value="1", description="Insatisfaisant")
]
super().__init__(placeholder="Notez le service...", min_values=1, max_values=1, options=options, row=0)
async def callback(self, interaction: disnake.Interaction):
self.view.rating = int(self.values[0])
await interaction.response.defer()
class FeedbackModal(disnake.ui.Modal):
"""Modal that collects a freeform comment for a ticket feedback."""
def __init__(self, view: FeedbackView):
self.view = view
self.comment = disnake.ui.TextInput(
label="Commentaire",
style=disnake.TextInputStyle.paragraph,
placeholder="Dites-nous ce que vous avez pensé du support...",
required=True,
max_length=1000,
)
super().__init__(title="Votre avis", components=[self.comment])
async def callback(self, interaction: disnake.Interaction):
self.view.comment = self.comment.value
await interaction.response.send_message(
"Commentaire enregistré! N'oubliez pas de valider avec «Envoyer».",
ephemeral=True,
)