From a6b7bb540126524ef0a69d36fd938381d14ba004 Mon Sep 17 00:00:00 2001 From: Jordan Trouw Date: Tue, 26 Nov 2024 15:59:23 -0800 Subject: [PATCH] updating theme showcase options --- .storybook/preview.tsx | 2 +- .../Buttons/ThemeModeButtonGroup.stories.tsx | 39 +-- packages/theme/src/index.ts | 5 +- .../ThemeExtensions/customThemeColors.ts | 0 .../ThemeExtensions/index.ts | 0 .../src/product-theme/ThemeViewer.stories.tsx | 23 ++ .../theme/src/product-theme/ThemeViewer.tsx | 71 +++++ .../dataism/customThemeColors.tsx | 0 .../dataism/darkThemePalette.tsx | 2 +- .../src/{ => product-theme}/dataism/index.ts | 0 .../dataism/lightThemePalette.tsx | 2 +- .../src/{ => product-theme}/dataism/theme.tsx | 0 packages/theme/src/product-theme/index.ts | 4 + .../xylabs/darkThemeOptions.tsx | 2 +- .../src/{ => product-theme}/xylabs/index.ts | 0 .../xylabs/lightThemeOptions.tsx | 2 +- .../src/{ => product-theme}/xylabs/theme.tsx | 0 .../xyo-website/darkThemeOptions.tsx | 2 +- .../{ => product-theme}/xyo-website/index.ts | 0 .../xyo-website/lightThemeOptions.tsx | 2 +- .../{ => product-theme}/xyo-website/theme.ts | 11 +- .../LineCharts/DailyVerificationLineChart.tsx | 50 ++++ ...lyVerificationStackedAreaChart.stories.tsx | 18 ++ .../DailyVerificationStackedAreaChart.tsx | 63 +++++ .../DailyVerificationStatus.stories.tsx | 18 ++ .../DataViewers/Charts/LineCharts/index.ts | 3 + .../LineCharts/sampleVerificationData.ts | 27 ++ .../PieCharts/DualRingPieChart.stories.tsx | 29 ++ .../Charts/PieCharts/DualRingPieChart.tsx | 125 ++++++++ .../DataViewers/Charts/PieCharts/index.ts | 1 + .../DailyVerificationScatterChart.tsx | 121 ++++++++ .../DailyVerificationStatus.stories.tsx | 26 ++ .../DataViewers/Charts/ScatterCharts/index.ts | 2 + .../ScatterCharts/sampleVerificationData.ts | 262 +++++++++++++++++ .../Charts/Shared/CustomTooltip.tsx | 40 +++ .../DataViewers/Charts/Shared/DataProps.tsx | 84 ++++++ .../DataViewers/Charts/Shared/index.ts | 2 + .../dashboard/DataViewers/Charts/index.ts | 4 + .../DataViewers/DataHealth.stories.tsx | 44 +++ .../dashboard/DataViewers/DataHealth.tsx | 95 +++++++ .../VerificationSummary/VerificationList.tsx | 73 +++++ .../VerificationSummary.stories.tsx | 127 +++++++++ .../VerificationSummaryProps.tsx | 112 ++++++++ .../DataViewers/VerificationSummary/index.ts | 2 + .../dashboard/DataViewers/img/earth.webp | Bin 0 -> 161638 bytes .../dashboard/DataViewers/img/index.ts | 1 + .../showcase/dashboard/DataViewers/index.ts | 5 + .../dashboard/Drawer/BottomMenuArea.tsx | 33 +++ .../dashboard/Drawer/LogoutListItem.tsx | 73 +++++ .../showcase/dashboard/Drawer/MenuList.tsx | 79 ++++++ .../dashboard/Drawer/MenuListItem.tsx | 54 ++++ .../dashboard/Drawer/MiniDrawer.stories.tsx | 80 ++++++ .../showcase/dashboard/Drawer/MiniDrawer.tsx | 61 ++++ .../dashboard/Drawer/StyledListItemButton.tsx | 47 ++++ .../src/showcase/dashboard/Drawer/Styling.tsx | 58 ++++ .../src/showcase/dashboard/Drawer/index.ts | 3 + .../SampleDashboard1/AllCategoriesData.tsx | 22 ++ .../Data/SampleDashboard1/DataMapping.tsx | 88 ++++++ .../Data/SampleDashboard1/Depin.tsx | 88 ++++++ .../SampleDashboard1/EmployeeTracking.tsx | 88 ++++++ .../Data/SampleDashboard1/EventAttendance.tsx | 88 ++++++ .../Data/SampleDashboard1/GameFi.tsx | 88 ++++++ .../Data/SampleDashboard1/MobileApp.tsx | 88 ++++++ .../SampleDashboard1/PartnerValidation.tsx | 88 ++++++ .../Data/SampleDashboard1/RewardPrograms.tsx | 88 ++++++ .../Data/SampleDashboard1/SupplyChain.tsx | 88 ++++++ .../Data/SampleDashboard1/index.ts | 2 + .../SampleDashboard2/AllCategoriesData.tsx | 14 + .../Data/SampleDashboard2/DataMapping.tsx | 46 +++ .../Data/SampleDashboard2/Depin.tsx | 46 +++ .../Data/SampleDashboard2/index.ts | 1 + .../dashboard/ExampleDashboards/Data/index.ts | 2 + .../ExampleDashboards/SampleDashboard1.tsx | 135 +++++++++ .../ExampleDashboards/SampleDashboard2.tsx | 102 +++++++ .../dashboard/ExampleDashboards/index.ts | 2 + .../src/showcase/dashboard/MenuNavItem.ts | 14 + .../AppChrome/AppChrome.stories.tsx | 55 ++++ .../AppChrome/AppChrome.tsx | 108 +++++++ .../StandardComponents/AppChrome/index.ts | 1 + .../StandardComponents/DataCard/DataCard.tsx | 63 +++++ .../DataCard/DataCardSpeedDial.tsx | 104 +++++++ .../StandardComponents/DataCard/index.ts | 2 + .../DropdownSelect/DropdownSelect.stories.tsx | 23 ++ .../DropdownSelect/DropdownSelect.tsx | 99 +++++++ .../DropdownSelect/DropdownSelectData.tsx | 36 +++ .../DropdownSelect/index.ts | 2 + .../StandardComponents/StatCard/StatCard.tsx | 92 ++++++ .../StandardComponents/StatCard/index.ts | 1 + .../dashboard/StandardComponents/index.ts | 3 + .../StyledListItemButton.stories.tsx | 17 ++ .../dashboard/StyledListItemButton.tsx | 47 ++++ .../theme/src/showcase/dashboard/index.ts | 4 + packages/theme/src/showcase/index.ts | 2 + .../src/{ => showcase/theme}/ColorCard.tsx | 0 .../theme}/ColorShowcase.stories.tsx | 2 +- .../{ => showcase/theme}/ColorShowcase.tsx | 8 +- .../theme}/ThemeShowcase.stories.tsx | 2 +- .../{ => showcase/theme}/ThemeShowcase.tsx | 0 packages/theme/src/showcase/theme/index.ts | 3 + yarn.lock | 266 +++++++++++++++++- 100 files changed, 4058 insertions(+), 49 deletions(-) rename packages/theme/src/{ => product-theme}/ThemeExtensions/customThemeColors.ts (100%) rename packages/theme/src/{ => product-theme}/ThemeExtensions/index.ts (100%) create mode 100644 packages/theme/src/product-theme/ThemeViewer.stories.tsx create mode 100644 packages/theme/src/product-theme/ThemeViewer.tsx rename packages/theme/src/{ => product-theme}/dataism/customThemeColors.tsx (100%) rename packages/theme/src/{ => product-theme}/dataism/darkThemePalette.tsx (91%) rename packages/theme/src/{ => product-theme}/dataism/index.ts (100%) rename packages/theme/src/{ => product-theme}/dataism/lightThemePalette.tsx (90%) rename packages/theme/src/{ => product-theme}/dataism/theme.tsx (100%) create mode 100644 packages/theme/src/product-theme/index.ts rename packages/theme/src/{ => product-theme}/xylabs/darkThemeOptions.tsx (88%) rename packages/theme/src/{ => product-theme}/xylabs/index.ts (100%) rename packages/theme/src/{ => product-theme}/xylabs/lightThemeOptions.tsx (90%) rename packages/theme/src/{ => product-theme}/xylabs/theme.tsx (100%) rename packages/theme/src/{ => product-theme}/xyo-website/darkThemeOptions.tsx (97%) rename packages/theme/src/{ => product-theme}/xyo-website/index.ts (100%) rename packages/theme/src/{ => product-theme}/xyo-website/lightThemeOptions.tsx (88%) rename packages/theme/src/{ => product-theme}/xyo-website/theme.ts (91%) create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationLineChart.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStackedAreaChart.stories.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStackedAreaChart.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStatus.stories.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/index.ts create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/sampleVerificationData.ts create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/DualRingPieChart.stories.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/DualRingPieChart.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/index.ts create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/DailyVerificationScatterChart.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/DailyVerificationStatus.stories.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/index.ts create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/sampleVerificationData.ts create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/CustomTooltip.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/DataProps.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/index.ts create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/Charts/index.ts create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/DataHealth.stories.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/DataHealth.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationList.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationSummary.stories.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationSummaryProps.tsx create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/index.ts create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/img/earth.webp create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/img/index.ts create mode 100644 packages/theme/src/showcase/dashboard/DataViewers/index.ts create mode 100644 packages/theme/src/showcase/dashboard/Drawer/BottomMenuArea.tsx create mode 100644 packages/theme/src/showcase/dashboard/Drawer/LogoutListItem.tsx create mode 100644 packages/theme/src/showcase/dashboard/Drawer/MenuList.tsx create mode 100644 packages/theme/src/showcase/dashboard/Drawer/MenuListItem.tsx create mode 100644 packages/theme/src/showcase/dashboard/Drawer/MiniDrawer.stories.tsx create mode 100644 packages/theme/src/showcase/dashboard/Drawer/MiniDrawer.tsx create mode 100644 packages/theme/src/showcase/dashboard/Drawer/StyledListItemButton.tsx create mode 100644 packages/theme/src/showcase/dashboard/Drawer/Styling.tsx create mode 100644 packages/theme/src/showcase/dashboard/Drawer/index.ts create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/AllCategoriesData.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/DataMapping.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/Depin.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/EmployeeTracking.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/EventAttendance.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/GameFi.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/MobileApp.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/PartnerValidation.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/RewardPrograms.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/SupplyChain.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/index.ts create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/AllCategoriesData.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/DataMapping.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/Depin.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/index.ts create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/Data/index.ts create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/SampleDashboard1.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/SampleDashboard2.tsx create mode 100644 packages/theme/src/showcase/dashboard/ExampleDashboards/index.ts create mode 100644 packages/theme/src/showcase/dashboard/MenuNavItem.ts create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/AppChrome.stories.tsx create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/AppChrome.tsx create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/index.ts create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/DataCard/DataCard.tsx create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/DataCard/DataCardSpeedDial.tsx create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/DataCard/index.ts create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelect.stories.tsx create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelect.tsx create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelectData.tsx create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/index.ts create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/StatCard/StatCard.tsx create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/StatCard/index.ts create mode 100644 packages/theme/src/showcase/dashboard/StandardComponents/index.ts create mode 100644 packages/theme/src/showcase/dashboard/StyledListItemButton.stories.tsx create mode 100644 packages/theme/src/showcase/dashboard/StyledListItemButton.tsx create mode 100644 packages/theme/src/showcase/dashboard/index.ts create mode 100644 packages/theme/src/showcase/index.ts rename packages/theme/src/{ => showcase/theme}/ColorCard.tsx (100%) rename packages/theme/src/{ => showcase/theme}/ColorShowcase.stories.tsx (95%) rename packages/theme/src/{ => showcase/theme}/ColorShowcase.tsx (92%) rename packages/theme/src/{ => showcase/theme}/ThemeShowcase.stories.tsx (93%) rename packages/theme/src/{ => showcase/theme}/ThemeShowcase.tsx (100%) create mode 100644 packages/theme/src/showcase/theme/index.ts diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index c7baa050..d0291b37 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -57,7 +57,7 @@ const withThemeProvider: Decorator = (Story, context) => { const theme = themeOptions return ( - + diff --git a/packages/invertible-theme/src/Buttons/ThemeModeButtonGroup.stories.tsx b/packages/invertible-theme/src/Buttons/ThemeModeButtonGroup.stories.tsx index 95434bc1..6d82a56c 100644 --- a/packages/invertible-theme/src/Buttons/ThemeModeButtonGroup.stories.tsx +++ b/packages/invertible-theme/src/Buttons/ThemeModeButtonGroup.stories.tsx @@ -1,33 +1,24 @@ -import { CssBaseline, ThemeProvider } from '@mui/material' -import { createTheme } from '@mui/material/styles' -import type { StoryFn } from '@storybook/react' +import type { Meta, StoryFn } from '@storybook/react' import React from 'react' -import { InvertibleMuiThemeProvider } from '../InvertibleMuiThemeProvider/index.ts' import { ThemeModeButtonGroup } from './ThemeModeButtonGroup.tsx' -export default { - title: 'Theme/ThemeModeButtonGroup', +const StorybookEntry = { + argTypes: {}, component: ThemeModeButtonGroup, - parameters: { layout: 'fullscreen' }, + parameters: { docs: { page: null } }, + title: 'theme/ThemeModeButtonGroup', +} as Meta + +const Template: StoryFn = () => { + return ( + + ) } -const theme = createTheme({ - palette: { - mode: 'light', - primary: { main: '#2c5ba8' }, - secondary: { main: '#ffb300' }, - }, -}) +const Default = Template.bind({}) +Default.args = {} -const Template: StoryFn = () => ( - - - - - - -) +export { Default } -export const Default = Template.bind({}) -Default.args = {} +export default StorybookEntry diff --git a/packages/theme/src/index.ts b/packages/theme/src/index.ts index f03bb5c3..ffdc9f43 100644 --- a/packages/theme/src/index.ts +++ b/packages/theme/src/index.ts @@ -1,3 +1,2 @@ -export * from './dataism/index.ts' -export * from './xylabs/index.ts' -export * from './xyo-website/index.ts' +export * from './product-theme/index.ts' +export * from './showcase/index.ts' diff --git a/packages/theme/src/ThemeExtensions/customThemeColors.ts b/packages/theme/src/product-theme/ThemeExtensions/customThemeColors.ts similarity index 100% rename from packages/theme/src/ThemeExtensions/customThemeColors.ts rename to packages/theme/src/product-theme/ThemeExtensions/customThemeColors.ts diff --git a/packages/theme/src/ThemeExtensions/index.ts b/packages/theme/src/product-theme/ThemeExtensions/index.ts similarity index 100% rename from packages/theme/src/ThemeExtensions/index.ts rename to packages/theme/src/product-theme/ThemeExtensions/index.ts diff --git a/packages/theme/src/product-theme/ThemeViewer.stories.tsx b/packages/theme/src/product-theme/ThemeViewer.stories.tsx new file mode 100644 index 00000000..a21c16c5 --- /dev/null +++ b/packages/theme/src/product-theme/ThemeViewer.stories.tsx @@ -0,0 +1,23 @@ +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' + +import { DataismTheme } from './dataism/index.ts' +import { ThemeViewer } from './ThemeViewer.tsx' + +const StorybookEntry = { + argTypes: {}, + component: ThemeViewer, + parameters: { docs: { page: null } }, + title: 'theme/ThemeViewer', +} as Meta + +const Template: StoryFn = args => ( + +) + +const Default = Template.bind({}) +Default.args = { data: DataismTheme } + +export { Default } + +export default StorybookEntry diff --git a/packages/theme/src/product-theme/ThemeViewer.tsx b/packages/theme/src/product-theme/ThemeViewer.tsx new file mode 100644 index 00000000..cc45f63e --- /dev/null +++ b/packages/theme/src/product-theme/ThemeViewer.tsx @@ -0,0 +1,71 @@ +import { ExpandMoreRounded } from '@mui/icons-material' +import { + Accordion, + AccordionDetails, + AccordionSummary, + Typography, +} from '@mui/material' +import type { Theme } from '@mui/material/styles' +import { useTheme } from '@mui/material/styles' +import React from 'react' + +interface RecursiveAccordionProps { + data: Record + path?: string +} + +const RecursiveAccordion: React.FC = ({ + data, + path = '', +}) => { + return ( + <> + {Object.entries(data).map(([key, value]) => { + const currentPath = path ? `${path}.${key}` : key + const isObject = typeof value === 'object' && value !== null + + return ( + + } + > + + {key} + {isObject && ':'} + + + + {isObject + ? ( + } path={currentPath} /> + ) + : ( + + {JSON.stringify(value, null, 2)} + + )} + + + ) + })} + + ) +} + +export const ThemeViewer: React.FC = () => { + const theme: Theme = useTheme() + + return ( +
+ + Material-UI Theme Viewer + + } /> +
+ ) +} diff --git a/packages/theme/src/dataism/customThemeColors.tsx b/packages/theme/src/product-theme/dataism/customThemeColors.tsx similarity index 100% rename from packages/theme/src/dataism/customThemeColors.tsx rename to packages/theme/src/product-theme/dataism/customThemeColors.tsx diff --git a/packages/theme/src/dataism/darkThemePalette.tsx b/packages/theme/src/product-theme/dataism/darkThemePalette.tsx similarity index 91% rename from packages/theme/src/dataism/darkThemePalette.tsx rename to packages/theme/src/product-theme/dataism/darkThemePalette.tsx index 0c6d1878..b1a6d41d 100644 --- a/packages/theme/src/dataism/darkThemePalette.tsx +++ b/packages/theme/src/product-theme/dataism/darkThemePalette.tsx @@ -5,7 +5,7 @@ import { personaColorsDarkMode } from './customThemeColors.tsx' export const darkThemePalette: ColorSystemOptions['palette'] = { background: { paper: '#1E1E1E', - gradient: 'linear-gradient(to right, #fff, #000)', + gradient: 'linear-gradient(45deg, #fff, #000)', }, info: { main: '#72b4f4' }, primary: { main: '#fff' }, diff --git a/packages/theme/src/dataism/index.ts b/packages/theme/src/product-theme/dataism/index.ts similarity index 100% rename from packages/theme/src/dataism/index.ts rename to packages/theme/src/product-theme/dataism/index.ts diff --git a/packages/theme/src/dataism/lightThemePalette.tsx b/packages/theme/src/product-theme/dataism/lightThemePalette.tsx similarity index 90% rename from packages/theme/src/dataism/lightThemePalette.tsx rename to packages/theme/src/product-theme/dataism/lightThemePalette.tsx index 67550f52..8e6b4406 100644 --- a/packages/theme/src/dataism/lightThemePalette.tsx +++ b/packages/theme/src/product-theme/dataism/lightThemePalette.tsx @@ -5,7 +5,7 @@ import { personaColorsLightMode } from './customThemeColors.tsx' export const lightThemePalette: ColorSystemOptions['palette'] = { background: { paper: '#FAFAFA', - gradient: 'linear-gradient(to right, #000, #fff)', + gradient: 'linear-gradient(45deg, #000, #fff)', }, info: { main: '#72b4f4' }, primary: { main: '#000' }, diff --git a/packages/theme/src/dataism/theme.tsx b/packages/theme/src/product-theme/dataism/theme.tsx similarity index 100% rename from packages/theme/src/dataism/theme.tsx rename to packages/theme/src/product-theme/dataism/theme.tsx diff --git a/packages/theme/src/product-theme/index.ts b/packages/theme/src/product-theme/index.ts new file mode 100644 index 00000000..30094542 --- /dev/null +++ b/packages/theme/src/product-theme/index.ts @@ -0,0 +1,4 @@ +export * from './dataism/index.ts' +export * from './ThemeExtensions/index.ts' +export * from './xylabs/index.ts' +export * from './xyo-website/index.ts' diff --git a/packages/theme/src/xylabs/darkThemeOptions.tsx b/packages/theme/src/product-theme/xylabs/darkThemeOptions.tsx similarity index 88% rename from packages/theme/src/xylabs/darkThemeOptions.tsx rename to packages/theme/src/product-theme/xylabs/darkThemeOptions.tsx index e854a350..52082f14 100644 --- a/packages/theme/src/xylabs/darkThemeOptions.tsx +++ b/packages/theme/src/product-theme/xylabs/darkThemeOptions.tsx @@ -5,7 +5,7 @@ export const darkThemeOptions: ThemeOptions = { background: { default: '#0b0f30', paper: '#101742', - gradient: 'linear-gradient(to right, #384AFD, #0b0f30)', + gradient: 'linear-gradient(45deg, #384AFD, #0b0f30)', }, primary: { dark: '#010965', diff --git a/packages/theme/src/xylabs/index.ts b/packages/theme/src/product-theme/xylabs/index.ts similarity index 100% rename from packages/theme/src/xylabs/index.ts rename to packages/theme/src/product-theme/xylabs/index.ts diff --git a/packages/theme/src/xylabs/lightThemeOptions.tsx b/packages/theme/src/product-theme/xylabs/lightThemeOptions.tsx similarity index 90% rename from packages/theme/src/xylabs/lightThemeOptions.tsx rename to packages/theme/src/product-theme/xylabs/lightThemeOptions.tsx index 26f04e4e..a768e652 100644 --- a/packages/theme/src/xylabs/lightThemeOptions.tsx +++ b/packages/theme/src/product-theme/xylabs/lightThemeOptions.tsx @@ -4,7 +4,7 @@ export const lightThemeOptions: ThemeOptions = { palette: { background: { default: '#fafafa', - gradient: 'linear-gradient(to right, #384AFD, #010965)', + gradient: 'linear-gradient(45deg, #384AFD, #fafafa)', }, primary: { dark: '#010965', diff --git a/packages/theme/src/xylabs/theme.tsx b/packages/theme/src/product-theme/xylabs/theme.tsx similarity index 100% rename from packages/theme/src/xylabs/theme.tsx rename to packages/theme/src/product-theme/xylabs/theme.tsx diff --git a/packages/theme/src/xyo-website/darkThemeOptions.tsx b/packages/theme/src/product-theme/xyo-website/darkThemeOptions.tsx similarity index 97% rename from packages/theme/src/xyo-website/darkThemeOptions.tsx rename to packages/theme/src/product-theme/xyo-website/darkThemeOptions.tsx index 740fbd8e..1c213e61 100644 --- a/packages/theme/src/xyo-website/darkThemeOptions.tsx +++ b/packages/theme/src/product-theme/xyo-website/darkThemeOptions.tsx @@ -9,7 +9,7 @@ export const darkThemeOptions: ThemeOptions = { background: { default: '#020223', paper: '#16163D', - gradient: 'linear-gradient(to right, #66caf7, #5658F3)', + gradient: 'linear-gradient(45deg, #66CAF7, #020223)', }, neutral: { main: '#fff', diff --git a/packages/theme/src/xyo-website/index.ts b/packages/theme/src/product-theme/xyo-website/index.ts similarity index 100% rename from packages/theme/src/xyo-website/index.ts rename to packages/theme/src/product-theme/xyo-website/index.ts diff --git a/packages/theme/src/xyo-website/lightThemeOptions.tsx b/packages/theme/src/product-theme/xyo-website/lightThemeOptions.tsx similarity index 88% rename from packages/theme/src/xyo-website/lightThemeOptions.tsx rename to packages/theme/src/product-theme/xyo-website/lightThemeOptions.tsx index 9259d34e..4cffce20 100644 --- a/packages/theme/src/xyo-website/lightThemeOptions.tsx +++ b/packages/theme/src/product-theme/xyo-website/lightThemeOptions.tsx @@ -5,7 +5,7 @@ export const lightThemeOptions: ThemeOptions = { palette: { background: { paper: '#FAFAFA', - gradient: 'linear-gradient(to right, #72b4f4, #463dc6)', + gradient: 'linear-gradient(45deg, #72b4f4, #fff)', }, neutral: { contrastText: '#fff', diff --git a/packages/theme/src/xyo-website/theme.ts b/packages/theme/src/product-theme/xyo-website/theme.ts similarity index 91% rename from packages/theme/src/xyo-website/theme.ts rename to packages/theme/src/product-theme/xyo-website/theme.ts index 61f30bbd..16c76774 100644 --- a/packages/theme/src/xyo-website/theme.ts +++ b/packages/theme/src/product-theme/xyo-website/theme.ts @@ -39,7 +39,7 @@ export const XyoTheme = (theme: Theme, rtl = false): Theme => createTheme({ styleOverrides: { root: { boxShadow: 'none', - padding: `${theme.spacing(1)} ${theme.spacing(2)}`, + // padding: `${theme.spacing(1)} ${theme.spacing(2)}`, borderWidth: '2px', borderColor: 'inherit', }, @@ -50,11 +50,11 @@ export const XyoTheme = (theme: Theme, rtl = false): Theme => createTheme({ style: { 'WebkitBackdropFilter': 'blur(2px)', 'backdropFilter': 'blur(2px)', - 'border': `2px solid ${alpha('#fff', 0.4)}`, - 'color': '#fff', + 'border': `2px solid ${alpha(theme.palette.text.primary, 0.4)}`, + 'color': theme.palette.text.primary, '&:hover': { - backgroundColor: '#ffffff', - border: `2px solid ${alpha('#fff', 0)}`, + backgroundColor: theme.palette.background.default, + border: `2px solid ${alpha(theme.palette.text.primary, 0)}`, color: darken(theme.palette.primary.dark, 0.7), }, }, @@ -117,6 +117,7 @@ export const XyoTheme = (theme: Theme, rtl = false): Theme => createTheme({ button: { fontSize: '1rem', fontWeight: 500, + textTransform: 'capitalize', }, fontWeightBold: 600, fontWeightLight: 200, diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationLineChart.tsx b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationLineChart.tsx new file mode 100644 index 00000000..713f428d --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationLineChart.tsx @@ -0,0 +1,50 @@ +// DailyVerificationLineChart.tsx + +import { useTheme } from '@mui/material' +import React from 'react' +import { + Area, AreaChart, CartesianGrid, ResponsiveContainer, + Tooltip, XAxis, YAxis, +} from 'recharts' + +import { CustomDataTooltip, type DailyVerificationChartProps } from '../Shared/index.ts' + +export const DailyVerificationLineChart: React.FC = ({ data }) => { + const theme = useTheme() + + return ( + + + + + + + )} + cursor={{ strokeDasharray: '3 3' }} + /> + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStackedAreaChart.stories.tsx b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStackedAreaChart.stories.tsx new file mode 100644 index 00000000..fcb96268 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStackedAreaChart.stories.tsx @@ -0,0 +1,18 @@ +// DailyVerificationStackedAreaChart.stories.tsx + +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' + +import { DailyVerificationStackedAreaChart } from './DailyVerificationStackedAreaChart.tsx' +import { stackedVerificationData } from './sampleVerificationData.ts' + +export default { + component: DailyVerificationStackedAreaChart, + title: 'theme/showcase/charts/DailyVerificationStackedAreaChart', + argTypes: {}, +} as Meta + +const Template: StoryFn = args => + +export const Default = Template.bind({}) +Default.args = { data: stackedVerificationData } diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStackedAreaChart.tsx b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStackedAreaChart.tsx new file mode 100644 index 00000000..8ad5a283 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStackedAreaChart.tsx @@ -0,0 +1,63 @@ +import { useTheme } from '@mui/material' +import React from 'react' +import { + Area, AreaChart, CartesianGrid, ResponsiveContainer, + Tooltip, XAxis, YAxis, +} from 'recharts' + +import type { DailyVerificationStackedChartProps } from '../Shared/index.ts' +import { CustomDataTooltip } from '../Shared/index.ts' + +export const DailyVerificationStackedAreaChart: React.FC = ({ data }) => { + const theme = useTheme() + + return ( + + + + + + + )} + cursor={{ strokeDasharray: '3 3' }} + /> + + + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStatus.stories.tsx b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStatus.stories.tsx new file mode 100644 index 00000000..4d7ad58e --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/DailyVerificationStatus.stories.tsx @@ -0,0 +1,18 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +// DailyVerificationLineChart.stories.tsx + +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' + +import { DailyVerificationLineChart } from './DailyVerificationLineChart.tsx' +import { employeeCheckInsData } from './sampleVerificationData.ts' + +export default { + component: DailyVerificationLineChart, + title: 'theme/showcase/charts/DailyVerificationLineChart', +} as Meta + +const Template: StoryFn = (args: any) => + +export const Example = Template.bind({}) +Example.args = { data: employeeCheckInsData } diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/index.ts b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/index.ts new file mode 100644 index 00000000..36d37fc4 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/index.ts @@ -0,0 +1,3 @@ +export * from './DailyVerificationLineChart.tsx' +export * from './DailyVerificationStackedAreaChart.tsx' +export * as LineChartSampleData from './sampleVerificationData.ts' diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/sampleVerificationData.ts b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/sampleVerificationData.ts new file mode 100644 index 00000000..b867300e --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/LineCharts/sampleVerificationData.ts @@ -0,0 +1,27 @@ +import type { StackedVerificationDataPoint, VerificationDataPoint } from '../Shared/index.ts' + +export const employeeCheckInsData: VerificationDataPoint[] = [ + { day: 'Monday', verifications: 120 }, + { day: 'Tuesday', verifications: 200 }, + { day: 'Wednesday', verifications: 150 }, + { day: 'Thursday', verifications: 300 }, + { day: 'Friday', verifications: 250 }, +] + +export const stackedVerificationData: StackedVerificationDataPoint[] = [ + { + day: 'Monday', mobile: 120, web: 90, email: 50, + }, + { + day: 'Tuesday', mobile: 200, web: 130, email: 80, + }, + { + day: 'Wednesday', mobile: 150, web: 100, email: 60, + }, + { + day: 'Thursday', mobile: 300, web: 200, email: 100, + }, + { + day: 'Friday', mobile: 250, web: 150, email: 70, + }, +] diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/DualRingPieChart.stories.tsx b/packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/DualRingPieChart.stories.tsx new file mode 100644 index 00000000..b1ed147f --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/DualRingPieChart.stories.tsx @@ -0,0 +1,29 @@ +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' + +import { StyledDualRingPieChart } from './DualRingPieChart.tsx' + +export default { + title: 'theme/showcase/charts/StyledDualRingPieChart', + component: StyledDualRingPieChart, + argTypes: { + showLegend: { + control: 'boolean', + description: 'Show or hide the legend', + }, + }, +} as Meta + +const Template: StoryFn = args => + +export const Default = Template.bind({}) +Default.args = { + data01: [ + { name: 'Residential areas', value: 38 }, + { name: 'Public parking lots and garages', value: 10.9 }, + { name: 'Public transportation hubs', value: 7.4 }, + { name: 'Commercial and retail locations', value: 4.1 }, + { name: 'Workplace', value: 2.7 }, + ], + showLegend: true, // Toggle this to show/hide the legend +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/DualRingPieChart.tsx b/packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/DualRingPieChart.tsx new file mode 100644 index 00000000..04ded7a9 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/DualRingPieChart.tsx @@ -0,0 +1,125 @@ +import { + alpha, + Box, Typography, useTheme, +} from '@mui/material' +import { FlexRow } from '@xylabs/react-flexbox' +import React, { useState } from 'react' +import { + Cell, Pie, PieChart, ResponsiveContainer, Tooltip, +} from 'recharts' + +import type { PieChartProps } from '../Shared/index.ts' +import { CustomDataTooltip } from '../Shared/index.ts' + +export const StyledDualRingPieChart: React.FC = ({ + data01, data02, showLegend = false, +}) => { + const theme = useTheme() + const [activeIndex, setActiveIndex] = useState(null) + + const handleMouseEnter = (index: number) => { + setActiveIndex(index) + } + + const handleMouseLeave = () => { + setActiveIndex(null) + } + + const colors = [ + alpha(theme.palette.primary.main, 0.8), + alpha(theme.palette.secondary.main, 0.8), + alpha(theme.palette.error.main, 0.8), + alpha(theme.palette.warning.main, 0.8), + alpha(theme.palette.success.main, 0.8), + ] + + return ( + + {showLegend && ( + + {data01.map((entry, index) => ( + + + {entry.name} + + ))} + + )} + + + + )} + /> + {/* Inner Ring */} + `${value}`} + labelLine={false} + paddingAngle={5} + cornerRadius={3} + stroke="none" + > + {data01.map((entry, index) => ( + handleMouseEnter(index)} + onMouseLeave={handleMouseLeave} + /> + ))} + + {/* Outer Ring */} + {data02 && ( + `${value}`} + labelLine={false} + paddingAngle={5} + cornerRadius={3} + stroke="none" + > + {data02.map((entry, index) => ( + handleMouseEnter(index)} + onMouseLeave={handleMouseLeave} + /> + ))} + + )} + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/index.ts b/packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/index.ts new file mode 100644 index 00000000..1a178616 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/PieCharts/index.ts @@ -0,0 +1 @@ +export * from './DualRingPieChart.tsx' diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/DailyVerificationScatterChart.tsx b/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/DailyVerificationScatterChart.tsx new file mode 100644 index 00000000..996e7203 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/DailyVerificationScatterChart.tsx @@ -0,0 +1,121 @@ +import { + alpha, + darken, + lighten, + useTheme, +} from '@mui/material' +import React, { useState } from 'react' +import { + CartesianGrid, Cell, ReferenceLine, ResponsiveContainer, Scatter, ScatterChart, Tooltip, XAxis, YAxis, +} from 'recharts' + +import type { DailyVerificationChartProps } from '../Shared/index.ts' +import { CustomDataTooltip } from '../Shared/index.ts' + +const getVerificationColor = (verifications: number): string => { + if (verifications >= 30) return '#006EF5' + if (verifications < 5) return alpha('#EF233C', 5 / verifications / 2) + return alpha('#006EF5', verifications / 30 / 3) +} + +export const DailyVerificationScatterChart: React.FC = ({ data }) => { + const [isHovered, setIsHovered] = useState(false) + const [tooltipPos, setTooltipPos] = useState({ x: 0, y: 0 }) + const theme = useTheme() + + const handleReferenceLineMouseMove = (event: React.MouseEvent) => { + setTooltipPos({ x: event.clientX - 60, y: event.clientY - 80 }) // Adjust as needed + setIsHovered(true) + } + + const handleReferenceLineMouseLeave = () => { + setIsHovered(false) + } + + return ( +
+ {isHovered && ( + + )} + + + + + + + )} + cursor={{ strokeDasharray: '3 3' }} + /> + {/* Actual threshold line */} + + {/* Invisible hit area for threshold line hover */} + + + {data.map((entry, index) => ( + + ))} + + + +
+ ) +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/DailyVerificationStatus.stories.tsx b/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/DailyVerificationStatus.stories.tsx new file mode 100644 index 00000000..e6b50d68 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/DailyVerificationStatus.stories.tsx @@ -0,0 +1,26 @@ +// DailyVerificationScatterChart.stories.tsx + +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' + +import { DailyVerificationScatterChart } from './DailyVerificationScatterChart.tsx' +import { + employeeCheckInsData, mobileAppQuestCheckInsData, productDeliveryCheckInsData, +} from './sampleVerificationData.ts' + +export default { + component: DailyVerificationScatterChart, + title: 'theme/showcase/charts/DailyVerificationScatterChart', + argTypes: {}, +} as Meta + +const Template: StoryFn = args => + +export const EmployeeCheckIns = Template.bind({}) +EmployeeCheckIns.args = { data: employeeCheckInsData } + +export const ProductDeliveryCheckIns = Template.bind({}) +ProductDeliveryCheckIns.args = { data: productDeliveryCheckInsData } + +export const MobileAppQuestCheckIns = Template.bind({}) +MobileAppQuestCheckIns.args = { data: mobileAppQuestCheckInsData } diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/index.ts b/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/index.ts new file mode 100644 index 00000000..fe02eaa0 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/index.ts @@ -0,0 +1,2 @@ +export * from './DailyVerificationScatterChart.tsx' +export * as ScatterChartSampleData from './sampleVerificationData.ts' diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/sampleVerificationData.ts b/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/sampleVerificationData.ts new file mode 100644 index 00000000..7695c25e --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/ScatterCharts/sampleVerificationData.ts @@ -0,0 +1,262 @@ +import type { VerificationDataPoint } from '../Shared/index.ts' + +export const employeeCheckInsData: VerificationDataPoint[] = [ + { time: 8, verifications: 5 }, + { time: 8, verifications: 8 }, + { time: 8, verifications: 12 }, + { time: 8, verifications: 18 }, + { time: 8, verifications: 20 }, + { time: 8, verifications: 25 }, + { time: 9, verifications: 15 }, + { time: 9, verifications: 20 }, + { time: 9, verifications: 22 }, + { time: 9, verifications: 28 }, + { time: 9, verifications: 35 }, + { time: 9, verifications: 40 }, + { time: 10, verifications: 2 }, + { time: 10, verifications: 12 }, + { time: 10, verifications: 15 }, + { time: 10, verifications: 18 }, + { time: 10, verifications: 22 }, + { time: 10, verifications: 30 }, + { time: 11, verifications: 35 }, + { time: 11, verifications: 37 }, + { time: 11, verifications: 40 }, + { time: 11, verifications: 45 }, + { time: 11, verifications: 50 }, + { time: 11, verifications: 55 }, + { time: 12, verifications: 25 }, + { time: 12, verifications: 30 }, + { time: 12, verifications: 28 }, + { time: 12, verifications: 35 }, + { time: 12, verifications: 40 }, + { time: 12, verifications: 45 }, + { time: 13, verifications: 18 }, + { time: 13, verifications: 28 }, + { time: 13, verifications: 32 }, + { time: 13, verifications: 37 }, + { time: 13, verifications: 45 }, + { time: 13, verifications: 50 }, + { time: 14, verifications: 3 }, + { time: 14, verifications: 7 }, + { time: 14, verifications: 10 }, + { time: 14, verifications: 12 }, + { time: 14, verifications: 15 }, + { time: 14, verifications: 18 }, + { time: 15, verifications: 30 }, + { time: 15, verifications: 32 }, + { time: 15, verifications: 34 }, + { time: 15, verifications: 37 }, + { time: 15, verifications: 40 }, + { time: 15, verifications: 45 }, + { time: 16, verifications: 8 }, + { time: 16, verifications: 10 }, + { time: 16, verifications: 12 }, + { time: 16, verifications: 15 }, + { time: 16, verifications: 18 }, + { time: 16, verifications: 22 }, + { time: 17, verifications: 22 }, + { time: 17, verifications: 24 }, + { time: 17, verifications: 27 }, + { time: 17, verifications: 30 }, + { time: 17, verifications: 35 }, + { time: 17, verifications: 40 }, + { time: 18, verifications: 16 }, + { time: 18, verifications: 18 }, + { time: 18, verifications: 19 }, + { time: 18, verifications: 22 }, + { time: 18, verifications: 24 }, + { time: 18, verifications: 28 }, + { time: 19, verifications: 10 }, + { time: 19, verifications: 8 }, + { time: 19, verifications: 12 }, + { time: 19, verifications: 15 }, + { time: 19, verifications: 18 }, + { time: 19, verifications: 22 }, + { time: 20, verifications: 5 }, + { time: 20, verifications: 9 }, + { time: 20, verifications: 14 }, + { time: 20, verifications: 16 }, + { time: 20, verifications: 18 }, + { time: 20, verifications: 20 }, + { time: 21, verifications: 25 }, + { time: 21, verifications: 27 }, + { time: 21, verifications: 30 }, + { time: 21, verifications: 35 }, + { time: 21, verifications: 40 }, + { time: 21, verifications: 45 }, +] + +export const productDeliveryCheckInsData: VerificationDataPoint[] = [ + { time: 8, verifications: 10 }, + { time: 8, verifications: 5 }, + { time: 8, verifications: 6 }, + { time: 8, verifications: 8 }, + { time: 8, verifications: 9 }, + { time: 8, verifications: 12 }, + { time: 9, verifications: 0 }, + { time: 9, verifications: 3 }, + { time: 9, verifications: 8 }, + { time: 9, verifications: 10 }, + { time: 9, verifications: 15 }, + { time: 9, verifications: 18 }, + { time: 10, verifications: 20 }, + { time: 10, verifications: 22 }, + { time: 10, verifications: 25 }, + { time: 10, verifications: 28 }, + { time: 10, verifications: 30 }, + { time: 10, verifications: 32 }, + { time: 11, verifications: 12 }, + { time: 11, verifications: 17 }, + { time: 11, verifications: 19 }, + { time: 11, verifications: 22 }, + { time: 11, verifications: 25 }, + { time: 11, verifications: 30 }, + { time: 12, verifications: 2 }, + { time: 12, verifications: 8 }, + { time: 12, verifications: 10 }, + { time: 12, verifications: 15 }, + { time: 12, verifications: 20 }, + { time: 12, verifications: 25 }, + { time: 13, verifications: 30 }, + { time: 13, verifications: 35 }, + { time: 13, verifications: 36 }, + { time: 13, verifications: 40 }, + { time: 13, verifications: 42 }, + { time: 13, verifications: 45 }, + { time: 14, verifications: 8 }, + { time: 14, verifications: 12 }, + { time: 14, verifications: 14 }, + { time: 14, verifications: 15 }, + { time: 14, verifications: 18 }, + { time: 14, verifications: 20 }, + { time: 15, verifications: 40 }, + { time: 15, verifications: 45 }, + { time: 15, verifications: 43 }, + { time: 15, verifications: 48 }, + { time: 15, verifications: 50 }, + { time: 15, verifications: 55 }, + { time: 16, verifications: 5 }, + { time: 16, verifications: 7 }, + { time: 16, verifications: 9 }, + { time: 16, verifications: 12 }, + { time: 16, verifications: 15 }, + { time: 16, verifications: 20 }, + { time: 17, verifications: 15 }, + { time: 17, verifications: 18 }, + { time: 17, verifications: 20 }, + { time: 17, verifications: 25 }, + { time: 17, verifications: 28 }, + { time: 17, verifications: 30 }, + { time: 18, verifications: 10 }, + { time: 18, verifications: 12 }, + { time: 18, verifications: 15 }, + { time: 18, verifications: 18 }, + { time: 18, verifications: 22 }, + { time: 18, verifications: 25 }, + { time: 19, verifications: 22 }, + { time: 19, verifications: 24 }, + { time: 19, verifications: 25 }, + { time: 19, verifications: 28 }, + { time: 19, verifications: 30 }, + { time: 19, verifications: 35 }, + { time: 20, verifications: 8 }, + { time: 20, verifications: 12 }, + { time: 20, verifications: 14 }, + { time: 20, verifications: 18 }, + { time: 20, verifications: 20 }, + { time: 20, verifications: 22 }, + { time: 21, verifications: 27 }, + { time: 21, verifications: 30 }, + { time: 21, verifications: 32 }, + { time: 21, verifications: 35 }, + { time: 21, verifications: 38 }, + { time: 21, verifications: 40 }, +] + +export const mobileAppQuestCheckInsData: VerificationDataPoint[] = [ + { time: 8, verifications: 1 }, + { time: 8, verifications: 2 }, + { time: 8, verifications: 3 }, + { time: 8, verifications: 5 }, + { time: 8, verifications: 7 }, + { time: 8, verifications: 9 }, + { time: 9, verifications: 5 }, + { time: 9, verifications: 6 }, + { time: 9, verifications: 7 }, + { time: 9, verifications: 9 }, + { time: 9, verifications: 10 }, + { time: 9, verifications: 12 }, + { time: 10, verifications: 3 }, + { time: 10, verifications: 7 }, + { time: 10, verifications: 9 }, + { time: 10, verifications: 11 }, + { time: 10, verifications: 13 }, + { time: 10, verifications: 15 }, + { time: 11, verifications: 2 }, + { time: 11, verifications: 4 }, + { time: 11, verifications: 6 }, + { time: 11, verifications: 8 }, + { time: 11, verifications: 10 }, + { time: 11, verifications: 12 }, + { time: 12, verifications: 4 }, + { time: 12, verifications: 9 }, + { time: 12, verifications: 11 }, + { time: 12, verifications: 13 }, + { time: 12, verifications: 15 }, + { time: 12, verifications: 18 }, + { time: 13, verifications: 7 }, + { time: 13, verifications: 10 }, + { time: 13, verifications: 12 }, + { time: 13, verifications: 15 }, + { time: 13, verifications: 17 }, + { time: 13, verifications: 20 }, + { time: 14, verifications: 9 }, + { time: 14, verifications: 11 }, + { time: 14, verifications: 13 }, + { time: 14, verifications: 15 }, + { time: 14, verifications: 17 }, + { time: 14, verifications: 19 }, + { time: 15, verifications: 8 }, + { time: 15, verifications: 12 }, + { time: 15, verifications: 14 }, + { time: 15, verifications: 16 }, + { time: 15, verifications: 18 }, + { time: 15, verifications: 22 }, + { time: 16, verifications: 30 }, + { time: 16, verifications: 32 }, + { time: 16, verifications: 35 }, + { time: 16, verifications: 37 }, + { time: 16, verifications: 40 }, + { time: 16, verifications: 42 }, + { time: 17, verifications: 25 }, + { time: 17, verifications: 28 }, + { time: 17, verifications: 27 }, + { time: 17, verifications: 30 }, + { time: 17, verifications: 32 }, + { time: 17, verifications: 35 }, + { time: 18, verifications: 10 }, + { time: 18, verifications: 8 }, + { time: 18, verifications: 12 }, + { time: 18, verifications: 15 }, + { time: 18, verifications: 18 }, + { time: 18, verifications: 20 }, + { time: 19, verifications: 20 }, + { time: 19, verifications: 18 }, + { time: 19, verifications: 15 }, + { time: 19, verifications: 17 }, + { time: 19, verifications: 19 }, + { time: 19, verifications: 22 }, + { time: 20, verifications: 7 }, + { time: 20, verifications: 5 }, + { time: 20, verifications: 8 }, + { time: 20, verifications: 10 }, + { time: 20, verifications: 12 }, + { time: 20, verifications: 15 }, + { time: 21, verifications: 11 }, + { time: 21, verifications: 9 }, + { time: 21, verifications: 12 }, + { time: 21, verifications: 15 }, + { time: 21, verifications: 18 }, + { time: 21, verifications: 20 }, +] diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/CustomTooltip.tsx b/packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/CustomTooltip.tsx new file mode 100644 index 00000000..5aa38e19 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/CustomTooltip.tsx @@ -0,0 +1,40 @@ +// CustomDataTooltip.tsx + +import type { CardProps } from '@mui/material' +import { Card, Typography } from '@mui/material' +import React from 'react' + +interface TooltipLabel { + dataKey: string + label: string +} + +interface CustomDataTooltipProps extends CardProps { + active?: boolean + payload?: { payload: Record }[] + tooltipData: TooltipLabel[] +} + +export const CustomDataTooltip: React.FC = ({ + active, payload, tooltipData, +}) => { + if (!active || !payload || payload.length === 0) return null + + return ( + + {tooltipData.map(({ label, dataKey }, index) => { + const value = payload[0].payload[dataKey] ?? 'N/A' + return ( + + + {label} + : + + {' '} + {value} + + ) + })} + + ) +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/DataProps.tsx b/packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/DataProps.tsx new file mode 100644 index 00000000..a704a9f5 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/DataProps.tsx @@ -0,0 +1,84 @@ +export interface VerificationDataPoint { + day?: string // Used by the line chart for day of the week + time?: number // Used by the scatter chart for hour of the day + verifications: number +} + +export const generateVerificationData = ( + count: number, + min: number, + max: number, + chartType: 'line-day' | 'scatter', // Use "day" instead of "time" for line charts +): VerificationDataPoint[] => { + const daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + + return Array.from({ length: count }, () => { + const randomVerifications = Math.floor(Math.random() * (max - min + 1)) + min + + return chartType === 'line-day' + ? { + day: daysOfWeek[Math.floor(Math.random() * daysOfWeek.length)], + verifications: randomVerifications, + } + : { + time: Math.floor(Math.random() * 24), // random hour of the day (0-23) + verifications: randomVerifications, + } + }) +} + +export interface DailyVerificationChartProps { + data: VerificationDataPoint[] +} +export interface DailySummaryChartData { + friday: { + title: 'Friday' + value: number + } + monday: { + title: 'Monday' + value: number + } + saturday: { + title: 'Saturday' + value: number + } + sunday: { + title: 'Sunday' + value: number + } + thursday: { + title: 'Thursday' + value: number + } + tuesday: { + title: 'Tuesday' + value: number + } + wednesday: { + title: 'Wednesday' + value: number + } +} + +export interface StackedVerificationDataPoint { + day: string + email: number + mobile: number + web: number +} + +export interface DailyVerificationStackedChartProps { + data: StackedVerificationDataPoint[] +} + +export interface PieChartDataPoint { + name: string + value: number +} + +export interface PieChartProps { + data01: PieChartDataPoint[] + data02: PieChartDataPoint[] + showLegend?: boolean +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/index.ts b/packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/index.ts new file mode 100644 index 00000000..4adb19e4 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/Shared/index.ts @@ -0,0 +1,2 @@ +export * from './CustomTooltip.tsx' +export * from './DataProps.tsx' diff --git a/packages/theme/src/showcase/dashboard/DataViewers/Charts/index.ts b/packages/theme/src/showcase/dashboard/DataViewers/Charts/index.ts new file mode 100644 index 00000000..ad658832 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/Charts/index.ts @@ -0,0 +1,4 @@ +export * from './LineCharts/index.ts' +export * from './PieCharts/index.ts' +export * from './ScatterCharts/index.ts' +export * from './Shared/index.ts' diff --git a/packages/theme/src/showcase/dashboard/DataViewers/DataHealth.stories.tsx b/packages/theme/src/showcase/dashboard/DataViewers/DataHealth.stories.tsx new file mode 100644 index 00000000..f408264e --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/DataHealth.stories.tsx @@ -0,0 +1,44 @@ +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' + +import type { DataHealthProps } from './DataHealth.tsx' +import { DataHealth } from './DataHealth.tsx' + +const sampleData = { + comparisonText: 'Compared to last month', + comparisonValue: 24.17, + status: 'updating health status now ...', +} + +export default { + component: DataHealth, + title: 'theme/showcase/cards/DataHealth', + argTypes: { + comparisonText: { control: 'text' }, + comparisonValue: { control: 'number' }, + status: { control: 'text' }, + }, +} as Meta + +const Template: StoryFn = args => + +export const Default = Template.bind({}) +Default.args = { + comparisonText: sampleData.comparisonText, + comparisonValue: sampleData.comparisonValue, + status: sampleData.status, +} + +export const HighPositiveChange = Template.bind({}) +HighPositiveChange.args = { + comparisonText: 'Compared to last month', + comparisonValue: 75.34, + status: 'updating health status now ...', +} + +export const NegativeChange = Template.bind({}) +NegativeChange.args = { + comparisonText: 'Compared to last month', + comparisonValue: -10.47, + status: 'updating health status now ...', +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/DataHealth.tsx b/packages/theme/src/showcase/dashboard/DataViewers/DataHealth.tsx new file mode 100644 index 00000000..ac126df6 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/DataHealth.tsx @@ -0,0 +1,95 @@ +import { ArrowDownwardRounded, ArrowUpwardRounded } from '@mui/icons-material' +import { + Box, Card, CardContent, CircularProgress, Fade, Stack, Tooltip, Typography, +} from '@mui/material' +import { FlexCol, FlexRow } from '@xylabs/react-flexbox' +import React, { useEffect, useState } from 'react' + +import { earth } from './img/index.ts' + +export interface DataHealthProps { + cardTitle: string + comparisonText: string + comparisonValue: number + status: string +} + +export const DataHealth: React.FC = ({ + cardTitle, + comparisonText, + comparisonValue, + status, +}) => { + const [loading, setLoading] = useState(true) + + useEffect(() => { + const timer = setTimeout(() => setLoading(false), 2000) + return () => clearTimeout(timer) + }, []) + + return ( + + + + + {cardTitle} + {loading + ? ( + + + + {status} + + + ) + : ( + + + + {comparisonText} + + )} + > + + + 97% + + + + {comparisonValue >= 0 ? `+${comparisonValue.toFixed(2)}%` : `${comparisonValue.toFixed(2)}%`} + + {comparisonValue >= 0 ? : } + + + + + )} + + + + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationList.tsx b/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationList.tsx new file mode 100644 index 00000000..6a30cf34 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationList.tsx @@ -0,0 +1,73 @@ +// VerificationList.tsx + +import { + Box, Table, TableBody, TableCell, TableHead, TableRow, Typography, useTheme, +} from '@mui/material' +import React from 'react' + +export interface VerificationStep { + name: string + time: string + verified: boolean +} + +interface VerificationListProps { + locationHeader: string + regions: VerificationStep[] + statusHeader: string + timeHeader: string +} + +export const VerificationList: React.FC = ({ + regions, + locationHeader, + timeHeader, + statusHeader, +}) => { + const theme = useTheme() + return ( + + + + + + + {locationHeader} + + + + + {timeHeader} + + + + + {statusHeader} + + + + + + {regions.map((region, index) => ( + + + {region.name} + + + {region.time} + + + + {region.verified ? 'Verified' : 'Unverified'} + + + + ))} + +
+
+ ) +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationSummary.stories.tsx b/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationSummary.stories.tsx new file mode 100644 index 00000000..dcdda307 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationSummary.stories.tsx @@ -0,0 +1,127 @@ +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' + +import type { VerificationSummaryProps } from './VerificationSummaryProps.tsx' +import { VerificationSummary } from './VerificationSummaryProps.tsx' + +export default { + component: VerificationSummary, + title: 'shared/VerificationSummary', + argTypes: { + comparisonText: { control: 'text' }, + comparisonValue: { control: 'number' }, + status: { control: 'text' }, + }, +} as Meta + +const Template: StoryFn = args => + +// Employee Check-ins Example +export const EmployeeCheckIns = Template.bind({}) +EmployeeCheckIns.args = { + title: 'Employee Location Check-ins', + comparisonText: "Compared to last month's checks", + comparisonValue: 4.5, + status: 'updating location accuracy...', + accuracyPercentage: 97.2, + locationCheckCount: 432, + locationHeader: 'Location', + timeHeader: 'Time', + statusHeader: 'Status', + monthlyChange: 8.9, + monthlyVerificationCount: 1842, + yearlyChange: 5.3, + yearlyVerificationCount: 8407, + currentLocation: 'San Francisco, CA', + regions: [ + { + name: 'Daly City, CA', time: '8:00 AM', verified: true, + }, + { + name: 'South San Francisco, CA', time: '9:30 AM', verified: true, + }, + { + name: 'San Bruno, CA', time: '11:15 AM', verified: false, + }, + { + name: 'Burlingame, CA', time: '1:00 PM', verified: false, + }, + { + name: 'San Mateo, CA', time: '3:00 PM', verified: true, + }, + ], +} + +// Product Delivery Check-ins Example (East Coast to West Coast) +export const ProductDeliveryCheckIns = Template.bind({}) +ProductDeliveryCheckIns.args = { + title: 'Product Delivery Check-ins', + comparisonText: 'Compared to last delivery cycle', + comparisonValue: 12.3, + status: 'Delivery en route...', + accuracyPercentage: 99.1, + locationHeader: 'Location', + timeHeader: 'Time', + statusHeader: 'Status', + locationCheckCount: 5, + monthlyChange: 15.2, + monthlyVerificationCount: 782, + yearlyChange: 6.4, + yearlyVerificationCount: 3056, + currentLocation: 'Los Angeles, CA', + regions: [ + { + name: 'New York, NY', time: 'Day 1', verified: true, + }, + { + name: 'Chicago, IL', time: 'Day 2', verified: false, + }, + { + name: 'Denver, CO', time: 'Day 3', verified: false, + }, + { + name: 'Las Vegas, NV', time: 'Day 4', verified: true, + }, + { + name: 'Los Angeles, CA', time: 'Day 5', verified: false, + }, + ], + finalConfirmation: true, +} + +// Mobile App Quest Check-ins Example (Quest Completion after 5 Check-ins) +export const MobileAppQuestCheckIns = Template.bind({}) +MobileAppQuestCheckIns.args = { + title: 'Mobile App Quest Check-ins', + comparisonText: 'Quest Progress', + comparisonValue: 75, + status: 'Verifying quest progress...', + accuracyPercentage: 100, + locationCheckCount: 5, + monthlyChange: 0, + monthlyVerificationCount: 5, + yearlyChange: 0, + yearlyVerificationCount: 20, + currentLocation: 'Austin, TX', + locationHeader: 'Location', + timeHeader: 'Time', + statusHeader: 'Status', + regions: [ + { + name: 'Round Rock, TX', time: '10:00 AM', verified: true, + }, + { + name: 'Pflugerville, TX', time: '11:30 AM', verified: true, + }, + { + name: 'Cedar Park, TX', time: '1:00 PM', verified: true, + }, + { + name: 'Georgetown, TX', time: '2:45 PM', verified: false, + }, + { + name: 'Austin, TX', time: '4:00 PM', verified: true, + }, + ], + finalConfirmation: true, +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationSummaryProps.tsx b/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationSummaryProps.tsx new file mode 100644 index 00000000..bd00db14 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/VerificationSummaryProps.tsx @@ -0,0 +1,112 @@ +import { + Box, + Typography, +} from '@mui/material' +import { FlexCol } from '@xylabs/react-flexbox' +import React from 'react' + +import { DataCard } from '../../StandardComponents/index.ts' +import type { VerificationStep } from './VerificationList.tsx' +import { VerificationList } from './VerificationList.tsx' + +export interface VerificationSummaryProps { + accuracyPercentage: number + comparisonText: string + comparisonValue: number + currentLocation: string + finalConfirmation?: boolean + locationCheckCount: number + locationHeader: string + monthlyChange: number + monthlyVerificationCount: number + regions: VerificationStep[] + status: string + statusHeader: string + timeHeader: string + title: string + yearlyChange: number + yearlyVerificationCount: number +} + +export const VerificationSummarySampleData: VerificationSummaryProps = { + accuracyPercentage: 97.2, + comparisonText: "Compared to last month's checks", + comparisonValue: 4.1, + currentLocation: 'Burlingame, CA', + locationCheckCount: 435, + monthlyChange: 8.9, + monthlyVerificationCount: 1842, + regions: [ + { + name: 'Daly City', time: '10:30 AM', verified: true, + }, + { + name: 'Millbrae', time: '11:15 AM', verified: false, + }, + { + name: 'Burlingame', time: '1:45 PM', verified: true, + }, + { + name: 'San Mateo', time: '2:30 PM', verified: true, + }, + { + name: 'Redwood City', time: '4:00 PM', verified: false, + }, + ], + status: 'updating location accuracy...', + title: 'Order Progress', + yearlyChange: 5.3, + yearlyVerificationCount: 8407, + finalConfirmation: true, + locationHeader: 'Location', + timeHeader: 'Time', + statusHeader: 'Status', +} + +export const VerificationSummary: React.FC = ({ + currentLocation, + regions, + title, + finalConfirmation, + locationHeader, + timeHeader, + statusHeader, +}) => { + return ( + + + Current Location: + + + {currentLocation} + + + + {finalConfirmation && ( + + + + Customer Confirmation: + + + Complete ✅ + + + Your order has reached the final destination. + + + + )} +
+ )} + /> + ) +} diff --git a/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/index.ts b/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/index.ts new file mode 100644 index 00000000..36c0120d --- /dev/null +++ b/packages/theme/src/showcase/dashboard/DataViewers/VerificationSummary/index.ts @@ -0,0 +1,2 @@ +export * from './VerificationList.tsx' +export * from './VerificationSummaryProps.tsx' diff --git a/packages/theme/src/showcase/dashboard/DataViewers/img/earth.webp b/packages/theme/src/showcase/dashboard/DataViewers/img/earth.webp new file mode 100644 index 0000000000000000000000000000000000000000..3dddbba6646763dc7d8f60987c0919779cdf3b62 GIT binary patch literal 161638 zcmd3N1yfv2(Cz|@ySqEVA-KC+fZ!|ycVC>v69^vMH8=!^#WuXSyIb(!!TsZ_d+Yv& zTXm*t>P(%Qt}`u9Ki#9Fte{{9h6j9>m(kMK5;8yo0021e!y5U2A89o$B}Wec0F$BL zc~xlU^$T;mSvM{ZoCFP?B3yZ3bqZOo7l^s5DBP(g(EM$+g*lnQe&tGu*C*-%q{My} zy8e=}oxi_F`S<87YC!vD~63PYh0byAH4ZIv(ja5Zxq9;L)5^GIKvI^^2fqp679NE_n-7V@&4$kMl9?D3NHB7g)O|4hwS33Ohl-3o0wm*r zzO+ex9NB?HdOI2hcsA9F%F4=-%1VYLpEbJkla3hL9}Pn>4LU~nopC7nc(^!#O&iD% z;?9te$Ks9Y;*IR&_IDn+g39WchOy)uhZO6_J2Qi+WzuFNOk{$jkxz_b6O_cI$vXC! zB~=aVA4)&k-IsiY)N+wL-_X$j;CZcvNbqY9+G-E{y3a*q+y;KI@64}zX^%}>91<<)Jtrd}3_Bvr5}OnX7Wk-G5xiOQZJ?sbFHe4um=05K7&<@zyG0tY~W zz;&W;U;ROTp5HM(mzRrz3{i4@UpdvEjUFGbvajZUK4Y1Q<_S5!EKvGW`u#CH%`ClW zeZ-Yd{lev4dweB-uinSM{pQ;h`<|7n|Fe{M_R`Xn?J*Yz2!N*nVKfDQb~|^yvpy0w z;nrhfbq}l7&Dz==97m;d3*a6^?FcUy>q;KVpr?ASb2GCi zicr^QRqv!Fczz;F@;f!FTeSyC^mOO!0hM}ML!|(~b1RA@#ZwLF;_1D^LwY_R7pUIb z+yNe7^%Vg4it>hKyB3$#B@LB79&NNQgmol*FI*r4B)*QzJ_<3wPXuY}AMzuga)UI! z;0#&useg(w3X>jb5s2B6jQC1-(iClM;UDx-T~(&xfTw32&D6{$TaWGIv+?(9=?E!m zgy6yP&Shu64zyhX0~NzXmtjoS1d#_#Pi z>@ZsuDGkK^2=S9KCxwIC`WuAOjeN(al8)Awt(D)Ha0)h8kD^?B0)CZm^tJYg-;VAb zHKqn{E`+>DRWoO^e~y>c!4EQ!)1}{$wX~?>TXUSq>xqGdP2Tl5GLE+C0>&^!#(TF% znbZF^(&EqnrhZD(NNo#EPn^{sxy?MBa@Ae6POZPKo-WTE`Th*anKf3b=~>NZN`Chi z+q3$A!eyAqjPJmEM=9Ur8rE;RQGd2G0i>*cW53W`AJp-cOv=%a=mGOHdL0u)YV?1O z?^nsNg>Wmq1(pHo9}dZlSWlZ;R=CV{AzybXa@JCT0F?V-30{KJuAS5Ie6u}Jl5PBP zL9&iR(VgF23zIMmnRh!HF1vQ?>R*B6Nu)@3Zk@-Y(7wE=;%btX$c7R;z%AOGBYylY+pvU&L|igR57}u6S`$Z?~7_q@iQUYRS21#!pYC`Ls0LoD^jZm$6kD zWOpx&u)%*5+5sM2Y57sTn?b&7h4v=8Q!8XG7Jd)^=zwq+)q=AwViLi26oZjx8`}bBCBh%WY#k6{HG9k+Lu%}<2^w3 zQWl<-0b0)fuy$<5c5io$)qOr068tF;1HOnHi;BW8n_xp>Kgw7!K->Ls)Ef>^6m&l? z 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 &FnMnv=%qOC2jk%$5_t(<=w{bwA5 z{|5$ev|`OV8F0mH);+!h>sRk_n7v+%?9%lu*Jw~$Z}Q-Kib|ZvlXP+w54j>8V}yV8~zveQkF^`Upd`0Hj_t!~TyaZ?uTJ$cRY6O1do@ax`DZB|pKAd~kh1 znP{r1p5__Y`9y7`0$1hNA7vza_G)0ueU>!2sCsck1Gpv~8i;S9lD~4U#~w-6%&=;D zAA~o~Br}KwmsY)jCQvFK4Qs7mT zVd#$P-CHs%@@3O^s1jI+IqYrD%*L@6UA+iGM1EI4rYzN8uoTc6^LNy#>BoakQ7(c= z!g%6TU9IaRVY=bB{jpY*5m{~--RVNa`6h7tL2dSi6hZ`4#mf6gULQCXW0fPxu(s6R zk8196V0JU^7IYIzw^t-^YHo+Dhz@b+wDspaC6+Bmn%G_lV9K5QDCmj+5bxU`6&!~xyeIm<0kb_JB|FvsgpQf z%x6X!;j;_E0-PQ|h(18@G0%Dt?Fn%JvoKrmaEq_O-w(6i72#6uuhq}%=nmyO!^<(S zVNE5^KMwAgb)%Mnisv0>ajNPcP_EP92H=84213CiFui0o>7W=5YFOUO*cJIp-W=H4 zsN&q&J`->lFH|H)!N=l5Lip6m4>)Xj?QRT;T!or>0?v&OvJJE(zTjj=E8km9B94-8 z_iFVwa=FH%V;8XX8)U>TJQl*_)Ut$E;9XJ*GHQQ?8hS^#2G56hVCp?4+}*hsCp7|q zQf%rznSvE^Vu6kEJTF%$l{6+ZU%L>CrK#iAH_urmCN{WiR|vf4-$*5ua+0_bnW%u> z`fxh^B6e5HYvga!GRxXIB`CEvQTUmXxs&Z%_bk1;A9WXdo~W!{#g>#l+dk2*53^?D z?=qu`%+pe1J5p4F_&tIC314UWfJsuhJI}Rasy)M-+BU{g)aXjJ|G#sWmc(=FHi9Cs z-jrZoymviC-iz)W8HDAm^ryyPY`DLo+N-WvV`ze&GcL`VoUe3yZclEAQ_DGUXbN5% z>I#ZuyN}OcefBwo^Bal&;=Nz}K%MADB?lX2rU+5ds#`2ov`3h|ivkobSf5W|t1t8D zfEqnp5(IIOU%w&INl7qChllFmrG1~2nC2%ph5Y0o+J2ETQh(E}U#vIlp!TDNl9Qcq zCy3-Te?4H^F*_i2pG`sKnX#Iu<4571qf#plHHdnG`D%Iq-c5N%H0NyVjD)(4{gHF^ zDOC*9D3+|#pQGXCsi+BB21+S8L@LZUC31^T)5dhw2&rE4Q^cd} zPf&5YXWB)Vp5OM!ppKl9hn0gg;Npj};~p3m=_QT(uF_iFib#gsYzTaG89093ZkWN8 z$1UQ7(e`(#`v&&=kheF~i0EJH)Fm-Y^E(W#oC&8m>3=i);By-_w}k*TofeCDetdui z>kMF)K4Znc&6OksJRb)5D*|-jNV}9sV%)aZ?5bv~G%DIrIrKGS;XQZznFFZ@>9ul0 zs#?j-iLlv+<8O=56D4Zg0MpV93GkIWt?qF}yvK%8-n1Dn z##-m>kEKwQrY$s}I4*=fIBLcYUUo9@iRWRpqB@vSTdPMU z;46}`s_2B2s3SEyNR;&l>ihs$qPDw-`xhkVpJ~SjLxB?UHHDklMY*Y{#G&OP{)jo7 zCTc>*bkC*9u)}KBO~zhvv4pP^G`*zdn!|A_xP)i)OgHWa%_iE`F|z_;eakZ{su|o* zS?)Bb(&9rC{mW%QSU8%6Zdv)W&j!!qAAl^AySNtOZj zr1oLCM#3h~Us#U|sz_&tx`^iwqftfE!3wC-rvbb@U%fO>Dh~Umr)A82N}a~@UBQDT z^IcdKMY+ms2dXxwGE_7N@@Nzq6~ZJ$UI&e4!>!-^nsrD3VoDy$V9hW@o!CbeDlSFg zUn5hY=mBiCp>yza!{r^K5MO--)wq7YVJ!K7xIY}$_wFGzM^6a3FIX2X5L z=eP;a&c*!<323c{Lrk@cfur$@E@BaA0r*KNXmiz`mJq2e!Nv*{xco{{^NGID&kDhF zf{rLsapIkV7QrJ_`o4Skai9!K`64y|#xhkLB6o=e=CUjDv%64$z`{#dk4;(Xh@V!` z%H`gap>w2z{zo}B@~acj)Avp>@sEo){ir0R39v%Z%U(gsgRwVkl6joFMukyU!`H{K z^Wp6?5+qIADbXR}1_;UGalGAq00Md{Uliw>5n6RoJk=U$kd};VObfaXb3D||I_2PA z6#IR8(}7G_ZO|0ITRR?eDreDw-6_obiNyXn5TiBA+h&7$J#vp9J%T+h)6DjQ^2JOF zpDv48D;qPHP{m+RmDmyu_gWPiB6x-WP+lOTBOkXsp0+B$tLo$B{#)zjn+gXI-VOP>d1T0 zdITq>2T&ulkzu0hz2945i=$pRz}0o0+DiwH7Kh5r#!*xQ{8O!3krBE~9W2x8`JC;H zXj{@rGqvm6Q)O$oQ^!_0!nljab@*eyWX^;61~m`L)TJ>;HbTri7q&^Ms~wK3HEmj? zb0%ldrKsE=NP?_p+ zp1$6glQjYC+~)uz0)jqX^ms0r!nCLhyU-}whrkQ@H0g$VLv*<4j?dlvAcxE= zeCeCn-|;K$hnBhxm4)UQ6rTiwPV5BbU-SgWBG8@bIol}Yv|dCV>+M5$fdrOh!MB+C zYV~}O&8a(#GYTEQIktB<_wOX7k44>m%oXD#TXjyO0`cf7a#dNxaKXl!+w8ag3}z++ z`gRA<342tvy8`qeutO$Y9RVFZf7~eZ$!fY3OE6HB4uei0w&>l&-s>0NO*2N8Dt}lq zz6_mPEm^*LFT>7)(t6hBBxK1elHuym;%~n>uYzpXFqCXDpG9FLkbd{QvX-2eayy;)A3hSoKpK}jeq~D#=dw%`GN>kt2@6@f;cHQ>PCmk zFYqBh@EmYEs90vR;`kxF9sI)*6G_uY;xK6c zY>NR$NxLqIx7H)%;ji5clQt{5V<$9Ppui+^9NIZrFKI;rBb%}l9mNTR^;#31g zf|Iyiy+C_5a3Cw5XcgE1q8GU^rPDSO=`e&276gR3^2YdQcW;wnXE$z00qDMUQGi&w zRr`VTv-5g9xd1NM2fm=fcpI*gHSH`z8zDil5SM972gU}~B?x^#C>=TYb{(qyZ@w}; zj7f9uA2e_DzY|#jBaqk-BEmDo51Q6pT~)@50)aNzSgL_g0|-HM0F0nn(<0+tfZ0`E zTs%v>#mU-ikXw)$JWnh2#3<^--?#Rq3aVaP8#=8I7eGIbTLQ}z2<1q?BD=Ts+Gq77ckoCm6eo-B3kS3NA7`kl7+#LjUSiTRwTR?BZ>l zeLeV3D~X&xk#G=kb?Daaj=d5gOv7_4vMBum>Vpx}0xy`0kChB> z2>_s^p(cX39LWmLfn+pdEniwfX+IAkdD+J`!s|Hyy(2Zhqj3(qi0q!LxWwr%jvgUH zHD7eF)#x0}X{dv{2yQin;zEI{>;Y6x1ar=xAaKa_u@ygP~ z6Abzzk34kdxj=eGZ^p0wzYz5Ir53d5h3E(Lu1SLD!2sANzkT_I_|Li0O z{ycp@Q&I36yAa&|0qWzvO#OPpFNz?a(9_B6`US%BM{3Cw7`tuJ=n$Fx*4T@wVi`kF z6O|a&H*Pi+R4dM<%w4@&b;PM#1JMstxW=bw7^^*8al=0G=Ex6tL>bvLKmXz>*Nq8VFNY;< z0#h>5Wkk0x?4ER#C5p`sAcQ5ZAwv1=Pp~byaf4(yVRi$YWAhb$wqn#cA?pa5l;%XO z#^4*uLplSP5q-^czL^dek8K$GRS3L3UrCV8H{jDpIeteMXniEmh?RthEm; znihkRdsJoxTb~qSDt6xy#6)u7zmMiity&0zzhd2baqw=|88yR4TdL%VmsH?cxOh2> zasbgD3x!)#P&T%f@T~7a;P~MV%xMXpbEpF8b~Mkwe*5Eb#!M?H$&ROv%|OdPg9J2< zAghNcJ#7SnNvptA*6m!aL9XvxzY(h49 z7+8xFDzxIL8qNpOxx-!@`F@}DV1!p>^1H=6Z~yyp86)Jj-w=ggWAcj&MHa; zsc_^{2$1`Di}?Kro;~e$5-vU^e~MV(lzx5PWmVpB53WwUi-+b;I5DB9z8G(5+BGa6 zNl56hDzPm{1NQ3>^X^JE&xHVS^*N(a4|dMXWHdI6jCjIP8E%QRJA9gotw2&>FrOfl z+t2v-OsLH8S@LU%5pEXNizphw$!a1NPlg0D*SKuBK*EZ> zl~6-EJgiMxtf+B1z~g{ZCOwsKae4BCuezV#F%Ri}L3x3+T$VrK?4GBJMXG>a=_->U zPOj`%#2KL`9tr%8n*wfX zG8*s*L(2LsNV_fJ1ep-DSl6(F)xF)Y`Jwsg<{o*7ajd0T89M=aN6JeviGVcc<4jZ4 zE97eRcpYQ~Qe4c~@h{_BIEP9vB42@=^vmNh&-#4tYIb;xr)e-92!|;{Ka!V84Z*116_P$a?(2LR6@w*G*y)9(`XAU)tbSj$pi;?pQpSK~$z&BG1)F zU?R`Cre!P`Bq<3Y7D!&mr@}LWr~ik;!Z;0X^GM z0*3s#(bvymtymqCS&SQFWuye4((GaGUF+Xxxu7y{PU+kyxe((6S|GId&5%Jo?eOjjnd+$^%{=jx-L#X2OW%_Jy!mJN00yHwG{6`#U zJLli}E!Ml0-Yh)R+C9BCC2w$S#IhpB<9%xp0H#&&o#vA4`7wEBMB`i{jSmS$7i?5~ z2`?hnPmS)v;-u3=V3L93I(PYwv8x;B zPO}9Sbr=Fq>yI$seGMPEv9Fs*^sVmBMYW0C#dy65xpwme+~JgP2CP5=sJGkHD0n|1 zyQ5$oDTYP-g+6B1!+T))MGelBCgp4_E#tguSSTMbPX~`LWiz zbWst^kSP-$pNf{_d;lDw737f`$_K91V&UN}6o5#$E30@8UFoiib(FGI_mc}?ebvzm z+ENq0-hCWNq+p(kk$hVW8RK^hS}Q?E%vCYM!G>5$r(<+S+&Rj&yqs0u)agyJz?MBvv@v% zPg*gtab`0a9@}d>Wbpx6yqWZb-K=*Gc&m0!biZIQy)9@l$F$SUK?+Tub|gA3=FV0_ z4;<5U^zKOYKd|G;gF;^MTy)k66Fz`pjb8CgcV{2s=|J%9v`PK$WDwcW0j+Db`&3fS zXiiHo&}=vAYb}=(V;BNKu=CoPU6B}lt9W5pWRbJ1r+x*sfmM&Un3M! z0tNiL?&k9%Lj)1R@-&^9FZrl(c{ti!%J3Ldf-}&ohL9%*H?Sx065Xk2WLPANV)_f` z;Tk`ZGnv^dCNoLx8=G#X=-&j>_`h%1sG$GW*5!`UIdhps;+M$9koTZ~RcLl4&Xh(8 zZHViP-_<#6aBPy+X&BT#&%pFvE9N3T=>p4Kst+CTTRftsWPsBe!0P;gK&q3RK3t3< zF#UbQVYgQFSRLld7w|YN3N~?17z-vXGHvm-uC!+nM0lJ*nNP*^q=l3kJR$}n`)e$( zslU3XbUb38c2FaAV3jZ%!3W=$P2tKSrlTE-x-vZ067angKd`~|t4kb5Y(ftxo|Flg z;i>B=4N!F)!*K$bukmGM(v`!_Ze#f|BTLBgeprv@D>}cD_~r~oALl%kB|nmhM;i>N zOKUBD-m>yD9)qj^G)e>-BMglZfyUs5@V_N~6tNO3)^6S90{j-BAErGC0lRFltPd0{ zW4ib|MGV_HoX_i?$idYpuD7c#I$hCyH z1aa7=#O=-?uR!&4#l~6BOJqRZF>A=4j1OUmipVgJ3@n zKXIhS^FNk!#Zt=nTPo*QCD`4AghSWkKQ9;655VlLNe!Z*o3Di{uFa-gJcS9U(Y+u#`?o(ZC2D3(S;hczK)f z4+;^cKLzrGp%S>E)XovM17UnD42H_Glk;3G>}|ekS5uA#v<|X5>`VC1jPingm+pUK zqk=NLXbg9xNF~H0OuO3iddHqpyy2?KYi`EOy9~o1p?}ootCO@l>Fer#pJp$#jpm2T zQncI~#HbPfyu@4Ju%5);$zNC_5WeKs#bYSX5qkaLJRv0P0?k7(IPD@s+Nrr`K7`$u z$|xUMuS199dw!JAI_iwR4#MSOu-G#&M%|VDP6}Ki z^RKGdIZzIW#1+f0)cMEKNGa%|H#HLyH4I(I1?jA}vt!zy&0+Fgu+JfigDJ|Dj}YPB zO7x96K|b@Q+rWAo?vCNRqqTtN4|z7qXx29m6-6;s7&SA@>yBud?wUV+s7K}to}4*! zhBoa7vm?~!HZoT_Y-KAU!^VZCp8>DMwwsJ7cmL_&SR zC$sCy|KW69q4Owu8+{3yao)my7KIjYPUb_QNZsUsmgR&T3EP6?&~{190(iqI9cO2tXI% z1l{Jr&-+uwzv>c}Oq-W(NcOJ+*+JVO=#7ZJs42?nX8GS`@?T4>J-@Wt2A;I2X+$%? zNJE0n@2xPpU4LVzJVc!yazgW~Ueg31!lu~8)^y6|A^R~CCu@9T3Y8t1ob!fl9$UD0 z(2nRP?L23PN^O@fTIC%mn&nkB?-|i)00mCyUl@!Yx&9IHhn-(Nz`_H)InMVqe1UKl zD)p~z=AYqP>s~+&%f-`Y!xZ=A{5wbi?sIU+l3*}p{+^XBtvz^GI`)#1zTX1W7O$p&%wpK zNwJ&$FBGVM0Gb$tzs-sLJ@`GNF6*h3M5qz7IyO3?5C=m)W(nMu;$FXhZpdT*aSL`b zRf2$s_QIj|>mE!6jiBVrBu!Lt;)OXVovQNl)GyQ@c0sF9PA=vh4M0cmXJ*qVI#Iu`x;qB0|ytY_}CxFLS3~ zG%omG*w17q!Rw3JT=sw1EgleuEUbjsR=2Xzy7uvMzQ9-XXmPbuX*%g-ne>j7}Sd9mEn16#kgB>~>RB3of<`92i` zvKrJRTcqa#%TogRWRkz3&JN(M>(?Z3IsOAr{TCTV#G;VaVY8ZOJ~d*MPOH&WF<&v0 z^6C;j!Bh@xUL~Z>z6gbml(P*Xoh~y^2G~@iA2oI()VR3BmoGi2<+R^MP|{oekAA^#hC|C?B*j-B->bZ< zNxk|MCy*O~V~)Ze@ocGQo)YDU|9}twsl96~$U;F9bIZV=*-u>1vP^F2PAG%r3BL3l zjy<#?*%0+-$sM}wb^?N95vl%+sY|+7MMBrPke!*3xoj0ZYys}Kyg)vGOd$WNCIH; z*oq+#7WHu`B9>W!hv#$nPn=eseHC0)9I&demNdv z_LB<*F%Ck9eZL{c0a9M~kr#3}Y@GSJaQ=NHzhQ#!Xu)sHpf85fe^u)KYpyr?G_4X@ z@;mM{JJcK}_8G>t?u7yQ)wZXH6_Vxrwz-0A!jq2}y<=MS&jX42Wx9&a{R$A5=+MFTid)YoBs`*Q%v7VrXhFSX1bJ>Cs!Hv zvFQ`kB`v0QD26qhPB^NhQWUKn`psVEN<0pdVqecAImH~5cb@z|{P%x9oyAaYf&8cW zmmwj=k6lNy1$i_o=CT3xJK1or0Mr^hGjlajcCRI}el0w^H?kE-#(l?l*&w1KR$g=~ zdF7aLIURT&Ss3r8mcx?613K4$bQKX1)owGc^-TM63IIu4Z2) zB6h4T-kf&tR(m2BLh_sn8<1C|zx5&i85#fl!hf`a1)u&alX{#)3$7aVJp&5bW2s2l z!c7q+2f|-JFWQ1)7r0TdDQ)y+Yi`H+3xTEZ65doMX2Y&3U?5?Q#Ba=4GQ3nHB$gFe z+7_4s16b;^=RS9LCe1GC)Mtg%>dHcx4cm^O;j=$yB(R!BFK~L~)3=s8GX!l=b!Xw= zv1Px=t?r@!h{_eGna(_6uA{gne(XnxuWQ8EY38n`szG@*nCQa{W0I@b3iLl3*#B`D z(y{x>{x8gB{1>B9H5=}}Cy9<>rzs0C8@4y(LW`J1JmCX@t7I8xZs7CcDoT-F8%6;7 z@%FxOGT~`QAD$xRQU;XM>B5896VoWz;3f^wNe+&k*_;yN2Kg8x@(DeEo~CTb?Utt( zkP-7+d_A2xrsiYvJ?+Bj1>1{La6+yoQ$1u6&R{GgIPh5G{`X7=t+sJh^bira$cQF4 z%|{d}-Y3m`r>Xzhu_Gx2A%|ea_e|uW{_7kLCG9(lafg}>+3AGu6z0`ZCUmII6g`suFJsB(suhqDB?P6-b3~uOKQ-U^>@s zAiXmrxwX{@;j^9sUU2Z$Lc602;nG8;EI-;st^XzLyc@b9qWKaWKGOGNz}Mf)F(p?`9; z|B{%^i@Y_Fqq`7rXq|D_&&V=qq>IrhnHmeXFt=)m1zk9uK2nGTkv1S61)CCsKi2F} z7fl#C1#6eV>lz&S_0Vln0{fb3T74(m#7$rsf-M>*#yv?!mPu>gnB>X@8?4SpX(Q4@ z@xk0X({M3xkDRYqo-Pr6)US@SeHW1iP<}wpN2<)UGX4( z%J`M(G|ByfudMhs^dN*8^)AW?)5#|-Fx?c>g>b@;wmpvywah*JYPFO&hYrpcF@d!( zS)sJF@``}}T5|q-^8Sqt&r;(4-{{1DU2sJ2I+^}lf6f)QY3X{JX%2n+c7Eko<3!rz z@Bqqd4V%Kyqe@@BB+$CeA*RRL#!_&G)X`W4wABc$Ejf+n+5b=V;@=7Q{~88534s4= zg{8r-k$4Z^&(9iI-*6*k#1=x>KAzbkx%X_@I#9*i_BPD_((lmoy2{Va))_t)j4vh2PcP;cyxx=GZStc+QT?G!DZf z;g1?A_|jD{4tm&<=6vl5@o1G2@B=}+M6$ESNX$pfjMFWZUQ>}h-T zPmdlkgy#Ma{eCv9X3q>Njp}4O`2pGA@T?uj05sg7)rL2lXSmDHS8|WoJSDU{MVQ-# zx?PHuZ7lRtAH&OO+1~TJQ2^Jcthr-hwa zn?mb0eiIvk@xk`#k|5BN(A74y?&`Ue-NNV>{MI?BBY$+Wk&V|XX(5Q#x#TgNpHJ-d zRJ<7Y+H$Fl#xkQwZJO~_c7uIe#8Gm;YT-(83zFDZPxQ;!lE$;MYl=al4*7`3V$mCn z_>XH=G>}<~jrG_ID_D!0J}Z2Wfr{v67%f6^0?W<3w4?05V!C`(BvR+75ou|R*QghYT!Dt zCTYy&T5hC0e|w`qKICrshG40B^@}=AFc2zend}Wj4j+(Dp_u*!Hf4gcD9TT9!uZ;_ zhSQhPC$#KRbXmSxr{+dg!7KN|%;RKw#)4_f#&c(HSAK3sY0gs&E;2&j7jef@!%JP{ zk>->sVzOXhnx!c5v4jGhx8Mb|olm{K1*6#1xeIX5bTA=P77KpPe~M3S1VS{QhD zg$~rsf>~~}*OpZIS?Kt#iDar}QEvC=C`G5MhnVNb2u}T)a&d%$AwpSzUT3|2Q8AF% zO;s$_5MCdg2fE`z!MZ?!q+K*6Y;OG|Wp(xDV6)8(Roo7cqaC@8Y3PZYImo+01Bx~B zZ>VP<+pq^m&7*hn3LHn=00oH_m{y83jAY@yG-glBWpJ*KAHW$eMItEFwhR~gMDPct zZqQi)pKzc%A!qO-YjxLPMtn*_L;`8l>=KNE{Dl~kQyoItDL)yb_F*@!!iP{B;qTU$ z7Zp0LTb5dFQFJU{9a(>z&*=D(Yv{Y_JJnIH{At`hErvc$g+2yn?q8&n)+QV&xk2AhDiYtIpb^{ZmuyBK9~Jh4N>-{YhX3$ev%UaHhd!WPEAzO_>?XuWIu@tF<6wk_aqjJJ}g<@w$+76)_l_L|4MflDe7S*d4)NUY2^7X&k z-9t3VG!oR2G$1#~On@fU<&y4u-Ivtfr4rRHBD`y+3}Vvdw#OXS>nZ95&Kxp`>t zLbt;P>UqM~)w(LJODo z+#5#?b%n_MEJzw^^Dgah%Ww zY@2t45K;||PPHiznZ)p7>A>+xcjNB4$$CR`_t;X~Yih9`8GgGiUsG$|K9k_1A7i!bx`k&t?gCxq-|@vt!2M>r&j2d=AqM$M6!b(l!KYtesVXaRj{=jEjw%;(WftRRr5_~s|%=VdPWF} zwmCSX&8+{$yFU6je3U8aI;#NRuelj!F7b2B?^N#nq0`CP1M9aQjA0*w!*cl_Y;IK9?aBEiS6DHRPc)lNPZVJ=6h z$I|2mPajI&iVu?b2EArqqEw?#lk{7Q=AdF^Pty1HB|RJGq+8 zwUJb{30miG7JU_1P^jT8fXed+jZ{7!glVSdMtT$T>oy`Y^DZ8bea$>#6-O60Y@umH z`_ATy2K{1&^B(KqLniV0iPQITrfewV_=lP~31b#)KP9_R&!V| zLUYsbeF7WQq|lAbGlRbe8QCY%zf(VGNU0xRdHa$kw*!chyA#z_Q6v0YxSU&8!hYcpVC4 zYIw_enJv6kzVT%g6&Fe7 zK+dQILC1HzlIS?Bx0Hll50mVF&+fq91{G#%!6$ZN<*A~ezrDK9yp$jg?S{DY{H4K? zIW&rI!I#TX)e4;>H>kB6003}&8<8zx^FuVzPv(6`M8O>#0?c-Xvl(9fWE@D#J(|h? z7^ndZcWR?rvwA(-@tGGfAkrom9)DHBbGR5ocgFtlq;!O7i8uYpyf;V|i#STMhCM&= z-bm96##9XqGUSQSCN0i8`Ar*?J20;)TL9{Zh@Y>)jP=d}V> zZ+Ubc|MwNXL`Cy$DW?mA^Kb+t9}tI$=ui4}($pC^sVYRAsg=2=tfUpr^~s90p0Q;s zHWs0yCaDVwzZff=bxKtKxRS`ZN!v&B7^jVg7t1LShQeSID5J0n4OAg{PZq4AKta*H z0|@B6+}C_d>GlCJjMWhrDT!H<&Ir$ zWT9)DsKv`O*{^XOcv()V5d83_^W@37-TKddnMx0hYF?`+6%be=#FJk^zGx;piHhHp zx5lsR>lsS|e|q(F=L?{t5{s`c3EFaPU~M48UyY5#C4^hp9FMx+^;(A8b_y@s@ECS& zPD(@Pe_g*++_Gbrq3!cq*ZbmyQml4Pq7O_%lg)^RRVr7qSSX{LuyR$HgWHSH3RgLG zm^0}FN-fCdYM5=BjbWQ(PWb}PV-rC&$ZIx7)=31D@NpTapF_3@bo@Kj8`3X&n#V(a z{QfMahaS=W1RRNQ@j6&x$JNg%oWC33O2Ko-hohYGXV)aaY^#zww7?0JL=kX(&p39{}C-kSGC$qq%Q zw9Pk1ZCGtj_qMXHUUcJ7TrJLX_1jsJ{!Q(37*ZWro+QZab8CU2;C~p-80%ydtSakV zdaqypB9L0S*IaUzWPje(lg0xdW83SMDVWcxZut;;Y&cPW^>=^<#tc1N2Blrp5d0QM z^{0Aj_G|0+mSlWFRNL9nZKvfn9?LM3kb9Li7|RZ~h+&ZNJ?X+$?UQh`mi zsCFj}E4Bp+dnhFX)xB{9cJf7&uO0+DY=s;+g|`VxJ6M#A)p2BdlR}agkaZhOH&fRo zU<_fTKnnwvYi{Hb`)P|G(5?XhUO=TYj=Y_jg>ifp9;~)Vw`6nZ<9C32oxsCyS0)Bs zXm_pluNrYs_o1EIFj;!nOkHlniGQ&{=-A(Cb5iA2eMu25)hx8T6|E#Yur<20#@kiTze|R4+ z9KV4t@Yqt+E9(i#}BcWeupUOMhSW3`Z{kTbB zrgKN(#944rn!hnBJ>C;w%^RQ^E*7Ga3;0P?R1QC~!G^QXL z{dDay5&D!|q%SkD-h}HKKq!9xZ!`xI>Zfb6)fA-UIOdo~>NW@YT`?z;RU>+@0Q<`3 z?2Z+@l+&Y_Lhxo-spv!&W+SPj575{7;lwTbVhXCVo?^9&@thy8McQq zA_HSv3qo4CP0vldkd}*0ab!A^$3GvjPu?!hFZdL`=Ygw32F^{HLsfj_iFNUzcjs*U%8wtAksUng zEAQ1mO_NxgE+BD#)dpd@5dYwoCtY^{?J0~*I$s-2 z1L@Hz1)2!cvB*4*n7@I(x*HkK!Z9O7L!FBxP%bG^6)U|tb{T-G5K z-&(nus4NZ)R{R2|WA{gdxm&u3aI`?psnc>%x}tnAULtuHyVz-h-L0%4k%kp9F05q{CKgeEQW|f?3w}!~`D^4S~6J@+E@UI&X~{ zkSJl3viM~c(Axr#>)E2CmaG%?Jr@gE@jZi4bMi*Vl9#lJ=x8%Lx9v8>(l5(fqYRVv z0SW}SYs?(^COHR|XedR;UBT1vNG-Sy&DkEap^6&Gi|Sq(4TM0Lrlw(E8r1r!G?NQX zwtH{;7}dX*BRDQI_kw#qOpoMNhxRJ-pS1pXBb}F3uYIOO-IynpYTQsn2uQZg#kuD6 zHC&{{IXO+Jji9%T_O ztkArcV*&xv)3?J0(&P_W(%JD`un_dChfsWiHFEIw4|;q19n0m4O8Z+JNHRvEW{D*- z%nT8^i>c(T}58iTHU# z(Oc3CB7chB`YFq2(>){Ng#JPRQ6PR#?(a!QDFzr|)e@~3DHvQ2fxI8{Cpooi6&?Cy5b!)n2b^jP~a;Yil3q$vqgE(seF;^p1&k(WELf{_IuKGb{Ou*AKm<6jaw*WJqn34TA>vbUSk zD>!3QhvsM=%oAQ`8NLYB82Da4wd}^%hx9x*zf35Na#$|G^{%O&iE%jz_bn8ng2e3X zqRrY%=YM4FjM7NQ50`P9j3_?6z@M}Y_9Y!H0@||BwRy*ULRZ`CN+Oqre_PY-9IFwK zH}daX>Vs?`orqH58!-wOFqT~LBKFzxv4p^&v(w6mtQakih(LX&!Ln&*C*4xY3Pa%r zd-}>f*WG!y$>VkV%^7%B$C5;L{ytav4wu*}nijy3f)8{%Pf0MRsg2q5me56+WWg&y z9cyIYhqvj8ktL@x-7k}kuzvJhjeV7CuFY)DImYe0_vY{^ifgW_qUK*$21bq{HGnGA zND-OkOKC^}1k?6O|G-4<*f&g)I`Z5sYR!w9$JR~rW?%6z^7qz>oQ|v7Dv*`3a;KfE z%{lVPLbF<_6CPl)`S6LX=cw-Usk@9W^$=0F2301g9XR<(7dP=9PGtvru>`?&w^9zu zEVB;cn}-Kb#rnaD_nihTw)##N6%csSAE-jB<2LMN#ypn7HiMU_F(&+Bs+*=IqvO05 zehuu+^>k+CR4ew8Q!Tdkj=##^Q6QL2S_y;<8bV8+fK>0S2c7=eeAuH<>G|X4I80klfIU3C#UH7SYnD zMQ?U=b}KuYFMPKqmiBp_6BJfej5_AkD}+UNvU<{^(DB=W6Bb@`G9GRs!ohXC`4DvN za_Ma9#&UUBo38Er@KYew;dYp-o6a1SsDXY=!)kz%7!K?Aa=DJEAMLn2z4+LTFO}EH z(hKiz$F`F~;I_F67xudnE;-b^EaU;Q7WnGB?!TQLQ8?s~P^xXAa7#Esr{X@Dm|r*q zAbW%D8fhT5W6^gx0;O7r%<31G&A_g`Tb``FK%6|AJfPYrg$B)+2kpMOV;W&GERsA( z`LFeDX^vA5DH$~LxxE6`57^uz!^H(tw#X{|E(Zkg4`W;i3F|?4j7IV>gn)KIcW%^$ zz<=Pd12u-QbZ^GG0|o00iub%{``qiHT}!&M8szy#!5E|kOhI$ZkWY;WBvC(gNC52E zQVQP&$P3sr)=T@cdE^iY&o{^l(z6#e`QP0zFtM*T^ryJgn$ct=2>2-u_ zmm99`QeEcg1xCLW5hL)l{nTJ`+B*U}uKa|5cDoY~wA0vw#w?Fvp6Ku8 z#*rz)61(>$#83`B&8wQAqrRMIE4GZbuPITl?DCU)5}2*bgYn9qa?!^lI-+#dl;z42 z*?gwSl+nx8-TS0Z0g#G=4kYhoL!=fQ+nfG8Ph-3>s8ICgQ?fy-&0&MHkiA-KWV@!t z0y^4E=6q#$7ol+-j)<8z5Pgl} zsOEC0$J|w2aS@jZ6S%uQ=1n`}o;<3)nO?P8(%nyR+?~ zvf1HLawb_>BP3`1a730NfC7r+3+9pTPG4q`gtO0B4|2jSbQ2l^E`PI1`|&qXHf-YHN%3C= zW_A84th@f|;aH~~=kE{wF{0t0Z*T%sSII3qbq5M0g)@p}jZ^}lOfW>ihEeZPl=E=s zdvi_jqGA%{-hj5aNUDgaM;rVKHhC`@8LSe5fmTJgeEbSh<|jJ4r3&P$Af{EsS4G9@ zldv}{pr?UFX5Blzf=!as$UuX1y%f_|RJUaB_RJUWG(ngHLsEJc7MAfvU&OfH+f3{_ z*73&F%5a5tDet=wzAdY|XUMIJZdQp8eS-81M~mu=E_x-5kysT#HEEQx+;FT)$EKn3 z71T5}Z8$i{tp!BSgjGJu4qly?z<}OKa)%PzX6ZoJmzLe5KA;U*61bDjmIq-`5D=v2a3TrCPKE$$!&9v%+ig~S^jl}k2&3Pm@BQ6FkrciE;`f3<%>eh>?+qKeL z5%Kbm@N@b1WM03RUZT^Wh~9O-{2x1o7;_G5bpqLDtvNHjZZcoca2yCWYz~joPU)IG2I1VoyoyMoWW0 zk!wg5vxNBxd&XYy@*fn(L?v9}i+yX2Mfm!eTy#}7Za0ULY(qq{B3RyN>T;-WWvu4YU zICP+YRA{HMA zE7Zo_67Y*ml}b6TRh@~mG{6R$tLMq<(d*RDLaV2R4%FLZwf`ol_|)K7wz6mO-m|%TiHm9&OIV}GiJ<5_6WrxYf>vt- z9xqWGpdT|DAi=M~(xI00v`T?Eqt1tzA5?Nzz0c8ov==A)=&!p<*_7ze6f}H!g{FRk zme`|nlWn8fawfJdBlMC#A(wEr_uCMv2#Z;ozdJie_Qf|ftNt<`&7s^8>Yy~;05EP`kd%FT?n<7yD{-{|DM z=XwBKvx1HlN5vANoK;vcdZWwwQe|Hx+jTFFO-}Lv>S4>4IF}YviP^=XJJUzfNCue> zlE?x&F1vH=yKbu)_hdv+QI$I)BkE^Q$i?iRu0(Mn*C8i6AuKdGtU2?@5KK-csn5C-t?vXPzMv_eE^})u<_iiV6<$X@APT1I-R5 zQiQ9kfuCG`aajx(CwZG}gQLq$=q^rOoj+s+6jg`z7tA-t_JCGZtCiVQ8D67K?O+T1lwH^_X)RVDSlqN`;3+7##8>$;6mGV^aB>{e;*Yjx zE#O+&9f27w;7#r0=xn)T>wuaEgF}6~uFLU$>7p+;g8~H)4ve^QW85juJ&-xfy#B=1 zs8rENB4@-kyMN$`k#^6__yhqhs&zh9P*$$)tr!^KnquB?!#}+@4h|zSL>lc#iz<)% zrPqGF{62m@;#gjV`e`%gVjCisAG&&#Jn(>pzH66@ppV6v8{L!_p!d_aP%>U^S5xIG zyG!=9xG2IbJWRxy)D*jb-m=5?>Q2@6czRpw=1X+ZHjgb0xT5%|r9^~}_D0N-|B}HL ze8_mj_fh_sONR?ReR^5d9OmrK2p4-D4QYR64|=#=Xe&`$XDp!2e2dZt@Q8OI(i2GX zfk5zi^F(jgiIP#;R9;mQf!aWq!K#%5K@XcQ{@g<*-YWczvl+jRdrNb=9NLjqv|i(T z-wf84C(af^mbg|;dBpycj`roM zt|mQMw@1;aJ?Q9}hChRo^Ti8Y1PRvut1Y#D=n9Ac=f}80LyxSwf892Mqf-@3%$5%cUZvj z=rIkU5&VqT3V2@6L1!3t&&W3iKaWJoy>A~f9UB`$$R$kRf?#K;PA{`INNPQTupsPb zS>CEyQ4xx!EoPO0^OQx9VQ`iq+Q|!^9+r8^pWy*PKSWggFN5Tjw9Y)ATIfDaC+}6P zQ(x7B>;43(*dkW|xmG)(?a#f5#)KSRKy^lvR6z5AWM%@WmbeAq!=z%h($5Do4B`N? zQ-iaOHMAh3U!Id3O>!Z|gH{XdHJbBo*6?JDVZ=Y_vGu`cv%n)m6iK{8x8AXBZ`zig z(*5S(;yfWod|=NboEYKXI#M-#pSf`iPq=4G*6(~gjI>+nkZi61-`lJb>U7URM`wca z*c?feIwR{hTlfYZGw-wI!x(npKRs(W||tYIZ|;tVI`T@ zGfi(BsXe=uznwss?lA9vv2_z@Z9fiTg+V~tOn5EMhEno)GNT0grBTZ>GZ0e$^uBGA zp99|OzK8_CqVW#^*nK(Z>Qe0~1fjhH2s6bU*MLKfDtV>YJP`AwuOWcc_98nHZ$Fj- zUCXsLH$9USB`K{3_C5>^7Q@ym$ofRd2%33~v}MSjfUyKhWtq}1ZB4b=9&r{xq`dV< zomV^3$ByVm|C}!x|8<>zUd||;+y$1>S9ho8AuJqcq28AAZP(56phlkCxlHBe=Z@Er z2S8LKfPVkvrGZ_A0N;tdk10>j&L3A8Y2s)KfjDa}yX)Bc>?L|kto{j*zX`{|jN@V0 zgbdc*8BC#NP}npRo%;P2sV;WsVid(Ye7)6h#him}EBTDRM2eWEEbBl^*@mCvFnGOl zbrF0^+35_h_O;=^IlZ(Iy6hy@5=j63s?JGnB?WBWECxa@-3y~VW`jJZa3n)k$TmWV zr44Ml55aFS{@Yo)&FB>~CR%7Jxz;+~F=NJDmAxZI1!cuWOs!;n^6Lx%1mWQ)(kMSf zf-=NoYOfOPNZN6>gcziJ!Wd@Kb2IX?oK2mr#kPUDHkP8dTT78FlX*{ZhTjptLu=jv zY*OlC^vyKqO%0jH4bp(3YR1PFiV7*|VryS(P&1`%58vb+CmMyZ z8g>ubwOvdeGqjsZ0g@uCL@9yr-kNS*I@5XRdMA<@?FS}!Uif+TUfk@-wfTs=%<2u= zeRoU~I8Kgl-NJmBWGK6{TlBR95sbm|#`_}{ zRc4Dk4h>P(Gf57YVE<3RjUABa?Q}>sFo8)~w;0g3lsG8* zt8M)*G2f?1y4Z&LAxuSPg92KR!LM#L3St4|G^ELInOCJDuxKK(EJUtnBWE*i?;Fp> zsWV1Edk2^Akxm1)!6XwbR0Y}2ExlaXu5E9zZKchmbgGk?-OuDFtovxdSh6WRP zDL#)-Cb>ypY;Ui|O>R&uWCTwmDAmF|D7f`yJy8sH=YEvqK*_s)UA1ZERYuufO77RP zcy|RE!NuhY!w8@E=R3w^GZjU#Np- zN1F5d9$0G472bwEuZOu@$;iOUS;_!03uF|(@|+3cMGxLoPJ+e!4&5N9B~0+;MTArN zh#h+`DNofimogW@X2gta_~xHyPi`CVNx*|dLDFAmh`WW-F|$B|F1y9f+?;KcG}O=O z`X=g)TL3NScp#WLk@RVJjp0+}b2fmrCJSw#+EDkV3rHnwMlCpyunLKcVS-hiN|;5b zVE*b^kbWW`S|(DSGyV07K%;1kuuZ+)Onbh zSR=ErYxj1isWFGI4RrMG@NqJhBK5yUMT=v?$*7&YC>=e%_DjZCCB+svLpgjT!1DP! z!qX!tQ@v=i1cF|mXo09^K6F4~WdWfdJk!YXr_M@3mgIBS2t))4g^G4k$ zE>mUrN3JCN7zMD!x30EDIw^0K1H~3q=%d#Vjo{)afVt7 z>>3+efN+n%Q^wRsXDj%q)%|j^Y6YJga?(4rWcG9|>o_T|L-P=<0?zX8W@xS6D3`P5 zRX)G5H&~hF1ym>>iMyOh8+*Ta@jYo+ZEviWJYp{+C#_EVg2R&vKod(+C961k+WL(P z0Tyav96zT45xoV=hCeKanYR0yT2ZANb{OZ8lW?&!&CQ0si@ZoJ>-IKK6`$t-Mv1No zn2|z%6(VQr=rZu#D+4n7N)qn3alSSLk{CFw5>#Sbh#bKrtsCPif?be`c2v`-P>+Qv zH&0VlqHjwc2%0@k%5cBX5+*fy!sgw5a@PY}O`Klsdl8JtKZ^nfN@}M=Io*Z>8dxmZ9r_~$|(*cU%^lJ!;q0B=*SU+c*9{lT)#dolVK5o$uwNd&F2nA zFuYAD*L{agI2O8P60xxtCUh2qlCEnCt+Y@OpwThe<_@32Y6`LBg=A7*EtSM5K)dNb zYj{%cyU4m}t<>hst6ZQzi;L31lsyokDtCpiJm7sX6+Bsk*5>8yEaFD3gB!f1t=|eH z3pjR>zk+-kYzkvWJS+9Gz|G{K2Xwiz|{?(>=;10IZKrHJ5cm**CG`N9~gVHQZcW zw*BwJFTK`=RD%Y5XJeh2MIQ|{1$s#_j`~jyI=}PzN|5hH$(oRjmkV?z`RKrEld*Ay zq-I2lfc##`Jso*7rPdlpr)q7ryp&6y#L+;}em9@&K98kmh8XrgTs#}uaXuGN%WjB< zH5ET&@C>oRjWv!>mTHCFADdm^NA6y3(d+A64-b{>!jpH;RSnnZ+N4)sT6oDP8oh9> z!zSi>n#7d&aQmrwe@A?UFiY`*eC9@3I;UMtVL$@kWJHcs5+*_xg*Y=5Yg`r;WV)VY zE*&KhZ#~-mVwF*)(^xovO31?C(>l;i#1}#!0W-FD^^S-&x*Qo0vxvw4n5apn;IMvc z7>de9`n}-m(I`<$DWYV_PAIW5Wh@xBacuUw$yw>4jhz^GH6o1=O~5{ywkZRxh;?526Wlm|>jn`+k3C9I&zzE8fg~*0E)i`q__w=IP8Z>& zt4|r#l%L8v+jQP2LSBJyUW(6?H)ayeOwW7Lf?Ga)i53@TV9GCoPCT}5VF-66fC8~d zi@bN0`#=!wsM#^yU$6!}f)Otw|JJc1k4;Z)#~{T(fWX-qLE^zChnq$~lK>8H`L8a34R)Sh8x1 zG<1@9Y@tge_C`T4SxDTCZEJLdaMa*#>Zm4j9)L6}rb?1T-Bc}tzIpyJ2e&mmIa+&r zcnca2W5q-2$npYISR#mzo|c!tM!hD5Va1)(|FZ9i4Vk2lO{}UVVa;gC1M=Jq`{SY) zycY`@&NspEDZ5 zy%tb5z=W8aeBfEbw`aX zl0rfww4Q8!2AZzE&CwqhunoxUi2*+TRgyjmdKe2g&0qfNtdkF|z(&*)qK2N!{p(7H zZ1F120_L!`nyoxJUAR=D5h!A4?4(^UMk~_vGr{*z=oW`ATVo4AqzFuLw5Cg@w@&7V zS$+L`g@L{9gN;kq$VM4Y@$k^A6 z-@6u~xQM=qgFu`12-BXEY!vV+F9I}_lFTpRrp_ahypHA<)Uv8a7goytYL{nMQE$#m zz)P1TlZw@KVu*k*emN~%&)Dla?0!M?9Yst(sACU{xOKL`wIJ4@z+z7}MT(WM={Ffu z_ISHS&G#kE1Kd;^wH&k2BFHqkAOrcAvt=)rH@?ir!RvczJ@Cz!Z?RM{6_la)bMIz2 z9!A(3u|?QI=-J0oP_K0#|LN%qs*rh%c>K&CLY`GIxE9Kmgt`=|4ac4X?~UuY-&pY0 zkAHHiKPa3=KeX-$TyT^1)Z)F>L(Q<7*md`kKOE;) z`%~UG;x~A6aT7pP>Pc5Y@D`QSL?Xkvtk>b?qi*SqD<5FE)mw$NRDlZ{%sS z1UiAi?qxA-v|g0@tzP3L+DYcHD`mOKa_ey&(1lD%7^+`nX+%2oDgqMND3S}0p3^Yc zDr+OZcBFO??KJ;_1&BEAu<9tpO`gYnzD0is8Yb7^`V{qX#$_(!iK^UU#>o*|+OK$} zn}q}h58jR~40ih!h!DqRWvAGL8&&PeHy5z1bW`XMbosys4pJ8uF*7rHoWLgha@=P7Mz-Hpi@{{{T(rQw3yR$DgH- zzqbbrxs#ocw9_Tj?66slJBNDG&V~;YfD`U}uv$m0+Dnk{I(`$5Nfx%Ak$Jnk`(v{* z(ZX$~-cp*xgizV$!xVY8DicuRm;(5Am}MRd%cm&EHkqY~_*SZ6HhlG~t`aEUh(df$+u{GYxdH9D@Z%!vMLGk~>ovfFD({SXXPI(atpO)VP9tz5E*i}* z;!**6JSD2Js+^0i`b&J4La_aqS7lG){wj2yY7RJpk1uNy(HD;JjPrxC5IVnfadxCj z)pMLfjO^%lju7Iky-K5?57p0IeyhIox-kv(SEM)Q#>14Uuy9z#)F5TE8><;Tkkbe) zI3|IV?4f_y)f{y*U@nZ5RRE*{IA;=$I}lJo4k9ZPZ1g^a{(dvHiX?lxjMR_(o+k2W*`TZ0sSHgd zb(kP&M71Q=ylOLddI}*^3e)=))auD{mzgsq(2LM06G_g;A}{BqLcud%t;SYq@EJJY z8TzLZbzjm4;RNOvD4r`)uzBY%e!U#qH4gQ&pIuceHPJyf#w{XN!fpUa9hohFJlR_3 zlA6+f*bhm?Oet4jjWPkN7IY-?wN5Q`H!sR-|6WVqfu*_4Nc&*(^rrB~b&N z2Pw-k{ApiHq<3ES-rHic-TkmAJ~L}QFM$p(yyJiX0002X$YjjZF-f0CW;*=CE~(}3 zDfd^Q0DEn$*%czt_&X5Qvk9&*zK0a}$>Mowq+whyW^Qm-UyD_G67yzQT2Y5haZ7(3 za^~?jgd2t!ytu8)UU)Hx0ULDP(q`k^N>!Tc0BrO*C}HFOEWFXXLOwTAM*Z zUw#Or`=HohAMXm=La;OdtCh+=pGdMxjqv z?MY1Rla4m~16xu~xRY8@6|S6`Z1s6XlF;YMu+j=|nR}O61rpf)((V01U%{&a4&xxw z&kzO=VJA^1Yrh!xrf69f{Td#BSIj)X7n{p3h-0H=(7bFWfhV{X(DYHt_9ZP--$!t+ zS}J%Lelo@XQN-T$jKA$>zp0a>TOUCB80E)lsWIObTjU5R-;!EMEYs9KB*LMWWCIa%g$)z~ky9pw zuUjm&)GJ?8iQKB3DML=+&+!g;Gy(*ZAdN;SLc%S)J@zXoJ~EpYPZ^dAm&7GUpLmu` za70?6nW0OW=f0akT>f%#chVm(GMn@cB}@r`BlBnh@A@W5O^pTzCT%})fxFg)q&9CS z)FXYSS}eG;MWXEmGNsUTwF7R9M^>))s|sXkq4*^-n&VGDj&oJrEO#acu*WBGbzZA-~7eH6N#0>G(xNp9Hr5Seb9a8yy@Ui z@NeZ@TaQC0#CnR$Yd$p8o25urBwZssoT#jRAqfUd$euJ*h~$~-m$Hnp)k znCF1{2ZXnEFR_X93v0AENZrxeY)7yYv?|I+KI!5;ft+8W68oSO2nJYgzw>RwME`&R z>1OqlnfemR#v&}NYR;^7O21tnJf4W{zhmj#(G3UvM%dBzC=hx@8lVgBo;8gdh~iW! ziFC%5irk1PKHV$4Csh;-6@iCIw-Y{idaaM9C}zzDRv@GH9gW$a@TGNP@q8o}u}0`L zWIjirVahQ1WWng4plHp67FB}5jnKLG4gc@5n}3sz70oU*kYsE#jH`D9>ii@b?o$}0 ze-q4DM^HKu_WOLn+FW9ym}Q;Zb6mvXONwhZHp59Uk(Ni37iXax5YKF^U34s4BF}8g z9)i_cY+NV$cs`0UAwXNlmmjA{y^%DuOLE|RYLq{1hZx#)zVOgAeo7gF`_#Wx#Vy{( zf-&>tumxQRA1<%eR8#s0HCaM+wf(CnG9~6k=DPY=b4Ph$=A8Et7+D=_W^P!!X(}Hv zSP(pLjk(>J`OfUx>OSyfRogAGWSe}>A|k@Qfdwj4U?ieQ|8$tAI$IIFJV_=MkDhDJ zbq2JPj<{N_)8*@h{_vhk{L{WI#G7umo{Y1^{&fJLcLJU`Y>sk#8jh_rNkwKyNeVG~+%PC3~ zyf(qxF%SiKqSkffZKI(nD{B=4uz?M)Lr}mcvy4#j@?! zdrOe<=D48jX!X6|C~2*$kkp`_)OhR@Kpz>kJ5Vyj>zK!R@y(1{ghkR5HgMDX*k zU>=&@r60K93VY2@fd0~sBmbLc+5cd^sb0fX63Nt*k5Ny}a6dJ;86W@v00kJEyYG6s zc0RLCm}R%59fO;TMLR236dO_`Qil@|vsp-aC0LQaplo0TIxCBMYOJAJ*C8nPSc-#| z9NPFq^LrU@)9EozmrL!O7#^GPzs62SYHZw=`-C=Rv@y#7I8enZ^*S5=HEsM9OFX2i zOmY8TmiiQX=HV?o>I5Y^8BP?RX4CHJ>Nu}Ep7VuiT!qs#f)m6dge&f6X%&5`!?E~5 z=Oo!MmO60E@4ms{dP!lUlT;tgW_o-YXBrI|kA0rR)}+E}eM$_-sgKnVHq5NZ)&^2B=1{Y3h-}*Rge(0^1ZU6@Di`W>u?VnI zcjo08Dsgg}Z0!&DbK$ab$Uk6uE<+^{GTCk;X|!Qf3qJO(W$LN<zBBqoYqlMB& zqXS*rbkJyYbwU$<8zyu^?T-7?6UoHc8|=nYQ{4OHy(PzO%9oeqy1L-7=GF6q|D5mB zT1kw3WPiE!&(;RGa2&4gYx9-H=~=!a_t*~;I)E(kjR_~K)Z#za(K+C)CO8iUl95EK z)~f=8B62`w8AqYmW6WQO3qkME6Q$=3W2(RDLohBT{?*Vcsg_5ogkHaTW+=osbF-9i z36Dx~&UMaf~ByE7F!4Hx@!rdJ>Mo?`9%`rnKtrZRJ8s z2=CVJ>^jF7Y+sVaCJM1B;jwzRu-DB>fV~)L$Tg;=vr#8@N2|s+fl?a(^1!q2N%9r0 z5}(4J`uc4jL&737c-9yxd8y8p6g{v72lg=V65Mzr4cb=)bNs<*!{1*scqAZc8UzpsS4o>e8oJ;-v=jVTd1L znQA56h0NmfCH!j1>`ps}NriTw%s%^Y(`KFt#`+5_N^tfkZme-`#aV+&cfV#~YzZqUeQf2k313I)+J zB%c0S7XPX)p`pm07Qy^5|gQZV%afQ--j$VDkZbV_zx^zx}Qq!)` zQv21OUEg^_-f<^Q(w`j5fACS~gl=#oi3B9y5mEt~`+JeTmS@^g)Zt#Kng{*oHA`9& z^Z!dy>|F9ei4I%XvBh3up|_r3aqf5Y;YDL*=v^ zu$smp|K#vvtyTiwQD{qQlM!FmMGquU>9CM=BA5R{Fa~;#;s5rKsT{UEri1F}VT~Ya z^%?J5o;r^Rv_`|OP&~pFF9~uAi-kwoz+5pR{XFsoL?6dq&g8^+SmYvC%7Fkr^_vxt zJ3ZIY3o$LFxuG~ieuZJ*8{}Dv)_v2WX5W1B;`>^lVb}2Ktjtq%rm9+?9kK=bmt&B?OlR2 z(mA`N*yPyIoFV|Cm|fUA7AIntP*|(>dhn0ikVjt6%i&0Q7^Vr36_BIiG!~Y<;m zf)wOezFz7am^Q;o1XrrsIduR400W-~*Yk7W4lUKv8@H-)IlBk1NwIf&5*ygJ9R>Km zFvfZRFQHCu!4Tx#OSw>On(6S)57P&{bPi&+0(ue8#DYCHi8_40Oe0&Bh&e6)a znDd~Xvs#LY%*@I%i~Ab$xDh`H+qx~*uSKOmoNnME+n0A+aT;3 z9xV!}S$wt7M^|b!oD?F(kQLo+^_6hPJt*4{UG4D*9 zf)EL&mG-8VTR$CHwIm#Zw=xS-sTe*`+TgqY;}w)ic6 zjQi|r-plEtyzMoikh;hQAwm==m1-*qkgqo$4uKOXU7ur#UE_Bo<~5-ggBbI-S%w>a z@B~F$SaSz|_nG2;^0|sDd&&!|&Xcl_TcqDr@poPniOy6mQHcai#yxnS4MEBV=OgNC zP>4tcVBeb6gMEt@f&PnpR8J0_a9RS=cATnua+5+4^j&GSTQ>;N27+yvY7G5-f*&9q zqei@5OXC3=4B{5rvgR}m)=39#j`~gr=W4NQLSlpa@XCJ*?XbtP-5RP&x#ZF%Y1$m( z{j6BC@i^Ej<1K@ny1Fz6JKeF@W%->q6CI)2+EVp#>7VwjltsN8#1}XaL99-7EWuVR z2lq6WPt*(a_@LQEpq~li1~oJ1o@l&jg8AIHFpX#8W`c&UgPW9>3D6&Cc+%^_(m^uG zN?YC{96W#<#l@UUr+#rKB?oW^sH5I#9*MDHj`B2y! z%j+GXZNVFG#^OQS>BQj`gQdp&wrYEd#UtnHOBKMv0n#Y{Ho=u1w zG&6H~>S#0t;W>4&8E8kZf&pZ{T}=maO)cJsN{4cSb_X z;TguioWA8`KTkhlYZ0_^>B-30A~7M~`!e=RgYb1h5{{J<+Mc!9GGMQqk^j0MjF3B| zjN0c>SKm_G;^7D1xwUzPFX5*cI&VcLzxwzYQ}HM1`cC5f@et9L<^4J|rFTu88^0Fe zuBe-nHbS}ib)1wX135!=b2qguYG?3)()OzQUsa|%?RiD3?R3ZY1BE~?z4J|^_FVf! zG2`$Z`O~06(q*jZFoPuQS%xj0+{XA)vvn7e)pQX$srjy(el^x68+g^yS=RlrOj`U( zytts}nm+a_*IErzC$%u{)$l?7O3?0gJ^=p*HcAa_T*bgy!k|C0_Od;T$p#0P zPa@<;QOQ?P_`+K1K~!RP@|BIO46+_*2d;oh_;UNhHJNVBVOpJ!bl6PA_}o#i z;2*JbOlJCeq=VJ7YQm$@@LU7&0?&G1Rl(?Pv>~7JqD0=4nX+BBCTohVAI#4N;vsay zA%RNSKeuy^z7%|mwq=IT_ETxZI>Lz@th$>+~l>PNtq$`f9#t(6B3#cXX}CYVmXH$ zgd+2#$47hpS~2#LV&RpIb}sE}TyVA{KKeT65af5+olN%`E16Q8J;^b#xE(3uQvs@%o^0ld@SIDdc&U;42to9nEY6Q#q-JxdzQ z*>et~Oo&CUrwWXt9a?yJLwOqP!Ze^SJXkwI%3bV#e=i+>-&es1KO#=BEkz;=R90Vf z>3jKc-$52XTCB%HBG!H(8#Z+H6_A8`_S&-qHOMZ0q{~;)mmi0@jB+u=Mqc(VWWdXB z;?0A{3(QbmQB$||jw0?rK(vG*^J~;-loMEG2#@>w;6$t8%>wX|hyI;HBT9UOwkn2W z6@P|Ba@(DNo3a%(D1XJcHDK#Yn;!y<5>_Z}X)eBixXQs_dK1_ym^H-FthFHKdgi1RUSHy!a5Q90(ejnSVTf6JCP-pWB#Ld2PSrt@Pxe zLjwq9gdG9l;aL7kVpT>t!0~mDuK>bo$TV!ztTXXLaTYjXjl4`GPj#h8kb+jP<~+`& z?;Y&|s38hO(b9S69#f;~D@-F0a4}O$f6rHoPn_`?fQ*jz>8z4z_@VKpq^gqMl%Y~d zEFFFg7K`x}QR@}v+-o-43b;r}JlOB~aG0`H1xz=ckGde4orn|pzVAyJ< z7G8Hk{nqusiBmDCvZ**d*el!1yG)%bMKji#|jVOBO}Ox(sMwhPXqNcOs_Fd`GO0r*gKo zmGx)|ApScU>^3N%$v|PCXg^Hq`aDxFzGTMQFG)Zc$9IzcX3QMlssPa~7_ns#YYKy>u{SoFXRFXf3c)vsuL<>UsVuy&!i22{TpT`T{y+CSOMrl z&h=k{^?9;G;=@{1zAVN+eF|ku5$T3$NEgh&+lhhP8`>1e+T3VyDR<0v0Rv3YL0kuY z1-Qv#X{0gKvFQkM5Y}#veST$HJ>hXRQ;K2ArG)(%|)r-RhWM*gUmfcamA^z zOZaw_2rRH-t<*Da;;z44;4$!AFvMc#fffB{a`p)@*EtX$bsiHrtD>DHp3gNT;h@OF z&Bj7E|203Bn}P)8PPxsIgB-TLY#k-%buCpG@610*h>7+-ykxj5+G=lg+wD!w4lF#u zrxYSCnDNk1a(gcfq7XA^AVJSvYc}*6F?+S$Pg=Ppk?$?3wHa+WRDZ`?;Zxd~ib#Og z!&M{JsT{-$3z6DFUU0cXw`cVNfnQm|KE^to+EpPi>BH%FijF^zoE@xaaDkP!%Mp5K zoFIHIq5NcNe;5mAtqgopPzy5=ZUaA(us%uHRero%_B~74N|~w?uI&RCe${5cEZ#Ha zNnHX5vsFI#fhqn3r&a%71BwYT3TkVH*^$odZ#N?Z7|vZtI@0#xH4bz{YgNAmMRt&?hZGk{3c-Rj{+2A0Yw$7m+ugL5B7THUVG z?qW{`fB!U^R~?=s6=v2Ilj?XY{{%j^(el9$^8IFyJ?E?No`fjN2li8z{ck0ZzXfn2 zN|j3wJsx76&UxStPL%ZI)qh6a%A2lTUzbB;GM_+fY7rDvQgjCl5x;9GPcKs58WN&7 zYn6?GpMD#hoB*=!z!Em0Dcf;!&H(_!W7+DQgv=+sheSR;&s>AFTw(Rck9J^)XcON* zpXCmfd@cs7!87M%S{P(6Y^JimJPpvD5naow499*1RuNO&va@eVpOqx(aDQpozAq1XZzOt?=8Ier3C2gGG4`)PpL>=T9a0y zs=5N8@`%PT3RjY>?7<|Xp*4gFw*)6mroEDXQa_fhE04`p)mL22?M|a>F7CKYrU8s;P^re z;r`b zP|LPxlhdOUuhz0u|O&q6%jl^7eJnBH>c4^ z{zF~|rkOq0+{4_fHv1qg-DMDUAVQgUzydldRS)f&M2v|hmQb3`|CKTSTYz_?(Lz|< z8=5v_MCn;5*Iy8UqD-)6N>Qt8M&O!9q#NCa;Dki-AO1RCr)1WY8If-ty`B8Fg#!eYK1S zZCN{_amP~_ji1Y|3Ftc@hBMSY#j^Mo?tTSwhwOeQxc;EX)iY`pS4^ASk*X5q|sW0?Z1K`A_^ZE2-Kv2JAr0@dC- zy5>WO+wuduWW2{oA7)zlE2?e}&DQJBdF2ddxj3K}Sh~=0`xm2njv=(zyT1_oD!3z8tW1GkTi)p+y5p}iLID2@vxlS}W@)z?9<8d)L{MlWQoj?o$ z4=0oX_N$IZh;3^96GUl#dOGdQpNFGLRY7DhmMtQLqN{6s0fs3UwWB^FBmpttDUxXC z5t_pL8n=|=YaH{Ks~o*#=4I5C27boBXjN-;MlAl>-`t~8)lK?-p3UmV!zDsFoW{!S z$M4$GcMI?xVg8$THu8-rO6f83CKg&~D3NFRui>OVj!HTbW*B5QktSY%CAVm!R6ShU zxTF>MyiT!M#|gosw5a%gnS-@I^U=&)FU~yDs76_5Qs(~{`elbIa0pHq!6W{0uFPd) z>+eykPV6FwD_KFfC1MQ5?DNN8!_dXX_Yre3tFVb+Jfgdn~VbF8MY0frv_Zb>bUQ&JF3WnfP zxHy@=-$CLRZziA?Q#D2Q4YDS~)5Z|x-Hh^#fbF#be!&B?q6o9y z_dUik3G7E=eVIjot>hN8gI~FfEX%1&`!YC~MPfZMJ+8DdG0uu)Wrqvn@ z-hj?b0Kf~099w_2<^Yh0!(+`&&RX{LGQyoILE4r^_?CST2;N#rmhI{ku!wLHR1ib; z`)425;{5Qop(N39#g`Gb44AkbjYjnIgHpAKTUnD+CT>f+Y}2jX$?l_JbjTPDQR}*- zEOa#fn#0L3kEX>U7(23{po9=>PfG-42!ST(!{b)X0v~%el2L-Aso>&!3J78QFC#mp zLa?Ccw>fHG&2D;LD4QpQABqvTgJRBJ+}ZwGJ(p({lYm1A!eGbZ7NAOQlo&_l4;{v^L(J--D3cZo4#157_ zkby^mNUYd#%)wD<2A=2LJ3U`+N^_j>Y)+N{;^^Y92TCx{Znui$inV7-h1g@sbz0sY zMLmnGL+f8-YW0|2R;|Xt2BQf<>MyUb;}mDUtD?bwOToF-ZwxVuLZX7%h`;^40QV^_ zbSsDfRP_Ov7@Ws}iW06CmX`6__c7|*?kCGg7U4OeG`gbf`D_=mNlV<1Hg)=FGW=fD z?Fx;{q&=#e39{-f%8TKYZXcM>*0@Ifz**Ku0kniRA;y;xj1(qH8H7@hf4%ygaanobK}{W* z>6Em7<%`gGV!xsjhf3ZM(J?e=a}DVR6kCd$Y(aN_JIO3;e6O~>M`(*CtWRx@#gJ#q zp+Jd?KoEW<8j3d&Z7`|RT1D+by7rnwd5gt`u-ORSEBL5N`bSK1#U0wu@Tw&Z8(uEh zdv^rJe4PA`_w6DYi0jo%HWM*A!E^ii4{2^c| zGoc zC)EZ3@G0F$Y&GAY_`f{hQcwQD>4gEAtANc%q0Cv<0I);CCPOaJf)Qv1i-rAYm^_kmS z`^eLQTYBM(r7n3?x)xb%?l;#K!DDlwqh$P&{nI4z)*mo6_}x6ZvwaT{~tUmGk_-XUH$4Q8K9ApfbC zF43vlT{{J>eml?NN}Vo4oN;`F&wxF*n$r7k>KX^zNakbV4!8p|jMm)qrNhmQ&7R7b z3X`hFb|PJIY&=49!}!l~y$y+cA6(Rwis4z{3-bUD3U@9UeAz86V9%TAvFrN9Kp6y& zJq}BbXL}CAUeQLr51GeyT225Q5KFEvxNvATjZ50G{#c(L{Uxy%3F0Fp^BclEe zsg^NO284gU7;BF?|C{-}lg|!3Vtu-yAG8Kd-atS8P%E*pJMQ=PjU>9(|GjcTYXLVX z0rP~;<(zdBkOuBJnlzS<8z{3hAl&qPBE_y_SL>W*NVy+Rjh_<|A*a}2J9>jz0SMh4 zu^V}%i_!dghl`bMl^1or{McF64JG#yxHxsPx2e+sh`F81fU4(VHLG$etP}NiyLh#W z4|16R?*gZ}L(uanrFr^-3jn9|H1mTi;Xw?!%)Lz2f{IqyEwV zWw2zg)|XYYDb;}BH~;_uF$Zp**xLfKg5X-e&+HkfZbo&eUE&$sy8l?|-pXo8D5o@~ z7nAUdAfRIDS~<@>qtIQvX(OWG-A*Bg8kZMHq5BZ&B-#1_<}J}rF@grUny^aUL=a)=1c<+2EQm0-loWO<2PsJ5mzoi zw)m9K=EKQvM+>2gi0X-?ZWb*wv7364FH-mRl4$U57y5H; zS8dgG@)&VYdm-9uL+++3=5z&CKCp!6xN~T_MMbWPm&D7J)2fZ4X8NnJ7*>ar7G(3| z#G9!SKj<=<|4=I+Dk`0??d)1s@inkF xx;<5cb%)7>8u2J*jId|g@t6Y*r#kQE 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%0AS`-ap4>2hF;_2F5MV2TM|T{bIf+HV&H8-LkXf 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

<* z$Hg=5raSAy?|zofk+q@-W70RHFmxVgZ-)Lmu;cn~-P$K4ocN?qA>U*85(qIS26p9% z%i|`iy&}{8#t z3A9KATp?kzQnko!F>YJRL|(qXJ}w>vd;6XcWG1xEZ1-qCzOUJ7U1D0@smnvZHrZdt zw?38)2Ktr(bwCyEc%>6!>fl1{i@3Bg(DcF4JVrRka%IYzkEdn4>?$6nFMW2wxY zWMVT$`br4`TN2gJ1tLC9x!~4F9$F)#(nuKIklt|26x)3~6J48@H8|-MBisRVCy$?5 zRfMsAe;?4Uwo?vHt+P_#+LNZTGe&0&rws_a{uji73!?x^VHlzpTIl|oNfKOjVHFOV z{00r(DXP0YK`$BH_Cx=i8n{YY(e(_&O{!vU9F{EeIsnb;SgO}hRY#naTp`uYv0t|? zR=OK^#Ntm0rOeK^E+uYH9 zbW*RnMk*8*f%=T3wGteCW^&$x+kG#@m0|CLcWE$#n^hv-r5Ef@cK;eiti=1>tbKpg zgdJQQ{qAvb#EvV%e&0Fks1$jRxnT7}=p*1-j|0mn^+sr%k- z%=q4S6RzppKITD#{DNMdOStFvev&&C0Q4Fh+f2+kR$o^FdUTfA#2qURF|gytQ?F_o zBDikDUN?x~h;E#XopBM)m6>jqJJ1?B#GI$QnEm&lCxxn}P6X!gmk#akVscd!wdf@PdVZ;JR5ge}RYyh70rM@QLAp$)&H3xahN8|FbHD3qygWzP zgQCTMLe+u|mjWnFVgka9b0={LGcXI5}(W@!YwcXyGflynQBNNl0 zahIf}mdGnM)bdP1#96wlW^2@o!0r4qbsQd%Hr}A^2`Tb)^yp34@hU2I zpm#5HLo7LJzQRu2gz!747ujxD+3W-k&i$}12P662%VXSj?k*wE-W)MmU-EZ?l>vPo#&JqbIMmmc%}#jS@uV(9IX1=ad&STi4fEL- z9{Q>z7NoE;a-rY)Fz`3gA~!INz9?SJw??{CxrZ{0@Fkq<-;fj75itjbDa$;ek?S#q zlSx*iTU)=x&3B9!{D^>k`%ysrCjs{JvbUs?j;A{EG95R(Sk;T5Lf*Knnd$1tWAp1W}0 zt`4~7>tkN`dlsdF(sdyS_>`aaubh3?Oc)qJWwb7w&Krcren0z&>xX31IjinZkUuS5 zvl=t)VS}d(eDQU6ZSj;pBg`Qb{=1`JEROZ)(oPTzW*-qUWBT;lC_;ZM7PaA0Xbe`z z40CRG2QGB@KqKe^kn$7jX#(~)Hbe#!W0LA&S2RaKud$IFAKdRx?}9OAsSz~GojR7g zwsQGTEf14dyQWk>#kl9MXGJJYKp*2>odNNb1k@(*WdD&N9!d0OIn1c@j^kW|n|)?w z$R|X%2y&!A{p>U_z1Vul*1azxT8ETOFdppqO(lB(Qk$1v@C{Y`w}}HZ*P*{pw#%V1 zReL_W_NbE>IAd?`8Ha~D9elhpA-8Voc|qO?5`C>^??sPIXWV|cl%yi(k=OZNEyex! z%yBPZs)etd{xgD#Yb>s9RFpm=@>G7qDFXqgjw%-;C7kz}SKSMjoIC2cQ5mlJOgMO| zd@p=YKG7LtDMtR$>-4@(*j72;hveL_z^SkRAW&i|<{Y_9 z&YbKz$XO2S)9cu7j+edaAbjF_SEcx4$Pl7t7sgNy6uc>3EofMKYm-6v z5tX1BzCmx>FX_)uGzM9WN@Wn-VcRlhJ9O*(x<^u~uwP0C^?#Rp>=IgM;nG;w5wml& z7p&no)^hTM$Ok&zX$d2v@41tb#9MI#y1mTFqAp;OE&QU64WiYmEKi%K7g6;KR1xQa zsb9aK>WXc**RT)tq`QAamCHj+7HeQOtEu2?rs!d void +} + +export const BottomMenuArea: React.FC = (props) => { + return ( + + + + + + + + + + © +   + {new Date().getFullYear()} + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/Drawer/LogoutListItem.tsx b/packages/theme/src/showcase/dashboard/Drawer/LogoutListItem.tsx new file mode 100644 index 00000000..0750dde8 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/Drawer/LogoutListItem.tsx @@ -0,0 +1,73 @@ +import { LogoutRounded } from '@mui/icons-material' +import { + alpha, + Button, + Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, ListItem, ListItemIcon, type ListItemProps, ListItemText, + useTheme, +} from '@mui/material' +import React, { useState } from 'react' + +import { StyledFlexRow, StyledListItemButton } from './StyledListItemButton.tsx' + +export const LogoutListItem: React.FC = (props) => { + const [open, setOpen] = useState(false) + const theme = useTheme() + + const handleClickOpen = () => { + setOpen(true) + } + + const handleClose = () => { + setOpen(false) + } + + return ( + <> + + + + + + + + + + + + + Confirm Logout + + + Are you sure you want to log out? + + + + + + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/Drawer/MenuList.tsx b/packages/theme/src/showcase/dashboard/Drawer/MenuList.tsx new file mode 100644 index 00000000..74db02bf --- /dev/null +++ b/packages/theme/src/showcase/dashboard/Drawer/MenuList.tsx @@ -0,0 +1,79 @@ +import { + alpha, List, ListItem, ListItemIcon, ListItemText, type ListProps, + useTheme, +} from '@mui/material' +import React, { useCallback } from 'react' +import { useLocation } from 'react-router-dom' + +import type { MenuNavItem } from '../MenuNavItem.ts' +import { + StyledFlexRow, StyledListItemButton, StyledMenuIconWrapSpan, +} from '../StyledListItemButton.tsx' + +export interface BaseMenuListProps extends ListProps { + menuItems?: MenuNavItem[] +} + +export const BaseMenuList: React.FC = (props) => { + const { + menuItems, sx, ...listProps + } = props + + const theme = useTheme() + const activeColor = theme.palette.primary.light + + const { pathname } = useLocation() + + const pathMatch = useCallback((path: string, matchType: MenuNavItem['matchType']) => { + if (matchType === 'exact') { + return pathname === path || pathname === `${path}/` + } + return pathname.startsWith(path) + }, [pathname]) + + return ( + + {menuItems?.map(({ + svgIcon: icon, primaryText, path, matchType, + }) => ( + + + + + { + if (ref) { + ref.innerHTML = icon ?? '' + } + }} + /> + + + + + + ))} + + ) +} diff --git a/packages/theme/src/showcase/dashboard/Drawer/MenuListItem.tsx b/packages/theme/src/showcase/dashboard/Drawer/MenuListItem.tsx new file mode 100644 index 00000000..f311d59c --- /dev/null +++ b/packages/theme/src/showcase/dashboard/Drawer/MenuListItem.tsx @@ -0,0 +1,54 @@ +import { LogoutRounded } from '@mui/icons-material' +import { + alpha, + ListItem, ListItemIcon, type ListItemProps, ListItemText, + useTheme, +} from '@mui/material' +import React from 'react' + +import { StyledFlexRow, StyledListItemButton } from '../StyledListItemButton.tsx' + +export interface MenuListItemProps extends ListItemProps { + active?: boolean + icon?: React.ReactNode + mode?: 'full-width' | 'icon-only' + onItemClick?: () => void + text: string +} + +const defaultIcon = + +export const MenuListItem: React.FC = ({ + icon = defaultIcon, text, onItemClick, mode = 'full-width', active, ...props +}) => { + const theme = useTheme() + + return ( + + + + + {icon} + + {mode === 'full-width' && ( + + )} + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/Drawer/MiniDrawer.stories.tsx b/packages/theme/src/showcase/dashboard/Drawer/MiniDrawer.stories.tsx new file mode 100644 index 00000000..95f7728a --- /dev/null +++ b/packages/theme/src/showcase/dashboard/Drawer/MiniDrawer.stories.tsx @@ -0,0 +1,80 @@ +import { + DashboardRounded, HubRounded, ReportRounded, SettingsRounded, +} from '@mui/icons-material' +import { Box } from '@mui/material' +import type { Meta, StoryFn } from '@storybook/react' +import { ButtonEx } from '@xylabs/react-button' +import { FlexRow } from '@xylabs/react-flexbox' +import React, { useState } from 'react' +import { + BrowserRouter as Router, Route, Routes, +} from 'react-router-dom' + +import { MiniDrawer } from './MiniDrawer.tsx' + +// Define placeholder components for each route +const Inbox = () =>
Inbox Content
+const Starred = () =>
Starred Content
+const SendEmail = () =>
Send Email Content
+const Drafts = () =>
Drafts Content
+ +export default { + component: MiniDrawer, + title: 'components/MiniDrawer', + argTypes: { + open: { + control: { type: 'boolean' }, + description: 'Controls whether the drawer is open or closed', + }, + }, +} as Meta + +const sampleMenuItems = [ + { + label: 'Dashboard', icon: , path: '/dashboard', + }, + { + label: 'Reports', icon: , path: '/reports', + }, + { + label: 'Integrations', icon: , path: '/integrations', + }, + { + label: 'Settings', icon: , path: '/settings', + }, +] + +const Template: StoryFn = (args) => { + const [isOpen, setIsOpen] = useState(args.open) + + const handleToggle = () => setIsOpen(!isOpen) + + return ( + + + + Toggle Drawer + + + Select an item from the drawer} /> + } /> + } /> + } /> + } /> + + + + + ) +} + +export const Default = Template.bind({}) +Default.args = { open: true, menuItems: sampleMenuItems } diff --git a/packages/theme/src/showcase/dashboard/Drawer/MiniDrawer.tsx b/packages/theme/src/showcase/dashboard/Drawer/MiniDrawer.tsx new file mode 100644 index 00000000..527d1bb4 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/Drawer/MiniDrawer.tsx @@ -0,0 +1,61 @@ +import { ChevronLeftRounded, ChevronRightRounded } from '@mui/icons-material' +import { + Divider, + IconButton, List, +} from '@mui/material' +import { FlexGrowCol } from '@xylabs/react-flexbox' +import type { ReactNode } from 'react' +import React from 'react' +import { useLocation, useNavigate } from 'react-router-dom' + +import { BottomMenuArea } from './BottomMenuArea.tsx' +import { MenuListItem } from './MenuListItem.tsx' +import { DrawerHeader, StyledDrawer } from './Styling.tsx' + +export interface DrawerMenuItem { + icon: ReactNode + label: string + path: string +} + +export interface MiniDrawerProps { + menuItems: DrawerMenuItem[] + open: boolean + openHandler: React.Dispatch> +} + +export const MiniDrawer: React.FC = ({ + menuItems, open, openHandler, +}) => { + const navigate = useNavigate() + const { pathname } = useLocation() + const toggleDrawer = () => { + openHandler(!open) + } + + return ( + + + + {open ? : } + + + + + {menuItems.map(item => ( + navigate(item.path)} + /> + ))} + + + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/Drawer/StyledListItemButton.tsx b/packages/theme/src/showcase/dashboard/Drawer/StyledListItemButton.tsx new file mode 100644 index 00000000..8bf301b6 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/Drawer/StyledListItemButton.tsx @@ -0,0 +1,47 @@ +import { + alpha, ListItemButton, styled, +} from '@mui/material' +import { FlexRow } from '@xylabs/react-flexbox' + +// Styled span for wrapping menu icons +export const StyledMenuIconWrapSpan = styled('span', { name: 'StyledMenuIconWrapSpan' })(() => ({ + alignItems: 'center', + display: 'inline-flex', + flexDirection: 'column', +})) + +export const StyledFlexRow = styled(FlexRow, { name: 'StyledFlexRow' })(({ theme }) => ({ + '&:hover': { backgroundColor: alpha(theme.palette.text.primary, 0.05) }, + 'borderRadius': '10px', + 'paddingLeft': theme.spacing(0.5), + 'padding': theme.spacing(0.5), + 'flexGrow': 1, +})) + +export const StyledListItemButton = styled(ListItemButton, { name: 'StyledListItemButton', shouldForwardProp: prop => prop !== 'active' })<{ + active?: boolean +}>(({ theme, active }) => { + const activeOrHoverColor = theme.palette.primary.main + + return { + 'position': 'relative', + 'padding': '8px 16px', + 'borderRadius': '12px', + 'transition': 'background-color 0.3s ease', + '&:hover': { + backgroundColor: 'transparent', + borderRadius: '12px', + }, + '&::before': { + content: '""', + position: 'absolute', + left: 0, + top: 0, + bottom: 0, + width: '6px', + backgroundColor: active ? activeOrHoverColor : 'transparent', + borderRadius: '0 4px 4px 0', + transition: 'background-color 0.3s ease', + }, + } +}) diff --git a/packages/theme/src/showcase/dashboard/Drawer/Styling.tsx b/packages/theme/src/showcase/dashboard/Drawer/Styling.tsx new file mode 100644 index 00000000..aaeb7f78 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/Drawer/Styling.tsx @@ -0,0 +1,58 @@ +import { Drawer } from '@mui/material' +import type { CSSObject, Theme } from '@mui/material/styles' +import { styled } from '@mui/material/styles' + +export const sideDrawerWidth = 240 + +export const openedDrawerMixin = (theme: Theme): CSSObject => ({ + width: sideDrawerWidth, + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + overflowX: 'hidden', +}) + +export const closedDrawerMixin = (theme: Theme): CSSObject => ({ + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + overflowX: 'hidden', + width: `calc(${theme.spacing(7)} + 1px)`, + [theme.breakpoints.up('sm')]: { width: `calc(${theme.spacing(8)} + 1px)` }, +}) + +export const DrawerHeader = styled('div')(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + padding: theme.spacing(0, 1), + // necessary for content to be below app bar + ...theme.mixins.toolbar, +})) + +export const StyledDrawer = styled(Drawer, { shouldForwardProp: prop => prop !== 'open' })( + ({ theme }) => ({ + width: sideDrawerWidth, + flexShrink: 0, + whiteSpace: 'nowrap', + boxSizing: 'border-box', + variants: [ + { + props: ({ open }) => open, + style: { + ...openedDrawerMixin(theme), + '& .MuiDrawer-paper': openedDrawerMixin(theme), + }, + }, + { + props: ({ open }) => !open, + style: { + ...closedDrawerMixin(theme), + '& .MuiDrawer-paper': closedDrawerMixin(theme), + }, + }, + ], + }), +) diff --git a/packages/theme/src/showcase/dashboard/Drawer/index.ts b/packages/theme/src/showcase/dashboard/Drawer/index.ts new file mode 100644 index 00000000..1342808f --- /dev/null +++ b/packages/theme/src/showcase/dashboard/Drawer/index.ts @@ -0,0 +1,3 @@ +export * from './LogoutListItem.tsx' +export * from './MenuList.tsx' +export * from './MiniDrawer.tsx' diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/AllCategoriesData.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/AllCategoriesData.tsx new file mode 100644 index 00000000..e3b9a04f --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/AllCategoriesData.tsx @@ -0,0 +1,22 @@ +import type { Dashboard1Props } from '../../SampleDashboard1.tsx' +import { DataMappingData } from './DataMapping.tsx' +import { DepinMappingData } from './Depin.tsx' +import { EmployeeTrackingData } from './EmployeeTracking.tsx' +import { EventAttendanceData } from './EventAttendance.tsx' +import { GameFiData } from './GameFi.tsx' +import { MobileAppData } from './MobileApp.tsx' +import { PartnerValidationData } from './PartnerValidation.tsx' +import { RewardProgramsData } from './RewardPrograms.tsx' +import { SupplyChainData } from './SupplyChain.tsx' + +export const AllCategoriesData: Dashboard1Props = { + dataMapping: DataMappingData, + depin: DepinMappingData, + employeeTracking: EmployeeTrackingData, + eventAttendance: EventAttendanceData, + gamefi: GameFiData, + mobileApp: MobileAppData, + partnerValidation: PartnerValidationData, + rewardPrograms: RewardProgramsData, + supplyChain: SupplyChainData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/DataMapping.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/DataMapping.tsx new file mode 100644 index 00000000..e92c148a --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/DataMapping.tsx @@ -0,0 +1,88 @@ +/* eslint-disable @stylistic/max-len */ + +import React from 'react' + +import type { VerificationSummaryProps } from '../../../DataViewers/index.ts' +import { DailyVerificationScatterChart, generateVerificationData } from '../../../DataViewers/index.ts' +import type { Dashboard1DataProps } from '../../SampleDashboard1.tsx' + +export const VerificationSummaryData: VerificationSummaryProps = { + accuracyPercentage: 98.7, + comparisonText: "Compared to last month's data mapping accuracy", + comparisonValue: 6.2, + currentLocation: 'Austin, TX', + locationCheckCount: 512, + monthlyChange: 10.2, + monthlyVerificationCount: 2374, + regions: [ + { + name: 'Downtown Austin', time: '10:45 AM', verified: true, + }, + { + name: 'North Loop', time: '11:30 AM', verified: true, + }, + { + name: 'South Congress', time: '12:15 PM', verified: false, + }, + { + name: 'Zilker', time: '2:00 PM', verified: true, + }, + { + name: 'Hyde Park', time: '3:45 PM', verified: false, + }, + ], + status: 'Mapping and verifying points...', + title: 'Mapping Progress', + yearlyChange: 8.1, + yearlyVerificationCount: 11_563, + finalConfirmation: true, + locationHeader: 'Region', + timeHeader: 'Last Updated', + statusHeader: 'Verification Status', +} + +export const DataMappingData: Dashboard1DataProps = { + statCard1: { + headerTitle: '🗺️ Total Data Points Mapped', + value: 128_945_234, + change: 12.3, + description: 'High accuracy: 98.1%', + }, + statCard2: { + headerTitle: '🌍 Active Mapping Regions', + value: 78, + change: 15.4, + description: 'Regions with active verifications', + }, + statCard3: { + headerTitle: '📍 Points of Interest', + value: 1_054_832, + change: 7.8, + description: 'Verified and mapped points globally', + }, + statCard4: { + headerTitle: '🔍 Quality Checks', + value: 2_540_983, + change: 9.5, + description: 'Quality verifications completed this year', + }, + statCard5: { + headerTitle: '📊 Verified Datasets', + value: 345_780, + change: 11.7, + description: 'Datasets approved for mapping integration', + }, + statCard6: { + headerTitle: '⏱️ Average Verification Time', + value: 3.4, + change: -5.2, + description: 'Time (in minutes) per data point verification', + }, + dataCard: { + headerTitle: 'Verification Scatter Map', + cardContent: , + dataDescription: + 'Each point on the scatter map represents a location verification process. Verifications ensure data accuracy for mapping efforts, with higher verification counts improving confidence levels. Low-quality verifications are flagged.', + }, + verificationSummary: VerificationSummaryData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/Depin.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/Depin.tsx new file mode 100644 index 00000000..4ab3cdb5 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/Depin.tsx @@ -0,0 +1,88 @@ +/* eslint-disable @stylistic/max-len */ + +import React from 'react' + +import type { VerificationSummaryProps } from '../../../DataViewers/index.ts' +import { DailyVerificationScatterChart, generateVerificationData } from '../../../DataViewers/index.ts' +import type { Dashboard1DataProps } from '../../SampleDashboard1.tsx' + +export const VerificationSummaryData: VerificationSummaryProps = { + accuracyPercentage: 99.2, + comparisonText: "Compared to last month's infrastructure checks", + comparisonValue: 5.6, + currentLocation: 'Denver, CO', + locationCheckCount: 642, + monthlyChange: 12.4, + monthlyVerificationCount: 3122, + regions: [ + { + name: 'Capitol Hill', time: '9:30 AM', verified: true, + }, + { + name: 'Five Points', time: '11:00 AM', verified: true, + }, + { + name: 'Cherry Creek', time: '12:45 PM', verified: false, + }, + { + name: 'LoDo', time: '3:15 PM', verified: true, + }, + { + name: 'Baker', time: '4:30 PM', verified: false, + }, + ], + status: 'Updating infrastructure points...', + title: 'Infrastructure Validation', + yearlyChange: 9.8, + yearlyVerificationCount: 14_892, + finalConfirmation: true, + locationHeader: 'Region', + timeHeader: 'Last Verified', + statusHeader: 'Verification Status', +} + +export const DepinMappingData: Dashboard1DataProps = { + statCard1: { + headerTitle: '🏗️ Total Nodes Verified', + value: 1_023_567, + change: 14.1, + description: 'Validated across all active networks', + }, + statCard2: { + headerTitle: '🔗 Network Integrations', + value: 250, + change: 18.5, + description: 'Successful integrations this year', + }, + statCard3: { + headerTitle: '📡 Active Devices', + value: 2_945_123, + change: 9.3, + description: 'Devices currently connected to networks', + }, + statCard4: { + headerTitle: '📍 Verified Locations', + value: 842_376, + change: 11.6, + description: 'Verified DePIN access points', + }, + statCard5: { + headerTitle: '📊 Infrastructure Quality Checks', + value: 563_481, + change: 10.2, + description: 'Assessments completed this year', + }, + statCard6: { + headerTitle: '⏱️ Average Validation Time', + value: 2.8, + change: -7.4, + description: 'Minutes per infrastructure validation', + }, + dataCard: { + headerTitle: 'DePIN Verification Scatter Map', + cardContent: , + dataDescription: + 'This scatter map visualizes DePIN verification activities. High verification density areas indicate strong network reliability, while flagged points require additional checks.', + }, + verificationSummary: VerificationSummaryData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/EmployeeTracking.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/EmployeeTracking.tsx new file mode 100644 index 00000000..4bee07fc --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/EmployeeTracking.tsx @@ -0,0 +1,88 @@ +/* eslint-disable @stylistic/max-len */ + +import React from 'react' + +import type { VerificationSummaryProps } from '../../../DataViewers/index.ts' +import { DailyVerificationScatterChart, generateVerificationData } from '../../../DataViewers/index.ts' +import type { Dashboard1DataProps } from '../../SampleDashboard1.tsx' + +export const VerificationSummaryData: VerificationSummaryProps = { + accuracyPercentage: 96.5, + comparisonText: "Compared to last month's tracking data", + comparisonValue: 4.9, + currentLocation: 'Chicago, IL', + locationCheckCount: 412, + monthlyChange: 7.8, + monthlyVerificationCount: 2482, + regions: [ + { + name: 'Headquarters', time: '9:00 AM', verified: true, + }, + { + name: 'Remote Office 1', time: '10:15 AM', verified: true, + }, + { + name: 'Warehouse Facility', time: '12:30 PM', verified: false, + }, + { + name: 'Regional Hub', time: '2:45 PM', verified: true, + }, + { + name: 'Satellite Office', time: '4:00 PM', verified: false, + }, + ], + status: 'Processing employee check-ins...', + title: 'Employee Activity Monitoring', + yearlyChange: 6.5, + yearlyVerificationCount: 13_572, + finalConfirmation: true, + locationHeader: 'Office', + timeHeader: 'Last Check-In', + statusHeader: 'Verification Status', +} + +export const EmployeeTrackingData: Dashboard1DataProps = { + statCard1: { + headerTitle: '👥 Total Employee Check-Ins', + value: 1_023_874, + change: 12.7, + description: 'Verified across all locations', + }, + statCard2: { + headerTitle: '🏢 Active Worksites', + value: 125, + change: 8.4, + description: 'Locations with employee activity', + }, + statCard3: { + headerTitle: '⏱️ Average Check-In Time', + value: 4.2, + change: -3.1, + description: 'Minutes per employee verification', + }, + statCard4: { + headerTitle: '📈 Verified Records', + value: 2_784_365, + change: 10.3, + description: 'Employee activity logs verified this year', + }, + statCard5: { + headerTitle: '📊 Daily Check-Ins', + value: 8213, + change: 5.9, + description: 'Check-ins processed per day', + }, + statCard6: { + headerTitle: '🌍 Global Workforce Coverage', + value: 92, + change: 14.8, + description: 'Countries with active employee tracking', + }, + dataCard: { + headerTitle: 'Employee Check-In Scatter Map', + cardContent: , + dataDescription: + 'This scatter map displays employee check-ins across all active worksites. High verification areas reflect consistent activity, while flagged points indicate missing or delayed check-ins.', + }, + verificationSummary: VerificationSummaryData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/EventAttendance.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/EventAttendance.tsx new file mode 100644 index 00000000..e619c3c9 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/EventAttendance.tsx @@ -0,0 +1,88 @@ +/* eslint-disable @stylistic/max-len */ + +import React from 'react' + +import type { VerificationSummaryProps } from '../../../DataViewers/index.ts' +import { DailyVerificationScatterChart, generateVerificationData } from '../../../DataViewers/index.ts' +import type { Dashboard1DataProps } from '../../SampleDashboard1.tsx' + +export const VerificationSummaryData: VerificationSummaryProps = { + accuracyPercentage: 94.3, + comparisonText: "Compared to last month's event attendance data", + comparisonValue: 5.6, + currentLocation: 'Madison Square Garden, NY', + locationCheckCount: 712, + monthlyChange: 9.4, + monthlyVerificationCount: 4218, + regions: [ + { + name: 'Main Entrance', time: '6:30 PM', verified: true, + }, + { + name: 'Concessions Area 1', time: '7:15 PM', verified: true, + }, + { + name: 'VIP Lounge', time: '7:45 PM', verified: false, + }, + { + name: 'Upper Deck', time: '8:30 PM', verified: true, + }, + { + name: 'Parking Lot', time: '9:15 PM', verified: false, + }, + ], + status: 'Monitoring attendee check-ins...', + title: 'Event Attendance Tracking', + yearlyChange: 7.2, + yearlyVerificationCount: 16_394, + finalConfirmation: true, + locationHeader: 'Area', + timeHeader: 'Last Activity', + statusHeader: 'Verification Status', +} + +export const EventAttendanceData: Dashboard1DataProps = { + statCard1: { + headerTitle: '🎟️ Total Attendees Checked-In', + value: 56_783, + change: 15.4, + description: 'Verified attendees this event', + }, + statCard2: { + headerTitle: '📍 Verified Areas', + value: 32, + change: 10.8, + description: 'Checked-in and verified access points', + }, + statCard3: { + headerTitle: '⏱️ Average Wait Time', + value: 2.8, + change: -4.6, + description: 'Minutes per attendee check-in', + }, + statCard4: { + headerTitle: '🏟️ Total Event Capacity', + value: 75_000, + change: 0, + description: 'Maximum allowed for this event', + }, + statCard5: { + headerTitle: '🍿 Concession Check-Ins', + value: 8921, + change: 6.2, + description: 'Visitors verified at concession areas', + }, + statCard6: { + headerTitle: '📊 Daily Check-In Peak', + value: 9345, + change: 12.3, + description: 'Highest verified check-ins in one hour', + }, + dataCard: { + headerTitle: 'Event Attendance Scatter Map', + cardContent: , + dataDescription: + 'The scatter map highlights attendee check-in patterns across the arena. High-activity zones like main entrances and concessions are prominently visible. Areas with insufficient verifications are flagged.', + }, + verificationSummary: VerificationSummaryData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/GameFi.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/GameFi.tsx new file mode 100644 index 00000000..c5293df9 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/GameFi.tsx @@ -0,0 +1,88 @@ +/* eslint-disable @stylistic/max-len */ + +import React from 'react' + +import type { VerificationSummaryProps } from '../../../DataViewers/index.ts' +import { DailyVerificationScatterChart, generateVerificationData } from '../../../DataViewers/index.ts' +import type { Dashboard1DataProps } from '../../SampleDashboard1.tsx' + +export const VerificationSummaryData: VerificationSummaryProps = { + accuracyPercentage: 96.8, + comparisonText: "Compared to last month's player engagement metrics", + comparisonValue: 8.2, + currentLocation: 'Central Arena - GameFi Metaverse', + locationCheckCount: 632, + monthlyChange: 11.4, + monthlyVerificationCount: 5214, + regions: [ + { + name: 'Player Hub', time: '2:00 PM', verified: true, + }, + { + name: 'Marketplace', time: '3:30 PM', verified: true, + }, + { + name: 'Battle Arena', time: '4:45 PM', verified: false, + }, + { + name: 'Guild Hall', time: '5:15 PM', verified: true, + }, + { + name: 'Crafting Zone', time: '6:30 PM', verified: true, + }, + ], + status: 'Tracking player activity across zones...', + title: 'GameFi Player Engagement', + yearlyChange: 10.1, + yearlyVerificationCount: 18_947, + finalConfirmation: true, + locationHeader: 'Zone', + timeHeader: 'Last Activity', + statusHeader: 'Verification Status', +} + +export const GameFiData: Dashboard1DataProps = { + statCard1: { + headerTitle: '🎮 Total Players Logged-In', + value: 150_372, + change: 18.3, + description: 'Active players in the last 24 hours', + }, + statCard2: { + headerTitle: '🏆 Total Battles Completed', + value: 85_921, + change: 15.7, + description: 'Player engagements in battle zones', + }, + statCard3: { + headerTitle: '💰 Marketplace Transactions', + value: 42_348, + change: 12.5, + description: 'Items traded in the marketplace', + }, + statCard4: { + headerTitle: '⛏️ Items Crafted', + value: 18_754, + change: 9.8, + description: 'Items created in the crafting zones', + }, + statCard5: { + headerTitle: '👥 Guild Interactions', + value: 23_548, + change: 14.2, + description: 'Collaborations and guild activities', + }, + statCard6: { + headerTitle: '📈 Engagement Peak', + value: 12_435, + change: 17.9, + description: 'Players active in one hour', + }, + dataCard: { + headerTitle: 'GameFi Player Activity Map', + cardContent: , + dataDescription: + 'This scatter map visualizes player activity across GameFi zones. High-activity areas like battle arenas and marketplaces are highlighted, while low-engagement zones are flagged for improvement.', + }, + verificationSummary: VerificationSummaryData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/MobileApp.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/MobileApp.tsx new file mode 100644 index 00000000..dc18b538 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/MobileApp.tsx @@ -0,0 +1,88 @@ +/* eslint-disable @stylistic/max-len */ + +import React from 'react' + +import type { VerificationSummaryProps } from '../../../DataViewers/index.ts' +import { DailyVerificationScatterChart, generateVerificationData } from '../../../DataViewers/index.ts' +import type { Dashboard1DataProps } from '../../SampleDashboard1.tsx' + +export const VerificationSummaryData: VerificationSummaryProps = { + accuracyPercentage: 92.8, + comparisonText: "Compared to last month's engagement metrics", + comparisonValue: 8.6, + currentLocation: 'Global User Base', + locationCheckCount: 1245, + monthlyChange: 12.4, + monthlyVerificationCount: 8342, + regions: [ + { + name: 'North America', time: '9:15 AM', verified: true, + }, + { + name: 'Europe', time: '11:30 AM', verified: true, + }, + { + name: 'Asia-Pacific', time: '2:45 PM', verified: true, + }, + { + name: 'South America', time: '5:30 PM', verified: true, + }, + { + name: 'Africa', time: '7:00 PM', verified: false, + }, + ], + status: 'Tracking user engagement...', + title: 'User Activity Summary', + yearlyChange: 14.3, + yearlyVerificationCount: 32_485, + finalConfirmation: true, + locationHeader: 'Region', + timeHeader: 'Last Check-In', + statusHeader: 'Engagement Status', +} + +export const MobileAppData: Dashboard1DataProps = { + statCard1: { + headerTitle: '📱 Total App Users', + value: 2_394_582, + change: 14.6, + description: 'Active users in the past month', + }, + statCard2: { + headerTitle: '⏱️ Average Session Time', + value: 5.2, + change: 3.4, + description: 'Minutes per session on average', + }, + statCard3: { + headerTitle: '📈 Daily Active Users (DAU)', + value: 1_045_678, + change: 10.9, + description: 'Users active within the last 24 hours', + }, + statCard4: { + headerTitle: '🛒 Monthly Purchases', + value: 234_874, + change: 12.8, + description: 'In-app purchases completed', + }, + statCard5: { + headerTitle: '⭐ User Ratings', + value: 4.7, + change: 0.1, + description: 'Average rating across app stores', + }, + statCard6: { + headerTitle: '🔔 Notifications Opened', + value: 348_219, + change: 15.2, + description: 'Push notifications opened this month', + }, + dataCard: { + headerTitle: 'User Engagement Scatter Map', + cardContent: , + dataDescription: + 'Each point on the scatter map reflects app usage at specific hours of the day. Clusters indicate peak usage times, helping optimize app notifications and performance.', + }, + verificationSummary: VerificationSummaryData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/PartnerValidation.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/PartnerValidation.tsx new file mode 100644 index 00000000..c36ce459 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/PartnerValidation.tsx @@ -0,0 +1,88 @@ +/* eslint-disable @stylistic/max-len */ + +import React from 'react' + +import type { VerificationSummaryProps } from '../../../DataViewers/index.ts' +import { DailyVerificationScatterChart, generateVerificationData } from '../../../DataViewers/index.ts' +import type { Dashboard1DataProps } from '../../SampleDashboard1.tsx' + +export const VerificationSummaryData: VerificationSummaryProps = { + accuracyPercentage: 99.2, + comparisonText: "Compared to last month's partner validations", + comparisonValue: 7.1, + currentLocation: 'Global Partner Network', + locationCheckCount: 752, + monthlyChange: 9.3, + monthlyVerificationCount: 4324, + regions: [ + { + name: 'New York Office', time: '10:15 AM', verified: true, + }, + { + name: 'London Office', time: '12:45 PM', verified: true, + }, + { + name: 'Tokyo Office', time: '3:00 PM', verified: false, + }, + { + name: 'Sydney Office', time: '6:30 PM', verified: true, + }, + { + name: 'Berlin Office', time: '8:15 PM', verified: true, + }, + ], + status: 'Validating partnerships...', + title: 'Partner Verification Summary', + yearlyChange: 15.4, + yearlyVerificationCount: 16_523, + finalConfirmation: true, + locationHeader: 'Office', + timeHeader: 'Last Validation', + statusHeader: 'Validation Status', +} + +export const PartnerValidationData: Dashboard1DataProps = { + statCard1: { + headerTitle: '✅ Total Partners Validated', + value: 14_578, + change: 18.2, + description: 'Partners verified for compliance', + }, + statCard2: { + headerTitle: '🌐 Active Partnerships', + value: 6234, + change: 12.5, + description: 'Partners actively working within agreements', + }, + statCard3: { + headerTitle: '🔎 Compliance Checks Passed', + value: 5982, + change: 10.1, + description: 'Completed compliance verifications', + }, + statCard4: { + headerTitle: '📊 Validation Accuracy', + value: 99.2, + change: 1, + description: '% of accurate partner validations', + }, + statCard5: { + headerTitle: '📋 Pending Validations', + value: 342, + change: -4.3, + description: 'Awaiting compliance approval', + }, + statCard6: { + headerTitle: '⏱️ Average Validation Time', + value: 4.8, + change: -2.7, + description: 'Time (in minutes) per partner validation', + }, + dataCard: { + headerTitle: 'Partner Validation Scatter Chart', + cardContent: , + dataDescription: + 'Each point on the scatter map represents a partner’s validation process. Clusters indicate areas with high validation activity, ensuring compliance and strong partnerships.', + }, + verificationSummary: VerificationSummaryData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/RewardPrograms.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/RewardPrograms.tsx new file mode 100644 index 00000000..5d62c27b --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/RewardPrograms.tsx @@ -0,0 +1,88 @@ +/* eslint-disable @stylistic/max-len */ + +import React from 'react' + +import type { VerificationSummaryProps } from '../../../DataViewers/index.ts' +import { DailyVerificationScatterChart, generateVerificationData } from '../../../DataViewers/index.ts' +import type { Dashboard1DataProps } from '../../SampleDashboard1.tsx' + +export const VerificationSummaryData: VerificationSummaryProps = { + accuracyPercentage: 96.8, + comparisonText: "Compared to last month's reward activity", + comparisonValue: 4.2, + currentLocation: 'Downtown Seattle Location', + locationCheckCount: 842, + monthlyChange: 5.6, + monthlyVerificationCount: 3721, + regions: [ + { + name: 'Seattle', time: '8:30 AM', verified: true, + }, + { + name: 'Chicago', time: '10:45 AM', verified: true, + }, + { + name: 'New York', time: '1:15 PM', verified: false, + }, + { + name: 'Los Angeles', time: '3:30 PM', verified: true, + }, + { + name: 'Dallas', time: '6:45 PM', verified: true, + }, + ], + status: 'Validating reward redemptions...', + title: 'Reward Program Activity', + yearlyChange: 6.7, + yearlyVerificationCount: 28_134, + finalConfirmation: true, + locationHeader: 'Location', + timeHeader: 'Last Activity', + statusHeader: 'Verification Status', +} + +export const RewardProgramsData: Dashboard1DataProps = { + statCard1: { + headerTitle: '☕ Rewards Redeemed', + value: 1_345_678, + change: 12.3, + description: 'Free drinks and offers claimed', + }, + statCard2: { + headerTitle: '🎁 Total Offers Issued', + value: 2_451_932, + change: 15.7, + description: 'Special discounts and rewards shared', + }, + statCard3: { + headerTitle: '🌟 Active Members', + value: 1_210_456, + change: 8.9, + description: 'Loyalty program participants', + }, + statCard4: { + headerTitle: '📊 Average Redemption Rate', + value: 78.6, + change: 4.3, + description: '% of rewards redeemed per member', + }, + statCard5: { + headerTitle: '📅 Monthly New Signups', + value: 45_324, + change: 10.8, + description: 'New members joining the rewards program', + }, + statCard6: { + headerTitle: '⏱️ Average Redemption Time', + value: 1.2, + change: -2.5, + description: 'Time (in minutes) to process rewards', + }, + dataCard: { + headerTitle: 'Rewards Redemption Scatter Chart', + cardContent: , + dataDescription: + 'This scatter chart shows when and where rewards are redeemed. Higher redemption activity indicates peak times and popular locations, helping improve targeted promotions.', + }, + verificationSummary: VerificationSummaryData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/SupplyChain.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/SupplyChain.tsx new file mode 100644 index 00000000..a030aec9 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/SupplyChain.tsx @@ -0,0 +1,88 @@ +/* eslint-disable @stylistic/max-len */ + +import React from 'react' + +import type { VerificationSummaryProps } from '../../../DataViewers/index.ts' +import { DailyVerificationScatterChart, generateVerificationData } from '../../../DataViewers/index.ts' +import type { Dashboard1DataProps } from '../../SampleDashboard1.tsx' + +export const VerificationSummaryData: VerificationSummaryProps = { + accuracyPercentage: 97.5, + comparisonText: "Compared to last month's supply chain accuracy", + comparisonValue: 5.4, + currentLocation: 'Dallas Manufacturing Plant', + locationCheckCount: 1230, + monthlyChange: 9.1, + monthlyVerificationCount: 5432, + regions: [ + { + name: 'Dallas Plant', time: '7:45 AM', verified: true, + }, + { + name: 'Los Angeles Port', time: '9:30 AM', verified: true, + }, + { + name: 'New York Distribution', time: '11:15 AM', verified: true, + }, + { + name: 'Shanghai Hub', time: '3:00 PM', verified: true, + }, + { + name: 'Berlin Distribution Center', time: '8:30 PM', verified: false, + }, + ], + status: 'Tracking shipments and validating routes...', + title: 'Supply Chain Performance', + yearlyChange: 7.2, + yearlyVerificationCount: 65_893, + finalConfirmation: true, + locationHeader: 'Location', + timeHeader: 'Last Updated', + statusHeader: 'Verification Status', +} + +export const SupplyChainData: Dashboard1DataProps = { + statCard1: { + headerTitle: '🚛 Shipments Verified', + value: 3_847_342, + change: 8.5, + description: 'Validations of shipments globally', + }, + statCard2: { + headerTitle: '🏭 Active Factories', + value: 65, + change: 6.3, + description: 'Factories currently operational', + }, + statCard3: { + headerTitle: '🌍 Countries Covered', + value: 92, + change: 3.7, + description: 'Regions in the global network', + }, + statCard4: { + headerTitle: '⛴️ Shipping Routes Monitored', + value: 1245, + change: 12.4, + description: 'Active routes tracked for shipments', + }, + statCard5: { + headerTitle: '📦 On-Time Deliveries', + value: 89.7, + change: 5.1, + description: '% of shipments delivered on schedule', + }, + statCard6: { + headerTitle: '⏱️ Average Validation Time', + value: 4.2, + change: -3.1, + description: 'Time (in hours) per shipment validation', + }, + dataCard: { + headerTitle: 'Shipping Validation Scatter Chart', + cardContent: , + dataDescription: + 'This scatter chart visualizes the shipment validations across the global supply chain. Data points reflect factory operations, shipping routes, and distribution centers, ensuring efficiency and accuracy.', + }, + verificationSummary: VerificationSummaryData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/index.ts b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/index.ts new file mode 100644 index 00000000..ec596fff --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard1/index.ts @@ -0,0 +1,2 @@ +export * from './AllCategoriesData.tsx' +export * from './EventAttendance.tsx' diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/AllCategoriesData.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/AllCategoriesData.tsx new file mode 100644 index 00000000..44c2fce2 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/AllCategoriesData.tsx @@ -0,0 +1,14 @@ +import type { Dashboard2Props } from '../../SampleDashboard2.tsx' +import { DataMappingData } from './DataMapping.tsx' + +export const AllCategoriesData: Dashboard2Props = { + dataMapping: DataMappingData, + depin: DataMappingData, + employeeTracking: DataMappingData, + eventAttendance: DataMappingData, + gamefi: DataMappingData, + mobileApp: DataMappingData, + partnerValidation: DataMappingData, + rewardPrograms: DataMappingData, + supplyChain: DataMappingData, +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/DataMapping.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/DataMapping.tsx new file mode 100644 index 00000000..d5ddfca7 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/DataMapping.tsx @@ -0,0 +1,46 @@ +import type { Dashboard2DataProps } from '../../SampleDashboard2.tsx' + +export const DataMappingData: Dashboard2DataProps = { + statCard1: { + headerTitle: '🏆 Yearly Verifications', + value: 90_238_974, + change: 10.9, + description: 93.7 + '% Validated', + }, + statCard2: { + headerTitle: '🏆 Yearly Verifications', + value: 90_238_974, + change: 10.9, + description: 93.7 + '% Validated', + }, + statCard3: { + headerTitle: '🏆 Yearly Verifications', + value: 90_238_974, + change: 10.9, + description: 93.7 + '% Validated', + }, + statCard4: { + headerTitle: '🏆 Yearly Verifications', + value: 90_238_974, + change: 10.9, + description: 93.7 + '% Validated', + }, + pieChart: { + data01: [ + { name: 'Residential areas', value: 38 }, + { name: 'Public parking lots and garages', value: 10.9 }, + { name: 'Public transportation hubs', value: 7.4 }, + { name: 'Commercial and retail locations', value: 4.1 }, + { name: 'Workplace', value: 2.7 }, + ], + data02: [ + { name: 'Residential areas', value: 38 }, + { name: 'Public parking lots and garages', value: 10.9 }, + { name: 'Public transportation hubs', value: 7.4 }, + { name: 'Commercial and retail locations', value: 4.1 }, + { name: 'Workplace', value: 2.7 }, + ], + showLegend: true, + }, + +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/Depin.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/Depin.tsx new file mode 100644 index 00000000..0ff95055 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/Depin.tsx @@ -0,0 +1,46 @@ +import type { Dashboard2DataProps } from '../../SampleDashboard2.tsx' + +export const DepinData: Dashboard2DataProps = { + statCard1: { + headerTitle: '🏆 Yearly Verifications', + value: 90_238_974, + change: 10.9, + description: 93.7 + '% Validated', + }, + statCard2: { + headerTitle: '🏆 Yearly Verifications', + value: 90_238_974, + change: 10.9, + description: 93.7 + '% Validated', + }, + statCard3: { + headerTitle: '🏆 Yearly Verifications', + value: 90_238_974, + change: 10.9, + description: 93.7 + '% Validated', + }, + statCard4: { + headerTitle: '🏆 Yearly Verifications', + value: 90_238_974, + change: 10.9, + description: 93.7 + '% Validated', + }, + pieChart: { + data01: [ + { name: 'Residential areas', value: 38 }, + { name: 'Public parking lots and garages', value: 10.9 }, + { name: 'Public transportation hubs', value: 7.4 }, + { name: 'Commercial and retail locations', value: 4.1 }, + { name: 'Workplace', value: 2.7 }, + ], + data02: [ + { name: 'Residential areas', value: 38 }, + { name: 'Public parking lots and garages', value: 10.9 }, + { name: 'Public transportation hubs', value: 7.4 }, + { name: 'Commercial and retail locations', value: 4.1 }, + { name: 'Workplace', value: 2.7 }, + ], + showLegend: true, + }, + +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/index.ts b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/index.ts new file mode 100644 index 00000000..3c8d7a1d --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/SampleDashboard2/index.ts @@ -0,0 +1 @@ +export * from './AllCategoriesData.tsx' diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/index.ts b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/index.ts new file mode 100644 index 00000000..46a4182c --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/Data/index.ts @@ -0,0 +1,2 @@ +export * as SampleDashboard1Data from './SampleDashboard1/index.ts' +export * as SampleDashboard2Data from './SampleDashboard2/index.ts' diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/SampleDashboard1.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/SampleDashboard1.tsx new file mode 100644 index 00000000..8c8c66ea --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/SampleDashboard1.tsx @@ -0,0 +1,135 @@ +import { + Box, Grid2, Typography, +} from '@mui/material' +import { FlexRow } from '@xylabs/react-flexbox' +import React from 'react' + +import type { DataCardProps } from '../DataViewers/index.ts' +import { DataCard } from '../DataViewers/index.ts' +import type { VerificationSummaryProps } from '../DataViewers/VerificationSummary/index.ts' +import { VerificationSummary } from '../DataViewers/VerificationSummary/index.ts' +import type { StatCardProps } from '../StandardComponents/index.ts' +import { + DropdownSelect, DropdownSelectCategories, StatCard, +} from '../StandardComponents/index.ts' + +export interface Dashboard1DataProps { + dataCard: DataCardProps + statCard1: StatCardProps + statCard2: StatCardProps + statCard3: StatCardProps + statCard4: StatCardProps + statCard5: StatCardProps + statCard6: StatCardProps + verificationSummary: VerificationSummaryProps +} + +export interface Dashboard1Props { + dataMapping: Dashboard1DataProps + depin: Dashboard1DataProps + employeeTracking: Dashboard1DataProps + eventAttendance: Dashboard1DataProps + gamefi: Dashboard1DataProps + mobileApp: Dashboard1DataProps + partnerValidation: Dashboard1DataProps + rewardPrograms: Dashboard1DataProps + supplyChain: Dashboard1DataProps +} + +export const SampleDashboard1: React.FC = ({ + dataMapping, + depin, + employeeTracking, + eventAttendance, + gamefi, + mobileApp, + partnerValidation, + rewardPrograms, + supplyChain, +}) => { + const [category, setCategory] = React.useState('employeeTracking') + + // Map the categories to the data object + const dataMappingObject: Dashboard1Props = { + dataMapping, + depin, + employeeTracking, + eventAttendance, + gamefi, + mobileApp, + partnerValidation, + rewardPrograms, + supplyChain, + } + + // Get the data for the currently selected category + const currentData = dataMappingObject[category] + + // Log the values for debugging + console.log('Selected Category:', category) + console.log('Current Data:', currentData) + + const handleCategoryChange = (value: string) => { + console.log('Dropdown selected value:', value) + setCategory(value as keyof Dashboard1Props) + } + + return ( + + + + Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/SampleDashboard2.tsx b/packages/theme/src/showcase/dashboard/ExampleDashboards/SampleDashboard2.tsx new file mode 100644 index 00000000..ab8c66b9 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/SampleDashboard2.tsx @@ -0,0 +1,102 @@ +import { + Box, Grid2, Typography, +} from '@mui/material' +import { FlexRow } from '@xylabs/react-flexbox' +import React from 'react' + +import type { PieChartProps } from '../DataViewers/index.ts' +import { DataCard, StyledDualRingPieChart } from '../DataViewers/index.ts' +import type { StatCardProps } from '../StandardComponents/index.ts' +import { + DropdownSelect, DropdownSelectCategories, StatCard, +} from '../StandardComponents/index.ts' + +export interface Dashboard2DataProps { + pieChart: PieChartProps + statCard1: StatCardProps + statCard2: StatCardProps + statCard3: StatCardProps + statCard4: StatCardProps +} + +export interface Dashboard2Props { + dataMapping: Dashboard2DataProps + depin: Dashboard2DataProps + employeeTracking: Dashboard2DataProps + eventAttendance: Dashboard2DataProps + gamefi: Dashboard2DataProps + mobileApp: Dashboard2DataProps + partnerValidation: Dashboard2DataProps + rewardPrograms: Dashboard2DataProps + supplyChain: Dashboard2DataProps +} + +export const SampleDashboard2: React.FC = ({ + dataMapping, + depin, + employeeTracking, + eventAttendance, + gamefi, + mobileApp, + partnerValidation, + rewardPrograms, + supplyChain, +}) => { + const [category, setCategory] = React.useState('employeeTracking') + + // Map the categories to the data object + const dataMappingObject: Dashboard2Props = { + dataMapping, + depin, + employeeTracking, + eventAttendance, + gamefi, + mobileApp, + partnerValidation, + rewardPrograms, + supplyChain, + } + + const currentData = dataMappingObject[category] + + const handleCategoryChange = (value: string) => { + console.log('Dropdown selected value:', value) + setCategory(value as keyof Dashboard2Props) + } + + return ( + + + + Dashboard + + + + + + + + + + + + + + + + + + + + + + + }> + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/ExampleDashboards/index.ts b/packages/theme/src/showcase/dashboard/ExampleDashboards/index.ts new file mode 100644 index 00000000..c538e732 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/ExampleDashboards/index.ts @@ -0,0 +1,2 @@ +export * from './SampleDashboard1.tsx' +export * from './SampleDashboard2.tsx' diff --git a/packages/theme/src/showcase/dashboard/MenuNavItem.ts b/packages/theme/src/showcase/dashboard/MenuNavItem.ts new file mode 100644 index 00000000..136161f8 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/MenuNavItem.ts @@ -0,0 +1,14 @@ +export const MenuNavItemSchema = 'network.xyo.menu.nav.item' +export type MenuNavItemSchema = typeof MenuNavItemSchema + +export type MenuNavItem = + { + hidden?: boolean + matchType?: 'startsWith' | 'exact' + path: T + primaryText: string + secondaryText?: string + svgIcon?: string + svgIconActive?: string + weight?: number + } diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/AppChrome.stories.tsx b/packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/AppChrome.stories.tsx new file mode 100644 index 00000000..3b77cf41 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/AppChrome.stories.tsx @@ -0,0 +1,55 @@ +import { + DashboardRounded, + HubRounded, + PieChartRounded, + SettingsRounded, +} from '@mui/icons-material' +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' +import { BrowserRouter as Router } from 'react-router-dom' + +import { SampleDashboard1Data, SampleDashboard2Data } from '../../ExampleDashboards/Data/index.ts' +import { SampleDashboard1, SampleDashboard2 } from '../../ExampleDashboards/index.ts' +import type { AppChromeProps } from './AppChrome.tsx' +import { AppChrome } from './AppChrome.tsx' + +export default { + component: AppChrome, + title: 'components/AppChrome', +} as Meta + +const Template: StoryFn = args => ( + + + +) + +export const FullDashboard = Template.bind({}) +FullDashboard.args = { + items: [ + { + menuItem: { + label: 'Dashboard', icon: , path: '/dashboard', + }, + pageContent: , + }, + { + menuItem: { + label: 'Reports', icon: , path: '/reports', + }, + pageContent: , + }, + { + menuItem: { + label: 'Integrations', icon: , path: '/integrations', + }, + pageContent:
Send Email Content
, + }, + { + menuItem: { + label: 'Settings', icon: , path: '/settings', + }, + pageContent:
Drafts Content
, + }, + ], +} diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/AppChrome.tsx b/packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/AppChrome.tsx new file mode 100644 index 00000000..95e89bcd --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/AppChrome.tsx @@ -0,0 +1,108 @@ +import { MenuRounded } from '@mui/icons-material' +import type { BoxProps, CSSObject } from '@mui/material' +import { + AppBar as MuiAppBar, + Box, + CssBaseline, + IconButton, + styled, + Toolbar, + Typography, + useTheme, +} from '@mui/material' +import { FlexRow } from '@xylabs/react-flexbox' +import type { ReactNode } from 'react' +import React, { useState } from 'react' +import { + Navigate, Route, Routes, +} from 'react-router-dom' + +import type { DrawerMenuItem } from '../../Drawer/index.ts' +import { MiniDrawer } from '../../Drawer/index.ts' + +const drawerWidth = 240 + +const AppBar = styled(MuiAppBar, { shouldForwardProp: prop => prop !== 'open' })<{ + open?: boolean +}>(({ theme, open }) => ({ + zIndex: theme.zIndex.drawer + 1, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + ...(open && { + marginLeft: drawerWidth, + width: `calc(100% - ${drawerWidth}px)`, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }), +})) + +export interface AppPageProps { + menuItem: DrawerMenuItem & { path: string } + pageContent: ReactNode +} + +export interface AppChromeProps extends BoxProps { + items: AppPageProps[] +} + +export const AppChrome: React.FC = ({ items }) => { + const [open, setOpen] = useState(false) + const theme = useTheme() + const handleDrawerOpen = () => setOpen(true) + + // Extract menu items for the drawer + const menuItems = items.map(({ menuItem }) => menuItem) + + // Get the path of the first item to use as the default route + const defaultPath = menuItems[0].path + + const dockedDrawerWidth = (theme.components?.MuiDrawer?.styleOverrides?.docked as CSSObject)?.width || '96px' + + return ( + + + + + + + + + + + + XYO Explorer + + + + + + + + + } /> + {items.map(({ menuItem, pageContent }) => ( + {pageContent}} + /> + ))} + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/index.ts b/packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/index.ts new file mode 100644 index 00000000..b107be22 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/AppChrome/index.ts @@ -0,0 +1 @@ +export * from './AppChrome.tsx' diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/DataCard/DataCard.tsx b/packages/theme/src/showcase/dashboard/StandardComponents/DataCard/DataCard.tsx new file mode 100644 index 00000000..ade3a10b --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/DataCard/DataCard.tsx @@ -0,0 +1,63 @@ +import { + Card, + CardContent, + CardHeader, + Typography, +} from '@mui/material' +import { FlexCol } from '@xylabs/react-flexbox' +import type { ReactNode } from 'react' +import React from 'react' + +import { DataCardSpeedDial } from './DataCardSpeedDial.tsx' + +export interface DataCardProps { + cardContent?: ReactNode + dataDescription?: string + headerTitle?: string + size?: 'small' | 'medium' | 'large' +} + +export const DataCard: React.FC = ({ + headerTitle, + cardContent, + dataDescription, + size = 'medium', +}) => { + return ( + + + {headerTitle} + + )} + action={( + + )} + /> + {dataDescription + ? ( + + + {dataDescription} + + + ) + : null} + + + {cardContent} + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/DataCard/DataCardSpeedDial.tsx b/packages/theme/src/showcase/dashboard/StandardComponents/DataCard/DataCardSpeedDial.tsx new file mode 100644 index 00000000..3a9deb5a --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/DataCard/DataCardSpeedDial.tsx @@ -0,0 +1,104 @@ +import { + FileCopyRounded, + MoreHorizRounded, + PrintRounded, + SaveRounded, + ShareRounded, +} from '@mui/icons-material' +import { + Box, + SpeedDial, + SpeedDialAction, + styled, + useTheme, +} from '@mui/material' +import { animated, useSpring } from '@react-spring/web' +import React, { useState } from 'react' + +const actions = [ + { icon: , name: 'Copy' }, + { icon: , name: 'Save' }, + { icon: , name: 'Print' }, + { icon: , name: 'Share' }, +] + +interface AnimatedIconProps { + open: boolean + size?: 'small' | 'medium' | 'large' +} + +export const AnimatedIcon: React.FC = ({ open, size }) => { + const { transform } = useSpring({ + transform: open ? 'rotate(90deg)' : 'rotate(0deg)', + config: { tension: 200, friction: 15 }, + }) + + return ( + + + + ) +} + +const StyledSpeedDial = styled(SpeedDial)(({ theme }) => ({ + 'position': 'absolute', + 'top': '0', + 'right': '0', + '& .MuiSpeedDial-fab': { + 'backgroundColor': 'transparent', + 'color': theme.palette.text.primary, + 'boxShadow': 'none', + 'minWidth': 'auto', + 'minHeight': 'auto', + '&:hover': { backgroundColor: 'transparent' }, + }, +})) + +interface DataCardSpeedDialProps { + size?: 'small' | 'medium' | 'large' +} + +export const DataCardSpeedDial: React.FC = ({ size }) => { + const [open, setOpen] = useState(false) + const theme = useTheme() + + const handleOpen = () => setOpen(true) + const handleClose = () => setOpen(false) + + return ( + + } + FabProps={{ size: size }} + direction="down" + onClose={handleClose} + onOpen={handleOpen} + open={open} + sx={{ zIndex: open ? 1300 : 1 }} + + > + {actions.map(action => ( + + ))} + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/DataCard/index.ts b/packages/theme/src/showcase/dashboard/StandardComponents/DataCard/index.ts new file mode 100644 index 00000000..b2564d16 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/DataCard/index.ts @@ -0,0 +1,2 @@ +export * from './DataCard.tsx' +export * from './DataCardSpeedDial.tsx' diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelect.stories.tsx b/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelect.stories.tsx new file mode 100644 index 00000000..efeca82c --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelect.stories.tsx @@ -0,0 +1,23 @@ +import type { Meta, StoryFn } from '@storybook/react' +import { FlexRow } from '@xylabs/react-flexbox' +import React from 'react' + +import type { DropdownSelectProps } from './DropdownSelect.tsx' +import { DropdownSelect } from './DropdownSelect.tsx' +import { DropdownSelectCategories } from './DropdownSelectData.tsx' + +export default { + component: DropdownSelect, + title: 'components/DropdownSelect', +} as Meta + +const Template: StoryFn = args => ( + + + +) + +export const Default = Template.bind({}) +Default.args = { + items: DropdownSelectCategories, onChange: console.log, selectedValue: 'gamefi', +} diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelect.tsx b/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelect.tsx new file mode 100644 index 00000000..6718e31a --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelect.tsx @@ -0,0 +1,99 @@ +import { KeyboardArrowDownRounded } from '@mui/icons-material' +import type { SelectChangeEvent, SelectProps } from '@mui/material' +import { + alpha, + Box, + FormControl, + MenuItem, + Select, + Typography, + useTheme, +} from '@mui/material' +import { FlexRow } from '@xylabs/react-flexbox' +import React, { useEffect, useState } from 'react' + +export interface DropdownItem { + icon: React.ReactNode + text: string + value: string +} + +export interface DropdownSelectProps { + items: DropdownItem[] + onChange: (value: string) => void + selectedValue: string + size?: SelectProps['size'] +} + +export const DropdownSelect: React.FC = ({ + items, + onChange, + selectedValue, + size, +}) => { + const theme = useTheme() + const [localSelectedValue, setLocalSelectedValue] = useState(selectedValue) + + useEffect(() => { + setLocalSelectedValue(selectedValue) + }, [selectedValue]) + + const handleChange = (event: SelectChangeEvent) => { + const newValue = event.target.value + setLocalSelectedValue(newValue) + onChange(newValue) + } + + return ( + + + + + + ) +} diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelectData.tsx b/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelectData.tsx new file mode 100644 index 00000000..4db0d713 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/DropdownSelectData.tsx @@ -0,0 +1,36 @@ +import { + CardGiftcard, Event, LocalShipping, Map, People, PhoneAndroid, Public, SportsEsports, VerifiedUser, +} from '@mui/icons-material' +import React from 'react' + +import type { DropdownItem } from './DropdownSelect.tsx' + +export const DropdownSelectCategories: DropdownItem[] = [ + { + icon: , text: 'Data Mapping', value: 'dataMapping', + }, + { + icon: , text: 'DePIN', value: 'depin', + }, + { + icon: , text: 'Employee Tracking', value: 'employeeTracking', + }, + { + icon: , text: 'Event Attendance', value: 'eventAttendance', + }, + { + icon: , text: 'GameFi', value: 'gamefi', + }, + { + icon: , text: 'Mobile Apps', value: 'mobileApp', + }, + { + icon: , text: 'Partner Validation', value: 'partnerValidation', + }, + { + icon: , text: 'Reward Programs', value: 'rewardPrograms', + }, + { + icon: , text: 'Supply Chain', value: 'supplyChain', + }, +] diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/index.ts b/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/index.ts new file mode 100644 index 00000000..11f363e2 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/DropdownSelect/index.ts @@ -0,0 +1,2 @@ +export * from './DropdownSelect.tsx' +export * from './DropdownSelectData.tsx' diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/StatCard/StatCard.tsx b/packages/theme/src/showcase/dashboard/StandardComponents/StatCard/StatCard.tsx new file mode 100644 index 00000000..373baa67 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/StatCard/StatCard.tsx @@ -0,0 +1,92 @@ +import { ArrowDownwardRounded, ArrowUpwardRounded } from '@mui/icons-material' +import { + Tooltip, + Typography, + useTheme, +} from '@mui/material' +import { FlexCol, FlexRow } from '@xylabs/react-flexbox' +import React from 'react' + +import type { DataCardProps } from '../DataCard/index.ts' +import { DataCard } from '../DataCard/index.ts' + +export interface StatCardProps extends DataCardProps { + change: number + customUnit?: string + description?: string + reverseDirectionality?: boolean + value: number +} + +const formatNumber = (num: number): string => { + if (num >= 1_000_000) { + return `${(num / 1_000_000).toFixed(1)}m` + } + if (num >= 1000) { + return `${(num / 1000).toFixed(1)}k` + } + return num.toString() +} + +export const StatCard: React.FC = ({ + headerTitle, value, change, description, customUnit, reverseDirectionality = false, ...props +}) => { + const theme = useTheme() + + const isPositive = change >= 0 + const changeColor = isPositive && !reverseDirectionality + ? theme.palette.success.main + : isPositive && reverseDirectionality + ? theme.palette.error.main + : theme.palette.success.main + const formattedValue = formatNumber(value) + const showTooltip = formattedValue !== value.toString() + + return ( + + + {showTooltip + ? ( + + + {formattedValue} + {' '} + {customUnit} + + + ) + : ( + + {formattedValue} + {' '} + {customUnit} + + )} + + {isPositive + ? ( + + ) + : ( + + )} + + {Math.abs(change)} + % + + + + {description && ( + + {description} + + )} + + )} + /> + ) +} diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/StatCard/index.ts b/packages/theme/src/showcase/dashboard/StandardComponents/StatCard/index.ts new file mode 100644 index 00000000..ea392be2 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/StatCard/index.ts @@ -0,0 +1 @@ +export * from './StatCard.tsx' diff --git a/packages/theme/src/showcase/dashboard/StandardComponents/index.ts b/packages/theme/src/showcase/dashboard/StandardComponents/index.ts new file mode 100644 index 00000000..85eba059 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StandardComponents/index.ts @@ -0,0 +1,3 @@ +export * from './DataCard/index.ts' +export * from './DropdownSelect/index.ts' +export * from './StatCard/index.ts' diff --git a/packages/theme/src/showcase/dashboard/StyledListItemButton.stories.tsx b/packages/theme/src/showcase/dashboard/StyledListItemButton.stories.tsx new file mode 100644 index 00000000..c808dc1b --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StyledListItemButton.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryFn } from '@storybook/react' +import React from 'react' + +import { StyledListItemButton } from './StyledListItemButton.tsx' + +export default { + component: StyledListItemButton, + title: 'components/StyledListItemButton', +} as Meta + +const Template: StoryFn = args => + +export const Default = Template.bind({}) +Default.args = { children: 'Sample List Item' } + +export const WithIconWrap = Template.bind({}) +WithIconWrap.args = { children: 📁 Sample Icon Wrap } diff --git a/packages/theme/src/showcase/dashboard/StyledListItemButton.tsx b/packages/theme/src/showcase/dashboard/StyledListItemButton.tsx new file mode 100644 index 00000000..8bf301b6 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/StyledListItemButton.tsx @@ -0,0 +1,47 @@ +import { + alpha, ListItemButton, styled, +} from '@mui/material' +import { FlexRow } from '@xylabs/react-flexbox' + +// Styled span for wrapping menu icons +export const StyledMenuIconWrapSpan = styled('span', { name: 'StyledMenuIconWrapSpan' })(() => ({ + alignItems: 'center', + display: 'inline-flex', + flexDirection: 'column', +})) + +export const StyledFlexRow = styled(FlexRow, { name: 'StyledFlexRow' })(({ theme }) => ({ + '&:hover': { backgroundColor: alpha(theme.palette.text.primary, 0.05) }, + 'borderRadius': '10px', + 'paddingLeft': theme.spacing(0.5), + 'padding': theme.spacing(0.5), + 'flexGrow': 1, +})) + +export const StyledListItemButton = styled(ListItemButton, { name: 'StyledListItemButton', shouldForwardProp: prop => prop !== 'active' })<{ + active?: boolean +}>(({ theme, active }) => { + const activeOrHoverColor = theme.palette.primary.main + + return { + 'position': 'relative', + 'padding': '8px 16px', + 'borderRadius': '12px', + 'transition': 'background-color 0.3s ease', + '&:hover': { + backgroundColor: 'transparent', + borderRadius: '12px', + }, + '&::before': { + content: '""', + position: 'absolute', + left: 0, + top: 0, + bottom: 0, + width: '6px', + backgroundColor: active ? activeOrHoverColor : 'transparent', + borderRadius: '0 4px 4px 0', + transition: 'background-color 0.3s ease', + }, + } +}) diff --git a/packages/theme/src/showcase/dashboard/index.ts b/packages/theme/src/showcase/dashboard/index.ts new file mode 100644 index 00000000..a3bbeb33 --- /dev/null +++ b/packages/theme/src/showcase/dashboard/index.ts @@ -0,0 +1,4 @@ +export * from './DataViewers/index.ts' +export * from './Drawer/index.ts' +export * from './ExampleDashboards/index.ts' +export * from './StandardComponents/index.ts' diff --git a/packages/theme/src/showcase/index.ts b/packages/theme/src/showcase/index.ts new file mode 100644 index 00000000..cb86a7cb --- /dev/null +++ b/packages/theme/src/showcase/index.ts @@ -0,0 +1,2 @@ +export * from './dashboard/index.ts' +export * from './theme/index.ts' diff --git a/packages/theme/src/ColorCard.tsx b/packages/theme/src/showcase/theme/ColorCard.tsx similarity index 100% rename from packages/theme/src/ColorCard.tsx rename to packages/theme/src/showcase/theme/ColorCard.tsx diff --git a/packages/theme/src/ColorShowcase.stories.tsx b/packages/theme/src/showcase/theme/ColorShowcase.stories.tsx similarity index 95% rename from packages/theme/src/ColorShowcase.stories.tsx rename to packages/theme/src/showcase/theme/ColorShowcase.stories.tsx index 4b0b17a3..4c7bb2b2 100644 --- a/packages/theme/src/ColorShowcase.stories.tsx +++ b/packages/theme/src/showcase/theme/ColorShowcase.stories.tsx @@ -9,7 +9,7 @@ const StorybookEntry = { argTypes: {}, component: ColorShowcase, parameters: { docs: { page: null }, layout: 'fullscreen' }, - title: 'Theme/ColorShowcase', + title: 'theme/showcase/ColorShowcase', } as Meta const Template: StoryFn = () => ( diff --git a/packages/theme/src/ColorShowcase.tsx b/packages/theme/src/showcase/theme/ColorShowcase.tsx similarity index 92% rename from packages/theme/src/ColorShowcase.tsx rename to packages/theme/src/showcase/theme/ColorShowcase.tsx index e19a43bb..32ad5827 100644 --- a/packages/theme/src/ColorShowcase.tsx +++ b/packages/theme/src/showcase/theme/ColorShowcase.tsx @@ -21,14 +21,14 @@ export const ColorShowcase: React.FC = () => { subtype="Gradient" /> diff --git a/packages/theme/src/ThemeShowcase.stories.tsx b/packages/theme/src/showcase/theme/ThemeShowcase.stories.tsx similarity index 93% rename from packages/theme/src/ThemeShowcase.stories.tsx rename to packages/theme/src/showcase/theme/ThemeShowcase.stories.tsx index fcd404d9..582e1e6e 100644 --- a/packages/theme/src/ThemeShowcase.stories.tsx +++ b/packages/theme/src/showcase/theme/ThemeShowcase.stories.tsx @@ -8,7 +8,7 @@ const StorybookEntry = { argTypes: {}, component: ThemeShowcase, parameters: { docs: { page: null } }, - title: 'Theme/ThemeShowcase', + title: 'theme/showcase/ThemeShowcase', } as Meta const Template: StoryFn = () => ( diff --git a/packages/theme/src/ThemeShowcase.tsx b/packages/theme/src/showcase/theme/ThemeShowcase.tsx similarity index 100% rename from packages/theme/src/ThemeShowcase.tsx rename to packages/theme/src/showcase/theme/ThemeShowcase.tsx diff --git a/packages/theme/src/showcase/theme/index.ts b/packages/theme/src/showcase/theme/index.ts new file mode 100644 index 00000000..141ad241 --- /dev/null +++ b/packages/theme/src/showcase/theme/index.ts @@ -0,0 +1,3 @@ +export * from './ColorCard.tsx' +export * from './ColorShowcase.tsx' +export * from './ThemeShowcase.tsx' diff --git a/yarn.lock b/yarn.lock index 6d8564bc..46685d6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3771,6 +3771,75 @@ __metadata: languageName: node linkType: hard +"@types/d3-array@npm:^3.0.3": + version: 3.2.1 + resolution: "@types/d3-array@npm:3.2.1" + checksum: 10c0/38bf2c778451f4b79ec81a2288cb4312fe3d6449ecdf562970cc339b60f280f31c93a024c7ff512607795e79d3beb0cbda123bb07010167bce32927f71364bca + languageName: node + linkType: hard + +"@types/d3-color@npm:*": + version: 3.1.3 + resolution: "@types/d3-color@npm:3.1.3" + checksum: 10c0/65eb0487de606eb5ad81735a9a5b3142d30bc5ea801ed9b14b77cb14c9b909f718c059f13af341264ee189acf171508053342142bdf99338667cea26a2d8d6ae + languageName: node + linkType: hard + +"@types/d3-ease@npm:^3.0.0": + version: 3.0.2 + resolution: "@types/d3-ease@npm:3.0.2" + checksum: 10c0/aff5a1e572a937ee9bff6465225d7ba27d5e0c976bd9eacdac2e6f10700a7cb0c9ea2597aff6b43a6ed850a3210030870238894a77ec73e309b4a9d0333f099c + languageName: node + linkType: hard + +"@types/d3-interpolate@npm:^3.0.1": + version: 3.0.4 + resolution: "@types/d3-interpolate@npm:3.0.4" + dependencies: + "@types/d3-color": "npm:*" + checksum: 10c0/066ebb8da570b518dd332df6b12ae3b1eaa0a7f4f0c702e3c57f812cf529cc3500ec2aac8dc094f31897790346c6b1ebd8cd7a077176727f4860c2b181a65ca4 + languageName: node + linkType: hard + +"@types/d3-path@npm:*": + version: 3.1.0 + resolution: "@types/d3-path@npm:3.1.0" + checksum: 10c0/85e8b3aa968a60a5b33198ade06ae7ffedcf9a22d86f24859ff58e014b053ccb7141ec163b78d547bc8215bb12bb54171c666057ab6156912814005b686afb31 + languageName: node + linkType: hard + +"@types/d3-scale@npm:^4.0.2": + version: 4.0.8 + resolution: "@types/d3-scale@npm:4.0.8" + dependencies: + "@types/d3-time": "npm:*" + checksum: 10c0/57de90e4016f640b83cb960b7e3a0ab3ed02e720898840ddc5105264ffcfea73336161442fdc91895377c2d2f91904d637282f16852b8535b77e15a761c8e99e + languageName: node + linkType: hard + +"@types/d3-shape@npm:^3.1.0": + version: 3.1.6 + resolution: "@types/d3-shape@npm:3.1.6" + dependencies: + "@types/d3-path": "npm:*" + checksum: 10c0/0625715925d3c7ed3d44ce998b42c993f063c31605b6e4a8046c4be0fe724e2d214fc83e86d04f429a30a6e1f439053e92b0d9e59e1180c3a5327b4a6e79fa0a + languageName: node + linkType: hard + +"@types/d3-time@npm:*, @types/d3-time@npm:^3.0.0": + version: 3.0.4 + resolution: "@types/d3-time@npm:3.0.4" + checksum: 10c0/6d9e2255d63f7a313a543113920c612e957d70da4fb0890931da6c2459010291b8b1f95e149a538500c1c99e7e6c89ffcce5554dd29a31ff134a38ea94b6d174 + languageName: node + linkType: hard + +"@types/d3-timer@npm:^3.0.0": + version: 3.0.2 + resolution: "@types/d3-timer@npm:3.0.2" + checksum: 10c0/c644dd9571fcc62b1aa12c03bcad40571553020feeb5811f1d8a937ac1e65b8a04b759b4873aef610e28b8714ac71c9885a4d6c127a048d95118f7e5b506d9e1 + languageName: node + linkType: hard + "@types/debug@npm:^4.0.0, @types/debug@npm:^4.1.7": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" @@ -5274,16 +5343,20 @@ __metadata: "@mui/material": "npm:^6.1.8" "@storybook/react": "npm:^8.4.5" "@types/react": "npm:^18.3.12" + "@xylabs/react-flexbox": "workspace:^" "@xylabs/react-invertible-theme": "workspace:^" "@xylabs/ts-scripts-yarn3": "npm:^4.2.4" "@xylabs/tsconfig-react": "npm:^4.2.4" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" - typescript: "npm:^5.7.2" + recharts: "npm:^2.13.3" + typescript: "npm:^5.6.3" peerDependencies: + "@mui/icons-material": ^6 "@mui/material": ^6 react: ^18 react-dom: ^18 + react-router-dom: ^6 languageName: unknown linkType: soft @@ -6481,7 +6554,7 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^2.1.1": +"clsx@npm:^2.0.0, clsx@npm:^2.1.1": version: 2.1.1 resolution: "clsx@npm:2.1.1" checksum: 10c0/c4c8eb865f8c82baab07e71bfa8897c73454881c4f99d6bc81585aecd7c441746c1399d08363dc096c550cceaf97bd4ce1e8854e1771e9998d9f94c4fe075839 @@ -6792,6 +6865,99 @@ __metadata: languageName: node linkType: hard +"d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:^3.1.6": + version: 3.2.4 + resolution: "d3-array@npm:3.2.4" + dependencies: + internmap: "npm:1 - 2" + checksum: 10c0/08b95e91130f98c1375db0e0af718f4371ccacef7d5d257727fe74f79a24383e79aba280b9ffae655483ffbbad4fd1dec4ade0119d88c4749f388641c8bf8c50 + languageName: node + linkType: hard + +"d3-color@npm:1 - 3": + version: 3.1.0 + resolution: "d3-color@npm:3.1.0" + checksum: 10c0/a4e20e1115fa696fce041fbe13fbc80dc4c19150fa72027a7c128ade980bc0eeeba4bcf28c9e21f0bce0e0dbfe7ca5869ef67746541dcfda053e4802ad19783c + languageName: node + linkType: hard + +"d3-ease@npm:^3.0.1": + version: 3.0.1 + resolution: "d3-ease@npm:3.0.1" + checksum: 10c0/fec8ef826c0cc35cda3092c6841e07672868b1839fcaf556e19266a3a37e6bc7977d8298c0fcb9885e7799bfdcef7db1baaba9cd4dcf4bc5e952cf78574a88b0 + languageName: node + linkType: hard + +"d3-format@npm:1 - 3": + version: 3.1.0 + resolution: "d3-format@npm:3.1.0" + checksum: 10c0/049f5c0871ebce9859fc5e2f07f336b3c5bfff52a2540e0bac7e703fce567cd9346f4ad1079dd18d6f1e0eaa0599941c1810898926f10ac21a31fd0a34b4aa75 + languageName: node + linkType: hard + +"d3-interpolate@npm:1.2.0 - 3, d3-interpolate@npm:^3.0.1": + version: 3.0.1 + resolution: "d3-interpolate@npm:3.0.1" + dependencies: + d3-color: "npm:1 - 3" + checksum: 10c0/19f4b4daa8d733906671afff7767c19488f51a43d251f8b7f484d5d3cfc36c663f0a66c38fe91eee30f40327443d799be17169f55a293a3ba949e84e57a33e6a + languageName: node + linkType: hard + +"d3-path@npm:^3.1.0": + version: 3.1.0 + resolution: "d3-path@npm:3.1.0" + checksum: 10c0/dc1d58ec87fa8319bd240cf7689995111a124b141428354e9637aa83059eb12e681f77187e0ada5dedfce346f7e3d1f903467ceb41b379bfd01cd8e31721f5da + languageName: node + linkType: hard + +"d3-scale@npm:^4.0.2": + version: 4.0.2 + resolution: "d3-scale@npm:4.0.2" + dependencies: + d3-array: "npm:2.10.0 - 3" + d3-format: "npm:1 - 3" + d3-interpolate: "npm:1.2.0 - 3" + d3-time: "npm:2.1.1 - 3" + d3-time-format: "npm:2 - 4" + checksum: 10c0/65d9ad8c2641aec30ed5673a7410feb187a224d6ca8d1a520d68a7d6eac9d04caedbff4713d1e8545be33eb7fec5739983a7ab1d22d4e5ad35368c6729d362f1 + languageName: node + linkType: hard + +"d3-shape@npm:^3.1.0": + version: 3.2.0 + resolution: "d3-shape@npm:3.2.0" + dependencies: + d3-path: "npm:^3.1.0" + checksum: 10c0/f1c9d1f09926daaf6f6193ae3b4c4b5521e81da7d8902d24b38694517c7f527ce3c9a77a9d3a5722ad1e3ff355860b014557b450023d66a944eabf8cfde37132 + languageName: node + linkType: hard + +"d3-time-format@npm:2 - 4": + version: 4.1.0 + resolution: "d3-time-format@npm:4.1.0" + dependencies: + d3-time: "npm:1 - 3" + checksum: 10c0/735e00fb25a7fd5d418fac350018713ae394eefddb0d745fab12bbff0517f9cdb5f807c7bbe87bb6eeb06249662f8ea84fec075f7d0cd68609735b2ceb29d206 + languageName: node + linkType: hard + +"d3-time@npm:1 - 3, d3-time@npm:2.1.1 - 3, d3-time@npm:^3.0.0": + version: 3.1.0 + resolution: "d3-time@npm:3.1.0" + dependencies: + d3-array: "npm:2 - 3" + checksum: 10c0/a984f77e1aaeaa182679b46fbf57eceb6ebdb5f67d7578d6f68ef933f8eeb63737c0949991618a8d29472dbf43736c7d7f17c452b2770f8c1271191cba724ca1 + languageName: node + linkType: hard + +"d3-timer@npm:^3.0.1": + version: 3.0.1 + resolution: "d3-timer@npm:3.0.1" + checksum: 10c0/d4c63cb4bb5461d7038aac561b097cd1c5673969b27cbdd0e87fa48d9300a538b9e6f39b4a7f0e3592ef4f963d858c8a9f0e92754db73116770856f2fc04561a + languageName: node + linkType: hard + "damerau-levenshtein@npm:^1.0.8": version: 1.0.8 resolution: "damerau-levenshtein@npm:1.0.8" @@ -6886,6 +7052,13 @@ __metadata: languageName: node linkType: hard +"decimal.js-light@npm:^2.4.1": + version: 2.5.1 + resolution: "decimal.js-light@npm:2.5.1" + checksum: 10c0/4fd33f535aac9e5bd832796831b65d9ec7914ad129c7437b3ab991b0c2eaaa5a57e654e6174c4a17f1b3895ea366f0c1ab4955cdcdf7cfdcf3ad5a58b456c020 + languageName: node + linkType: hard + "decode-named-character-reference@npm:^1.0.0": version: 1.0.2 resolution: "decode-named-character-reference@npm:1.0.2" @@ -8265,6 +8438,13 @@ __metadata: languageName: node linkType: hard +"eventemitter3@npm:^4.0.1": + version: 4.0.7 + resolution: "eventemitter3@npm:4.0.7" + checksum: 10c0/5f6d97cbcbac47be798e6355e3a7639a84ee1f7d9b199a07017f1d2f1e2fe236004d14fa5dfaeba661f94ea57805385e326236a6debbc7145c8877fbc0297c6b + languageName: node + linkType: hard + "events@npm:^3.3.0": version: 3.3.0 resolution: "events@npm:3.3.0" @@ -8327,6 +8507,13 @@ __metadata: languageName: node linkType: hard +"fast-equals@npm:^5.0.1": + version: 5.0.1 + resolution: "fast-equals@npm:5.0.1" + checksum: 10c0/d7077b8b681036c2840ed9860a3048e44fc268fad2b525b8f25b43458be0c8ad976152eb4b475de9617170423c5b802121ebb61ed6641c3ac035fadaf805c8c0 + languageName: node + linkType: hard + "fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.2": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" @@ -9218,6 +9405,13 @@ __metadata: languageName: node linkType: hard +"internmap@npm:1 - 2": + version: 2.0.3 + resolution: "internmap@npm:2.0.3" + checksum: 10c0/8cedd57f07bbc22501516fbfc70447f0c6812871d471096fad9ea603516eacc2137b633633daf432c029712df0baefd793686388ddf5737e3ea15074b877f7ed + languageName: node + linkType: hard + "ip-address@npm:^9.0.5": version: 9.0.5 resolution: "ip-address@npm:9.0.5" @@ -12281,6 +12475,20 @@ __metadata: languageName: node linkType: hard +"react-smooth@npm:^4.0.0": + version: 4.0.1 + resolution: "react-smooth@npm:4.0.1" + dependencies: + fast-equals: "npm:^5.0.1" + prop-types: "npm:^15.8.1" + react-transition-group: "npm:^4.4.5" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/5c19a2c147798c3de1329d442b1a371139c01113cc108c38c201b63502c329f943ede505c44089d26a6563eaa72a67b845d538d956f34a389b37fd3961308834 + languageName: node + linkType: hard + "react-transition-group@npm:^4.4.5": version: 4.4.5 resolution: "react-transition-group@npm:4.4.5" @@ -12423,6 +12631,34 @@ __metadata: languageName: node linkType: hard +"recharts-scale@npm:^0.4.4": + version: 0.4.5 + resolution: "recharts-scale@npm:0.4.5" + dependencies: + decimal.js-light: "npm:^2.4.1" + checksum: 10c0/64ce1fc4ebe62001787bf4dc4cbb779452d33831619309c71c50277c58e8968ffe98941562d9d0d5ffdb02588ebd62f4fe6548fa826110fd458db9c3cc6dadc1 + languageName: node + linkType: hard + +"recharts@npm:^2.13.3": + version: 2.13.3 + resolution: "recharts@npm:2.13.3" + dependencies: + clsx: "npm:^2.0.0" + eventemitter3: "npm:^4.0.1" + lodash: "npm:^4.17.21" + react-is: "npm:^18.3.1" + react-smooth: "npm:^4.0.0" + recharts-scale: "npm:^0.4.4" + tiny-invariant: "npm:^1.3.1" + victory-vendor: "npm:^36.6.8" + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/67c516cd142da0e5968cf9b723c1bc08c2324ff4c41952d623dfce06e8c13751e1ef885b2e39aaeb5e32595566c8d91633328850adee70ad53bc8685adff456d + languageName: node + linkType: hard + "redent@npm:^3.0.0": version: 3.0.0 resolution: "redent@npm:3.0.0" @@ -14897,7 +15133,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.7.2": +"typescript@npm:^5.6.3, typescript@npm:^5.7.2": version: 5.7.2 resolution: "typescript@npm:5.7.2" bin: @@ -14917,7 +15153,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.7.2#optional!builtin": +"typescript@patch:typescript@npm%3A^5.6.3#optional!builtin, typescript@patch:typescript@npm%3A^5.7.2#optional!builtin": version: 5.7.2 resolution: "typescript@patch:typescript@npm%3A5.7.2#optional!builtin::version=5.7.2&hash=5786d5" bin: @@ -15340,6 +15576,28 @@ __metadata: languageName: node linkType: hard +"victory-vendor@npm:^36.6.8": + version: 36.9.2 + resolution: "victory-vendor@npm:36.9.2" + dependencies: + "@types/d3-array": "npm:^3.0.3" + "@types/d3-ease": "npm:^3.0.0" + "@types/d3-interpolate": "npm:^3.0.1" + "@types/d3-scale": "npm:^4.0.2" + "@types/d3-shape": "npm:^3.1.0" + "@types/d3-time": "npm:^3.0.0" + "@types/d3-timer": "npm:^3.0.0" + d3-array: "npm:^3.1.6" + d3-ease: "npm:^3.0.1" + d3-interpolate: "npm:^3.0.1" + d3-scale: "npm:^4.0.2" + d3-shape: "npm:^3.1.0" + d3-time: "npm:^3.0.0" + d3-timer: "npm:^3.0.1" + checksum: 10c0/bad36de3bf4d406834743c2e99a8281d786af324d7e84b7f7a2fc02c27a3779034fb0c3c4707d4c8e68683334d924a67100cfa13985235565e83b9877f8e2ffd + languageName: node + linkType: hard + "viem@npm:^2.21.51": version: 2.21.51 resolution: "viem@npm:2.21.51"