Commit Graph

3 Commits

Author SHA1 Message Date
sdarbinyan
30afb5d778 feat(media): reusable media management
Sprint 22.

- MediaAsset gains folder (flat) and MediaListParams gains folder/tag
  filters; MediaRepository.listFolders() derives the folder list from
  existing records
- upload validation: 10MB size cap, mime allow-list (jpeg/png/webp/gif/
  svg+xml/pdf), real error messages surfaced through MediaLibraryFacade
  instead of a generic swallowed string
- SVG uploads are sanitized (script tags and on*= attributes stripped)
  before storage
- raster images (excl. gif) are downscaled to a 2000px max dimension and
  re-encoded via canvas before storage - compression, not a crop UI
- tag editing (window.prompt, comma-separated) via
  MediaLibraryFacade.updateTags()
- MediaPickerComponent wired into Project Editor branding (logo, compact
  logo, favicon) alongside its existing category/product usage - confirmed
  no image fields exist on Static Pages or as a dedicated hero field to
  wire

docs/ADMIN.md updated with the new Sprint 22 section including the storage
abstraction note (MediaRepository was already the abstraction).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 10:42:23 +04:00
sdarbinyan
5ffb353011 feat(media): add Media Manager UI (grid, upload, delete)
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
MediaLibraryPageComponent replaces the coming-soon placeholder at
/backoffice/media. Built entirely on Sprint 6 Design System primitives
(app-card, app-button, app-input, app-empty-state, app-dialog, app-pagination,
app-skeleton) and Sprint 4 Task 2's MediaRepository/MockMediaRepository.

- Grid view with per-tile filename/size and delete action
- Hidden native file input triggered by an app-button, uploads via
  MediaLibraryFacade -> MediaRepository.upload()
- Delete requires confirmation through app-dialog (destructive action)
- Search + pagination wired to MockMediaRepository's list() params
- Loading state shows app-skeleton tiles; empty state shows app-empty-state
- New mediaLibrary.* translation namespace across en/ru/hy

Verified in browser (via a temporary unguarded route, reverted before
commit - /backoffice/media itself requires Telegram QR admin auth not
available in this session): empty state renders correctly with translated
copy, search input and upload button present, no console errors.
2026-07-15 07:14:16 +04:00
sdarbinyan
b957112fc7 phase-1: scaffold platform foundation structure and architecture governance 2026-07-03 01:26:30 +04:00