diff --git a/package.json b/package.json
index da08efaab..1a2cb95de 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
"license": "MIT",
"author": "The CoreUI Team (https://github.com/orgs/coreui/people)",
"scripts": {
- "build": "react-scripts build",
+ "build": "DISABLE_ESLINT_PLUGIN=true react-scripts build",
"eject": "react-scripts eject",
"lint": "eslint \"src/**/*.js\"",
"start": "react-scripts start",
@@ -29,9 +29,11 @@
"@coreui/react": "^4.6.0",
"@coreui/react-chartjs": "^2.1.2",
"@coreui/utils": "^2.0.1",
+ "axios": "^1.3.5",
"chart.js": "^3.9.1",
"classnames": "^2.3.2",
"core-js": "^3.29.0",
+ "js-cookie": "^3.0.1",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-app-polyfill": "^3.0.0",
diff --git a/src/App.js b/src/App.js
index 7c2488188..bf29f7e10 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,6 +1,7 @@
import React, { Component, Suspense } from 'react'
-import { HashRouter, Route, Routes } from 'react-router-dom'
+import { Route, Routes, BrowserRouter } from 'react-router-dom'
import './scss/style.scss'
+import './checkToken'
const loading = (
@@ -20,7 +21,7 @@ const Page500 = React.lazy(() => import('./views/pages/page500/Page500'))
class App extends Component {
render() {
return (
-
+
} />
@@ -30,7 +31,7 @@ class App extends Component {
} />
-
+
)
}
}
diff --git a/src/_nav.js b/src/_nav.js
index 8f3d730db..cdc38bd93 100644
--- a/src/_nav.js
+++ b/src/_nav.js
@@ -11,6 +11,8 @@ import {
cilPencil,
cilPuzzle,
cilSpeedometer,
+ cilFile,
+ cilPeople,
cilStar,
} from '@coreui/icons'
import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react'
@@ -18,288 +20,305 @@ import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react'
const _nav = [
{
component: CNavItem,
- name: 'Dashboard',
- to: '/dashboard',
- icon:
,
+ name: 'User',
+ to: '/user',
+ icon:
,
badge: {
color: 'info',
- text: 'NEW',
},
},
- {
- component: CNavTitle,
- name: 'Theme',
- },
- {
- component: CNavItem,
- name: 'Colors',
- to: '/theme/colors',
- icon:
,
- },
- {
- component: CNavItem,
- name: 'Typography',
- to: '/theme/typography',
- icon:
,
- },
- {
- component: CNavTitle,
- name: 'Components',
- },
- {
- component: CNavGroup,
- name: 'Base',
- to: '/base',
- icon:
,
- items: [
- {
- component: CNavItem,
- name: 'Accordion',
- to: '/base/accordion',
- },
- {
- component: CNavItem,
- name: 'Breadcrumb',
- to: '/base/breadcrumbs',
- },
- {
- 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: 'Spinners',
- to: '/base/spinners',
- },
- {
- component: CNavItem,
- name: 'Tables',
- to: '/base/tables',
- },
- {
- component: CNavItem,
- name: 'Tooltips',
- to: '/base/tooltips',
- },
- ],
- },
- {
- component: CNavGroup,
- name: 'Buttons',
- to: '/buttons',
- 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: CNavGroup,
- name: 'Forms',
- icon:
,
- items: [
- {
- component: CNavItem,
- name: 'Form Control',
- to: '/forms/form-control',
- },
- {
- component: CNavItem,
- name: 'Select',
- to: '/forms/select',
- },
- {
- component: CNavItem,
- name: 'Checks & Radios',
- to: '/forms/checks-radios',
- },
- {
- component: CNavItem,
- name: 'Range',
- to: '/forms/range',
- },
- {
- component: CNavItem,
- name: 'Input Group',
- to: '/forms/input-group',
- },
- {
- component: CNavItem,
- name: 'Floating Labels',
- to: '/forms/floating-labels',
- },
- {
- component: CNavItem,
- name: 'Layout',
- to: '/forms/layout',
- },
- {
- component: CNavItem,
- name: 'Validation',
- to: '/forms/validation',
- },
- ],
- },
- {
- component: CNavItem,
- name: 'Charts',
- to: '/charts',
- icon:
,
- },
- {
- component: CNavGroup,
- name: 'Icons',
- icon:
,
- items: [
- {
- component: CNavItem,
- name: 'CoreUI Free',
- to: '/icons/coreui-icons',
- badge: {
- color: 'success',
- text: 'NEW',
- },
- },
- {
- component: CNavItem,
- name: 'CoreUI Flags',
- to: '/icons/flags',
- },
- {
- component: CNavItem,
- name: 'CoreUI Brands',
- to: '/icons/brands',
- },
- ],
- },
- {
- component: CNavGroup,
- name: 'Notifications',
- 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:
,
+ name: 'File',
+ to: '/file',
+ icon:
,
badge: {
color: 'info',
- text: 'NEW',
},
},
- {
- component: CNavTitle,
- name: 'Extras',
- },
- {
- component: CNavGroup,
- name: 'Pages',
- 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:
,
+ name: 'Customer',
+ to: '/customer',
+ icon:
,
+ badge: {
+ color: 'info',
+ },
},
+ // // {
+ // // component: CNavTitle,
+ // // name: 'Theme',
+ // // },
+ // // {
+ // // component: CNavItem,
+ // // name: 'Colors',
+ // // to: '/theme/colors',
+ // // icon:
,
+ // // },
+ // {
+ // component: CNavItem,
+ // name: 'Typography',
+ // to: '/theme/typography',
+ // icon:
,
+ // },
+ // {
+ // component: CNavTitle,
+ // name: 'Components',
+ // },
+ // {
+ // component: CNavGroup,
+ // name: 'Base',
+ // to: '/base',
+ // icon:
,
+ // items: [
+ // {
+ // component: CNavItem,
+ // name: 'Accordion',
+ // to: '/base/accordion',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Breadcrumb',
+ // to: '/base/breadcrumbs',
+ // },
+ // {
+ // 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: 'Spinners',
+ // to: '/base/spinners',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Tables',
+ // to: '/base/tables',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Tooltips',
+ // to: '/base/tooltips',
+ // },
+ // ],
+ // },
+ // {
+ // component: CNavGroup,
+ // name: 'Buttons',
+ // to: '/buttons',
+ // 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: CNavGroup,
+ // name: 'Forms',
+ // icon:
,
+ // items: [
+ // {
+ // component: CNavItem,
+ // name: 'Form Control',
+ // to: '/forms/form-control',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Select',
+ // to: '/forms/select',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Checks & Radios',
+ // to: '/forms/checks-radios',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Range',
+ // to: '/forms/range',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Input Group',
+ // to: '/forms/input-group',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Floating Labels',
+ // to: '/forms/floating-labels',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Layout',
+ // to: '/forms/layout',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Validation',
+ // to: '/forms/validation',
+ // },
+ // ],
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'Charts',
+ // to: '/charts',
+ // icon:
,
+ // },
+ // {
+ // component: CNavGroup,
+ // name: 'Icons',
+ // icon:
,
+ // items: [
+ // {
+ // component: CNavItem,
+ // name: 'CoreUI Free',
+ // to: '/icons/coreui-icons',
+ // badge: {
+ // color: 'success',
+ // text: 'NEW',
+ // },
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'CoreUI Flags',
+ // to: '/icons/flags',
+ // },
+ // {
+ // component: CNavItem,
+ // name: 'CoreUI Brands',
+ // to: '/icons/brands',
+ // },
+ // ],
+ // },
+ // {
+ // component: CNavGroup,
+ // name: 'Notifications',
+ // 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:
,
+ // badge: {
+ // color: 'info',
+ // text: 'NEW',
+ // },
+ // },
+ // {
+ // component: CNavTitle,
+ // name: 'Extras',
+ // },
+ // {
+ // component: CNavGroup,
+ // name: 'Pages',
+ // 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:
,
+ // },
]
export default _nav
diff --git a/src/checkToken.js b/src/checkToken.js
new file mode 100644
index 000000000..657ea991d
--- /dev/null
+++ b/src/checkToken.js
@@ -0,0 +1,6 @@
+import Cookies from "js-cookie";
+import axios from "axios";
+
+const token = Cookies.get('authToken');
+
+axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
diff --git a/src/components/AppHeader.js b/src/components/AppHeader.js
index dd5f544e3..0e6f16aaa 100644
--- a/src/components/AppHeader.js
+++ b/src/components/AppHeader.js
@@ -34,36 +34,6 @@ const AppHeader = () => {
-
-
-
- Dashboard
-
-
-
- Users
-
-
- Settings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/header/AppHeaderDropdown.js b/src/components/header/AppHeaderDropdown.js
index 5be919ee9..6a2c94bf5 100644
--- a/src/components/header/AppHeaderDropdown.js
+++ b/src/components/header/AppHeaderDropdown.js
@@ -1,92 +1,37 @@
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 Cookies from 'js-cookie'
+import { useNavigate } from 'react-router-dom';
import avatar8 from './../../assets/images/avatars/8.jpg'
const AppHeaderDropdown = () => {
+ const navigate = useNavigate();
+
+ const doLogOut = () => {
+ Cookies.remove('authToken')
+ navigate('/login')
+ }
+
return (
- Account
-
-
- Updates
-
- 42
-
-
-
-
- Messages
-
- 42
-
-
-
-
- Tasks
-
- 42
-
-
-
-
- Comments
-
- 42
-
-
- Settings
-
-
- Profile
-
-
-
- Settings
-
-
-
- Payments
-
- 42
-
-
-
-
- Projects
-
- 42
-
-
-
-
+
- Lock Account
+ Log out
diff --git a/src/components/multiselect/MultiSelect.js b/src/components/multiselect/MultiSelect.js
new file mode 100644
index 000000000..77085724f
--- /dev/null
+++ b/src/components/multiselect/MultiSelect.js
@@ -0,0 +1,46 @@
+/* eslint-disable prettier/prettier */
+import React, { useState } from 'react'
+import './MultiSelect.scss'
+import { CCloseButton } from '@coreui/react'
+
+export default function MultiSelect() {
+ const [text, setText] = useState('')
+
+ const data = [
+ { id: 1, name: 'hieu' },
+ { id: 2, name: 'hieu2' },
+ { id: 3, name: 'hieu3' },
+ { id: 4, name: 'hieu4s' },
+ { id: 5, name: 'hieu4s' },
+ { id: 6, name: 'hieu4s' },
+ { id: 7, name: 'hieu4s' },
+ ]
+
+ return (
+
+
+ {data.map((d, i) => {
+ return (
+
+ {d.name}
+
+
+ )
+ })}
+
setText(e.target.value)}
+ />
+
+
+
+ {data.map((d) => {
+ return - {d.name}
+ })}
+
+
+
+ )
+}
diff --git a/src/components/multiselect/MultiSelect.scss b/src/components/multiselect/MultiSelect.scss
new file mode 100644
index 000000000..110ae5963
--- /dev/null
+++ b/src/components/multiselect/MultiSelect.scss
@@ -0,0 +1,37 @@
+.multi-select {
+ position: relative;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+
+ .search-bar {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ height: 38px;
+ flex-wrap: wrap;
+ border: 1px solid #ccc;
+ .search-item {
+ width: 60px;
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+ background-color: #ccc;
+ margin: 4px;
+ border-radius: 2px;
+ padding: 2px;
+ .item-icon {
+ font-size: 10px;
+ }
+ }
+ .search-input {
+ border: none;
+ padding: 4px;
+ outline: none;
+ }
+ }
+ .search-option {
+ position: absolute;
+ display: none;
+ }
+}
diff --git a/src/constant.js b/src/constant.js
new file mode 100644
index 000000000..a9be83b71
--- /dev/null
+++ b/src/constant.js
@@ -0,0 +1,4 @@
+export const BACKEND_HOST =
+ process.env.NODE_ENV === 'development'
+ ? 'http://51.79.147.198:3000'
+ : 'http://api.namthanhdatholdings.com'
diff --git a/src/layout/DefaultLayout.js b/src/layout/DefaultLayout.js
index 43bd64432..34626157a 100644
--- a/src/layout/DefaultLayout.js
+++ b/src/layout/DefaultLayout.js
@@ -1,9 +1,11 @@
import React from 'react'
import { AppContent, AppSidebar, AppFooter, AppHeader } from '../components/index'
+import Auth from '../views/Auth';
const DefaultLayout = () => {
return (
+
diff --git a/src/routes.js b/src/routes.js
index d168b1ca4..16665fbc4 100644
--- a/src/routes.js
+++ b/src/routes.js
@@ -50,6 +50,10 @@ const Toasts = React.lazy(() => import('./views/notifications/toasts/Toasts'))
const Widgets = React.lazy(() => import('./views/widgets/Widgets'))
+const User = React.lazy(() => import('./views/data/User'))
+const File = React.lazy(() => import('./views/data/File'))
+const Customer = React.lazy(() => import('./views/data/Customer'))
+
const routes = [
{ path: '/', exact: true, name: 'Home' },
{ path: '/dashboard', name: 'Dashboard', element: Dashboard },
@@ -95,6 +99,9 @@ const routes = [
{ path: '/notifications/modals', name: 'Modals', element: Modals },
{ path: '/notifications/toasts', name: 'Toasts', element: Toasts },
{ path: '/widgets', name: 'Widgets', element: Widgets },
+ { path: '/user', name: 'User', element: User },
+ { path: '/file', name: 'File', element: File },
+ { path: '/customer', name: 'Customer', element: Customer },
]
export default routes
diff --git a/src/store.js b/src/store.js
index ab446364c..743345492 100644
--- a/src/store.js
+++ b/src/store.js
@@ -2,6 +2,7 @@ import { createStore } from 'redux'
const initialState = {
sidebarShow: true,
+ authToken: null
}
const changeState = (state = initialState, { type, ...rest }) => {
diff --git a/src/views/Auth.js b/src/views/Auth.js
new file mode 100644
index 000000000..fec2824f6
--- /dev/null
+++ b/src/views/Auth.js
@@ -0,0 +1,18 @@
+import React, { useEffect } from 'react';
+import Cookies from 'js-cookie';
+import { useNavigate } from 'react-router-dom';
+
+export default function Auth() {
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ const token = Cookies.get('authToken');
+ if (!token) {
+ setTimeout(() => {
+ navigate('/login');
+ }, 100)
+ }
+ }, []);
+
+ return null;
+}
diff --git a/src/views/data/Actions.js b/src/views/data/Actions.js
new file mode 100644
index 000000000..f2cbe59ec
--- /dev/null
+++ b/src/views/data/Actions.js
@@ -0,0 +1,18 @@
+/* eslint-disable prettier/prettier */
+import { CButton, CCol, CContainer, CRow, CTable, CTableHeaderCell, CTableRow } from '@coreui/react'
+import React from 'react'
+export default function Actions() {
+ return (
+
+ edit
+ delete
+ change password
+
+
+ //
+ // edit
+ // delete
+ // change password
+ //
+ )
+}
diff --git a/src/views/data/Customer.js b/src/views/data/Customer.js
new file mode 100644
index 000000000..7f872262e
--- /dev/null
+++ b/src/views/data/Customer.js
@@ -0,0 +1,109 @@
+import {
+ CButton,
+ CCol,
+ CPagination,
+ CPaginationItem,
+ CRow,
+ CTable,
+ CTableBody,
+ CTableDataCell,
+ CTableHead,
+ CTableHeaderCell,
+ CTableRow,
+} from '@coreui/react'
+import React, { useEffect, useState, useRef } from 'react'
+import axios from 'axios'
+import { BACKEND_HOST } from '../../constant'
+
+import CustomerCreateModel from '../modal/CustomerCreateModel'
+
+const Customer = () => {
+ const [customer, setCustomer] = useState([])
+ const [limit, setLimit] = useState(20)
+ const [offset, setOffset] = useState(0)
+
+ const createUserModalRef = useRef()
+
+ useEffect(() => {
+ getCustomersData()
+ }, [])
+
+ const getCustomersData = () => {
+ axios
+ .get(`${BACKEND_HOST}/customer`, {
+ params: {
+ limit,
+ offset,
+ },
+ })
+ .then((res) => {
+ const newCustomer = res.data.customers
+ setCustomer(newCustomer)
+ })
+ .catch((err) => {
+ console.log('Error while getting Customer', err)
+ })
+ }
+
+ const openCreateUser = () => {
+ createUserModalRef.current?.show()
+ }
+ console.log(customer)
+ return (
+
+
+
+ Create Customer
+
+
+
+
+
+ Name
+ Phone
+ Age
+ Job
+ Location
+ GoodWill
+ Intimacy
+ MinBudget
+ MaxBudget
+ CaringArea
+ CaringProduct
+
+
+
+ {customer.map((item, index) => {
+ return (
+
+ {item.name}
+ {item.phone}
+ {item.age}
+ {item.job}
+ {item.userArea}
+ {item.goodwill}
+ {item.intimacy}
+ {item.minBudget}
+ {item.maxBudget}
+ {item.caringArea.toString()}
+ {item.caringProduct.toString()}
+
+ )
+ })}
+
+
+
+
+ «
+
+ 1
+
+ »
+
+
+
+
+ )
+}
+
+export default Customer
diff --git a/src/views/data/File.js b/src/views/data/File.js
new file mode 100644
index 000000000..5dd8bc26e
--- /dev/null
+++ b/src/views/data/File.js
@@ -0,0 +1,90 @@
+import {
+ CButton,
+ CCol,
+ CPagination,
+ CPaginationItem,
+ CRow,
+ CTable,
+ CTableBody,
+ CTableDataCell,
+ CTableHead,
+ CTableHeaderCell,
+ CTableRow,
+} from '@coreui/react'
+import React, { useEffect, useState, useRef } from 'react'
+import axios from 'axios'
+import { BACKEND_HOST } from '../../constant'
+import UploadFileModal from '../modal/UploadFileModal'
+
+const File = () => {
+ const [files, setFiles] = useState([])
+ const [limit, setLimit] = useState(20)
+ const [offset, setOffset] = useState(0)
+
+ const uploadFileRef = useRef()
+
+ useEffect(() => {
+ console.log('shit')
+ getFilesData()
+ }, [])
+
+ const getFilesData = () => {
+ axios
+ .get(`${BACKEND_HOST}/file`, {
+ params: {
+ limit,
+ offset,
+ },
+ })
+ .then((res) => {
+ const newFiles = res.data.files
+ console.log('123123', newFiles)
+ setFiles(newFiles)
+ })
+ .catch((err) => {
+ console.log('Error while getting user', err)
+ })
+ }
+
+ const openUploadFile = () => {
+ uploadFileRef.current?.show()
+ }
+
+ return (
+
+
+
+ Upload file
+
+
+
+
+
+ Filename
+
+
+
+ {files.map((item, index) => {
+ return (
+
+ {item.originalName}
+
+ )
+ })}
+
+
+
+
+ «
+
+ 1
+
+ »
+
+
+
+
+ )
+}
+
+export default File
diff --git a/src/views/data/User.js b/src/views/data/User.js
new file mode 100644
index 000000000..d29f65b13
--- /dev/null
+++ b/src/views/data/User.js
@@ -0,0 +1,101 @@
+import {
+ CButton,
+ CCol,
+ CPagination,
+ CPaginationItem,
+ CRow,
+ CTable,
+ CTableBody,
+ CTableDataCell,
+ CTableHead,
+ CTableHeaderCell,
+ CTableRow,
+} from '@coreui/react'
+import React, { useEffect, useState, useRef } from 'react'
+import { useNavigate } from 'react-router-dom'
+import axios from 'axios'
+import { BACKEND_HOST } from '../../constant'
+import UserCreateModal from '../modal/UserCreateModal'
+import Actions from './Actions'
+
+const User = () => {
+ const [users, setUsers] = useState([])
+ const [limit, setLimit] = useState(20)
+ const [offset, setOffset] = useState(0)
+
+ const createUserModalRef = useRef()
+
+ const navigate = useNavigate()
+
+ useEffect(() => {
+ getUsersData()
+ }, [])
+
+ const getUsersData = () => {
+ axios
+ .get(`${BACKEND_HOST}/user`, {
+ params: {
+ limit,
+ offset,
+ },
+ })
+ .then((res) => {
+ const newUsers = res.data.users
+ setUsers(newUsers)
+ })
+ .catch((err) => {
+ console.log('Error while getting user', err)
+ })
+ }
+
+ const openCreateUser = () => {
+ createUserModalRef.current?.show()
+ }
+ console.log(users)
+
+ return (
+
+
+
+ Create user
+
+
+
+
+
+ Action
+ Username
+ Role
+ Name
+
+
+
+ {users.map((item, index) => {
+ return (
+
+
+
+
+ {item.username}
+ {item.role}
+ {item.name}
+
+ )
+ })}
+
+
+
+
+ «
+
+ 1
+
+ »
+
+
+
+
+ )
+}
+
+export default User
diff --git a/src/views/modal/CustomerCreateModel.js b/src/views/modal/CustomerCreateModel.js
new file mode 100644
index 000000000..623740253
--- /dev/null
+++ b/src/views/modal/CustomerCreateModel.js
@@ -0,0 +1,265 @@
+/* eslint-disable prettier/prettier */
+/* eslint-disable no-undef */
+/* eslint-disable prettier/prettier */
+import React, { useState, useImperativeHandle, useEffect } from 'react'
+import {
+ CButton,
+ CModal,
+ CModalBody,
+ CModalFooter,
+ CModalHeader,
+ CModalTitle,
+ CForm,
+ CInputGroupText,
+ CFormInput,
+ CInputGroup,
+ CAlert,
+ CFormSelect,
+ CFormCheck,
+} from '@coreui/react'
+import CIcon from '@coreui/icons-react'
+import {
+ cilLockLocked,
+ cilUser,
+ cilText,
+ cilPhone,
+ cilFactory,
+ cilBriefcase,
+ cilLocationPin,
+ cilStar,
+ cilMoney,
+ cilArrowRight,
+} from '@coreui/icons'
+import axios from 'axios'
+import { BACKEND_HOST } from '../../constant'
+import provinces_item from './Provinces.json'
+import MultiSelect from 'src/components/multiselect/MultiSelect'
+
+const CustomerCreateModel = ({}, ref) => {
+ const [visible, setVisible] = useState(false)
+ const [phone, setPhone] = useState('')
+ const [name, setName] = useState('')
+ const [age, setAge] = useState('')
+ const [job, setJob] = useState('')
+ const [userArea, setUserArea] = useState('')
+ const [goodwill, setGoodWill] = useState('')
+ const [intimacy, setIntimacy] = useState('')
+ const [minBudget, setMinBudget] = useState('')
+ const [maxBudget, setMaxBudget] = useState('')
+ const [caringArea, setcaringArea] = useState([])
+ const [caringProduct, setCaringProduct] = useState([])
+
+ const [error, setError] = useState(false)
+ const [success, setSuccess] = useState(false)
+
+ const provinces = provinces_item
+
+ useImperativeHandle(ref, () => ({
+ show: () => {
+ setVisible(true)
+ },
+ }))
+
+ const handleSubmit = () => {
+ axios
+ .post(`${BACKEND_HOST}/customer/create`, {
+ name,
+ phone,
+ age,
+ job,
+ userArea,
+ goodwill,
+ intimacy,
+ minBudget,
+ maxBudget,
+ caringArea,
+ caringProduct,
+ })
+ .then((res) => {
+ setSuccess(true)
+ })
+ .catch((err) => {
+ console.log('Error', err)
+ setError(true)
+ })
+ }
+
+ return (
+
setVisible(false)}>
+
+ Create User
+
+
+ {error && {'Error'}}
+ {success && {'Done'}}
+
+
+
+
+
+ setName(event.target.value)}
+ placeholder="Name"
+ autoComplete="name"
+ />
+
+
+
+
+
+ setPhone(event.target.value)}
+ />
+
+
+
+
+
+ setAge(event.target.value)}
+ />
+
+
+
+
+
+ setJob(event.target.value)}
+ />
+
+
+
+
+
+ setUserArea(e.target.value)}
+ >
+ {provinces.map((p) => {
+ return
+ })}
+
+
+
+
+
+
+ setGoodWill(e.target.value)}
+ >
+
+
+
+
+
+ setIntimacy(e.target.value)}
+ >
+
+
+
+
+
+
+
+
+
+
+
+ setMinBudget(e.target.value)}
+ >
+
+
+
+
+
+
+
+
+
+ setMaxBudget(e.target.value)}
+ >
+
+
+
+
+
+
+
+
+
+ CaringArea
+
+
+
+
+
+
+
+
+
+
+
+
+ CaringProduct
+
+
+
+
+
+
+
+
+
+
+
+
+
+ setVisible(false)}>
+ Cancel
+
+
+ Create
+
+
+
+ )
+}
+
+export default React.forwardRef(CustomerCreateModel)
diff --git a/src/views/modal/ErrorModal.js b/src/views/modal/ErrorModal.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/views/modal/Provinces.json b/src/views/modal/Provinces.json
new file mode 100644
index 000000000..00e815605
--- /dev/null
+++ b/src/views/modal/Provinces.json
@@ -0,0 +1,443 @@
+[
+ {
+ "name": "Hà Nội",
+ "slug": "ha-noi",
+ "type": "thanh-pho",
+ "name_with_type": "Thành phố Hà Nội",
+ "code": "01"
+ },
+ {
+ "name": "Hà Giang",
+ "slug": "ha-giang",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Hà Giang",
+ "code": "02"
+ },
+ {
+ "name": "Cao Bằng",
+ "slug": "cao-bang",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Cao Bằng",
+ "code": "04"
+ },
+ {
+ "name": "Bắc Kạn",
+ "slug": "bac-kan",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Bắc Kạn",
+ "code": "06"
+ },
+ {
+ "name": "Tuyên Quang",
+ "slug": "tuyen-quang",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Tuyên Quang",
+ "code": "08"
+ },
+ {
+ "name": "Lào Cai",
+ "slug": "lao-cai",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Lào Cai",
+ "code": "10"
+ },
+ {
+ "name": "Điện Biên",
+ "slug": "dien-bien",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Điện Biên",
+ "code": "11"
+ },
+ {
+ "name": "Lai Châu",
+ "slug": "lai-chau",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Lai Châu",
+ "code": "12"
+ },
+ {
+ "name": "Sơn La",
+ "slug": "son-la",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Sơn La",
+ "code": "14"
+ },
+ {
+ "name": "Yên Bái",
+ "slug": "yen-bai",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Yên Bái",
+ "code": "15"
+ },
+ {
+ "name": "Hoà Bình",
+ "slug": "hoa-binh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Hoà Bình",
+ "code": "17"
+ },
+ {
+ "name": "Thái Nguyên",
+ "slug": "thai-nguyen",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Thái Nguyên",
+ "code": "19"
+ },
+ {
+ "name": "Lạng Sơn",
+ "slug": "lang-son",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Lạng Sơn",
+ "code": "20"
+ },
+ {
+ "name": "Quảng Ninh",
+ "slug": "quang-ninh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Quảng Ninh",
+ "code": "22"
+ },
+ {
+ "name": "Bắc Giang",
+ "slug": "bac-giang",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Bắc Giang",
+ "code": "24"
+ },
+ {
+ "name": "Phú Thọ",
+ "slug": "phu-tho",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Phú Thọ",
+ "code": "25"
+ },
+ {
+ "name": "Vĩnh Phúc",
+ "slug": "vinh-phuc",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Vĩnh Phúc",
+ "code": "26"
+ },
+ {
+ "name": "Bắc Ninh",
+ "slug": "bac-ninh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Bắc Ninh",
+ "code": "27"
+ },
+ {
+ "name": "Hải Dương",
+ "slug": "hai-duong",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Hải Dương",
+ "code": "30"
+ },
+ {
+ "name": "Hải Phòng",
+ "slug": "hai-phong",
+ "type": "thanh-pho",
+ "name_with_type": "Thành phố Hải Phòng",
+ "code": "31"
+ },
+ {
+ "name": "Hưng Yên",
+ "slug": "hung-yen",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Hưng Yên",
+ "code": "33"
+ },
+ {
+ "name": "Thái Bình",
+ "slug": "thai-binh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Thái Bình",
+ "code": "34"
+ },
+ {
+ "name": "Hà Nam",
+ "slug": "ha-nam",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Hà Nam",
+ "code": "35"
+ },
+ {
+ "name": "Nam Định",
+ "slug": "nam-dinh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Nam Định",
+ "code": "36"
+ },
+ {
+ "name": "Ninh Bình",
+ "slug": "ninh-binh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Ninh Bình",
+ "code": "37"
+ },
+ {
+ "name": "Thanh Hóa",
+ "slug": "thanh-hoa",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Thanh Hóa",
+ "code": "38"
+ },
+ {
+ "name": "Nghệ An",
+ "slug": "nghe-an",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Nghệ An",
+ "code": "40"
+ },
+ {
+ "name": "Hà Tĩnh",
+ "slug": "ha-tinh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Hà Tĩnh",
+ "code": "42"
+ },
+ {
+ "name": "Quảng Bình",
+ "slug": "quang-binh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Quảng Bình",
+ "code": "44"
+ },
+ {
+ "name": "Quảng Trị",
+ "slug": "quang-tri",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Quảng Trị",
+ "code": "45"
+ },
+ {
+ "name": "Thừa Thiên Huế",
+ "slug": "thua-thien-hue",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Thừa Thiên Huế",
+ "code": "46"
+ },
+ {
+ "name": "Đà Nẵng",
+ "slug": "da-nang",
+ "type": "thanh-pho",
+ "name_with_type": "Thành phố Đà Nẵng",
+ "code": "48"
+ },
+ {
+ "name": "Quảng Nam",
+ "slug": "quang-nam",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Quảng Nam",
+ "code": "49"
+ },
+ {
+ "name": "Quảng Ngãi",
+ "slug": "quang-ngai",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Quảng Ngãi",
+ "code": "51"
+ },
+ {
+ "name": "Bình Định",
+ "slug": "binh-dinh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Bình Định",
+ "code": "52"
+ },
+ {
+ "name": "Phú Yên",
+ "slug": "phu-yen",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Phú Yên",
+ "code": "54"
+ },
+ {
+ "name": "Khánh Hòa",
+ "slug": "khanh-hoa",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Khánh Hòa",
+ "code": "56"
+ },
+ {
+ "name": "Ninh Thuận",
+ "slug": "ninh-thuan",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Ninh Thuận",
+ "code": "58"
+ },
+ {
+ "name": "Bình Thuận",
+ "slug": "binh-thuan",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Bình Thuận",
+ "code": "60"
+ },
+ {
+ "name": "Kon Tum",
+ "slug": "kon-tum",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Kon Tum",
+ "code": "62"
+ },
+ {
+ "name": "Gia Lai",
+ "slug": "gia-lai",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Gia Lai",
+ "code": "64"
+ },
+ {
+ "name": "Đắk Lắk",
+ "slug": "dak-lak",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Đắk Lắk",
+ "code": "66"
+ },
+ {
+ "name": "Đắk Nông",
+ "slug": "dak-nong",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Đắk Nông",
+ "code": "67"
+ },
+ {
+ "name": "Lâm Đồng",
+ "slug": "lam-dong",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Lâm Đồng",
+ "code": "68"
+ },
+ {
+ "name": "Bình Phước",
+ "slug": "binh-phuoc",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Bình Phước",
+ "code": "70"
+ },
+ {
+ "name": "Tây Ninh",
+ "slug": "tay-ninh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Tây Ninh",
+ "code": "72"
+ },
+ {
+ "name": "Bình Dương",
+ "slug": "binh-duong",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Bình Dương",
+ "code": "74"
+ },
+ {
+ "name": "Đồng Nai",
+ "slug": "dong-nai",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Đồng Nai",
+ "code": "75"
+ },
+ {
+ "name": "Bà Rịa - Vũng Tàu",
+ "slug": "ba-ria-vung-tau",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Bà Rịa - Vũng Tàu",
+ "code": "77"
+ },
+ {
+ "name": "Hồ Chí Minh",
+ "slug": "ho-chi-minh",
+ "type": "thanh-pho",
+ "name_with_type": "Thành phố Hồ Chí Minh",
+ "code": "79"
+ },
+ {
+ "name": "Long An",
+ "slug": "long-an",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Long An",
+ "code": "80"
+ },
+ {
+ "name": "Tiền Giang",
+ "slug": "tien-giang",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Tiền Giang",
+ "code": "82"
+ },
+ {
+ "name": "Bến Tre",
+ "slug": "ben-tre",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Bến Tre",
+ "code": "83"
+ },
+ {
+ "name": "Trà Vinh",
+ "slug": "tra-vinh",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Trà Vinh",
+ "code": "84"
+ },
+ {
+ "name": "Vĩnh Long",
+ "slug": "vinh-long",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Vĩnh Long",
+ "code": "86"
+ },
+ {
+ "name": "Đồng Tháp",
+ "slug": "dong-thap",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Đồng Tháp",
+ "code": "87"
+ },
+ {
+ "name": "An Giang",
+ "slug": "an-giang",
+ "type": "tinh",
+ "name_with_type": "Tỉnh An Giang",
+ "code": "89"
+ },
+ {
+ "name": "Kiên Giang",
+ "slug": "kien-giang",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Kiên Giang",
+ "code": "91"
+ },
+ {
+ "name": "Cần Thơ",
+ "slug": "can-tho",
+ "type": "thanh-pho",
+ "name_with_type": "Thành phố Cần Thơ",
+ "code": "92"
+ },
+ {
+ "name": "Hậu Giang",
+ "slug": "hau-giang",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Hậu Giang",
+ "code": "93"
+ },
+ {
+ "name": "Sóc Trăng",
+ "slug": "soc-trang",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Sóc Trăng",
+ "code": "94"
+ },
+ {
+ "name": "Bạc Liêu",
+ "slug": "bac-lieu",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Bạc Liêu",
+ "code": "95"
+ },
+ {
+ "name": "Cà Mau",
+ "slug": "ca-mau",
+ "type": "tinh",
+ "name_with_type": "Tỉnh Cà Mau",
+ "code": "96"
+ }
+]
diff --git a/src/views/modal/UploadFileModal.js b/src/views/modal/UploadFileModal.js
new file mode 100644
index 000000000..c4291448f
--- /dev/null
+++ b/src/views/modal/UploadFileModal.js
@@ -0,0 +1,115 @@
+import React, { useState, useImperativeHandle } from 'react'
+import {
+ CButton,
+ CModal,
+ CModalBody,
+ CModalFooter,
+ CModalHeader,
+ CModalTitle,
+ CForm,
+ CInputGroupText,
+ CFormInput,
+ CInputGroup,
+ CAlert,
+ CProgress,
+} from '@coreui/react'
+import CIcon from '@coreui/icons-react'
+import { cilLockLocked, cilUser, cilText } from '@coreui/icons'
+import axios from 'axios'
+import { BACKEND_HOST } from '../../constant'
+import * as PropTypes from 'prop-types'
+
+function CFormGroup(props) {
+ return null
+}
+
+CFormGroup.propTypes = { children: PropTypes.node }
+
+function CLabel(props) {
+ return null
+}
+
+CLabel.propTypes = { children: PropTypes.node }
+
+function CInputFile(props) {
+ return null
+}
+
+CInputFile.propTypes = {
+ onChange: PropTypes.func,
+ name: PropTypes.string,
+ id: PropTypes.string,
+ required: PropTypes.bool,
+}
+const UploadFileModal = ({}, ref) => {
+ const [visible, setVisible] = useState(false)
+ const [file, setFile] = useState(null)
+ const [uploading, setUploading] = useState(false)
+ const [progress, setProgress] = useState(0)
+ const [success, setSuccess] = useState(false)
+ const [error, setError] = useState(false)
+
+ useImperativeHandle(ref, () => ({
+ show: () => {
+ setVisible(true)
+ },
+ }))
+
+ const handleUpload = () => {
+ setUploading(true)
+ axios
+ .post(
+ `${BACKEND_HOST}/file/upload`,
+ {
+ file,
+ },
+ {
+ headers: {
+ 'content-type': 'multipart/form-data',
+ },
+ onUploadProgress: (progressEvent) => {
+ const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
+ setProgress(percentCompleted)
+ },
+ },
+ )
+ .then((res) => {
+ setSuccess(true)
+ })
+ .catch((err) => {
+ console.log('Error', err)
+ setError(true)
+ })
+ }
+
+ return (
+
setVisible(false)}>
+
+ Upload file
+
+
+
+ setFile(event.target.files[0])}
+ type="file"
+ id="formFile"
+ label="Choose file"
+ />
+
+ {uploading && (
+
+ )}
+
+
+ setVisible(false)}>
+ Cancel
+
+
+ Create
+
+
+
+ )
+}
+
+export default React.forwardRef(UploadFileModal)
diff --git a/src/views/modal/UserCreateModal.js b/src/views/modal/UserCreateModal.js
new file mode 100644
index 000000000..bb7a33d7c
--- /dev/null
+++ b/src/views/modal/UserCreateModal.js
@@ -0,0 +1,106 @@
+import React, { useState, useImperativeHandle } from 'react'
+import {
+ CButton,
+ CModal,
+ CModalBody,
+ CModalFooter,
+ CModalHeader,
+ CModalTitle,
+ CForm,
+ CInputGroupText,
+ CFormInput,
+ CInputGroup,
+ CAlert,
+} from '@coreui/react'
+import CIcon from '@coreui/icons-react'
+import { cilLockLocked, cilUser, cilText } from '@coreui/icons'
+import axios from 'axios'
+import { BACKEND_HOST } from '../../constant'
+
+const UserCreateModal = ({}, ref) => {
+ const [visible, setVisible] = useState(false)
+ const [username, setUsername] = useState('')
+ const [name, setName] = useState('')
+ const [password, setPassword] = useState('')
+ const [error, setError] = useState(false)
+ const [success, setSuccess] = useState(false)
+
+ useImperativeHandle(ref, () => ({
+ show: () => {
+ setVisible(true)
+ },
+ }))
+
+ const handleSubmit = () => {
+ axios
+ .post(`${BACKEND_HOST}/user/create`, {
+ username,
+ password,
+ name,
+ })
+ .then((res) => {
+ setSuccess(true)
+ })
+ .catch((err) => {
+ console.log('Error', err)
+ setError(true)
+ })
+ }
+
+ return (
+
setVisible(false)}>
+
+ Create User
+
+
+ {error && {'Error'}}
+ {success && {'Done'}}
+
+
+
+
+
+ setUsername(event.target.value)}
+ placeholder="Username"
+ autoComplete="username"
+ />
+
+
+
+
+
+ setPassword(event.target.value)}
+ />
+
+
+
+
+
+ setName(event.target.value)}
+ />
+
+
+
+
+ setVisible(false)}>
+ Cancel
+
+
+ Create
+
+
+
+ )
+}
+
+export default React.forwardRef(UserCreateModal)
diff --git a/src/views/pages/login/Login.js b/src/views/pages/login/Login.js
index 6b889d530..f5f28ca8b 100644
--- a/src/views/pages/login/Login.js
+++ b/src/views/pages/login/Login.js
@@ -1,5 +1,5 @@
-import React from 'react'
-import { Link } from 'react-router-dom'
+import React, { useState, useEffect } from 'react'
+import { Link, useNavigate } from 'react-router-dom'
import {
CButton,
CCard,
@@ -12,11 +12,37 @@ import {
CInputGroup,
CInputGroupText,
CRow,
+ CModal,
+ CModalBody
} from '@coreui/react'
import CIcon from '@coreui/icons-react'
import { cilLockLocked, cilUser } from '@coreui/icons'
+import axios from 'axios';
+import { BACKEND_HOST } from '../../../constant';
+import { useDispatch } from 'react-redux';
+import Cookies from 'js-cookie';
const Login = () => {
+ const [username, setUsername] = useState('');
+ const [password, setPassword] = useState('');
+ const [showErrorModal, setShowErrorModal] = useState(false);
+ const dispatch = useDispatch();
+
+ const navigate = useNavigate();
+ const doLogin = async () => {
+ try {
+ const response = await axios.post(`${BACKEND_HOST}/auth/login`, {username, password});
+ const token = response?.data?.token;
+ dispatch({ type: 'set', authToken: token });
+ axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
+ Cookies.set('authToken', token, { expires: 1 });
+ navigate('/dashboard');
+ } catch (err) {
+ console.log('Error while login', err);
+ setShowErrorModal(true);
+ }
+ }
+
return (
@@ -32,7 +58,11 @@ const Login = () => {
-
+ setUsername(event.target.value)}
+ placeholder="Username"
+ autoComplete="username"/>
@@ -41,43 +71,30 @@ const Login = () => {
setPassword(event.target.value)}
/>
-
+
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!
-
-
-
-
-
+ setShowErrorModal(false)}>
+
+ Incorrect username or password. Please try again.
+
+
)