UNPKG

@salla.sa/twilight-components

Version:
139 lines (135 loc) 6.32 kB
/*! * Crafted with ❤ by Salla */ import { r as registerInstance, c as createEvent, h } from './index-D4I5TLtE.js'; import { C as CameraIcon } from './camera-C6jIkM-X.js'; import { F as FormFieldTypes } from './interfaces-OF8QcbMM.js'; const sallaCustomFieldsCss = ":host{display:block}"; const SallaCustomFields = class { constructor(hostRef) { registerInstance(this, hostRef); this.fieldChanged = createEvent(this, "fieldChanged"); this.fileUploaded = createEvent(this, "fileUploaded"); /** Whether the fields can be edited by the user. */ this.isEditable = true; this.fieldErrors = {}; this.isSubmitting = false; } get dragAndDropText() { return salla.lang.get("common.uploader.drag_and_drop"); } get browseText() { return salla.lang.get("common.uploader.browse"); } get saveButtonText() { return salla.lang.get("common.elements.save"); } /** Update the displayed fields programmatically. */ async setFields(fields) { this.parsedFields = fields; } /** Gets the current values of all fields, formatted for submission. */ async getFieldValues() { return this.parsedFields?.reduce((values, field) => { values[`custom_fields[${field.id}]`] = field.value; return values; }, {}) || {}; } /** Validates all required fields and updates the error state. Returns true if valid. */ async validateFields() { if (!this.parsedFields) return true; const errors = this.parsedFields.reduce((acc, field) => { if (field.required && (!field.value || field.value === "")) { acc[field.id.toString()] = `${field.label} is required`; } return acc; }, {}); this.fieldErrors = errors; return Object.keys(errors).length === 0; } handleFieldChange(field, event) { const value = event.target.value; field.value = value; this.clearFieldError(field.id); const isValid = !(field.required && !value); if (!isValid) { this.setFieldError(field.id, `${field.label} is required`); } this.fieldChanged.emit({ fieldId: field.id, value, isValid }); } handleFileUpload(field, event) { const { error, file } = event.detail; const isValid = !error; this.clearFieldError(field.id); if (isValid) { field.value = file; } else { this.setFieldError(field.id, "File upload failed"); } this.fileUploaded.emit({ fieldId: field.id, file, isValid }); } clearFieldError(fieldId) { this.fieldErrors = { ...this.fieldErrors }; delete this.fieldErrors[fieldId]; } setFieldError(fieldId, message) { this.fieldErrors = { ...this.fieldErrors, [fieldId]: message }; } renderTextField(field) { return (h("input", { disabled: !this.isEditable, type: field.type, id: `custom-field-${field.id}`, value: field.value?.toString() || "", onChange: (e) => this.handleFieldChange(field, e), name: `${field.id}`, class: "form-input", required: field.required })); } renderFileField(field) { return (h("salla-file-upload", { url: salla.url.api('upload'), id: `custom-field-${field.id}`, name: `${field.id}`, type: "registration", value: field.value, height: "120px", onAdded: (e) => this.handleFileUpload(field, e), required: field.required, disabled: !this.isEditable, onUploaded: e => { e.target.value = e.target.value?.url; }, allowRemove: true, onRemoved: (e) => { e.preventDefault(); e.stopPropagation(); field.value = ""; e.target.value = ""; }, payloadName: "files[]", payloadParams: { type: 'registration' }, "instant-upload": true }, h("div", { class: "s-custom-fields-filepond-placeholder" }, h("span", { class: "s-custom-fields-filepond-placeholder-icon" }, h("i", { innerHTML: CameraIcon })), h("p", { class: "s-custom-fields-filepond-placeholder-text" }, this.dragAndDropText), h("span", { class: "filepond--label-action" }, this.browseText)))); } renderField(field) { return (h("div", { class: "s-custom-fields-field", key: field.id }, h("label", { class: "s-custom-fields-field-label", htmlFor: `custom-field-${field.id}` }, field.label, field.required && h("span", { class: "s-custom-fields-required" }, "*")), h("div", null, field.type === FormFieldTypes.Photo ? this.renderFileField(field) : this.renderTextField(field), this.fieldErrors[field.id] && (h("p", { class: "s-custom-fields-error" }, this.fieldErrors[field.id]))))); } componentWillLoad() { this.parsedFields = this.parseFields(this.fields); } parseFields(fields) { if (!fields) return []; return typeof fields === "string" ? JSON.parse(fields) : Array.isArray(fields) ? fields : []; } async handleSubmit(e) { e.preventDefault(); this.isSubmitting = true; try { const payload = {}; const form = e.target; const elements = form.elements; for (let i = 0; i < elements.length; i++) { const element = elements[i]; if (element.name && !element.name.startsWith("hidden") && element.value) { payload[element.name] = element.value; } } await salla.api.profile.updateCustomFields({ id: salla.config.get("store.id"), fields: payload, }); } finally { this.isSubmitting = false; } } render() { if (!this.parsedFields?.length) return null; return (h("form", { class: "s-custom-fields-wrapper", onSubmit: this.handleSubmit }, this.parsedFields.map(field => this.renderField(field)), h("salla-button", { type: "submit", loading: this.isSubmitting, disabled: this.isSubmitting || !this.isEditable, "loader-position": "end", class: "s-custom-fields-submit-btn" }, this.saveButtonText))); } }; SallaCustomFields.style = sallaCustomFieldsCss; export { SallaCustomFields as salla_custom_fields };