goobs-frontend 0.7.63 → 0.7.65

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.
@@ -1,580 +0,0 @@
1
- 'use client'
2
-
3
- import { useCallback, useState, useMemo, useRef, useEffect } from 'react'
4
- import { debounce } from 'lodash'
5
- import { get, set, StringValue, JSONValue } from 'goobs-cache'
6
-
7
- const isValidEmailFormat = (email: string): boolean => {
8
- const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
9
- return emailRegex.test(email)
10
- }
11
-
12
- export interface HelperFooterMessage {
13
- status: 'error' | 'success' | 'emptyAndRequired'
14
- statusMessage: string
15
- spreadMessage: string
16
- spreadMessagePriority: number
17
- required: boolean
18
- }
19
-
20
- export const useHelperFooter = () => {
21
- const [helperFooterValue, setHelperFooterValue] = useState<
22
- Record<string, HelperFooterMessage>
23
- >({})
24
- const helperFooterRef = useRef<Record<string, HelperFooterMessage>>({})
25
-
26
- const handleGenericErrorCreation = useCallback(
27
- async (
28
- formData: FormData,
29
- name: string,
30
- label: string,
31
- required: boolean,
32
- formname: string
33
- ): Promise<HelperFooterMessage | undefined> => {
34
- const value = formData.get(name) as string
35
- if (required && (!value || !value.trim())) {
36
- const message: HelperFooterMessage = {
37
- status: 'error',
38
- statusMessage: `${label} is required. Please enter a ${label.toLowerCase()}.`,
39
- spreadMessage: `${label} is required.`,
40
- spreadMessagePriority: 1,
41
- required,
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
62
- }
63
- return undefined
64
- },
65
- []
66
- )
67
-
68
- const handleEmailErrorCreation = useCallback(
69
- async (
70
- formData: FormData,
71
- required: boolean,
72
- formname: string
73
- ): Promise<HelperFooterMessage | undefined> => {
74
- const email = formData.get('email') as string
75
- let message: HelperFooterMessage | undefined
76
-
77
- if (required && (!email || !email.trim())) {
78
- message = {
79
- status: 'error',
80
- statusMessage: 'Please enter an email address.',
81
- spreadMessage: 'Email is required.',
82
- spreadMessagePriority: 1,
83
- required,
84
- }
85
- } else if (email && !isValidEmailFormat(email)) {
86
- message = {
87
- status: 'error',
88
- statusMessage: 'Please enter a valid email address.',
89
- spreadMessage: 'Invalid email format.',
90
- spreadMessagePriority: 1,
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,
99
- required,
100
- }
101
- }
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
- )
122
- }
123
-
124
- return message
125
- },
126
- []
127
- )
128
-
129
- const handlePasswordErrorCreation = useCallback(
130
- async (
131
- formData: FormData,
132
- required: boolean,
133
- formname: string
134
- ): Promise<HelperFooterMessage | undefined> => {
135
- const password = formData.get('verifyPassword') as string
136
- console.log('handlePasswordErrorCreation - Password:', password)
137
-
138
- const debouncedPasswordStorage = debounce(async () => {
139
- try {
140
- if (password) {
141
- console.log('Storing password in goobs-cache...')
142
- await set(
143
- 'validate',
144
- formname,
145
- { type: 'string', value: password } as StringValue,
146
- 'client'
147
- )
148
- console.log('Password stored successfully')
149
- } else {
150
- console.log('No password to store')
151
- }
152
- } catch (error) {
153
- console.error('Error interacting with goobs-cache:', error)
154
- }
155
- }, 2000)
156
-
157
- debouncedPasswordStorage()
158
-
159
- let message: HelperFooterMessage | undefined
160
-
161
- if (required && (!password || !password.trim())) {
162
- message = {
163
- status: 'error',
164
- statusMessage: 'Password is required.',
165
- spreadMessage: 'Password is required.',
166
- spreadMessagePriority: 4,
167
- required,
168
- }
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
- }
192
- }
193
- }
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
- )
214
- }
215
-
216
- return message
217
- },
218
- []
219
- )
220
-
221
- const handleConfirmPasswordErrorCreation = useCallback(
222
- async (
223
- formData: FormData,
224
- required: boolean,
225
- formname: string
226
- ): Promise<HelperFooterMessage | undefined> => {
227
- const confirmPassword = formData.get('confirmPassword') as string
228
- console.log(
229
- 'handleConfirmPasswordErrorCreation - Confirm Password:',
230
- confirmPassword
231
- )
232
-
233
- let message: HelperFooterMessage | undefined
234
-
235
- if (required && (!confirmPassword || !confirmPassword.trim())) {
236
- message = {
237
- status: 'error',
238
- statusMessage: 'Please confirm your password.',
239
- spreadMessage: 'Password confirmation is required.',
240
- spreadMessagePriority: 4,
241
- required,
242
- }
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
- }
252
-
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
- }
267
-
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
- }
292
- }
293
- }
294
-
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
- },
307
- }
308
- await set('helperfooter', formname, jsonValue, 'client')
309
- console.log(
310
- `Stored helper footer for confirmPassword:`,
311
- message,
312
- `storeName: ${formname}`
313
- )
314
- }
315
-
316
- return message
317
- },
318
- []
319
- )
320
-
321
- const handlePhoneNumberErrorCreation = useCallback(
322
- async (
323
- formData: FormData,
324
- required: boolean,
325
- formname: string
326
- ): Promise<HelperFooterMessage | undefined> => {
327
- const phoneNumber = formData.get('phoneNumber') as string
328
- let message: HelperFooterMessage | undefined
329
-
330
- if (required && (!phoneNumber || !phoneNumber.trim())) {
331
- message = {
332
- status: 'error',
333
- statusMessage:
334
- 'Phone number is required. Please enter a phone number.',
335
- spreadMessage: 'Phone number is required.',
336
- spreadMessagePriority: 1,
337
- required,
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
- }
363
- }
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
- },
377
- }
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,
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
406
- }
407
-
408
- setHelperFooterValue({ ...helperFooterRef.current })
409
- },
410
- []
411
- )
412
-
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
-
437
- const validateField = useCallback(
438
- async (
439
- name: string,
440
- formData: FormData,
441
- label: string,
442
- required: boolean,
443
- formname: string
444
- ) => {
445
- console.log(`Validating field: ${name}`)
446
- let validationResult: HelperFooterMessage | undefined
447
-
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
- )
485
- }
486
-
487
- updateHelperFooter(name, validationResult)
488
- console.log(`Validation result for ${name}:`, validationResult)
489
- },
490
- [
491
- handleEmailErrorCreation,
492
- handlePasswordErrorCreation,
493
- handleConfirmPasswordErrorCreation,
494
- handlePhoneNumberErrorCreation,
495
- handleGenericErrorCreation,
496
- updateHelperFooter,
497
- ]
498
- )
499
-
500
- const validateRequiredField = useCallback(
501
- (required: boolean, formname: string, name: string, label: string) => {
502
- console.log(`Validating required field: ${name}`)
503
- if (required && formname && name && label) {
504
- const emptyFormData = new FormData()
505
- emptyFormData.append(name, '')
506
- validateField(name, emptyFormData, label, required, formname)
507
- }
508
- },
509
- [validateField]
510
- )
511
-
512
- const useShowErrorEffect = (
513
- formSubmitted: boolean,
514
- hasInput: boolean,
515
- isFocused: boolean
516
- ): boolean => {
517
- const [showError, setShowError] = useState<boolean>(false)
518
-
519
- useEffect(() => {
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
- }
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
-
561
- return useMemo(
562
- () => ({
563
- validateField,
564
- validateRequiredField,
565
- helperFooterValue,
566
- useShowErrorEffect,
567
- initializeRequiredFields,
568
- fetchHelperFooters,
569
- }),
570
- [
571
- validateField,
572
- validateRequiredField,
573
- helperFooterValue,
574
- initializeRequiredFields,
575
- fetchHelperFooters,
576
- ]
577
- )
578
- }
579
-
580
- export default useHelperFooter