Add UI sync status indicator with pending badge
- Create htmx-powered partial template for sync status display - Show Online/Offline indicator with color coding (green/red) - Display pending changes count badge when there are unsynced items - Add Sync button to push pending changes (appears only when needed) - Auto-refresh every 30 seconds via htmx polling - Replace JavaScript-based sync indicator with server-rendered partial - Integrate SyncStatusPartial handler with template rendering Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -16,15 +18,24 @@ type SyncHandler struct {
|
||||
localDB *localdb.LocalDB
|
||||
syncService *sync.Service
|
||||
mariaDB *gorm.DB
|
||||
tmpl *template.Template
|
||||
}
|
||||
|
||||
// NewSyncHandler creates a new sync handler
|
||||
func NewSyncHandler(localDB *localdb.LocalDB, syncService *sync.Service, mariaDB *gorm.DB) *SyncHandler {
|
||||
func NewSyncHandler(localDB *localdb.LocalDB, syncService *sync.Service, mariaDB *gorm.DB, templatesPath string) (*SyncHandler, error) {
|
||||
// Load sync_status partial template
|
||||
partialPath := filepath.Join(templatesPath, "partials", "sync_status.html")
|
||||
tmpl, err := template.ParseFiles(partialPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SyncHandler{
|
||||
localDB: localDB,
|
||||
syncService: syncService,
|
||||
mariaDB: mariaDB,
|
||||
}
|
||||
tmpl: tmpl,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SyncStatusResponse represents the sync status
|
||||
@@ -270,3 +281,24 @@ func (h *SyncHandler) GetPendingChanges(c *gin.Context) {
|
||||
"changes": changes,
|
||||
})
|
||||
}
|
||||
|
||||
// SyncStatusPartial renders the sync status partial for htmx
|
||||
// GET /partials/sync-status
|
||||
func (h *SyncHandler) SyncStatusPartial(c *gin.Context) {
|
||||
// Check online status
|
||||
isOffline, _ := c.Get("is_offline")
|
||||
|
||||
// Get pending count
|
||||
pendingCount := h.localDB.GetPendingCount()
|
||||
|
||||
data := gin.H{
|
||||
"IsOffline": isOffline.(bool),
|
||||
"PendingCount": pendingCount,
|
||||
}
|
||||
|
||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||
if err := h.tmpl.ExecuteTemplate(c.Writer, "sync_status", data); err != nil {
|
||||
slog.Error("failed to render sync_status template", "error", err)
|
||||
c.String(http.StatusInternalServerError, "Template error")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user