@progress/sitefinity-nextjs-sdk
Version:
Provides OOB widgets developed using the Next.js framework, which includes an abstraction layer for Sitefinity communication. Additionally, it offers an expanded API, typings, and tools for further development and integration.
117 lines (116 loc) • 7.33 kB
JavaScript
'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React from 'react';
import { VisibilityStyle } from '../styling/visibility-style';
import { invalidDataAttr, invalidateElement, serializeForm } from '../common/utils';
import { classNames } from '../../editor/utils/classNames';
import { getUniqueId } from '../../editor/utils/getUniqueId';
export function ResetPasswordFormClient(props) {
const securityQuestionInputId = getUniqueId('sf-security-question-', props.widgetContext.model.Id);
const newPasswordInputId = getUniqueId('sf-new-password-', props.widgetContext.model.Id);
const repeatPasswordInputId = getUniqueId('sf-repeat-password-', props.widgetContext.model.Id);
const formRef = React.useRef(null);
const newPasswordInputRef = React.useRef(null);
const repeatPasswordInputRef = React.useRef(null);
const securityQuestionInputRef = React.useRef(null);
const labels = props.labels;
const visibilityClassHidden = props.visibilityClasses[VisibilityStyle.Hidden];
const [invalidInputs, setInvalidInputs] = React.useState({});
const [showFormContainer, setShowFormContainer] = React.useState(true);
const [showSuccessContainer, setShowSuccessContainer] = React.useState(false);
const [errorMessage, setErrorMessage] = React.useState('');
const handleSubmit = (event) => {
event.preventDefault();
if (!validateForm(formRef.current)) {
return;
}
let model = { model: serializeForm(formRef.current) };
let submitUrl = formRef.current.attributes['action'].value;
window.fetch(submitUrl, {
method: 'POST',
body: JSON.stringify(model),
headers: {
'Content-Type': 'application/json'
}
})
.then((response) => {
let status = response.status;
if (status === 204) {
setShowFormContainer(false);
setShowSuccessContainer(true);
}
else {
let invalidInput;
const emptyInputs = {};
if (status === 400) {
invalidInput = newPasswordInputRef.current;
}
else if (status === 403) {
invalidInput = securityQuestionInputRef.current;
}
invalidateElement(emptyInputs, invalidInput);
setInvalidInputs(emptyInputs);
response.json().then((res) => {
let errorMessage = res.error.message;
setErrorMessage(errorMessage);
});
}
});
};
const validateForm = (form) => {
let isValid = true;
setInvalidInputs({});
setErrorMessage('');
const emptyInputs = {};
const requiredInputs = form.querySelectorAll('input[data-sf-role=\'required\']');
requiredInputs.forEach((input) => {
if (!input.value) {
invalidateElement(emptyInputs, input);
setInvalidInputs(emptyInputs);
isValid = false;
}
});
if (!isValid) {
setErrorMessage(labels.allFieldsAreRequiredErrorMessage);
return isValid;
}
if (newPasswordInputRef.current.value !== repeatPasswordInputRef.current.value) {
invalidateElement(emptyInputs, repeatPasswordInputRef.current);
setInvalidInputs(emptyInputs);
setErrorMessage(labels.passwordsMismatchErrorMessage);
return false;
}
return isValid;
};
const inputValidationAttrs = (name) => {
return {
className: classNames('form-control', {
[props.invalidClass]: invalidInputs[name]
}),
[invalidDataAttr]: invalidInputs[name],
name: name
};
};
const formContainerClass = classNames({
[visibilityClassHidden]: !showFormContainer
});
const formContainerStyle = {
display: !visibilityClassHidden ? showFormContainer ? '' : 'none' : ''
};
const errorMessageClass = classNames('alert alert-danger my-3', {
[visibilityClassHidden]: !errorMessage
});
const errorMessageStyles = {
display: !visibilityClassHidden ? errorMessage ? '' : 'none' : ''
};
const successContainerClass = classNames({
[visibilityClassHidden]: !showSuccessContainer
});
const successContainerStyle = {
display: !visibilityClassHidden ? showSuccessContainer ? '' : 'none' : ''
};
return (_jsxs(_Fragment, { children: [_jsxs("div", { "data-sf-role": "form-container", className: formContainerClass, style: formContainerStyle, children: [_jsx("h2", { className: "mb-3", children: labels.resetPasswordHeader }), _jsx("div", { "data-sf-role": "error-message-container", className: errorMessageClass, style: errorMessageStyles, role: "alert", "aria-live": "assertive", children: errorMessage }), _jsxs("form", { ref: formRef, onSubmit: handleSubmit, method: "post", action: props.resetUserPasswordHandlerPath, role: "form", children: [props.requiresQuestionAndAnswer && props.securityQuestion &&
_jsxs("div", { className: "mb-3", children: [_jsx("label", { htmlFor: securityQuestionInputId, className: "form-label", children: !labels.securityQuestionLabel ? props.securityQuestion : `${labels.securityQuestionLabel} ${props.securityQuestion}` }), _jsx("input", { ref: securityQuestionInputRef, id: securityQuestionInputId, type: "text", "data-sf-role": "required", ...inputValidationAttrs('Answer') })] }), _jsxs("div", { className: "mb-3", children: [_jsx("label", { htmlFor: newPasswordInputId, className: "form-label", children: labels.newPasswordLabel }), _jsx("input", { ref: newPasswordInputRef, id: newPasswordInputId, type: "password", "data-sf-role": "required", ...inputValidationAttrs('NewPassword') })] }), _jsxs("div", { className: "mb-3", children: [_jsx("label", { htmlFor: repeatPasswordInputId, className: "form-label", children: labels.repeatNewPasswordLabel }), _jsx("input", { ref: repeatPasswordInputRef, id: repeatPasswordInputId, type: "password", "data-sf-role": "required", ...inputValidationAttrs('NewPassword') })] }), _jsx("input", { type: "hidden", name: "SecurityToken", value: props.securityToken }), _jsx("input", { type: "hidden", name: "MembershipProviderName", value: props.membershipProviderName || '' }), _jsx("input", { className: "btn btn-primary w-100", type: "submit", value: labels.saveButtonLabel })] }), _jsx("input", { type: "hidden", name: "ErrorMessage", value: labels.errorMessage }), _jsx("input", { type: "hidden", name: "AllFieldsAreRequiredErrorMessage", value: labels.allFieldsAreRequiredErrorMessage }), _jsx("input", { type: "hidden", name: "PasswordsMismatchErrorMessage", value: labels.passwordsMismatchErrorMessage })] }), _jsxs("div", { "data-sf-role": "success-message-container", className: successContainerClass, style: successContainerStyle, children: [_jsx("h2", { children: labels.successMessage }), props.loginPageUrl &&
_jsx("a", { href: props.loginPageUrl, className: "text-decoration-none", children: labels.backLinkLabel })] })] }));
}
;