1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-07 01:16:28 +02:00
unleash.unleash/frontend/src/component/environments/EnvironmentTable/OrderEnvironments/OrderEnvironmentsDialog/OrderEnvironmentsDialog.tsx
2024-10-11 13:23:54 +03:00

205 lines
7.4 KiB
TypeScript

import { useState, type FC } from 'react';
import {
Box,
Button,
Checkbox,
Dialog,
styled,
Typography,
} from '@mui/material';
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
import { OrderEnvironmentsDialogPricing } from './OrderEnvironmentsDialogPricing/OrderEnvironmentsDialogPricing';
import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect';
import Input from 'component/common/Input/Input';
import type { IFormErrors } from 'hooks/useFormErrors';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
type OrderEnvironmentsDialogProps = {
open: boolean;
onClose: () => void;
onSubmit: (environments: string[]) => void;
errors?: IFormErrors;
};
const StyledDialog = styled(Dialog)(({ theme }) => ({
maxWidth: '940px',
margin: 'auto',
'& .MuiDialog-paper': {
borderRadius: theme.shape.borderRadiusExtraLarge,
maxWidth: theme.spacing(170),
width: '100%',
backgroundColor: 'transparent',
},
padding: 0,
'& .MuiPaper-root > section': {
overflowX: 'hidden',
},
}));
const StyledTitle = styled('div')(({ theme }) => ({
marginBottom: theme.spacing(3),
}));
const StyledFooter = styled('div')(({ theme }) => ({
display: 'flex',
justifyContent: 'flex-end',
gap: theme.spacing(2),
}));
const StyledGeneralSelect = styled(GeneralSelect)(({ theme }) => ({
margin: theme.spacing(1, 0),
}));
const StyledFields = styled(Box)(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(2),
paddingTop: theme.spacing(3),
}));
const StyledEnvironmentNameInputs = styled('fieldset')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
border: 'none',
padding: 0,
margin: 0,
gap: theme.spacing(1.5),
}));
const StyledCheckbox = styled(Checkbox)(({ theme }) => ({
marginBottom: theme.spacing(0.4),
}));
const PRICE = 10;
const OPTIONS = [1, 2, 3];
export const OrderEnvironmentsDialog: FC<OrderEnvironmentsDialogProps> = ({
open,
onClose,
onSubmit,
errors,
}) => {
const { trackEvent } = usePlausibleTracker();
const [selectedOption, setSelectedOption] = useState(OPTIONS[0]);
const [costCheckboxChecked, setCostCheckboxChecked] = useState(false);
const [environmentNames, setEnvironmentNames] = useState<string[]>(['']);
const trackEnvironmentSelect = () => {
trackEvent('order-environments', {
props: {
eventType: 'selected environment count',
},
});
};
return (
<StyledDialog open={open} title=''>
<FormTemplate
compact
description={
<OrderEnvironmentsDialogPricing
pricingOptions={OPTIONS.map((option) => ({
environments: option,
price: option * PRICE,
}))}
/>
}
footer={
<StyledFooter>
<Button onClick={onClose}>Cancel</Button>
<Button
variant='contained'
disabled={!costCheckboxChecked}
onClick={() => onSubmit(environmentNames)}
>
Order
</Button>
</StyledFooter>
}
>
<StyledTitle>
<Typography variant='h3' component='div'>
Order additional environments
</Typography>
</StyledTitle>
<Typography variant='body2' color='text.secondary'>
With our PRO plan, you have the flexibility to expand your
workspace by adding environments at ${PRICE} per user per
month.
</Typography>
<StyledFields>
<Box>
<Typography
component='label'
htmlFor='numberOfEnvironments'
>
Select the number of additional environments
</Typography>
<StyledGeneralSelect
id='numberOfEnvironments'
value={`${selectedOption}`}
options={OPTIONS.map((option) => ({
key: `${option}`,
label: `${option} environment${option > 1 ? 's' : ''}`,
}))}
onChange={(option) => {
const value = Number.parseInt(option, 10);
setSelectedOption(value);
setEnvironmentNames((names) =>
[...names, ...Array(value).fill('')].slice(
0,
value,
),
);
trackEnvironmentSelect();
}}
/>
</Box>
<StyledEnvironmentNameInputs>
<Typography>
How would you like the environment
{selectedOption > 1 ? 's' : ''} to be named?
</Typography>
{[...Array(selectedOption)].map((_, i) => {
const error = errors?.getFormError(
`environment-${i}`,
);
return (
<Input
key={i}
label={`Environment ${i + 1} name`}
value={environmentNames[i]}
onChange={(event) => {
setEnvironmentNames((names) => {
const newValues = [...names];
newValues[i] = event.target.value;
return newValues;
});
}}
error={Boolean(error)}
errorText={error}
/>
);
})}
</StyledEnvironmentNameInputs>
<Box>
<StyledCheckbox
edge='start'
id='costsCheckbox'
checked={costCheckboxChecked}
onChange={() =>
setCostCheckboxChecked((state) => !state)
}
/>
<Typography component='label' htmlFor='costsCheckbox'>
I understand adding environments leads to extra
costs
</Typography>
</Box>
</StyledFields>
</FormTemplate>
</StyledDialog>
);
};