goobs-frontend 0.7.67 → 0.7.69
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/package.json +14 -16
- package/src/app/_app.tsx +8 -8
- package/src/components/Button/index.tsx +95 -203
- package/src/components/ConfirmationCodeInput/index.tsx +4 -6
- package/src/components/Content/Structure/button/useButton.tsx +1 -35
- package/src/components/Content/Structure/datefield/useDateField.tsx +55 -0
- package/src/components/Content/Structure/dropdown/useDropdown.tsx +55 -0
- package/src/components/Content/Structure/incremementNumberField/useIncremementNumberField.tsx +65 -0
- package/src/components/Content/Structure/numberField/useNumberField.tsx +55 -0
- package/src/components/Content/Structure/passwordField/usePasswordField.tsx +57 -0
- package/src/components/Content/Structure/phoneNumber/usePhoneNumber.tsx +0 -0
- package/src/components/Content/Structure/qrcode/useQRCode.tsx +69 -0
- package/src/components/Content/Structure/searchbar/useSearchbar.tsx +55 -0
- package/src/components/Content/Structure/textfield/useTextField.tsx +84 -0
- package/src/components/Content/index.tsx +44 -7
- package/src/components/DateField/index.tsx +112 -0
- package/src/components/Dropdown/index.tsx +91 -0
- package/src/components/Form/Popup/index.tsx +1 -1
- package/src/components/IncrementNumberField/index.tsx +123 -0
- package/src/components/Nav/HorizontalVariant/index.tsx +18 -12
- package/src/components/Nav/VerticalVariant/index.tsx +14 -10
- package/src/components/NumberField/index.tsx +95 -0
- package/src/components/PasswordField/index.tsx +105 -0
- package/src/components/PhoneNumberField/index.tsx +102 -0
- package/src/components/PricingTable/index.tsx +10 -8
- package/src/components/QRCode/index.tsx +105 -0
- package/src/components/Searchbar/index.tsx +77 -0
- package/src/components/TextField/index.tsx +130 -0
- package/src/components/Toolbar/index.tsx +11 -10
- package/src/index.ts +54 -9
- package/src/components/Button/hook/useHelperFooter.tsx +0 -214
- package/src/components/Content/Structure/styledcomponent/useStyledComponent.tsx +0 -104
- package/src/components/StyledComponent/adornment/index.tsx +0 -125
- package/src/components/StyledComponent/hooks/useDropdown.tsx +0 -150
- package/src/components/StyledComponent/hooks/useInputHelperFooter.tsx +0 -524
- package/src/components/StyledComponent/hooks/usePhoneNumber.tsx +0 -99
- package/src/components/StyledComponent/hooks/useRequiredFieldsValidator.tsx +0 -190
- package/src/components/StyledComponent/hooks/useSearchbar.tsx +0 -46
- package/src/components/StyledComponent/hooks/useSplitButton.tsx +0 -70
- package/src/components/StyledComponent/index.tsx +0 -473
- package/src/components/StyledComponent/useCallbacks/index.tsx +0 -46
- package/src/styles/StyledComponent/Label/index.ts +0 -76
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { useCallback, useMemo, MutableRefObject, useRef } from 'react'
|
|
4
|
-
import { session } from 'goobs-cache'
|
|
5
|
-
import { StyledComponentProps } from '../index'
|
|
6
|
-
import { HelperFooterMessage } from './useInputHelperFooter'
|
|
7
|
-
import { ClientLogger } from 'goobs-testing'
|
|
8
|
-
|
|
9
|
-
type HelperFooterState = Record<string, HelperFooterMessage>
|
|
10
|
-
|
|
11
|
-
export const useRequiredFieldsValidator = (
|
|
12
|
-
formname: string,
|
|
13
|
-
components: StyledComponentProps[],
|
|
14
|
-
hasInputRef: MutableRefObject<boolean>,
|
|
15
|
-
helperFooterAtom: ReturnType<typeof session.atom<HelperFooterState>>
|
|
16
|
-
) => {
|
|
17
|
-
ClientLogger.debug('useRequiredFieldsValidator called', {
|
|
18
|
-
formname,
|
|
19
|
-
componentsCount: components.length,
|
|
20
|
-
hasInputRefCurrent: hasInputRef.current,
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
const [helperFooters, setHelperFooters] = session.useAtom(helperFooterAtom)
|
|
24
|
-
const failedAttempts = useRef<Record<string, number>>({})
|
|
25
|
-
|
|
26
|
-
const initializeComponentStatuses = useCallback(() => {
|
|
27
|
-
ClientLogger.debug('initializeComponentStatuses called')
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
const initialHelperFooters: HelperFooterState = {
|
|
31
|
-
...(helperFooters || {}),
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
components.forEach(component => {
|
|
35
|
-
if (
|
|
36
|
-
component.name &&
|
|
37
|
-
component.required &&
|
|
38
|
-
component.label &&
|
|
39
|
-
!initialHelperFooters[component.name]
|
|
40
|
-
) {
|
|
41
|
-
initialHelperFooters[component.name] = {
|
|
42
|
-
status: 'emptyAndRequired',
|
|
43
|
-
statusMessage: `${component.label} is required.`,
|
|
44
|
-
spreadMessage: `${component.label} is required.`,
|
|
45
|
-
spreadMessagePriority: component.spreadMessagePriority || 1,
|
|
46
|
-
required: true,
|
|
47
|
-
hasInput: false,
|
|
48
|
-
}
|
|
49
|
-
ClientLogger.debug(`Created new helper footer`, {
|
|
50
|
-
componentName: component.name,
|
|
51
|
-
helperFooter: initialHelperFooters[component.name],
|
|
52
|
-
})
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
ClientLogger.debug('Setting helper footers in session atom')
|
|
57
|
-
setHelperFooters(initialHelperFooters)
|
|
58
|
-
|
|
59
|
-
ClientLogger.debug(`Initialized helper footers`, { initialHelperFooters })
|
|
60
|
-
} catch (error) {
|
|
61
|
-
ClientLogger.error('Error in initializeComponentStatuses', { error })
|
|
62
|
-
}
|
|
63
|
-
}, [components, helperFooters, setHelperFooters])
|
|
64
|
-
|
|
65
|
-
const checkFormStatus = useCallback(() => {
|
|
66
|
-
ClientLogger.debug('checkFormStatus called')
|
|
67
|
-
try {
|
|
68
|
-
const requiredComponents = components.filter(
|
|
69
|
-
component => component.required
|
|
70
|
-
)
|
|
71
|
-
ClientLogger.debug('Required components', {
|
|
72
|
-
count: requiredComponents.length,
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
const allRequiredHaveInput = requiredComponents.every(
|
|
76
|
-
component =>
|
|
77
|
-
helperFooters[component.name || '']?.hasInput || hasInputRef.current
|
|
78
|
-
)
|
|
79
|
-
ClientLogger.debug('All required fields have input', {
|
|
80
|
-
allRequiredHaveInput,
|
|
81
|
-
})
|
|
82
|
-
return allRequiredHaveInput
|
|
83
|
-
} catch (error) {
|
|
84
|
-
ClientLogger.error('Error in checkFormStatus', { error })
|
|
85
|
-
return false
|
|
86
|
-
}
|
|
87
|
-
}, [components, hasInputRef, helperFooters])
|
|
88
|
-
|
|
89
|
-
const getEmptyRequiredFields = useCallback(() => {
|
|
90
|
-
ClientLogger.debug('getEmptyRequiredFields called')
|
|
91
|
-
|
|
92
|
-
try {
|
|
93
|
-
const emptyFields = Object.entries(helperFooters)
|
|
94
|
-
.filter(
|
|
95
|
-
([, value]) =>
|
|
96
|
-
value.required && !value.hasInput && !hasInputRef.current
|
|
97
|
-
)
|
|
98
|
-
.map(([key]) => key)
|
|
99
|
-
ClientLogger.debug('Empty required fields', { emptyFields })
|
|
100
|
-
return emptyFields
|
|
101
|
-
} catch (error) {
|
|
102
|
-
ClientLogger.error('Error in getEmptyRequiredFields', { error })
|
|
103
|
-
return []
|
|
104
|
-
}
|
|
105
|
-
}, [hasInputRef, helperFooters])
|
|
106
|
-
|
|
107
|
-
const validateRequiredField = useCallback(
|
|
108
|
-
(
|
|
109
|
-
name: string,
|
|
110
|
-
label: string,
|
|
111
|
-
required: boolean,
|
|
112
|
-
spreadMessagePriority: number
|
|
113
|
-
) => {
|
|
114
|
-
ClientLogger.debug('validateRequiredField called', {
|
|
115
|
-
name,
|
|
116
|
-
label,
|
|
117
|
-
required,
|
|
118
|
-
spreadMessagePriority,
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
if (failedAttempts.current[name] && failedAttempts.current[name] >= 3) {
|
|
123
|
-
ClientLogger.warn('Validation attempts exceeded for field', {
|
|
124
|
-
name,
|
|
125
|
-
attempts: failedAttempts.current[name],
|
|
126
|
-
})
|
|
127
|
-
return
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
required &&
|
|
132
|
-
!helperFooters[name]?.hasInput &&
|
|
133
|
-
!hasInputRef.current
|
|
134
|
-
) {
|
|
135
|
-
ClientLogger.debug(
|
|
136
|
-
`${name} is required and empty, updating helper footer`
|
|
137
|
-
)
|
|
138
|
-
const newHelperFooter: HelperFooterMessage = {
|
|
139
|
-
status: 'emptyAndRequired',
|
|
140
|
-
statusMessage: `${label} is required.`,
|
|
141
|
-
spreadMessage: `${label} is required.`,
|
|
142
|
-
spreadMessagePriority,
|
|
143
|
-
required: true,
|
|
144
|
-
hasInput: false,
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
setHelperFooters((prev: HelperFooterState) => ({
|
|
148
|
-
...prev,
|
|
149
|
-
[name]: newHelperFooter,
|
|
150
|
-
}))
|
|
151
|
-
|
|
152
|
-
ClientLogger.debug('Updated helperFooters', {
|
|
153
|
-
name,
|
|
154
|
-
newHelperFooter,
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
failedAttempts.current[name] = (failedAttempts.current[name] || 0) + 1
|
|
158
|
-
} else {
|
|
159
|
-
ClientLogger.debug(
|
|
160
|
-
`${name} validation not needed or already has input`
|
|
161
|
-
)
|
|
162
|
-
}
|
|
163
|
-
} catch (error) {
|
|
164
|
-
ClientLogger.error('Error in validateRequiredField', { error, name })
|
|
165
|
-
failedAttempts.current[name] = (failedAttempts.current[name] || 0) + 1
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
[hasInputRef, helperFooters, setHelperFooters]
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
const result = useMemo(
|
|
172
|
-
() => ({
|
|
173
|
-
checkFormStatus,
|
|
174
|
-
getEmptyRequiredFields,
|
|
175
|
-
validateRequiredField,
|
|
176
|
-
initializeComponentStatuses,
|
|
177
|
-
}),
|
|
178
|
-
[
|
|
179
|
-
checkFormStatus,
|
|
180
|
-
getEmptyRequiredFields,
|
|
181
|
-
validateRequiredField,
|
|
182
|
-
initializeComponentStatuses,
|
|
183
|
-
]
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
ClientLogger.debug('useRequiredFieldsValidator returning', { result })
|
|
187
|
-
return result
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export default useRequiredFieldsValidator
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { useState, useCallback } from 'react'
|
|
4
|
-
import React from 'react'
|
|
5
|
-
|
|
6
|
-
interface UseSearchbarProps {
|
|
7
|
-
options: readonly string[]
|
|
8
|
-
defaultValue?: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* useSearchbar hook provides functionality for handling searchbar input and filtering options.
|
|
13
|
-
* It maintains the input value state and filters options based on the search query.
|
|
14
|
-
* @param props The props for the useSearchbar hook.
|
|
15
|
-
* @returns An object containing the inputValue state, filteredOptions, and the handleOnChange function.
|
|
16
|
-
*/
|
|
17
|
-
export const useSearchbar = ({
|
|
18
|
-
options,
|
|
19
|
-
defaultValue = '',
|
|
20
|
-
}: UseSearchbarProps) => {
|
|
21
|
-
const [inputValue, setInputValue] = useState(defaultValue)
|
|
22
|
-
const [filteredOptions, setFilteredOptions] = useState(options)
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* handleOnChange function is called when the searchbar input value changes.
|
|
26
|
-
* It updates the inputValue state and filters the options based on the search query.
|
|
27
|
-
* @param event The change event triggered by the searchbar input.
|
|
28
|
-
*/
|
|
29
|
-
const handleOnChange = useCallback(
|
|
30
|
-
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
31
|
-
const searchQuery = event.target.value
|
|
32
|
-
setInputValue(searchQuery)
|
|
33
|
-
const newFilteredOptions = options.filter(option =>
|
|
34
|
-
option.toLowerCase().includes(searchQuery.toLowerCase())
|
|
35
|
-
)
|
|
36
|
-
setFilteredOptions(newFilteredOptions)
|
|
37
|
-
},
|
|
38
|
-
[options]
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
inputValue,
|
|
43
|
-
filteredOptions,
|
|
44
|
-
handleOnChange,
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { useState, useCallback } from 'react'
|
|
4
|
-
import { StyledComponentProps } from '../index'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* useSplitButton hook handles the state and logic for a split button component.
|
|
8
|
-
* @param props The props for the split button component.
|
|
9
|
-
* @returns An object containing the value and handlers for the split button.
|
|
10
|
-
*/
|
|
11
|
-
export const useSplitButton = (props: StyledComponentProps) => {
|
|
12
|
-
const [value, setValue] = useState(() => {
|
|
13
|
-
return props.value !== undefined ? props.value : '0'
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Increment the value by 1.
|
|
18
|
-
*/
|
|
19
|
-
const handleIncrement = useCallback(() => {
|
|
20
|
-
setValue(prev => {
|
|
21
|
-
const num = parseInt(prev)
|
|
22
|
-
if (isNaN(num)) {
|
|
23
|
-
return '0'
|
|
24
|
-
}
|
|
25
|
-
const newValue = num + 1
|
|
26
|
-
return newValue > 0 ? newValue.toString() : '0'
|
|
27
|
-
})
|
|
28
|
-
}, [])
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Decrement the value by 1.
|
|
32
|
-
*/
|
|
33
|
-
const handleDecrement = useCallback(() => {
|
|
34
|
-
setValue(prev => {
|
|
35
|
-
const num = parseInt(prev)
|
|
36
|
-
if (isNaN(num)) {
|
|
37
|
-
return '0'
|
|
38
|
-
}
|
|
39
|
-
const newValue = num - 1
|
|
40
|
-
return newValue >= 0 ? newValue.toString() : '0'
|
|
41
|
-
})
|
|
42
|
-
}, [])
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Update the value when the input value changes.
|
|
46
|
-
* @param newValue The new value from the input.
|
|
47
|
-
*/
|
|
48
|
-
const handleChange = useCallback((newValue: string) => {
|
|
49
|
-
const numValue = newValue.replace(/[^0-9]/g, '')
|
|
50
|
-
setValue(numValue === '' ? '0' : numValue)
|
|
51
|
-
}, [])
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Update the value state when the value prop changes.
|
|
55
|
-
* This function replaces the useEffect from the original implementation.
|
|
56
|
-
*/
|
|
57
|
-
const updateValueFromProps = useCallback(() => {
|
|
58
|
-
if (props.value !== undefined) {
|
|
59
|
-
setValue(props.value)
|
|
60
|
-
}
|
|
61
|
-
}, [props.value])
|
|
62
|
-
|
|
63
|
-
return {
|
|
64
|
-
value,
|
|
65
|
-
handleIncrement,
|
|
66
|
-
handleDecrement,
|
|
67
|
-
handleChange,
|
|
68
|
-
updateValueFromProps,
|
|
69
|
-
}
|
|
70
|
-
}
|