feat(router): add collection modal routes for HTMX
Add three new frontend routes to support HTMX-powered modal dialogs: 1. GET /collections/create-modal - Renders empty collection creation modal - Uses CollectionModal template with empty CollectionData 2. GET /collections/:id/edit-modal - Fetches collection by ID from database - Pre-populates modal with existing collection data - Returns 400 for invalid UUID, 404 if collection not found 3. GET /collections/restore-modal - Renders system collection restoration modal - Allows users to restore deleted system collections Route registration order: - /collections/:id/edit-modal must be registered before /collections/:id to avoid path conflicts in Echo's router These routes enable the collections page to load modals dynamically via HTMX (hx-get) instead of embedding modal HTML in the base page.
This commit is contained in:
@@ -238,6 +238,63 @@ func registerFrontendRoutes(cfg *Config) {
|
|||||||
return c.HTML(http.StatusOK, buf.String())
|
return c.HTML(http.StatusOK, buf.String())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Collection create modal
|
||||||
|
frontendProtected.GET("/collections/create-modal", func(c echo.Context) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := templates.CollectionModal(templates.CollectionData{}).Render(c.Request().Context(), &buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.HTML(http.StatusOK, buf.String())
|
||||||
|
})
|
||||||
|
|
||||||
|
// Collection edit modal
|
||||||
|
frontendProtected.GET("/collections/:id/edit-modal", func(c echo.Context) error {
|
||||||
|
// Parse collection ID
|
||||||
|
collectionID := c.Param("id")
|
||||||
|
collUUID, err := uuid.Parse(collectionID)
|
||||||
|
if err != nil {
|
||||||
|
return c.HTML(http.StatusBadRequest, "<div>Invalid collection ID</div>")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch collection data
|
||||||
|
collection, err := cfg.Queries.GetCollection(c.Request().Context(), pgtype.UUID{Bytes: collUUID, Valid: true})
|
||||||
|
if err != nil {
|
||||||
|
return c.HTML(http.StatusNotFound, "<div>Collection not found</div>")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to template type
|
||||||
|
colData := templates.CollectionData{
|
||||||
|
ID: uuid.UUID(collection.ID.Bytes).String(),
|
||||||
|
Name: collection.Name,
|
||||||
|
Description: getText(collection.Description),
|
||||||
|
Color: getText(collection.Color),
|
||||||
|
Icon: getText(collection.Icon),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure default color if empty
|
||||||
|
if colData.Color == "" {
|
||||||
|
colData.Color = "blue"
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = templates.CollectionModal(colData).Render(c.Request().Context(), &buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.HTML(http.StatusOK, buf.String())
|
||||||
|
})
|
||||||
|
|
||||||
|
// Restore system collection modal
|
||||||
|
frontendProtected.GET("/collections/restore-modal", func(c echo.Context) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := templates.RestoreSystemCollectionModal().Render(c.Request().Context(), &buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.HTML(http.StatusOK, buf.String())
|
||||||
|
})
|
||||||
|
|
||||||
// Collection detail page (works for both system and user collections)
|
// Collection detail page (works for both system and user collections)
|
||||||
frontendProtected.GET("/collections/:id", func(c echo.Context) error {
|
frontendProtected.GET("/collections/:id", func(c echo.Context) error {
|
||||||
user, err := getTemplateUserWithTheme(c, cfg)
|
user, err := getTemplateUserWithTheme(c, cfg)
|
||||||
|
|||||||
Reference in New Issue
Block a user