import disnake from disnake.ext import commands import matplotlib.pyplot as plt import plotly.graph_objects as go import plotly.express as px from plotly.subplots import make_subplots import io import numpy as np from datetime import datetime, timedelta from collections import defaultdict from commandes.ticket.data.storage import get_storage from commandes.ticket.data.models import TicketStatus from commandes.ticket.staff_analytics import StaffAnalytics class StaffRatings(commands.Cog): def __init__(self, bot): self.bot = bot @commands.slash_command(name="staff-ratings", description="Affiche les évaluations du staff") async def staff_ratings(self, interaction: disnake.ApplicationCommandInteraction, team: str = commands.Param(None, description="Filtrer par équipe (optionnel)")): """Commande pour afficher les évaluations du staff""" await interaction.response.defer(ephemeral=False) try: storage = get_storage() analytics = StaffAnalytics(self.bot) # Get staff list staff_list = await analytics.get_staff_list(interaction.guild_id) if not staff_list: await interaction.followup.send("Aucun membre du staff n'a été trouvé.", ephemeral=True) return # Filter by team if specified if team: # This would require a team mapping in the staff data # For now, we'll show all staff pass # Create the rating chart using matplotlib chart_buffer = self.create_staff_rating_chart_matplotlib(staff_list) # Create embed embed = disnake.Embed( title="📊 Évaluations du Staff", description="Performance globale du staff", color=disnake.Color.blue(), timestamp=datetime.now() ) # Add stats total_ratings = sum(s['total_ratings'] for s in staff_list) avg_rating = sum(s['average_rating'] for s in staff_list if s['total_ratings'] > 0) / len([s for s in staff_list if s['total_ratings'] > 0]) if any(s['total_ratings'] > 0 for s in staff_list) else 0 embed.add_field( name="📈 Statistiques", value=f"**Membres du staff:** {len(staff_list)}\n" f"**Évaluations totales:** {total_ratings}\n" f"**Note moyenne globale:** {avg_rating:.1f}⭐", inline=False ) # Send chart file = disnake.File(chart_buffer, filename="staff_ratings.png") await interaction.followup.send(embed=embed, file=file) except Exception as e: print(f"Error in staff_ratings command: {e}") await interaction.followup.send("Une erreur est survenue lors de la génération des statistiques.", ephemeral=True) def create_staff_rating_chart_matplotlib(self, staff_list): """Create staff rating chart using matplotlib""" # Filter staff with ratings rated_staff = [s for s in staff_list if s['total_ratings'] > 0] if not rated_staff: # Return empty chart fig, ax = plt.subplots(figsize=(10, 6), facecolor='#2F3136') ax.set_facecolor('#2F3136') ax.text(0.5, 0.5, 'Aucune évaluation disponible', ha='center', va='center', transform=ax.transAxes, color='white') ax.set_title('Évaluations des Membres du Staff', color='white') buf = io.BytesIO() plt.savefig(buf, format='png', bbox_inches='tight', facecolor='#2F3136') buf.seek(0) plt.close() return buf # Sort by average rating rated_staff.sort(key=lambda x: x['average_rating'], reverse=True) # Prepare data names = [s['name'][:15] + '...' if len(s['name']) > 15 else s['name'] for s in rated_staff] ratings = [s['average_rating'] for s in rated_staff] counts = [s['total_ratings'] for s in rated_staff] # Create figure fig, ax = plt.subplots(figsize=(12, 8), facecolor='#2F3136') fig.patch.set_facecolor('#2F3136') ax.set_facecolor('#2F3136') # Create bars bars = ax.bar(range(len(ratings)), ratings, color=['#57F287' if r >= 4.5 else '#FEE75C' if r >= 3.5 else '#FAA61A' if r >= 2.5 else '#ED4245' for r in ratings]) # Customize ax.set_xticks(range(len(names))) ax.set_xticklabels(names, rotation=45, ha='right', color='white') ax.set_ylabel('Note moyenne', color='white') ax.set_title('Évaluations des Membres du Staff', color='white', fontsize=16) ax.tick_params(colors='white') ax.grid(True, alpha=0.3, color='gray') # Add value labels on bars for i, (bar, rating, count) in enumerate(zip(bars, ratings, counts)): ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.05, f'{rating:.1f}⭐\n({count})', ha='center', va='bottom', color='white', fontsize=8) # Set y-axis limits ax.set_ylim(0, 5.2) # Adjust layout plt.tight_layout() # Save to buffer buf = io.BytesIO() plt.savefig(buf, format='png', bbox_inches='tight', facecolor='#2F3136') buf.seek(0) plt.close() return buf def setup(bot): bot.add_cog(StaffRatings(bot))