kris@sentientgeeks.com e8d6a59a8c initial commit
2021-09-06 21:48:42 +05:30

301 lines
12 KiB
JavaScript

// ** React Imports
import { Fragment, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
// ** Third Party Components
import * as Icon from 'react-feather'
import classnames from 'classnames'
import Autocomplete from '@components/autocomplete'
import {
NavItem,
NavLink,
UncontrolledTooltip,
UncontrolledDropdown,
DropdownToggle,
DropdownMenu,
DropdownItem,
Tooltip
} from 'reactstrap'
// ** Store & Actions
import { useDispatch, useSelector } from 'react-redux'
import { getBookmarks, updateBookmarked, handleSearchQuery } from '@store/actions/navbar'
const NavbarBookmarks = props => {
// ** Props
const { setMenuVisibility } = props
// ** State
const [value, setValue] = useState('')
const [openSearch, setOpenSearch] = useState(false)
// ** Store Vars
const dispatch = useDispatch()
const store = useSelector(state => state.navbar)
// ** ComponentDidMount
useEffect(() => {
dispatch(getBookmarks())
}, [])
// ** Function to toggle Theme (Light/Dark)
const ThemeToggler = () => {
if (props.skin === 'dark') {
return <Icon.Sun className='ficon' onClick={() => props.setSkin('light')} />
} else {
return <Icon.Moon className='ficon' onClick={() => props.setSkin('dark')} />
}
}
const [tooltipOpen, setTooltipOpen] = useState(false)
const toggle = () => setTooltipOpen(!tooltipOpen)
const [mailtpOpen, setMailtpOpen] = useState(false)
const mailtoggle = () => setMailtpOpen(!mailtpOpen)
const [smstpOpen, setSmstpOpen] = useState(false)
const smstoggle = () => setSmstpOpen(!smstpOpen)
const [doctpOpen, setDoctpOpen] = useState(false)
const doctoggle = () => setDoctpOpen(!doctpOpen)
const [markettpOpen, setMarkettpOpen] = useState(false)
const markettoggle = () => setMarkettpOpen(!markettpOpen)
const [zoomtpOpen, setZoomtpOpen] = useState(false)
const zoomtoggle = () => setZoomtpOpen(!zoomtpOpen)
const [linkedtpOpen, setLinkedtpOpen] = useState(false)
const linkedtoggle = () => setLinkedtpOpen(!linkedtpOpen)
const [swthemetpOpen, setSwitchThemetpOpen] = useState(false)
const switchThemetoggle = () => setSwitchThemetpOpen(!swthemetpOpen)
// ** Loops through Bookmarks Array to return Bookmarks
const renderBookmarks = () => {
if (store.bookmarks.length) {
return store.bookmarks
.map(item => {
const IconTag = Icon[item.icon]
return (
<NavItem key={item.target} className='d-none d-lg-block'>
<NavLink tag={Link} to={item.link} id={item.target}>
<IconTag className='ficon' />
<UncontrolledTooltip target={item.target}>{item.title}</UncontrolledTooltip>
</NavLink>
</NavItem>
)
})
.slice(0, 10)
} else {
return null
}
}
// ** If user has more than 10 bookmarks then add the extra Bookmarks to a dropdown
const renderExtraBookmarksDropdown = () => {
if (store.bookmarks.length && store.bookmarks.length >= 11) {
return (
<NavItem className='d-none d-lg-block'>
<NavLink tag='span'>
<UncontrolledDropdown>
<DropdownToggle tag='span'>
<Icon.ChevronDown className='ficon' />
</DropdownToggle>
<DropdownMenu right>
{store.bookmarks
.map(item => {
const IconTag = Icon[item.icon]
return (
<DropdownItem tag={Link} to={item.link} key={item.id}>
<IconTag className='mr-50' size={14} />
<span className='align-middle'>{item.title}</span>
</DropdownItem>
)
})
.slice(10)}
</DropdownMenu>
</UncontrolledDropdown>
</NavLink>
</NavItem>
)
} else {
return null
}
}
// ** Removes query in store
const handleClearQueryInStore = () => dispatch(handleSearchQuery(''))
// ** Loops through Bookmarks Array to return Bookmarks
const onKeyDown = e => {
if (e.keyCode === 27 || e.keyCode === 13) {
setTimeout(() => {
setOpenSearch(false)
handleClearQueryInStore()
}, 1)
}
}
// ** Function to toggle Bookmarks
const handleBookmarkUpdate = id => dispatch(updateBookmarked(id))
// ** Function to handle Bookmarks visibility
const handleBookmarkVisibility = () => {
setOpenSearch(!openSearch)
setValue('')
handleClearQueryInStore()
}
// ** Function to handle Input change
const handleInputChange = e => {
setValue(e.target.value)
dispatch(handleSearchQuery(e.target.value))
}
// ** Function to handle external Input click
const handleExternalClick = () => {
if (openSearch === true) {
setOpenSearch(false)
handleClearQueryInStore()
}
}
// ** Function to clear input value
const handleClearInput = setUserInput => {
if (!openSearch) {
setUserInput('')
handleClearQueryInStore()
}
}
return (
<Fragment>
<ul className='nav navbar-nav bookmark-icons'>
<NavItem className='d-none d-lg-block'>
<NavLink className='nav-link-style' id="switchtheme">
<ThemeToggler />
<Tooltip placement="bottom" isOpen={swthemetpOpen} target="switchtheme" toggle={switchThemetoggle}>
Switch Theme
</Tooltip>
</NavLink>
</NavItem>
<div>
<span style={{ padding: '6px' }} id="TooltipExample">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="ficon"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="8" y1="12" x2="16" y2="12"></line><line x1="12" y1="16" x2="12" y2="16"></line><line x1="12" y1="8" x2="12" y2="8"></line></svg>
<Tooltip placement="bottom" isOpen={tooltipOpen} target="TooltipExample" toggle={toggle}>
Xero
</Tooltip>
</span>
<span style={{ padding: '6px' }} id="emailsvg">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="ficon"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
<Tooltip placement="bottom" isOpen={mailtpOpen} target="emailsvg" toggle={mailtoggle}>
Email
</Tooltip>
</span>
<span style={{ padding: '6px' }} id="smssvg">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="ficon"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
<Tooltip placement="bottom" isOpen={smstpOpen} target="smssvg" toggle={smstoggle}>
SMS
</Tooltip>
</span>
<span style={{ padding: '6px' }} id="docsvg">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="ficon"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="12" y1="18" x2="12" y2="12"></line><line x1="9" y1="15" x2="15" y2="15"></line></svg>
<Tooltip placement="bottom" isOpen={doctpOpen} target="docsvg" toggle={doctoggle}>
Documents
</Tooltip>
</span>
<span style={{ padding: '6px' }} id="marketsvg">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="ficon"><circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M13 6h3a2 2 0 0 1 2 2v7"></path><line x1="6" y1="9" x2="6" y2="21"></line></svg>
<Tooltip placement="bottom" isOpen={markettpOpen} target="marketsvg" toggle={markettoggle}>
Marketting
</Tooltip>
</span>
<span style={{ padding: '6px' }} id="zoomsvg">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="ficon"><polygon points="23 7 16 12 23 17 23 7"></polygon><rect x="1" y="5" width="15" height="14" rx="2" ry="2"></rect></svg>
<Tooltip placement="bottom" isOpen={zoomtpOpen} target="zoomsvg" toggle={zoomtoggle}>
Zoom
</Tooltip>
</span>
<span style={{ padding: '6px' }} id="linkedinsvg">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="ficon"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path><rect x="2" y="9" width="4" height="12"></rect><circle cx="4" cy="4" r="2"></circle></svg>
<Tooltip placement="bottom" isOpen={linkedtpOpen} target="linkedinsvg" toggle={linkedtoggle}>
LinkedIn
</Tooltip>
</span>
</div>
{renderExtraBookmarksDropdown()}
<NavItem className='nav-item d-none d-lg-block'>
<div className={classnames('bookmark-input search-input', { show: openSearch })}>
<div className='bookmark-input-icon'>
<Icon.Search size={14} />
</div>
{openSearch && store.suggestions.length ? (
<Autocomplete
wrapperClass={classnames('search-list search-list-bookmark', {
show: openSearch
})}
className='form-control'
suggestions={!value.length ? store.bookmarks : store.suggestions}
filterKey='title'
autoFocus={true}
defaultSuggestions
suggestionLimit={!value.length ? store.bookmarks.length : 6}
placeholder='Search...'
externalClick={handleExternalClick}
clearInput={(userInput, setUserInput) => handleClearInput(setUserInput)}
onKeyDown={onKeyDown}
value={value}
onChange={handleInputChange}
customRender={(
item,
i,
filteredData,
activeSuggestion,
onSuggestionItemClick,
onSuggestionItemHover
) => {
const IconTag = Icon[item.icon ? item.icon : 'X']
return (
<li
key={i}
onMouseEnter={() => onSuggestionItemHover(filteredData.indexOf(item))}
className={classnames('suggestion-item d-flex align-items-center justify-content-between', {
active: filteredData.indexOf(item) === activeSuggestion
})}
>
<Link
to={item.link}
className='d-flex align-items-center justify-content-between p-0'
onClick={() => {
setOpenSearch(false)
handleClearQueryInStore()
}}
style={{
width: 'calc(90%)'
}}
>
<div className='d-flex justify-content-start align-items-center overflow-hidden'>
<IconTag size={17.5} className='mr-75' />
<span className='text-truncate'>{item.title}</span>
</div>
</Link>
<Icon.Star
size={17.5}
className={classnames('bookmark-icon float-right', {
'text-warning': item.isBookmarked
})}
onClick={() => handleBookmarkUpdate(item.id)}
/>
</li>
)
}}
/>
) : null}
</div>
</NavItem>
</ul>
</Fragment>
)
}
export default NavbarBookmarks