301 lines
12 KiB
JavaScript
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
|