feat: organize uploads by folder + cdn.hotelsync.ru active

- Upload route now accepts ?folder=categories|rooms|hotels|guests
- Files saved to /uploads/{folder}/uuid.ext, served at cdn.hotelsync.ru/{folder}/uuid.ext
- api.upload.photo() accepts optional folder param (default: 'rooms')
- RoomCategoriesPage passes folder='categories' on photo upload
- SSL cert issued and nginx config active for cdn.hotelsync.ru

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-23 12:41:27 +03:00
parent f625d82cc5
commit dd75794a78
3 changed files with 21 additions and 10 deletions

View File

@@ -346,11 +346,11 @@ export const api = {
// ── File Upload ───────────────────────────────────────────────────────────
upload: {
photo: async (file: File): Promise<string> => {
photo: async (file: File, folder: 'categories' | 'rooms' | 'hotels' | 'guests' = 'rooms'): Promise<string> => {
const token = localStorage.getItem('access_token')
const fd = new FormData()
fd.append('file', file)
const res = await fetch(`${BASE}/api/upload`, {
const res = await fetch(`${BASE}/api/upload?folder=${folder}`, {
method: 'POST',
headers: token ? { Authorization: `Bearer ${token}` } : {},
body: fd,

View File

@@ -59,7 +59,7 @@ function CategoryForm({ category, onClose, onSave }: CategoryFormProps) {
if (!list.length) return
setUploading(true)
try {
const urls = await Promise.all(list.map(f => api.upload.photo(f)))
const urls = await Promise.all(list.map(f => api.upload.photo(f, 'categories')))
setPhotos(prev => {
const next = [...prev, ...urls]
setPhotoIdx(next.length - 1)