diff --git a/frontend/src/assets/img/easyToDeploy.png b/frontend/src/assets/img/easyToDeploy.png new file mode 100644 index 0000000000..0030201f99 Binary files /dev/null and b/frontend/src/assets/img/easyToDeploy.png differ diff --git a/frontend/src/component/admin/Admin.tsx b/frontend/src/component/admin/Admin.tsx index ccca09ded3..549e929246 100644 --- a/frontend/src/component/admin/Admin.tsx +++ b/frontend/src/component/admin/Admin.tsx @@ -19,12 +19,20 @@ import NotFound from 'component/common/NotFound/NotFound'; import { AdminIndex } from './AdminIndex'; import { Banners } from './banners/Banners'; import { License } from './license/License'; +import { useUiFlag } from 'hooks/useUiFlag'; +import { AdminHome } from './AdminHome'; export const Admin = () => { + const newAdminUIEnabled = useUiFlag('adminNavUI'); + return ( <> - } /> + {newAdminUIEnabled ? ( + } /> + ) : ( + } /> + )} } /> } /> } /> diff --git a/frontend/src/component/admin/AdminHome.tsx b/frontend/src/component/admin/AdminHome.tsx new file mode 100644 index 0000000000..d198499188 --- /dev/null +++ b/frontend/src/component/admin/AdminHome.tsx @@ -0,0 +1,251 @@ +import { Box, Button, Grid, Paper, styled, Typography } from '@mui/material'; +import { useInstanceStats } from 'hooks/api/getters/useInstanceStats/useInstanceStats'; +import { useInstanceStatus } from 'hooks/api/getters/useInstanceStatus/useInstanceStatus'; +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; +import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward'; +import { formatAssetPath } from 'utils/formatPath'; +import easyToDeploy from 'assets/img/easyToDeploy.png'; + +const StyledContainer = styled(Grid)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(2), +})); + +const StyledInstanceWidget = styled(Paper)(({ theme }) => ({ + height: theme.spacing(44), + padding: theme.spacing(3), + borderRadius: `${theme.shape.borderRadiusLarge}px`, + boxShadow: 'none', + color: 'white', + backgroundColor: theme.palette.web.main, + overflow: 'hidden', +})); + +const StyledWidget = styled(Paper)(({ theme }) => ({ + minHeight: theme.spacing(44), + padding: theme.spacing(3), + borderRadius: `${theme.shape.borderRadiusLarge}px`, + boxShadow: 'none', + [theme.breakpoints.up('md')]: { + flexDirection: 'row', + flexWrap: 'nowrap', + }, +})); + +const StyledHeader = styled(Typography)(({ theme }) => ({ + width: '100%', + fontSize: theme.fontSizes.largeHeader, + fontWeight: 'bold', + marginBottom: theme.spacing(1), +})); + +const StyledLicenseSection = styled('div')(({ theme }) => ({ + marginBottom: theme.spacing(6), +})); + +const StyledParagraph = styled(Typography)(({ theme }) => ({ + fontSize: theme.fontSizes.bodySize, + marginTop: theme.spacing(2), + marginBottom: theme.spacing(2), + flexDirection: 'row', + display: 'flex', + gap: theme.spacing(1), + justifyContent: 'space-between', +})); + +const StyledParamName = styled('div')(({ theme }) => ({ + fontSize: theme.fontSizes.bodySize, + fontWeight: 'bold', +})); + +const StyledParamValue = styled('div')(({ theme }) => ({ + color: 'white', +})); + +const InstanceStatsHeader = styled(Typography)(({ theme }) => ({ + fontSize: theme.fontSizes.mainHeader, + marginTop: theme.spacing(2), + marginBottom: theme.spacing(4), +})); + +const StyledGridContainer = styled(Grid)(({ theme }) => ({ + display: 'flex', + flexDirection: 'row', + gap: theme.spacing(2), + justifyContent: 'space-between', + marginBottom: theme.spacing(7), +})); + +const StyledGridItem = styled(Grid)(({ theme }) => ({ + width: theme.spacing(16), + aspectRatio: '1 / 1', + padding: theme.spacing(2), + alignItems: 'center', + borderRadius: `50%`, + backgroundColor: theme.mode === 'light' ? '#F1F0FC' : '#302E42', +})); + +const StyledGridItemContent = styled(Box)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', +})); + +export const StatNumber = styled(Typography)(({ theme }) => ({ + color: theme.palette.primary.main, + fontSize: theme.fontSizes.largeHeader, + fontWeight: 'bold', + marginTop: theme.spacing(1), +})); + +export const StatText = styled(Typography)(({ theme }) => ({ + color: theme.palette.text.primary, + fontSize: theme.fontSizes.bodySize, +})); + +const StyledLinkContainer = styled('div')(({ theme }) => ({ + display: 'flex', + justifyContent: 'flex-start', + marginTop: theme.spacing(3), +})); + +const ImageContainer = styled('div')(({ theme }) => ({ + display: 'flex', + justifyContent: 'flex-end', + marginTop: theme.spacing(-6), + marginRight: theme.spacing(-10), +})); + +const StyledImg = styled('img')(({ theme }) => ({ + width: theme.spacing(33), + transform: 'rotate(180deg)', + clipPath: 'polygon(21% 28%, 100% 28%, 21% 94%)', +})); + +interface IInstanceWidgetProps { + plan: string; + instanceId: string; + version: string; +} + +const InstanceWidget = ({ + plan, + instanceId, + version, +}: IInstanceWidgetProps) => { + return ( + + +
Current plan
+ {plan} +
+ + Instance id + {instanceId} + + + Unleash version + {version} + + + + +
+ ); +}; + +interface IInstanceStatsWidgetProps { + users: number; + featureToggles: number; + projects: number; + environments: number; +} + +const InstanceStatsWidget = ({ + users, + featureToggles, + projects, + environments, +}: IInstanceStatsWidgetProps) => { + return ( + + Instance statistics + + + + {users} + Users + + + + + {featureToggles} + Feature flags + + + + + {projects} + Projects + + + + + {environments} + Environments + + + + + + + + ); +}; + +export const AdminHome = () => { + const stats = useInstanceStats(); + const { isOss, isPro, isEnterprise } = useUiConfig(); + const plan = isOss() + ? 'Open source' + : isPro() + ? 'Pro' + : isEnterprise() + ? 'Enterprise' + : 'Unknown'; + const { instanceStatus } = useInstanceStatus(); + return ( + + {stats && !stats.loading && ( + + + + + + + + + )} + + ); +};