goobs-frontend 0.8.11 → 0.8.13

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,5 +1,4 @@
1
1
  'use client'
2
-
3
2
  import React, { useState, useCallback } from 'react'
4
3
  import {
5
4
  Drawer,
@@ -36,6 +35,11 @@ export interface VerticalVariantProps {
36
35
  backgroundcolor?: string
37
36
  shrunkfontcolor?: string
38
37
  unshrunkfontcolor?: string
38
+ titleUrl?: string
39
+ mobileOpen?: boolean
40
+ onClose?: () => void
41
+ variant?: 'temporary' | 'permanent'
42
+ spacingfromtopofscreen?: string
39
43
  }
40
44
 
41
45
  function VerticalVariant({
@@ -54,6 +58,11 @@ function VerticalVariant({
54
58
  backgroundcolor,
55
59
  shrunkfontcolor = white.main,
56
60
  unshrunkfontcolor = white.main,
61
+ titleUrl = '/',
62
+ mobileOpen = false,
63
+ onClose,
64
+ variant = 'permanent',
65
+ spacingfromtopofscreen = '0px',
57
66
  }: VerticalVariantProps) {
58
67
  const router = useRouter()
59
68
  const [selectedNav, setSelectedNav] = useState<string | null>(null)
@@ -68,17 +77,22 @@ function VerticalVariant({
68
77
  if (nav.trigger === 'route') {
69
78
  if (nav.route) {
70
79
  router.push(nav.route)
80
+ if (variant === 'temporary' && onClose) {
81
+ onClose()
82
+ }
71
83
  }
72
84
  } else if (nav.trigger === 'onClick') {
73
85
  if (nav.onClick) {
74
86
  nav.onClick()
87
+ if (variant === 'temporary' && onClose) {
88
+ onClose()
89
+ }
75
90
  }
76
91
  }
77
92
  },
78
- [router]
93
+ [router, variant, onClose]
79
94
  )
80
95
 
81
- // Adjusted handler to match the SearchableDropdown onChange signature
82
96
  const handleSearchableNavChange = useCallback(
83
97
  (newValue: { value: string } | null) => {
84
98
  const newVal = newValue ? newValue.value : null
@@ -297,6 +311,7 @@ function VerticalVariant({
297
311
  color: 'white',
298
312
  }}
299
313
  href={view.route ?? ''}
314
+ onClick={variant === 'temporary' ? onClose : undefined}
300
315
  >
301
316
  <MenuItem
302
317
  sx={{
@@ -327,35 +342,21 @@ function VerticalVariant({
327
342
  expandedSubnavs,
328
343
  setExpandedSubnavs,
329
344
  handleNavClick,
345
+ variant,
346
+ onClose,
330
347
  ]
331
348
  )
332
349
 
333
- return (
334
- <Drawer
335
- variant="permanent"
336
- anchor={anchor}
337
- elevation={0}
338
- sx={{
339
- width: verticalNavWidth,
340
- height: '100%',
341
- flexShrink: 0,
342
- '& .MuiDrawer-paper': {
343
- width: verticalNavWidth,
344
- border: 0,
345
- zIndex: theme => theme.zIndex.drawer - 1,
346
- backgroundColor: ocean.main,
347
- pt: '17px',
348
- boxSizing: 'border-box',
349
- },
350
- }}
351
- >
350
+ const drawerContent = (
351
+ <>
352
352
  <Box px={`15px`}>
353
353
  {showTitle && (
354
354
  <Box pt="0px" pb="0px">
355
355
  <Link
356
- href="/dashboard/"
356
+ href={titleUrl || '/'}
357
357
  passHref
358
358
  style={{ textDecoration: 'none' }}
359
+ onClick={variant === 'temporary' ? onClose : undefined}
359
360
  >
360
361
  <Typography
361
362
  fontvariant="merrih4"
@@ -366,7 +367,7 @@ function VerticalVariant({
366
367
  </Box>
367
368
  )}
368
369
  {showSearchableNav && (
369
- <Stack mt={0} spacing={0}>
370
+ <Stack mt={{ xs: '10px', md: '10px', lg: 0 }} spacing={0}>
370
371
  <Box
371
372
  sx={{
372
373
  position: 'relative',
@@ -408,6 +409,35 @@ function VerticalVariant({
408
409
  )
409
410
  .map(item => renderItem(item, 0))
410
411
  : items.map(item => renderItem(item, 0))}
412
+ </>
413
+ )
414
+
415
+ return (
416
+ <Drawer
417
+ variant={variant}
418
+ anchor={anchor}
419
+ open={variant === 'temporary' ? mobileOpen : true}
420
+ onClose={onClose}
421
+ elevation={0}
422
+ sx={{
423
+ width: variant === 'permanent' ? verticalNavWidth : 'auto',
424
+ height: '100%',
425
+ flexShrink: 0,
426
+ '& .MuiDrawer-paper': {
427
+ width: verticalNavWidth,
428
+ border: 0,
429
+ zIndex: theme =>
430
+ variant === 'temporary'
431
+ ? theme.zIndex.drawer + 2
432
+ : theme.zIndex.drawer - 1,
433
+ backgroundColor: ocean.main,
434
+ pt: '17px',
435
+ boxSizing: 'border-box',
436
+ marginTop: spacingfromtopofscreen,
437
+ },
438
+ }}
439
+ >
440
+ {drawerContent}
411
441
  </Drawer>
412
442
  )
413
443
  }
@@ -32,6 +32,11 @@ export interface NavProps {
32
32
  backgroundcolor?: string
33
33
  shrunkfontcolor?: string // Color of the label when shrunk
34
34
  unshrunkfontcolor?: string // Color of the label when not shrunk
35
+ titleUrl?: string // Changed from url to titleUrl
36
+ mobileOpen?: boolean // Controls mobile drawer open state
37
+ onClose?: () => void // Handler for closing mobile drawer
38
+ variant?: 'temporary' | 'permanent' // Drawer variant for mobile/desktop
39
+ spacingfromtopofscreen?: string // Spacing from top of screen
35
40
  }
36
41
 
37
42
  /**
@@ -75,6 +80,11 @@ function Nav({
75
80
  shrunkfontcolor = 'black',
76
81
  unshrunkfontcolor = 'black',
77
82
  backgroundcolor,
83
+ titleUrl, // Changed from url to titleUrl
84
+ mobileOpen = false,
85
+ onClose,
86
+ variant = 'permanent',
87
+ spacingfromtopofscreen,
78
88
  }: NavProps): JSX.Element {
79
89
  // State for expanded navigation items
80
90
  const [expandedNavs, setExpandedNavs] = useState<string[]>([])
@@ -116,7 +126,12 @@ function Nav({
116
126
  verticalNavWidth={`${verticalNavWidth}px`}
117
127
  shrunkfontcolor={shrunkfontcolor}
118
128
  unshrunkfontcolor={unshrunkfontcolor}
119
- backgroundcolor={backgroundcolor} // Pass backgroundcolor to VerticalVariant
129
+ backgroundcolor={backgroundcolor}
130
+ titleUrl={titleUrl}
131
+ mobileOpen={mobileOpen}
132
+ onClose={onClose}
133
+ variant={variant}
134
+ spacingfromtopofscreen={spacingfromtopofscreen}
120
135
  />
121
136
  )
122
137
  } else {
@@ -1,9 +1,15 @@
1
1
  'use client'
2
- import React, { useCallback, useMemo, useState } from 'react'
3
- import { Box, TextField as MuiTextField, TextFieldProps } from '@mui/material'
2
+ import React, { useCallback, useState, useMemo } from 'react'
3
+ import { Box } from '@mui/material'
4
+ import TextField, { TextFieldProps } from '../TextField'
5
+
6
+ const formatPhoneNumber = (inputValue: string): string => {
7
+ let digits = inputValue.replace(/\D/g, '')
8
+ // If it starts with '1', remove it because we already provide '+1'
9
+ if (digits.startsWith('1')) {
10
+ digits = digits.slice(1)
11
+ }
4
12
 
5
- const formatPhoneNumber = (value: string): string => {
6
- const digits = value.replace(/\D/g, '')
7
13
  const limitedDigits = digits.slice(0, 10)
8
14
  let formattedNumber = '+1 '
9
15
  if (limitedDigits.length > 0) {
@@ -39,10 +45,17 @@ const PhoneNumberField: React.FC<TextFieldProps> = React.memo(props => {
39
45
  (e: React.ChangeEvent<HTMLInputElement>) => {
40
46
  const input = e.target.value
41
47
  let strippedInput = input.replace(/^\+1\s?/, '').replace(/\D/g, '')
48
+
49
+ // Remove leading '1' if present
50
+ if (strippedInput.startsWith('1')) {
51
+ strippedInput = strippedInput.slice(1)
52
+ }
53
+
42
54
  strippedInput = strippedInput.slice(0, 10)
43
55
  const formattedValue =
44
56
  strippedInput.length > 0 ? formatPhoneNumber(strippedInput) : '+1 '
45
57
  setPhoneNumber(formattedValue)
58
+
46
59
  if (onChange) {
47
60
  onChange(e)
48
61
  }
@@ -72,24 +85,30 @@ const PhoneNumberField: React.FC<TextFieldProps> = React.memo(props => {
72
85
  e.preventDefault()
73
86
  }, [])
74
87
 
75
- const inputProps = useMemo(
76
- () => ({
77
- style: {
78
- height: '40px',
79
- padding: '8px 14px',
88
+ const mergedSlotProps = useMemo(() => {
89
+ return {
90
+ input: {
91
+ sx: {
92
+ height: '40px',
93
+ padding: '8px 0px',
94
+ },
80
95
  },
81
- }),
82
- []
83
- )
84
-
85
- const InputProps = useMemo(
86
- () => ({
87
- style: {
88
- height: '45px',
96
+ inputLabel: {
97
+ sx: {
98
+ '&.MuiInputLabel-shrink': {
99
+ top: '0px',
100
+ left: '0px',
101
+ },
102
+ '&:not(.MuiInputLabel-shrink)': {
103
+ transform: 'scale(1)',
104
+ transformOrigin: 'top left',
105
+ top: '9px',
106
+ left: '12px',
107
+ },
108
+ },
89
109
  },
90
- }),
91
- []
92
- )
110
+ }
111
+ }, [])
93
112
 
94
113
  return (
95
114
  <Box
@@ -98,12 +117,10 @@ const PhoneNumberField: React.FC<TextFieldProps> = React.memo(props => {
98
117
  flexDirection: 'column',
99
118
  justifyContent: 'center',
100
119
  width: '100%',
101
- marginTop: '5px',
102
- height: '70px',
103
120
  }}
104
121
  onClick={handleClick}
105
122
  >
106
- <MuiTextField
123
+ <TextField
107
124
  name={name}
108
125
  label={label}
109
126
  placeholder={placeholder}
@@ -114,8 +131,7 @@ const PhoneNumberField: React.FC<TextFieldProps> = React.memo(props => {
114
131
  error={error}
115
132
  fullWidth
116
133
  variant="outlined"
117
- inputProps={inputProps}
118
- InputProps={InputProps}
134
+ slotProps={mergedSlotProps}
119
135
  {...restProps}
120
136
  />
121
137
  </Box>
@@ -2,13 +2,16 @@ import { PricingProps } from './index'
2
2
 
3
3
  /**
4
4
  * Default configuration for the PricingTable component
5
+ *
6
+ * All margin and padding values are now defined as ResponsiveObject<number> directly
7
+ * in the columnconfig, allowing you to edit each breakpoint value individually.
5
8
  */
9
+
6
10
  const defaultConfig: PricingProps = {
7
11
  // Configuration for the header grid
8
12
  headerGridConfig: {
9
13
  gridname: 'pricingtableheader',
10
14
  alignment: 'center' as const,
11
- margintop: 1,
12
15
  gridwidth: '100%',
13
16
  },
14
17
  // Configuration for the table title
@@ -19,11 +22,27 @@ const defaultConfig: PricingProps = {
19
22
  column: 1,
20
23
  gridname: 'pricingtableheader',
21
24
  alignment: 'left' as const,
22
- marginleft: 3,
23
- marginbottom: 1,
25
+ paddingleft: {
26
+ xs: 2,
27
+ sm: 2,
28
+ md: 2,
29
+ ms: 2,
30
+ ml: 2,
31
+ lg: 2,
32
+ xl: 2,
33
+ },
34
+ paddingtop: {
35
+ xs: 1,
36
+ sm: 1,
37
+ md: 1,
38
+ ms: 1,
39
+ ml: 1,
40
+ lg: 1,
41
+ xl: 1,
42
+ },
24
43
  mobilewidth: '100%',
25
44
  tabletwidth: '100%',
26
- computerwidth: '100%',
45
+ computerwidth: '50%',
27
46
  },
28
47
  },
29
48
  // Configuration for package columns
@@ -31,10 +50,46 @@ const defaultConfig: PricingProps = {
31
50
  packagenames: ['ThothOS', 'ThothOS Pro', 'ThothOS Enterprise'],
32
51
  columnconfig: {
33
52
  row: 1,
34
- column: 2,
53
+ column: 1,
35
54
  gridname: 'pricingtableheader',
36
55
  alignment: 'center' as const,
37
- mobilewidth: '80%',
56
+ paddingleft: {
57
+ xs: 2,
58
+ sm: 2,
59
+ md: 2,
60
+ ms: 2,
61
+ ml: 2,
62
+ lg: 2,
63
+ xl: 2,
64
+ },
65
+ paddingright: {
66
+ xs: 2,
67
+ sm: 2,
68
+ md: 2,
69
+ ms: 2,
70
+ ml: 2,
71
+ lg: 2,
72
+ xl: 2,
73
+ },
74
+ paddingtop: {
75
+ xs: 2.5,
76
+ sm: 2.5,
77
+ md: 2.5,
78
+ ms: 2.5,
79
+ ml: 2.5,
80
+ lg: 2.5,
81
+ xl: 2.5,
82
+ },
83
+ paddingbottom: {
84
+ xs: 1,
85
+ sm: 2,
86
+ md: 2,
87
+ ms: 2,
88
+ ml: 2,
89
+ lg: 2,
90
+ xl: 2,
91
+ },
92
+ mobilewidth: '100%',
38
93
  tabletwidth: '48%',
39
94
  computerwidth: '48%',
40
95
  },
@@ -250,10 +305,35 @@ const defaultConfig: PricingProps = {
250
305
  ],
251
306
  columnconfig: {
252
307
  row: 7,
253
- column: 2,
308
+ column: 1,
254
309
  mobilewidth: '100%',
255
- marginbottom: 1,
256
- marginright: 1,
310
+ marginbottom: {
311
+ xs: 1,
312
+ sm: 1,
313
+ md: 1,
314
+ ms: 1,
315
+ ml: 1,
316
+ lg: 1,
317
+ xl: 1,
318
+ },
319
+ marginright: {
320
+ xs: 1,
321
+ sm: 1,
322
+ md: 1,
323
+ ms: 1,
324
+ ml: 1,
325
+ lg: 1,
326
+ xl: 1,
327
+ },
328
+ marginleft: {
329
+ xs: 1,
330
+ sm: 1,
331
+ md: 1,
332
+ ms: 1,
333
+ ml: 1,
334
+ lg: 1,
335
+ xl: 1,
336
+ },
257
337
  tabletwidth: '100%',
258
338
  computerwidth: '48%',
259
339
  gridname: 'pricingtablefeatures',
@@ -129,6 +129,9 @@ const PricingTable: React.FC<PricingProps> = props => {
129
129
  if (config.packagecolumns && config.packagecolumns.columnconfig) {
130
130
  headerColumnConfigs.push({
131
131
  ...config.packagecolumns.columnconfig,
132
+ // Add 5px margin above (margintop: 0.625) and to the right (marginright: 0.625)
133
+ margintop: 1,
134
+ marginright: 0.625,
132
135
  component: (
133
136
  <Dropdown
134
137
  label="Packages"
@@ -138,6 +141,7 @@ const PricingTable: React.FC<PricingProps> = props => {
138
141
  }))}
139
142
  defaultValue={selectedPackage}
140
143
  backgroundcolor={semiTransparentBlack.main}
144
+ shrunklabelposition="aboveNotch"
141
145
  outlinecolor={black.main}
142
146
  fontcolor={black.main}
143
147
  shrunkfontcolor={black.main}
@@ -177,6 +181,8 @@ const PricingTable: React.FC<PricingProps> = props => {
177
181
  if (feature.columnconfig) {
178
182
  featureColumnConfigs.push({
179
183
  ...feature.columnconfig,
184
+ margintop: 1,
185
+ paddingleft: 2,
180
186
  component: (
181
187
  <Box display="flex" alignItems="center">
182
188
  <Typography
@@ -207,6 +213,7 @@ const PricingTable: React.FC<PricingProps> = props => {
207
213
  if (feature.tiedtopackage && feature.tiedtopackage.columnconfig) {
208
214
  const tiedConfig: columnconfig = {
209
215
  ...feature.tiedtopackage.columnconfig,
216
+ margintop: 1,
210
217
  cellconfig: {
211
218
  minHeight: '40px',
212
219
  },
@@ -225,6 +232,8 @@ const PricingTable: React.FC<PricingProps> = props => {
225
232
  if (subFeature.columnconfig) {
226
233
  featureColumnConfigs.push({
227
234
  ...subFeature.columnconfig,
235
+ margintop: 1,
236
+ paddingleft: 3,
228
237
  component: (
229
238
  <Box display="flex" alignItems="center">
230
239
  <Typography
@@ -255,6 +264,7 @@ const PricingTable: React.FC<PricingProps> = props => {
255
264
  if (subFeature.tiedtopackage && subFeature.tiedtopackage.columnconfig) {
256
265
  const tiedConfig: columnconfig = {
257
266
  ...subFeature.tiedtopackage.columnconfig,
267
+ margintop: 1,
258
268
  cellconfig: {
259
269
  minHeight: '40px',
260
270
  },
@@ -279,6 +289,7 @@ const PricingTable: React.FC<PricingProps> = props => {
279
289
 
280
290
  featureColumnConfigs.push({
281
291
  ...config.buttoncolumns.columnconfig,
292
+ margintop: 1,
282
293
  component: (
283
294
  <CustomButton
284
295
  variant="contained"
@@ -31,40 +31,115 @@ export type TextFieldProps = (
31
31
  left?: number
32
32
  }
33
33
  backgroundcolor?: string
34
+ outlinecolor?: string
35
+ fontcolor?: string
36
+ inputfontcolor?: string
37
+ shrunkfontcolor?: string
38
+ unshrunkfontcolor?: string
39
+ placeholdercolor?: string
40
+ shrunklabelposition?: 'onNotch' | 'aboveNotch'
34
41
  sx?: MuiTextFieldProps['sx']
35
42
  slotProps?: MuiTextFieldProps['slotProps']
36
43
  }
37
44
 
38
- const StyledMuiTextField = styled(MuiTextField)<{
45
+ interface StyledTextFieldProps {
39
46
  hasvalue: string
40
47
  textalign?: string
41
48
  paddingleft?: number
42
49
  paddingtop?: number
43
- }>(({ hasvalue, textalign = 'left' }) => ({
44
- '& .MuiOutlinedInput-root': {
45
- minHeight: '40px',
46
- height: '40px',
47
- '& fieldset': {
48
- borderColor: hasvalue === 'true' ? 'black' : 'rgba(0, 0, 0, 0.23)',
49
- },
50
- '&:hover fieldset': {
51
- borderColor: hasvalue === 'true' ? 'black' : 'rgba(0, 0, 0, 0.23)',
50
+ backgroundcolor?: string
51
+ outlinecolor?: string
52
+ fontcolor?: string
53
+ inputfontcolor?: string
54
+ shrunkfontcolor?: string
55
+ unshrunkfontcolor?: string
56
+ placeholdercolor?: string
57
+ shrunklabelposition?: 'onNotch' | 'aboveNotch'
58
+ }
59
+
60
+ const StyledMuiTextField = styled(MuiTextField, {
61
+ shouldForwardProp: prop =>
62
+ ![
63
+ 'hasvalue',
64
+ 'textalign',
65
+ 'paddingleft',
66
+ 'paddingtop',
67
+ 'backgroundcolor',
68
+ 'outlinecolor',
69
+ 'fontcolor',
70
+ 'inputfontcolor',
71
+ 'shrunkfontcolor',
72
+ 'unshrunkfontcolor',
73
+ 'placeholdercolor',
74
+ 'shrunklabelposition',
75
+ ].includes(prop as string),
76
+ })<StyledTextFieldProps>(
77
+ ({
78
+ hasvalue,
79
+ textalign = 'left',
80
+ backgroundcolor,
81
+ outlinecolor,
82
+ fontcolor,
83
+ inputfontcolor,
84
+ shrunkfontcolor,
85
+ unshrunkfontcolor,
86
+ placeholdercolor,
87
+ shrunklabelposition,
88
+ }) => ({
89
+ '& .MuiOutlinedInput-root': {
90
+ minHeight: '40px',
91
+ height: '40px',
92
+ backgroundColor: backgroundcolor || 'inherit',
93
+ color: fontcolor || 'black',
94
+ '& fieldset': {
95
+ borderColor:
96
+ outlinecolor ||
97
+ (hasvalue === 'true' ? 'black' : 'rgba(0, 0, 0, 0.23)'),
98
+ ...(shrunklabelposition === 'aboveNotch' && {
99
+ legend: {
100
+ width: '0px !important',
101
+ },
102
+ }),
103
+ },
104
+ '&:hover fieldset': {
105
+ borderColor:
106
+ outlinecolor ||
107
+ (hasvalue === 'true' ? 'black' : 'rgba(0, 0, 0, 0.23)'),
108
+ },
109
+ '&.Mui-focused fieldset': {
110
+ borderColor:
111
+ outlinecolor ||
112
+ (hasvalue === 'true' ? 'black' : 'rgba(0, 0, 0, 0.23)'),
113
+ },
114
+ '& input': {
115
+ color: inputfontcolor || fontcolor || 'black',
116
+ '&::placeholder': {
117
+ color: placeholdercolor || 'rgba(0, 0, 0, 0.54)',
118
+ opacity: 1,
119
+ },
120
+ },
52
121
  },
53
- '&.Mui-focused fieldset': {
54
- borderColor: hasvalue === 'true' ? 'black' : 'rgba(0, 0, 0, 0.23)',
122
+ '& .MuiInputLabel-root': {
123
+ color: unshrunkfontcolor || 'black',
124
+ '&.Mui-focused': {
125
+ color: shrunkfontcolor || 'black',
126
+ },
127
+ '&.MuiInputLabel-shrink': {
128
+ color: shrunkfontcolor || 'black',
129
+ ...(shrunklabelposition === 'aboveNotch' && {
130
+ transform: 'translate(0px, -17px) scale(0.75)',
131
+ }),
132
+ ...(shrunklabelposition === 'onNotch' && {
133
+ transform: 'translate(13px, -4px) scale(0.75)',
134
+ }),
135
+ },
55
136
  },
56
- },
57
- '& .MuiInputLabel-root': {
58
- color: 'black',
59
- '&.Mui-focused': {
60
- color: 'black',
137
+ '& .MuiOutlinedInput-input': {
138
+ padding: '8px 14px',
139
+ textAlign: textalign,
61
140
  },
62
- },
63
- '& .MuiOutlinedInput-input': {
64
- padding: '8px 14px',
65
- textAlign: textalign,
66
- },
67
- }))
141
+ })
142
+ )
68
143
 
69
144
  const TextField = React.memo<TextFieldProps>(props => {
70
145
  const {
@@ -81,6 +156,13 @@ const TextField = React.memo<TextFieldProps>(props => {
81
156
  textAlign = 'left',
82
157
  slotProps: customSlotProps = {},
83
158
  backgroundcolor,
159
+ outlinecolor,
160
+ fontcolor,
161
+ inputfontcolor,
162
+ shrunkfontcolor,
163
+ unshrunkfontcolor,
164
+ placeholdercolor,
165
+ shrunklabelposition,
84
166
  ...restProps
85
167
  } = props
86
168
 
@@ -193,6 +275,14 @@ const TextField = React.memo<TextFieldProps>(props => {
193
275
  variant="outlined"
194
276
  hasvalue={hasValue}
195
277
  textalign={textAlign}
278
+ backgroundcolor={backgroundcolor}
279
+ outlinecolor={outlinecolor}
280
+ fontcolor={fontcolor}
281
+ inputfontcolor={inputfontcolor}
282
+ shrunkfontcolor={shrunkfontcolor}
283
+ unshrunkfontcolor={unshrunkfontcolor}
284
+ placeholdercolor={placeholdercolor}
285
+ shrunklabelposition={shrunklabelposition}
196
286
  {...restProps}
197
287
  />
198
288
  </Box>