AnalyticsDetailSkeleton.js
3 months ago
AnalyticsPageSkeleton.js
3 months ago
DashboardSkeleton.js
3 months ago
MediaHubPageSkeleton.js
2 months ago
MediaHubRowSkeleton.js
2 months ago
SettingsSectionSkeleton.js
3 months ago
SettingsSkeleton.js
3 months ago
UserAnalyticsDetailSkeleton.js
3 months ago
SettingsSectionSkeleton.js
56 lines
| 1 | import { Skeleton } from '@bsf/force-ui'; |
| 2 | |
| 3 | const SectionSkeleton = ( { children } ) => ( |
| 4 | <div className="bg-white p-6 box-border shadow-sm rounded-xl flex flex-col gap-4"> |
| 5 | { children } |
| 6 | </div> |
| 7 | ); |
| 8 | |
| 9 | const CardHeader = () => ( |
| 10 | <div className="flex flex-col gap-1"> |
| 11 | <Skeleton className="h-5 w-28 rounded-md" /> |
| 12 | <Skeleton className="h-3 w-56 rounded-md" /> |
| 13 | </div> |
| 14 | ); |
| 15 | |
| 16 | const FieldRow = ( { labelWidth = 'w-24' } ) => ( |
| 17 | <div className="flex flex-col gap-2"> |
| 18 | <Skeleton className={ `h-3 ${ labelWidth } rounded-md` } /> |
| 19 | <Skeleton className="h-9 w-full rounded-md" /> |
| 20 | </div> |
| 21 | ); |
| 22 | |
| 23 | const ToggleRow = () => ( |
| 24 | <div className="flex items-center justify-between gap-4"> |
| 25 | <div className="flex flex-col gap-1"> |
| 26 | <Skeleton className="h-4 w-32 rounded-md" /> |
| 27 | <Skeleton className="h-3 w-48 rounded-md" /> |
| 28 | </div> |
| 29 | <Skeleton className="h-5 w-9 rounded-full shrink-0" /> |
| 30 | </div> |
| 31 | ); |
| 32 | |
| 33 | const GenericCard = () => ( |
| 34 | <SectionSkeleton> |
| 35 | <CardHeader /> |
| 36 | <FieldRow labelWidth="w-20" /> |
| 37 | <FieldRow labelWidth="w-28" /> |
| 38 | <ToggleRow /> |
| 39 | </SectionSkeleton> |
| 40 | ); |
| 41 | |
| 42 | // `cards` mirrors the real page's <SectionCard> count so the skeleton doesn't |
| 43 | // visually over- or under-claim the eventual layout. Almost every settings |
| 44 | // page renders exactly one SectionCard — default = 1. Pages that genuinely |
| 45 | // render more (e.g. EmailCapture with its optional CsvExportSection) opt in |
| 46 | // via the `skeletonCards` field on their SETTINGS_PAGES entry. |
| 47 | const SettingsSectionSkeleton = ( { cards = 1 } ) => ( |
| 48 | <div className="flex flex-col gap-6"> |
| 49 | { Array.from( { length: Math.max( 1, cards ) } ).map( ( _, index ) => ( |
| 50 | <GenericCard key={ index } /> |
| 51 | ) ) } |
| 52 | </div> |
| 53 | ); |
| 54 | |
| 55 | export default SettingsSectionSkeleton; |
| 56 |