Files
react-test/docs/data/material/getting-started/templates/checkout/Checkout.tsx
how2ice 005cf56baf
Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
init project
2025-12-12 14:26:25 +09:00

268 lines
8.8 KiB
TypeScript

import * as React from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Card from '@mui/material/Card';
import CardContent from '@mui/material/CardContent';
import CssBaseline from '@mui/material/CssBaseline';
import Grid from '@mui/material/Grid';
import Stack from '@mui/material/Stack';
import Step from '@mui/material/Step';
import StepLabel from '@mui/material/StepLabel';
import Stepper from '@mui/material/Stepper';
import Typography from '@mui/material/Typography';
import ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded';
import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded';
import AddressForm from './components/AddressForm';
import Info from './components/Info';
import InfoMobile from './components/InfoMobile';
import PaymentForm from './components/PaymentForm';
import Review from './components/Review';
import SitemarkIcon from './components/SitemarkIcon';
import AppTheme from '../shared-theme/AppTheme';
import ColorModeIconDropdown from '../shared-theme/ColorModeIconDropdown';
const steps = ['Shipping address', 'Payment details', 'Review your order'];
function getStepContent(step: number) {
switch (step) {
case 0:
return <AddressForm />;
case 1:
return <PaymentForm />;
case 2:
return <Review />;
default:
throw new Error('Unknown step');
}
}
export default function Checkout(props: { disableCustomTheme?: boolean }) {
const [activeStep, setActiveStep] = React.useState(0);
const handleNext = () => {
setActiveStep(activeStep + 1);
};
const handleBack = () => {
setActiveStep(activeStep - 1);
};
return (
<AppTheme {...props}>
<CssBaseline enableColorScheme />
<Box sx={{ position: 'fixed', top: '1rem', right: '1rem' }}>
<ColorModeIconDropdown />
</Box>
<Grid
container
sx={{
height: {
xs: '100%',
sm: 'calc(100dvh - var(--template-frame-height, 0px))',
},
mt: {
xs: 4,
sm: 0,
},
}}
>
<Grid
size={{ xs: 12, sm: 5, lg: 4 }}
sx={{
display: { xs: 'none', md: 'flex' },
flexDirection: 'column',
backgroundColor: 'background.paper',
borderRight: { sm: 'none', md: '1px solid' },
borderColor: { sm: 'none', md: 'divider' },
alignItems: 'start',
pt: 16,
px: 10,
gap: 4,
}}
>
<SitemarkIcon />
<Box
sx={{
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
width: '100%',
maxWidth: 500,
}}
>
<Info totalPrice={activeStep >= 2 ? '$144.97' : '$134.98'} />
</Box>
</Grid>
<Grid
size={{ sm: 12, md: 7, lg: 8 }}
sx={{
display: 'flex',
flexDirection: 'column',
maxWidth: '100%',
width: '100%',
backgroundColor: { xs: 'transparent', sm: 'background.default' },
alignItems: 'start',
pt: { xs: 0, sm: 16 },
px: { xs: 2, sm: 10 },
gap: { xs: 4, md: 8 },
}}
>
<Box
sx={{
display: 'flex',
justifyContent: { sm: 'space-between', md: 'flex-end' },
alignItems: 'center',
width: '100%',
maxWidth: { sm: '100%', md: 600 },
}}
>
<Box
sx={{
display: { xs: 'none', md: 'flex' },
flexDirection: 'column',
justifyContent: 'space-between',
alignItems: 'flex-end',
flexGrow: 1,
}}
>
<Stepper
id="desktop-stepper"
activeStep={activeStep}
sx={{ width: '100%', height: 40 }}
>
{steps.map((label) => (
<Step
sx={{ ':first-child': { pl: 0 }, ':last-child': { pr: 0 } }}
key={label}
>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
</Box>
</Box>
<Card sx={{ display: { xs: 'flex', md: 'none' }, width: '100%' }}>
<CardContent
sx={{
display: 'flex',
width: '100%',
alignItems: 'center',
justifyContent: 'space-between',
}}
>
<div>
<Typography variant="subtitle2" gutterBottom>
Selected products
</Typography>
<Typography variant="body1">
{activeStep >= 2 ? '$144.97' : '$134.98'}
</Typography>
</div>
<InfoMobile totalPrice={activeStep >= 2 ? '$144.97' : '$134.98'} />
</CardContent>
</Card>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
width: '100%',
maxWidth: { sm: '100%', md: 600 },
maxHeight: '720px',
gap: { xs: 5, md: 'none' },
}}
>
<Stepper
id="mobile-stepper"
activeStep={activeStep}
alternativeLabel
sx={{ display: { sm: 'flex', md: 'none' } }}
>
{steps.map((label) => (
<Step
sx={{
':first-child': { pl: 0 },
':last-child': { pr: 0 },
'& .MuiStepConnector-root': { top: { xs: 6, sm: 12 } },
}}
key={label}
>
<StepLabel
sx={{ '.MuiStepLabel-labelContainer': { maxWidth: '70px' } }}
>
{label}
</StepLabel>
</Step>
))}
</Stepper>
{activeStep === steps.length ? (
<Stack spacing={2} useFlexGap>
<Typography variant="h1">📦</Typography>
<Typography variant="h5">Thank you for your order!</Typography>
<Typography variant="body1" sx={{ color: 'text.secondary' }}>
Your order number is
<strong>&nbsp;#140396</strong>. We have emailed your order
confirmation and will update you once its shipped.
</Typography>
<Button
variant="contained"
sx={{ alignSelf: 'start', width: { xs: '100%', sm: 'auto' } }}
>
Go to my orders
</Button>
</Stack>
) : (
<React.Fragment>
{getStepContent(activeStep)}
<Box
sx={[
{
display: 'flex',
flexDirection: { xs: 'column-reverse', sm: 'row' },
alignItems: 'end',
flexGrow: 1,
gap: 1,
pb: { xs: 12, sm: 0 },
mt: { xs: 2, sm: 0 },
mb: '60px',
},
activeStep !== 0
? { justifyContent: 'space-between' }
: { justifyContent: 'flex-end' },
]}
>
{activeStep !== 0 && (
<Button
startIcon={<ChevronLeftRoundedIcon />}
onClick={handleBack}
variant="text"
sx={{ display: { xs: 'none', sm: 'flex' } }}
>
Previous
</Button>
)}
{activeStep !== 0 && (
<Button
startIcon={<ChevronLeftRoundedIcon />}
onClick={handleBack}
variant="outlined"
fullWidth
sx={{ display: { xs: 'flex', sm: 'none' } }}
>
Previous
</Button>
)}
<Button
variant="contained"
endIcon={<ChevronRightRoundedIcon />}
onClick={handleNext}
sx={{ width: { xs: '100%', sm: 'fit-content' } }}
>
{activeStep === steps.length - 1 ? 'Place order' : 'Next'}
</Button>
</Box>
</React.Fragment>
)}
</Box>
</Grid>
</Grid>
</AppTheme>
);
}