From d04452093f886902562324641a0966c864e9cd6c Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 10:41:56 +0000 Subject: [PATCH 1/2] Migrate design library from Bootstrap/CoreUI to Material UI - Replace CoreUI components with Material UI equivalents - Update layout components (DefaultLayout, AppHeader, AppSidebar, AppFooter) - Update navigation components (AppSidebarNav, AppBreadcrumb, AppContent) - Migrate Dashboard view and widgets to Material UI - Migrate authentication pages (Login, Register, 404, 500) - Replace @coreui/icons with @mui/icons-material - Replace @coreui/react-chartjs with react-chartjs-2 - Update theme configuration to use MUI ThemeProvider - Add MUI dependencies and remove CoreUI dependencies --- package.json | 16 +- src/App.js | 122 +++-- src/_nav.js | 148 ++--- src/components/AppBreadcrumb.js | 35 +- src/components/AppContent.js | 17 +- src/components/AppFooter.js | 47 +- src/components/AppHeader.js | 240 ++++----- src/components/AppSidebar.js | 128 +++-- src/components/AppSidebarNav.js | 192 +++++-- src/components/header/AppHeaderDropdown.js | 206 ++++--- src/layout/DefaultLayout.js | 28 +- src/views/dashboard/Dashboard.js | 596 ++++++++++----------- src/views/dashboard/MainChart.js | 245 +++++---- src/views/pages/login/Login.js | 181 ++++--- src/views/pages/page404/Page404.js | 82 +-- src/views/pages/page500/Page500.js | 82 +-- src/views/pages/register/Register.js | 160 +++--- src/views/widgets/WidgetsBrand.js | 339 ++++++------ src/views/widgets/WidgetsDropdown.js | 591 ++++++++------------ 19 files changed, 1780 insertions(+), 1675 deletions(-) diff --git a/package.json b/package.json index fccb0aebe9..9c4709b678 100644 --- a/package.json +++ b/package.json @@ -19,24 +19,20 @@ "start": "vite" }, "dependencies": { - "@coreui/chartjs": "^4.1.0", - "@coreui/coreui": "^5.5.0", - "@coreui/icons": "^3.0.1", - "@coreui/icons-react": "^2.3.0", - "@coreui/react": "^5.9.2", - "@coreui/react-chartjs": "^3.0.0", - "@coreui/utils": "^2.0.2", - "@popperjs/core": "^2.11.8", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^7.3.7", + "@mui/material": "^7.3.7", "chart.js": "^4.5.1", "classnames": "^2.5.1", "core-js": "^3.47.0", "prop-types": "^15.8.1", "react": "^19.2.3", + "react-chartjs-2": "^5.3.1", "react-dom": "^19.2.3", "react-redux": "^9.2.0", "react-router-dom": "^7.11.0", - "redux": "5.0.1", - "simplebar-react": "^3.3.2" + "redux": "5.0.1" }, "devDependencies": { "@vitejs/plugin-react": "^5.1.2", diff --git a/src/App.js b/src/App.js index f5b22393e1..f520e6ffa5 100644 --- a/src/App.js +++ b/src/App.js @@ -1,58 +1,100 @@ -import React, { Suspense, useEffect } from 'react' +import React, { Suspense, useMemo, useState } from 'react' import { HashRouter, Route, Routes } from 'react-router-dom' import { useSelector } from 'react-redux' +import { ThemeProvider, createTheme } from '@mui/material/styles' +import CssBaseline from '@mui/material/CssBaseline' +import CircularProgress from '@mui/material/CircularProgress' +import Box from '@mui/material/Box' -import { CSpinner, useColorModes } from '@coreui/react' -import './scss/style.scss' - -// We use those styles to show code examples, you should remove them in your application. -import './scss/examples.scss' - -// Containers const DefaultLayout = React.lazy(() => import('./layout/DefaultLayout')) -// Pages const Login = React.lazy(() => import('./views/pages/login/Login')) const Register = React.lazy(() => import('./views/pages/register/Register')) const Page404 = React.lazy(() => import('./views/pages/page404/Page404')) const Page500 = React.lazy(() => import('./views/pages/page500/Page500')) +const getInitialMode = (storedTheme) => { + const urlParams = new URLSearchParams(window.location.href.split('?')[1]) + const urlTheme = urlParams.get('theme')?.match(/^[A-Za-z0-9\s]+/)?.[0] + if (urlTheme && (urlTheme === 'light' || urlTheme === 'dark')) { + return urlTheme + } + return storedTheme || 'light' +} + const App = () => { - const { isColorModeSet, setColorMode } = useColorModes('coreui-free-react-admin-template-theme') const storedTheme = useSelector((state) => state.theme) + const [mode] = useState(() => getInitialMode(storedTheme)) - useEffect(() => { - const urlParams = new URLSearchParams(window.location.href.split('?')[1]) - const theme = urlParams.get('theme') && urlParams.get('theme').match(/^[A-Za-z0-9\s]+/)[0] - if (theme) { - setColorMode(theme) - } - - if (isColorModeSet()) { - return - } - - setColorMode(storedTheme) - }, []) // eslint-disable-line react-hooks/exhaustive-deps + const theme = useMemo( + () => + createTheme({ + palette: { + mode, + primary: { + main: '#321fdb', + }, + secondary: { + main: '#9da5b1', + }, + success: { + main: '#2eb85c', + }, + info: { + main: '#39f', + }, + warning: { + main: '#f9b115', + }, + error: { + main: '#e55353', + }, + }, + typography: { + fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', + }, + components: { + MuiDrawer: { + styleOverrides: { + paper: { + backgroundColor: mode === 'dark' ? '#1e1e2d' : '#3c4b64', + color: 'rgba(255, 255, 255, 0.87)', + }, + }, + }, + }, + }), + [mode], + ) return ( - - - - - } - > - - } /> - } /> - } /> - } /> - } /> - - - + + + + + + + } + > + + } /> + } /> + } /> + } /> + } /> + + + + ) } diff --git a/src/_nav.js b/src/_nav.js index e43f1df1ee..bda4fa0c3e 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -1,74 +1,63 @@ import React from 'react' -import CIcon from '@coreui/icons-react' -import { - cilBell, - cilCalculator, - cilChartPie, - cilCursor, - cilDescription, - cilDrop, - cilExternalLink, - cilNotes, - cilPencil, - cilPuzzle, - cilSpeedometer, - cilStar, -} from '@coreui/icons' -import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react' +import DashboardIcon from '@mui/icons-material/Dashboard' +import PaletteIcon from '@mui/icons-material/Palette' +import TextFieldsIcon from '@mui/icons-material/TextFields' +import ExtensionIcon from '@mui/icons-material/Extension' +import TouchAppIcon from '@mui/icons-material/TouchApp' +import NotesIcon from '@mui/icons-material/Notes' +import PieChartIcon from '@mui/icons-material/PieChart' +import StarIcon from '@mui/icons-material/Star' +import NotificationsIcon from '@mui/icons-material/Notifications' +import CalculateIcon from '@mui/icons-material/Calculate' +import DescriptionIcon from '@mui/icons-material/Description' +import OpenInNewIcon from '@mui/icons-material/OpenInNew' const _nav = [ { - component: CNavItem, name: 'Dashboard', to: '/dashboard', - icon: , + icon: , badge: { color: 'info', text: 'NEW', }, }, { - component: CNavTitle, + title: true, name: 'Theme', }, { - component: CNavItem, name: 'Colors', to: '/theme/colors', - icon: , + icon: , }, { - component: CNavItem, name: 'Typography', to: '/theme/typography', - icon: , + icon: , }, { - component: CNavTitle, + title: true, name: 'Components', }, { - component: CNavGroup, name: 'Base', to: '/base', - icon: , + icon: , items: [ { - component: CNavItem, name: 'Accordion', to: '/base/accordion', }, { - component: CNavItem, name: 'Breadcrumb', to: '/base/breadcrumbs', }, { - component: CNavItem, name: ( {'Calendar'} - + ), href: 'https://coreui.io/react/docs/components/calendar/', @@ -78,52 +67,42 @@ const _nav = [ }, }, { - component: CNavItem, name: 'Cards', to: '/base/cards', }, { - component: CNavItem, name: 'Carousel', to: '/base/carousels', }, { - component: CNavItem, name: 'Collapse', to: '/base/collapses', }, { - component: CNavItem, name: 'List group', to: '/base/list-groups', }, { - component: CNavItem, name: 'Navs & Tabs', to: '/base/navs', }, { - component: CNavItem, name: 'Pagination', to: '/base/paginations', }, { - component: CNavItem, name: 'Placeholders', to: '/base/placeholders', }, { - component: CNavItem, name: 'Popovers', to: '/base/popovers', }, { - component: CNavItem, name: 'Progress', to: '/base/progress', }, { - component: CNavItem, name: 'Smart Pagination', href: 'https://coreui.io/react/docs/components/smart-pagination/', badge: { @@ -132,11 +111,10 @@ const _nav = [ }, }, { - component: CNavItem, name: ( {'Smart Table'} - + ), href: 'https://coreui.io/react/docs/components/smart-table/', @@ -146,31 +124,26 @@ const _nav = [ }, }, { - component: CNavItem, name: 'Spinners', to: '/base/spinners', }, { - component: CNavItem, name: 'Tables', to: '/base/tables', }, { - component: CNavItem, name: 'Tabs', to: '/base/tabs', }, { - component: CNavItem, name: 'Tooltips', to: '/base/tooltips', }, { - component: CNavItem, name: ( {'Virtual Scroller'} - + ), href: 'https://coreui.io/react/docs/components/virtual-scroller/', @@ -182,32 +155,27 @@ const _nav = [ ], }, { - component: CNavGroup, name: 'Buttons', to: '/buttons', - icon: , + icon: , items: [ { - component: CNavItem, name: 'Buttons', to: '/buttons/buttons', }, { - component: CNavItem, name: 'Buttons groups', to: '/buttons/button-groups', }, { - component: CNavItem, name: 'Dropdowns', to: '/buttons/dropdowns', }, { - component: CNavItem, name: ( {'Loading Button'} - + ), href: 'https://coreui.io/react/docs/components/loading-button/', @@ -219,16 +187,14 @@ const _nav = [ ], }, { - component: CNavGroup, name: 'Forms', - icon: , + icon: , items: [ { - component: CNavItem, name: ( {'Autocomplete'} - + ), href: 'https://coreui.io/react/docs/forms/autocomplete/', @@ -238,16 +204,14 @@ const _nav = [ }, }, { - component: CNavItem, name: 'Checks & Radios', to: '/forms/checks-radios', }, { - component: CNavItem, name: ( {'Date Picker'} - + ), href: 'https://coreui.io/react/docs/forms/date-picker/', @@ -257,7 +221,6 @@ const _nav = [ }, }, { - component: CNavItem, name: 'Date Range Picker', href: 'https://coreui.io/react/docs/forms/date-range-picker/', badge: { @@ -266,26 +229,22 @@ const _nav = [ }, }, { - component: CNavItem, name: 'Floating Labels', to: '/forms/floating-labels', }, { - component: CNavItem, name: 'Form Control', to: '/forms/form-control', }, { - component: CNavItem, name: 'Input Group', to: '/forms/input-group', }, { - component: CNavItem, name: ( {'Multi Select'} - + ), href: 'https://coreui.io/react/docs/forms/multi-select/', @@ -295,11 +254,10 @@ const _nav = [ }, }, { - component: CNavItem, name: ( {'OTP Input'} - + ), href: 'https://coreui.io/react/docs/forms/one-time-password-input/', @@ -309,11 +267,10 @@ const _nav = [ }, }, { - component: CNavItem, name: ( {'Password Input'} - + ), href: 'https://coreui.io/react/docs/forms/password-input/', @@ -323,16 +280,14 @@ const _nav = [ }, }, { - component: CNavItem, name: 'Range', to: '/forms/range', }, { - component: CNavItem, name: ( {'Range Slider'} - + ), href: 'https://coreui.io/react/docs/forms/range-slider/', @@ -342,11 +297,10 @@ const _nav = [ }, }, { - component: CNavItem, name: ( {'Rating'} - + ), href: 'https://coreui.io/react/docs/forms/rating/', @@ -356,16 +310,14 @@ const _nav = [ }, }, { - component: CNavItem, name: 'Select', to: '/forms/select', }, { - component: CNavItem, name: ( {'Stepper'} - + ), href: 'https://coreui.io/react/docs/forms/stepper/', @@ -375,11 +327,10 @@ const _nav = [ }, }, { - component: CNavItem, name: ( {'Time Picker'} - + ), href: 'https://coreui.io/react/docs/forms/time-picker/', @@ -389,118 +340,99 @@ const _nav = [ }, }, { - component: CNavItem, name: 'Layout', to: '/forms/layout', }, { - component: CNavItem, name: 'Validation', to: '/forms/validation', }, ], }, { - component: CNavItem, name: 'Charts', to: '/charts', - icon: , + icon: , }, { - component: CNavGroup, name: 'Icons', - icon: , + icon: , items: [ { - component: CNavItem, name: 'CoreUI Free', to: '/icons/coreui-icons', }, { - component: CNavItem, name: 'CoreUI Flags', to: '/icons/flags', }, { - component: CNavItem, name: 'CoreUI Brands', to: '/icons/brands', }, ], }, { - component: CNavGroup, name: 'Notifications', - icon: , + icon: , items: [ { - component: CNavItem, name: 'Alerts', to: '/notifications/alerts', }, { - component: CNavItem, name: 'Badges', to: '/notifications/badges', }, { - component: CNavItem, name: 'Modal', to: '/notifications/modals', }, { - component: CNavItem, name: 'Toasts', to: '/notifications/toasts', }, ], }, { - component: CNavItem, name: 'Widgets', to: '/widgets', - icon: , + icon: , badge: { color: 'info', text: 'NEW', }, }, { - component: CNavTitle, + title: true, name: 'Extras', }, { - component: CNavGroup, name: 'Pages', - icon: , + icon: , items: [ { - component: CNavItem, name: 'Login', to: '/login', }, { - component: CNavItem, name: 'Register', to: '/register', }, { - component: CNavItem, name: 'Error 404', to: '/404', }, { - component: CNavItem, name: 'Error 500', to: '/500', }, ], }, { - component: CNavItem, name: 'Docs', href: 'https://coreui.io/react/docs/templates/installation/', - icon: , + icon: , }, ] diff --git a/src/components/AppBreadcrumb.js b/src/components/AppBreadcrumb.js index d37de8ce9b..61e550c02a 100644 --- a/src/components/AppBreadcrumb.js +++ b/src/components/AppBreadcrumb.js @@ -1,10 +1,12 @@ import React from 'react' -import { useLocation } from 'react-router-dom' +import { useLocation, Link as RouterLink } from 'react-router-dom' +import Breadcrumbs from '@mui/material/Breadcrumbs' +import Link from '@mui/material/Link' +import Typography from '@mui/material/Typography' +import HomeIcon from '@mui/icons-material/Home' import routes from '../routes' -import { CBreadcrumb, CBreadcrumbItem } from '@coreui/react' - const AppBreadcrumb = () => { const currentLocation = useLocation().pathname @@ -32,19 +34,28 @@ const AppBreadcrumb = () => { const breadcrumbs = getBreadcrumbs(currentLocation) return ( - - Home + + + + Home + {breadcrumbs.map((breadcrumb, index) => { - return ( - + return breadcrumb.active ? ( + + {breadcrumb.name} + + ) : ( + {breadcrumb.name} - + ) })} - + ) } diff --git a/src/components/AppContent.js b/src/components/AppContent.js index b9a39ef505..0e9df3ad01 100644 --- a/src/components/AppContent.js +++ b/src/components/AppContent.js @@ -1,14 +1,21 @@ import React, { Suspense } from 'react' import { Navigate, Route, Routes } from 'react-router-dom' -import { CContainer, CSpinner } from '@coreui/react' +import Container from '@mui/material/Container' +import CircularProgress from '@mui/material/CircularProgress' +import Box from '@mui/material/Box' -// routes config import routes from '../routes' const AppContent = () => { return ( - - }> + + + + + } + > {routes.map((route, idx) => { return ( @@ -26,7 +33,7 @@ const AppContent = () => { } /> - + ) } diff --git a/src/components/AppFooter.js b/src/components/AppFooter.js index 217c5a04c3..113fa5e1f3 100644 --- a/src/components/AppFooter.js +++ b/src/components/AppFooter.js @@ -1,22 +1,43 @@ import React from 'react' -import { CFooter } from '@coreui/react' +import Box from '@mui/material/Box' +import Typography from '@mui/material/Typography' +import Link from '@mui/material/Link' const AppFooter = () => { return ( - -
- + + + CoreUI - - © 2025 creativeLabs. -
- -
+ + + ) } diff --git a/src/components/AppHeader.js b/src/components/AppHeader.js index 534dadaa89..5f62027fad 100644 --- a/src/components/AppHeader.js +++ b/src/components/AppHeader.js @@ -1,144 +1,138 @@ -import React, { useEffect, useRef } from 'react' +import React, { useState } from 'react' import { NavLink } from 'react-router-dom' import { useSelector, useDispatch } from 'react-redux' -import { - CContainer, - CDropdown, - CDropdownItem, - CDropdownMenu, - CDropdownToggle, - CHeader, - CHeaderNav, - CHeaderToggler, - CNavLink, - CNavItem, - useColorModes, -} from '@coreui/react' -import CIcon from '@coreui/icons-react' -import { - cilBell, - cilContrast, - cilEnvelopeOpen, - cilList, - cilMenu, - cilMoon, - cilSun, -} from '@coreui/icons' +import PropTypes from 'prop-types' +import AppBar from '@mui/material/AppBar' +import Toolbar from '@mui/material/Toolbar' +import IconButton from '@mui/material/IconButton' +import Typography from '@mui/material/Typography' +import Box from '@mui/material/Box' +import Menu from '@mui/material/Menu' +import MenuItem from '@mui/material/MenuItem' +import Badge from '@mui/material/Badge' +import Divider from '@mui/material/Divider' +import Button from '@mui/material/Button' +import MenuIcon from '@mui/icons-material/Menu' +import NotificationsIcon from '@mui/icons-material/Notifications' +import MailIcon from '@mui/icons-material/Mail' +import ListIcon from '@mui/icons-material/List' +import LightModeIcon from '@mui/icons-material/LightMode' +import DarkModeIcon from '@mui/icons-material/DarkMode' +import ContrastIcon from '@mui/icons-material/Contrast' import { AppBreadcrumb } from './index' import { AppHeaderDropdown } from './header/index' -const AppHeader = () => { - const headerRef = useRef() - const { colorMode, setColorMode } = useColorModes('coreui-free-react-admin-template-theme') +const AppHeader = ({ drawerWidth }) => { + const [colorMode, setColorMode] = useState('light') + const [anchorEl, setAnchorEl] = useState(null) const dispatch = useDispatch() const sidebarShow = useSelector((state) => state.sidebarShow) - useEffect(() => { - const handleScroll = () => { - headerRef.current && - headerRef.current.classList.toggle('shadow-sm', document.documentElement.scrollTop > 0) - } + const handleThemeMenuOpen = (event) => { + setAnchorEl(event.currentTarget) + } - document.addEventListener('scroll', handleScroll) - return () => document.removeEventListener('scroll', handleScroll) - }, []) + const handleThemeMenuClose = () => { + setAnchorEl(null) + } + + const handleThemeChange = (mode) => { + setColorMode(mode) + handleThemeMenuClose() + } return ( - - - + + dispatch({ type: 'set', sidebarShow: !sidebarShow })} - style={{ marginInlineStart: '-14px' }} + sx={{ mr: 2, display: { sm: 'none' } }} > - - - - - - Dashboard - - - - Users - - - Settings - - - - - - - - - - - - - - - - - - - - -
  • -
    -
  • - - - {colorMode === 'dark' ? ( - - ) : colorMode === 'auto' ? ( - - ) : ( - - )} - - - setColorMode('light')} - > - Light - - setColorMode('dark')} - > - Dark - - setColorMode('auto')} - > - Auto - - - -
  • -
    -
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {colorMode === 'dark' ? ( + + ) : colorMode === 'auto' ? ( + + ) : ( + + )} + + + handleThemeChange('light')}> + Light + + handleThemeChange('dark')}> + Dark + + handleThemeChange('auto')}> + Auto + + + + + -
    -
    - + + + - -
    + + ) } +AppHeader.propTypes = { + drawerWidth: PropTypes.number, +} + export default AppHeader diff --git a/src/components/AppSidebar.js b/src/components/AppSidebar.js index 021cb52c34..74d0f3ed0e 100644 --- a/src/components/AppSidebar.js +++ b/src/components/AppSidebar.js @@ -1,59 +1,101 @@ import React from 'react' import { useSelector, useDispatch } from 'react-redux' - -import { - CCloseButton, - CSidebar, - CSidebarBrand, - CSidebarFooter, - CSidebarHeader, - CSidebarToggler, -} from '@coreui/react' -import CIcon from '@coreui/icons-react' +import PropTypes from 'prop-types' +import Drawer from '@mui/material/Drawer' +import Box from '@mui/material/Box' +import Typography from '@mui/material/Typography' +import IconButton from '@mui/material/IconButton' +import Divider from '@mui/material/Divider' +import ChevronLeftIcon from '@mui/icons-material/ChevronLeft' +import ChevronRightIcon from '@mui/icons-material/ChevronRight' import { AppSidebarNav } from './AppSidebarNav' -import { logo } from 'src/assets/brand/logo' -import { sygnet } from 'src/assets/brand/sygnet' - -// sidebar nav config import navigation from '../_nav' -const AppSidebar = () => { +const AppSidebar = ({ drawerWidth }) => { const dispatch = useDispatch() const unfoldable = useSelector((state) => state.sidebarUnfoldable) const sidebarShow = useSelector((state) => state.sidebarShow) - return ( - { - dispatch({ type: 'set', sidebarShow: visible }) - }} - > - - - - - - dispatch({ type: 'set', sidebarShow: false })} - /> - + const handleDrawerClose = () => { + dispatch({ type: 'set', sidebarShow: false }) + } + + const handleToggleUnfoldable = () => { + dispatch({ type: 'set', sidebarUnfoldable: !unfoldable }) + } + + const drawerContent = ( + <> + + + CoreUI + + + + + + - - dispatch({ type: 'set', sidebarUnfoldable: !unfoldable })} - /> - - + + + + + {unfoldable ? : } + + + ) + + return ( + + + {drawerContent} + + + {drawerContent} + + + ) +} + +AppSidebar.propTypes = { + drawerWidth: PropTypes.number, } export default React.memo(AppSidebar) diff --git a/src/components/AppSidebarNav.js b/src/components/AppSidebarNav.js index 7583abf49e..6a82670c6b 100644 --- a/src/components/AppSidebarNav.js +++ b/src/components/AppSidebarNav.js @@ -1,70 +1,150 @@ -import React from 'react' +import React, { useState } from 'react' import { NavLink } from 'react-router-dom' import PropTypes from 'prop-types' +import List from '@mui/material/List' +import ListItem from '@mui/material/ListItem' +import ListItemButton from '@mui/material/ListItemButton' +import ListItemIcon from '@mui/material/ListItemIcon' +import ListItemText from '@mui/material/ListItemText' +import Collapse from '@mui/material/Collapse' +import Chip from '@mui/material/Chip' +import Typography from '@mui/material/Typography' +import Box from '@mui/material/Box' +import ExpandLess from '@mui/icons-material/ExpandLess' +import ExpandMore from '@mui/icons-material/ExpandMore' +import FiberManualRecordIcon from '@mui/icons-material/FiberManualRecord' -import SimpleBar from 'simplebar-react' -import 'simplebar-react/dist/simplebar.min.css' +const NavItemComponent = ({ item, indent = false }) => { + const { name, badge, icon, to, href } = item -import { CBadge, CNavLink, CSidebarNav } from '@coreui/react' + const content = ( + + + {icon ? icon : indent ? : null} + + + {badge && ( + + )} + + ) -export const AppSidebarNav = ({ items }) => { - const navLink = (name, icon, badge, indent = false) => { - return ( - <> - {icon - ? icon - : indent && ( - - - - )} - {name && name} - {badge && ( - - {badge.text} - - )} - - ) - } + return {content} +} + +NavItemComponent.propTypes = { + item: PropTypes.object.isRequired, + indent: PropTypes.bool, +} + +const NavGroupComponent = ({ item }) => { + const [open, setOpen] = useState(false) + const { name, icon, items } = item - const navItem = (item, index, indent = false) => { - const { component, name, badge, icon, ...rest } = item - const Component = component - return ( - - {rest.to || rest.href ? ( - - {navLink(name, icon, badge, indent)} - - ) : ( - navLink(name, icon, badge, indent) - )} - - ) + const handleClick = () => { + setOpen(!open) } - const navGroup = (item, index) => { - const { component, name, icon, items, to, ...rest } = item - const Component = component - return ( - - {items?.map((item, index) => - item.items ? navGroup(item, index) : navItem(item, index, true), - )} - - ) + return ( + <> + + + {icon} + + {open ? : } + + + + + {items?.map((subItem, index) => + subItem.items ? ( + + ) : ( + + ), + )} + + + + ) +} + +NavGroupComponent.propTypes = { + item: PropTypes.object.isRequired, +} + +const NavTitleComponent = ({ item }) => { + return ( + + + {item.name} + + + ) +} + +NavTitleComponent.propTypes = { + item: PropTypes.object.isRequired, +} + +export const AppSidebarNav = ({ items }) => { + const renderNavItem = (item, index) => { + if (item.items) { + return + } + if (item.component?.displayName === 'CNavTitle' || item.title) { + return + } + return } return ( - - {items && - items.map((item, index) => (item.items ? navGroup(item, index) : navItem(item, index)))} - + + {items && items.map((item, index) => renderNavItem(item, index))} + ) } diff --git a/src/components/header/AppHeaderDropdown.js b/src/components/header/AppHeaderDropdown.js index 30c0df82ba..35bfbc7526 100644 --- a/src/components/header/AppHeaderDropdown.js +++ b/src/components/header/AppHeaderDropdown.js @@ -1,95 +1,127 @@ -import React from 'react' -import { - CAvatar, - CBadge, - CDropdown, - CDropdownDivider, - CDropdownHeader, - CDropdownItem, - CDropdownMenu, - CDropdownToggle, -} from '@coreui/react' -import { - cilBell, - cilCreditCard, - cilCommentSquare, - cilEnvelopeOpen, - cilFile, - cilLockLocked, - cilSettings, - cilTask, - cilUser, -} from '@coreui/icons' -import CIcon from '@coreui/icons-react' +import React, { useState } from 'react' +import Avatar from '@mui/material/Avatar' +import IconButton from '@mui/material/IconButton' +import Menu from '@mui/material/Menu' +import MenuItem from '@mui/material/MenuItem' +import ListItemIcon from '@mui/material/ListItemIcon' +import ListItemText from '@mui/material/ListItemText' +import Divider from '@mui/material/Divider' +import Typography from '@mui/material/Typography' +import Badge from '@mui/material/Badge' +import Box from '@mui/material/Box' +import NotificationsIcon from '@mui/icons-material/Notifications' +import MailIcon from '@mui/icons-material/Mail' +import TaskIcon from '@mui/icons-material/Task' +import CommentIcon from '@mui/icons-material/Comment' +import PersonIcon from '@mui/icons-material/Person' +import SettingsIcon from '@mui/icons-material/Settings' +import CreditCardIcon from '@mui/icons-material/CreditCard' +import FolderIcon from '@mui/icons-material/Folder' +import LockIcon from '@mui/icons-material/Lock' import avatar8 from './../../assets/images/avatars/8.jpg' const AppHeaderDropdown = () => { + const [anchorEl, setAnchorEl] = useState(null) + const open = Boolean(anchorEl) + + const handleClick = (event) => { + setAnchorEl(event.currentTarget) + } + + const handleClose = () => { + setAnchorEl(null) + } + return ( - - - - - - Account - - - Updates - - 42 - - - - - Messages - - 42 - - - - - Tasks - - 42 - - - - - Comments - - 42 - - - Settings - - - Profile - - - - Settings - - - - Payments - - 42 - - - - - Projects - - 42 - - - - - - Lock Account - - - + <> + + + + + + + Account + + + + + + + Updates + + + + + + + Messages + + + + + + + Tasks + + + + + + + Comments + + + + + Settings + + + + + + + Profile + + + + + + Settings + + + + + + Payments + + + + + + + Projects + + + + + + + + Lock Account + + + ) } diff --git a/src/layout/DefaultLayout.js b/src/layout/DefaultLayout.js index 19fbf225fd..cfc29c6ae5 100644 --- a/src/layout/DefaultLayout.js +++ b/src/layout/DefaultLayout.js @@ -1,18 +1,30 @@ import React from 'react' +import Box from '@mui/material/Box' import { AppContent, AppSidebar, AppFooter, AppHeader } from '../components/index' +const drawerWidth = 256 + const DefaultLayout = () => { return ( -
    - -
    - -
    + + + + + -
    + -
    -
    +
    + ) } diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index 57a55290d9..ab895e76f5 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -1,47 +1,29 @@ import React from 'react' -import classNames from 'classnames' - -import { - CAvatar, - CButton, - CButtonGroup, - CCard, - CCardBody, - CCardFooter, - CCardHeader, - CCol, - CProgress, - CRow, - CTable, - CTableBody, - CTableDataCell, - CTableHead, - CTableHeaderCell, - CTableRow, -} from '@coreui/react' -import CIcon from '@coreui/icons-react' -import { - cibCcAmex, - cibCcApplePay, - cibCcMastercard, - cibCcPaypal, - cibCcStripe, - cibCcVisa, - cibGoogle, - cibFacebook, - cibLinkedin, - cifBr, - cifEs, - cifFr, - cifIn, - cifPl, - cifUs, - cibTwitter, - cilCloudDownload, - cilPeople, - cilUser, - cilUserFemale, -} from '@coreui/icons' +import Box from '@mui/material/Box' +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import CardHeader from '@mui/material/CardHeader' +import Grid from '@mui/material/Grid' +import Typography from '@mui/material/Typography' +import Button from '@mui/material/Button' +import ButtonGroup from '@mui/material/ButtonGroup' +import LinearProgress from '@mui/material/LinearProgress' +import Table from '@mui/material/Table' +import TableBody from '@mui/material/TableBody' +import TableCell from '@mui/material/TableCell' +import TableContainer from '@mui/material/TableContainer' +import TableHead from '@mui/material/TableHead' +import TableRow from '@mui/material/TableRow' +import Avatar from '@mui/material/Avatar' +import Divider from '@mui/material/Divider' +import CloudDownloadIcon from '@mui/icons-material/CloudDownload' +import PeopleIcon from '@mui/icons-material/People' +import PersonIcon from '@mui/icons-material/Person' +import Person2Icon from '@mui/icons-material/Person2' +import GoogleIcon from '@mui/icons-material/Google' +import FacebookIcon from '@mui/icons-material/Facebook' +import TwitterIcon from '@mui/icons-material/Twitter' +import LinkedInIcon from '@mui/icons-material/LinkedIn' import avatar1 from 'src/assets/images/avatars/1.jpg' import avatar2 from 'src/assets/images/avatars/2.jpg' @@ -54,6 +36,15 @@ import WidgetsBrand from '../widgets/WidgetsBrand' import WidgetsDropdown from '../widgets/WidgetsDropdown' import MainChart from './MainChart' +const colorMap = { + success: 'success', + info: 'info', + warning: 'warning', + danger: 'error', + primary: 'primary', + secondary: 'secondary', +} + const Dashboard = () => { const progressExample = [ { title: 'Visits', value: '29.703 Users', percent: 40, color: 'success' }, @@ -74,313 +65,320 @@ const Dashboard = () => { ] const progressGroupExample2 = [ - { title: 'Male', icon: cilUser, value: 53 }, - { title: 'Female', icon: cilUserFemale, value: 43 }, + { title: 'Male', icon: , value: 53 }, + { title: 'Female', icon: , value: 43 }, ] const progressGroupExample3 = [ - { title: 'Organic Search', icon: cibGoogle, percent: 56, value: '191,235' }, - { title: 'Facebook', icon: cibFacebook, percent: 15, value: '51,223' }, - { title: 'Twitter', icon: cibTwitter, percent: 11, value: '37,564' }, - { title: 'LinkedIn', icon: cibLinkedin, percent: 8, value: '27,319' }, + { title: 'Organic Search', icon: , percent: 56, value: '191,235' }, + { title: 'Facebook', icon: , percent: 15, value: '51,223' }, + { title: 'Twitter', icon: , percent: 11, value: '37,564' }, + { title: 'LinkedIn', icon: , percent: 8, value: '27,319' }, ] const tableExample = [ { avatar: { src: avatar1, status: 'success' }, - user: { - name: 'Yiorgos Avraamu', - new: true, - registered: 'Jan 1, 2023', - }, - country: { name: 'USA', flag: cifUs }, - usage: { - value: 50, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'success', - }, - payment: { name: 'Mastercard', icon: cibCcMastercard }, + user: { name: 'Yiorgos Avraamu', new: true, registered: 'Jan 1, 2023' }, + country: { name: 'USA', flag: '🇺🇸' }, + usage: { value: 50, period: 'Jun 11, 2023 - Jul 10, 2023', color: 'success' }, + payment: { name: 'Mastercard' }, activity: '10 sec ago', }, { avatar: { src: avatar2, status: 'danger' }, - user: { - name: 'Avram Tarasios', - new: false, - registered: 'Jan 1, 2023', - }, - country: { name: 'Brazil', flag: cifBr }, - usage: { - value: 22, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'info', - }, - payment: { name: 'Visa', icon: cibCcVisa }, + user: { name: 'Avram Tarasios', new: false, registered: 'Jan 1, 2023' }, + country: { name: 'Brazil', flag: '🇧🇷' }, + usage: { value: 22, period: 'Jun 11, 2023 - Jul 10, 2023', color: 'info' }, + payment: { name: 'Visa' }, activity: '5 minutes ago', }, { avatar: { src: avatar3, status: 'warning' }, user: { name: 'Quintin Ed', new: true, registered: 'Jan 1, 2023' }, - country: { name: 'India', flag: cifIn }, - usage: { - value: 74, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'warning', - }, - payment: { name: 'Stripe', icon: cibCcStripe }, + country: { name: 'India', flag: '🇮🇳' }, + usage: { value: 74, period: 'Jun 11, 2023 - Jul 10, 2023', color: 'warning' }, + payment: { name: 'Stripe' }, activity: '1 hour ago', }, { avatar: { src: avatar4, status: 'secondary' }, user: { name: 'Enéas Kwadwo', new: true, registered: 'Jan 1, 2023' }, - country: { name: 'France', flag: cifFr }, - usage: { - value: 98, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'danger', - }, - payment: { name: 'PayPal', icon: cibCcPaypal }, + country: { name: 'France', flag: '🇫🇷' }, + usage: { value: 98, period: 'Jun 11, 2023 - Jul 10, 2023', color: 'danger' }, + payment: { name: 'PayPal' }, activity: 'Last month', }, { avatar: { src: avatar5, status: 'success' }, - user: { - name: 'Agapetus Tadeáš', - new: true, - registered: 'Jan 1, 2023', - }, - country: { name: 'Spain', flag: cifEs }, - usage: { - value: 22, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'primary', - }, - payment: { name: 'Google Wallet', icon: cibCcApplePay }, + user: { name: 'Agapetus Tadeáš', new: true, registered: 'Jan 1, 2023' }, + country: { name: 'Spain', flag: '🇪🇸' }, + usage: { value: 22, period: 'Jun 11, 2023 - Jul 10, 2023', color: 'primary' }, + payment: { name: 'Google Wallet' }, activity: 'Last week', }, { avatar: { src: avatar6, status: 'danger' }, - user: { - name: 'Friderik Dávid', - new: true, - registered: 'Jan 1, 2023', - }, - country: { name: 'Poland', flag: cifPl }, - usage: { - value: 43, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'success', - }, - payment: { name: 'Amex', icon: cibCcAmex }, + user: { name: 'Friderik Dávid', new: true, registered: 'Jan 1, 2023' }, + country: { name: 'Poland', flag: '🇵🇱' }, + usage: { value: 43, period: 'Jun 11, 2023 - Jul 10, 2023', color: 'success' }, + payment: { name: 'Amex' }, activity: 'Last week', }, ] return ( - <> - - - - - -

    + + + + + + + + Traffic -

    -
    January - July 2023
    -
    - - - - - + + + January - July 2023 + + + + + {['Day', 'Month', 'Year'].map((value) => ( - + ))} - - -
    + + + -
    - - - {progressExample.map((item, index, items) => ( - + + + + {progressExample.map((item, index) => ( + -
    {item.title}
    -
    + + {item.title} + + {item.value} ({item.percent}%) -
    - -
    + + + ))} -
    -
    -
    - - - - - Traffic {' & '} Sales - - - - - -
    -
    New Clients
    -
    9,123
    -
    -
    - -
    -
    - Recurring Clients -
    -
    22,643
    -
    -
    -
    -
    - {progressGroupExample1.map((item, index) => ( -
    -
    - {item.title} -
    -
    - - -
    -
    - ))} -
    - - - -
    -
    Pageviews
    -
    78,623
    -
    -
    - -
    -
    Organic
    -
    49,123
    -
    -
    -
    + + + -
    - - {progressGroupExample2.map((item, index) => ( -
    -
    - - {item.title} - {item.value}% -
    -
    - -
    -
    - ))} - -
    - - {progressGroupExample3.map((item, index) => ( -
    -
    - - {item.title} - - {item.value}{' '} - ({item.percent}%) - -
    -
    - -
    -
    - ))} -
    -
    + -
    + + + + + + + + + + New Clients + + + 9,123 + + + + + + + Recurring Clients + + + 22,643 + + + + + + {progressGroupExample1.map((item, index) => ( + + + {item.title} + + + + + ))} + + + + + + + Pageviews + + + 78,623 + + + + + + + Organic + + + 49,123 + + + + + + {progressGroupExample2.map((item, index) => ( + + + {item.icon} + + {item.title} + + + {item.value}% + + + + + ))} + + {progressGroupExample3.map((item, index) => ( + + + {item.icon} + + {item.title} + + + {item.value}{' '} + + ({item.percent}%) + + + + + + ))} + + - - - - - - - User - + + + + + + + + + User + Country - - Usage - + + Usage + Payment Method - - Activity - - - + + Activity + + + {tableExample.map((item, index) => ( - - - - - -
    {item.user.name}
    -
    - {item.user.new ? 'New' : 'Recurring'} | Registered:{' '} - {item.user.registered} -
    -
    - - - - -
    -
    {item.usage.value}%
    -
    - {item.usage.period} -
    -
    - -
    - - - - -
    Last login
    -
    {item.activity}
    -
    -
    + + + + + + {item.user.name} + + {item.user.new ? 'New' : 'Recurring'} | Registered: {item.user.registered} + + + + {item.country.flag} + + + + + {item.usage.value}% + + + {item.usage.period} + + + + + + {item.payment.name} + + + + Last login + + + {item.activity} + + + ))} - - - - - - - +
    +
    +
    +
    +
    +
    + ) } diff --git a/src/views/dashboard/MainChart.js b/src/views/dashboard/MainChart.js index 98b7eec3cf..2e16792e2d 100644 --- a/src/views/dashboard/MainChart.js +++ b/src/views/dashboard/MainChart.js @@ -1,136 +1,133 @@ -import React, { useEffect, useRef } from 'react' +import React, { useMemo } from 'react' +import { useTheme } from '@mui/material/styles' +import Box from '@mui/material/Box' +import { Line } from 'react-chartjs-2' +import { + Chart as ChartJS, + CategoryScale, + LinearScale, + PointElement, + LineElement, + Title, + Tooltip, + Legend, + Filler, +} from 'chart.js' -import { CChartLine } from '@coreui/react-chartjs' -import { getStyle } from '@coreui/utils' +ChartJS.register( + CategoryScale, + LinearScale, + PointElement, + LineElement, + Title, + Tooltip, + Legend, + Filler, +) -const MainChart = () => { - const chartRef = useRef(null) +const generateRandomData = (count, min, max) => { + const data = [] + for (let i = 0; i < count; i++) { + data.push(Math.floor(Math.random() * (max - min + 1)) + min) + } + return data +} - useEffect(() => { - const handleColorSchemeChange = () => { - if (chartRef.current) { - setTimeout(() => { - chartRef.current.options.scales.x.grid.borderColor = getStyle( - '--cui-border-color-translucent', - ) - chartRef.current.options.scales.x.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.x.ticks.color = getStyle('--cui-body-color') - chartRef.current.options.scales.y.grid.borderColor = getStyle( - '--cui-border-color-translucent', - ) - chartRef.current.options.scales.y.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.y.ticks.color = getStyle('--cui-body-color') - chartRef.current.update() - }) - } - } +const initialData1 = generateRandomData(7, 50, 200) +const initialData2 = generateRandomData(7, 50, 200) - document.documentElement.addEventListener('ColorSchemeChange', handleColorSchemeChange) - return () => - document.documentElement.removeEventListener('ColorSchemeChange', handleColorSchemeChange) - }, [chartRef]) +const MainChart = () => { + const theme = useTheme() - const random = (min = 0, max = 100) => Math.floor(Math.random() * (max - min + 1)) + min + const data = useMemo( + () => ({ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'My First dataset', + backgroundColor: + theme.palette.mode === 'dark' ? 'rgba(57, 153, 255, 0.1)' : 'rgba(57, 153, 255, 0.1)', + borderColor: theme.palette.info.main, + pointHoverBackgroundColor: theme.palette.info.main, + borderWidth: 2, + data: initialData1, + fill: true, + }, + { + label: 'My Second dataset', + backgroundColor: 'transparent', + borderColor: theme.palette.success.main, + pointHoverBackgroundColor: theme.palette.success.main, + borderWidth: 2, + data: initialData2, + }, + { + label: 'My Third dataset', + backgroundColor: 'transparent', + borderColor: theme.palette.error.main, + pointHoverBackgroundColor: theme.palette.error.main, + borderWidth: 1, + borderDash: [8, 5], + data: [65, 65, 65, 65, 65, 65, 65], + }, + ], + }), + [theme], + ) - return ( - <> - ({ + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + }, + scales: { + x: { + grid: { + color: theme.palette.divider, + drawOnChartArea: false, }, - scales: { - x: { - grid: { - color: getStyle('--cui-border-color-translucent'), - drawOnChartArea: false, - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - y: { - beginAtZero: true, - border: { - color: getStyle('--cui-border-color-translucent'), - }, - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - max: 250, - ticks: { - color: getStyle('--cui-body-color'), - maxTicksLimit: 5, - stepSize: Math.ceil(250 / 5), - }, - }, + ticks: { + color: theme.palette.text.secondary, }, - elements: { - line: { - tension: 0.4, - }, - point: { - radius: 0, - hitRadius: 10, - hoverRadius: 4, - hoverBorderWidth: 3, - }, + }, + y: { + beginAtZero: true, + border: { + color: theme.palette.divider, }, - }} - /> - + grid: { + color: theme.palette.divider, + }, + max: 250, + ticks: { + color: theme.palette.text.secondary, + maxTicksLimit: 5, + stepSize: Math.ceil(250 / 5), + }, + }, + }, + elements: { + line: { + tension: 0.4, + }, + point: { + radius: 0, + hitRadius: 10, + hoverRadius: 4, + hoverBorderWidth: 3, + }, + }, + }), + [theme], + ) + + return ( + + + ) } diff --git a/src/views/pages/login/Login.js b/src/views/pages/login/Login.js index 1b2ee0baa2..7a8ff16ee4 100644 --- a/src/views/pages/login/Login.js +++ b/src/views/pages/login/Login.js @@ -1,85 +1,112 @@ import React from 'react' import { Link } from 'react-router-dom' -import { - CButton, - CCard, - CCardBody, - CCardGroup, - CCol, - CContainer, - CForm, - CFormInput, - CInputGroup, - CInputGroupText, - CRow, -} from '@coreui/react' -import CIcon from '@coreui/icons-react' -import { cilLockLocked, cilUser } from '@coreui/icons' +import Box from '@mui/material/Box' +import Container from '@mui/material/Container' +import Grid from '@mui/material/Grid' +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import TextField from '@mui/material/TextField' +import Button from '@mui/material/Button' +import InputAdornment from '@mui/material/InputAdornment' +import PersonIcon from '@mui/icons-material/Person' +import LockIcon from '@mui/icons-material/Lock' const Login = () => { return ( -
    - - - - - - - -

    Login

    -

    Sign In to your account

    - - - - - - - - - - - - - - - - Login - - - - - Forgot password? - - - -
    -
    -
    - - -
    -

    Sign up

    -

    - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod - tempor incididunt ut labore et dolore magna aliqua. -

    - - - Register Now! - - -
    -
    -
    -
    -
    -
    -
    -
    + + + + + + + + Login + + + Sign In to your account + + + + + ), + }, + }} + /> + + + + ), + }, + }} + /> + + + + + + + + + + + + Sign up + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor + incididunt ut labore et dolore magna aliqua. + + + + + + + + ) } diff --git a/src/views/pages/page404/Page404.js b/src/views/pages/page404/Page404.js index d7fe9a0a25..7a32b17dbe 100644 --- a/src/views/pages/page404/Page404.js +++ b/src/views/pages/page404/Page404.js @@ -1,40 +1,56 @@ import React from 'react' -import { - CButton, - CCol, - CContainer, - CFormInput, - CInputGroup, - CInputGroupText, - CRow, -} from '@coreui/react' -import CIcon from '@coreui/icons-react' -import { cilMagnifyingGlass } from '@coreui/icons' +import Box from '@mui/material/Box' +import Container from '@mui/material/Container' +import Typography from '@mui/material/Typography' +import TextField from '@mui/material/TextField' +import Button from '@mui/material/Button' +import InputAdornment from '@mui/material/InputAdornment' +import SearchIcon from '@mui/icons-material/Search' const Page404 = () => { return ( -
    - - - -
    -

    404

    -

    Oops! You{"'"}re lost.

    -

    - The page you are looking for was not found. -

    -
    - - - - - - Search - -
    -
    -
    -
    + + + + + 404 + + + + Oops! You{"'"}re lost. + + + The page you are looking for was not found. + + + + + + + + ), + }, + }} + /> + + + + ) } diff --git a/src/views/pages/page500/Page500.js b/src/views/pages/page500/Page500.js index ea11a0cb2d..0f089cff89 100644 --- a/src/views/pages/page500/Page500.js +++ b/src/views/pages/page500/Page500.js @@ -1,40 +1,56 @@ import React from 'react' -import { - CButton, - CCol, - CContainer, - CFormInput, - CInputGroup, - CInputGroupText, - CRow, -} from '@coreui/react' -import CIcon from '@coreui/icons-react' -import { cilMagnifyingGlass } from '@coreui/icons' +import Box from '@mui/material/Box' +import Container from '@mui/material/Container' +import Typography from '@mui/material/Typography' +import TextField from '@mui/material/TextField' +import Button from '@mui/material/Button' +import InputAdornment from '@mui/material/InputAdornment' +import SearchIcon from '@mui/icons-material/Search' const Page500 = () => { return ( -
    - - - - -

    500

    -

    Houston, we have a problem!

    -

    - The page you are looking for is temporarily unavailable. -

    -
    - - - - - - Search - -
    -
    -
    -
    + + + + + 500 + + + + Houston, we have a problem! + + + The page you are looking for is temporarily unavailable. + + + + + + + + ), + }, + }} + /> + + + + ) } diff --git a/src/views/pages/register/Register.js b/src/views/pages/register/Register.js index d78b24c8fd..cfd3ca182f 100644 --- a/src/views/pages/register/Register.js +++ b/src/views/pages/register/Register.js @@ -1,70 +1,104 @@ import React from 'react' -import { - CButton, - CCard, - CCardBody, - CCol, - CContainer, - CForm, - CFormInput, - CInputGroup, - CInputGroupText, - CRow, -} from '@coreui/react' -import CIcon from '@coreui/icons-react' -import { cilLockLocked, cilUser } from '@coreui/icons' +import Box from '@mui/material/Box' +import Container from '@mui/material/Container' +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import TextField from '@mui/material/TextField' +import Button from '@mui/material/Button' +import InputAdornment from '@mui/material/InputAdornment' +import PersonIcon from '@mui/icons-material/Person' +import EmailIcon from '@mui/icons-material/Email' +import LockIcon from '@mui/icons-material/Lock' const Register = () => { return ( -
    - - - - - - -

    Register

    -

    Create your account

    - - - - - - - - @ - - - - - - - - - - - - - - -
    - Create Account -
    -
    -
    -
    -
    -
    -
    -
    + + + + + + Register + + + Create your account + + + + + ), + }, + }} + /> + + + + ), + }, + }} + /> + + + + ), + }, + }} + /> + + + + ), + }, + }} + /> + + + + + ) } diff --git a/src/views/widgets/WidgetsBrand.js b/src/views/widgets/WidgetsBrand.js index 03eea83efd..76b485706c 100644 --- a/src/views/widgets/WidgetsBrand.js +++ b/src/views/widgets/WidgetsBrand.js @@ -1,181 +1,200 @@ import React from 'react' import PropTypes from 'prop-types' -import { CWidgetStatsD, CRow, CCol } from '@coreui/react' -import CIcon from '@coreui/icons-react' -import { cibFacebook, cibLinkedin, cibTwitter, cilCalendar } from '@coreui/icons' -import { CChart } from '@coreui/react-chartjs' +import { useTheme } from '@mui/material/styles' +import Grid from '@mui/material/Grid' +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Box from '@mui/material/Box' +import FacebookIcon from '@mui/icons-material/Facebook' +import TwitterIcon from '@mui/icons-material/Twitter' +import LinkedInIcon from '@mui/icons-material/LinkedIn' +import CalendarMonthIcon from '@mui/icons-material/CalendarMonth' +import { Line } from 'react-chartjs-2' +import { + Chart as ChartJS, + CategoryScale, + LinearScale, + PointElement, + LineElement, + Filler, +} from 'chart.js' -const WidgetsBrand = (props) => { +ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Filler) + +const BrandWidget = ({ icon, values, color, chartData, withCharts }) => { const chartOptions = { elements: { - line: { - tension: 0.4, - }, - point: { - radius: 0, - hitRadius: 10, - hoverRadius: 4, - hoverBorderWidth: 3, - }, + line: { tension: 0.4 }, + point: { radius: 0, hitRadius: 10, hoverRadius: 4, hoverBorderWidth: 3 }, }, maintainAspectRatio: false, - plugins: { - legend: { - display: false, + plugins: { legend: { display: false } }, + scales: { x: { display: false }, y: { display: false } }, + } + + return ( + + + {withCharts && ( + + + + )} + {icon} + + + {values.map((item, index) => ( + + + {item.value} + + + {item.title} + + + ))} + + + ) +} + +BrandWidget.propTypes = { + icon: PropTypes.node.isRequired, + values: PropTypes.arrayOf( + PropTypes.shape({ + title: PropTypes.string, + value: PropTypes.string, + }), + ).isRequired, + color: PropTypes.string.isRequired, + chartData: PropTypes.object, + withCharts: PropTypes.bool, +} + +const WidgetsBrand = (props) => { + const theme = useTheme() + + const brands = [ + { + icon: , + values: [ + { title: 'friends', value: '89K' }, + { title: 'feeds', value: '459' }, + ], + color: '#3b5998', + chartData: { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + backgroundColor: 'rgba(255,255,255,.1)', + borderColor: 'rgba(255,255,255,.55)', + pointHoverBackgroundColor: '#fff', + borderWidth: 2, + data: [65, 59, 84, 84, 51, 55, 40], + fill: true, + }, + ], }, }, - scales: { - x: { - display: false, + { + icon: , + values: [ + { title: 'followers', value: '973k' }, + { title: 'tweets', value: '1.792' }, + ], + color: '#00aced', + chartData: { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + backgroundColor: 'rgba(255,255,255,.1)', + borderColor: 'rgba(255,255,255,.55)', + pointHoverBackgroundColor: '#fff', + borderWidth: 2, + data: [1, 13, 9, 17, 34, 41, 38], + fill: true, + }, + ], }, - y: { - display: false, + }, + { + icon: , + values: [ + { title: 'contacts', value: '500' }, + { title: 'feeds', value: '1.292' }, + ], + color: '#4875b4', + chartData: { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + backgroundColor: 'rgba(255,255,255,.1)', + borderColor: 'rgba(255,255,255,.55)', + pointHoverBackgroundColor: '#fff', + borderWidth: 2, + data: [78, 81, 80, 45, 34, 12, 40], + fill: true, + }, + ], }, }, - } + { + icon: , + values: [ + { title: 'events', value: '12+' }, + { title: 'meetings', value: '4' }, + ], + color: theme.palette.warning.main, + chartData: { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + backgroundColor: 'rgba(255,255,255,.1)', + borderColor: 'rgba(255,255,255,.55)', + pointHoverBackgroundColor: '#fff', + borderWidth: 2, + data: [35, 23, 56, 22, 97, 23, 64], + fill: true, + }, + ], + }, + }, + ] return ( - - - - ), - })} - icon={} - values={[ - { title: 'friends', value: '89K' }, - { title: 'feeds', value: '459' }, - ]} - style={{ - '--cui-card-cap-bg': '#3b5998', - }} - /> - - - - ), - })} - icon={} - values={[ - { title: 'followers', value: '973k' }, - { title: 'tweets', value: '1.792' }, - ]} - style={{ - '--cui-card-cap-bg': '#00aced', - }} - /> - - - - ), - })} - icon={} - values={[ - { title: 'contacts', value: '500' }, - { title: 'feeds', value: '1.292' }, - ]} - style={{ - '--cui-card-cap-bg': '#4875b4', - }} - /> - - - - ), - })} - icon={} - values={[ - { title: 'events', value: '12+' }, - { title: 'meetings', value: '4' }, - ]} - /> - - + + {brands.map((brand, index) => ( + + + + ))} + ) } WidgetsBrand.propTypes = { - className: PropTypes.string, + sx: PropTypes.object, withCharts: PropTypes.bool, } diff --git a/src/views/widgets/WidgetsDropdown.js b/src/views/widgets/WidgetsDropdown.js index 85e2fc969d..03af6b88a2 100644 --- a/src/views/widgets/WidgetsDropdown.js +++ b/src/views/widgets/WidgetsDropdown.js @@ -1,395 +1,224 @@ -import React, { useEffect, useRef } from 'react' +import React, { useState } from 'react' import PropTypes from 'prop-types' - +import { useTheme } from '@mui/material/styles' +import Grid from '@mui/material/Grid' +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Box from '@mui/material/Box' +import IconButton from '@mui/material/IconButton' +import Menu from '@mui/material/Menu' +import MenuItem from '@mui/material/MenuItem' +import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward' +import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward' +import MoreVertIcon from '@mui/icons-material/MoreVert' +import { Line, Bar } from 'react-chartjs-2' import { - CRow, - CCol, - CDropdown, - CDropdownMenu, - CDropdownItem, - CDropdownToggle, - CWidgetStatsA, -} from '@coreui/react' -import { getStyle } from '@coreui/utils' -import { CChartBar, CChartLine } from '@coreui/react-chartjs' -import CIcon from '@coreui/icons-react' -import { cilArrowBottom, cilArrowTop, cilOptions } from '@coreui/icons' + Chart as ChartJS, + CategoryScale, + LinearScale, + PointElement, + LineElement, + BarElement, + Filler, +} from 'chart.js' -const WidgetsDropdown = (props) => { - const widgetChartRef1 = useRef(null) - const widgetChartRef2 = useRef(null) +ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, BarElement, Filler) + +const StatWidget = ({ title, value, change, changeType, color, chartData, chartType }) => { + const [anchorEl, setAnchorEl] = useState(null) + const open = Boolean(anchorEl) + + const handleClick = (event) => { + setAnchorEl(event.currentTarget) + } - useEffect(() => { - document.documentElement.addEventListener('ColorSchemeChange', () => { - if (widgetChartRef1.current) { - setTimeout(() => { - widgetChartRef1.current.data.datasets[0].pointBackgroundColor = getStyle('--cui-primary') - widgetChartRef1.current.update() - }) - } + const handleClose = () => { + setAnchorEl(null) + } + + const chartOptions = { + plugins: { legend: { display: false } }, + maintainAspectRatio: false, + scales: { + x: { display: false }, + y: { display: false }, + }, + elements: { + line: { borderWidth: 2, tension: 0.4 }, + point: { radius: 0, hitRadius: 10, hoverRadius: 4 }, + }, + } + + return ( + + + + + + {value}{' '} + + ({change}{' '} + {changeType === 'down' ? ( + + ) : ( + + )} + ) + + + + {title} + + + + + + + Action + Another action + Something else here... + Disabled action + + + + + {chartType === 'bar' ? ( + + ) : ( + + )} + + + ) +} + +StatWidget.propTypes = { + title: PropTypes.string.isRequired, + value: PropTypes.string.isRequired, + change: PropTypes.string.isRequired, + changeType: PropTypes.oneOf(['up', 'down']).isRequired, + color: PropTypes.string.isRequired, + chartData: PropTypes.object.isRequired, + chartType: PropTypes.oneOf(['line', 'bar']), +} + +const WidgetsDropdown = (props) => { + const theme = useTheme() - if (widgetChartRef2.current) { - setTimeout(() => { - widgetChartRef2.current.data.datasets[0].pointBackgroundColor = getStyle('--cui-info') - widgetChartRef2.current.update() - }) - } - }) - }, [widgetChartRef1, widgetChartRef2]) + const widgets = [ + { + title: 'Users', + value: '26K', + change: '-12.4%', + changeType: 'down', + color: theme.palette.primary.main, + chartType: 'line', + chartData: { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'Users', + backgroundColor: 'transparent', + borderColor: 'rgba(255,255,255,.55)', + pointBackgroundColor: theme.palette.primary.main, + data: [65, 59, 84, 84, 51, 55, 40], + }, + ], + }, + }, + { + title: 'Income', + value: '$6.200', + change: '40.9%', + changeType: 'up', + color: theme.palette.info.main, + chartType: 'line', + chartData: { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'Income', + backgroundColor: 'transparent', + borderColor: 'rgba(255,255,255,.55)', + pointBackgroundColor: theme.palette.info.main, + data: [1, 18, 9, 17, 34, 22, 11], + }, + ], + }, + }, + { + title: 'Conversion Rate', + value: '2.49%', + change: '84.7%', + changeType: 'up', + color: theme.palette.warning.main, + chartType: 'line', + chartData: { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'Conversion', + backgroundColor: 'rgba(255,255,255,.2)', + borderColor: 'rgba(255,255,255,.55)', + data: [78, 81, 80, 45, 34, 12, 40], + fill: true, + }, + ], + }, + }, + { + title: 'Sessions', + value: '44K', + change: '-23.6%', + changeType: 'down', + color: theme.palette.error.main, + chartType: 'bar', + chartData: { + labels: [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', + 'Jan', + 'Feb', + 'Mar', + 'Apr', + ], + datasets: [ + { + label: 'Sessions', + backgroundColor: 'rgba(255,255,255,.2)', + borderColor: 'rgba(255,255,255,.55)', + data: [78, 81, 80, 45, 34, 12, 40, 85, 65, 23, 12, 98, 34, 84, 67, 82], + barPercentage: 0.6, + }, + ], + }, + }, + ] return ( - - - - 26K{' '} - - (-12.4% ) - - - } - title="Users" - action={ - - - - - - Action - Another action - Something else here... - Disabled action - - - } - chart={ - - } - /> - - - - $6.200{' '} - - (40.9% ) - - - } - title="Income" - action={ - - - - - - Action - Another action - Something else here... - Disabled action - - - } - chart={ - - } - /> - - - - 2.49%{' '} - - (84.7% ) - - - } - title="Conversion Rate" - action={ - - - - - - Action - Another action - Something else here... - Disabled action - - - } - chart={ - - } - /> - - - - 44K{' '} - - (-23.6% ) - - - } - title="Sessions" - action={ - - - - - - Action - Another action - Something else here... - Disabled action - - - } - chart={ - - } - /> - - + + {widgets.map((widget, index) => ( + + + + ))} + ) } WidgetsDropdown.propTypes = { - className: PropTypes.string, + sx: PropTypes.object, withCharts: PropTypes.bool, } From fb12b4b27f7621539858ffaf3ae99fbe730ffcdc Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 10:47:15 +0000 Subject: [PATCH 2/2] Re-add CoreUI dependencies for unmigrated files The migration is partial - some views still use CoreUI components. Re-added CoreUI dependencies to allow the app to run while the unmigrated files are still present. --- package.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 9c4709b678..f85415bce4 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,17 @@ "start": "vite" }, "dependencies": { + "@coreui/coreui": "^5.5.0", + "@coreui/icons": "^3.0.1", + "@coreui/icons-react": "^2.3.0", + "@coreui/react": "^5.6.0", + "@coreui/react-chartjs": "^3.0.0", + "@coreui/utils": "^2.0.2", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", "@mui/icons-material": "^7.3.7", "@mui/material": "^7.3.7", + "@popperjs/core": "^2.11.8", "chart.js": "^4.5.1", "classnames": "^2.5.1", "core-js": "^3.47.0", @@ -32,7 +39,8 @@ "react-dom": "^19.2.3", "react-redux": "^9.2.0", "react-router-dom": "^7.11.0", - "redux": "5.0.1" + "redux": "5.0.1", + "simplebar-react": "^3.3.0" }, "devDependencies": { "@vitejs/plugin-react": "^5.1.2",