// ** React Imports import { useEffect, useCallback, useRef, useState, ChangeEvent } from 'react' // ** Next Imports import Link from 'next/link' import { useRouter } from 'next/router' // ** MUI Imports import Box from '@mui/material/Box' import Grid from '@mui/material/Grid' import List from '@mui/material/List' import MuiDialog from '@mui/material/Dialog' import ListItem from '@mui/material/ListItem' import TextField from '@mui/material/TextField' import Typography from '@mui/material/Typography' import IconButton from '@mui/material/IconButton' import useMediaQuery from '@mui/material/useMediaQuery' import { styled, useTheme } from '@mui/material/styles' import ListItemButton from '@mui/material/ListItemButton' import InputAdornment from '@mui/material/InputAdornment' import MuiAutocomplete, { AutocompleteRenderInputParams } from '@mui/material/Autocomplete' // ** Third Party Imports import axios from 'axios' // ** Types Imports import { AppBarSearchType } from 'src/@fake-db/types' import { Settings } from 'src/@core/context/settingsContext' // ** Icon Imports import Icon from 'src/@core/components/icon' // ** Configs Imports import themeConfig from 'src/configs/themeConfig' interface Props { hidden: boolean settings: Settings } interface DefaultSuggestionsProps { setOpenDialog: (val: boolean) => void } interface NoResultProps { value: string setOpenDialog: (val: boolean) => void } interface DefaultSuggestionsType { category: string suggestions: { link: string icon: string suggestion: string }[] } const defaultSuggestionsData: DefaultSuggestionsType[] = [ { category: 'Popular Searches', suggestions: [ { icon: 'mdi:chart-donut', suggestion: 'CRM', link: '/dashboards/crm' }, { icon: 'mdi:poll', suggestion: 'Analytics', link: '/dashboards/analytics' }, { icon: 'mdi:chart-bubble', suggestion: 'eCommerce', link: '/dashboards/ecommerce' }, { icon: 'mdi:account-group', suggestion: 'User List', link: '/apps/user/list' } ] }, { category: 'Apps & Pages', suggestions: [ { icon: 'mdi:calendar-blank', suggestion: 'Calendar', link: '/apps/calendar' }, { icon: 'mdi:format-list-numbered', suggestion: 'Invoice List', link: '/apps/invoice/list' }, { icon: 'mdi:currency-usd', suggestion: 'Pricing', link: '/pages/pricing' }, { icon: 'mdi:account-cog-outline', suggestion: 'Account Settings', link: '/pages/account-settings/account' } ] }, { category: 'User Interface', suggestions: [ { icon: 'mdi:format-text-variant-outline', suggestion: 'Typography', link: '/ui/typography' }, { icon: 'mdi:tab', suggestion: 'Tabs', link: '/components/tabs' }, { icon: 'mdi:gesture-tap-button', suggestion: 'Buttons', link: '/components/buttons' }, { icon: 'mdi:card-bulleted-settings-outline', suggestion: 'Advanced Cards', link: '/ui/cards/advanced' } ] }, { category: 'Forms & Tables', suggestions: [ { icon: 'mdi:format-list-checkbox', suggestion: 'Select', link: '/forms/form-elements/select' }, { icon: 'mdi:lastpass', suggestion: 'Autocomplete', link: '/forms/form-elements/autocomplete' }, { icon: 'mdi:view-grid-outline', suggestion: 'Table', link: '/tables/mui' }, { icon: 'mdi:calendar-range', suggestion: 'Date Pickers', link: '/forms/form-elements/pickers' } ] } ] const categoryTitle: { [k: string]: string } = { dashboards: 'Dashboards', appsPages: 'Apps & Pages', userInterface: 'User Interface', formsTables: 'Forms & Tables', chartsMisc: 'Charts & Misc' } // ** Styled Autocomplete component const Autocomplete = styled(MuiAutocomplete)(({ theme }) => ({ '& fieldset': { border: 0 }, '& + .MuiAutocomplete-popper': { '& .MuiAutocomplete-listbox': { paddingTop: 0, height: '100%', maxHeight: 'inherit', '& .MuiListSubheader-root': { top: 0, fontWeight: 400, lineHeight: '15px', fontSize: '0.75rem', letterSpacing: '1px', color: theme.palette.text.disabled } }, '& .MuiAutocomplete-paper': { border: 0, height: '100%', borderRadius: 0, boxShadow: 'none' }, '& .MuiListItem-root.suggestion': { padding: 0, '& .MuiListItemSecondaryAction-root': { display: 'flex' }, '&.Mui-focused.Mui-focusVisible, &:hover': { backgroundColor: theme.palette.action.hover }, '& .MuiListItemButton-root: hover': { backgroundColor: 'transparent' }, '&:not(:hover)': { '& .MuiListItemSecondaryAction-root': { display: 'none' }, '&.Mui-focused, &.Mui-focused.Mui-focusVisible:not(:hover)': { '& .MuiListItemSecondaryAction-root': { display: 'flex' } }, [theme.breakpoints.down('sm')]: { '&.Mui-focused:not(.Mui-focusVisible) .MuiListItemSecondaryAction-root': { display: 'none' } } } }, '& .MuiAutocomplete-noOptions': { display: 'grid', minHeight: '100%', alignItems: 'center', flexDirection: 'column', justifyContent: 'center', padding: theme.spacing(10) } } })) // ** Styled Dialog component const Dialog = styled(MuiDialog)({ '& .MuiBackdrop-root': { backdropFilter: 'blur(4px)' }, '& .MuiDialog-paper': { overflow: 'hidden', '&:not(.MuiDialog-paperFullScreen)': { height: '100%', maxHeight: 550 } } }) const NoResult = ({ value, setOpenDialog }: NoResultProps) => { return ( No results for{' '} {`"${value}"`} Try searching for setOpenDialog(false)}> *': { color: 'primary.main' } }} > CRM Dashboard setOpenDialog(false)}> *': { color: 'primary.main' } }} > User Profile setOpenDialog(false)}> *': { color: 'primary.main' } }} > Account Settings ) } const DefaultSuggestions = ({ setOpenDialog }: DefaultSuggestionsProps) => { return ( {defaultSuggestionsData.map((item, index) => ( {item.category} {item.suggestions.map((suggestionItem, index2) => ( setOpenDialog(false)} sx={{ display: 'flex', alignItems: 'center', '& svg': { mr: 2.5 }, color: 'text.primary', textDecoration: 'none', '&:hover > *': { color: 'primary.main' } }} > {suggestionItem.suggestion} ))} ))} ) } const AutocompleteComponent = ({ hidden, settings }: Props) => { // ** States const [isMounted, setIsMounted] = useState(false) const [searchValue, setSearchValue] = useState('') const [openDialog, setOpenDialog] = useState(false) const [options, setOptions] = useState([]) // ** Hooks & Vars const theme = useTheme() const router = useRouter() const { layout } = settings const wrapper = useRef(null) const fullScreenDialog = useMediaQuery(theme.breakpoints.down('sm')) // Get all data using API useEffect(() => { setOptions([]) // axios // .get('/app-bar/search', { // params: { q: searchValue } // }) // .then(response => { // if (response.data && response.data.length) { // setOptions(response.data) // } else { // setOptions([]) // } // }) }, [searchValue]) useEffect(() => { if (!openDialog) { setSearchValue('') } }, [openDialog]) useEffect(() => { setIsMounted(true) return () => setIsMounted(false) }, []) // Handle click event on a list item in search result const handleOptionClick = (obj: AppBarSearchType) => { setSearchValue('') setOpenDialog(false) if (obj.url) { router.push(obj.url) } } // Handle ESC & shortcut keys keydown events const handleKeydown = useCallback( (event: KeyboardEvent) => { // ** Shortcut keys to open searchbox (Ctrl + /) if (!openDialog && event.ctrlKey && event.which === 191) { setOpenDialog(true) } }, [openDialog] ) // Handle shortcut keys keyup events const handleKeyUp = useCallback( (event: KeyboardEvent) => { // ** ESC key to close searchbox if (openDialog && event.keyCode === 27) { setOpenDialog(false) } }, [openDialog] ) useEffect(() => { document.addEventListener('keydown', handleKeydown) document.addEventListener('keyup', handleKeyUp) return () => { document.removeEventListener('keydown', handleKeydown) document.removeEventListener('keyup', handleKeyUp) } }, [handleKeyUp, handleKeydown]) if (!isMounted) { return null } else { return ( !openDialog && setOpenDialog(true)} sx={{ display: 'flex', cursor: 'pointer', alignItems: 'center' }} > {openDialog && ( setOpenDialog(false)}> true} onInputChange={(event, value: string) => setSearchValue(value)} onChange={(event, obj) => handleOptionClick(obj as AppBarSearchType)} noOptionsText={} getOptionLabel={(option: AppBarSearchType | unknown) => (option as AppBarSearchType).title || ''} groupBy={(option: AppBarSearchType | unknown) => searchValue.length ? categoryTitle[(option as AppBarSearchType).category] : '' } sx={{ '& + .MuiAutocomplete-popper': { ...(searchValue.length ? { overflow: 'auto', maxHeight: 'calc(100vh - 69px)', borderTop: `1px solid ${theme.palette.divider}`, height: fullScreenDialog ? 'calc(100vh - 69px)' : 481, '& .MuiListSubheader-root': { p: theme.spacing(3.75, 6, 0.75) } } : { '& .MuiAutocomplete-listbox': { pb: 0 } }) } }} renderInput={(params: AutocompleteRenderInputParams) => { return ( ) => setSearchValue(event.target.value)} inputRef={input => { if (input) { if (openDialog) { input.focus() } else { input.blur() } } }} InputProps={{ ...params.InputProps, sx: { p: `${theme.spacing(3.75, 6)} !important` }, startAdornment: ( ), endAdornment: ( setOpenDialog(false)} sx={{ display: 'flex', cursor: 'pointer', alignItems: 'center' }} > {!hidden ? [esc] : null} ) }} /> ) }} renderOption={(props, option: AppBarSearchType | unknown) => { return searchValue.length ? ( handleOptionClick(option as AppBarSearchType)} secondaryAction={} sx={{ '& .MuiListItemSecondaryAction-root': { '& svg': { cursor: 'pointer', color: 'text.disabled' } } }} > {(option as AppBarSearchType).title} ) : null }} /> {searchValue.length === 0 ? ( ) : null} )} ) } } export default AutocompleteComponent