UNPKG

@defikitdotnet/education-module-ai

Version:
127 lines (126 loc) 9.55 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FileUpload = FileUpload; var jsx_runtime_1 = require("react/jsx-runtime"); var react_1 = require("react"); var lucide_react_1 = require("lucide-react"); var button_1 = require("./button"); function FileUpload(_a) { var _this = this; var onFileUpload = _a.onFileUpload, _b = _a.className, className = _b === void 0 ? "" : _b, _c = _a.accept, accept = _c === void 0 ? "image/*" : _c, _d = _a.maxSize, maxSize = _d === void 0 ? 5 : _d; var _e = (0, react_1.useState)(false), isUploading = _e[0], setIsUploading = _e[1]; var _f = (0, react_1.useState)(0), uploadProgress = _f[0], setUploadProgress = _f[1]; var _g = (0, react_1.useState)(null), error = _g[0], setError = _g[1]; var _h = (0, react_1.useState)(false), isSuccess = _h[0], setIsSuccess = _h[1]; var _j = (0, react_1.useState)(null), filename = _j[0], setFilename = _j[1]; var fileInputRef = (0, react_1.useRef)(null); var handleFileChange = function (e) { return __awaiter(_this, void 0, void 0, function () { var file, formData, xhr_1; var _a; return __generator(this, function (_b) { file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0]; if (!file) return [2 /*return*/]; // Check file size if (file.size > maxSize * 1024 * 1024) { setError("File size exceeds ".concat(maxSize, "MB limit")); return [2 /*return*/]; } setFilename(file.name); setIsUploading(true); setError(null); setIsSuccess(false); try { formData = new FormData(); formData.append("image", file); xhr_1 = new XMLHttpRequest(); // Track upload progress xhr_1.upload.addEventListener("progress", function (event) { if (event.lengthComputable) { var progress = Math.round((event.loaded / event.total) * 100); setUploadProgress(progress); } }); // Handle response xhr_1.onload = function () { if (xhr_1.status >= 200 && xhr_1.status < 300) { var response = JSON.parse(xhr_1.responseText); setIsSuccess(true); onFileUpload(response.url); } else { var errorMessage = void 0; try { var errorResponse = JSON.parse(xhr_1.responseText); errorMessage = errorResponse.error || "Upload failed"; } catch (_a) { errorMessage = "Upload failed"; } setError(errorMessage); } setIsUploading(false); }; // Handle network errors xhr_1.onerror = function () { setError("Network error occurred"); setIsUploading(false); }; xhr_1.open("POST", "".concat(process.env.NEXT_PUBLIC_BACKEND_URL, "/api/uploads/image"), true); xhr_1.send(formData); } catch (err) { console.error("Error uploading file:", err); setError("An unexpected error occurred during upload"); setIsUploading(false); } return [2 /*return*/]; }); }); }; var handleReset = function () { setFilename(null); setError(null); setIsSuccess(false); setUploadProgress(0); if (fileInputRef.current) { fileInputRef.current.value = ""; } }; return ((0, jsx_runtime_1.jsx)("div", { className: "space-y-4 ".concat(className), children: (0, jsx_runtime_1.jsx)("div", { className: "\n relative\n border-2 border-dashed rounded-lg p-4 transition-colors\n ".concat(error ? "border-red-400 bg-red-50" : "", "\n ").concat(isSuccess ? "border-green-400 bg-green-50" : "", "\n ").concat(!error && !isSuccess ? "border-gray-300 hover:border-gray-400 bg-gray-50" : "", "\n "), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center justify-center p-4 text-center", children: [isUploading ? ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-10 w-10 animate-spin text-gray-400 mb-2" }), (0, jsx_runtime_1.jsxs)("p", { className: "text-sm text-gray-500", children: ["Uploading... ", uploadProgress, "%"] }), (0, jsx_runtime_1.jsx)("div", { className: "w-full bg-gray-200 rounded-full h-2.5 mt-2", children: (0, jsx_runtime_1.jsx)("div", { className: "bg-indigo-600 h-2.5 rounded-full", style: { width: "".concat(uploadProgress, "%") } }) })] })) : error ? ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.AlertCircle, { className: "h-10 w-10 text-red-500 mb-2" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-red-600 mb-2", children: error }), (0, jsx_runtime_1.jsx)(button_1.Button, { type: "button", variant: "outline", size: "sm", onClick: handleReset, children: "Try Again" })] })) : isSuccess ? ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.CheckCircle2, { className: "h-10 w-10 text-green-500 mb-2" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-green-600", children: "Successfully uploaded" }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-gray-500 truncate max-w-xs", children: filename }), (0, jsx_runtime_1.jsxs)(button_1.Button, { type: "button", variant: "outline", size: "sm", className: "mt-2", onClick: handleReset, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-4 w-4 mr-1" }), " Remove"] })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Upload, { className: "h-10 w-10 text-gray-400 mb-2" }), (0, jsx_runtime_1.jsxs)("p", { className: "mb-2 text-sm text-gray-500", children: [(0, jsx_runtime_1.jsx)("span", { className: "font-semibold", children: "Click to upload" }), " or drag and drop"] }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-gray-500", children: ["Images only (MAX. ", maxSize, "MB)"] })] })), (0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", className: "absolute inset-0 w-full h-full opacity-0 cursor-pointer ".concat(isUploading || isSuccess ? "hidden" : ""), onChange: handleFileChange, accept: accept, disabled: isUploading })] }) }) })); }