@dashadmin/dash-admin 1.3.51 → 1.3.52
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/components/avatar/Avatar.js +10 -1
- package/dist/components/currency/Format.js +3 -1
- package/dist/components/i18n/BridgedLocalesMenuButton.js +4 -2
- package/dist/components/misc/NoResults.js +3 -1
- package/dist/components/permission/PermissionsSelector.js +34 -14
- package/dist/components/permission/PermissionsSelectorList.js +11 -1
- package/dist/components/selects/RASearchableSelect.js +8 -6
- package/dist/components/selects/RASearchableSelectChips.js +8 -6
- package/dist/components/selects/SearchableSelect.js +8 -6
- package/dist/components/subscription/PlanAddonsSettings.js +88 -17
- package/dist/components/subscription/PlanAuditLog.js +41 -21
- package/dist/components/subscription/PlanFeaturesSettings.js +35 -6
- package/dist/components/subscription/PlanMetadataSettings.js +78 -42
- package/dist/components/subscription/PlanPricesSettings.js +20 -8
- package/dist/components/tenant/TenantSelector.js +8 -6
- package/dist/components/user/UserPreferences.js +77 -22
- package/dist/pages/DASHLightWeightLogin.js +7 -5
- package/dist/pages/Profile.js +5 -3
- package/dist/pages/RecoverPassword.js +28 -14
- package/dist/schemas/subscription/components/SubscriptionPaymentHistory.js +14 -2
- package/dist/schemas/subscription/components/SubscriptionPlanFeatures.js +37 -25
- package/dist/schemas/subscription/components/SubscriptionPlanPreview.js +47 -28
- package/dist/schemas/subscription/components/SubscriptionPlanStats.js +127 -37
- package/package.json +3 -3
- package/src/components/avatar/Avatar.tsx +8 -4
- package/src/components/currency/Format.tsx +8 -6
- package/src/components/i18n/BridgedLocalesMenuButton.tsx +4 -2
- package/src/components/misc/DASHGlobalErrorHandler.tsx +1 -1
- package/src/components/misc/NoResults.tsx +7 -4
- package/src/components/permission/AvailablePermissionsContext.tsx +1 -1
- package/src/components/permission/PermissionsSelector.tsx +48 -33
- package/src/components/permission/PermissionsSelectorList.tsx +7 -2
- package/src/components/selects/RASearchableSelect.tsx +22 -19
- package/src/components/selects/RASearchableSelectChips.tsx +23 -19
- package/src/components/selects/SearchableSelect.tsx +22 -18
- package/src/components/subscription/PlanAddonsSettings.tsx +61 -20
- package/src/components/subscription/PlanAuditLog.tsx +22 -8
- package/src/components/subscription/PlanFeaturesSettings.tsx +28 -8
- package/src/components/subscription/PlanMetadataSettings.tsx +29 -7
- package/src/components/subscription/PlanPricesSettings.tsx +30 -18
- package/src/components/tenant/TenantAttributesContext.tsx +1 -1
- package/src/components/tenant/TenantSelector.tsx +20 -17
- package/src/components/tenant/TenantSettingsContext.tsx +1 -1
- package/src/components/user/UserPreferences.tsx +56 -21
- package/src/contexts/SystemRequestsCache.tsx +1 -1
- package/src/default-theme/menu/AppMenuComponents/expanded/CollapsableSidebarMenu.tsx +3 -3
- package/src/default-theme/menu/SidebarActions.tsx +6 -6
- package/src/pages/DASHLightWeightLogin.tsx +8 -7
- package/src/pages/Profile.tsx +10 -9
- package/src/pages/RecoverPassword.tsx +15 -6
- package/src/schemas/subscription/components/SubscriptionPaymentHistory.tsx +9 -2
- package/src/schemas/subscription/components/SubscriptionPlanFeatures.tsx +10 -3
- package/src/schemas/subscription/components/SubscriptionPlanPreview.tsx +25 -12
- package/src/schemas/subscription/components/SubscriptionPlanStats.tsx +64 -14
- package/src/theme/AppSidebarLogo.tsx +7 -7
|
@@ -71,7 +71,7 @@ export const TenantAttributesFormatsProvider: React.FC<{children: React.ReactNod
|
|
|
71
71
|
if (!LAST_FETCH_TIME) {
|
|
72
72
|
try {
|
|
73
73
|
// Try to get last fetch time from IndexedDB
|
|
74
|
-
LAST_FETCH_TIME = await idbGet("tenant_attributes_cache") || 0;
|
|
74
|
+
LAST_FETCH_TIME = (await idbGet("tenant_attributes_cache")) || 0;
|
|
75
75
|
} catch (error) {
|
|
76
76
|
console.error("Error reading from IndexedDB:", error);
|
|
77
77
|
}
|
|
@@ -77,9 +77,8 @@ const TenantSelector = React.forwardRef<
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
return (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
<Autocomplete
|
|
80
|
+
<>Cliente impersonado: {selectedTenantInput}
|
|
81
|
+
<Autocomplete
|
|
83
82
|
fullWidth
|
|
84
83
|
loading={isLoading && open}
|
|
85
84
|
sx={{ width: 300 }}
|
|
@@ -117,23 +116,27 @@ const TenantSelector = React.forwardRef<
|
|
|
117
116
|
handleSearch(ev.target.value);
|
|
118
117
|
}
|
|
119
118
|
}}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
119
|
+
slotProps={{
|
|
120
|
+
...params.slotProps,
|
|
121
|
+
|
|
122
|
+
input: {
|
|
123
|
+
...params.slotProps.input,
|
|
124
|
+
autoComplete: 'new-password',
|
|
125
|
+
endAdornment: (
|
|
126
|
+
<>
|
|
127
|
+
{isLoading ? (
|
|
128
|
+
<CircularProgress color='inherit' size={20} />
|
|
129
|
+
) : null}
|
|
130
|
+
{params.slotProps.input.endAdornment}
|
|
131
|
+
</>
|
|
132
|
+
),
|
|
133
|
+
}
|
|
134
|
+
}}
|
|
132
135
|
/>
|
|
133
136
|
)}
|
|
134
137
|
/>
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
</>
|
|
139
|
+
);
|
|
137
140
|
});
|
|
138
141
|
|
|
139
142
|
export default TenantSelector;
|
|
@@ -71,7 +71,7 @@ export const TenantSettingsFormatsProvider: React.FC<{children: React.ReactNode}
|
|
|
71
71
|
if (!LAST_FETCH_TIME) {
|
|
72
72
|
try {
|
|
73
73
|
// Try to get last fetch time from IndexedDB
|
|
74
|
-
LAST_FETCH_TIME = await idbGet("tenant_settings_cache") || 0;
|
|
74
|
+
LAST_FETCH_TIME = (await idbGet("tenant_settings_cache")) || 0;
|
|
75
75
|
} catch (error) {
|
|
76
76
|
console.error("Error reading from IndexedDB:", error);
|
|
77
77
|
}
|
|
@@ -332,7 +332,9 @@ const UserPreferences: React.FC = () => {
|
|
|
332
332
|
<Box>
|
|
333
333
|
<Typography variant="subtitle1">{format.label}</Typography>
|
|
334
334
|
{format.description && (
|
|
335
|
-
<Typography variant="caption"
|
|
335
|
+
<Typography variant="caption" sx={{
|
|
336
|
+
color: "text.secondary"
|
|
337
|
+
}}>
|
|
336
338
|
{format.description}
|
|
337
339
|
</Typography>
|
|
338
340
|
)}
|
|
@@ -352,7 +354,13 @@ const UserPreferences: React.FC = () => {
|
|
|
352
354
|
<CardContent>
|
|
353
355
|
<Typography variant="subtitle1" gutterBottom>{format.label}</Typography>
|
|
354
356
|
{format.description && (
|
|
355
|
-
<Typography
|
|
357
|
+
<Typography
|
|
358
|
+
variant="caption"
|
|
359
|
+
sx={{
|
|
360
|
+
color: "text.secondary",
|
|
361
|
+
display: "block",
|
|
362
|
+
mb: 2
|
|
363
|
+
}}>
|
|
356
364
|
{format.description}
|
|
357
365
|
</Typography>
|
|
358
366
|
)}
|
|
@@ -371,12 +379,14 @@ const UserPreferences: React.FC = () => {
|
|
|
371
379
|
value={value ?? format.default_value ?? 0}
|
|
372
380
|
onChange={(e) => handleGenericPreferenceChange(format.id, parseInt(e.target.value, 10))}
|
|
373
381
|
disabled={saving || !format.editable}
|
|
374
|
-
inputProps={{
|
|
375
|
-
min: format.min ?? 0,
|
|
376
|
-
max: format.max ?? 100,
|
|
377
|
-
}}
|
|
378
382
|
sx={{ width: 80 }}
|
|
379
383
|
size="small"
|
|
384
|
+
slotProps={{
|
|
385
|
+
htmlInput: {
|
|
386
|
+
min: format.min ?? 0,
|
|
387
|
+
max: format.max ?? 100,
|
|
388
|
+
}
|
|
389
|
+
}}
|
|
380
390
|
/>
|
|
381
391
|
</Box>
|
|
382
392
|
</CardContent>
|
|
@@ -389,7 +399,13 @@ const UserPreferences: React.FC = () => {
|
|
|
389
399
|
<CardContent>
|
|
390
400
|
<Typography variant="subtitle1" gutterBottom>{format.label}</Typography>
|
|
391
401
|
{format.description && (
|
|
392
|
-
<Typography
|
|
402
|
+
<Typography
|
|
403
|
+
variant="caption"
|
|
404
|
+
sx={{
|
|
405
|
+
color: "text.secondary",
|
|
406
|
+
display: "block",
|
|
407
|
+
mb: 2
|
|
408
|
+
}}>
|
|
393
409
|
{format.description}
|
|
394
410
|
</Typography>
|
|
395
411
|
)}
|
|
@@ -398,15 +414,17 @@ const UserPreferences: React.FC = () => {
|
|
|
398
414
|
value={value ?? ''}
|
|
399
415
|
onChange={(e) => handleGenericPreferenceChange(format.id, e.target.value)}
|
|
400
416
|
disabled={saving || !format.editable}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
417
|
+
slotProps={{
|
|
418
|
+
input: format.maxLength ? {
|
|
419
|
+
endAdornment: (
|
|
420
|
+
<InputAdornment position="end">
|
|
421
|
+
{(value?.length || 0)}/{format.maxLength}
|
|
422
|
+
</InputAdornment>
|
|
423
|
+
),
|
|
424
|
+
} : undefined,
|
|
425
|
+
|
|
426
|
+
htmlInput: { maxLength: format.maxLength }
|
|
427
|
+
}} />
|
|
410
428
|
</CardContent>
|
|
411
429
|
</Card>
|
|
412
430
|
);
|
|
@@ -417,7 +435,13 @@ const UserPreferences: React.FC = () => {
|
|
|
417
435
|
<CardContent>
|
|
418
436
|
<Typography variant="subtitle1" gutterBottom>{format.label}</Typography>
|
|
419
437
|
{format.description && (
|
|
420
|
-
<Typography
|
|
438
|
+
<Typography
|
|
439
|
+
variant="caption"
|
|
440
|
+
sx={{
|
|
441
|
+
color: "text.secondary",
|
|
442
|
+
display: "block",
|
|
443
|
+
mb: 2
|
|
444
|
+
}}>
|
|
421
445
|
{format.description}
|
|
422
446
|
</Typography>
|
|
423
447
|
)}
|
|
@@ -428,8 +452,10 @@ const UserPreferences: React.FC = () => {
|
|
|
428
452
|
value={value ?? ''}
|
|
429
453
|
onChange={(e) => handleGenericPreferenceChange(format.id, e.target.value)}
|
|
430
454
|
disabled={saving || !format.editable}
|
|
431
|
-
inputProps={{ maxLength: format.maxLength }}
|
|
432
455
|
helperText={format.maxLength ? `${(value?.length || 0)}/${format.maxLength} characters` : undefined}
|
|
456
|
+
slotProps={{
|
|
457
|
+
htmlInput: { maxLength: format.maxLength }
|
|
458
|
+
}}
|
|
433
459
|
/>
|
|
434
460
|
</CardContent>
|
|
435
461
|
</Card>
|
|
@@ -462,7 +488,9 @@ const UserPreferences: React.FC = () => {
|
|
|
462
488
|
<Typography variant="subtitle1">
|
|
463
489
|
{formatNotificationName(pref.name)}
|
|
464
490
|
</Typography>
|
|
465
|
-
<Typography variant="caption"
|
|
491
|
+
<Typography variant="caption" sx={{
|
|
492
|
+
color: "text.secondary"
|
|
493
|
+
}}>
|
|
466
494
|
{pref.name}
|
|
467
495
|
</Typography>
|
|
468
496
|
</Box>
|
|
@@ -497,7 +525,9 @@ const UserPreferences: React.FC = () => {
|
|
|
497
525
|
)}
|
|
498
526
|
|
|
499
527
|
{!config?.hasEmail && !config?.hasPush && (
|
|
500
|
-
<Typography variant="caption"
|
|
528
|
+
<Typography variant="caption" sx={{
|
|
529
|
+
color: "text.secondary"
|
|
530
|
+
}}>
|
|
501
531
|
(No configurable channels)
|
|
502
532
|
</Typography>
|
|
503
533
|
)}
|
|
@@ -518,7 +548,12 @@ const UserPreferences: React.FC = () => {
|
|
|
518
548
|
return (
|
|
519
549
|
<Box sx={{ pt: 2 }}>
|
|
520
550
|
{groupConfig?.description && (
|
|
521
|
-
<Typography
|
|
551
|
+
<Typography
|
|
552
|
+
variant="body2"
|
|
553
|
+
sx={{
|
|
554
|
+
color: "text.secondary",
|
|
555
|
+
mb: 3
|
|
556
|
+
}}>
|
|
522
557
|
{groupConfig.description}
|
|
523
558
|
</Typography>
|
|
524
559
|
)}
|
|
@@ -101,7 +101,7 @@ export const SystemRequestsCacheProvider: React.FC<SystemRequestsCacheProviderPr
|
|
|
101
101
|
const now = Date.now();
|
|
102
102
|
if (!GLOBALS.current.lastFetchTime) {
|
|
103
103
|
try {
|
|
104
|
-
GLOBALS.current.lastFetchTime = await idbGet(cacheKey) || 0;
|
|
104
|
+
GLOBALS.current.lastFetchTime = (await idbGet(cacheKey)) || 0;
|
|
105
105
|
if (DEBUG_SYSTEM_REQUESTS_CACHE) {
|
|
106
106
|
console.log(`[SystemRequestsCache] Loaded lastFetchTime from IndexedDB: ${GLOBALS.current.lastFetchTime}`);
|
|
107
107
|
}
|
|
@@ -231,7 +231,7 @@ const CollapsableSidebarMenu = ({
|
|
|
231
231
|
// onClick above does closest('.expand-icon') to tell "clicked the arrow"
|
|
232
232
|
// from "clicked the row" — if only the svg had it, clicking the circle's
|
|
233
233
|
// padding (outside the svg's own box) would miss the check and navigate.
|
|
234
|
-
<div className="expand-icon expand-icon-wrapper" onClick={handleExpandClick}>
|
|
234
|
+
(<div className="expand-icon expand-icon-wrapper" onClick={handleExpandClick}>
|
|
235
235
|
{/* For bottom position, invert icons since submenu opens upward */}
|
|
236
236
|
{sidebarPosition === "bottom" ? (
|
|
237
237
|
localOpen ?
|
|
@@ -242,11 +242,11 @@ const CollapsableSidebarMenu = ({
|
|
|
242
242
|
<ExpandLessOutlinedIcon className='expand-icon less' /> :
|
|
243
243
|
<ExpandMoreOutlinedIcon className='expand-icon more' />
|
|
244
244
|
)}
|
|
245
|
-
</div>
|
|
245
|
+
</div>)
|
|
246
246
|
)}
|
|
247
247
|
</ListItemButton>
|
|
248
248
|
</div>
|
|
249
|
-
|
|
249
|
+
|
|
250
250
|
{/* Portal submenu for all positions */}
|
|
251
251
|
{/* Vertical mode (Left/Right) - Inline Expansion using Collapse */}
|
|
252
252
|
{!isHorizontal && (
|
|
@@ -62,20 +62,20 @@ const SidebarActions: React.FC<SidebarActionsProps> = ({
|
|
|
62
62
|
),
|
|
63
63
|
}}
|
|
64
64
|
>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
{authContext?.authenticated && authContext.user?.id !== 'guest' && (
|
|
66
|
+
<AvatarComponent sidebarPosition={sidebarPosition} />
|
|
67
|
+
)}
|
|
68
68
|
|
|
69
69
|
{HeaderToolBar && headerToolBarReplace ? (
|
|
70
70
|
// Replace mode: Only render the custom HeaderToolBar
|
|
71
|
-
<HeaderToolBar />
|
|
71
|
+
(<HeaderToolBar />)
|
|
72
72
|
) : (
|
|
73
73
|
// Default mode: Render all actions
|
|
74
|
-
<>
|
|
74
|
+
(<>
|
|
75
75
|
{HeaderToolBar && <HeaderToolBar />}
|
|
76
76
|
{authContext?.authenticated ? <BridgedLocalesMenuButton /> : <LangSwitcher />}
|
|
77
77
|
<DarkToggleMode />
|
|
78
|
-
</>
|
|
78
|
+
</>)
|
|
79
79
|
)}
|
|
80
80
|
</Box>
|
|
81
81
|
);
|
|
@@ -403,13 +403,14 @@ const DASHLightWeightLogin: React.FC<DASHLightWeightLoginProps> = (props) => {
|
|
|
403
403
|
|
|
404
404
|
>
|
|
405
405
|
<Container maxWidth="sm" sx={{ p: 1 }}>
|
|
406
|
-
<Box
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
406
|
+
<Box
|
|
407
|
+
sx={{
|
|
408
|
+
display: "flex",
|
|
409
|
+
justifyContent: "center",
|
|
410
|
+
alignItems: "center",
|
|
411
|
+
minHeight: "50vh",
|
|
412
|
+
textAlign: "center"
|
|
413
|
+
}}>
|
|
413
414
|
<div>Cargando...</div>
|
|
414
415
|
</Box>
|
|
415
416
|
</Container>
|
package/src/pages/Profile.tsx
CHANGED
|
@@ -149,9 +149,9 @@ const Profile: FC = (_props) => {
|
|
|
149
149
|
};
|
|
150
150
|
|
|
151
151
|
return (
|
|
152
|
-
|
|
152
|
+
<div className='dash-profile'>
|
|
153
153
|
|
|
154
|
-
|
|
154
|
+
{user ? (
|
|
155
155
|
<Form
|
|
156
156
|
onSubmit={handleSubmit}
|
|
157
157
|
validate={validateUserCreation}
|
|
@@ -168,11 +168,12 @@ const Profile: FC = (_props) => {
|
|
|
168
168
|
>
|
|
169
169
|
{/* Profile Image Section */}
|
|
170
170
|
<Grid
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
171
|
+
size={{ xs: 12, md: 4 }}
|
|
172
|
+
sx={{
|
|
173
|
+
display: "flex",
|
|
174
|
+
justifyContent: "center",
|
|
175
|
+
alignItems: "center"
|
|
176
|
+
}}>
|
|
176
177
|
<CardContent
|
|
177
178
|
sx={{
|
|
178
179
|
height: '100%',
|
|
@@ -349,8 +350,8 @@ const Profile: FC = (_props) => {
|
|
|
349
350
|
) : (
|
|
350
351
|
<Loading />
|
|
351
352
|
)}
|
|
352
|
-
|
|
353
|
-
|
|
353
|
+
</div>
|
|
354
|
+
);
|
|
354
355
|
};
|
|
355
356
|
|
|
356
357
|
export default Profile;
|
|
@@ -55,8 +55,8 @@ const RecoverPassword = ({ }: { }) => {
|
|
|
55
55
|
}, [])
|
|
56
56
|
|
|
57
57
|
return (
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
<FullLayoutMarkup>
|
|
59
|
+
<Box
|
|
60
60
|
sx={{
|
|
61
61
|
//height: '100vh',
|
|
62
62
|
display: 'flex',
|
|
@@ -104,7 +104,14 @@ const RecoverPassword = ({ }: { }) => {
|
|
|
104
104
|
</Box>
|
|
105
105
|
) : (
|
|
106
106
|
<form onSubmit={handleSubmit} className='dash-app-login-form'>
|
|
107
|
-
<Grid
|
|
107
|
+
<Grid
|
|
108
|
+
container
|
|
109
|
+
spacing={2}
|
|
110
|
+
sx={{
|
|
111
|
+
alignItems: "center",
|
|
112
|
+
mb:4,
|
|
113
|
+
mt:2
|
|
114
|
+
}}>
|
|
108
115
|
{/* @ts-ignore */}
|
|
109
116
|
<Grid item xs={2}>
|
|
110
117
|
<IconButton
|
|
@@ -135,13 +142,15 @@ const RecoverPassword = ({ }: { }) => {
|
|
|
135
142
|
placeholder='Email'
|
|
136
143
|
required
|
|
137
144
|
value={email}
|
|
138
|
-
inputProps={{type:'email'}}
|
|
139
145
|
onChange={(e) => setEmail(e.target.value)}
|
|
140
146
|
className='dash-app-form-item-input'
|
|
141
147
|
autoComplete="username"
|
|
142
148
|
name="email"
|
|
143
149
|
type="email"
|
|
144
150
|
id="email"
|
|
151
|
+
slotProps={{
|
|
152
|
+
htmlInput: {type:'email'}
|
|
153
|
+
}}
|
|
145
154
|
/>
|
|
146
155
|
</div>
|
|
147
156
|
|
|
@@ -159,8 +168,8 @@ const RecoverPassword = ({ }: { }) => {
|
|
|
159
168
|
)}
|
|
160
169
|
</Box>
|
|
161
170
|
</Box>
|
|
162
|
-
|
|
163
|
-
|
|
171
|
+
</FullLayoutMarkup>
|
|
172
|
+
);
|
|
164
173
|
};
|
|
165
174
|
|
|
166
175
|
export default RecoverPassword;
|
|
@@ -53,7 +53,12 @@ const PaymentHistoryView: React.FC<IDashAutoAdminCustomFieldComponent> = () => {
|
|
|
53
53
|
|
|
54
54
|
if (loading) {
|
|
55
55
|
return (
|
|
56
|
-
<Box
|
|
56
|
+
<Box
|
|
57
|
+
sx={{
|
|
58
|
+
display: "flex",
|
|
59
|
+
justifyContent: "center",
|
|
60
|
+
p: 2
|
|
61
|
+
}}>
|
|
57
62
|
<CircularProgress />
|
|
58
63
|
</Box>
|
|
59
64
|
);
|
|
@@ -96,7 +101,9 @@ const PaymentHistoryView: React.FC<IDashAutoAdminCustomFieldComponent> = () => {
|
|
|
96
101
|
</Typography>
|
|
97
102
|
</TableCell>
|
|
98
103
|
<TableCell>
|
|
99
|
-
<Typography variant="body2"
|
|
104
|
+
<Typography variant="body2" sx={{
|
|
105
|
+
fontFamily: "monospace"
|
|
106
|
+
}}>
|
|
100
107
|
{payment.transaction_id}
|
|
101
108
|
</Typography>
|
|
102
109
|
</TableCell>
|
|
@@ -48,8 +48,13 @@ const EditComponent: React.FC<IDashAutoAdminCustomFieldComponent> = ({ method, a
|
|
|
48
48
|
<Typography variant="h6" gutterBottom>
|
|
49
49
|
Características del Plan
|
|
50
50
|
</Typography>
|
|
51
|
-
|
|
52
|
-
<Box
|
|
51
|
+
|
|
52
|
+
<Box
|
|
53
|
+
sx={{
|
|
54
|
+
display: "flex",
|
|
55
|
+
gap: 1,
|
|
56
|
+
mb: 2
|
|
57
|
+
}}>
|
|
53
58
|
<TextField
|
|
54
59
|
fullWidth
|
|
55
60
|
size="small"
|
|
@@ -95,7 +100,9 @@ const EditComponent: React.FC<IDashAutoAdminCustomFieldComponent> = ({ method, a
|
|
|
95
100
|
</Typography>
|
|
96
101
|
)}
|
|
97
102
|
|
|
98
|
-
<Box
|
|
103
|
+
<Box sx={{
|
|
104
|
+
mt: 2
|
|
105
|
+
}}>
|
|
99
106
|
<Typography variant="body2" color="textSecondary">
|
|
100
107
|
Las características se mostrarán a los usuarios al seleccionar este plan de suscripción.
|
|
101
108
|
</Typography>
|
|
@@ -31,11 +31,17 @@ const SubscriptionPlanPreview: React.FC<IDashAutoAdminCustomFieldComponent> = ({
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
return (
|
|
34
|
-
<Box
|
|
34
|
+
<Box sx={{
|
|
35
|
+
maxWidth: 400
|
|
36
|
+
}}>
|
|
35
37
|
<Card elevation={3}>
|
|
36
38
|
<CardContent>
|
|
37
39
|
{/* Header */}
|
|
38
|
-
<Box
|
|
40
|
+
<Box
|
|
41
|
+
sx={{
|
|
42
|
+
textAlign: "center",
|
|
43
|
+
mb: 2
|
|
44
|
+
}}>
|
|
39
45
|
<Typography variant="h5" component="h2" gutterBottom>
|
|
40
46
|
{record.name}
|
|
41
47
|
</Typography>
|
|
@@ -59,7 +65,9 @@ const SubscriptionPlanPreview: React.FC<IDashAutoAdminCustomFieldComponent> = ({
|
|
|
59
65
|
</Typography>
|
|
60
66
|
|
|
61
67
|
{record.billing_cycle === 'yearly' && (
|
|
62
|
-
<Typography variant="body2"
|
|
68
|
+
<Typography variant="body2" sx={{
|
|
69
|
+
color: "success.main"
|
|
70
|
+
}}>
|
|
63
71
|
{formatPrice(record.price_per_month)} por mes
|
|
64
72
|
</Typography>
|
|
65
73
|
)}
|
|
@@ -69,7 +77,9 @@ const SubscriptionPlanPreview: React.FC<IDashAutoAdminCustomFieldComponent> = ({
|
|
|
69
77
|
|
|
70
78
|
{/* Description */}
|
|
71
79
|
{record.description && (
|
|
72
|
-
<Typography variant="body2" color="textSecondary"
|
|
80
|
+
<Typography variant="body2" color="textSecondary" sx={{
|
|
81
|
+
marginBottom: "16px"
|
|
82
|
+
}}>
|
|
73
83
|
{record.description}
|
|
74
84
|
</Typography>
|
|
75
85
|
)}
|
|
@@ -88,7 +98,9 @@ const SubscriptionPlanPreview: React.FC<IDashAutoAdminCustomFieldComponent> = ({
|
|
|
88
98
|
</ListItemIcon>
|
|
89
99
|
<ListItemText
|
|
90
100
|
primary={feature}
|
|
91
|
-
|
|
101
|
+
slotProps={{
|
|
102
|
+
primary: { variant: 'body2' }
|
|
103
|
+
}}
|
|
92
104
|
/>
|
|
93
105
|
</ListItem>
|
|
94
106
|
))}
|
|
@@ -109,13 +121,14 @@ const SubscriptionPlanPreview: React.FC<IDashAutoAdminCustomFieldComponent> = ({
|
|
|
109
121
|
</Button>
|
|
110
122
|
|
|
111
123
|
{!record.is_active && (
|
|
112
|
-
<Typography
|
|
113
|
-
variant="caption"
|
|
114
|
-
color="error"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
124
|
+
<Typography
|
|
125
|
+
variant="caption"
|
|
126
|
+
color="error"
|
|
127
|
+
sx={{
|
|
128
|
+
display: "block",
|
|
129
|
+
textAlign: "center",
|
|
130
|
+
mt: 1
|
|
131
|
+
}}>
|
|
119
132
|
Plan no disponible
|
|
120
133
|
</Typography>
|
|
121
134
|
)}
|