687 lines
20 KiB
Go
687 lines
20 KiB
Go
package renders
|
|
|
|
import (
|
|
"cangui/whatsapp/backend/models"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"text/template"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/gorilla/mux"
|
|
"golang.org/x/crypto/bcrypt"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// les renders permette d afficher les pages html.
|
|
|
|
func Login(w http.ResponseWriter, r *http.Request){
|
|
renderTemplate(w,"login",nil)
|
|
}
|
|
func JwtTest(w http.ResponseWriter, r *http.Request){
|
|
renderTemplate(w,"jwt",nil)
|
|
}
|
|
func TestMessagesPages(w http.ResponseWriter, r *http.Request){
|
|
renderTemplate(w,"test-send",nil)
|
|
}
|
|
func TestMessagesPages2(w http.ResponseWriter, r *http.Request){
|
|
renderTemplate(w,"test",nil)
|
|
}
|
|
func ApiDocPage(db *gorm.DB) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
data := map[string]interface{}{}
|
|
if val := r.Context().Value("ssoid"); val != nil {
|
|
var user models.User
|
|
if err := db.Where("sso_id = ?", val.(string)).First(&user).Error; err == nil {
|
|
data["User"] = user
|
|
}
|
|
}
|
|
renderTemplate(w, "apidoc", data)
|
|
}
|
|
}
|
|
|
|
func AdminUserList(db *gorm.DB) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var users []models.User
|
|
|
|
if err := db.Find(&users).Error; err != nil {
|
|
http.Error(w, "Erreur lors du chargement des utilisateurs", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
data := map[string]interface{}{
|
|
"Users": users,
|
|
}
|
|
if _, exists := data["User"]; !exists {
|
|
if val := r.Context().Value("ssoid"); val != nil {
|
|
ssoid := val.(string)
|
|
var user models.User
|
|
if err := db.Where("sso_id = ?", ssoid).First(&user).Error; err == nil {
|
|
data["User"] = user
|
|
}
|
|
}
|
|
}
|
|
|
|
renderTemplate(w, "admin_users", data)
|
|
}
|
|
}
|
|
func AdminUserEdit(db *gorm.DB) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
id, _ := strconv.Atoi(mux.Vars(r)["id"])
|
|
var user models.User
|
|
if err := db.First(&user, id).Error; err != nil {
|
|
http.Error(w, "Utilisateur introuvable", http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
data := map[string]interface{}{
|
|
"U": user,
|
|
}
|
|
if _, exists := data["User"]; !exists {
|
|
if val := r.Context().Value("ssoid"); val != nil {
|
|
ssoid := val.(string)
|
|
var user models.User
|
|
if err := db.Where("sso_id = ?", ssoid).First(&user).Error; err == nil {
|
|
data["User"] = user
|
|
}
|
|
}
|
|
}
|
|
|
|
renderTemplate(w, "admin_user_edit", data)
|
|
}
|
|
}
|
|
func CreateUserHandler(db *gorm.DB) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if err := r.ParseForm(); err != nil {
|
|
http.Error(w, "Formulaire invalide", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
email := r.FormValue("email")
|
|
password := r.FormValue("password")
|
|
role := r.FormValue("role")
|
|
monthlyCreditsStr := r.FormValue("monthly_credits")
|
|
waToken := r.FormValue("whatsapp_token")
|
|
waPhoneID := r.FormValue("whatsapp_phone_number_id")
|
|
|
|
if email == "" || password == "" {
|
|
http.Error(w, "Email et mot de passe requis", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
http.Error(w, "Erreur hash mot de passe", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
monthlyCredits := uint(100)
|
|
if monthlyCreditsStr != "" {
|
|
if val, err := strconv.Atoi(monthlyCreditsStr); err == nil {
|
|
monthlyCredits = uint(val)
|
|
}
|
|
}
|
|
|
|
newUser := models.User{
|
|
Email: email,
|
|
Password: string(hashedPassword),
|
|
Role: models.UserRole(role),
|
|
SSOID: uuid.New().String(),
|
|
IsActive: true,
|
|
MonthlyCredits: monthlyCredits,
|
|
CurrentMonthCredits: monthlyCredits,
|
|
WhatsappToken: waToken,
|
|
WhatsappPhoneNumberID: waPhoneID,
|
|
}
|
|
|
|
if err := db.Create(&newUser).Error; err != nil {
|
|
http.Error(w, "Erreur lors de la création", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("HX-Trigger", "userCreated")
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write([]byte("<article class='message is-success'><div class='message-body'>Utilisateur créé avec succès.</div></article>"))
|
|
}
|
|
}
|
|
func AdminUserCreateForm(db *gorm.DB) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
data := map[string]interface{}{
|
|
"H": "",
|
|
}
|
|
if val := r.Context().Value("ssoid"); val != nil {
|
|
ssoid := val.(string)
|
|
var user models.User
|
|
if err := db.Where("sso_id = ?", ssoid).First(&user).Error; err == nil {
|
|
data["U"] = user
|
|
}
|
|
}
|
|
if _, exists := data["User"]; !exists {
|
|
if val := r.Context().Value("ssoid"); val != nil {
|
|
ssoid := val.(string)
|
|
var user models.User
|
|
if err := db.Where("sso_id = ?", ssoid).First(&user).Error; err == nil {
|
|
data["User"] = user
|
|
}
|
|
}
|
|
}
|
|
renderTemplate(w, "admin_user_create", data)
|
|
}
|
|
}
|
|
func AdminUserCreate(db *gorm.DB) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if err := r.ParseForm(); err != nil {
|
|
http.Error(w, "Formulaire invalide", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
email := r.FormValue("email")
|
|
password := r.FormValue("password")
|
|
role := models.UserRole(r.FormValue("role"))
|
|
|
|
hashed, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
http.Error(w, "Erreur hash", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
ssoid := "sso_" + uuid.New().String()
|
|
user := models.User{
|
|
Email: email,
|
|
Password: string(hashed),
|
|
Role: role,
|
|
IsActive: true,
|
|
SSOID: ssoid,
|
|
}
|
|
|
|
if err := db.Create(&user).Error; err != nil {
|
|
http.Error(w, "Erreur enregistrement", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("HX-Trigger", `{"userCreated":"Utilisateur créé avec succès"}`)
|
|
w.Header().Set("HX-Remove", "true") // cache le form
|
|
renderPartial(w, "admin_user_row", map[string]interface{}{"User": user})
|
|
}
|
|
}
|
|
|
|
func AdminUserEditForm(db *gorm.DB) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
id := mux.Vars(r)["id"]
|
|
|
|
var user models.User
|
|
if err := db.First(&user, id).Error; err != nil {
|
|
http.Error(w, "Utilisateur introuvable", http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
data := map[string]interface{}{
|
|
"User": user,
|
|
}
|
|
if _, exists := data["User"]; !exists {
|
|
if val := r.Context().Value("ssoid"); val != nil {
|
|
ssoid := val.(string)
|
|
var user models.User
|
|
if err := db.Where("sso_id = ?", ssoid).First(&user).Error; err == nil {
|
|
data["User"] = user
|
|
}
|
|
}
|
|
}
|
|
|
|
renderTemplate(w, "admin_user_edit", data)
|
|
}
|
|
}
|
|
func AdminUserUpdate(db *gorm.DB) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
id := mux.Vars(r)["id"]
|
|
|
|
var user models.User
|
|
if err := db.First(&user, id).Error; err != nil {
|
|
http.Error(w, "Utilisateur introuvable", http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
if err := r.ParseForm(); err != nil {
|
|
http.Error(w, "Formulaire invalide", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
email := r.FormValue("email")
|
|
password := r.FormValue("password")
|
|
role := r.FormValue("role")
|
|
isActive := r.FormValue("is_active") == "on"
|
|
waToken := r.FormValue("whatsapp_token")
|
|
waPhoneID := r.FormValue("whatsapp_phone_number_id")
|
|
monthlyCreditsStr := r.FormValue("monthly_credits")
|
|
|
|
user.Email = email
|
|
user.Role = models.UserRole(role)
|
|
user.IsActive = isActive
|
|
user.WhatsappToken = waToken
|
|
user.WhatsappPhoneNumberID = waPhoneID
|
|
|
|
if monthlyCreditsStr != "" {
|
|
if val, err := strconv.Atoi(monthlyCreditsStr); err == nil {
|
|
user.MonthlyCredits = uint(val)
|
|
}
|
|
}
|
|
|
|
if password != "" {
|
|
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
http.Error(w, "Erreur de hachage du mot de passe", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
user.Password = string(hash)
|
|
}
|
|
|
|
if err := db.Save(&user).Error; err != nil {
|
|
http.Error(w, "Erreur lors de la mise à jour", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("HX-Trigger", "userUpdated")
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write([]byte("<article class='message is-success'><div class='message-body'>Utilisateur mis à jour avec succès.</div></article>"))
|
|
}
|
|
}
|
|
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
|
|
}
|
|
fmt.Println("🔐 SSOID reçu :", ssoid)
|
|
|
|
var currentUser models.User
|
|
if err := db.Where("sso_id = ?", ssoid).First(¤tUser).Error; err != nil {
|
|
http.Error(w, "Utilisateur introuvable", http.StatusUnauthorized)
|
|
fmt.Println("❌ Utilisateur introuvable en base pour ce SSOID")
|
|
return
|
|
}
|
|
fmt.Printf("👤 Utilisateur connecté : %s (ID %d - rôle %s)\n", currentUser.Email, currentUser.ID, currentUser.Role)
|
|
|
|
// Récupérer les filtres
|
|
period := r.URL.Query().Get("period")
|
|
clientIDStr := r.URL.Query().Get("client")
|
|
var clientID uint
|
|
if clientIDStr != "" {
|
|
idParsed, _ := strconv.Atoi(clientIDStr)
|
|
clientID = uint(idParsed)
|
|
}
|
|
fmt.Println("📅 Filtre période :", period)
|
|
if clientID > 0 {
|
|
fmt.Println("🎯 Filtre client ID :", clientID)
|
|
}
|
|
|
|
// Calcul de la date de début
|
|
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{}
|
|
}
|
|
fmt.Println("📆 Date de début utilisée :", fromDate)
|
|
|
|
// Requête de base
|
|
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)
|
|
}
|
|
|
|
// Résumé journalier
|
|
type DailySummary struct {
|
|
Date time.Time
|
|
TotalCredits uint
|
|
}
|
|
var summaries []DailySummary
|
|
result := query.Select("DATE(created_at) as date, SUM(credits_used) as total_credits").
|
|
Group("DATE(created_at)").Order("date desc").
|
|
Scan(&summaries)
|
|
|
|
if result.Error != nil {
|
|
fmt.Println("❌ Erreur lors de la récupération du résumé :", result.Error)
|
|
}
|
|
fmt.Printf("📊 Résumés trouvés : %d\n", len(summaries))
|
|
|
|
// Détails par date
|
|
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)
|
|
|
|
fmt.Printf("📅 Détails du %s : %d enregistrements\n", s.Date.Format("2006-01-02"), len(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)
|
|
fmt.Printf("👥 Nombre de clients trouvés : %d\n", len(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)
|
|
}
|
|
}
|
|
|