UNPKG

react-garden

Version:

React + TypeScript + ThreeJS app using Material UI on NextJS, Apollo Client, GraphQL + WordPress REST APIs, for ThreeD web development.. a part of the threed.ai code family.

531 lines (499 loc) 22.2 kB
// ** React Imports import { useState, forwardRef } from 'react' // ** MUI Imports import Card from '@mui/material/Card' import Table from '@mui/material/Table' import Button from '@mui/material/Button' import Divider from '@mui/material/Divider' import Tooltip from '@mui/material/Tooltip' import TableRow from '@mui/material/TableRow' import Collapse from '@mui/material/Collapse' import TableBody from '@mui/material/TableBody' import TextField from '@mui/material/TextField' import IconButton from '@mui/material/IconButton' import Typography from '@mui/material/Typography' import InputLabel from '@mui/material/InputLabel' import Box from '@mui/material/Box' import Grid from '@mui/material/Grid' import InputAdornment from '@mui/material/InputAdornment' import TableContainer from '@mui/material/TableContainer' import { styled, alpha, useTheme } from '@mui/material/styles' import Select from '@mui/material/Select' import MenuItem from '@mui/material/MenuItem' import TableCell from '@mui/material/TableCell' import CardContent from '@mui/material/CardContent' // ** Icon Imports import Plus from 'mdi-material-ui/Plus' import Close from 'mdi-material-ui/Close' // ** Third Party Imports import DatePicker from 'react-datepicker' // ** Configs import themeConfig from '~/configs/themeConfig' // ** Custom Component Imports import Repeater from '~/@core/components/repeater' // ** Styles import DatePickerWrapper from '~/@core/styles/libs/react-datepicker' const CustomInput = forwardRef(({ ...props }, ref) => { return <TextField size='small' inputRef={ref} sx={{ width: { sm: '250px', xs: '170px' } }} {...props} /> }) const MUITableCell = styled(TableCell)(({ theme }) => ({ borderBottom: 0, paddingLeft: '0 !important', paddingRight: '0 !important', paddingTop: `${theme.spacing(1)} !important`, paddingBottom: `${theme.spacing(1)} !important` })) const CalcWrapper = styled(Box)(({ theme }) => ({ display: 'flex', alignItems: 'center', justifyContent: 'space-between', '&:not(:last-of-type)': { marginBottom: theme.spacing(2) } })) const RepeatingContent = styled(Grid)(({ theme }) => ({ paddingRight: 0, display: 'flex', position: 'relative', borderRadius: theme.shape.borderRadius, border: `1px solid ${theme.palette.divider}`, '& .col-title': { top: '-1.5rem', position: 'absolute' }, [theme.breakpoints.down('lg')]: { '& .col-title': { top: '0', position: 'relative' } } })) const RepeaterWrapper = styled(CardContent)(({ theme }) => ({ paddingTop: theme.spacing(12), paddingBottom: theme.spacing(12), '& .repeater-wrapper + .repeater-wrapper': { marginTop: theme.spacing(12) } })) const InvoiceAction = styled(Box)(({ theme }) => ({ display: 'flex', flexDirection: 'column', justifyContent: 'flex-start', padding: theme.spacing(2, 1), borderLeft: `1px solid ${theme.palette.divider}` })) const CustomSelectItem = styled(MenuItem)(({ theme }) => ({ backgroundColor: 'transparent !important', '&:hover': { backgroundColor: `${alpha(theme.palette.success.main, 0.1)} !important` } })) const now = new Date() const tomorrowDate = now.setDate(now.getDate() + 7) const EditCard = props => { // ** Props const { clients, invoiceNumber, selectedClient, setSelectedClient, toggleAddCustomerDrawer } = props // ** States const [count, setCount] = useState(1) const [selected, setSelected] = useState('') const [issueDate, setIssueDate] = useState(new Date()) const [dueDate, setDueDate] = useState(new Date(tomorrowDate)) // ** Hook const theme = useTheme() // ** Deletes form const deleteForm = e => { e.preventDefault() // @ts-ignore e.target.closest('.repeater-wrapper').remove() } // ** Handle Invoice To Change const handleInvoiceChange = event => { setSelected(event.target.value) if (clients !== undefined) { setSelectedClient(clients.filter(i => i.name === event.target.value)[0]) } } const handleAddNewCustomer = () => { toggleAddCustomerDrawer() } return ( <Card> <CardContent> <Grid container> <Grid item xl={6} xs={12} sx={{ mb: { xl: 0, xs: 4 } }}> <Box sx={{ display: 'flex', flexDirection: 'column' }}> <Box sx={{ mb: 6, display: 'flex', alignItems: 'center' }}> <svg width={30} height={25} version='1.1' viewBox='0 0 30 23' xmlns='http://www.w3.org/2000/svg' xmlnsXlink='http://www.w3.org/1999/xlink' > <g stroke='none' strokeWidth='1' fill='none' fillRule='evenodd'> <g id='Artboard' transform='translate(-95.000000, -51.000000)'> <g id='logo' transform='translate(95.000000, 50.000000)'> <path id='Combined-Shape' fill={theme.palette.primary.main} d='M30,21.3918362 C30,21.7535219 29.9019196,22.1084381 29.7162004,22.4188007 C29.1490236,23.366632 27.9208668,23.6752135 26.9730355,23.1080366 L26.9730355,23.1080366 L23.714971,21.1584295 C23.1114106,20.7972624 22.7419355,20.1455972 22.7419355,19.4422291 L22.7419355,19.4422291 L22.741,12.7425689 L15,17.1774194 L7.258,12.7425689 L7.25806452,19.4422291 C7.25806452,20.1455972 6.88858935,20.7972624 6.28502902,21.1584295 L3.0269645,23.1080366 C2.07913318,23.6752135 0.850976404,23.366632 0.283799571,22.4188007 C0.0980803893,22.1084381 2.0190442e-15,21.7535219 0,21.3918362 L0,3.58469444 L0.00548573643,3.43543209 L0.00548573643,3.43543209 L0,3.5715689 C3.0881846e-16,2.4669994 0.8954305,1.5715689 2,1.5715689 C2.36889529,1.5715689 2.73060353,1.67359571 3.04512412,1.86636639 L15,9.19354839 L26.9548759,1.86636639 C27.2693965,1.67359571 27.6311047,1.5715689 28,1.5715689 C29.1045695,1.5715689 30,2.4669994 30,3.5715689 L30,3.5715689 Z' /> <polygon id='Rectangle' opacity='0.077704' fill={theme.palette.common.black} points='0 8.58870968 7.25806452 12.7505183 7.25806452 16.8305646' /> <polygon id='Rectangle' opacity='0.077704' fill={theme.palette.common.black} points='0 8.58870968 7.25806452 12.6445567 7.25806452 15.1370162' /> <polygon id='Rectangle' opacity='0.077704' fill={theme.palette.common.black} points='22.7419355 8.58870968 30 12.7417372 30 16.9537453' transform='translate(26.370968, 12.771227) scale(-1, 1) translate(-26.370968, -12.771227) ' /> <polygon id='Rectangle' opacity='0.077704' fill={theme.palette.common.black} points='22.7419355 8.58870968 30 12.6409734 30 15.2601969' transform='translate(26.370968, 11.924453) scale(-1, 1) translate(-26.370968, -11.924453) ' /> <path id='Rectangle' fillOpacity='0.15' fill={theme.palette.common.white} d='M3.04512412,1.86636639 L15,9.19354839 L15,9.19354839 L15,17.1774194 L0,8.58649679 L0,3.5715689 C3.0881846e-16,2.4669994 0.8954305,1.5715689 2,1.5715689 C2.36889529,1.5715689 2.73060353,1.67359571 3.04512412,1.86636639 Z' /> <path id='Rectangle' fillOpacity='0.35' fill={theme.palette.common.white} transform='translate(22.500000, 8.588710) scale(-1, 1) translate(-22.500000, -8.588710) ' d='M18.0451241,1.86636639 L30,9.19354839 L30,9.19354839 L30,17.1774194 L15,8.58649679 L15,3.5715689 C15,2.4669994 15.8954305,1.5715689 17,1.5715689 C17.3688953,1.5715689 17.7306035,1.67359571 18.0451241,1.86636639 Z' /> </g> </g> </g> </svg> <Typography variant='h6' sx={{ ml: 2.5, fontWeight: 600, lineHeight: 'normal', textTransform: 'uppercase' }} > {themeConfig.templateName} </Typography> </Box> <Box> <Typography variant='body2' sx={{ mb: 1 }}> Office 149, 450 South Brand Brooklyn </Typography> <Typography variant='body2' sx={{ mb: 1 }}> San Diego County, CA 91905, USA </Typography> <Typography variant='body2'>+1 (123) 456 7891, +44 (876) 543 2198</Typography> </Box> </Box> </Grid> <Grid item xl={6} xs={12}> <DatePickerWrapper sx={{ '& .react-datepicker-wrapper': { width: 'auto' } }}> <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: { xl: 'flex-end', xs: 'flex-start' } }}> <Box sx={{ mb: 4, display: 'flex', alignItems: 'center' }}> <Typography variant='h6' sx={{ mr: 2, width: '105px' }}> Invoice </Typography> <TextField size='small' value={invoiceNumber} sx={{ width: { sm: '250px', xs: '170px' } }} InputProps={{ disabled: true, startAdornment: <InputAdornment position='start'>#</InputAdornment> }} /> </Box> <Box sx={{ mb: 4, display: 'flex', alignItems: 'center' }}> <Typography variant='body2' sx={{ mr: 3, width: '100px' }}> Date Issued: </Typography> <DatePicker id='issue-date' selected={issueDate} customInput={<CustomInput />} onChange={date => setIssueDate(date)} /> </Box> <Box sx={{ display: 'flex' }}> <Typography variant='body2' sx={{ mr: 3, width: '100px' }}> Date Due: </Typography> <DatePicker id='due-date' selected={dueDate} customInput={<CustomInput />} onChange={date => setDueDate(date)} /> </Box> </Box> </DatePickerWrapper> </Grid> </Grid> </CardContent> <Divider /> <CardContent> <Grid container> <Grid item xs={12} sm={6} sx={{ mb: { lg: 0, xs: 4 } }}> <Typography variant='body2' sx={{ mb: 3.5, color: 'text.primary', fontWeight: 600 }}> Invoice To: </Typography> <Select size='small' value={selected} onChange={handleInvoiceChange} sx={{ mb: 4, width: '200px' }}> <CustomSelectItem value=''> <Button fullWidth size='small' color='success' onClick={handleAddNewCustomer} startIcon={<Plus fontSize='small' />} sx={{ '&:hover': { backgroundColor: 'transparent' } }} > Add New Customer </Button> </CustomSelectItem> {clients !== undefined && clients.map(client => ( <MenuItem key={client.name} value={client.name}> {client.name} </MenuItem> ))} </Select> {selectedClient !== null && selectedClient !== undefined ? ( <Box> <Typography variant='body2' sx={{ mb: 1 }}> {selectedClient.company} </Typography> <Typography variant='body2' sx={{ mb: 1 }}> {selectedClient.address} </Typography> <Typography variant='body2' sx={{ mb: 1 }}> {selectedClient.contact} </Typography> <Typography variant='body2' sx={{ mb: 1 }}> {selectedClient.companyEmail} </Typography> </Box> ) : null} </Grid> <Grid item xs={12} sm={6} sx={{ display: 'flex', justifyContent: ['flex-start', 'flex-end'] }}> <div> <Typography variant='body2' sx={{ mb: 3.5, color: 'text.primary', fontWeight: 600 }}> Bill To: </Typography> <TableContainer> <Table> <TableBody> <TableRow> <MUITableCell>Total Due:</MUITableCell> <MUITableCell>$12,110.55</MUITableCell> </TableRow> <TableRow> <MUITableCell>Bank name:</MUITableCell> <MUITableCell>American Bank</MUITableCell> </TableRow> <TableRow> <MUITableCell>Country:</MUITableCell> <MUITableCell>United States</MUITableCell> </TableRow> <TableRow> <MUITableCell>IBAN:</MUITableCell> <MUITableCell>ETD95476213874685</MUITableCell> </TableRow> <TableRow> <MUITableCell>SWIFT code:</MUITableCell> <MUITableCell>BR91905</MUITableCell> </TableRow> </TableBody> </Table> </TableContainer> </div> </Grid> </Grid> </CardContent> <Divider /> <RepeaterWrapper> <Repeater count={count}> {i => { const Tag = i === 0 ? Box : Collapse return ( <Tag key={i} className='repeater-wrapper' {...(i !== 0 ? { in: true } : {})}> <Grid container> <RepeatingContent item xs={12}> <Grid container sx={{ py: 4, width: '100%', pr: { lg: 0, xs: 4 } }}> <Grid item lg={6} md={5} xs={12} sx={{ px: 4, my: { lg: 0, xs: 4 } }}> <Typography variant='body2' className='col-title' sx={{ fontWeight: '600', mb: { md: 2, xs: 0 } }} > Item </Typography> <Select fullWidth size='small' defaultValue='App Design'> <MenuItem value='App Design'>App Design</MenuItem> <MenuItem value='App Customization'>App Customization</MenuItem> <MenuItem value='ABC Template'>ABC Template</MenuItem> <MenuItem value='App Development'>App Development</MenuItem> </Select> <TextField rows={2} fullWidth multiline size='small' sx={{ mt: 3.5 }} defaultValue='Customization & Bug Fixes' /> </Grid> <Grid item lg={2} md={3} xs={12} sx={{ px: 4, my: { lg: 0, xs: 4 } }}> <Typography variant='body2' className='col-title' sx={{ fontWeight: '600', mb: { md: 2, xs: 0 } }} > Cost </Typography> <TextField size='small' type='number' placeholder='24' defaultValue='24' InputProps={{ inputProps: { min: 0 } }} /> <Box sx={{ mt: 3.5 }}> <Typography component='span' variant='body2'> Discount: </Typography>{' '} <Typography component='span' variant='body2'> 0% </Typography> <Tooltip title='Tax 1' placement='top'> <Typography component='span' variant='body2' sx={{ mx: 2 }}> 0% </Typography> </Tooltip> <Tooltip title='Tax 2' placement='top'> <Typography component='span' variant='body2'> 0% </Typography> </Tooltip> </Box> </Grid> <Grid item lg={2} md={2} xs={12} sx={{ px: 4, my: { lg: 0, xs: 4 } }}> <Typography variant='body2' className='col-title' sx={{ fontWeight: '600', mb: { md: 2, xs: 0 } }} > Hours </Typography> <TextField size='small' type='number' placeholder='1' defaultValue='1' InputProps={{ inputProps: { min: 0 } }} /> </Grid> <Grid item lg={2} md={1} xs={12} sx={{ px: 4, my: { lg: 0 }, mt: 2 }}> <Typography variant='body2' className='col-title' sx={{ fontWeight: '600', mb: { md: 2, xs: 0 } }} > Price </Typography> <Typography>$24.00</Typography> </Grid> </Grid> <InvoiceAction> <IconButton size='small' onClick={deleteForm}> <Close fontSize='small' /> </IconButton> </InvoiceAction> </RepeatingContent> </Grid> </Tag> ) }} </Repeater> <Grid container sx={{ mt: 4 }}> <Grid item xs={12} sx={{ px: 0 }}> <Button size='small' variant='contained' startIcon={<Plus fontSize='small' />} onClick={() => setCount(count + 1)} > Add Item </Button> </Grid> </Grid> </RepeaterWrapper> <Divider /> <CardContent> <Grid container> <Grid item xs={12} sm={9} sx={{ order: { sm: 1, xs: 2 } }}> <Box sx={{ mb: 4, display: 'flex', alignItems: 'center' }}> <Typography variant='body2' sx={{ mr: 2, fontWeight: 600 }}> Salesperson: </Typography> <TextField size='small' sx={{ maxWidth: '150px' }} defaultValue='Tommy Shelby' /> </Box> <TextField size='small' sx={{ maxWidth: '300px' }} placeholder='Thanks for your business' /> </Grid> <Grid item xs={12} sm={3} sx={{ mb: { sm: 0, xs: 4 }, order: { sm: 2, xs: 1 } }}> <CalcWrapper> <Typography variant='body2'>Subtotal:</Typography> <Typography variant='body2' sx={{ fontWeight: 600 }}> $1800 </Typography> </CalcWrapper> <CalcWrapper> <Typography variant='body2'>Discount:</Typography> <Typography variant='body2' sx={{ fontWeight: 600 }}> $28 </Typography> </CalcWrapper> <CalcWrapper> <Typography variant='body2'>Tax:</Typography> <Typography variant='body2' sx={{ fontWeight: 600 }}> 21% </Typography> </CalcWrapper> <Divider /> <CalcWrapper> <Typography variant='body2'>Total:</Typography> <Typography variant='body2' sx={{ fontWeight: 600 }}> $1690 </Typography> </CalcWrapper> </Grid> </Grid> </CardContent> <Divider /> <CardContent> <InputLabel htmlFor='invoice-note' sx={{ mb: 2 }}> Note: </InputLabel> <TextField rows={2} fullWidth multiline id='invoice-note' defaultValue='It was a pleasure working with you and your team. We hope you will keep us in mind for future freelance projects. Thank You!' /> </CardContent> </Card> ) } export default EditCard