added many images in post
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import {useCallback, useEffect, useState} from "react";
|
||||
import PinIcon from "./icons/PinIcon";
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import { EMPTY_FORM, CATEGORIES } from "../config/feedConstants";
|
||||
import { usePostMutation } from "../hooks/usePostMutation";
|
||||
@@ -7,7 +6,6 @@ import { useImageUpload, ACCEPT } from "../hooks/useImageUpload";
|
||||
import { validatePostForm } from "../utils/validatePostForm";
|
||||
import { formatPhone } from "../utils/formatPhone";
|
||||
import { useYandexMap } from "../hooks/useYandexMap";
|
||||
import { API_URL } from "../config/authConstants";
|
||||
|
||||
const MAX_SIZE_MB = 5;
|
||||
|
||||
@@ -40,21 +38,16 @@ export default function CreateUpdatePost({ onClose, onSuccess, initialData }) {
|
||||
// Ошибки валидации — ключ совпадает с именем поля
|
||||
const [errors, setErrors] = useState({});
|
||||
|
||||
// URL существующей картинки с сервера (только при редактировании)
|
||||
const existingImageUrl = isEdit && initialData.images?.[0]
|
||||
? `${API_URL}${initialData.images[0]}`
|
||||
: null;
|
||||
|
||||
// Вся логика работы с фото вынесена в хук
|
||||
const {
|
||||
imageFile,
|
||||
displayImage,
|
||||
images: uploadedImages,
|
||||
imgError,
|
||||
compressing,
|
||||
fileInputRef,
|
||||
handleFileChange,
|
||||
removeImage,
|
||||
} = useImageUpload(existingImageUrl);
|
||||
getFilesForUpload,
|
||||
getExistingUrlsToKeep,
|
||||
} = useImageUpload(isEdit ? initialData.images : []);
|
||||
|
||||
// Единый хук для создания и обновления
|
||||
const { save, loading: saving, error: apiError } = usePostMutation();
|
||||
@@ -106,7 +99,15 @@ export default function CreateUpdatePost({ onClose, onSuccess, initialData }) {
|
||||
data.append("category", form.category);
|
||||
data.append("phone", form.phone.trim());
|
||||
if (form.date) data.append("date", form.date);
|
||||
if (imageFile) data.append("image", imageFile);
|
||||
const files = getFilesForUpload();
|
||||
files.forEach(f => data.append("images", f));
|
||||
|
||||
if (isEdit) {
|
||||
const existing = getExistingUrlsToKeep();
|
||||
if (existing.length > 0) {
|
||||
data.append("existingImages", JSON.stringify(existing));
|
||||
}
|
||||
}
|
||||
|
||||
if (coords) {
|
||||
data.append("latitude", coords.latitude);
|
||||
@@ -189,41 +190,50 @@ export default function CreateUpdatePost({ onClose, onSuccess, initialData }) {
|
||||
className="f-err-msg">{errors.description}</p>}
|
||||
</div>
|
||||
|
||||
{/* Фотография: превью + удаление или загрузчик */}
|
||||
{/* Фотографии: сетка превью + кнопка добавления */}
|
||||
<div className="f-m-group">
|
||||
<label className="f-m-label">Фотография</label>
|
||||
{displayImage ? (
|
||||
<div className="f-img-preview-wrap">
|
||||
<img src={displayImage} alt="preview"
|
||||
className="f-img-preview"/>
|
||||
<button
|
||||
className="f-img-remove"
|
||||
onClick={removeImage}
|
||||
type="button"
|
||||
aria-label="Удалить фото"
|
||||
>
|
||||
<CloseIcon/>
|
||||
</button>
|
||||
<label className="f-m-label">Фотографии</label>
|
||||
|
||||
{uploadedImages.length > 0 && (
|
||||
<div className="f-img-grid">
|
||||
{uploadedImages.map(img => (
|
||||
<div key={img.id} className="f-img-grid-item">
|
||||
<img src={img.preview} alt="" className="f-img-grid-preview"/>
|
||||
<button
|
||||
className="f-img-remove"
|
||||
onClick={() => removeImage(img.id)}
|
||||
type="button"
|
||||
aria-label="Удалить фото"
|
||||
>
|
||||
<CloseIcon/>
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<label className="f-img-upload-label"
|
||||
aria-disabled={compressing}>
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
accept={ACCEPT}
|
||||
// На мобильных открываем камеру напрямую
|
||||
capture={/Mobi|Android|iPhone/i.test(navigator.userAgent)
|
||||
? "environment" : undefined}
|
||||
onChange={handleFileChange}
|
||||
className="f-img-input"
|
||||
disabled={compressing}
|
||||
/>
|
||||
{compressing ? <span>Обработка...</span> : <span>📷 Добавить фото</span>}
|
||||
</label>
|
||||
)}
|
||||
|
||||
<label className="f-img-upload-label"
|
||||
aria-disabled={compressing}>
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
accept={ACCEPT}
|
||||
multiple
|
||||
capture={/Mobi|Android|iPhone/i.test(navigator.userAgent)
|
||||
? "environment" : undefined}
|
||||
onChange={handleFileChange}
|
||||
className="f-img-input"
|
||||
disabled={compressing}
|
||||
/>
|
||||
{compressing ? (
|
||||
<span>Обработка...</span>
|
||||
) : (
|
||||
<span>{uploadedImages.length > 0 ? "➕ Добавить ещё" : "📷 Добавить фото"}</span>
|
||||
)}
|
||||
</label>
|
||||
|
||||
{imgError && <p className="f-err-msg">{imgError}</p>}
|
||||
<p className="f-hint">JPEG / PNG / WebP · до {MAX_SIZE_MB} МБ</p>
|
||||
<p className="f-hint">JPEG / PNG / WebP · до {MAX_SIZE_MB} МБ · можно несколько</p>
|
||||
</div>
|
||||
|
||||
{/* Категория */}
|
||||
|
||||
Reference in New Issue
Block a user