upgade package

This commit is contained in:
CHIEFSOFT\ameye
2024-04-23 14:04:21 -04:00
parent ede879d821
commit 44f6fb0816
966 changed files with 7972 additions and 88698 deletions
@@ -0,0 +1,42 @@
import {useEffect} from 'react'
import {useLocation} from 'react-router'
import clsx from 'clsx'
import {useLayout} from '../../core'
import {DrawerComponent} from '../../../assets/ts/components'
import {WithChildren} from '../../../helpers'
const Content = ({children}: WithChildren) => {
const {config, classes} = useLayout()
const location = useLocation()
useEffect(() => {
DrawerComponent.hideAll()
}, [location])
const appContentContainer = config.app?.content?.container
return (
<div
id='kt_app_content'
className={clsx(
'app-content flex-column-fluid',
classes.content.join(' '),
config?.app?.content?.class
)}
>
{appContentContainer ? (
<div
id='kt_app_content_container'
className={clsx('app-container', classes.contentContainer.join(' '), {
'container-xxl': appContentContainer === 'fixed',
'container-fluid': appContentContainer === 'fluid',
})}
>
{children}
</div>
) : (
<>{children}</>
)}
</div>
)
}
export {Content}
@@ -0,0 +1 @@
export * from './Content'
@@ -0,0 +1,61 @@
import {useEffect} from 'react'
import {ILayout, useLayout} from '../../core'
const Footer = () => {
const {config} = useLayout()
useEffect(() => {
updateDOM(config)
}, [config])
return (
<>
<div className='text-gray-900 order-2 order-md-1'>
<span className='text-muted fw-semibold me-1'>
{new Date().getFullYear().toString()}&copy;
</span>
<a
href='https://keenthemes.com/'
target='_blank'
className='text-gray-800 text-hover-primary'
>
Keenthemes
</a>
</div>
<ul className='menu menu-gray-600 menu-hover-primary fw-semibold order-1'>
<li className='menu-item'>
<a href='https://keenthemes.com/' target='_blank' className='menu-link px-2'>
About
</a>
</li>
<li className='menu-item'>
<a href='https://devs.keenthemes.com/' target='_blank' className='menu-link px-2'>
Support
</a>
</li>
<li className='menu-item'>
<a
href='https://themeforest.net/item/metronic-responsive-admin-dashboard-template/4021469'
target='_blank'
className='menu-link px-2'
>
Purchase
</a>
</li>
</ul>
</>
)
}
const updateDOM = (config: ILayout) => {
if (config.app?.footer?.fixed?.desktop) {
document.body.classList.add('data-kt-app-footer-fixed', 'true')
}
if (config.app?.footer?.fixed?.mobile) {
document.body.classList.add('data-kt-app-footer-fixed-mobile', 'true')
}
}
export {Footer}
@@ -0,0 +1,30 @@
import clsx from 'clsx'
import {useLayout} from '../../core'
import {Footer} from './Footer'
const FooterWrapper = () => {
const {config} = useLayout()
if (!config.app?.footer?.display) {
return null
}
return (
<div className='app-footer' id='kt_app_footer'>
{config.app.footer.containerClass ? (
<div
className={clsx(
'app-container',
config.app.footer.container === 'fixed' ? 'container-xxl' : 'container-fluid',
config.app.footer.containerClass
)}
>
<Footer />
</div>
) : (
<Footer />
)}
</div>
)
}
export {FooterWrapper}
@@ -0,0 +1 @@
export * from './FooterWrapper'
@@ -0,0 +1,92 @@
/* eslint-disable no-prototype-builtins */
import {FC, useEffect} from 'react'
import {ILayout, useLayout} from '../../core'
import {MenuInner} from './header-menus'
const Header: FC = () => {
const {config} = useLayout()
useEffect(() => {
updateDOM(config)
}, [config])
return (
<div
className='
menu
menu-rounded
menu-column
menu-lg-row
my-5
my-lg-0
align-items-stretch
fw-semibold
px-2 px-lg-0
'
id='kt_app_header_menu'
data-kt-menu='true'
>
<MenuInner />
</div>
)
}
const updateDOM = (config: ILayout) => {
if (config.app?.header?.default?.fixed?.desktop) {
document.body.setAttribute('data-kt-app-header-fixed', 'true')
document.body.setAttribute('data-kt-app-header-minimize', 'on')
}
if (config.app?.header?.default?.fixed?.mobile) {
document.body.setAttribute('data-kt-app-header-fixed-mobile', 'true')
}
if (config.app?.header?.default?.stacked) {
document.body.setAttribute('data-kt-app-header-stacked', 'true')
}
const appHeaderDefaultStickyEnabled = config.app?.header?.default?.sticky?.enabled
let appHeaderDefaultStickyAttributes: {[attrName: string]: string} = {}
if (appHeaderDefaultStickyEnabled) {
appHeaderDefaultStickyAttributes = config.app?.header?.default?.sticky?.attributes as {
[attrName: string]: string
}
}
const appHeaderDefaultMinimizeEnabled = config.app?.header?.default?.minimize?.enabled
let appHeaderDefaultMinimizeAttributes: {[attrName: string]: string} = {}
if (appHeaderDefaultMinimizeEnabled) {
appHeaderDefaultMinimizeAttributes = config.app?.header?.default?.minimize?.attributes as {
[attrName: string]: string
}
}
setTimeout(() => {
const headerElement = document.getElementById('kt_app_header')
// header
if (headerElement) {
const headerAttributes = headerElement
.getAttributeNames()
.filter((t) => t.indexOf('data-') > -1)
headerAttributes.forEach((attr) => headerElement.removeAttribute(attr))
if (appHeaderDefaultStickyEnabled) {
for (const key in appHeaderDefaultStickyAttributes) {
if (appHeaderDefaultStickyAttributes.hasOwnProperty(key)) {
headerElement.setAttribute(key, appHeaderDefaultStickyAttributes[key])
}
}
}
if (appHeaderDefaultMinimizeEnabled) {
for (const key in appHeaderDefaultMinimizeAttributes) {
if (appHeaderDefaultMinimizeAttributes.hasOwnProperty(key)) {
headerElement.setAttribute(key, appHeaderDefaultMinimizeAttributes[key])
}
}
}
}
}, 0)
}
export {Header}
@@ -0,0 +1,111 @@
import clsx from 'clsx'
import {Link} from 'react-router-dom'
import {KTIcon, toAbsoluteUrl} from '../../../helpers'
import {LayoutSetup, useLayout} from '../../core'
import {Header} from './Header'
import {Navbar} from './Navbar'
export function HeaderWrapper() {
const {config, classes} = useLayout()
if (config.app?.header?.default?.container === 'fluid') {
LayoutSetup.classes.headerContainer.push("container-fluid");
} else {
LayoutSetup.classes.headerContainer.push("container-xxl");
}
if (!config.app?.header?.display) {
return null
}
return (
<div id='kt_app_header' className='app-header'>
<div
id='kt_app_header_container'
className={clsx(
'app-container',
classes.headerContainer.join(' '),
config.app?.header?.default?.containerClass
)}
>
{config.app.sidebar?.display && (
<>
{config.layoutType !== 'dark-header' && config.layoutType !== 'light-header' ? (
<div
className='d-flex align-items-center d-lg-none ms-n2 me-2'
title='Show sidebar menu'
>
<div
className='btn btn-icon btn-active-color-primary w-35px h-35px'
id='kt_app_sidebar_mobile_toggle'
>
<KTIcon iconName='abstract-14' className=' fs-1' />
</div>
<div className='d-flex align-items-center flex-grow-1 flex-lg-grow-0'>
<Link to='/dashboard' className='d-lg-none'>
<img
alt='Logo'
src={toAbsoluteUrl('media/logos/default-small.svg')}
className='h-30px'
/>
</Link>
</div>
</div>
) : null}
</>
)}
{!(config.layoutType === 'dark-sidebar' || config.layoutType === 'light-sidebar') && (
<div className='d-flex align-items-center flex-grow-1 flex-lg-grow-0 me-lg-15'>
<Link to='/dashboard'>
{config.layoutType === 'dark-header' ? (
<img
alt='Logo'
src={toAbsoluteUrl('media/logos/sidelogo.png')}
className='h-20px h-lg-30px app-sidebar-logo-default'
/>
) : (
<>
<img
alt='Logo'
src={toAbsoluteUrl('media/logos/sidelogo.png')}
className='h-20px h-lg-30px app-sidebar-logo-default theme-light-show'
/>
<img
alt='Logo'
src={toAbsoluteUrl('media/logos/sidelogo.png')}
className='h-20px h-lg-30px app-sidebar-logo-default theme-dark-show'
/>
</>
)}
</Link>
</div>
)}
<div
id='kt_app_header_wrapper'
className='d-flex align-items-stretch justify-content-between flex-lg-grow-1'
>
{config.app.header.default?.content === 'menu' &&
config.app.header.default.menu?.display && (
<div
className='app-header-menu app-header-mobile-drawer align-items-stretch'
data-kt-drawer='true'
data-kt-drawer-name='app-header-menu'
data-kt-drawer-activate='{default: true, lg: false}'
data-kt-drawer-overlay='true'
data-kt-drawer-width='225px'
data-kt-drawer-direction='end'
data-kt-drawer-toggle='#kt_app_header_menu_toggle'
data-kt-swapper='true'
data-kt-swapper-mode="{default: 'append', lg: 'prepend'}"
data-kt-swapper-parent="{default: '#kt_app_body', lg: '#kt_app_header_wrapper'}"
>
<Header />
</div>
)}
<Navbar />
</div>
</div>
</div>
)
}
@@ -0,0 +1,75 @@
import clsx from 'clsx'
import {KTIcon, toAbsoluteUrl} from '../../../helpers'
import {HeaderNotificationsMenu, HeaderUserMenu, Search, ThemeModeSwitcher} from '../../../partials'
import {useLayout} from '../../core'
const itemClass = 'ms-1 ms-md-4'
const btnClass =
'btn btn-icon btn-custom btn-icon-muted btn-active-light btn-active-color-primary w-35px h-35px'
const userAvatarClass = 'symbol-35px'
const btnIconClass = 'fs-2'
const Navbar = () => {
const {config} = useLayout()
return (
<div className='app-navbar flex-shrink-0'>
<div className={clsx('app-navbar-item align-items-stretch', itemClass)}>
<Search />
</div>
<div className={clsx('app-navbar-item', itemClass)}>
<div id='kt_activities_toggle' className={btnClass}>
<KTIcon iconName='chart-simple' className={btnIconClass} />
</div>
</div>
<div className={clsx('app-navbar-item', itemClass)}>
<div
data-kt-menu-trigger="{default: 'click'}"
data-kt-menu-attach='parent'
data-kt-menu-placement='bottom-end'
className={btnClass}
>
<KTIcon iconName='element-plus' className={btnIconClass} />
</div>
<HeaderNotificationsMenu />
</div>
<div className={clsx('app-navbar-item', itemClass)}>
<div className={clsx('position-relative', btnClass)} id='kt_drawer_chat_toggle'>
<KTIcon iconName='message-text-2' className={btnIconClass} />
<span className='bullet bullet-dot bg-success h-6px w-6px position-absolute translate-middle top-0 start-50 animation-blink' />
</div>
</div>
<div className={clsx('app-navbar-item', itemClass)}>
<ThemeModeSwitcher toggleBtnClass={clsx('btn-active-light-primary btn-custom')} />
</div>
<div className={clsx('app-navbar-item', itemClass)}>
<div
className={clsx('cursor-pointer symbol', userAvatarClass)}
data-kt-menu-trigger="{default: 'click'}"
data-kt-menu-attach='parent'
data-kt-menu-placement='bottom-end'
>
<img src={toAbsoluteUrl('media/avatars/300-3.jpg')} alt='' />
</div>
<HeaderUserMenu />
</div>
{config.app?.header?.default?.menu?.display && (
<div className='app-navbar-item d-lg-none ms-2 me-n3' title='Show header menu'>
<div
className='btn btn-icon btn-active-color-primary w-35px h-35px'
id='kt_app_header_menu_toggle'
>
<KTIcon iconName='text-align-left' className={btnIconClass} />
</div>
</div>
)}
</div>
)
}
export {Navbar}
@@ -0,0 +1,162 @@
import {FC} from 'react'
import {Link} from 'react-router-dom'
import {toAbsoluteUrl} from '../../../../helpers'
import {useLayout} from '../../../core'
const MegaMenu: FC = () => {
const {setLayoutType, setToolbarType} = useLayout()
return (
<div className='row'>
{/* begin:Col */}
<div className='col-lg-6'>
{/* begin:Row */}
<div className='row'>
{/* begin:Col */}
<div className='col-lg-6 mb-3'>
{/* begin:Heading */}
<h4 className='fs-6 fs-lg-4 text-gray-800 fw-bold mt-3 mb-3 ms-4'>Layouts</h4>
{/* end:Heading */}
{/* begin:Menu item */}
<div className='menu-item p-0 m-0'>
{/* begin:Menu link */}
<a onClick={() => setLayoutType('light-sidebar')} className='menu-link'>
<span className='menu-bullet'>
<span className='bullet bullet-dot bg-gray-300i h-6px w-6px'></span>
</span>
<span className='menu-title'>Light Sidebar</span>
</a>
{/* end:Menu link */}
</div>
{/* end:Menu item */}
{/* begin:Menu item */}
<div className='menu-item p-0 m-0'>
{/* begin:Menu link */}
<a onClick={() => setLayoutType('dark-sidebar')} className='menu-link'>
<span className='menu-bullet'>
<span className='bullet bullet-dot bg-gray-300i h-6px w-6px'></span>
</span>
<span className='menu-title'>Dark Sidebar</span>
</a>
{/* end:Menu link */}
</div>
{/* end:Menu item */}
{/* begin:Menu item */}
<div className='menu-item p-0 m-0'>
{/* begin:Menu link */}
<a onClick={() => setLayoutType('light-header')} className='menu-link'>
<span className='menu-bullet'>
<span className='bullet bullet-dot bg-gray-300i h-6px w-6px'></span>
</span>
<span className='menu-title'>Light Header</span>
</a>
{/* end:Menu link */}
</div>
{/* end:Menu item */}
{/* begin:Menu item */}
<div className='menu-item p-0 m-0'>
{/* begin:Menu link */}
<a onClick={() => setLayoutType('dark-header')} className='menu-link'>
<span className='menu-bullet'>
<span className='bullet bullet-dot bg-gray-300i h-6px w-6px'></span>
</span>
<span className='menu-title'>Dark Header</span>
</a>
{/* end:Menu link */}
</div>
{/* end:Menu item */}
</div>
{/* end:Col */}
{/* begin:Col */}
<div className='col-lg-6 mb-3'>
{/* begin:Heading */}
<h4 className='fs-6 fs-lg-4 text-gray-800 fw-bold mt-3 mb-3 ms-4'>Toolbars</h4>
{/* end:Heading */}
{/* begin:Menu item */}
<div className='menu-item p-0 m-0'>
{/* begin:Menu link */}
<a onClick={() => setToolbarType('classic')} className='menu-link'>
<span className='menu-bullet'>
<span className='bullet bullet-dot bg-gray-300i h-6px w-6px'></span>
</span>
<span className='menu-title'>Classic</span>
</a>
{/* end:Menu link */}
</div>
{/* end:Menu item */}
{/* begin:Menu item */}
<div className='menu-item p-0 m-0'>
{/* begin:Menu link */}
<a onClick={() => setToolbarType('saas')} className='menu-link'>
<span className='menu-bullet'>
<span className='bullet bullet-dot bg-gray-300i h-6px w-6px'></span>
</span>
<span className='menu-title'>SaaS</span>
</a>
{/* end:Menu link */}
</div>
{/* end:Menu item */}
{/* begin:Menu item */}
<div className='menu-item p-0 m-0'>
{/* begin:Menu link */}
<a onClick={() => setToolbarType('accounting')} className='menu-link'>
<span className='menu-bullet'>
<span className='bullet bullet-dot bg-gray-300i h-6px w-6px'></span>
</span>
<span className='menu-title'>Accounting</span>
</a>
{/* end:Menu link */}
</div>
{/* end:Menu item */}
{/* begin:Menu item */}
<div className='menu-item p-0 m-0'>
{/* begin:Menu link */}
<a onClick={() => setToolbarType('extended')} className='menu-link'>
<span className='menu-bullet'>
<span className='bullet bullet-dot bg-gray-300i h-6px w-6px'></span>
</span>
<span className='menu-title'>Extended</span>
</a>
{/* end:Menu link */}
</div>
{/* end:Menu item */}
{/* begin:Menu item */}
<div className='menu-item p-0 m-0'>
{/* begin:Menu link */}
<a onClick={() => setToolbarType('reports')} className='menu-link'>
<span className='menu-bullet'>
<span className='bullet bullet-dot bg-gray-300i h-6px w-6px'></span>
</span>
<span className='menu-title'>Reports</span>
</a>
{/* end:Menu link */}
</div>
{/* end:Menu item */}
</div>
{/* end:Col */}
</div>
{/* end:Row */}
<div className='separator separator-dashed mx-lg-5 mt-2 mb-6'></div>
{/* begin:Layout Builder */}
<div className='d-flex flex-stack flex-wrap flex-lg-nowrap gap-2 mb-5 mb-lg-0 mx-lg-5'>
<div className='d-flex flex-column me-5'>
<div className='fs-6 fw-bold text-gray-800'>Layout Builder</div>
<div className='fs-7 fw-semibold text-muted'>Customize view</div>
</div>
<Link to='/builder' className='btn btn-sm btn-primary fw-bold'>
Try Builder
</Link>
</div>
{/* end:Layout Builder */}
</div>
{/* end:Col */}
{/* begin:Col */}
<div className='col-lg-6 mb-3 py-lg-3 pe-lg-8 d-flex align-items-center'>
<img src={toAbsoluteUrl('media/stock/900x600/45.jpg')} className='rounded mw-100' alt='' />
</div>
{/* end:Col */}
</div>
)
}
export {MegaMenu}
@@ -0,0 +1,130 @@
import {useIntl} from 'react-intl'
import {MenuItem} from './MenuItem'
import {MenuInnerWithSub} from './MenuInnerWithSub'
import {MegaMenu} from './MegaMenu'
export function MenuInner() {
const intl = useIntl()
return (
<>
<MenuItem title={intl.formatMessage({id: 'MENU.DASHBOARD'})} to='/dashboard' />
<MenuItem title='Layout Builder' to='/builder' />
<MenuInnerWithSub
title='Crafted'
to='/crafted'
menuPlacement='bottom-start'
menuTrigger='click'
>
{/* PAGES */}
<MenuInnerWithSub
title='Pages'
to='/crafted/pages'
fontIcon='bi-archive'
hasArrow={true}
menuPlacement='right-start'
menuTrigger={`{default:'click', lg: 'hover'}`}
>
<MenuInnerWithSub
title='Profile'
to='/crafted/pages/profile'
hasArrow={true}
hasBullet={true}
menuPlacement='right-start'
menuTrigger={`{default:'click', lg: 'hover'}`}
>
<MenuItem to='/crafted/pages/profile/overview' title='Overview' hasBullet={true} />
<MenuItem to='/crafted/pages/profile/projects' title='Projects' hasBullet={true} />
<MenuItem to='/crafted/pages/profile/campaigns' title='Campaigns' hasBullet={true} />
<MenuItem to='/crafted/pages/profile/documents' title='Documents' hasBullet={true} />
<MenuItem
to='/crafted/pages/profile/connections'
title='Connections'
hasBullet={true}
/>
</MenuInnerWithSub>
<MenuInnerWithSub
title='Wizards'
to='/crafted/pages/wizards'
hasArrow={true}
hasBullet={true}
menuPlacement='right-start'
menuTrigger={`{default:'click', lg: 'hover'}`}
>
<MenuItem to='/crafted/pages/wizards/horizontal' title='Horizontal' hasBullet={true} />
<MenuItem to='/crafted/pages/wizards/vertical' title='Vertical' hasBullet={true} />
</MenuInnerWithSub>
</MenuInnerWithSub>
{/* ACCOUNT */}
<MenuInnerWithSub
title='Accounts'
to='/crafted/accounts'
fontIcon='bi-person'
hasArrow={true}
menuPlacement='right-start'
menuTrigger={`{default:'click', lg: 'hover'}`}
>
<MenuItem to='/crafted/account/overview' title='Overview' hasBullet={true} />
<MenuItem to='/crafted/account/settings' title='Settings' hasBullet={true} />
</MenuInnerWithSub>
{/* ERRORS */}
<MenuInnerWithSub
title='Errors'
to='/error'
fontIcon='bi-sticky'
hasArrow={true}
menuPlacement='right-start'
menuTrigger={`{default:'click', lg: 'hover'}`}
>
<MenuItem to='/error/404' title='Error 404' hasBullet={true} />
<MenuItem to='/error/500' title='Error 500' hasBullet={true} />
</MenuInnerWithSub>
{/* Widgets */}
<MenuInnerWithSub
title='Widgets'
to='/crafted/widgets'
fontIcon='bi-layers'
hasArrow={true}
menuPlacement='right-start'
menuTrigger={`{default:'click', lg: 'hover'}`}
>
<MenuItem to='/crafted/widgets/lists' title='Lists' hasBullet={true} />
<MenuItem to='/crafted/widgets/statistics' title='Statistics' hasBullet={true} />
<MenuItem to='/crafted/widgets/charts' title='Charts' hasBullet={true} />
<MenuItem to='/crafted/widgets/mixed' title='Mixed' hasBullet={true} />
<MenuItem to='/crafted/widgets/tables' title='Tables' hasBullet={true} />
<MenuItem to='/crafted/widgets/feeds' title='Feeds' hasBullet={true} />
</MenuInnerWithSub>
</MenuInnerWithSub>
<MenuInnerWithSub title='Apps' to='/apps' menuPlacement='bottom-start' menuTrigger='click'>
{/* PAGES */}
<MenuInnerWithSub
title='Chat'
to='/apps/chat'
icon='message-text-2'
hasArrow={true}
menuPlacement='right-start'
menuTrigger={`{default:'click', lg: 'hover'}`}
>
<MenuItem to='/apps/chat/private-chat' title='Private Chat' hasBullet={true} />
<MenuItem to='/apps/chat/group-chat' title='Group Chart' hasBullet={true} />
<MenuItem to='/apps/chat/drawer-chat' title='Drawer Chart' hasBullet={true} />
</MenuInnerWithSub>
<MenuItem icon='abstract-28' to='/apps/user-management/users' title='User management' />
</MenuInnerWithSub>
<MenuInnerWithSub
isMega={true}
title='Layouts'
to='/mega-menu'
menuPlacement='bottom-start'
menuTrigger='click'
>
<MegaMenu />
</MenuInnerWithSub>
</>
)
}
@@ -0,0 +1,82 @@
import {FC, useEffect, useRef} from 'react'
import {useLocation} from 'react-router'
import clsx from 'clsx'
import {checkIsActive, KTIcon, WithChildren} from '../../../../helpers'
type Props = {
to: string
title: string
icon?: string
fontIcon?: string
menuTrigger?: 'click' | `{default:'click', lg: 'hover'}`
menuPlacement?: 'right-start' | 'bottom-start' | 'left-start'
hasArrow?: boolean
hasBullet?: boolean
isMega?: boolean
}
const MenuInnerWithSub: FC<Props & WithChildren> = ({
children,
to,
title,
icon,
fontIcon,
menuTrigger,
menuPlacement,
hasArrow = false,
hasBullet = false,
isMega = false,
}) => {
const menuItemRef = useRef<HTMLDivElement>(null)
const {pathname} = useLocation()
useEffect(() => {
if (menuItemRef.current && menuTrigger && menuPlacement) {
menuItemRef.current.setAttribute('data-kt-menu-trigger', menuTrigger)
menuItemRef.current.setAttribute('data-kt-menu-placement', menuPlacement)
}
}, [menuTrigger, menuPlacement])
return (
<div ref={menuItemRef} className='menu-item menu-lg-down-accordion me-lg-1'>
<span
className={clsx('menu-link py-3', {
active: checkIsActive(pathname, to),
})}
>
{hasBullet && (
<span className='menu-bullet'>
<span className='bullet bullet-dot'></span>
</span>
)}
{icon && (
<span className='menu-icon'>
<KTIcon iconName={icon} className='fs-2' />
</span>
)}
{fontIcon && (
<span className='menu-icon'>
<i className={clsx('bi fs-3', fontIcon)}></i>
</span>
)}
<span className='menu-title'>{title}</span>
{hasArrow && <span className='menu-arrow'></span>}
</span>
<div
className={clsx(
'menu-sub menu-sub-lg-down-accordion menu-sub-lg-dropdown',
isMega ? 'w-100 w-lg-850px p-5 p-lg-5' : 'menu-rounded-0 py-lg-4 w-lg-225px'
)}
data-kt-menu-dismiss='true'
>
{children}
</div>
</div>
)
}
export {MenuInnerWithSub}
@@ -0,0 +1,53 @@
import {FC} from 'react'
import {useLocation} from 'react-router'
import {Link} from 'react-router-dom'
import clsx from 'clsx'
import {checkIsActive, KTIcon} from '../../../../helpers'
type Props = {
to: string
title: string
icon?: string
fontIcon?: string
hasArrow?: boolean
hasBullet?: boolean
}
const MenuItem: FC<Props> = ({to, title, icon, fontIcon, hasArrow = false, hasBullet = false}) => {
const {pathname} = useLocation()
return (
<div className='menu-item me-lg-1'>
<Link
className={clsx('menu-link py-3', {
'active menu-here': checkIsActive(pathname, to),
})}
to={to}
>
{hasBullet && (
<span className='menu-bullet'>
<span className='bullet bullet-dot'></span>
</span>
)}
{icon && (
<span className='menu-icon'>
<KTIcon iconName={icon} className='fs-2' />
</span>
)}
{fontIcon && (
<span className='menu-icon'>
<i className={clsx('bi fs-3', fontIcon)}></i>
</span>
)}
<span className='menu-title'>{title}</span>
{hasArrow && <span className='menu-arrow'></span>}
</Link>
</div>
)
}
export {MenuItem}
@@ -0,0 +1 @@
export * from './MenuInner'
@@ -0,0 +1 @@
export * from './HeaderWrapper'
@@ -0,0 +1,57 @@
import {useEffect, useState} from 'react'
import {useLocation} from 'react-router-dom'
import {
DrawerComponent,
ScrollTopComponent,
StickyComponent,
ToggleComponent,
} from '../../../assets/ts/components'
import {KTIcon} from '../../../helpers'
export function ScrollTop() {
const {pathname} = useLocation()
const [initialized, setInintialized] = useState(false)
const pluginsReinitialization = () => {
setTimeout(() => {
StickyComponent.reInitialization()
setTimeout(() => {
ToggleComponent.reinitialization()
DrawerComponent.reinitialization()
}, 70)
}, 140)
}
const scrollTop = () => {
ScrollTopComponent.goTop()
}
const updateHeaderSticky = () => {
const stickyHeader = document.body.querySelectorAll(`[data-kt-sticky-name="header"]`)
if (stickyHeader && stickyHeader.length > 0) {
const sticky = StickyComponent.getInstance(stickyHeader[0] as HTMLElement)
if (sticky) {
sticky.update()
}
}
}
useEffect(() => {
if (!initialized) {
setInintialized(true)
} else {
pluginsReinitialization()
}
updateHeaderSticky()
setTimeout(() => {
scrollTop()
}, 0)
}, [initialized, pathname])
return (
<div id='kt_scrolltop' className='scrolltop' data-kt-scrolltop='true'>
<KTIcon iconName='arrow-up' />
</div>
)
}
@@ -0,0 +1 @@
export * from './ScrollTop'
@@ -0,0 +1,141 @@
/* eslint-disable no-prototype-builtins */
import clsx from 'clsx'
import {useEffect, useRef} from 'react'
import {ILayout, useLayout} from '../../core'
import {SidebarMenu} from './sidebar-menu/SidebarMenu'
import {SidebarFooter} from './SidebarFooter'
import {SidebarLogo} from './SidebarLogo'
const Sidebar = () => {
const {config} = useLayout()
const sidebarRef = useRef<HTMLDivElement>(null)
useEffect(() => {
updateDOM(config)
}, [config])
if (!config.app?.sidebar?.display) {
return null
}
return (
<>
{(config.layoutType === 'dark-sidebar' || config.layoutType === 'light-sidebar') && (
<div
ref={sidebarRef}
id='kt_app_sidebar'
className={clsx('app-sidebar', config.app?.sidebar?.default?.class)}
>
<SidebarLogo sidebarRef={sidebarRef} />
<SidebarMenu />
<SidebarFooter />
</div>
)}
</>
)
}
const updateDOM = (config: ILayout) => {
if (config.layoutType === 'dark-sidebar' || config.layoutType === 'light-sidebar') {
if (config.app?.sidebar?.default?.minimize?.desktop?.enabled) {
if (config.app?.sidebar?.default?.minimize?.desktop?.default) {
document.body.setAttribute('data-kt-app-sidebar-minimize', 'on')
}
if (config.app?.sidebar?.default?.minimize?.desktop?.hoverable) {
document.body.setAttribute('data-kt-app-sidebar-hoverable', 'true')
}
}
if (config.app?.sidebar?.default?.minimize?.mobile?.enabled) {
if (config.app?.sidebar?.default?.minimize?.mobile?.default) {
document.body.setAttribute('data-kt-app-sidebar-minimize-mobile', 'on')
}
if (config.app?.sidebar?.default?.minimize?.mobile?.hoverable) {
document.body.setAttribute('data-kt-app-sidebar-hoverable-mobile', 'true')
}
}
if (config.app?.sidebar?.default?.collapse?.desktop?.enabled) {
if (config.app?.sidebar?.default?.collapse?.desktop?.default) {
document.body.setAttribute('data-kt-app-sidebar-collapse', 'on')
}
}
if (config.app?.sidebar?.default?.collapse?.mobile?.enabled) {
if (config.app?.sidebar?.default?.collapse?.mobile?.default) {
document.body.setAttribute('data-kt-app-sidebar-collapse-mobile', 'on')
}
}
if (config.app?.sidebar?.default?.push) {
if (config.app?.sidebar?.default?.push?.header) {
document.body.setAttribute('data-kt-app-sidebar-push-header', 'true')
}
if (config.app?.sidebar?.default?.push?.toolbar) {
document.body.setAttribute('data-kt-app-sidebar-push-toolbar', 'true')
}
if (config.app?.sidebar?.default?.push?.footer) {
document.body.setAttribute('data-kt-app-sidebar-push-footer', 'true')
}
}
if (config.app?.sidebar?.default?.stacked) {
document.body.setAttribute('app-sidebar-stacked', 'true')
}
document.body.setAttribute('data-kt-app-sidebar-enabled', 'true')
document.body.setAttribute(
'data-kt-app-sidebar-fixed',
config.app?.sidebar?.default?.fixed?.desktop?.toString() || ''
)
const appSidebarDefaultDrawerEnabled = config.app?.sidebar?.default?.drawer?.enabled
let appSidebarDefaultDrawerAttributes: {[attrName: string]: string} = {}
if (appSidebarDefaultDrawerEnabled) {
appSidebarDefaultDrawerAttributes = config.app?.sidebar?.default?.drawer?.attributes as {
[attrName: string]: string
}
}
const appSidebarDefaultStickyEnabled = config.app?.sidebar?.default?.sticky?.enabled
let appSidebarDefaultStickyAttributes: {[attrName: string]: string} = {}
if (appSidebarDefaultStickyEnabled) {
appSidebarDefaultStickyAttributes = config.app?.sidebar?.default?.sticky?.attributes as {
[attrName: string]: string
}
}
setTimeout(() => {
const sidebarElement = document.getElementById('kt_app_sidebar')
// sidebar
if (sidebarElement) {
const sidebarAttributes = sidebarElement
.getAttributeNames()
.filter((t) => t.indexOf('data-') > -1)
sidebarAttributes.forEach((attr) => sidebarElement.removeAttribute(attr))
if (appSidebarDefaultDrawerEnabled) {
for (const key in appSidebarDefaultDrawerAttributes) {
if (appSidebarDefaultDrawerAttributes.hasOwnProperty(key)) {
sidebarElement.setAttribute(key, appSidebarDefaultDrawerAttributes[key])
}
}
}
if (appSidebarDefaultStickyEnabled) {
for (const key in appSidebarDefaultStickyAttributes) {
if (appSidebarDefaultStickyAttributes.hasOwnProperty(key)) {
sidebarElement.setAttribute(key, appSidebarDefaultStickyAttributes[key])
}
}
}
}
}, 0)
}
}
export {Sidebar}
@@ -0,0 +1,26 @@
import {KTIcon} from '../../../helpers'
const SidebarFooter = () => {
return (
<div>
</div>
// <div className='app-sidebar-footer flex-column-auto pt-2 pb-6 px-6' id='kt_app_sidebar_footer'>
// <a
// href={import.meta.env.VITE_APP_PREVIEW_DOCS_URL}
// target='_blank'
// className='btn btn-flex flex-center btn-custom btn-primary overflow-hidden text-nowrap px-0 h-40px w-100'
// data-bs-toggle='tooltip'
// data-bs-trigger='hover'
// data-bs-dismiss-='click'
// title='Metronic Docs & Components'
// >
// {/*<span className='btn-label'>Docs & Components</span>*/}
// <KTIcon iconName='document' className='btn-icon fs-2 m-0' />
// </a>
// </div>
)
}
export {SidebarFooter}
@@ -0,0 +1,101 @@
import {Link} from 'react-router-dom'
import clsx from 'clsx'
import {KTIcon, toAbsoluteUrl} from '../../../helpers'
import {useLayout} from '../../core'
import {MutableRefObject, useEffect, useRef} from 'react'
import {ToggleComponent} from '../../../assets/ts/components'
type PropsType = {
sidebarRef: MutableRefObject<HTMLDivElement | null>
}
const SidebarLogo = (props: PropsType) => {
const {config} = useLayout()
const toggleRef = useRef<HTMLDivElement>(null)
const appSidebarDefaultMinimizeDesktopEnabled =
config?.app?.sidebar?.default?.minimize?.desktop?.enabled
const appSidebarDefaultCollapseDesktopEnabled =
config?.app?.sidebar?.default?.collapse?.desktop?.enabled
const toggleType = appSidebarDefaultCollapseDesktopEnabled
? 'collapse'
: appSidebarDefaultMinimizeDesktopEnabled
? 'minimize'
: ''
const toggleState = appSidebarDefaultMinimizeDesktopEnabled ? 'active' : ''
const appSidebarDefaultMinimizeDefault = config.app?.sidebar?.default?.minimize?.desktop?.default
useEffect(() => {
setTimeout(() => {
const toggleObj = ToggleComponent.getInstance(toggleRef.current!) as ToggleComponent | null
if (toggleObj === null) {
return
}
// Add a class to prevent sidebar hover effect after toggle click
toggleObj.on('kt.toggle.change', function () {
// Set animation state
props.sidebarRef.current!.classList.add('animating')
// Wait till animation finishes
setTimeout(function () {
// Remove animation state
props.sidebarRef.current!.classList.remove('animating')
}, 300)
})
}, 600)
}, [toggleRef, props.sidebarRef])
return (
<div className='app-sidebar-logo px-6' id='kt_app_sidebar_logo'>
<Link to='/dashboard'>
{config.layoutType === 'dark-sidebar' ? (
<img
alt='Logo'
src={toAbsoluteUrl('media/logos/default-dark.svg')}
className='h-25px app-sidebar-logo-default'
/>
) : (
<>
<img
alt='Logo'
src={toAbsoluteUrl('media/logos/sidelogo.png')}
className='h-25px app-sidebar-logo-default theme-light-show'
/>
<img
alt='Logo'
src={toAbsoluteUrl('media/logos/default-dark.svg')}
className='h-25px app-sidebar-logo-default theme-dark-show'
/>
</>
)}
<img
alt='Logo'
src={toAbsoluteUrl('media/logos/default-small.svg')}
className='h-20px app-sidebar-logo-minimize'
/>
</Link>
{(appSidebarDefaultMinimizeDesktopEnabled || appSidebarDefaultCollapseDesktopEnabled) && (
<div
ref={toggleRef}
id='kt_app_sidebar_toggle'
className={clsx(
'app-sidebar-toggle btn btn-icon btn-shadow btn-sm btn-color-muted btn-active-color-primary h-30px w-30px position-absolute top-50 start-100 translate-middle rotate',
{active: appSidebarDefaultMinimizeDefault}
)}
data-kt-toggle='true'
data-kt-toggle-state={toggleState}
data-kt-toggle-target='body'
data-kt-toggle-name={`app-sidebar-${toggleType}`}
>
<KTIcon iconName='black-left-line' className='fs-3 rotate-180 ms-1' />
</div>
)}
</div>
)
}
export {SidebarLogo}
@@ -0,0 +1 @@
export * from './Sidebar'
@@ -0,0 +1,30 @@
import {SidebarMenuMain} from './SidebarMenuMain'
const SidebarMenu = () => {
return (
<div className='app-sidebar-menu overflow-hidden flex-column-fluid'>
<div
id='kt_app_sidebar_menu_wrapper'
className='app-sidebar-wrapper hover-scroll-overlay-y my-5'
data-kt-scroll='true'
data-kt-scroll-activate='true'
data-kt-scroll-height='auto'
data-kt-scroll-dependencies='#kt_app_sidebar_logo, #kt_app_sidebar_footer'
data-kt-scroll-wrappers='#kt_app_sidebar_menu'
data-kt-scroll-offset='5px'
data-kt-scroll-save-state='true'
>
<div
className='menu menu-column menu-rounded menu-sub-indention px-3'
id='#kt_app_sidebar_menu'
data-kt-menu='true'
data-kt-menu-expand='false'
>
<SidebarMenuMain />
</div>
</div>
</div>
)
}
export {SidebarMenu}
@@ -0,0 +1,53 @@
import {FC} from 'react'
import clsx from 'clsx'
import {Link} from 'react-router-dom'
import {useLocation} from 'react-router'
import {checkIsActive, KTIcon, WithChildren} from '../../../../helpers'
import {useLayout} from '../../../core'
type Props = {
to: string
title: string
icon?: string
fontIcon?: string
hasBullet?: boolean
}
const SidebarMenuItem: FC<Props & WithChildren> = ({
children,
to,
title,
icon,
fontIcon,
hasBullet = false,
}) => {
const {pathname} = useLocation()
const isActive = checkIsActive(pathname, to)
const {config} = useLayout()
const {app} = config
return (
<div className='menu-item'>
<Link className={clsx('menu-link without-sub', {active: isActive})} to={to}>
{hasBullet && (
<span className='menu-bullet'>
<span className='bullet bullet-dot'></span>
</span>
)}
{icon && app?.sidebar?.default?.menu?.iconType === 'svg' && (
<span className='menu-icon'>
{' '}
<KTIcon iconName={icon} className='fs-2' />
</span>
)}
{fontIcon && app?.sidebar?.default?.menu?.iconType === 'font' && (
<i className={clsx('bi fs-3', fontIcon)}></i>
)}
<span className='menu-title'>{title}</span>
</Link>
{children}
</div>
)
}
export {SidebarMenuItem}
@@ -0,0 +1,57 @@
import React from 'react'
import clsx from 'clsx'
import {useLocation} from 'react-router'
import {checkIsActive, KTIcon, WithChildren} from '../../../../helpers'
import {useLayout} from '../../../core'
type Props = {
to: string
title: string
icon?: string
fontIcon?: string
hasBullet?: boolean
}
const SidebarMenuItemWithSub: React.FC<Props & WithChildren> = ({
children,
to,
title,
icon,
fontIcon,
hasBullet,
}) => {
const {pathname} = useLocation()
const isActive = checkIsActive(pathname, to)
const {config} = useLayout()
const {app} = config
return (
<div
className={clsx('menu-item', {'here show': isActive}, 'menu-accordion')}
data-kt-menu-trigger='click'
>
<span className='menu-link'>
{hasBullet && (
<span className='menu-bullet'>
<span className='bullet bullet-dot'></span>
</span>
)}
{icon && app?.sidebar?.default?.menu?.iconType === 'svg' && (
<span className='menu-icon'>
<KTIcon iconName={icon} className='fs-2' />
</span>
)}
{fontIcon && app?.sidebar?.default?.menu?.iconType === 'font' && (
<i className={clsx('bi fs-3', fontIcon)}></i>
)}
<span className='menu-title'>{title}</span>
<span className='menu-arrow'></span>
</span>
<div className={clsx('menu-sub menu-sub-accordion', {'menu-active-bg': isActive})}>
{children}
</div>
</div>
)
}
export {SidebarMenuItemWithSub}
@@ -0,0 +1,121 @@
import {useIntl} from 'react-intl'
import {KTIcon} from '../../../../helpers'
import {SidebarMenuItemWithSub} from './SidebarMenuItemWithSub'
import {SidebarMenuItem} from './SidebarMenuItem'
const SidebarMenuMain = () => {
const intl = useIntl()
return (
<>
<SidebarMenuItem
to='/dashboard'
icon='element-11'
title={intl.formatMessage({id: 'MENU.DASHBOARD'})}
fontIcon='bi-app-indicator'
/>
{/*<SidebarMenuItem to='/builder' icon='switch' title='Layout Builder' fontIcon='bi-layers' />*/}
<div className='menu-item'>
<div className='menu-content pt-8 pb-2'>
<span className='menu-section text-muted text-uppercase fs-8 ls-1'>Crafted</span>
</div>
</div>
<SidebarMenuItemWithSub
to='/crafted/pages'
title='Pages'
fontIcon='bi-archive'
icon='element-plus'
>
<SidebarMenuItemWithSub to='/crafted/pages/profile' title='Profile' hasBullet={true}>
<SidebarMenuItem to='/crafted/pages/profile/overview' title='Overview' hasBullet={true} />
<SidebarMenuItem to='/crafted/pages/profile/projects' title='Projects' hasBullet={true} />
<SidebarMenuItem
to='/crafted/pages/profile/campaigns'
title='Campaigns'
hasBullet={true}
/>
<SidebarMenuItem
to='/crafted/pages/profile/documents'
title='Documents'
hasBullet={true}
/>
<SidebarMenuItem
to='/crafted/pages/profile/connections'
title='Connections'
hasBullet={true}
/>
</SidebarMenuItemWithSub>
<SidebarMenuItemWithSub to='/crafted/pages/wizards' title='Wizards' hasBullet={true}>
<SidebarMenuItem
to='/crafted/pages/wizards/horizontal'
title='Horizontal'
hasBullet={true}
/>
<SidebarMenuItem to='/crafted/pages/wizards/vertical' title='Vertical' hasBullet={true} />
</SidebarMenuItemWithSub>
</SidebarMenuItemWithSub>
<SidebarMenuItemWithSub
to='/crafted/accounts'
title='Accounts'
icon='profile-circle'
fontIcon='bi-person'
>
<SidebarMenuItem to='/crafted/account/overview' title='Overview' hasBullet={true} />
<SidebarMenuItem to='/crafted/account/settings' title='Settings' hasBullet={true} />
</SidebarMenuItemWithSub>
<SidebarMenuItemWithSub to='/error' title='Errors' fontIcon='bi-sticky' icon='cross-circle'>
<SidebarMenuItem to='/error/404' title='Error 404' hasBullet={true} />
<SidebarMenuItem to='/error/500' title='Error 500' hasBullet={true} />
</SidebarMenuItemWithSub>
<SidebarMenuItemWithSub
to='/crafted/widgets'
title='Widgets'
icon='element-7'
fontIcon='bi-layers'
>
<SidebarMenuItem to='/crafted/widgets/lists' title='Lists' hasBullet={true} />
<SidebarMenuItem to='/crafted/widgets/statistics' title='Statistics' hasBullet={true} />
<SidebarMenuItem to='/crafted/widgets/charts' title='Charts' hasBullet={true} />
<SidebarMenuItem to='/crafted/widgets/mixed' title='Mixed' hasBullet={true} />
<SidebarMenuItem to='/crafted/widgets/tables' title='Tables' hasBullet={true} />
<SidebarMenuItem to='/crafted/widgets/feeds' title='Feeds' hasBullet={true} />
</SidebarMenuItemWithSub>
<div className='menu-item'>
<div className='menu-content pt-8 pb-2'>
<span className='menu-section text-muted text-uppercase fs-8 ls-1'>Apps</span>
</div>
</div>
<SidebarMenuItemWithSub
to='/apps/chat'
title='Chat'
fontIcon='bi-chat-left'
icon='message-text-2'
>
<SidebarMenuItem to='/apps/chat/private-chat' title='Private Chat' hasBullet={true} />
<SidebarMenuItem to='/apps/chat/group-chat' title='Group Chart' hasBullet={true} />
<SidebarMenuItem to='/apps/chat/drawer-chat' title='Drawer Chart' hasBullet={true} />
</SidebarMenuItemWithSub>
<SidebarMenuItem
to='/apps/user-management/users'
icon='abstract-28'
title='User management'
fontIcon='bi-layers'
/>
{/*<div className='menu-item'>*/}
{/* <a*/}
{/* target='_blank'*/}
{/* className='menu-link'*/}
{/* href={import.meta.env.VITE_APP_PREVIEW_DOCS_URL + '/changelog'}*/}
{/* >*/}
{/* <span className='menu-icon'>*/}
{/* <KTIcon iconName='code' className='fs-2' />*/}
{/* </span>*/}
{/* <span className='menu-title'>Changelog {import.meta.env.VITE_APP_VERSION}</span>*/}
{/* </a>*/}
{/*</div>*/}
</>
)
}
export {SidebarMenuMain}
@@ -0,0 +1,102 @@
/* eslint-disable no-prototype-builtins */
import {useEffect} from 'react'
import {ILayout, useLayout} from '../../core'
import {
ToolbarAccounting,
ToolbarClassic,
ToolbarExtended,
ToolbarReports,
ToolbarSaas,
} from './toolbars'
const Toolbar = () => {
const {config} = useLayout()
useEffect(() => {
updateDOM(config)
document.body.setAttribute('data-kt-app-toolbar-enabled', 'true')
}, [config])
switch (config.app?.toolbar?.layout) {
case 'classic':
return <ToolbarClassic />
case 'accounting':
return <ToolbarAccounting />
case 'extended':
return <ToolbarExtended />
case 'reports':
return <ToolbarReports />
case 'saas':
return <ToolbarSaas />
default:
return <ToolbarClassic />
}
}
const updateDOM = (config: ILayout) => {
let appToolbarSwapAttributes: {[attrName: string]: string} = {}
const appToolbarSwapEnabled = config.app?.toolbar?.swap?.enabled
if (appToolbarSwapEnabled) {
appToolbarSwapAttributes = config.app?.toolbar?.swap?.attributes as {[attrName: string]: string}
}
let appToolbarStickyAttributes: {[attrName: string]: string} = {}
const appToolbarStickyEnabled = config.app?.toolbar?.sticky?.enabled
if (appToolbarStickyEnabled) {
appToolbarStickyAttributes = config.app?.toolbar?.sticky?.attributes as {
[attrName: string]: string
}
let appToolbarMinimizeAttributes: {[attrName: string]: string} = {}
const appToolbarMinimizeEnabled = config.app?.toolbar?.minimize?.enabled
if (appToolbarMinimizeEnabled) {
appToolbarMinimizeAttributes = config.app?.toolbar?.minimize?.attributes as {
[attrName: string]: string
}
}
if (config.app?.toolbar?.fixed?.desktop) {
document.body.setAttribute('data-kt-app-toolbar-fixed', 'true')
}
if (config.app?.toolbar?.fixed?.mobile) {
document.body.setAttribute('data-kt-app-toolbar-fixed-mobile', 'true')
}
setTimeout(() => {
const toolbarElement = document.getElementById('kt_app_toolbar')
// toolbar
if (toolbarElement) {
const toolbarAttributes = toolbarElement
.getAttributeNames()
.filter((t) => t.indexOf('data-') > -1)
toolbarAttributes.forEach((attr) => toolbarElement.removeAttribute(attr))
if (appToolbarSwapEnabled) {
for (const key in appToolbarSwapAttributes) {
if (appToolbarSwapAttributes.hasOwnProperty(key)) {
toolbarElement.setAttribute(key, appToolbarSwapAttributes[key])
}
}
}
if (appToolbarStickyEnabled) {
for (const key in appToolbarStickyAttributes) {
if (appToolbarStickyAttributes.hasOwnProperty(key)) {
toolbarElement.setAttribute(key, appToolbarStickyAttributes[key])
}
}
}
if (appToolbarMinimizeEnabled) {
for (const key in appToolbarMinimizeAttributes) {
if (appToolbarMinimizeAttributes.hasOwnProperty(key)) {
toolbarElement.setAttribute(key, appToolbarMinimizeAttributes[key])
}
}
}
}
}, 0)
}
}
export {Toolbar}
@@ -0,0 +1,51 @@
import clsx from 'clsx'
import {ToolbarType, useLayout} from '../../core'
import {Toolbar} from './Toolbar'
import {PageTitleWrapper} from './page-title'
const ToolbarWrapper = () => {
const {config, classes} = useLayout()
if (!config.app?.toolbar?.display) {
return null
}
const isPageTitleVisible = showPageTitle(
config.app?.toolbar?.layout,
config.app?.pageTitle?.display
)
return (
<div
id='kt_app_toolbar'
className={clsx('app-toolbar', classes.toolbar.join(' '), config?.app?.toolbar?.class)}
>
<div
id='kt_app_toolbar_container'
className={clsx(
'app-container',
classes.toolbarContainer.join(' '),
config.app?.toolbar?.containerClass,
config.app?.toolbar?.minimize?.enabled ? 'app-toolbar-minimize' : '',
{
'container-fluid': config.app?.toolbar?.container === 'fluid',
'container-xxl': config.app?.toolbar?.container === 'fixed',
}
)}
>
{isPageTitleVisible && <PageTitleWrapper />}
<Toolbar />
</div>
</div>
)
}
const showPageTitle = (appToolbarLayout?: ToolbarType, appPageTitleDisplay?: boolean): boolean => {
const viewsWithPageTitles = ['classic', 'reports', 'saas']
if (!appToolbarLayout || !appPageTitleDisplay) {
return false
}
return appPageTitleDisplay && viewsWithPageTitles.some((t) => t === appToolbarLayout)
}
export {ToolbarWrapper}
@@ -0,0 +1 @@
export * from './ToolbarWrapper'
@@ -0,0 +1,86 @@
import clsx from 'clsx'
import {Link} from 'react-router-dom'
import {useLayout} from '../../../core'
import {usePageData} from '../../../core/PageData'
const PageTitle = () => {
const {pageTitle, pageDescription, pageBreadcrumbs} = usePageData()
const {config, classes} = useLayout()
const appPageTitleDirection = config.app?.pageTitle?.direction
return (
<div
id='kt_page_title'
data-kt-swapper='true'
data-kt-swapper-mode='prepend'
data-kt-swapper-parent="{default: '#kt_content_container', 'lg': '#kt_toolbar_container'}"
className={clsx(
'page-title d-flex flex-wrap me-3',
classes.pageTitle.join(' '),
config.app?.pageTitle?.class,
{
'flex-column justify-content-center': appPageTitleDirection === 'column',
'align-items-center': appPageTitleDirection !== 'column',
}
)}
>
{/* begin::Title */}
{config.app?.pageTitle?.display && pageTitle && (
<h1
className={clsx('page-heading d-flex text-gray-900 fw-bold fs-3 my-0', {
'flex-column justify-content-center': appPageTitleDirection,
'align-items-center': !appPageTitleDirection,
})}
>
{pageTitle}
{pageDescription && config.app?.pageTitle && config.app?.pageTitle?.description && (
<span
className={clsx('page-desc text-muted fs-7 fw-semibold', {
'pt-2': appPageTitleDirection === 'column',
})}
>
{config.app?.pageTitle?.direction === 'row' && (
<span className='h-20px border-1 border-gray-300 border-start ms-3 mx-2'></span>
)}
{pageDescription}{' '}
</span>
)}
</h1>
)}
{/* end::Title */}
{pageBreadcrumbs &&
pageBreadcrumbs.length > 0 &&
config.app?.pageTitle &&
config.app?.pageTitle?.breadCrumb && (
<>
{config.app?.pageTitle?.direction === 'row' && (
<span className='h-20px border-gray-300 border-start mx-4'></span>
)}
<ul className='breadcrumb breadcrumb-separatorless fw-semibold fs-7 my-0'>
{Array.from(pageBreadcrumbs).map((item, index) => (
<li
className={clsx('breadcrumb-item', {
'text-gray-900': !item.isSeparator && item.isActive,
'text-muted': !item.isSeparator && !item.isActive,
})}
key={`${item.path}${index}`}
>
{!item.isSeparator ? (
<Link className='text-muted text-hover-primary' to={item.path}>
{item.title}
</Link>
) : (
<span className='bullet bg-gray-500 w-5px h-2px'></span>
)}
</li>
))}
<li className='breadcrumb-item text-gray-900'>{pageTitle}</li>
</ul>
</>
)}
</div>
)
}
export {PageTitle}
@@ -0,0 +1,13 @@
import {useLayout} from '../../../core'
import {PageTitle} from './PageTitle'
const PageTitleWrapper = () => {
const {config} = useLayout()
if (!config.app?.pageTitle?.display) {
return null
}
return <PageTitle />
}
export {PageTitleWrapper}
@@ -0,0 +1 @@
export * from './PageTitleWrapper'
@@ -0,0 +1,139 @@
import {FC, useEffect, useState} from 'react'
import {KTIcon} from '../../../../helpers'
const ToolbarAccounting: FC = () => {
const [progress, setProgress] = useState<string>('1')
const [filter, setFilter] = useState<string>('1')
useEffect(() => {
document.body.setAttribute('data-kt-app-toolbar-fixed', 'true')
}, [])
return (
<>
<div className='d-flex align-items-center me-5'>
{/* begin::Input group */}
<div className='d-flex align-items-center flex-shrink-0'>
{/* begin::Label */}
<span className='fs-7 text-gray-700 fw-bold pe-3 d-none d-md-block'>Actions:</span>
{/* end::Label */}
{/* begin::Actions */}
<div className='d-flex flex-shrink-0'>
{/* begin::Button */}
<div
data-bs-toggle='tooltip'
data-bs-placement='top'
data-bs-trigger='hover'
title='Add a team member'
>
<a href='#' className='btn btn-sm btn-icon btn-active-color-success'>
<KTIcon iconName='plus-square' className='fs-2x' />
</a>
</div>
{/* end::Button */}
{/* begin::Button */}
<div
data-bs-toggle='tooltip'
data-bs-placement='top'
data-bs-trigger='hover'
title='Create new account'
>
<a href='#' className='btn btn-sm btn-icon btn-active-color-success'>
<KTIcon iconName='minus-square' className='fs-2x' />
</a>
</div>
{/* end::Button */}
{/* begin::Button */}
<div
data-bs-toggle='tooltip'
data-bs-placement='top'
data-bs-trigger='hover'
title='Invite friends'
>
<a href='#' className='btn btn-sm btn-icon btn-active-color-success'>
<KTIcon iconName='dots-square' className='fs-2x' />
</a>
</div>
{/* end::Button */}
</div>
{/* end::Actions */}
</div>
{/* end::Input group */}
{/* begin::Input group */}
<div className='d-flex align-items-center flex-shrink-0'>
{/* begin::Desktop separartor */}
<div className='bullet bg-secondary h-35px w-1px mx-5'></div>
{/* end::Desktop separartor */}
{/* begin::Label */}
<span className='fs-7 text-gray-700 fw-bold pe-4 ps-1 d-none d-md-block'>Progress:</span>
{/* end::Label */}
<div className='progress w-100px w-xl-150px w-xxl-300px h-25px bg-light-success'>
<div
className='progress-bar rounded bg-success fs-7 fw-bold'
role='progressbar'
style={{width: '72%'}}
aria-valuenow={72}
aria-valuemin={0}
aria-valuemax={100}
>
72%
</div>
</div>
</div>
{/* end::Input group */}
{/* end::Toolbar start */}
</div>
{/* begin::Toolbar end */}
<div className='d-flex align-items-center'>
{/* begin::Input group */}
<div className='me-3'>
{/* begin::Select */}
<select
className='form-select form-select-sm form-select-solid'
data-control='select2'
data-placeholder='Latest'
data-hide-search='true'
value={progress}
onChange={(e) => setProgress(e.target.value)}
>
<option value=''></option>
<option value='1'>Today 16 Feb</option>
<option value='2'>In Progress</option>
<option value='3'>Done</option>
</select>
{/* end::Select */}
</div>
{/* end::Input group- */}
{/* begin::Input group- */}
<div className='m-0'>
{/* begin::Select */}
<select
className='form-select form-select-sm form-select-solid w-md-125px'
data-control='select2'
data-placeholder='Filters'
data-hide-search='true'
value={filter}
onChange={(e) => setFilter(e.target.value)}
>
<option value=''></option>
<option value='1'>Filters</option>
<option value='2'>In Progress</option>
<option value='3'>Done</option>
</select>
{/* end::Content */}
</div>
{/* end::Input group- */}
</div>
</>
)
}
export {ToolbarAccounting}
@@ -0,0 +1,66 @@
import clsx from 'clsx'
import {useState} from 'react'
import {KTIcon} from '../../../../helpers'
import {CreateAppModal, Dropdown1} from '../../../../partials'
import {useLayout} from '../../../core'
const ToolbarClassic = () => {
const {config} = useLayout()
const [showCreateAppModal, setShowCreateAppModal] = useState<boolean>(false)
const daterangepickerButtonClass = config.app?.toolbar?.fixed?.desktop
? 'btn-light'
: 'bg-body btn-color-gray-700 btn-active-color-primary'
return (
<div className='d-flex align-items-center gap-2 gap-lg-3'>
{config.app?.toolbar?.filterButton && (
<div className='m-0'>
<a
href='#'
className={clsx('btn btn-sm btn-flex fw-bold', daterangepickerButtonClass)}
data-kt-menu-trigger='click'
data-kt-menu-placement='bottom-end'
>
<KTIcon iconName='filter' className='fs-6 text-muted me-1' />
Filter
</a>
<Dropdown1 />
</div>
)}
{config.app?.toolbar?.daterangepickerButton && (
<div
data-kt-daterangepicker='true'
data-kt-daterangepicker-opens='left'
className={clsx(
'btn btn-sm fw-bold d-flex align-items-center px-4',
daterangepickerButtonClass
)}
>
<div className='text-gray-600 fw-bold'>Loading date range...</div>
<KTIcon iconName='calendar-8' className='fs-1 ms-2 me-0' />
</div>
)}
{config.app?.toolbar?.secondaryButton && (
<a href='#' className='btn btn-sm btn-flex btn-light fw-bold'>
Filter
</a>
)}
{config.app?.toolbar?.primaryButton && (
<a
href='#'
onClick={() => setShowCreateAppModal(true)}
className='btn btn-sm fw-bold btn-primary'
>
Create
</a>
)}
<CreateAppModal show={showCreateAppModal} handleClose={() => setShowCreateAppModal(false)} />
</div>
)
}
export {ToolbarClassic}
@@ -0,0 +1,154 @@
import {FC, useEffect, useState} from 'react'
import {KTIcon, toAbsoluteUrl} from '../../../../helpers'
const ToolbarExtended: FC = () => {
const [progress, setProgress] = useState<string>('1')
const [search, setSearch] = useState<string>('')
useEffect(() => {
document.body.setAttribute('data-kt-app-toolbar-fixed', 'true')
}, [])
return (
<>
<div className='d-flex align-items-center flex-shrink-0 me-5'>
{/* begin::Label */}
<span className='fs-7 fw-bold text-gray-700 pe-4 d-none d-md-block'>Team:</span>
{/* end::Label */}
{/* begin::Users */}
<div className='symbol-group symbol-hover flex-shrink-0 me-2'>
{/* begin::User */}
<div className='symbol symbol-circle symbol-35px'>
<div className='symbol-label fw-bold bg-warning text-inverse-warning'>A</div>
</div>
{/* end::User */}
{/* begin::User */}
<div className='symbol symbol-circle symbol-35px'>
<img src={toAbsoluteUrl('media/avatars/300-1.jpg')} alt='' />
</div>
{/* end::User */}
{/* begin::User */}
<div className='symbol symbol-circle symbol-35px'>
<img src={toAbsoluteUrl('media/avatars/300-2.jpg')} alt='' />
</div>
{/* end::User */}
{/* begin::User */}
<div className='symbol symbol-circle symbol-35px'>
<div className='symbol-label fw-bold bg-primary text-inverse-primary'>S</div>
</div>
{/* end::User */}
{/* begin::User */}
<div className='symbol symbol-circle symbol-35px'>
<img src={toAbsoluteUrl('media/avatars/300-5.jpg')} alt='' />
</div>
{/* end::User */}
{/* begin::User */}
<div className='symbol symbol-circle symbol-35px'>
<div className='symbol-label fw-bold bg-danger text-inverse-danger'>P</div>
</div>
{/* end::User */}
{/* begin::User */}
<div className='symbol symbol-circle symbol-35px'>
<img src={toAbsoluteUrl('media/avatars/300-20.jpg')} alt='' />
</div>
{/* end::User */}
</div>
{/* end::Users */}
{/* begin::Button */}
<div
data-bs-toggle='tooltip'
data-bs-placement='top'
data-bs-trigger='hover'
title='Invite a team member'
>
<a href='#' className='btn btn-sm btn-icon'>
<KTIcon iconName='plus-square' className='fs-2hx text-success' />
</a>
</div>
</div>
{/* end::Button */}
{/* end::Toolbar start */}
{/* begin::Toolbar end */}
<div className='d-flex align-items-center overflow-auto'>
{/* begin::Search */}
<div className='position-relative my-1'>
<KTIcon
iconName='magnifier'
className='fs-3 text-gray-500 position-absolute top-50 translate-middle ps-10'
/>
<input
type='text'
className='form-control form-control-sm form-control-solid w-150px ps-10'
name='Search Team'
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder='Search Team'
/>
</div>
{/* end::Search */}
{/* begin::Separartor */}
<div className='bullet bg-secondary h-35px w-1px mx-6'></div>
{/* end::Separartor */}
{/* begin::Label */}
<span className='fs-7 fw-bold text-gray-700 flex-shrink-0 pe-4 d-none d-md-block'>
Sort By:
</span>
{/* end::Label */}
{/* begin::Select */}
<select
className='form-select form-select-sm w-125px form-select-solid me-6'
data-control='select2'
data-placeholder='Latest'
data-hide-search='true'
value={progress}
onChange={(e) => setProgress(e.target.value)}
>
<option value=''></option>
<option value='1'>Latest</option>
<option value='2'>In Progress</option>
<option value='3'>Done</option>
</select>
{/* end::Select */}
{/* begin::Actions */}
<div className='d-flex align-items-center'>
<button
type='button'
className='btn btn-sm btn-icon btn-light-primary me-3'
data-bs-toggle='tooltip'
data-bs-placement='top'
title='Enable grid view'
>
<KTIcon iconName='element-11' className='fs-3 text-primary' />
</button>
<button
type='button'
className='btn btn-sm btn-icon btn-light'
data-bs-toggle='tooltip'
data-bs-placement='top'
title='Enable row view'
>
<KTIcon iconName='row-horizontal' className='fs-3 text-gray-500' />
</button>
</div>
{/* end::Actions */}
</div>
</>
)
}
export {ToolbarExtended}
@@ -0,0 +1,115 @@
import {useEffect, useState} from 'react'
import {KTIcon} from '../../../../helpers'
const ToolbarReports = () => {
const [progress, setProgress] = useState<string>('1')
useEffect(() => {
document.body.setAttribute('data-kt-app-toolbar-fixed', 'true')
}, [])
return (
<div className='d-flex align-items-center overflow-auto'>
{/* begin::Wrapper */}
<div className='d-flex align-items-center flex-shrink-0'>
{/* begin::Label */}
<span className='fs-7 fw-bold text-gray-700 flex-shrink-0 pe-4 d-none d-md-block'>
Filter By:
</span>
{/* end::Label */}
<div className='flex-shrink-0 '>
<ul className='nav'>
<li className='nav-item'>
<a
className='nav-link btn btn-sm btn-color-muted btn-active-color-primary btn-active-light active fw-semibold fs-7 px-4 me-1'
data-bs-toggle='tab'
href='#'
>
Today
</a>
</li>
<li className='nav-item'>
<a
className='nav-link btn btn-sm btn-color-muted btn-active-color-primary btn-active-light fw-semibold fs-7 px-4 me-1'
data-bs-toggle='tab'
href=''
>
Week
</a>
</li>
<li className='nav-item'>
<a
className='nav-link btn btn-sm btn-color-muted btn-active-color-primary btn-active-light fw-semibold fs-7 px-4'
data-bs-toggle='tab'
href='#'
>
Day
</a>
</li>
</ul>
</div>
</div>
{/* end::Wrapper */}
{/* begin::Separartor */}
<div className='bullet bg-secondary h-35px w-1px mx-5'></div>
{/* end::Separartor */}
{/* begin::Wrapper */}
<div className='d-flex align-items-center'>
{/* begin::Label */}
<span className='fs-7 fw-bold text-gray-700 flex-shrink-0 pe-4 d-none d-md-block'>
Sort By:
</span>
{/* end::Label */}
{/* begin::Select */}
<select
className='form-select form-select-sm w-md-125px form-select-solid'
data-control='select2'
data-placeholder='Latest'
data-hide-search='true'
value={progress}
onChange={(e) => setProgress(e.target.value)}
>
<option value=''></option>
<option value='1'>Latest</option>
<option value='2'>In Progress</option>
<option value='3'>Done</option>
</select>
{/* end::Select */}
{/* begin::Actions */}
<div className='d-flex align-items-center ms-3'>
<button
type='button'
className='btn btn-sm btn-icon btn-light-primary me-3'
data-bs-toggle='tooltip'
data-bs-placement='top'
title='Enable grid view'
>
<KTIcon iconName='element-11' className='fs-2 text-primary' />
</button>
<button
type='button'
className='btn btn-sm btn-icon btn-light'
data-bs-toggle='tooltip'
data-bs-placement='top'
title='Enable row view'
>
<KTIcon iconName='abstract-14' className=' fs-2 text-gray-500' />
</button>
</div>
{/* end::Actions */}
</div>
{/* end::Wrapper */}
</div>
)
}
export {ToolbarReports}
@@ -0,0 +1,126 @@
import {FC, useEffect, useState} from 'react'
import {KTIcon} from '../../../../helpers'
const ToolbarSaas: FC = () => {
const [progress, setProgress] = useState<string>('1')
useEffect(() => {
document.body.setAttribute('data-kt-app-toolbar-fixed', 'true')
}, [])
return (
<div className='d-flex align-items-center gap-2'>
{/* begin::Action wrapper */}
<div className='d-flex align-items-center'>
{/* begin::Label */}
<span className='fs-7 fw-bold text-gray-700 pe-4 text-nowrap d-none d-md-block'>
Sort By:
</span>
{/* end::Label */}
{/* begin::Select */}
<select
className='form-select form-select-sm form-select-solid w-100px w-xxl-125px'
data-control='select2'
data-placeholder='Latest'
data-hide-search='true'
onChange={(e) => setProgress(e.target.value)}
value={progress}
>
<option value=''></option>
<option value='1'>Latest</option>
<option value='2'>In Progress</option>
<option value='3'>Done</option>
</select>
{/* end::Select */}
</div>
{/* end::Action wrapper */}
{/* begin::Action wrapper */}
<div className='d-flex align-items-center'>
{/* begin::Separartor */}
<div className='bullet bg-secondary h-35px w-1px mx-5'></div>
{/* end::Separartor */}
{/* begin::Label */}
<span className='fs-7 text-gray-700 fw-bold'>Impact Level:</span>
{/* end::Label */}
{/* begin::NoUiSlider */}
<div className='d-flex align-items-center ps-4'>
<div
id='kt_app_toolbar_slider'
className='noUi-target noUi-target-success w-75px w-xxl-150px noUi-sm'
></div>
<span
id='kt_app_toolbar_slider_value'
className='d-flex flex-center bg-light-success rounded-circle w-35px h-35px ms-4 fs-7 fw-bold text-success'
data-bs-toggle='tooltip'
data-bs-placement='top'
title='Set impact level'
></span>
</div>
{/* end::NoUiSlider */}
{/* begin::Separartor */}
<div className='bullet bg-secondary h-35px w-1px mx-5'></div>
{/* end::Separartor */}
</div>
{/* end::Action wrapper */}
{/* begin::Action wrapper */}
<div className='d-flex align-items-center'>
{/* begin::Label */}
<span className='fs-7 text-gray-700 fw-bold pe-3 d-none d-md-block'>Quick Tools:</span>
{/* end::Label */}
{/* begin::Actions */}
<div className='d-flex'>
{/* begin::Action */}
<a
href='#'
className='btn btn-sm btn-icon btn-icon-muted btn-active-icon-success'
data-bs-toggle='tooltip'
data-bs-trigger='hover'
data-bs-placement='top'
title='Add new page'
>
<KTIcon iconName='files' className='fs-2x' />
</a>
{/* end::Action */}
{/* begin::Action */}
<a
href='#'
className='btn btn-sm btn-icon btn-icon-muted btn-active-icon-success'
data-bs-toggle='tooltip'
data-bs-trigger='hover'
data-bs-placement='top'
title='Add new category'
>
<KTIcon iconName='add-files' className='fs-2x' />
</a>
{/* end::Action */}
{/* begin::Action */}
<a
href='#'
className='btn btn-sm btn-icon btn-icon-muted btn-active-icon-success'
data-bs-toggle='tooltip'
data-bs-trigger='hover'
data-bs-placement='top'
title='Add new section'
>
<KTIcon iconName='search-list' className='fs-2x' />
</a>
{/* end::Action */}
</div>
{/* end::Actions */}
</div>
{/* end::Action wrapper */}
</div>
)
}
export {ToolbarSaas}
@@ -0,0 +1,5 @@
export * from './ToolbarAccounting'
export * from './ToolbarClassic'
export * from './ToolbarExtended'
export * from './ToolbarReports'
export * from './ToolbarSaas'