держится контекст о выбранной картинке у Images
Some checks failed
Deploy / CreateImage (push) Failing after 3m49s
Deploy / DeployService (push) Failing after 25s

This commit is contained in:
Nastya 2025-06-20 20:07:46 +03:00
parent 9f32bd9c9d
commit 38bd30ce35
3 changed files with 54 additions and 50 deletions

@ -10,7 +10,8 @@ import UploadIcon from "@/assets/icons/UploadIcon";
import { sendFile } from "@/api/quizRelase";
import { ACCEPT_SEND_FILE_TYPES_MAP, MAX_FILE_SIZE } from "../../tools/fileUpload";
type OwnImageProps = {
// Пропсы компонента
export type OwnImageProps = {
imageUrl?: string;
questionId: string;
variantId: string;
@ -21,24 +22,24 @@ export const OwnImage = ({ imageUrl, questionId, variantId, onValidationError }:
const theme = useTheme();
const { t } = useTranslation();
const { quizId, preview } = useQuizStore();
const { answers, updateAnswer, ownVariants, updateOwnVariant } = useQuizViewStore((state) => state);
const { ownVariants, updateOwnVariant } = useQuizViewStore((state) => state);
const { enqueueSnackbar } = useSnackbar();
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const [isUploading, setIsUploading] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);
// Получаем ownVariant для этого варианта
const ownVariantData = ownVariants.find((v) => v.id === variantId);
// Загрузка файла
const uploadImage = async (file: File) => {
if (isUploading) return;
if (!file) return;
if (file.size > MAX_FILE_SIZE) {
onValidationError("size");
return;
}
const isFileTypeAccepted = ACCEPT_SEND_FILE_TYPES_MAP.picture.some((fileType) =>
file.name.toLowerCase().endsWith(fileType)
);
@ -46,28 +47,16 @@ export const OwnImage = ({ imageUrl, questionId, variantId, onValidationError }:
onValidationError("type");
return;
}
setIsUploading(true);
try {
const data = await sendFile({
questionId,
body: {
file: file,
name: file.name,
preview,
},
body: { file, name: file.name, preview },
qid: quizId,
});
const fileId = data!.data.fileIDMap[questionId];
// Сохраняем fileId в originalImageUrl
updateOwnVariant(variantId, "", "", fileId);
// Для UI — локальный preview
const fileId = data?.data.fileIDMap[questionId];
const localImageUrl = URL.createObjectURL(file);
updateAnswer(questionId, `${file.name}|${localImageUrl}`, 0);
updateOwnVariant(variantId, "", "", fileId, localImageUrl);
setSelectedFile(file);
} catch (error) {
console.error("Error uploading image:", error);
@ -77,6 +66,7 @@ export const OwnImage = ({ imageUrl, questionId, variantId, onValidationError }:
}
};
// Обработчик выбора файла
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
@ -84,24 +74,29 @@ export const OwnImage = ({ imageUrl, questionId, variantId, onValidationError }:
}
};
// Открытие диалога выбора файла
const handleClick = (e: React.MouseEvent) => {
e.stopPropagation();
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
if (fileInputRef.current) fileInputRef.current.value = "";
fileInputRef.current?.click();
};
// Удаление изображения
const handleRemoveImage = (e: React.MouseEvent) => {
e.stopPropagation();
setSelectedFile(null);
updateAnswer(questionId, "", 0);
updateOwnVariant(variantId, "", "", "");
updateOwnVariant(variantId, "", "", "", "");
};
const imageToDisplay = selectedFile
? URL.createObjectURL(selectedFile)
: ownVariantData?.variant.originalImageUrl || imageUrl;
// Определяем, что показывать
let imageToDisplay: string | null = null;
if (selectedFile) {
imageToDisplay = URL.createObjectURL(selectedFile);
} else if (ownVariantData?.variant.localImageUrl) {
imageToDisplay = ownVariantData.variant.localImageUrl;
} else if (imageUrl) {
imageToDisplay = imageUrl;
}
if (isUploading) {
return (
@ -137,7 +132,6 @@ export const OwnImage = ({ imageUrl, questionId, variantId, onValidationError }:
accept={ACCEPT_SEND_FILE_TYPES_MAP.picture.join(",")}
hidden
/>
{imageToDisplay ? (
<>
<Box sx={{ width: "100%", height: "100%", position: "relative" }}>
@ -147,26 +141,24 @@ export const OwnImage = ({ imageUrl, questionId, variantId, onValidationError }:
style={{ width: "100%", height: "100%", objectFit: "cover" }}
/>
</Box>
{(selectedFile || ownVariantData?.variant.originalImageUrl) && (
<IconButton
onClick={handleRemoveImage}
sx={{
position: "absolute",
top: 8,
right: 8,
zIndex: 1,
backgroundColor: "rgba(0, 0, 0, 0.5)",
color: "white",
height: "25px",
width: "25px",
"&:hover": {
backgroundColor: "rgba(0, 0, 0, 0.7)",
},
}}
>
<CloseIcon />
</IconButton>
)}
<IconButton
onClick={handleRemoveImage}
sx={{
position: "absolute",
top: 8,
right: 8,
zIndex: 1,
backgroundColor: "rgba(0, 0, 0, 0.5)",
color: "white",
height: "25px",
width: "25px",
"&:hover": {
backgroundColor: "rgba(0, 0, 0, 0.7)",
},
}}
>
<CloseIcon />
</IconButton>
</>
) : (
<Box

@ -51,6 +51,8 @@ export type QuestionVariant = {
isMulti?: boolean;
/** Оригинал изображения (до кропа) */
originalImageUrl: string;
/** Локальный URL для предпросмотра */
localImageUrl?: string;
points?: number;
};
export interface QuestionVariantWithEditedImages extends QuestionVariant {

@ -30,7 +30,13 @@ interface QuizViewStore {
interface QuizViewActions {
updateAnswer: (questionId: string, answer: string | string[] | Moment, points: number) => void;
deleteAnswer: (questionId: string) => void;
updateOwnVariant: (id: string, answer: string, extendedText?: string, originalImageUrl?: string) => void;
updateOwnVariant: (
id: string,
answer: string,
extendedText?: string,
originalImageUrl?: string,
localImageUrl?: string
) => void;
deleteOwnVariant: (id: string) => void;
setCurrentQuizStep: (step: QuizStep) => void;
}
@ -90,7 +96,7 @@ export const createQuizViewStore = () =>
}
);
},
updateOwnVariant(id, answer, extendedText, originalImageUrl) {
updateOwnVariant(id, answer, extendedText, originalImageUrl, localImageUrl) {
set(
(state) => {
const index = state.ownVariants.findIndex((variant) => variant.id === id);
@ -104,6 +110,7 @@ export const createQuizViewStore = () =>
extendedText: extendedText || "",
hints: "",
originalImageUrl: originalImageUrl || "",
localImageUrl: localImageUrl || "",
},
});
} else {
@ -114,6 +121,9 @@ export const createQuizViewStore = () =>
if (originalImageUrl) {
state.ownVariants[index].variant.originalImageUrl = originalImageUrl;
}
if (localImageUrl) {
state.ownVariants[index].variant.localImageUrl = localImageUrl;
}
}
},
false,