Fixed template function call mismatches: - conflicts.templ: Renamed showConflictModal→showResolveModal, hideConflictModal→hideResolveModal, handleResolveConflict→handleResolveSubmit - collections.templ: Fixed case mismatch addSelectedBooks→addbooksToAdd - queue.templ: Removed dead /static/queue.js reference - progress.templ: Removed vestigial x-data="progress" attribute Added missing queue functions: - showQueueItemModal() - Shows queue item detail modal - hideQueueItemModal() - Hides queue item modal - filterQueue() - Filters queue by status (stubbed) Fixed build errors: - main.ts: Removed imports for deleted themeDropdown.ts and woodPaneling.ts files All fixes are minimal and conservative. No breaking changes to existing functionality. TypeScript builds successfully (168KB main.js). Templates regenerate successfully.
103 lines
3.9 KiB
Templ
103 lines
3.9 KiB
Templ
package templates
|
|
|
|
import "bookhoard/internal/handlers"
|
|
|
|
templ Progress(user User, progressData []handlers.ProgressWithMedia, errorMessage string) {
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
<title>Reading Progress - Bookhoard</title>
|
|
<script src="/static/htmx.min.js"></script>
|
|
<script src="/static/main.js"></script>
|
|
<link href="/static/style.css" rel="stylesheet"/>
|
|
</head>
|
|
<body class="theme-{ user.Theme }">
|
|
@Header(user, "/progress")
|
|
<div class="w-full px-4 sm:px-6 lg:px-8 py-8">
|
|
<div class="mb-8">
|
|
<h1 class="text-3xl font-bold" style="color: var(--text-primary)">Reading Progress</h1>
|
|
<p style="color: var(--text-secondary)">Track your reading progress across all devices</p>
|
|
</div>
|
|
<div id="progress-container" class="space-y-6">
|
|
if len(progressData) == 0 {
|
|
<div class="text-center py-16" style="color: var(--text-secondary)">
|
|
<div class="text-6xl mb-4">📖</div>
|
|
<h3 class="text-xl font-semibold mb-2" style="color: var(--text-primary)">No Progress Yet</h3>
|
|
<p>Start reading a book to track your progress</p>
|
|
</div>
|
|
}
|
|
for _, item := range progressData {
|
|
<div class="card p-6 rounded-lg border" style="background-color: var(--bg-secondary); border-color: var(--border);">
|
|
<div class="flex gap-6">
|
|
<div class="flex-shrink-0">
|
|
<img
|
|
src="{ item.CoverImagePath }"
|
|
alt="Cover"
|
|
class="w-24 h-32 object-cover rounded"
|
|
onerror="this.src='/static/placeholder-book.svg'"
|
|
/>
|
|
</div>
|
|
<div class="flex-1">
|
|
<div class="flex justify-between items-start mb-2">
|
|
<div>
|
|
<h3 class="font-semibold text-lg" style="color: var(--text-primary)">{ item.Title }</h3>
|
|
if item.Author != "" {
|
|
<p class="text-sm" style="color: var(--text-secondary)">by { item.Author }</p>
|
|
}
|
|
</div>
|
|
<div class="text-right">
|
|
<span class="text-2xl font-bold" style="color: var(--accent)">{ item.ProgressPercentage }%</span>
|
|
</div>
|
|
</div>
|
|
<div class="mb-4">
|
|
<div class="w-full bg-gray-700 rounded-full h-3">
|
|
<div class="h-3 rounded-full transition-all" style="width: { item.ProgressPercentage }%; background-color: var(--accent);"></div>
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 text-sm">
|
|
<div>
|
|
<p style="color: var(--text-secondary)">Current Position</p>
|
|
<p style="color: var(--text-primary)">
|
|
{ item.CurrentPage } / { item.TotalPages }
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<p style="color: var(--text-secondary)">Last Updated</p>
|
|
<p style="color: var(--text-primary)">{ item.LastUpdated }</p>
|
|
</div>
|
|
<div>
|
|
<p style="color: var(--text-secondary)">Synced From</p>
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-xl">{ item.DeviceIcon }</span>
|
|
<span style="color: var(--text-primary)">{ item.DeviceName }</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
if item.DeviceIcon != "" {
|
|
<div class="mt-3 pt-3 border-t" style="border-color: var(--border);">
|
|
<div class="flex items-center gap-2 text-xs" style="color: var(--text-secondary);">
|
|
<span>🔄</span>
|
|
<span>Last sync from <strong>{ item.DeviceName }</strong></span>
|
|
<span>({ item.DeviceType })</span>
|
|
</div>
|
|
</div>
|
|
}
|
|
if item.EpubCFI != "" {
|
|
<div class="mt-2 text-xs" style="color: var(--text-secondary);">
|
|
<span>📍</span>
|
|
<span>CFI: { item.EpubCFI }</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
@ErrorToast(errorMessage)
|
|
</body>
|
|
</html>
|
|
}
|