package controllers import ( "lost-and-found/internal/repositories" "lost-and-found/internal/services" "lost-and-found/internal/utils" "net/http" "strconv" "github.com/gin-gonic/gin" "gorm.io/gorm" ) type AdminController struct { userService *services.UserService itemRepo *repositories.ItemRepository claimRepo *repositories.ClaimRepository archiveRepo *repositories.ArchiveRepository auditService *services.AuditService } func NewAdminController(db *gorm.DB) *AdminController { return &AdminController{ userService: services.NewUserService(db), itemRepo: repositories.NewItemRepository(db), claimRepo: repositories.NewClaimRepository(db), archiveRepo: repositories.NewArchiveRepository(db), auditService: services.NewAuditService(db), } } // GetDashboardStats gets dashboard statistics (admin/manager) // GET /api/admin/dashboard func (c *AdminController) GetDashboardStats(ctx *gin.Context) { stats := make(map[string]interface{}) // Item statistics totalItems, _ := c.itemRepo.CountByStatus("") unclaimedItems, _ := c.itemRepo.CountByStatus("unclaimed") verifiedItems, _ := c.itemRepo.CountByStatus("verified") expiredItems, _ := c.itemRepo.CountByStatus("expired") stats["items"] = map[string]interface{}{ "total": totalItems, "unclaimed": unclaimedItems, "verified": verifiedItems, "expired": expiredItems, } // Claim statistics totalClaims, _ := c.claimRepo.CountByStatus("") pendingClaims, _ := c.claimRepo.CountByStatus("pending") approvedClaims, _ := c.claimRepo.CountByStatus("approved") rejectedClaims, _ := c.claimRepo.CountByStatus("rejected") stats["claims"] = map[string]interface{}{ "total": totalClaims, "pending": pendingClaims, "approved": approvedClaims, "rejected": rejectedClaims, } // Archive statistics archivedExpired, _ := c.archiveRepo.CountByReason("expired") archivedClosed, _ := c.archiveRepo.CountByReason("case_closed") stats["archives"] = map[string]interface{}{ "total": archivedExpired + archivedClosed, "expired": archivedExpired, "case_closed": archivedClosed, } utils.SuccessResponse(ctx, http.StatusOK, "Dashboard stats retrieved", stats) } // GetAuditLogs gets audit logs (admin only) // GET /api/admin/audit-logs func (c *AdminController) GetAuditLogs(ctx *gin.Context) { page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1")) limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "20")) action := ctx.Query("action") entityType := ctx.Query("entity_type") var userID *uint if userIDStr := ctx.Query("user_id"); userIDStr != "" { id, _ := strconv.ParseUint(userIDStr, 10, 32) userID = new(uint) *userID = uint(id) } logs, total, err := c.auditService.GetAllAuditLogs(page, limit, action, entityType, userID) if err != nil { utils.ErrorResponse(ctx, http.StatusInternalServerError, "Failed to get audit logs", err.Error()) return } utils.SendPaginatedResponse(ctx, http.StatusOK, "Audit logs retrieved", logs, total, page, limit) }