UNPKG

firebase-admin-panel

Version:

A customizable React admin panel for managing Firebase collections.

214 lines (213 loc) 8.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _creatable = _interopRequireDefault(require("react-select/creatable")); var _useFirestore = require("../hooks/useFirestore"); var _useStorage = require("../hooks/useStorage"); var _firestore = require("firebase/firestore"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const DocumentForm = _ref => { let { collectionName, docToEdit, onSave, schema, formClassName = "", inputClassName = "", labelClassName = "", buttonClassName = "" } = _ref; const [formData, setFormData] = (0, _react.useState)({}); const [file, setFile] = (0, _react.useState)(null); const [docRefOptions, setDocRefOptions] = (0, _react.useState)({}); const [errors, setErrors] = (0, _react.useState)({}); (0, _react.useEffect)(() => { if (docToEdit) { const initialData = { ...docToEdit }; Object.keys(initialData).forEach(key => { if (initialData[key] instanceof _firestore.Timestamp) { initialData[key] = initialData[key].toDate().toISOString().split("T")[0]; } else if (Array.isArray(initialData[key])) { initialData[key] = initialData[key].map(value => ({ label: value, value: value })); } }); setFormData(initialData); } else { const initialData = {}; Object.keys(schema).forEach(key => { initialData[key] = schema[key].type === "array" || schema[key].type === "docRef array" ? [] : ""; }); setFormData(initialData); } }, [docToEdit, schema]); (0, _react.useEffect)(() => { const fetchDocRefOptions = async () => { const options = {}; for (const key in schema) { if (schema[key].type === "docRef" || schema[key].type === "docRef array") { const docs = await (0, _useFirestore.getCollectionDocuments)(schema[key].collection); options[key] = docs.map(doc => ({ label: doc.id, value: doc.id })); } } setDocRefOptions(options); }; fetchDocRefOptions(); }, [schema]); const handleChange = e => { setFormData({ ...formData, [e.target.name]: e.target.value }); }; const handleSelectChange = (selectedOptions, key) => { setFormData({ ...formData, [key]: selectedOptions }); }; const handleFileChange = e => { setFile(e.target.files[0]); }; const validateForm = () => { const newErrors = {}; Object.keys(schema).forEach(key => { if ((!formData[key] || formData[key].length === 0) && schema[key] !== "image") { newErrors[key] = "This field is required"; } else if (schema[key] === "image" && !file && !(docToEdit !== null && docToEdit !== void 0 && docToEdit[key])) { newErrors[key] = "This field is required"; } }); if (Object.keys(newErrors).length > 0) { setErrors(newErrors); return false; } return true; }; function getKeyByValue(object, value) { let result = []; for (let prop in object) { if (object.hasOwnProperty(prop)) { if (object[prop] === value) result.push(prop); } } return result; } const handleSubmit = async e => { e.preventDefault(); if (!validateForm()) { return; } let tempDataToSave = { ...formData }; let dataToSave = tempDataToSave; let arrayTypes = getKeyByValue(schema, "array"); arrayTypes.forEach(arrayType => { if (tempDataToSave && arrayType && tempDataToSave[arrayType] && tempDataToSave[arrayType].length > 0) { var _tempDataToSave$array; (_tempDataToSave$array = tempDataToSave[arrayType]) === null || _tempDataToSave$array === void 0 || _tempDataToSave$array.forEach((e, index) => { dataToSave[arrayType][index] = e.value; }); } }); if (file) { const imageUrl = await (0, _useStorage.uploadImage)(file, "".concat(collectionName, "/").concat(file.name)); dataToSave[getKeyByValue(schema, "image")] = imageUrl; } Object.keys(dataToSave).forEach(key => { if (schema[key] && schema[key] === "date" && dataToSave[key]) { dataToSave[key] = _firestore.Timestamp.fromDate(new Date(dataToSave[key])); } else if (schema[key] && schema[key] === "array" || schema[key] && schema[key].type === "docRef array") { dataToSave[key] = dataToSave[key].map(option => { if (schema[key].type === "docRef array") return option.value; return option; }); } else if (schema[key] && schema[key] === "number") { dataToSave[key] = parseFloat(dataToSave[key]); } }); if (docToEdit) { await (0, _useFirestore.updateDocument)(collectionName, docToEdit.id, dataToSave); } else { await (0, _useFirestore.addDocument)(collectionName, dataToSave); } onSave(); }; const getInputType = type => { switch (type) { case "string": return "text"; case "number": return "number"; case "date": return "date"; case "image": return "file"; case "docRef": case "docRef array": return "select"; default: return "text"; } }; return /*#__PURE__*/_react.default.createElement("form", { onSubmit: handleSubmit, className: "mt-4 p-4 border border-gray-300 bg-white ".concat(formClassName) }, Object.keys(schema).map(key => /*#__PURE__*/_react.default.createElement("div", { key: key, className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block font-bold ".concat(labelClassName) }, key), schema[key] === "image" ? /*#__PURE__*/_react.default.createElement("input", { type: "file", name: key, onChange: handleFileChange, className: "w-full p-2 my-2 border border-gray-300 rounded ".concat(inputClassName) }) : schema[key] === "array" || schema[key].type === "docRef array" ? /*#__PURE__*/_react.default.createElement(_creatable.default, { isMulti: true, name: key, value: formData[key], onChange: selectedOptions => handleSelectChange(selectedOptions, key), className: "basic-multi-select", classNamePrefix: "select", formatCreateLabel: inputValue => "Add \"".concat(inputValue, "\""), options: schema[key].type === "docRef array" ? docRefOptions[key] : [] }) : schema[key].type === "docRef" ? /*#__PURE__*/_react.default.createElement("select", { name: key, value: formData[key], onChange: handleChange, className: "w-full p-2 my-2 border border-gray-300 rounded ".concat(inputClassName) }, docRefOptions[key] && docRefOptions[key].map(option => /*#__PURE__*/_react.default.createElement("option", { key: option.value, value: option.value }, option.label))) : /*#__PURE__*/_react.default.createElement("input", { type: getInputType(schema[key]), name: key, value: formData[key], onChange: handleChange, className: "w-full p-2 my-2 border border-gray-300 rounded ".concat(inputClassName) }), errors[key] && /*#__PURE__*/_react.default.createElement("p", { className: "text-red-500" }, errors[key]))), /*#__PURE__*/_react.default.createElement("button", { type: "submit", className: "bg-blue-500 text-white py-2 px-4 rounded text-white border-none cursor-pointer mr-2 ".concat(buttonClassName) }, docToEdit ? "Update" : "Add", " Document"), /*#__PURE__*/_react.default.createElement("button", { type: "button", onClick: onSave, className: "bg-red-500 text-white py-2 px-4 rounded ml-2 text-white border-none cursor-pointer mr-2 ".concat(buttonClassName) }, "Cancel")); }; var _default = exports.default = DocumentForm;