@bookinglab/booking-ui-react 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -672,6 +672,7 @@ var ContactDetailsForm = forwardRef(
672
672
  questions = [],
673
673
  onSubmit,
674
674
  onChange: _onChange,
675
+ initialValues,
675
676
  validateOnBlur = true,
676
677
  submitLabel = "Submit",
677
678
  className = "",
@@ -679,12 +680,19 @@ var ContactDetailsForm = forwardRef(
679
680
  fieldSettings = {}
680
681
  }, ref) => {
681
682
  const formId = useId();
682
- const [firstName, setFirstName] = useState("");
683
- const [lastName, setLastName] = useState("");
684
- const [emailValue, setEmailValue] = useState("");
683
+ const [firstName, setFirstName] = useState(initialValues?.firstName || "");
684
+ const [lastName, setLastName] = useState(initialValues?.lastName || "");
685
+ const [emailValue, setEmailValue] = useState(initialValues?.email || "");
685
686
  const [contactErrors, setContactErrors] = useState({});
686
687
  const [contactTouched, setContactTouched] = useState({});
687
- const [questionValues, setQuestionValues] = useState({});
688
+ const [questionValues, setQuestionValues] = useState(() => {
689
+ if (!initialValues?.questions) return {};
690
+ const init = {};
691
+ for (const [key, val] of Object.entries(initialValues.questions)) {
692
+ init[Number(key)] = val;
693
+ }
694
+ return init;
695
+ });
688
696
  const [questionErrors, setQuestionErrors] = useState({});
689
697
  const [questionTouched, setQuestionTouched] = useState({});
690
698
  const getFieldRequired = (name) => {
@@ -848,12 +856,20 @@ var ContactDetailsForm = forwardRef(
848
856
  }, [contactFields, questions, validateAllContacts, validateAllQuestions, onSubmit, buildOutput]);
849
857
  useImperativeHandle(ref, () => ({
850
858
  reset: () => {
851
- setFirstName("");
852
- setLastName("");
853
- setEmailValue("");
859
+ setFirstName(initialValues?.firstName || "");
860
+ setLastName(initialValues?.lastName || "");
861
+ setEmailValue(initialValues?.email || "");
854
862
  setContactErrors({});
855
863
  setContactTouched({});
856
- setQuestionValues({});
864
+ if (initialValues?.questions) {
865
+ const init = {};
866
+ for (const [key, val] of Object.entries(initialValues.questions)) {
867
+ init[Number(key)] = val;
868
+ }
869
+ setQuestionValues(init);
870
+ } else {
871
+ setQuestionValues({});
872
+ }
857
873
  setQuestionErrors({});
858
874
  setQuestionTouched({});
859
875
  },
@@ -862,7 +878,7 @@ var ContactDetailsForm = forwardRef(
862
878
  if (vals.lastName !== void 0) setLastName(vals.lastName);
863
879
  if (vals.email !== void 0) setEmailValue(vals.email);
864
880
  }
865
- }), []);
881
+ }), [initialValues]);
866
882
  const styles = {
867
883
  fieldWrapper: classNames.fieldWrapper || "mb-4",
868
884
  label: classNames.label || "block text-sm font-medium mb-1",
@@ -1070,7 +1086,178 @@ var ContactDetailsForm = forwardRef(
1070
1086
  }
1071
1087
  );
1072
1088
  ContactDetailsForm.displayName = "ContactDetailsForm";
