Files
Doormilexpress_console/src/pages/nearle/clients/createclient.js

214 lines
7.5 KiB
JavaScript

import { useState } from 'react';
// material-ui
import {
Avatar,
Button,
FormControlLabel,
Grid,
InputLabel,
MenuItem,
Paper,
Select,
Stack,
Switch,
TextField,
Typography,
useMediaQuery,
useTheme
} from '@mui/material';
import { MdPersonAddAlt1 } from 'react-icons/md';
import { useMutation } from '@tanstack/react-query';
// project import
import MainCard from 'components/MainCard';
import { createAdminTenant } from 'pages/api/doormileApi';
import Loader from 'components/Loader';
import { enqueueSnackbar } from 'notistack';
import { useNavigate } from 'react-router';
import { DT, tint } from 'themes/dt/tokens';
const Createclient = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const navigate = useNavigate();
const [tenantname, setTenantname] = useState('');
const [primaryemail, setPrimaryemail] = useState('');
const [primarycontact, setPrimarycontact] = useState('');
// Confirmed live: POST /admin/tenants doesn't reject lowercase status, but
// stores it exactly as sent — every real tenant uses "Active" (title
// case), so a lowercase one would be inconsistent with the rest of the
// data even though the request itself succeeds.
const [status, setStatus] = useState('Active');
const [requiredeliveryotp, setRequiredeliveryotp] = useState(false);
const opentoast = (message) => {
enqueueSnackbar(message, {
variant: 'error',
anchorOrigin: { vertical: 'top', horizontal: 'right' },
autoHideDuration: 2000
});
};
const createTenantMutation = useMutation({
mutationFn: (payload) => createAdminTenant(payload),
onSuccess: (res) => {
if (res.success) {
enqueueSnackbar('Client created successfully', {
variant: 'success',
anchorOrigin: { vertical: 'top', horizontal: 'right' },
autoHideDuration: 2000
});
navigate('/doormile/tenants');
} else {
opentoast(res.message || 'Client already exists');
}
},
onError: (err) => {
opentoast(err.response?.data?.message || err.message || 'Failed to create client');
}
});
const createprofile = () => {
if (!tenantname) {
opentoast('Fill Client / Business Name');
} else if (!primarycontact || primarycontact.length !== 10) {
opentoast('Fill a valid 10-digit Contact Number');
} else if (!primaryemail) {
opentoast('Fill Primary Email');
} else {
// POST /admin/tenants — requiredeliveryotp is a pointer server-side;
// it's opt-in and off by default, so we only send it when the operator
// explicitly turns it on rather than always sending false.
const obj = {
tenantname,
primaryemail,
primarycontact,
status,
...(requiredeliveryotp ? { requiredeliveryotp: true } : {})
};
createTenantMutation.mutate(obj);
}
};
return (
<>
{createTenantMutation.isPending && <Loader />}
<Grid item xs={12} sx={{ mb: 2 }}>
<Paper
sx={{
p: 2.5,
borderRadius: DT.radiusCard + 'px',
boxShadow: DT.shadowSoft,
border: '1px solid',
borderColor: DT.borderSubtle,
background: `linear-gradient(135deg, ${tint('#C01227')} 0%, ${tint('#D25463')} 100%)`
}}
>
<Stack direction="row" spacing={1.5} alignItems="center">
<Avatar sx={{ width: 48, height: 48, bgcolor: DT.brand }}>
<MdPersonAddAlt1 size={22} />
</Avatar>
<Typography variant="h3">Create Client</Typography>
</Stack>
</Paper>
</Grid>
<MainCard
contentSX={{ p: { xs: 1.5, md: 3 } }}
sx={{ borderRadius: DT.radiusCard + 'px', boxShadow: DT.shadowSoft, borderColor: DT.borderSubtle }}
>
<Grid container spacing={isMobile ? 2 : 3}>
<Grid item xs={12}>
<MainCard sx={{ height: '100%' }} contentSX={{ p: { xs: 1.5, md: 2.5 } }}>
<Grid container spacing={isMobile ? 2 : 3}>
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="tenant-name">Client / Business Name</InputLabel>
<TextField
fullWidth
id="tenant-name"
placeholder="e.g. DailyGrubs"
onChange={(e) => setTenantname(e.target.value)}
value={tenantname}
autoComplete="off"
/>
</Stack>
</Grid>
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="tenant-status">Status</InputLabel>
<Select id="tenant-status" fullWidth value={status} onChange={(e) => setStatus(e.target.value)}>
<MenuItem value="Active">Active</MenuItem>
<MenuItem value="Inactive">Inactive</MenuItem>
</Select>
</Stack>
</Grid>
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="tenant-contact">Primary Contact Number</InputLabel>
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
<Select defaultValue="+1" disabled sx={{ cursor: 'not-allowed' }}>
<MenuItem value="+1">+91</MenuItem>
</Select>
<TextField
type="number"
id="tenant-contact"
fullWidth
placeholder="Contact Number"
onChange={(e) => {
if (e.target.value.toString().length <= 10) {
setPrimarycontact(e.target.value);
}
}}
value={primarycontact}
autoComplete="off"
/>
</Stack>
</Stack>
</Grid>
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="tenant-email">Primary Email</InputLabel>
<TextField
type="email"
fullWidth
id="tenant-email"
placeholder="Primary Email Address"
onChange={(e) => setPrimaryemail(e.target.value)}
value={primaryemail}
autoComplete="off"
/>
</Stack>
</Grid>
<Grid item xs={12}>
<FormControlLabel
control={<Switch checked={requiredeliveryotp} onChange={(e) => setRequiredeliveryotp(e.target.checked)} />}
label="Require delivery OTP for this client (off by default)"
/>
</Grid>
</Grid>
</MainCard>
</Grid>
<Grid item xs={12}>
<Stack
direction={{ xs: 'column', sm: 'row' }}
justifyContent="flex-end"
alignItems={{ xs: 'stretch', sm: 'center' }}
spacing={2}
>
<Button variant="contained" onClick={createprofile} fullWidth={isMobile}>
Create
</Button>
</Stack>
</Grid>
</Grid>
</MainCard>
</>
);
};
export default Createclient;