From 73b67ab61d1c2190af333a5e21de768a95871e82 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 15 Apr 2026 16:35:08 +0200 Subject: [PATCH] Add reinstate feature for deleted files - Add MarkNotDeleted method to repository - Add ReinstateFile method to service - Add AdminReinstate handler - Add /reinstate/:id route - Add Reinstate button in admin menu for deleted files --- internal/file/handlers.go | 17 +++++++++++++++++ internal/file/repository.go | 6 ++++++ internal/file/routes.go | 1 + internal/file/service.go | 23 +++++++++++++++++++++++ templates/admin.html | 4 ++++ 5 files changed, 51 insertions(+) diff --git a/internal/file/handlers.go b/internal/file/handlers.go index d615cb9..854f035 100644 --- a/internal/file/handlers.go +++ b/internal/file/handlers.go @@ -213,6 +213,23 @@ func (h *Handler) AdminForceDelete(c *gin.Context) { c.Redirect(301, "/admin") } +func (h *Handler) AdminReinstate(c *gin.Context) { + id := c.Param("id") + + _, err := h.service.GetFileByID(id) + if err != nil { + c.JSON(http.StatusNotFound, gin.H{"error": "file not found"}) + return + } + + if _, err := h.service.ReinstateFile(id); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.Redirect(301, "/admin") +} + func (h *Handler) Import(c *gin.Context) { var records []ImportFileRecord diff --git a/internal/file/repository.go b/internal/file/repository.go index 7d66f42..a5adce6 100644 --- a/internal/file/repository.go +++ b/internal/file/repository.go @@ -95,6 +95,12 @@ func (r *Repository) MarkDeleted(f *FileRecord) error { return r.db.Save(f).Error } +// MarkNotDeleted Restore a deleted record by setting Deleted to false +func (r *Repository) MarkNotDeleted(f *FileRecord) error { + f.Deleted = false + return r.db.Save(f).Error +} + // Delete Permanently delete the record from the database func (r *Repository) Delete(f *FileRecord) error { return r.db.Delete(f).Error diff --git a/internal/file/routes.go b/internal/file/routes.go index 188035a..0a70722 100644 --- a/internal/file/routes.go +++ b/internal/file/routes.go @@ -33,6 +33,7 @@ func RegisterRoutes(r *gin.RouterGroup, h *Handler) { adminRoutes.GET("/delete/:id", h.AdminDelete) adminRoutes.GET("/delete/fr/:id", h.AdminForceDelete) + adminRoutes.GET("/reinstate/:id", h.AdminReinstate) adminRoutes.POST("/import", h.Import) adminRoutes.GET("/export", h.Export) diff --git a/internal/file/service.go b/internal/file/service.go index 4a88f1c..aaa89e5 100644 --- a/internal/file/service.go +++ b/internal/file/service.go @@ -134,6 +134,29 @@ func (s *Service) ForceDelete(id string) (*FileRecord, error) { return f, nil } +func (s *Service) ReinstateFile(id string) (*FileRecord, error) { + f, err := s.repo.GetByID(id) + if err != nil { + return nil, err + } + + if !f.Deleted { + return nil, ErrFileNotFound // or just return f, nil maybe? + } + + // Check if file actually exists on disk + path := s.storageDir + "/" + f.ID + if _, err := os.Stat(path); os.IsNotExist(err) { + return nil, ErrFileNotFound + } + + if err := s.repo.MarkNotDeleted(f); err != nil { + return nil, err + } + + return f, nil +} + func (s *Service) GetPaginatedFiles(limit, offset int) ([]FileRecord, int, error) { return s.repo.GetPaginated(limit, offset) } diff --git a/templates/admin.html b/templates/admin.html index 2e6f6d3..e67e0c9 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -183,6 +183,10 @@
+ {{else}} +
+ +
{{end}}