Skip to content

Commit fa02ed6

Browse files
track update admin initial
1 parent 0a857e3 commit fa02ed6

File tree

4 files changed

+155
-12
lines changed

4 files changed

+155
-12
lines changed

internal/admin/handlers.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package admin
22

33
import (
4+
"bytes"
45
"fmt"
56
"io"
67
"log"
@@ -12,6 +13,7 @@ import (
1213

1314
"millions-of-words/fetch"
1415
loader "millions-of-words/loaders/supabase"
16+
"millions-of-words/models"
1517

1618
"github.com/labstack/echo/v4"
1719
)
@@ -376,6 +378,104 @@ func (h *Handler) AlbumEditFormHandler(c echo.Context) error {
376378
}, c)
377379
}
378380

381+
func (h *Handler) AlbumEditPostHandler(c echo.Context) error {
382+
if err := validateAuth(c); err != nil {
383+
return err
384+
}
385+
albumID := c.Param("id")
386+
387+
releaseDate := c.FormValue("release_date")
388+
genre := c.FormValue("genre")
389+
country := c.FormValue("country")
390+
label := c.FormValue("label")
391+
notes := c.FormValue("notes")
392+
393+
albumReq := models.UpdateAlbumRequest{
394+
AlbumID: albumID,
395+
ReleaseDate: releaseDate,
396+
Genre: genre,
397+
Country: country,
398+
Label: label,
399+
Notes: notes,
400+
}
401+
402+
if err := loader.UpdateAlbum(albumReq); err != nil {
403+
log.Printf("Error updating album: %v", err)
404+
return c.HTML(http.StatusOK, `<div class="text-red-500">Error: Failed to update album</div>`)
405+
}
406+
407+
album, err := loader.GetAlbumByID(albumID)
408+
if err == nil {
409+
for _, track := range album.Tracks {
410+
lyricsField := "lyrics_" + strconv.Itoa(track.TrackNumber)
411+
lyrics := c.FormValue(lyricsField)
412+
if lyrics != track.Lyrics {
413+
trackReq := models.UpdateTrackRequest{
414+
AlbumID: albumID,
415+
TrackName: track.Name,
416+
TrackNumber: track.TrackNumber,
417+
Lyrics: lyrics,
418+
}
419+
if err := loader.UpdateTrack(trackReq); err != nil {
420+
log.Printf("Error updating track %d: %v", track.TrackNumber, err)
421+
}
422+
}
423+
}
424+
}
425+
426+
return c.Redirect(http.StatusSeeOther, "/admin/content/album-edit/"+albumID)
427+
}
428+
429+
func (h *Handler) TrackEditPostHandler(c echo.Context) error {
430+
if err := validateAuth(c); err != nil {
431+
return err
432+
}
433+
albumID := c.Param("album_id")
434+
trackNumberStr := c.Param("track_number")
435+
trackNumber, err := strconv.Atoi(trackNumberStr)
436+
if err != nil {
437+
return c.HTML(http.StatusBadRequest, "Invalid track number")
438+
}
439+
440+
trackName := c.FormValue("track_name")
441+
lyrics := c.FormValue("lyrics")
442+
443+
trackReq := models.UpdateTrackRequest{
444+
AlbumID: albumID,
445+
TrackName: trackName,
446+
TrackNumber: trackNumber,
447+
Lyrics: lyrics,
448+
}
449+
if err := loader.UpdateTrack(trackReq); err != nil {
450+
log.Printf("Error updating track %d: %v", trackNumber, err)
451+
return c.HTML(http.StatusOK, `<div class=\"text-red-500\">Error: Failed to update track</div>`)
452+
}
453+
454+
album, err := loader.GetAlbumByID(albumID)
455+
if err != nil {
456+
return c.HTML(http.StatusOK, `<div class=\"text-red-500\">Error: Failed to reload album</div>`)
457+
}
458+
var updatedTrack models.BandcampTrackData
459+
for _, t := range album.Tracks {
460+
if t.TrackNumber == trackNumber {
461+
updatedTrack = t
462+
break
463+
}
464+
}
465+
466+
var buf bytes.Buffer
467+
err = h.templates.Render(&buf, "components/track-card", map[string]interface{}{
468+
"Track": updatedTrack,
469+
"AlbumID": albumID,
470+
}, c)
471+
if err != nil {
472+
log.Printf("Error rendering track card template: %v", err)
473+
return c.HTML(http.StatusInternalServerError, `<div class="text-red-500">Error: Failed to render track card</div>`)
474+
}
475+
476+
return c.HTML(http.StatusOK, buf.String())
477+
}
478+
379479
func validateAuth(c echo.Context) error {
380480
cookie, err := c.Cookie("session")
381481
if err != nil {

internal/admin/routes.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ func SetupRoutes(e *echo.Echo, h *Handler) {
1717
admin.GET("/logout", h.LogoutHandler)
1818
admin.GET("/content/albums", h.AlbumListHandler)
1919
admin.GET("/content/album-edit/:id", h.AlbumEditFormHandler)
20+
admin.POST("/content/album-edit/:id", h.AlbumEditPostHandler)
21+
admin.POST("/content/track-edit/:album_id/:track_number", h.TrackEditPostHandler)
2022
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{{define "components/track-card"}}
2+
<div id="track-card-{{.Track.TrackNumber}}" class="bg-gray-800 rounded-lg p-4 shadow">
3+
<form hx-post="/admin/content/track-edit/{{.AlbumID}}/{{.Track.TrackNumber}}"
4+
hx-target="#track-card-{{.Track.TrackNumber}}"
5+
hx-swap="outerHTML"
6+
class="space-y-3">
7+
<div class="flex flex-col md:flex-row md:items-center md:gap-6 mb-2">
8+
<div class="flex-1">
9+
<label class="block text-sm font-medium mb-1">Track Name</label>
10+
<input type="text"
11+
name="track_name"
12+
value="{{.Track.Name}}"
13+
class="w-full p-2 rounded bg-gray-900 text-gray-200 border border-gray-600 focus:border-blue-500 font-semibold text-lg"
14+
required />
15+
<div class="text-gray-400 text-sm mt-1">Length: {{.Track.FormattedLength}}</div>
16+
</div>
17+
</div>
18+
<div>
19+
<label class="block text-sm font-medium mb-1">Lyrics</label>
20+
<textarea name="lyrics"
21+
rows="5"
22+
class="w-full p-2 rounded bg-gray-900 text-gray-200 border border-gray-600 focus:border-blue-500 resize-y">{{.Track.Lyrics}}</textarea>
23+
</div>
24+
<div class="flex justify-end">
25+
<button type="submit"
26+
class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">Save Track</button>
27+
</div>
28+
</form>
29+
</div>
30+
{{end}}

templates/admin/pages/album-edit.html

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ <h1 class="text-2xl font-bold">Edit Album</h1>
1616
<form
1717
method="POST"
1818
action="/admin/content/album-edit/{{ .Album.ID }}"
19-
class="space-y-6 bg-gray-800 p-6 rounded-lg shadow-lg"
19+
class="space-y-6 bg-gray-800 p-6 rounded-lg shadow-lg mb-10"
2020
>
2121
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
2222
<div>
@@ -50,24 +50,35 @@ <h1 class="text-2xl font-bold">Edit Album</h1>
5050
</div>
5151
<div class="flex justify-end gap-2">
5252
<a href="/admin/content/albums" class="px-4 py-2 bg-gray-700 text-gray-300 rounded hover:bg-gray-600">Cancel</a>
53-
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">Save Album</button>
53+
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">Save Album Info</button>
5454
</div>
5555
</form>
5656
<div class="mt-10">
5757
<h2 class="text-xl font-semibold mb-4">Tracks</h2>
5858
<div class="space-y-6">
5959
{{ range .Album.Tracks }}
60-
<div class="bg-gray-800 rounded-lg p-4 shadow">
61-
<div class="flex flex-col md:flex-row md:items-center md:gap-6 mb-2">
62-
<div class="flex-1">
63-
<div class="font-semibold text-lg">{{ .TrackNumber }}. {{ .Name }}</div>
64-
<div class="text-gray-400 text-sm">Length: {{ .FormattedLength }}</div>
60+
<div id="track-card-{{ .TrackNumber }}" class="bg-gray-800 rounded-lg p-4 shadow">
61+
<form
62+
hx-post="/admin/content/track-edit/{{ $.Album.ID }}/{{ .TrackNumber }}"
63+
hx-target="#track-card-{{ .TrackNumber }}"
64+
hx-swap="outerHTML"
65+
class="space-y-3"
66+
>
67+
<div class="flex flex-col md:flex-row md:items-center md:gap-6 mb-2">
68+
<div class="flex-1">
69+
<label class="block text-sm font-medium mb-1">Track Name</label>
70+
<input type="text" name="track_name" value="{{ .Name }}" class="w-full p-2 rounded bg-gray-900 text-gray-200 border border-gray-600 focus:border-blue-500 font-semibold text-lg" required />
71+
<div class="text-gray-400 text-sm mt-1">Length: {{ .FormattedLength }}</div>
72+
</div>
6573
</div>
66-
</div>
67-
<div>
68-
<label class="block text-sm font-medium mb-1">Lyrics</label>
69-
<textarea name="lyrics_{{ .TrackNumber }}" rows="3" class="w-full p-2 rounded bg-gray-900 text-gray-200 border border-gray-600 focus:border-blue-500">{{ .Lyrics }}</textarea>
70-
</div>
74+
<div>
75+
<label class="block text-sm font-medium mb-1">Lyrics</label>
76+
<textarea name="lyrics" rows="5" class="w-full p-2 rounded bg-gray-900 text-gray-200 border border-gray-600 focus:border-blue-500 resize-y">{{ .Lyrics }}</textarea>
77+
</div>
78+
<div class="flex justify-end">
79+
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">Save Track</button>
80+
</div>
81+
</form>
7182
</div>
7283
{{ end }}
7384
</div>

0 commit comments

Comments
 (0)