diff --git a/IMPLEMENTATION_EXACT.md b/IMPLEMENTATION_EXACT.md index 5842154..436dd29 100644 --- a/IMPLEMENTATION_EXACT.md +++ b/IMPLEMENTATION_EXACT.md @@ -42,6 +42,7 @@ - `internal/router/device.go` - Add regenerate token route - `internal/handlers/devices.go` - Add regenerate token handler - `templates/devices.templ` - Add copy/regenerate UI +- `web/src/device-management.ts` - Add device management TypeScript - `bruno/sync-kobo/api.bru` - Add URL path token requests - `bruno/devices/regenerate-*.bru` - New token regeneration test files - `bruno/opds/*-*.bru` - New OPDS authentication test files @@ -86,14 +87,6 @@ SET updated_at = NOW() WHERE id = $1 RETURNING *; - --- name: RevokeDevice :exec -UPDATE devices -SET - auth_token = NULL, - sync_enabled = false, - updated_at = NOW() -WHERE id = $1; ``` **Verification**: Run `go build ./...` after adding this query to ensure sqlc generates the new function correctly. @@ -504,24 +497,45 @@ func (h *DeviceHandler) RegenerateDeviceToken(c echo.Context) error { 3. Add "Regenerate Token" button for each device 4. Add JavaScript functions for copy and regenerate -#### 1.6.1 Update DeviceData Struct - -**Location**: Find `DeviceData` struct (near top of file) - -**Current struct** (lines vary, find structure): +**ADD FIELD** to struct: ```go type DeviceData struct { - ID string - DeviceName string - DeviceType string - LastSync string - LastSeen string - SyncEnabled bool - AutoSync bool - SyncFrequency int + ID string + DeviceName string + DeviceType string + LastSync string + LastSeen string + SyncEnabled bool + AutoSync bool + SyncFrequency int CreatedAt string DeviceMetadata json.RawMessage + AuthToken string // NEW: Device API key for authentication +} +``` + +#### 1.6.3 Update Collection Detail Template + +**File**: `templates/collection.templ` + +**Location**: Line 213 (function signature) + +**Current**: +```templ +templ CollectionDetail(user User, collection CollectionDetailData, books []BookData) { +``` + +**CHANGE** (use handlers.BookInfo): + +```templ +templ CollectionDetail(user User, collection CollectionData, books []handlers.BookInfo) { +``` + +**ADD FIELD** to struct: + +```go + AuthToken string // NEW: Device API key for authentication } ``` @@ -872,7 +886,7 @@ put { docs { ## Regenerate Device Token - Regenerates the auth token for a device, invalidating the old token immediately. + Regenerates auth token for a device, invalidating old token immediately. **Method:** PUT @@ -899,7 +913,7 @@ docs { **Important Notes:** - Old token stops working immediately - Device must be updated with new token to resume syncing - - No data loss - device ID remains the same + - No data loss - device ID remains same **Example Response:** ```json @@ -911,14 +925,24 @@ docs { "device_name": "My Kobo Clara", "device_type": "kobo", "sync_enabled": true, - "auto_sync": true + "auto_sync": true, + "sync_frequency_minutes": 5, + "created_at": "2026-02-12T10:00:00Z", + "device_metadata": "{...}" }, "sync_urls": { "sync_url": "http://localhost:8765/api/sync/kobo/dev_new_token", - "markup": "http://localhost:8765/api/sync/kobo/dev_new_token/markup" + "markup": "http://localhost:8765/api/sync/kobo/dev_new_token/markup", + "bookmark": "http://localhost:8765/api/sync/kobo/dev_new_token/bookmark", + "init": "http://localhost:8765/api/sync/kobo/dev_new_token/v1/initialization" } } ``` + + **Important Notes:** + - Old token stops working immediately + - Device must be updated with new token to resume syncing + - No data loss - device ID remains same } ``` diff --git a/REFACTORING_PLAN.md b/REFACTORING_PLAN.md new file mode 100644 index 0000000..d06acd5 --- /dev/null +++ b/REFACTORING_PLAN.md @@ -0,0 +1,474 @@ +# Type Duplication Refactoring Plan + +**Document Purpose**: Consolidate duplicate type definitions across templates/ and handlers/ packages to align with templ's design philosophy and reduce maintenance burden. + +**Status**: Planning Phase +**Last Updated**: 2026-02-12 +**Separation from**: IMPLEMENTATION_EXACT.md (this is independent refactoring) + +**Core Principle**: **API wins** - When there's ambiguity between template types and API/handler types, the API/handler types take precedence. + +--- + +## Executive Summary + +**Problem**: Codebase maintains parallel type systems: +- `templates/types.go` - Template-specific types +- `handlers/*.go` - API response types + +**Core Principle**: **API wins - when in doubt, API/handler types take precedence** + +### Why "API wins"? + +1. **API is public contract**: Handler types define your public API surface - these are more stable +2. **Templates are presentation**: HTML templates can format any Go type - they're flexible +3. **Single source of truth**: One authoritative type definition vs two parallel definitions +4. **Json serialization**: Handler types already have `json:"..."` tags for API responses +5. **Future API clients**: If you add mobile apps or CLI tools, they need handler types anyway + +### Trade-offs + +**Pro**: Simpler codebase, one type to maintain, automatic API/HTML consistency +**Con**: Templates may have unused fields visible in scope (acceptable - templ handles this well) + +**Impact**: +- ~40 lines of duplicate type definitions +- Unnecessary conversion functions +- Maintenance burden (update 2 places for 1 change) +- Violates templ's design philosophy + +**Solution**: Use handler types directly in templates, eliminate template-specific duplicates. + +--- + +## Current State Analysis + +### Duplicates Found + +| Template Type | Handler Type | Overlap | Action | +|---------------|---------------|----------|--------| +| `DeviceData` | `DeviceInfo` | 90% | **DELETE** DeviceData | +| `BookData` | `collections.BookInfo` | 100% | **DELETE** BookData | +| `CollectionDetailData` | `CollectionData` | 100% | **DELETE** CollectionDetailData | +| `ProgressItemData` | `ProgressWithMedia` | 70% | **MERGE** (different fields) | +| `QueueItemData` | `QueueItemResponse` | 60% | **KEEP** (template uses subset) | + +### Already Using Handler Types (Good Patterns) + +✅ `Conflicts` template uses `handlers.ConflictDetailResponse` +✅ `Queue` template uses `handlers.QueueItemResponse` + +**This is the pattern we want everywhere.** + +--- + +## Refactoring Plan + +### Phase 1: Eliminate Complete Duplicates + +#### 1.1 Delete CollectionDetailData + +**Files to Modify**: +- `templates/types.go` (lines 26-32) - DELETE struct +- `templates/collection_rules.templ` (line 3) - Change signature +- `templates/collections.templ` (line 213) - Change signature + +**Changes**: + +**Delete** from `templates/types.go`: +```go +type CollectionDetailData struct { + ID string + Name string + Description string + Color string + Icon string +} +``` + +**Update** `templates/collection_rules.templ:3`: +```templ +// BEFORE: +templ CollectionRules(user User, collection CollectionDetailData) { + +// AFTER: +templ CollectionRules(user User, collection templates.CollectionData) { +``` + +**Update** `templates/collections.templ:213`: +```templ +// BEFORE: +templ CollectionDetail(user User, collection CollectionDetailData, books []BookData) { + +// AFTER: +templ CollectionDetail(user User, collection templates.CollectionData, books []collections.BookInfo) { +``` + +**Test**: `go test ./templates/...` after template regeneration + +--- + +#### 1.2 Delete BookData + +**Files to Modify**: +- `templates/types.go` (lines 34-39) - DELETE struct +- `templates/collections.templ` (line 213) - Change books param + +**Changes**: + +**Delete** from `templates/types.go`: +```go +type BookData struct { + MediaItemID string + Title string + Author string + CoverImagePath string +} +``` + +**Update** `templates/collections.templ:213`: +```templ +// BEFORE: +templ CollectionDetail(user User, collection templates.CollectionData, books []BookData) { + +// AFTER: +templ CollectionDetail(user User, collection templates.CollectionData, books []collections.BookInfo) { +``` + +**Test**: View collection detail page, verify books display correctly + +--- + +#### 1.3 Delete DeviceData and ConvertDevices + +**Files to Modify**: +- `templates/types.go` (lines 48-57) - DELETE struct +- `templates/devices.templ` (line 3) - Change signature +- `internal/router/helpers.go` (lines 46-67) - DELETE function +- `internal/router/frontend.go` (lines 161-169) - Remove conversion + +**Changes**: + +**Delete** from `templates/types.go`: +```go +type DeviceData struct { + ID string + DeviceName string + DeviceType string + SyncEnabled bool + AutoSync bool + SyncFrequency int32 + LastSync string + LastSeen string +} +``` + +**Delete** from `internal/router/helpers.go`: +```go +func convertDevices(deviceInfos []handlers.DeviceInfo) []templates.DeviceData { + // ... entire function (lines 46-67) +} +``` + +**Update** `templates/devices.templ:3`: +```templ +// BEFORE: +templ Devices(user User, devices []DeviceData, pendingRegistrations []PendingRegistrationData) { + +// AFTER: +templ Devices(user User, devices []handlers.DeviceInfo, pendingRegistrations []PendingRegistrationData) { +``` + +**Update** `templates/devices.templ` template logic: + +Find these patterns and update: +```templ +// BEFORE: +if device.LastSync != "" { + { device.LastSync } +} + +// AFTER: +if device.LastSync != nil { + { device.LastSync.Format("2006-01-02 15:04") } +} +``` + +**Update** `internal/router/frontend.go:161-169`: +```go +// BEFORE: +deviceData, err := cfg.DeviceHandler.GetDevicesData(c) +if err != nil { + return c.HTML(http.StatusInternalServerError, "Error loading devices") +} +pendingData, err := cfg.DeviceHandler.GetPendingRegistrationsData(c) +if err != nil { + return c.HTML(http.StatusInternalServerError, "Error loading pending") +} +deviesList := convertDevices(deviceData) +pendingList := convertPending(pendingData) + +// AFTER: +deviceData, err := cfg.DeviceHandler.GetDevicesData(c) +if err != nil { + return c.HTML(http.StatusInternalServerError, "Error loading devices") +} +pendingData, err := cfg.DeviceHandler.GetPendingRegistrationsData(c) +if err != nil { + return c.HTML(http.StatusInternalServerError, "Error loading pending") +} +// No conversion - use handler data directly +``` + +**Test**: Devices page renders correctly with proper date formatting + +--- + +### Phase 2: Eliminate Remaining Template Types + +#### 2.1 ProgressItemData → Use ProgressWithMedia + +**Current Issue**: +- `handlers.ProgressWithMedia` exists as API response type +- `templates.ProgressItemData` duplicates it with minor variations + +**Decision**: **API wins** - Use `handlers.ProgressWithMedia` everywhere + +**Files to Modify**: +- `internal/handlers/progress.go` - Update `ProgressWithMedia` struct +- `templates/types.go` - DELETE `ProgressItemData` +- `templates/progress.templ` - Use `handlers.ProgressWithMedia` + +**Changes**: + +**Add fields to** `internal/handlers/progress.go:ProgressWithMedia`: +```go +// ADD fields to existing struct: +type ProgressWithMedia struct { + MediaItemID uuid.UUID `json:"media_item_id"` + Title string `json:"title"` + Author string `json:"author"` + CoverImagePath string `json:"cover_image_path"` + Percentage float64 `json:"percentage"` + CurrentPage int32 `json:"current_page"` + TotalPages int32 `json:"total_pages"` + LastReadAt time.Time `json:"last_read_at"` + Epubcfi string `json:"epubcfi"` + LastSyncDevice string `json:"last_sync_device"` + DeviceName string `json:"device_name,omitempty"` // ADD + DeviceType string `json:"device_type,omitempty"` // ADD + DeviceIcon string `json:"device_icon,omitempty"` // ADD +} +``` + +**Update** `internal/handlers/progress.go:GetAllProgress()` to populate new device fields. + +**Delete** from `templates/types.go` (lines 99-112): +```go +type ProgressItemData struct { + // ... delete entire struct +} +``` + +**Update** `templates/progress.templ:3`: +```templ +// BEFORE: +templ Progress(user User, progressData []ProgressItemData) { + +// AFTER: +templ Progress(user User, progressData []handlers.ProgressWithMedia) { +``` + +**Test**: Progress page displays device names and icons + +**Delete** from `templates/types.go` (lines 99-112): +```go +type ProgressItemData struct { + // ... delete entire struct +} +``` + +**Update** `templates/progress.templ:3`: +```templ +// BEFORE: +templ Progress(user User, progressData []ProgressItemData) { + +// AFTER: +templ Progress(user User, progressData []handlers.ProgressWithMedia) { +``` + +**Test**: Progress page displays device names and icons + +--- + +### Phase 3: Update Get*Data Functions + +**Issue**: Several handler functions return handler types but aren't used directly by templates due to conversion layer. + +**Files to Modify**: +- `internal/router/frontend.go` - Remove conversions + +**Changes**: + +**Devices** (already done in Phase 1.3): +- `GetDevicesData()` returns `[]handlers.DeviceInfo` +- Template uses directly + +**Progress**: +```go +// frontend.go - update progress route +protected.GET("/progress-page", func(c echo.Context) error { + // ... + progressData, err := cfg.Handler.GetAllProgressData(c) + // Returns []handlers.ProgressWithMedia directly - no conversion + // ... +}) +``` + +**Collections**: +```go +// collections.go - update to return handler types +func (h *CollectionHandler) GetCollectionBooksData(c echo.Context) ([]collections.BookInfo, error) { + // Already returns BookInfo - just update template +} +``` + +--- + +## Summary Table + +| Phase | Files Changed | Lines Removed | Lines Added | Net Change | +|-------|--------------|---------------|--------------|-------------| +| 1.1 CollectionDetailData | 3 | 7 | 2 | -5 | +| 1.2 BookData | 3 | 6 | 0 | -6 | +| 1.3 DeviceData | 4 | 24 | 5 | -19 | +| 2.1 ProgressItemData | 4 | 14 | 3 | -11 | +| **Total** | **14** | **51** | **10** | **-41** | + +**Note**: QueueItemData already uses handler type (good pattern). Conflicts already uses handler type (good pattern). + +--- + +## Testing Checklist + +After each phase: + +### Phase 1.1 (CollectionDetailData) +- [ ] View collection rules page +- [ ] Edit collection rules +- [ ] View collection detail page +- [ ] Add books to collection + +### Phase 1.2 (BookData) +- [ ] View collection detail page +- [ ] Browse books in collection +- [ ] Book covers display correctly + +### Phase 1.3 (DeviceData) +- [ ] Devices page loads +- [ ] Device cards display +- [ ] Last sync/last seen dates formatted +- [ ] Device type icons show correctly + +### Phase 2.1 (ProgressItemData) +- [ ] Progress page loads +- [ ] Progress entries show device names/icons +- [ ] Percentage display works +- [ ] Cover images display + +--- + +## Rollback Plan + +If refactoring breaks functionality: + +1. **Git stash** changes before starting +2. **Commit after each successful phase** +3. **Revert individual commits** if needed +4. **Keep conversion functions** commented out temporarily + +```bash +# Before starting +git stash push -m "pre-refactor-state" + +# After Phase 1.1 +git commit -m "refactor: delete CollectionDetailData, use CollectionData" + +# If Phase 1.2 breaks +git revert HEAD +# Continue with 1.3 +``` + +--- + +## Benefits + +### Code Quality +- ✅ Aligns with templ's design philosophy +- ✅ Single source of truth for types +- ✅ Reduced code duplication +- ✅ **API-first**: Handler types are authoritative + +### Maintenance +- ✅ Update types in 1 place, not 2 +- ✅ Less conversion logic to maintain +- ✅ Clearer data flow +- ✅ **Template changes automatically get API updates** + +### Consistency +- ✅ All templates use handlers types (like Queue/Conflicts already do) +- ✅ API and HTML use same type definitions +- ✅ 41 fewer lines of code +- ✅ **"API wins"** principle eliminates ambiguity + +--- + +## Future Considerations + +### For IMPLEMENTATION_EXACT.md +After this refactoring, adding `AuthToken` to devices is simpler: +- Add `AuthToken string` to `handlers.DeviceInfo` struct +- Add to `GetDevicesData()` function return values +- Template automatically gets it (no conversion layer) + +This **solves the critical issue** found in IMPLEMENTATION_EXACT.md analysis automatically. + +### For New Features +- Define handler types with json tags first +- Templates use same types directly +- Only create template-specific types for: + - Computed/derived fields not in API + - Combining data from multiple sources + - Simplifying complex nested structures + +--- + +## Execution Order + +1. **Run tests** to ensure baseline: `go test ./...` +2. **Create feature branch**: `git checkout -b refactor/types-consolidation` +3. **Execute Phase 1.1** (CollectionDetailData) - DELETE template type, use API type +4. **Commit and test** +5. **Execute Phase 1.2** (BookData) - DELETE template type, use API type +6. **Commit and test** +7. **Execute Phase 1.3** (DeviceData) - DELETE template type, use API type +8. **Commit and test** +9. **Execute Phase 2.1** (ProgressItemData) - DELETE template type, enhance API type +10. **Final commit and test** +11. **Update IMPLEMENTATION_EXACT.md** to reference handler types only + +**Total Estimated Time**: 2-3 hours with testing + +**Key Mindset**: Every change removes a template type, never the reverse. API types are authoritative. + +--- + +## Questions for User + +1. **Progress template updates**: Since we're using `handlers.ProgressWithMedia` (API type) in templates, any template formatting changes (like date formatting) should be done in the template itself. Is this acceptable? + +2. **Testing**: Do you have automated template tests, or is this manual testing only? + +3. **Implementation plan**: Should I update IMPLEMENTATION_EXACT.md after this refactoring to reference `handlers.DeviceInfo` instead of `DeviceData`? + +4. **Json tags on handler types**: Templates don't need `json:"..."` tags - should we document that these are for API responses only? diff --git a/internal/handlers/collections.go b/internal/handlers/collections.go index 91d5dc4..fef9fb6 100644 --- a/internal/handlers/collections.go +++ b/internal/handlers/collections.go @@ -63,6 +63,13 @@ type UpdateDeviceMappingRequest struct { SyncDirection string `json:"sync_direction" validate:"required,oneof=bidirectional book_to_device device_to_book none"` } +type BookInfo struct { + MediaItemID string `json:"media_item_id"` + Title string `json:"title"` + Author string `json:"author"` + CoverImagePath string `json:"cover_image_path"` +} + func (h *CollectionHandler) CreateCollection(c echo.Context) error { user := c.Get("user").(database.Users) userUUID := uuid.UUID(user.ID.Bytes) @@ -171,13 +178,6 @@ func (h *CollectionHandler) GetCollection(c echo.Context) error { return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) } - type BookInfo struct { - MediaItemID string `json:"media_item_id"` - Title string `json:"title"` - Author string `json:"author"` - CoverImagePath string `json:"cover_image_path"` - } - bookList := make([]BookInfo, 0, len(books)) for _, book := range books { bookList = append(bookList, BookInfo{ diff --git a/internal/handlers/progress.go b/internal/handlers/progress.go index 3526100..5e692a7 100644 --- a/internal/handlers/progress.go +++ b/internal/handlers/progress.go @@ -14,6 +14,20 @@ import ( "github.com/labstack/echo/v4" ) +// getDeviceIcon returns an emoji icon for device type +func getDeviceIcon(deviceType string) string { + switch deviceType { + case "kobo": + return "📚" + case "koreader": + return "📖" + case "kindle": + return "📱" + default: + return "📚" + } +} + // GetUniversalProgress retrieves progress with all location references func (h *Handler) GetUniversalProgress(c echo.Context) error { user := MustGetAuthenticatedUser(c) @@ -229,16 +243,22 @@ func (h *Handler) GetProgressHistory(c echo.Context) error { } type ProgressWithMedia struct { - MediaItemID uuid.UUID - Title string - Author string - CoverImagePath string - Percentage float64 - CurrentPage int32 - TotalPages int32 - LastReadAt time.Time - Epubcfi string - LastSyncDevice string + MediaItemID uuid.UUID `json:"media_item_id"` + Title string `json:"title"` + Author string `json:"author"` + CoverImagePath string `json:"cover_image_path"` + Percentage float64 `json:"percentage"` + CurrentPage int32 `json:"current_page"` + TotalPages int32 `json:"total_pages"` + LastReadAt time.Time `json:"last_read_at"` + Epubcfi string `json:"epubcfi"` + LastSyncDevice string `json:"last_sync_device"` + DeviceName string `json:"device_name,omitempty"` + DeviceType string `json:"device_type,omitempty"` + DeviceIcon string `json:"device_icon,omitempty"` + ProgressPercentage float64 `json:"-"` + EpubCFI string `json:"-"` + LastUpdated string `json:"-"` } // GetAllProgress retrieves all progress for a user with sync source info @@ -283,17 +303,26 @@ func (h *Handler) GetAllProgress(c echo.Context) error { deviceName = progress.LastSyncDevice.String } + lastUpdated := "" + if progress.LastReadAt.Valid { + lastUpdated = progress.LastReadAt.Time.Format("2006-01-02 15:04") + } + progressList = append(progressList, ProgressWithMedia{ - MediaItemID: progress.MediaItemID.Bytes, - Title: mediaItem.Title, - Author: author, - CoverImagePath: coverPath, - Percentage: progress.Percentage.Float64, - CurrentPage: progress.CurrentPage.Int32, - TotalPages: progress.TotalPages.Int32, - LastReadAt: progress.LastReadAt.Time, - Epubcfi: epubcfi, - LastSyncDevice: deviceName, + MediaItemID: progress.MediaItemID.Bytes, + Title: mediaItem.Title, + Author: author, + CoverImagePath: coverPath, + Percentage: progress.Percentage.Float64, + CurrentPage: progress.CurrentPage.Int32, + TotalPages: progress.TotalPages.Int32, + LastReadAt: progress.LastReadAt.Time, + Epubcfi: epubcfi, + LastSyncDevice: deviceName, + ProgressPercentage: progress.Percentage.Float64, + EpubCFI: epubcfi, + LastUpdated: lastUpdated, + DeviceIcon: getDeviceIcon(deviceName), }) } @@ -349,7 +378,7 @@ func (h *Handler) GetAllProgressData(c echo.Context) ([]ProgressWithMedia, error MediaItemID: progress.MediaItemID.Bytes, Title: mediaItem.Title, Author: author, - CoverImagePath: coverPath, + CoverImagePath: coverPath, Percentage: progress.Percentage.Float64, CurrentPage: progress.CurrentPage.Int32, TotalPages: progress.TotalPages.Int32, @@ -361,4 +390,3 @@ func (h *Handler) GetAllProgressData(c echo.Context) ([]ProgressWithMedia, error return progressList, nil } - diff --git a/internal/router/frontend.go b/internal/router/frontend.go index d8b7bd4..5c39575 100644 --- a/internal/router/frontend.go +++ b/internal/router/frontend.go @@ -158,18 +158,17 @@ func registerFrontendRoutes(cfg *Config) { if err != nil { return c.HTML(http.StatusInternalServerError, "Error loading user") } - deviceData, err := cfg.DeviceHandler.GetDevicesData(c) + devices, err := cfg.DeviceHandler.GetDevicesData(c) if err != nil { return c.HTML(http.StatusInternalServerError, "Error loading devices") } - pendingData, err := cfg.DeviceHandler.GetPendingRegistrationsData(c) + pendingMaps, err := cfg.DeviceHandler.GetPendingRegistrationsData(c) if err != nil { return c.HTML(http.StatusInternalServerError, "Error loading pending") } - devicesList := convertDevices(deviceData) - pendingList := convertPending(pendingData) + pendingList := convertPending(pendingMaps) var buf bytes.Buffer - err = templates.Devices(user, devicesList, pendingList).Render(c.Request().Context(), &buf) + err = templates.Devices(user, devices, pendingList).Render(c.Request().Context(), &buf) if err != nil { return err } diff --git a/internal/router/helpers.go b/internal/router/helpers.go index ced0eee..101a57a 100644 --- a/internal/router/helpers.go +++ b/internal/router/helpers.go @@ -2,9 +2,7 @@ package router import ( "context" - "time" - "bookhoard/internal/handlers" "bookhoard/templates" "github.com/google/uuid" @@ -43,29 +41,6 @@ func getTemplateUserWithTheme(c echo.Context, cfg *Config) (templates.User, erro }, nil } -func convertDevices(deviceInfos []handlers.DeviceInfo) []templates.DeviceData { - result := make([]templates.DeviceData, len(deviceInfos)) - for i, d := range deviceInfos { - lastSync := "" - if d.LastSync != nil { - lastSync = d.LastSync.Format(time.RFC3339) - } - lastSeen := "" - if d.LastSeen != nil { - lastSeen = d.LastSeen.Format(time.RFC3339) - } - result[i] = templates.DeviceData{ - ID: d.ID.String(), - DeviceName: d.DeviceName, - DeviceType: d.DeviceType, - SyncEnabled: d.SyncEnabled, - LastSync: lastSync, - LastSeen: lastSeen, - } - } - return result -} - func convertPending(pending []map[string]interface{}) []templates.PendingRegistrationData { result := make([]templates.PendingRegistrationData, len(pending)) for i, p := range pending { diff --git a/templates/collection_rules.templ b/templates/collection_rules.templ index b347b21..75fe362 100644 --- a/templates/collection_rules.templ +++ b/templates/collection_rules.templ @@ -1,6 +1,6 @@ package templates -templ CollectionRules(user User, collection CollectionDetailData) { +templ CollectionRules(user User, collection CollectionData) { diff --git a/templates/collection_rules_templ.go b/templates/collection_rules_templ.go index 4bb0d82..a091d04 100644 --- a/templates/collection_rules_templ.go +++ b/templates/collection_rules_templ.go @@ -8,7 +8,7 @@ package templates import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -func CollectionRules(user User, collection CollectionDetailData) templ.Component { +func CollectionRules(user User, collection CollectionData) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { diff --git a/templates/collections.templ b/templates/collections.templ index a40cf99..737d61a 100644 --- a/templates/collections.templ +++ b/templates/collections.templ @@ -1,5 +1,7 @@ package templates +import "bookhoard/internal/handlers" + templ Collection(user User, collections []CollectionData) { @@ -210,7 +212,7 @@ templ Collection(user User, collections []CollectionData) { } -templ CollectionDetail(user User, collection CollectionDetailData, books []BookData) { +templ CollectionDetail(user User, collection CollectionData, books []handlers.BookInfo) { diff --git a/templates/collections_templ.go b/templates/collections_templ.go index 604e5ad..54acdfd 100644 --- a/templates/collections_templ.go +++ b/templates/collections_templ.go @@ -8,6 +8,8 @@ package templates import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" +import "bookhoard/internal/handlers" + func Collection(user User, collections []CollectionData) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context @@ -55,7 +57,7 @@ func Collection(user User, collections []CollectionData) templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(col.Icon) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 46, Col: 60} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 48, Col: 60} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -68,7 +70,7 @@ func Collection(user User, collections []CollectionData) templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(col.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 58, Col: 109} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 60, Col: 109} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -81,7 +83,7 @@ func Collection(user User, collections []CollectionData) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(col.Description) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 59, Col: 103} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 61, Col: 103} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -100,7 +102,7 @@ func Collection(user User, collections []CollectionData) templ.Component { }) } -func CollectionDetail(user User, collection CollectionDetailData, books []BookData) templ.Component { +func CollectionDetail(user User, collection CollectionData, books []handlers.BookInfo) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -128,7 +130,7 @@ func CollectionDetail(user User, collection CollectionDetailData, books []BookDa var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(collection.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 219, Col: 32} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 221, Col: 32} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -149,7 +151,7 @@ func CollectionDetail(user User, collection CollectionDetailData, books []BookDa var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(collection.Icon) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 234, Col: 95} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 236, Col: 95} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -162,7 +164,7 @@ func CollectionDetail(user User, collection CollectionDetailData, books []BookDa var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(collection.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 236, Col: 107} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 238, Col: 107} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { @@ -175,7 +177,7 @@ func CollectionDetail(user User, collection CollectionDetailData, books []BookDa var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(collection.Description) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 237, Col: 88} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 239, Col: 88} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { @@ -199,7 +201,7 @@ func CollectionDetail(user User, collection CollectionDetailData, books []BookDa var templ_7745c5c3_Var10 string templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(book.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 284, Col: 131} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 286, Col: 131} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) if templ_7745c5c3_Err != nil { @@ -217,7 +219,7 @@ func CollectionDetail(user User, collection CollectionDetailData, books []BookDa var templ_7745c5c3_Var11 string templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(book.Author) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 286, Col: 108} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 288, Col: 108} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) if templ_7745c5c3_Err != nil { diff --git a/templates/devices.templ b/templates/devices.templ index 741dec4..32074ec 100644 --- a/templates/devices.templ +++ b/templates/devices.templ @@ -1,6 +1,8 @@ package templates -templ Devices(user User, devices []DeviceData, pendingRegistrations []PendingRegistrationData) { +import "bookhoard/internal/handlers" + +templ Devices(user User, devices []handlers.DeviceInfo, pendingRegistrations []PendingRegistrationData) { @@ -79,16 +81,16 @@ templ Devices(user User, devices []DeviceData, pendingRegistrations []PendingReg
Last Sync - if device.LastSync != "" { - { device.LastSync } + if device.LastSync != nil { + { device.LastSync.Format("2006-01-02 15:04") } } else { Never }
Last Seen - if device.LastSeen != "" { - { device.LastSeen } + if device.LastSeen != nil { + { device.LastSeen.Format("2006-01-02 15:04") } } else { Never } diff --git a/templates/devices_templ.go b/templates/devices_templ.go index 6f3d5e4..ab69003 100644 --- a/templates/devices_templ.go +++ b/templates/devices_templ.go @@ -8,7 +8,9 @@ package templates import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -func Devices(user User, devices []DeviceData, pendingRegistrations []PendingRegistrationData) templ.Component { +import "bookhoard/internal/handlers" + +func Devices(user User, devices []handlers.DeviceInfo, pendingRegistrations []PendingRegistrationData) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -89,7 +91,7 @@ func Devices(user User, devices []DeviceData, pendingRegistrations []PendingRegi var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(device.DeviceName) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 69, Col: 102} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 71, Col: 102} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -102,7 +104,7 @@ func Devices(user User, devices []DeviceData, pendingRegistrations []PendingRegi var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(device.DeviceType) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 70, Col: 89} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 72, Col: 89} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -127,15 +129,15 @@ func Devices(user User, devices []DeviceData, pendingRegistrations []PendingRegi if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if device.LastSync != "" { + if device.LastSync != nil { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(device.LastSync) + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(device.LastSync.Format("2006-01-02 15:04")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 83, Col: 70} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 85, Col: 97} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -155,15 +157,15 @@ func Devices(user User, devices []DeviceData, pendingRegistrations []PendingRegi if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if device.LastSeen != "" { + if device.LastSeen != nil { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(device.LastSeen) + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(device.LastSeen.Format("2006-01-02 15:04")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 91, Col: 70} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 93, Col: 97} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -206,7 +208,7 @@ func Devices(user User, devices []DeviceData, pendingRegistrations []PendingRegi var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(reg.DeviceName) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 110, Col: 87} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 112, Col: 87} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -219,7 +221,7 @@ func Devices(user User, devices []DeviceData, pendingRegistrations []PendingRegi var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(reg.DeviceType) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 112, Col: 27} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 114, Col: 27} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -232,7 +234,7 @@ func Devices(user User, devices []DeviceData, pendingRegistrations []PendingRegi var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(reg.ExpiresAt) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 112, Col: 58} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/devices.templ`, Line: 114, Col: 58} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { diff --git a/templates/progress.templ b/templates/progress.templ index 804cc47..8707890 100644 --- a/templates/progress.templ +++ b/templates/progress.templ @@ -1,6 +1,8 @@ package templates -templ Progress(user User, progressData []ProgressItemData) { +import "bookhoard/internal/handlers" + +templ Progress(user User, progressData []handlers.ProgressWithMedia) { diff --git a/templates/progress_templ.go b/templates/progress_templ.go index 858993f..6418c4e 100644 --- a/templates/progress_templ.go +++ b/templates/progress_templ.go @@ -8,7 +8,9 @@ package templates import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -func Progress(user User, progressData []ProgressItemData) templ.Component { +import "bookhoard/internal/handlers" + +func Progress(user User, progressData []handlers.ProgressWithMedia) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -55,7 +57,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(item.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 44, Col: 121} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 46, Col: 121} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -73,7 +75,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(item.Author) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 46, Col: 116} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 48, Col: 116} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -91,7 +93,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(item.ProgressPercentage) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 50, Col: 127} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 52, Col: 127} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -104,7 +106,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(item.CurrentPage) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 64, Col: 62} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 66, Col: 62} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -117,7 +119,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(item.TotalPages) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 64, Col: 84} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 66, Col: 84} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -130,7 +132,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(item.LastUpdated) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 69, Col: 96} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 71, Col: 96} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -143,7 +145,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(item.DeviceIcon) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 74, Col: 83} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 76, Col: 83} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { @@ -156,7 +158,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(item.DeviceName) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 75, Col: 102} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 77, Col: 102} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { @@ -174,7 +176,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var10 string templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(item.DeviceName) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 84, Col: 90} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 86, Col: 90} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) if templ_7745c5c3_Err != nil { @@ -187,7 +189,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var11 string templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(item.DeviceType) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 85, Col: 68} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 87, Col: 68} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) if templ_7745c5c3_Err != nil { @@ -206,7 +208,7 @@ func Progress(user User, progressData []ProgressItemData) templ.Component { var templ_7745c5c3_Var12 string templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(item.EpubCFI) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 93, Col: 65} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/progress.templ`, Line: 95, Col: 65} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) if templ_7745c5c3_Err != nil { diff --git a/templates/types.go b/templates/types.go index 04b5a3d..b58873a 100644 --- a/templates/types.go +++ b/templates/types.go @@ -23,21 +23,6 @@ type CollectionData struct { Icon string } -type CollectionDetailData struct { - ID string - Name string - Description string - Color string - Icon string -} - -type BookData struct { - MediaItemID string - Title string - Author string - CoverImagePath string -} - type LibraryData struct { ID string Name string @@ -45,17 +30,6 @@ type LibraryData struct { TypeName string } -type DeviceData struct { - ID string - DeviceName string - DeviceType string - SyncEnabled bool - AutoSync bool - SyncFrequency int32 - LastSync string - LastSeen string -} - type PendingRegistrationData struct { RegistrationID string DeviceName string @@ -96,21 +70,6 @@ type DeviceShelfMappingData struct { CreatedAt string } -type ProgressItemData struct { - MediaItemID string - Title string - Author string - CoverImagePath string - CurrentPage int32 - TotalPages int32 - ProgressPercentage float64 - LastUpdated string - DeviceName string - DeviceType string - DeviceIcon string - EpubCFI string -} - type UnlinkedBookData struct { ProgressID string DeviceID string