Implement live collection preview system with contextual template selection
Replace isolated template previews with live collection reconstruction:
- Frontend now reconstructs collection container with all template variants
- Users click directly on rendered templates in proper CSS context
- Perfect preservation of grid/flex layouts and responsive behavior
- Simplified API: preview endpoint returns container_html + templates for frontend reconstruction
- Enhanced UX: WYSIWYG template selection shows exactly what will be added
- Removed redundant templates endpoint in favor of unified preview approach
Backend changes:
- Add GET /api/collections/{id}/preview endpoint
- Remove GET /api/collections/{id}/templates endpoint
- Return container HTML + templates for frontend reconstruction
Frontend changes:
- Replace isolated template modal with live collection preview
- Add generateLivePreview() method for container reconstruction
- Update CollectionManager to use preview API
- Add interactive CSS styling for template selection
This provides true contextual template selection where CSS inheritance,
grid layouts, and responsive design work perfectly in preview mode.
This commit is contained in:
@@ -405,8 +405,8 @@ func (h *ContentHandler) GetCollectionItems(w http.ResponseWriter, r *http.Reque
|
||||
json.NewEncoder(w).Encode(items)
|
||||
}
|
||||
|
||||
// GetCollectionTemplates handles GET /api/collections/{id}/templates
|
||||
func (h *ContentHandler) GetCollectionTemplates(w http.ResponseWriter, r *http.Request) {
|
||||
// GetCollectionPreview handles GET /api/collections/{id}/preview
|
||||
func (h *ContentHandler) GetCollectionPreview(w http.ResponseWriter, r *http.Request) {
|
||||
collectionID := chi.URLParam(r, "id")
|
||||
siteID := r.URL.Query().Get("site_id")
|
||||
|
||||
@@ -415,14 +415,24 @@ func (h *ContentHandler) GetCollectionTemplates(w http.ResponseWriter, r *http.R
|
||||
return
|
||||
}
|
||||
|
||||
// Get collection container
|
||||
collection, err := h.repository.GetCollection(context.Background(), siteID, collectionID)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("Collection not found: %v", err), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
// Get all templates for this collection
|
||||
templates, err := h.repository.GetCollectionTemplates(context.Background(), siteID, collectionID)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("Database error: %v", err), http.StatusInternalServerError)
|
||||
http.Error(w, fmt.Sprintf("Templates not found: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response := map[string]interface{}{
|
||||
"templates": templates,
|
||||
"collection_id": collectionID,
|
||||
"container_html": collection.ContainerHTML,
|
||||
"templates": templates,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
@@ -525,10 +535,10 @@ func (h *ContentHandler) RegisterRoutes(r chi.Router) {
|
||||
// COLLECTION MANAGEMENT - Groups of related content
|
||||
// =============================================================================
|
||||
r.Route("/collections", func(r chi.Router) {
|
||||
r.Get("/", h.GetAllCollections) // GET /api/collections?site_id=X
|
||||
r.Get("/{id}", h.GetCollection) // GET /api/collections/{id}?site_id=X
|
||||
r.Get("/{id}/items", h.GetCollectionItems) // GET /api/collections/{id}/items?site_id=X
|
||||
r.Get("/{id}/templates", h.GetCollectionTemplates) // GET /api/collections/{id}/templates?site_id=X
|
||||
r.Get("/", h.GetAllCollections) // GET /api/collections?site_id=X
|
||||
r.Get("/{id}", h.GetCollection) // GET /api/collections/{id}?site_id=X
|
||||
r.Get("/{id}/items", h.GetCollectionItems) // GET /api/collections/{id}/items?site_id=X
|
||||
r.Get("/{id}/preview", h.GetCollectionPreview) // GET /api/collections/{id}/preview?site_id=X
|
||||
|
||||
// Protected routes
|
||||
r.Group(func(r chi.Router) {
|
||||
|
||||
Reference in New Issue
Block a user