goobs-frontend 0.7.61 → 0.7.63

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.
@@ -2,186 +2,152 @@
2
2
 
3
3
  import { useCallback, useState, useMemo, useRef, useEffect } from 'react'
4
4
  import { debounce } from 'lodash'
5
- import React from 'react'
6
- import { get, set, StringValue } from 'goobs-cache'
7
-
8
- /**
9
- * Validates if the given string is a valid email format.
10
- *
11
- * @param {string} email - The email string to validate.
12
- * @returns {boolean} True if the email is valid, false otherwise.
13
- */
5
+ import { get, set, StringValue, JSONValue } from 'goobs-cache'
6
+
14
7
  const isValidEmailFormat = (email: string): boolean => {
15
8
  const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
16
9
  return emailRegex.test(email)
17
10
  }
18
11
 
19
- /**
20
- * Represents a message for the helper footer.
21
- *
22
- * @interface HelperFooterMessage
23
- * @property {('error' | 'success')} status - The status of the message.
24
- * @property {string} statusMessage - The detailed status message.
25
- * @property {string} spreadMessage - A condensed version of the message for spreading.
26
- * @property {number} spreadMessagePriority - The priority of the spread message.
27
- * @property {string} formname - The name of the form this message is associated with.
28
- * @property {boolean} required - Indicates if the field associated with this message is required.
29
- */
30
12
  export interface HelperFooterMessage {
31
- status: 'error' | 'success'
13
+ status: 'error' | 'success' | 'emptyAndRequired'
32
14
  statusMessage: string
33
15
  spreadMessage: string
34
16
  spreadMessagePriority: number
35
- formname: string
36
17
  required: boolean
37
18
  }
38
19
 