1089
+ var FIELDS = [
1090
+ { name: "currentPassword", label: "Current Password" },
1091
+ { name: "newPassword", label: "New Password" },
1092
+ { name: "confirmNewPassword", label: "Confirm New Password" }
1093
+ ];
1094
+ var ResetPasswordForm = forwardRef(
1095
+ ({
1096
+ onSubmit,
1097
+ onChange,
1098
+ validateOnBlur = true,
1099
+ submitLabel = "Update Password",
1100
+ className = "",
1101
+ classNames = {}
1102
+ }, ref) => {
1103
+ const formId = useId();
1104
+ const [values, setValues] = useState({
1105
+ currentPassword: "",
1106
+ newPassword: "",
1107
+ confirmNewPassword: ""
1108
+ });
1109
+ const [errors, setErrors] = useState({});
1110
+ const [touched, setTouched] = useState({});
1111
+ const validateField = useCallback(
1112
+ (name, val, allValues) => {
1113
+ if (!val || val.trim() === "") return "This field is required";
1114
+ if (name === "confirmNewPassword" && val !== allValues.newPassword) {
1115
+ return "Passwords do not match";
1116
+ }
1117
+ return null;
1118
+ },
1119
+ []
1120
+ );
1121
+ const checkIsValid = useCallback(
1122
+ (v) => {
1123
+ for (const field of FIELDS) {
1124
+ if (validateField(field.name, v[field.name], v)) return false;
1125
+ }
1126
+ return true;
1127
+ },
1128
+ [validateField]
1129
+ );
1130
+ const handleChange = useCallback(
1131
+ (name, val) => {
1132
+ const newValues = { ...values, [name]: val };
1133
+ setValues(newValues);
1134
+ if (touched[name]) {
1135
+ const error = validateField(name, val, newValues);
1136
+ if (!error) {
1137
+ setErrors((prev) => {
1138
+ const next = { ...prev };
1139
+ delete next[name];
1140
+ return next;
1141
+ });
1142
+ }
1143
+ }
1144
+ if (name === "newPassword" && touched.confirmNewPassword) {
1145
+ const confirmError = validateField("confirmNewPassword", newValues.confirmNewPassword, newValues);
1146
+ if (confirmError) {
1147
+ setErrors((prev) => ({ ...prev, confirmNewPassword: confirmError }));
1148
+ } else {
1149
+ setErrors((prev) => {
1150
+ const next = { ...prev };
1151
+ delete next.confirmNewPassword;
1152
+ return next;
1153
+ });
1154
+ }
1155
+ }
1156
+ onChange?.(newValues, checkIsValid(newValues));
1157
+ },
1158
+ [values, touched, validateField, onChange, checkIsValid]
1159
+ );
1160
+ const handleBlur = useCallback(
1161
+ (name) => {
1162
+ setTouched((prev) => ({ ...prev, [name]: true }));
1163
+ if (validateOnBlur) {
1164
+ const error = validateField(name, values[name], values);
1165
+ if (error) {
1166
+ setErrors((prev) => ({ ...prev, [name]: error }));
1167
+ } else {
1168
+ setErrors((prev) => {
1169
+ const next = { ...prev };
1170
+ delete next[name];
1171
+ return next;
1172
+ });
1173
+ }
1174
+ }
1175
+ },
1176
+ [validateOnBlur, values, validateField]
1177
+ );
1178
+ const handleSubmit = useCallback(
1179
+ (e) => {
1180
+ e.preventDefault();
1181
+ const allTouched = {};
1182
+ const newErrors = {};
1183
+ let isValid = true;
1184
+ for (const field of FIELDS) {
1185
+ allTouched[field.name] = true;
1186
+ const error = validateField(field.name, values[field.name], values);
1187
+ if (error) {
1188
+ newErrors[field.name] = error;
1189
+ isValid = false;
1190
+ }
1191
+ }
1192
+ setTouched(allTouched);
1193
+ setErrors(newErrors);
1194
+ if (isValid) onSubmit(values);
1195
+ },
1196
+ [values, validateField, onSubmit]
1197
+ );
1198
+ useImperativeHandle(ref, () => ({
1199
+ reset: () => {
1200
+ setValues({ currentPassword: "", newPassword: "", confirmNewPassword: "" });
1201
+ setErrors({});
1202
+ setTouched({});
1203
+ },
1204
+ setValues: (newVals) => {
1205
+ setValues((prev) => {
1206
+ const merged = { ...prev };
1207
+ for (const [key, value] of Object.entries(newVals)) {
1208
+ if (value !== void 0) {
1209
+ merged[key] = value;
1210
+ }
1211
+ }
1212
+ return merged;
1213
+ });
1214
+ }
1215
+ }), []);
1216
+ const styles = {
1217
+ fieldWrapper: classNames.fieldWrapper || "mb-4",
1218
+ label: classNames.label || "block text-sm font-medium mb-1",
1219
+ input: classNames.input || "w-full px-3 py-2 border rounded-md",
1220
+ inputError: classNames.inputError || "border-red-500",
1221
+ errorText: classNames.errorText || "mt-1 text-xs text-red-600",
1222
+ button: classNames.button || "w-full mt-4 px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 disabled:opacity-50"
1223
+ };
1224
+ return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className, noValidate: true, children: [
1225
+ FIELDS.map((field) => {
1226
+ const fieldId = `${formId}-${field.name}`;
1227
+ const errorId = `${fieldId}-error`;
1228
+ const value = values[field.name];
1229
+ const error = errors[field.name];
1230
+ const isTouched = touched[field.name];
1231
+ const showError = isTouched && error;
1232
+ return /* @__PURE__ */ jsxs("div", { className: styles.fieldWrapper, children: [
1233
+ /* @__PURE__ */ jsxs("label", { htmlFor: fieldId, className: styles.label, children: [
1234
+ field.label,
1235
+ /* @__PURE__ */ jsx("span", { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" })
1236
+ ] }),
1237
+ /* @__PURE__ */ jsx(
1238
+ "input",
1239
+ {
1240
+ id: fieldId,
1241
+ name: field.name,
1242
+ type: "password",
1243
+ value,
1244
+ onChange: (e) => handleChange(field.name, e.target.value),
1245
+ onBlur: () => handleBlur(field.name),
1246
+ className: `${styles.input} ${showError ? styles.inputError : ""}`,
1247
+ "aria-invalid": showError ? "true" : "false",
1248
+ "aria-describedby": showError ? errorId : void 0,
1249
+ "aria-required": "true"
1250
+ }
1251
+ ),
1252
+ showError && /* @__PURE__ */ jsx("p", { id: errorId, className: styles.errorText, role: "alert", children: error })
1253
+ ] }, field.name);
1254
+ }),
1255
+ /* @__PURE__ */ jsx("button", { type: "submit", className: styles.button, children: submitLabel })
1256
+ ] });
1257
+ }
1258
+ );
1259
+ ResetPasswordForm.displayName = "ResetPasswordForm";
1073
1260
 
1074
- export { BookingForm, ContactDetailsForm, RegistrationForm, compose, email, minLen, phone, required, ukPostcode };
1261
+ export { BookingForm, ContactDetailsForm, RegistrationForm, ResetPasswordForm, compose, email, minLen, phone, required, ukPostcode };
1075
1262
  //# sourceMappingURL=index.mjs.map
1076
1263
  //# sourceMappingURL=index.mjs.map