Utilisateur mis à jour avec succès.
"))
}
}
func AdminConversationPage(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
idStr := mux.Vars(r)["id"]
data := map[string]interface{}{
"UserID": idStr,
}
var currentUser models.User
if val := r.Context().Value("ssoid"); val != nil {
ssoid := val.(string)
if err := db.Where("sso_id = ?", ssoid).First(¤tUser).Error; err == nil {
data["User"] = currentUser
}
}
// Si ADMIN → récupérer tous les utilisateurs qui ont des conversations
if currentUser.Role == models.ROLE_ADMIN {
var clients []models.User
db.Raw(`
SELECT DISTINCT users.*
FROM users
JOIN conversations ON users.id = conversations.user_id
ORDER BY users.email
`).Scan(&clients)
data["Clients"] = clients
}
renderTemplate(w, "adminconversations", data)
}
}
func AdminConversationRows(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 1. Récupérer SSOID depuis le contexte
val := r.Context().Value("ssoid")
ssoid, ok := val.(string)
if !ok || ssoid == "" {
http.Error(w, "Non authentifié", http.StatusUnauthorized)
return
}
// 2. Trouver l'utilisateur
var currentUser models.User
if err := db.Where("sso_id = ?", ssoid).First(¤tUser).Error; err != nil {
http.Error(w, "Utilisateur introuvable", http.StatusUnauthorized)
return
}
// 3. Récupération des filtres
idStr := mux.Vars(r)["id"]
id, _ := strconv.Atoi(idStr)
typeFilter := r.URL.Query().Get("type")
dateFilter := r.URL.Query().Get("filter")
var fromDate time.Time
now := time.Now()
switch dateFilter {
case "today":
fromDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
case "week":
fromDate = now.AddDate(0, 0, -7)
default:
fromDate = time.Time{}
}
var convs []models.Conversation
query := db.Model(&models.Conversation{})
// 4. ADMIN → tout ou par utilisateur ciblé
if currentUser.Role != models.ROLE_ADMIN {
query = query.Where("user_id = ?", currentUser.ID)
} else if id > 0 {
query = query.Where("user_id = ?", id)
}
if !fromDate.IsZero() {
query = query.Where("created_at >= ?", fromDate)
}
if typeFilter != "" {
query = query.Where("type = ?", typeFilter)
}
query.Order("created_at desc").Find(&convs)
data := map[string]interface{}{
"Conversations": convs,
"UserID": idStr,
}
renderPartial(w, "admin_conversations_rows", data)
}
}
func AdminConversationThread(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
idStr := mux.Vars(r)["id"]
id, _ := strconv.Atoi(idStr)
var convs []models.Conversation
query := db.Order("created_at asc")
if id != 0 {
query = query.Where("user_id = ?", id)
}
if err := query.Find(&convs).Error; err != nil {
http.Error(w, "Erreur lors du chargement des conversations", http.StatusInternalServerError)
return
}
data := map[string]interface{}{
"Conversations": convs,
"UserID": idStr,
}
renderPartial(w, "admin_conversations_thread", data)
}
}
func Dashboard(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
val := r.Context().Value("ssoid")
ssoid, ok := val.(string)
if !ok || ssoid == "" {
http.Error(w, "Utilisateur non authentifié", http.StatusUnauthorized)
return
}
var user models.User
if err := db.Where("sso_id = ?", ssoid).First(&user).Error; err != nil {
http.Error(w, "Utilisateur introuvable", http.StatusUnauthorized)
return
}
filter := r.URL.Query().Get("filter")
var fromDate time.Time
now := time.Now()
switch filter {
case "today":
fromDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
case "week":
fromDate = now.AddDate(0, 0, -7)
default:
fromDate = time.Time{} // zero time: no filter
}
var totalUsers int64
var totalCredits uint
var totalConversations int64
var conversations []models.Conversation
if user.Role == models.ROLE_ADMIN {
db.Model(&models.User{}).Count(&totalUsers)
db.Model(&models.Consumption{}).Select("SUM(credits_used)").Scan(&totalCredits)
db.Model(&models.Conversation{}).Where("created_at >= ?", fromDate).Count(&totalConversations)
db.Where("created_at >= ?", fromDate).Order("created_at desc").Limit(10).Find(&conversations)
} else {
db.Model(&models.User{}).Where("id = ?", user.ID).Count(&totalUsers)
db.Model(&models.Consumption{}).Where("user_id = ?", user.ID).Select("SUM(credits_used)").Scan(&totalCredits)
db.Model(&models.Conversation{}).Where("user_id = ? AND created_at >= ?", user.ID, fromDate).Count(&totalConversations)
db.Where("user_id = ? AND created_at >= ?", user.ID, fromDate).Order("created_at desc").Limit(10).Find(&conversations)
}
data := map[string]interface{}{
"User": user,
"Stats": map[string]interface{}{
"TotalUsers": totalUsers,
"TotalCreditsUsed": totalCredits,
"TotalConversations": totalConversations,
},
"Conversations": conversations,
}
renderTemplate(w, "dashboard", data)
}
}
// func ClientConsumptionPage(db *gorm.DB) http.HandlerFunc {
// return func(w http.ResponseWriter, r *http.Request) {
// val := r.Context().Value("ssoid")
// ssoid, ok := val.(string)
// if !ok || ssoid == "" {
// http.Error(w, "Non authentifié", http.StatusUnauthorized)
// return
// }
// var currentUser models.User
// if err := db.Where("sso_id = ?", ssoid).First(¤tUser).Error; err != nil {
// http.Error(w, "Utilisateur introuvable", http.StatusUnauthorized)
// return
// }
// period := r.URL.Query().Get("period")
// clientIDStr := r.URL.Query().Get("client")
// var clientID uint
// if clientIDStr != "" {
// idParsed, _ := strconv.Atoi(clientIDStr)
// clientID = uint(idParsed)
// }
// var fromDate time.Time
// now := time.Now()
// switch period {
// case "today":
// fromDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
// case "week":
// fromDate = now.AddDate(0, 0, -7)
// case "month":
// fromDate = now.AddDate(0, -1, 0)
// case "year":
// fromDate = now.AddDate(-1, 0, 0)
// default:
// fromDate = time.Time{}
// }
// query := db.Model(&models.Consumption{})
// if currentUser.Role == models.ROLE_ADMIN {
// if clientID > 0 {
// query = query.Where("user_id = ?", clientID)
// }
// } else {
// query = query.Where("user_id = ?", currentUser.ID)
// }
// if !fromDate.IsZero() {
// query = query.Where("created_at >= ?", fromDate)
// }
// var consumptions []models.Consumption
// query.Order("created_at desc").Find(&consumptions)
// data := map[string]interface{}{
// "Consumptions": consumptions,
// "User": currentUser,
// "SelectedClientID": clientID,
// }
// if currentUser.Role == models.ROLE_ADMIN {
// var clients []models.User
// db.Where("role = ?", "CLIENT").Find(&clients)
// data["Clients"] = clients
// }
// renderTemplate(w, "client_consumption", data)
// }
// }
func ClientConsumptionPage(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
val := r.Context().Value("ssoid")
ssoid, ok := val.(string)
if !ok || ssoid == "" {
http.Error(w, "Non authentifié", http.StatusUnauthorized)
return
}
var currentUser models.User
if err := db.Where("sso_id = ?", ssoid).First(¤tUser).Error; err != nil {
http.Error(w, "Utilisateur introuvable", http.StatusUnauthorized)
return
}
period := r.URL.Query().Get("period")
clientIDStr := r.URL.Query().Get("client")
var clientID uint
if clientIDStr != "" {
idParsed, _ := strconv.Atoi(clientIDStr)
clientID = uint(idParsed)
}
var fromDate time.Time
now := time.Now()
switch period {
case "today":
fromDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
case "week":
fromDate = now.AddDate(0, 0, -7)
case "month":
fromDate = now.AddDate(0, -1, 0)
case "year":
fromDate = now.AddDate(-1, 0, 0)
default:
fromDate = time.Time{}
}
// Préparation des filtres
query := db.Model(&models.Consumption{})
if currentUser.Role == models.ROLE_ADMIN {
if clientID > 0 {
query = query.Where("user_id = ?", clientID)
}
} else {
query = query.Where("user_id = ?", currentUser.ID)
}
if !fromDate.IsZero() {
query = query.Where("created_at >= ?", fromDate)
}
// Regroupement par date
type DailySummary struct {
Date time.Time
TotalCredits uint
}
var summaries []DailySummary
query.Select("DATE(created_at) as date, SUM(credits_used) as total_credits").
Group("DATE(created_at)").Order("date desc").
Scan(&summaries)
// Détail par jour
details := make(map[string][]models.Consumption)
for _, s := range summaries {
var daily []models.Consumption
start := time.Date(s.Date.Year(), s.Date.Month(), s.Date.Day(), 0, 0, 0, 0, s.Date.Location())
end := start.Add(24 * time.Hour)
detailQuery := db.Model(&models.Consumption{}).Where("created_at >= ? AND created_at < ?", start, end)
if currentUser.Role == models.ROLE_ADMIN {
if clientID > 0 {
detailQuery = detailQuery.Where("user_id = ?", clientID)
}
} else {
detailQuery = detailQuery.Where("user_id = ?", currentUser.ID)
}
detailQuery.Order("created_at desc").Find(&daily)
details[s.Date.Format("2006-01-02")] = daily
}
data := map[string]interface{}{
"User": currentUser,
"Summaries": summaries,
"DetailsByDate": details,
"SelectedClientID": clientID,
"Period": period,
}
if currentUser.Role == models.ROLE_ADMIN {
var clients []models.User
db.Where("role = ?", "CLIENT").Find(&clients)
data["Clients"] = clients
}
renderTemplate(w, "client_consumption", data)
}
}
// pour un rendu complet de la page
func renderTemplate(w http.ResponseWriter, templ string, data map[string]interface{}) {
t, err := template.ParseFiles(
"./frontend/templates/head.pages.tmpl",
"./frontend/templates/sidebar.pages.tmpl",
"./frontend/templates/" + templ + ".pages.tmpl",
)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Exécutez explicitement le template principal
err = t.ExecuteTemplate(w, templ+".pages.tmpl", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
// pour un rendu de composent.
func renderPartial(w http.ResponseWriter, templ string, data map[string]interface{}) {
t, err := template.ParseFiles("./frontend/templates/" + templ + ".pages.tmpl")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
err = t.Execute(w, data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}