39
- /**
40
- * A custom hook for managing form validation and helper messages.
41
- *
42
- * @returns {Object} An object containing validation functions and helper footer state.
43
- */
44
20
  export const useHelperFooter = () => {
45
21
  const [helperFooterValue, setHelperFooterValue] = useState<
46
22
  Record<string, HelperFooterMessage>
47
23
  >({})
48
24
  const helperFooterRef = useRef<Record<string, HelperFooterMessage>>({})
49
25
 
50
- /**
51
- * Handles creation of generic error messages for form fields.
52
- *
53
- * @param {FormData} formData - The form data to validate.
54
- * @param {string} name - The name of the form field.
55
- * @param {string} label - The label of the form field.
56
- * @param {boolean} required - Whether the field is required.
57
- * @param {string} formname - The name of the form.
58
- * @returns {HelperFooterMessage | undefined} An error message object if there's an error, undefined otherwise.
59
- */
60
26
  const handleGenericErrorCreation = useCallback(
61
- (
27
+ async (
62
28
  formData: FormData,
63
29
  name: string,
64
30
  label: string,
65
31
  required: boolean,
66
32
  formname: string
67
- ): HelperFooterMessage | undefined => {
68
- console.log(`Handling generic error creation for ${name}`)
33
+ ): Promise<HelperFooterMessage | undefined> => {
69
34
  const value = formData.get(name) as string
70
35
  if (required && (!value || !value.trim())) {
71
- console.log(`Error: ${label} is required`)
72
- return {
36
+ const message: HelperFooterMessage = {
73
37
  status: 'error',
74
38
  statusMessage: `${label} is required. Please enter a ${label.toLowerCase()}.`,
75
39
  spreadMessage: `${label} is required.`,
76
40
  spreadMessagePriority: 1,
77
- formname,
78
41
  required,
79
42
  }
43
+ const jsonValue: JSONValue = {
44
+ type: 'json',
45
+ value: {
46
+ [name]: {
47
+ status: message.status,
48
+ statusMessage: message.statusMessage,
49
+ spreadMessage: message.spreadMessage,
50
+ spreadMessagePriority: message.spreadMessagePriority,
51
+ required: message.required,
52
+ },
53
+ },
54
+ }
55
+ await set('helperfooter', formname, jsonValue, 'client')
56
+ console.log(
57
+ `Stored helper footer for ${name}:`,
58
+ message,
59
+ `storeName: ${formname}`
60
+ )
61
+ return message
80
62
  }
81
- console.log(`No error for ${name}`)
82
63
  return undefined
83
64
  },
84
65
  []
85
66
  )
86
67
 
87
- /**
88
- * Handles creation of email-specific error messages.
89
- *
90
- * @param {FormData} formData - The form data to validate.
91
- * @param {boolean} required - Whether the email field is required.
92
- * @param {string} formname - The name of the form.
93
- * @returns {HelperFooterMessage | undefined} An error or success message object, or undefined if no message is needed.
94
- */
95
68
  const handleEmailErrorCreation = useCallback(
96
- (
69
+ async (
97
70
  formData: FormData,
98
71
  required: boolean,
99
72
  formname: string
100
- ): HelperFooterMessage | undefined => {
101
- console.log('Handling email error creation')
73
+ ): Promise<HelperFooterMessage | undefined> => {
102
74
  const email = formData.get('email') as string
75
+ let message: HelperFooterMessage | undefined
76
+
103
77
  if (required && (!email || !email.trim())) {
104
- console.log('Error: Email is required')
105
- return {
78
+ message = {
106
79
  status: 'error',
107
80
  statusMessage: 'Please enter an email address.',
108
81
  spreadMessage: 'Email is required.',
109
82
  spreadMessagePriority: 1,
110
- formname,
111
83
  required,
112
84
  }
113
- }
114
- if (!email) return undefined
115
- if (email && !isValidEmailFormat(email)) {
116
- console.log('Error: Invalid email format')
117
- return {
85
+ } else if (email && !isValidEmailFormat(email)) {
86
+ message = {
118
87
  status: 'error',
119
88
  statusMessage: 'Please enter a valid email address.',
120
89
  spreadMessage: 'Invalid email format.',
121
90
  spreadMessagePriority: 1,
122
- formname,
91
+ required,
92
+ }
93
+ } else if (email) {
94
+ message = {
95
+ status: 'success',
96
+ statusMessage: 'Email is valid.',
97
+ spreadMessage: 'Email is valid.',
98
+ spreadMessagePriority: 1,
123
99
  required,
124
100
  }
125
101
  }
126
- console.log('Email is valid')
127
- return {
128
- status: 'success',
129
- statusMessage: 'Email is valid.',
130
- spreadMessage: 'Email is valid.',
131
- spreadMessagePriority: 1,
132
- formname,
133
- required,
102
+
103
+ if (message) {
104
+ const jsonValue: JSONValue = {
105
+ type: 'json',
106
+ value: {
107
+ email: {
108
+ status: message.status,
109
+ statusMessage: message.statusMessage,
110
+ spreadMessage: message.spreadMessage,
111
+ spreadMessagePriority: message.spreadMessagePriority,
112
+ required: message.required,
113
+ },
114
+ },
115
+ }
116
+ await set('helperfooter', formname, jsonValue, 'client')
117
+ console.log(
118
+ `Stored helper footer for email:`,
119
+ message,
120
+ `storeName: ${formname}`
121
+ )
134
122
  }
123
+
124
+ return message
135
125
  },
136
126
  []
137
127
  )
138
128
 
139
- /**
140
- * Handles creation of password-specific error messages and stores the password in the client cache.
141
- *
142
- * @param {FormData} formData - The form data to validate.
143
- * @param {boolean} required - Whether the password field is required.
144
- * @param {string} formname - The name of the form.
145
- * @returns {HelperFooterMessage | undefined} An error or success message object, or undefined if no message is needed.
146
- */
147
129
  const handlePasswordErrorCreation = useCallback(
148
- (
130
+ async (
149
131
  formData: FormData,
150
132
  required: boolean,
151
133
  formname: string
152
- ): HelperFooterMessage | undefined => {
153
- console.log('Handling password error creation')
134
+ ): Promise<HelperFooterMessage | undefined> => {
154
135
  const password = formData.get('verifyPassword') as string
155
- console.log('Password received:', password)
136
+ console.log('handlePasswordErrorCreation - Password:', password)
156
137
 
157
138
  const debouncedPasswordStorage = debounce(async () => {
158
- console.log('Attempting to store password in goobs-cache client store')
159
139
  try {
160
140
  if (password) {
161
- console.log('Setting password in goobs-cache:', password)
141
+ console.log('Storing password in goobs-cache...')
162
142
  await set(
163
- 'verifyPassword',
143
+ 'validate',
144
+ formname,
164
145
  { type: 'string', value: password } as StringValue,
165
- new Date(Date.now() + 30 * 60 * 1000),
166
146
  'client'
167
147
  )
168
- console.log('Password set operation completed')
169
-
170
- // Immediately retrieve the password to verify it was stored
171
- console.log('Attempting to retrieve password from client store')
172
- const storedPassword = await get('verifyPassword', 'client')
173
- console.log('Raw stored password result:', storedPassword)
174
-
175
- if (storedPassword && storedPassword.value) {
176
- console.log(
177
- 'Immediately retrieved password from client store:',
178
- storedPassword.value
179
- )
180
- } else {
181
- console.log('Retrieved password is null or undefined')
182
- }
148
+ console.log('Password stored successfully')
183
149
  } else {
184
- console.log('Password is null or empty, not storing in goobs-cache')
150
+ console.log('No password to store')
185
151
  }
186
152
  } catch (error) {
187
153
  console.error('Error interacting with goobs-cache:', error)
@@ -190,217 +156,286 @@ export const useHelperFooter = () => {
190
156
 
191
157
  debouncedPasswordStorage()
192
158
 
159
+ let message: HelperFooterMessage | undefined
160
+
193
161
  if (required && (!password || !password.trim())) {
194
- console.log('Error: Password is required')
195
- return {
162
+ message = {
196
163
  status: 'error',
197
164
  statusMessage: 'Password is required.',
198
165
  spreadMessage: 'Password is required.',
199
166
  spreadMessagePriority: 4,
200
- formname,
201
167
  required,
202
168
  }
203
- }
204
- if (!password) return undefined
205
- const passwordRegex =
206
- /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/
207
- const passwordComplexityStatus: 'error' | 'success' = passwordRegex.test(
208
- password
209
- )
210
- ? 'success'
211
- : 'error'
212
- if (passwordComplexityStatus === 'error') {
213
- console.log('Error: Invalid password complexity')
214
- return {
215
- status: 'error',
216
- statusMessage:
217
- 'Password must include at least 8 characters, one uppercase letter, one lowercase letter, one number, and one special character.',
218
- spreadMessage: 'Invalid password.',
219
- spreadMessagePriority: 1,
220
- formname,
221
- required,
169
+ } else if (password) {
170
+ const passwordRegex =
171
+ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/
172
+ const passwordComplexityStatus: 'error' | 'success' =
173
+ passwordRegex.test(password) ? 'success' : 'error'
174
+
175
+ if (passwordComplexityStatus === 'error') {
176
+ message = {
177
+ status: 'error',
178
+ statusMessage:
179
+ 'Password must include at least 8 characters, one uppercase letter, one lowercase letter, one number, and one special character.',
180
+ spreadMessage: 'Invalid password.',
181
+ spreadMessagePriority: 1,
182
+ required,
183
+ }
184
+ } else {
185
+ message = {
186
+ status: 'success',
187
+ statusMessage: 'Password meets all requirements.',
188
+ spreadMessage: 'Password is valid.',
189
+ spreadMessagePriority: 1,
190
+ required,
191
+ }
222
192
  }
223
193
  }
224
- console.log('Password meets all requirements')
225
- return {
226
- status: 'success',
227
- statusMessage: 'Password meets all requirements.',
228
- spreadMessage: 'Password is valid.',
229
- spreadMessagePriority: 1,
230
- formname,
231
- required,
194
+
195
+ if (message) {
196
+ const jsonValue: JSONValue = {
197
+ type: 'json',
198
+ value: {
199
+ verifyPassword: {
200
+ status: message.status,
201
+ statusMessage: message.statusMessage,
202
+ spreadMessage: message.spreadMessage,
203
+ spreadMessagePriority: message.spreadMessagePriority,
204
+ required: message.required,
205
+ },
206
+ },
207
+ }
208
+ await set('helperfooter', formname, jsonValue, 'client')
209
+ console.log(
210
+ `Stored helper footer for verifyPassword:`,
211
+ message,
212
+ `storeName: ${formname}`
213
+ )
232
214
  }
215
+
216
+ return message
233
217
  },
234
218
  []
235
219
  )
236
220
 
237
- /**
238
- * Handles creation of confirm password error messages by comparing with the stored password.
239
- *
240
- * @param {FormData} formData - The form data to validate.
241
- * @param {boolean} required - Whether the confirm password field is required.
242
- * @param {string} formname - The name of the form.
243
- * @returns {Promise<HelperFooterMessage | undefined>} A promise that resolves to an error or success message object, or undefined if no message is needed.
244
- */
245
221
  const handleConfirmPasswordErrorCreation = useCallback(
246
222
  async (
247
223
  formData: FormData,
248
224
  required: boolean,
249
225
  formname: string
250
226
  ): Promise<HelperFooterMessage | undefined> => {
251
- console.log('Handling confirm password error creation')
252
227
  const confirmPassword = formData.get('confirmPassword') as string
253
- console.log('Confirm password received:', confirmPassword)
228
+ console.log(
229
+ 'handleConfirmPasswordErrorCreation - Confirm Password:',
230
+ confirmPassword
231
+ )
232
+
233
+ let message: HelperFooterMessage | undefined
254
234
 
255
235
  if (required && (!confirmPassword || !confirmPassword.trim())) {
256
- console.log('Error: Password confirmation is required')
257
- return {
236
+ message = {
258
237
  status: 'error',
259
238
  statusMessage: 'Please confirm your password.',
260
239
  spreadMessage: 'Password confirmation is required.',
261
240
  spreadMessagePriority: 4,
262
- formname,
263
241
  required,
264
242
  }
265
- }
266
- if (!confirmPassword) return undefined
267
-
268
- console.log(
269
- 'Attempting to retrieve verify password from goobs-cache client store'
270
- )
271
- let verifyPasswordResult
272
- try {
273
- verifyPasswordResult = await get('verifyPassword', 'client')
274
- console.log('Retrieved verify password result:', verifyPasswordResult)
275
- } catch (error) {
276
- console.error('Error retrieving password from goobs-cache:', error)
277
- }
243
+ } else if (confirmPassword) {
244
+ let verifyPasswordResult
245
+ try {
246
+ console.log('Retrieving password from goobs-cache...')
247
+ verifyPasswordResult = await get('validate', formname, 'client')
248
+ console.log('Retrieved password result:', verifyPasswordResult)
249
+ } catch (error) {
250
+ console.error('Error retrieving password from goobs-cache:', error)
251
+ }
278
252
 
279
- let verifyPassword: string | undefined
280
- if (
281
- verifyPasswordResult &&
282
- typeof verifyPasswordResult === 'object' &&
283
- 'value' in verifyPasswordResult &&
284
- verifyPasswordResult.value &&
285
- typeof verifyPasswordResult.value === 'object' &&
286
- 'value' in verifyPasswordResult.value
287
- ) {
288
- verifyPassword = verifyPasswordResult.value.value
289
- console.log('Verify password from client store:', verifyPassword)
290
- } else {
291
- console.log(
292
- 'Verify password not found in client store or in unexpected format'
293
- )
294
- }
253
+ let verifyPassword: string | undefined
254
+ if (
255
+ verifyPasswordResult &&
256
+ typeof verifyPasswordResult === 'object' &&
257
+ 'type' in verifyPasswordResult &&
258
+ verifyPasswordResult.type === 'string' &&
259
+ 'value' in verifyPasswordResult &&
260
+ typeof verifyPasswordResult.value === 'string'
261
+ ) {
262
+ verifyPassword = verifyPasswordResult.value
263
+ console.log('Verify password retrieved:', verifyPassword)
264
+ } else {
265
+ console.log('Invalid or missing verify password result')
266
+ }
295
267
 
296
- if (!verifyPassword) {
297
- console.log('Error: Password not set')
298
- return {
299
- status: 'error',
300
- statusMessage: 'Please enter your password first.',
301
- spreadMessage: 'Password not set.',
302
- spreadMessagePriority: 4,
303
- formname,
304
- required,
268
+ if (!verifyPassword) {
269
+ message = {
270
+ status: 'error',
271
+ statusMessage: 'Please enter your password first.',
272
+ spreadMessage: 'Password not set.',
273
+ spreadMessagePriority: 4,
274
+ required,
275
+ }
276
+ } else if (confirmPassword !== verifyPassword) {
277
+ message = {
278
+ status: 'error',
279
+ statusMessage: 'Passwords do not match.',
280
+ spreadMessage: 'Passwords do not match.',
281
+ spreadMessagePriority: 4,
282
+ required,
283
+ }
284
+ } else {
285
+ message = {
286
+ status: 'success',
287
+ statusMessage: 'Passwords match.',
288
+ spreadMessage: 'Passwords match.',
289
+ spreadMessagePriority: 4,
290
+ required,
291
+ }
305
292
  }
306
293
  }
307
294
 
308
- if (confirmPassword !== verifyPassword) {
309
- console.log('Error: Passwords do not match')
310
- return {
311
- status: 'error',
312
- statusMessage: 'Passwords do not match.',
313
- spreadMessage: 'Passwords do not match.',
314
- spreadMessagePriority: 4,
315
- formname,
316
- required,
295
+ if (message) {
296
+ const jsonValue: JSONValue = {
297
+ type: 'json',
298
+ value: {
299
+ confirmPassword: {
300
+ status: message.status,
301
+ statusMessage: message.statusMessage,
302
+ spreadMessage: message.spreadMessage,
303
+ spreadMessagePriority: message.spreadMessagePriority,
304
+ required: message.required,
305
+ },
306
+ },
317
307
  }
308
+ await set('helperfooter', formname, jsonValue, 'client')
309
+ console.log(
310
+ `Stored helper footer for confirmPassword:`,
311
+ message,
312
+ `storeName: ${formname}`
313
+ )
318
314
  }
319
315
 
320
- console.log('Passwords match')
321
- return {
322
- status: 'success',
323
- statusMessage: 'Passwords match.',
324
- spreadMessage: 'Passwords match.',
325
- spreadMessagePriority: 4,
326
- formname,
327
- required,
328
- }
316
+ return message
329
317
  },
330
318
  []
331
319
  )
332
320
 
333
- /**
334
- * Handles creation of phone number error messages.
335
- *
336
- * @param {FormData} formData - The form data to validate.
337
- * @param {boolean} required - Whether the phone number field is required.
338
- * @param {string} formname - The name of the form.
339
- * @returns {HelperFooterMessage | undefined} An error or success message object, or undefined if no message is needed.
340
- */
341
321
  const handlePhoneNumberErrorCreation = useCallback(
342
- (
322
+ async (
343
323
  formData: FormData,
344
324
  required: boolean,
345
325
  formname: string
346
- ): HelperFooterMessage | undefined => {
347
- console.log('Handling phone number error creation')
326
+ ): Promise<HelperFooterMessage | undefined> => {
348
327
  const phoneNumber = formData.get('phoneNumber') as string
328
+ let message: HelperFooterMessage | undefined
329
+
349
330
  if (required && (!phoneNumber || !phoneNumber.trim())) {
350
- console.log('Error: Phone number is required')
351
- return {
331
+ message = {
352
332
  status: 'error',
353
333
  statusMessage:
354
334
  'Phone number is required. Please enter a phone number.',
355
335
  spreadMessage: 'Phone number is required.',
356
336
  spreadMessagePriority: 1,
357
- formname,
358
337
  required,
359
338
  }
339
+ } else if (phoneNumber) {
340
+ const digitsOnly = phoneNumber.replace(/[^\d]/g, '')
341
+ const length = digitsOnly.length
342
+ if (
343
+ (length === 10 && !digitsOnly.startsWith('1')) ||
344
+ (length === 11 && digitsOnly.startsWith('1'))
345
+ ) {
346
+ message = {
347
+ status: 'success',
348
+ statusMessage: 'Phone number is valid.',
349
+ spreadMessage: 'Phone number is valid.',
350
+ spreadMessagePriority: 1,
351
+ required,
352
+ }
353
+ } else {
354
+ message = {
355
+ status: 'error',
356
+ statusMessage:
357
+ 'Please enter a valid 10-digit phone number or a 10-digit number starting with 1.',
358
+ spreadMessage: 'Invalid phone number format.',
359
+ spreadMessagePriority: 1,
360
+ required,
361
+ }
362
+ }
360
363
  }
361
- if (!phoneNumber) return undefined
362
- const digitsOnly = phoneNumber.replace(/[^\d]/g, '')
363
- const length = digitsOnly.length
364
- if (
365
- (length === 10 && !digitsOnly.startsWith('1')) ||
366
- (length === 11 && digitsOnly.startsWith('1'))
367
- ) {
368
- console.log('Phone number is valid')
369
- return {
370
- status: 'success',
371
- statusMessage: 'Phone number is valid.',
372
- spreadMessage: 'Phone number is valid.',
373
- spreadMessagePriority: 1,
374
- formname,
375
- required,
364
+
365
+ if (message) {
366
+ const jsonValue: JSONValue = {
367
+ type: 'json',
368
+ value: {
369
+ phoneNumber: {
370
+ status: message.status,
371
+ statusMessage: message.statusMessage,
372
+ spreadMessage: message.spreadMessage,
373
+ spreadMessagePriority: message.spreadMessagePriority,
374
+ required: message.required,
375
+ },
376
+ },
376
377
  }
377
- } else {
378
- console.log('Error: Invalid phone number format')
379
- return {
380
- status: 'error',
381
- statusMessage:
382
- 'Please enter a valid 10-digit phone number or a 10-digit number starting with 1.',
383
- spreadMessage: 'Invalid phone number format.',
384
- spreadMessagePriority: 1,
385
- formname,
386
- required,
378
+ await set('helperfooter', formname, jsonValue, 'client')
379
+ console.log(
380
+ `Stored helper footer for phoneNumber:`,
381
+ message,
382
+ `storeName: ${formname}`
383
+ )
384
+ }
385
+
386
+ return message
387
+ },
388
+ []
389
+ )
390
+
391
+ const updateHelperFooter = useCallback(
392
+ (name: string, validationResult: HelperFooterMessage | undefined): void => {
393
+ if (validationResult) {
394
+ helperFooterRef.current = {
395
+ ...helperFooterRef.current,
396
+ [name]: validationResult,
387
397
  }
398
+ } else {
399
+ const newHelperFooter: Record<string, HelperFooterMessage> = {}
400
+ Object.keys(helperFooterRef.current).forEach(key => {
401
+ if (key !== name) {
402
+ newHelperFooter[key] = helperFooterRef.current[key]
403
+ }
404
+ })
405
+ helperFooterRef.current = newHelperFooter
388
406
  }
407
+
408
+ setHelperFooterValue({ ...helperFooterRef.current })
389
409
  },
390
410
  []
391
411
  )
392
412
 
393
- /**
394
- * Validates a specific field in the form.
395
- *
396
- * @param {string} name - The name of the field to validate.
397
- * @param {FormData} formData - The form data to validate.
398
- * @param {string} label - The label of the field.
399
- * @param {boolean} required - Whether the field is required.
400
- * @param {string} formname - The name of the form.
401
- */
413
+ const initializeRequiredFields = useCallback(
414
+ async (formname: string) => {
415
+ console.log(`Initializing required fields for ${formname}`)
416
+ const fields = await get('helperfooter', formname, 'client')
417
+ if (
418
+ fields &&
419
+ typeof fields === 'object' &&
420
+ 'type' in fields &&
421
+ fields.type === 'json' &&
422
+ 'value' in fields
423
+ ) {
424
+ Object.entries(fields.value as Record<string, unknown>).forEach(
425
+ ([field, message]) => {
426
+ if (message && typeof message === 'object' && 'status' in message) {
427
+ updateHelperFooter(field, message as HelperFooterMessage)
428
+ console.log(`Initialized required field ${field}:`, message)
429
+ }
430
+ }
431
+ )
432
+ }
433
+ },
434
+ [updateHelperFooter]
435
+ )
436
+
402
437
  const validateField = useCallback(
403
- (
438
+ async (
404
439
  name: string,
405
440
  formData: FormData,
406
441
  label: string,
@@ -408,54 +443,49 @@ export const useHelperFooter = () => {
408
443
  formname: string
409
444
  ) => {
410
445
  console.log(`Validating field: ${name}`)
411
- const validation = () => {
412
- let validationResult: HelperFooterMessage | undefined
413
- switch (name) {
414
- case 'email':
415
- validationResult = handleEmailErrorCreation(
416
- formData,
417
- required,
418
- formname
419
- )
420
- break
421
- case 'verifyPassword':
422
- validationResult = handlePasswordErrorCreation(
423
- formData,
424
- required,
425
- formname
426
- )
427
- break
428
- case 'confirmPassword':
429
- handleConfirmPasswordErrorCreation(
430
- formData,
431
- required,
432
- formname
433
- ).then(result => {
434
- validationResult = result
435
- updateHelperFooter(name, validationResult)
436
- })
437
- return
438
- case 'phoneNumber':
439
- validationResult = handlePhoneNumberErrorCreation(
440
- formData,
441
- required,
442
- formname
443
- )
444
- break
445
- default:
446
- validationResult = handleGenericErrorCreation(
447
- formData,
448
- name,
449
- label,
450
- required,
451
- formname
452
- )
453
- }
446
+ let validationResult: HelperFooterMessage | undefined
454
447
 
455
- updateHelperFooter(name, validationResult)
448
+ switch (name) {
449
+ case 'email':
450
+ validationResult = await handleEmailErrorCreation(
451
+ formData,
452
+ required,
453
+ formname
454
+ )
455
+ break
456
+ case 'verifyPassword':
457
+ validationResult = await handlePasswordErrorCreation(
458
+ formData,
459
+ required,
460
+ formname
461
+ )
462
+ break
463
+ case 'confirmPassword':
464
+ validationResult = await handleConfirmPasswordErrorCreation(
465
+ formData,
466
+ required,
467
+ formname
468
+ )
469
+ break
470
+ case 'phoneNumber':
471
+ validationResult = await handlePhoneNumberErrorCreation(
472
+ formData,
473
+ required,
474
+ formname
475
+ )
476
+ break
477
+ default:
478
+ validationResult = await handleGenericErrorCreation(
479
+ formData,
480
+ name,
481
+ label,
482
+ required,
483
+ formname
484
+ )
456
485
  }
457
486
 
458
- validation()
487
+ updateHelperFooter(name, validationResult)
488
+ console.log(`Validation result for ${name}:`, validationResult)
459
489
  },
460
490
  [
461
491
  handleEmailErrorCreation,
@@ -463,46 +493,17 @@ export const useHelperFooter = () => {
463
493
  handleConfirmPasswordErrorCreation,
464
494
  handlePhoneNumberErrorCreation,
465
495
  handleGenericErrorCreation,
496
+ updateHelperFooter,
466
497
  ]
467
498
  )
468
499
 
469
- const updateHelperFooter = (
470
- name: string,
471
- validationResult: HelperFooterMessage | undefined
472
- ) => {
473
- if (validationResult) {
474
- helperFooterRef.current = {
475
- ...helperFooterRef.current,
476
- [name]: validationResult,
477
- }
478
- } else {
479
- helperFooterRef.current = Object.fromEntries(
480
- Object.entries(helperFooterRef.current).filter(([key]) => key !== name)
481
- )
482
- }
483
-
484
- console.log('Updated helperFooterRef:', helperFooterRef.current)
485
- setHelperFooterValue({ ...helperFooterRef.current })
486
- console.log('Helper footer updated in state')
487
- }
488
-
489
500
  const validateRequiredField = useCallback(
490
501
  (required: boolean, formname: string, name: string, label: string) => {
491
- console.log('validateRequiredField: Starting', {
492
- required,
493
- formname,
494
- name,
495
- label,
496
- })
502
+ console.log(`Validating required field: ${name}`)
497
503
  if (required && formname && name && label) {
498
- console.log('validateRequiredField: Validating required field')
499
504
  const emptyFormData = new FormData()
500
505
  emptyFormData.append(name, '')
501
506
  validateField(name, emptyFormData, label, required, formname)
502
- } else {
503
- console.log(
504
- 'validateRequiredField: Not validating (missing required props)'
505
- )
506
507
  }
507
508
  },
508
509
  [validateField]
@@ -511,27 +512,69 @@ export const useHelperFooter = () => {
511
512
  const useShowErrorEffect = (
512
513
  formSubmitted: boolean,
513
514
  hasInput: boolean,
514
- isFocused: boolean,
515
- setShowError: React.Dispatch<React.SetStateAction<boolean>>
516
- ) => {
515
+ isFocused: boolean
516
+ ): boolean => {
517
+ const [showError, setShowError] = useState<boolean>(false)
518
+
517
519
  useEffect(() => {
518
- const showError = formSubmitted || (hasInput && !isFocused)
519
- console.log('useShowErrorEffect: Setting showError to', showError, {
520
- formSubmitted,
521
- hasInput,
522
- isFocused,
523
- })
524
- setShowError(showError)
525
- }, [formSubmitted, hasInput, isFocused, setShowError])
520
+ const shouldShowError = formSubmitted || (hasInput && !isFocused)
521
+ setShowError(shouldShowError)
522
+ console.log('Show error state updated:', shouldShowError)
523
+ }, [formSubmitted, hasInput, isFocused])
524
+
525
+ return showError
526
526
  }
527
527
 
528
+ const fetchHelperFooters = useCallback(
529
+ async (formname: string): Promise<HelperFooterMessage[]> => {
530
+ console.log(`Fetching helper footers for ${formname}`)
531
+ const helperFooters = await get('helperfooter', formname, 'client')
532
+ if (
533
+ helperFooters &&
534
+ typeof helperFooters === 'object' &&
535
+ 'type' in helperFooters &&
536
+ helperFooters.type === 'json' &&
537
+ 'value' in helperFooters &&
538
+ typeof helperFooters.value === 'object' &&
539
+ helperFooters.value !== null
540
+ ) {
541
+ const value = helperFooters.value as Record<string, unknown>
542
+ return Object.values(value).filter(
543
+ (item): item is HelperFooterMessage => {
544
+ return (
545
+ typeof item === 'object' &&
546
+ item !== null &&
547
+ 'status' in item &&
548
+ 'statusMessage' in item &&
549
+ 'spreadMessage' in item &&
550
+ 'spreadMessagePriority' in item &&
551
+ 'required' in item
552
+ )
553
+ }
554
+ )
555
+ }
556
+ return []
557
+ },
558
+ []
559
+ )
560
+
528
561
  return useMemo(
529
562
  () => ({
530
563
  validateField,
531
564
  validateRequiredField,
532
565
  helperFooterValue,
533
566
  useShowErrorEffect,
567
+ initializeRequiredFields,
568
+ fetchHelperFooters,
534
569
  }),
535
- [validateField, validateRequiredField, helperFooterValue]
570
+ [
571
+ validateField,
572
+ validateRequiredField,
573
+ helperFooterValue,
574
+ initializeRequiredFields,
575
+ fetchHelperFooters,
576
+ ]
536
577
  )
537
578
  }
579
+
580
+ export default useHelperFooter