Files
dashfront/src/components/article/ArticlePhotoTile.jsx
2026-07-31 20:10:23 +02:00

83 lines
2.1 KiB
JavaScript

import { useRef, useState } from 'react';
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
import { article } from '../../api';
import { PanelTile } from '../panels';
import { requireObject } from '../../utils/apiShape';
import { prepareArticlePhoto } from '../../utils/prepareArticlePhoto';
import { pasteImageOrFallback } from '../../utils/pasteImage';
import { primaryPhoto } from '../../utils/articleDetail';
import ArticlePhoto from './ArticlePhoto';
export default function ArticlePhotoTile({
article: articleData,
onArticleUpdated,
wide = 1,
minHeight = 0,
sx,
tileKey,
}) {
const fileInputRef = useRef(null);
const [busy, setBusy] = useState(false);
const photo = primaryPhoto(articleData);
const imageUrl = photo?.url;
const uploadRawImage = async (rawBlob) => {
setBusy(true);
try {
const file = await prepareArticlePhoto(rawBlob);
const res = await article.uploadPhoto(articleData.sku, file);
requireObject(res, 'POST /api/article/:sku/photos');
requireObject(res.article, 'article');
onArticleUpdated?.(res.article);
} finally {
setBusy(false);
}
};
const handlePasteClick = () => {
if (busy) return;
void pasteImageOrFallback(() => {
fileInputRef.current?.click();
}).then((image) => {
if (image) void uploadRawImage(image);
});
};
const handleFileChange = (event) => {
const file = event.target.files?.[0];
event.target.value = '';
if (!file) return;
void uploadRawImage(file);
};
return (
<>
<PanelTile
wide={wide}
minHeight={minHeight}
sx={sx}
tileKey={tileKey}
action={
imageUrl
? undefined
: {
label: 'Bild einfügen',
icon: ContentPasteIcon,
onClick: handlePasteClick,
busy,
}
}
>
<ArticlePhoto imageUrl={imageUrl} />
</PanelTile>
<input
ref={fileInputRef}
type="file"
accept="image/*"
hidden
onChange={handleFileChange}
/>
</>
);
}