Files
jobtrackingapp/vendor/saasable-ui-main/admin/vite/src/components/Contact.jsx
T
2026-03-21 11:55:27 +01:00

187 lines
6.5 KiB
React

import PropTypes from 'prop-types';
import { useEffect, useState } from 'react';
// @mui
import { useTheme } from '@mui/material/styles';
import Button from '@mui/material/Button';
import Card from '@mui/material/Card';
import CardMedia from '@mui/material/CardMedia';
import ClickAwayListener from '@mui/material/ClickAwayListener';
import Divider from '@mui/material/Divider';
import Fade from '@mui/material/Fade';
import InputAdornment from '@mui/material/InputAdornment';
import List from '@mui/material/List';
import ListItemAvatar from '@mui/material/ListItemAvatar';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemText from '@mui/material/ListItemText';
import OutlinedInput from '@mui/material/OutlinedInput';
import Popper from '@mui/material/Popper';
import Stack from '@mui/material/Stack';
import Tooltip from '@mui/material/Tooltip';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
// @third-party
import { Controller } from 'react-hook-form';
// @project
import { contactSchema } from '@/utils/validation-schema/common';
// @icons
import { IconChevronDown, IconHelp } from '@tabler/icons-react';
// @types
// @data
import countries from '@/data/countries';
/*************************** CONTACT ***************************/
export default function Contact({
dialCode,
placeholder = 'ex. 9876x xxxxx',
helpText,
isDisabled = false,
isCountryDisabled = false,
fullWidth = false,
control,
isError = false,
onCountryChange
}) {
const theme = useTheme();
const [anchorEl, setAnchorEl] = useState(null);
const [selectedCountry, setSelectedCountry] = useState(countries[0]);
const open = Boolean(anchorEl);
const id = open ? 'dialcode-popper' : undefined;
const handleClick = (event) => {
setAnchorEl(anchorEl ? null : event.currentTarget);
};
useEffect(() => {
const data = countries.find((item) => item.dialCode === (dialCode || '+1')) || countries[0];
setSelectedCountry(data);
if (!dialCode && onCountryChange) onCountryChange(data);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dialCode]);
const countryChange = (country) => {
if (onCountryChange) {
onCountryChange(country);
}
setAnchorEl(null);
};
return (
<Controller
control={control}
name={'contact'}
rules={contactSchema}
render={({ field: { value, onChange } }) => (
<OutlinedInput
placeholder={placeholder}
value={value || ''}
onChange={onChange}
error={isError}
{...(helpText && {
endAdornment: (
<InputAdornment position="end" sx={{ '& svg': { cursor: 'default' } }}>
<Tooltip title={helpText}>
<IconHelp />
</Tooltip>
</InputAdornment>
)
})}
disabled={isDisabled}
aria-describedby="contact-field"
slotProps={{ input: { 'aria-label': 'contact' } }}
fullWidth={fullWidth}
startAdornment={
<>
<Stack direction="row" sx={{ minHeight: 'inherit', height: 1, gap: 0.5, alignItems: 'center', mr: 0.75 }}>
<Button
endIcon={<IconChevronDown width={16} height={16} />}
disabled={isDisabled || isCountryDisabled}
color="secondary"
sx={{
...theme.typography.body2,
height: 'auto',
p: 0,
borderRadius: 2,
minWidth: 40,
'&:hover': { bgcolor: 'transparent' },
'&:before': { display: 'none' },
'& .MuiInputBase-input:focus': { bgcolor: 'transparent' }
}}
disableRipple
aria-describedby={id}
type="button"
onClick={handleClick}
>
{selectedCountry.countryCode}
</Button>
<Divider orientation="vertical" flexItem />
</Stack>
<Popper
placement="bottom-start"
id={id}
open={open}
anchorEl={anchorEl}
transition
popperOptions={{ modifiers: [{ name: 'offset', options: { offset: [-10, 11] } }] }}
sx={{ zIndex: 1301 }}
>
{({ TransitionProps }) => (
<Fade in={open} {...TransitionProps}>
<Card elevation={0} sx={{ border: '1px solid', borderColor: theme.vars.palette.divider, borderRadius: 2 }}>
<ClickAwayListener onClickAway={() => setAnchorEl(null)}>
<Box sx={{ p: 0.5 }}>
<List disablePadding>
<Box style={{ maxHeight: 320, width: 280, overflow: 'auto' }}>
{countries.map((country, index) => (
<ListItemButton
key={index}
sx={{ borderRadius: 2, mb: 0.25 }}
selected={country.dialCode === dialCode}
onClick={() => countryChange(country)}
>
<ListItemAvatar sx={{ minWidth: 32 }}>
<CardMedia
image={`https://flagcdn.com/w20/${country.countryCode.toLowerCase()}.png`}
component="img"
sx={{ height: 'fit-content', width: 21 }}
/>
</ListItemAvatar>
<ListItemText primary={<Typography variant="body2">{country.name}</Typography>} />
</ListItemButton>
))}
</Box>
</List>
</Box>
</ClickAwayListener>
</Card>
</Fade>
)}
</Popper>
</>
}
/>
)}
/>
);
}
Contact.propTypes = {
dialCode: PropTypes.any,
placeholder: PropTypes.string,
helpText: PropTypes.any,
isDisabled: PropTypes.bool,
isCountryDisabled: PropTypes.bool,
fullWidth: PropTypes.bool,
control: PropTypes.any,
isError: PropTypes.bool,
onCountryChange: PropTypes.any
};