feat: MediaPicker — sürükle-bırak + progress bar + kütüphane modal
Mevcut sorun: - Her görsel için medya sayfasına git, yükle, URL kopyala, forma yapıştır → 4 adım - Sürükle-bırak yok, progress yok, hangi dosyanın yüklendiği belirsiz Çözüm: MediaPicker component (tek/çoklu mode) API route'ları: - POST /api/admin/media/upload — session auth + Appwrite Storage upload - GET /api/admin/media/list — kütüphane modal için dosya listesi Component özellikleri: - Sürükle-bırak drop zone (hover state ile) - Multiple file upload (çoklu mode) - XHR ile gerçek progress bar (%) — Server Action ile alınamazdı - Görsel preview (single: aspect-video, multiple: aspect-square grid) - Hover'da × ile kaldırma - Multiple mode'da sırasını değiştirme - 'Kütüphaneden seç' modal — daha önce yüklenmiş görselleri grid'de göster, tıklayınca seç - Error handling (dosya boyutu, ağ hatası vb.) - Başarılı yüklemeyi 2 saniye gösterip kaybetme Form alanları → MediaPicker (URL field'ları kaldırıldı): - Blog: cover_image, seo_image - Hizmet: hero_image - Proje: image_url (kapak), gallery (çoklu) - Referans: image_url - Sektör: hero_image - Ekip: photo_url - SEO sayfa: og_image - SEO global: default_og_image - Site Settings: client_logos (çoklu) Backward compat: form data formatı aynı kalıyor — hidden input ile URL satır satır. admin-actions değişmedi. URL elle yapıştırmak hala mümkün (kütüphaneden URL kopyala).
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import {
|
||||
ID,
|
||||
MEDIA_BUCKET_ID,
|
||||
storage,
|
||||
} from "@/lib/appwrite-rest";
|
||||
import { requireSessionSecret } from "@/lib/auth";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const secret = await requireSessionSecret();
|
||||
const formData = await req.formData();
|
||||
const file = formData.get("file");
|
||||
if (!(file instanceof File) || file.size === 0) {
|
||||
return NextResponse.json({ error: "Dosya seçilmedi" }, { status: 400 });
|
||||
}
|
||||
try {
|
||||
const created = await storage.createFile(
|
||||
MEDIA_BUCKET_ID,
|
||||
ID.unique(),
|
||||
file,
|
||||
secret,
|
||||
);
|
||||
return NextResponse.json({
|
||||
id: created.$id,
|
||||
name: created.name,
|
||||
size: created.sizeOriginal,
|
||||
mimeType: created.mimeType,
|
||||
url: storage.fileViewUrl(MEDIA_BUCKET_ID, created.$id),
|
||||
});
|
||||
} catch (err) {
|
||||
const msg = err instanceof Error ? err.message : "Yükleme başarısız";
|
||||
return NextResponse.json({ error: msg }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user