@asgerami/zemenay-blog
Version:
Plug-and-play blog system for Next.js - Get a fully functional blog running in minutes with zero configuration
77 lines (76 loc) • 4.78 kB
JavaScript
;
'use client';
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImageUpload = ImageUpload;
exports.ImagePreview = ImagePreview;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const imageUpload_1 = require("../lib/imageUpload");
function ImageUpload({ onImageUploaded, onError, className = '', accept = 'image/*', maxSize = 5 }) {
const [uploading, setUploading] = (0, react_1.useState)(false);
const [dragOver, setDragOver] = (0, react_1.useState)(false);
const fileInputRef = (0, react_1.useRef)(null);
const handleFileSelect = async (file) => {
if (!file)
return;
// Validate file size
if (file.size > maxSize * 1024 * 1024) {
const error = `Image must be smaller than ${maxSize}MB`;
onError === null || onError === void 0 ? void 0 : onError(error);
return;
}
setUploading(true);
try {
const result = await (0, imageUpload_1.uploadImage)({
file,
altText: file.name.split('.')[0] // Use filename without extension as default alt text
});
if (result.success && result.image && result.publicUrl) {
onImageUploaded(result.image, result.publicUrl);
}
else {
onError === null || onError === void 0 ? void 0 : onError(result.error || 'Upload failed');
}
}
catch (error) {
onError === null || onError === void 0 ? void 0 : onError(error instanceof Error ? error.message : 'Upload failed');
}
finally {
setUploading(false);
}
};
const handleFileInputChange = (event) => {
var _a;
const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
if (file) {
handleFileSelect(file);
}
};
const handleDrop = (event) => {
event.preventDefault();
setDragOver(false);
const file = event.dataTransfer.files[0];
if (file && file.type.startsWith('image/')) {
handleFileSelect(file);
}
else {
onError === null || onError === void 0 ? void 0 : onError('Please drop an image file');
}
};
const handleDragOver = (event) => {
event.preventDefault();
setDragOver(true);
};
const handleDragLeave = (event) => {
event.preventDefault();
setDragOver(false);
};
const openFileDialog = () => {
var _a;
(_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
};
return ((0, jsx_runtime_1.jsxs)("div", { className: `image-upload ${className}`, children: [(0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", accept: accept, onChange: handleFileInputChange, style: { display: 'none' } }), (0, jsx_runtime_1.jsx)("div", { className: `upload-area ${dragOver ? 'drag-over' : ''} ${uploading ? 'uploading' : ''}`, onDrop: handleDrop, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onClick: openFileDialog, children: uploading ? ((0, jsx_runtime_1.jsxs)("div", { className: "upload-progress", children: [(0, jsx_runtime_1.jsx)("div", { className: "spinner" }), (0, jsx_runtime_1.jsx)("p", { children: "Uploading image..." })] })) : ((0, jsx_runtime_1.jsxs)("div", { className: "upload-prompt", children: [(0, jsx_runtime_1.jsx)("div", { className: "upload-icon", children: "\uD83D\uDCF7" }), (0, jsx_runtime_1.jsxs)("p", { children: [(0, jsx_runtime_1.jsx)("strong", { children: "Click to upload" }), " or drag and drop"] }), (0, jsx_runtime_1.jsxs)("p", { className: "upload-hint", children: ["PNG, JPG, GIF up to ", maxSize, "MB"] })] })) })] }));
}
function ImagePreview({ image, publicUrl, onRemove, onInsert, className = '' }) {
return ((0, jsx_runtime_1.jsxs)("div", { className: `image-preview ${className}`, children: [(0, jsx_runtime_1.jsx)("div", { className: "preview-image", children: (0, jsx_runtime_1.jsx)("img", { src: publicUrl, alt: image.alt_text || image.original_name, loading: "lazy" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "preview-info", children: [(0, jsx_runtime_1.jsx)("p", { className: "image-name", children: image.original_name }), (0, jsx_runtime_1.jsxs)("p", { className: "image-size", children: [(image.file_size / 1024).toFixed(1), " KB"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "preview-actions", children: [onInsert && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onInsert, className: "insert-btn", children: "Insert" })), onRemove && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onRemove, className: "remove-btn", children: "Remove" }))] })] }));
}