fix: remove fallback content, fix video upload and positioning

- Remove hardcoded fallback data — DB is sole content source
- Sections render conditionally when data exists
- Hero video slots save after each upload (not only when all 3 filled)
- Video positions preserved (left/center/right) with empty string slots
- Client-side 10MB hard limit on video uploads with clear error
- Server-side upload error handling for body size limits
- Guard Team section against empty members array
- Clean up old uploaded images and videos
This commit is contained in:
2026-03-29 22:17:11 +03:00
parent 77ad2a6b68
commit e56a6a1608
66 changed files with 75 additions and 66 deletions
+16 -7
View File
@@ -10,10 +10,19 @@ const IMAGE_FOLDERS = ["team", "master-classes", "news", "classes"];
const VIDEO_FOLDERS = ["hero"];
const ALL_FOLDERS = [...IMAGE_FOLDERS, ...VIDEO_FOLDERS];
const IMAGE_MAX_SIZE = 5 * 1024 * 1024; // 5MB
const VIDEO_MAX_SIZE = 50 * 1024 * 1024; // 50MB
const VIDEO_MAX_SIZE = 10 * 1024 * 1024; // 10MB
export async function POST(request: NextRequest) {
const formData = await request.formData();
let formData: FormData;
try {
formData = await request.formData();
} catch (e) {
const msg = e instanceof Error ? e.message : "Upload failed";
return NextResponse.json(
{ error: msg.includes("size") || msg.includes("multipart") ? "Файл слишком большой (макс. 10 МБ)" : `Ошибка загрузки: ${msg}` },
{ status: 413 }
);
}
const file = formData.get("file") as File | null;
const rawFolder = (formData.get("folder") as string) || "team";
const folder = ALL_FOLDERS.includes(rawFolder) ? rawFolder : "team";
@@ -26,16 +35,16 @@ export async function POST(request: NextRequest) {
const allowedTypes = isVideoFolder ? VIDEO_TYPES : IMAGE_TYPES;
if (!allowedTypes.includes(file.type)) {
const msg = isVideoFolder
? "Only MP4 and WebM videos are allowed"
: "Only JPEG, PNG, WebP, and AVIF are allowed";
? "Допустимы только MP4 и WebM"
: "Допустимы только JPEG, PNG, WebP и AVIF";
return NextResponse.json({ error: msg }, { status: 400 });
}
const maxSize = isVideoFolder ? VIDEO_MAX_SIZE : IMAGE_MAX_SIZE;
if (file.size > maxSize) {
const label = isVideoFolder ? "50MB" : "5MB";
const label = isVideoFolder ? "10 МБ" : "5 МБ";
return NextResponse.json(
{ error: `File too large (max ${label})` },
{ error: `Файл слишком большой (макс. ${label})` },
{ status: 400 }
);
}
@@ -45,7 +54,7 @@ export async function POST(request: NextRequest) {
const allowedExts = isVideoFolder ? VIDEO_EXTENSIONS : IMAGE_EXTENSIONS;
if (!allowedExts.includes(ext)) {
return NextResponse.json(
{ error: "Invalid file extension" },
{ error: "Недопустимое расширение файла" },
{ status: 400 }
);
}