mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentral-ui-libs.git
synced 2025-10-30 02:12:22 +00:00
First commit
This commit is contained in:
33737
package-lock.json
generated
33737
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@@ -11,11 +11,12 @@
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@coreui/coreui": "^3.4.0",
|
||||
"@coreui/icons": "^2.0.1",
|
||||
"@coreui/icons-react": "^1.1.0",
|
||||
"@coreui/react": "^3.4.6",
|
||||
"@coreui/react-chartjs": "^1.1.0",
|
||||
"@coreui/coreui": "^4.0.5",
|
||||
"@coreui/icons": "^2.1.0",
|
||||
"@coreui/icons-react": "^2.0.0",
|
||||
"@coreui/react": "^4.0.1",
|
||||
"@coreui/react-chartjs": "^2.0.0",
|
||||
"color-convert": "^1.9.3",
|
||||
"libphonenumber-js": "^1.9.37",
|
||||
"lodash": "^4.17.21",
|
||||
"react-flow-renderer": "^9.6.6",
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
CModalBody,
|
||||
CModalHeader,
|
||||
CModalTitle,
|
||||
CDataTable,
|
||||
CSmartTable,
|
||||
} from '@coreui/react';
|
||||
import Select from 'react-select';
|
||||
import CIcon from '@coreui/icons-react';
|
||||
@@ -23,7 +23,7 @@ import useToggle from '../../hooks/useToggle';
|
||||
|
||||
const ApiStatusCard = ({ t, info, reload }) => {
|
||||
const [types, setTypes] = useState([]);
|
||||
const [showCerts, toggleCerts] = useToggle();
|
||||
const [showCerts, toggleCerts, setShowCerts] = useToggle(false);
|
||||
|
||||
const submit = () => {
|
||||
reload(
|
||||
@@ -105,7 +105,7 @@ const ApiStatusCard = ({ t, info, reload }) => {
|
||||
<CCol>
|
||||
<div block="true">
|
||||
{info.certificates?.length > 0 ? (
|
||||
<CButton className="ml-0 pl-0 py-0" color="link" onClick={toggleCerts}>
|
||||
<CButton className="ms-0 ps-0 py-0" color="link" onClick={toggleCerts}>
|
||||
{t('common.details')} ({info.certificates.length})
|
||||
</CButton>
|
||||
) : (
|
||||
@@ -124,7 +124,7 @@ const ApiStatusCard = ({ t, info, reload }) => {
|
||||
t('common.unknown')
|
||||
) : (
|
||||
<div>
|
||||
<div className="float-left" style={{ width: '85%' }}>
|
||||
<div className="float-start" style={{ width: '85%' }}>
|
||||
<Select
|
||||
isMulti
|
||||
closeMenuOnSelect={false}
|
||||
@@ -136,7 +136,7 @@ const ApiStatusCard = ({ t, info, reload }) => {
|
||||
classNamePrefix="select"
|
||||
/>
|
||||
</div>
|
||||
<div className="float-left text-right" style={{ width: '15%' }}>
|
||||
<div className="float-end text-end" style={{ width: '15%' }}>
|
||||
<CPopover content={t('system.reload')}>
|
||||
<CButton
|
||||
color="primary"
|
||||
@@ -144,7 +144,7 @@ const ApiStatusCard = ({ t, info, reload }) => {
|
||||
onClick={submit}
|
||||
disabled={types.length === 0}
|
||||
>
|
||||
<CIcon content={cilSync} />
|
||||
<CIcon icon={cilSync} />
|
||||
</CButton>
|
||||
</CPopover>
|
||||
</div>
|
||||
@@ -154,19 +154,19 @@ const ApiStatusCard = ({ t, info, reload }) => {
|
||||
</CCol>
|
||||
</CRow>
|
||||
</CCardBody>
|
||||
<CModal size="lg" show={showCerts} onClose={toggleCerts}>
|
||||
<CModalHeader className="p-1">
|
||||
<CModalTitle className="pl-1 pt-1">{t('common.certificates')}</CModalTitle>
|
||||
<CModal size="lg" visible={showCerts} onClose={() => setShowCerts(false)}>
|
||||
<CModalHeader closeButton={false} className="p-1">
|
||||
<CModalTitle className="ps-1 pt-1">{t('common.certificates')}</CModalTitle>
|
||||
<div className="text-right">
|
||||
<CPopover content={t('common.close')}>
|
||||
<CPopover content={t('common.close')} trigger="hover" placement="bottom">
|
||||
<CButton color="primary" variant="outline" className="ml-2" onClick={toggleCerts}>
|
||||
<CIcon content={cilX} />
|
||||
<CIcon icon={cilX} />
|
||||
</CButton>
|
||||
</CPopover>
|
||||
</div>
|
||||
</CModalHeader>
|
||||
<CModalBody>
|
||||
<CDataTable
|
||||
<CSmartTable
|
||||
addTableClasses="table-sm"
|
||||
border
|
||||
items={info?.certificates.map((cert) => ({
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
import { CSelect } from '@coreui/react';
|
||||
import { CFormSelect } from '@coreui/react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const LanguageSwitcher = ({ i18n }) => (
|
||||
<CSelect
|
||||
custom
|
||||
<CFormSelect
|
||||
className="custom-select"
|
||||
defaultValue={i18n.language.split('-')[0]}
|
||||
onChange={(e) => i18n.changeLanguage(e.target.value)}
|
||||
>
|
||||
@@ -13,7 +13,7 @@ const LanguageSwitcher = ({ i18n }) => (
|
||||
<option value="en">English</option>
|
||||
<option value="fr">Français</option>
|
||||
<option value="pt">Portugues</option>
|
||||
</CSelect>
|
||||
</CFormSelect>
|
||||
);
|
||||
|
||||
LanguageSwitcher.propTypes = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { CButton, CCol, CForm, CInput, CRow, CSpinner, CAlert, CLink } from '@coreui/react';
|
||||
import { CButton, CCol, CForm, CFormInput, CRow, CSpinner, CAlert, CLink } from '@coreui/react';
|
||||
import PropTypes from 'prop-types';
|
||||
import LanguageSwitcher from '../LanguageSwitcher';
|
||||
import styles from './index.module.scss';
|
||||
@@ -48,7 +48,7 @@ const AccountVerificationForm = ({
|
||||
: t('login.email_code_validation')}
|
||||
</p>
|
||||
<div className="d-flex flex-row">
|
||||
<CInput
|
||||
<CFormInput
|
||||
autoFocus
|
||||
required
|
||||
type="text"
|
||||
@@ -69,7 +69,7 @@ const AccountVerificationForm = ({
|
||||
</div>
|
||||
<CRow className="pt-2">
|
||||
<CCol>
|
||||
<CAlert show={success !== null} color={success ? 'success' : 'danger'}>
|
||||
<CAlert visible={success !== null} color={success ? 'success' : 'danger'}>
|
||||
{t('login.wrong_code')}
|
||||
</CAlert>
|
||||
</CCol>
|
||||
@@ -89,9 +89,12 @@ const AccountVerificationForm = ({
|
||||
>
|
||||
{t('common.access_policy')}
|
||||
</CLink>
|
||||
</CCol>
|
||||
<CCol xs="5" className={styles.forgotPassword}>
|
||||
<CButton variant="ghost" color="primary" onClick={toggleForgotPassword}>
|
||||
<CButton
|
||||
className="float-end"
|
||||
variant="ghost"
|
||||
color="primary"
|
||||
onClick={toggleForgotPassword}
|
||||
>
|
||||
{t('common.back_to_login')}
|
||||
</CButton>
|
||||
</CCol>
|
||||
|
||||
@@ -3,15 +3,14 @@ import {
|
||||
CButton,
|
||||
CCol,
|
||||
CForm,
|
||||
CInput,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupPrepend,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
CSpinner,
|
||||
CPopover,
|
||||
CAlert,
|
||||
CInvalidFeedback,
|
||||
CFormFeedback,
|
||||
CLink,
|
||||
} from '@coreui/react';
|
||||
import PropTypes from 'prop-types';
|
||||
@@ -42,13 +41,11 @@ const ChangePasswordForm = ({
|
||||
<p className="text-muted">{t('login.change_password_instructions')}</p>
|
||||
<CInputGroup className="mb-4">
|
||||
<CPopover content={t('login.password')}>
|
||||
<CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon name="cilLockLocked" content={cilLockLocked} />
|
||||
</CInputGroupText>
|
||||
</CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon name="cilLockLocked" content={cilLockLocked} />
|
||||
</CInputGroupText>
|
||||
</CPopover>
|
||||
<CInput
|
||||
<CFormInput
|
||||
id="newpassword"
|
||||
invalid={fields.newpassword.error}
|
||||
autoFocus
|
||||
@@ -58,17 +55,17 @@ const ChangePasswordForm = ({
|
||||
autoComplete="username"
|
||||
onChange={updateField}
|
||||
/>
|
||||
<CInvalidFeedback className="help-block">{t('login.please_enter_username')}</CInvalidFeedback>
|
||||
<CFormFeedback invalid className="help-block">
|
||||
{t('login.please_enter_username')}
|
||||
</CFormFeedback>
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-4">
|
||||
<CPopover content={t('login.password')}>
|
||||
<CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon content={cilLockLocked} />
|
||||
</CInputGroupText>
|
||||
</CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilLockLocked} />
|
||||
</CInputGroupText>
|
||||
</CPopover>
|
||||
<CInput
|
||||
<CFormInput
|
||||
id="confirmpassword"
|
||||
invalid={fields.confirmpassword.error}
|
||||
required
|
||||
@@ -77,12 +74,14 @@ const ChangePasswordForm = ({
|
||||
autoComplete="current-password"
|
||||
onChange={updateField}
|
||||
/>
|
||||
<CInvalidFeedback className="help-block">{t('login.different_passwords')}</CInvalidFeedback>
|
||||
<CFormFeedback invalid className="help-block">
|
||||
{t('login.different_passwords')}
|
||||
</CFormFeedback>
|
||||
</CInputGroup>
|
||||
<CRow>
|
||||
<CCol>
|
||||
<CAlert
|
||||
show={changePasswordResponse.tried}
|
||||
visible={changePasswordResponse.tried}
|
||||
color={!changePasswordResponse.error ? 'success' : 'danger'}
|
||||
>
|
||||
{changePasswordResponse.text}
|
||||
|
||||
@@ -3,20 +3,19 @@ import {
|
||||
CButton,
|
||||
CCol,
|
||||
CForm,
|
||||
CInput,
|
||||
CFormInput,
|
||||
CInputGroup,
|
||||
CInputGroupPrepend,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
CSpinner,
|
||||
CPopover,
|
||||
CAlert,
|
||||
CInvalidFeedback,
|
||||
CFormFeedback,
|
||||
CLink,
|
||||
} from '@coreui/react';
|
||||
import PropTypes from 'prop-types';
|
||||
import CIcon from '@coreui/icons-react';
|
||||
import { cilUser, cilLink } from '@coreui/icons';
|
||||
import { cilLink, cilUser } from '@coreui/icons';
|
||||
import LanguageSwitcher from '../LanguageSwitcher';
|
||||
import styles from './index.module.scss';
|
||||
|
||||
@@ -42,13 +41,11 @@ const ForgotPasswordForm = ({
|
||||
<p className="text-muted">{t('login.forgot_password_explanation')}</p>
|
||||
<CInputGroup className="mb-4">
|
||||
<CPopover content={t('login.username')}>
|
||||
<CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon name="cilUser" content={cilUser} />
|
||||
</CInputGroupText>
|
||||
</CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilUser} />
|
||||
</CInputGroupText>
|
||||
</CPopover>
|
||||
<CInput
|
||||
<CFormInput
|
||||
id="forgotusername"
|
||||
invalid={fields.forgotusername.error}
|
||||
autoFocus
|
||||
@@ -59,17 +56,17 @@ const ForgotPasswordForm = ({
|
||||
autoComplete="forgotusername"
|
||||
onChange={updateField}
|
||||
/>
|
||||
<CInvalidFeedback className="help-block">{t('login.please_enter_username')}</CInvalidFeedback>
|
||||
<CFormFeedback invalid className="help-block">
|
||||
{t('login.please_enter_username')}
|
||||
</CFormFeedback>
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-4" hidden={fields.ucentralsecurl.hidden}>
|
||||
<CPopover content={t('login.url')}>
|
||||
<CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon name="cilLink" content={cilLink} />
|
||||
</CInputGroupText>
|
||||
</CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilLink} />
|
||||
</CInputGroupText>
|
||||
</CPopover>
|
||||
<CInput
|
||||
<CFormInput
|
||||
id="ucentralsecurl"
|
||||
invalid={fields.ucentralsecurl.error}
|
||||
type="text"
|
||||
@@ -79,11 +76,13 @@ const ForgotPasswordForm = ({
|
||||
autoComplete="gateway-url"
|
||||
onChange={updateField}
|
||||
/>
|
||||
<CInvalidFeedback className="help-block">{t('login.please_enter_gateway')}</CInvalidFeedback>
|
||||
<CFormFeedback invalid className="help-block">
|
||||
{t('login.please_enter_gateway')}
|
||||
</CFormFeedback>
|
||||
</CInputGroup>
|
||||
<CRow>
|
||||
<CCol>
|
||||
<CAlert show={forgotResponse.tried} color={!forgotResponse.error ? 'success' : 'danger'}>
|
||||
<CAlert visible={forgotResponse.tried} color={!forgotResponse.error ? 'success' : 'danger'}>
|
||||
{forgotResponse.text}
|
||||
</CAlert>
|
||||
</CCol>
|
||||
@@ -117,9 +116,12 @@ const ForgotPasswordForm = ({
|
||||
>
|
||||
{t('common.password_policy')}
|
||||
</CLink>
|
||||
</CCol>
|
||||
<CCol xs="5" className={styles.forgotPassword}>
|
||||
<CButton variant="ghost" color="primary" onClick={toggleForgotPassword}>
|
||||
<CButton
|
||||
className="float-end"
|
||||
variant="ghost"
|
||||
color="primary"
|
||||
onClick={toggleForgotPassword}
|
||||
>
|
||||
{t('common.back_to_login')}
|
||||
</CButton>
|
||||
</CCol>
|
||||
|
||||
@@ -3,20 +3,19 @@ import {
|
||||
CButton,
|
||||
CCol,
|
||||
CForm,
|
||||
CInput,
|
||||
CInputGroup,
|
||||
CInputGroupPrepend,
|
||||
CInputGroupText,
|
||||
CRow,
|
||||
CSpinner,
|
||||
CPopover,
|
||||
CAlert,
|
||||
CInvalidFeedback,
|
||||
CLink,
|
||||
CFormInput,
|
||||
CFormFeedback,
|
||||
} from '@coreui/react';
|
||||
import PropTypes from 'prop-types';
|
||||
import CIcon from '@coreui/icons-react';
|
||||
import { cilUser, cilLockLocked, cilLink } from '@coreui/icons';
|
||||
import { cilLink, cilLockLocked, cilUser } from '@coreui/icons';
|
||||
import LanguageSwitcher from '../LanguageSwitcher';
|
||||
import styles from './index.module.scss';
|
||||
|
||||
@@ -42,13 +41,11 @@ const LoginForm = ({
|
||||
<p className="text-muted">{t('login.sign_in_to_account')}</p>
|
||||
<CInputGroup className="mb-4">
|
||||
<CPopover content={t('login.username')}>
|
||||
<CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon name="cilUser" content={cilUser} />
|
||||
</CInputGroupText>
|
||||
</CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilUser} />
|
||||
</CInputGroupText>
|
||||
</CPopover>
|
||||
<CInput
|
||||
<CFormInput
|
||||
id="username"
|
||||
invalid={fields.username.error}
|
||||
autoFocus
|
||||
@@ -58,17 +55,17 @@ const LoginForm = ({
|
||||
autoComplete="username"
|
||||
onChange={updateField}
|
||||
/>
|
||||
<CInvalidFeedback className="help-block">{t('login.please_enter_username')}</CInvalidFeedback>
|
||||
<CFormFeedback invalid className="help-block">
|
||||
{t('login.please_enter_username')}
|
||||
</CFormFeedback>
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-4">
|
||||
<CPopover content={t('login.password')}>
|
||||
<CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon content={cilLockLocked} />
|
||||
</CInputGroupText>
|
||||
</CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilLockLocked} />
|
||||
</CInputGroupText>
|
||||
</CPopover>
|
||||
<CInput
|
||||
<CFormInput
|
||||
id="password"
|
||||
invalid={fields.password.error}
|
||||
required
|
||||
@@ -77,17 +74,17 @@ const LoginForm = ({
|
||||
autoComplete="current-password"
|
||||
onChange={updateField}
|
||||
/>
|
||||
<CInvalidFeedback className="help-block">{t('login.please_enter_password')}</CInvalidFeedback>
|
||||
<CFormFeedback invalid className="help-block">
|
||||
{t('login.please_enter_password')}
|
||||
</CFormFeedback>
|
||||
</CInputGroup>
|
||||
<CInputGroup className="mb-4" hidden={fields.ucentralsecurl.hidden}>
|
||||
<CPopover content={t('login.url')}>
|
||||
<CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon name="cilLink" content={cilLink} />
|
||||
</CInputGroupText>
|
||||
</CInputGroupPrepend>
|
||||
<CInputGroupText>
|
||||
<CIcon icon={cilLink} />
|
||||
</CInputGroupText>
|
||||
</CPopover>
|
||||
<CInput
|
||||
<CFormInput
|
||||
id="ucentralsecurl"
|
||||
invalid={fields.ucentralsecurl.error}
|
||||
type="text"
|
||||
@@ -97,22 +94,24 @@ const LoginForm = ({
|
||||
autoComplete="gateway-url"
|
||||
onChange={updateField}
|
||||
/>
|
||||
<CInvalidFeedback className="help-block">{t('login.please_enter_gateway')}</CInvalidFeedback>
|
||||
<CFormFeedback invalid className="help-block">
|
||||
{t('login.please_enter_gateway')}
|
||||
</CFormFeedback>
|
||||
</CInputGroup>
|
||||
<CRow>
|
||||
<CCol>
|
||||
<CAlert show={loginResponse.tried} color={!loginResponse.error ? 'success' : 'danger'}>
|
||||
<CAlert visible={loginResponse.tried} color={!loginResponse.error ? 'success' : 'danger'}>
|
||||
{loginResponse.text}
|
||||
</CAlert>
|
||||
</CCol>
|
||||
</CRow>
|
||||
<div className="d-flex flex-row align-middle">
|
||||
<div>
|
||||
<CButton color="primary" className="px-4" onClick={signIn} disabled={loading}>
|
||||
{loading ? t('login.logging_in') : t('login.login')}
|
||||
<CSpinner hidden={!loading} color="light" component="span" size="sm" />
|
||||
</CButton>
|
||||
<CLink
|
||||
className="c-subheader-nav-link px-3 align-self-center"
|
||||
className="c-subheader-nav-link mx-2 align-self-center"
|
||||
aria-current="page"
|
||||
href={policies.accessPolicy}
|
||||
target="_blank"
|
||||
@@ -129,7 +128,7 @@ const LoginForm = ({
|
||||
>
|
||||
{t('common.password_policy')}
|
||||
</CLink>
|
||||
<CButton className="ml-auto" variant="ghost" color="primary" onClick={toggleForgotPassword}>
|
||||
<CButton className="float-end" variant="ghost" color="primary" onClick={toggleForgotPassword}>
|
||||
{t('common.forgot_password')}
|
||||
</CButton>
|
||||
</div>
|
||||
|
||||
@@ -92,12 +92,12 @@ const LoginPage = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="c-app c-default-layout flex-row align-items-center">
|
||||
<div className="bg-light min-vh-100 d-flex flex-row align-items-center">
|
||||
<CContainer>
|
||||
<CRow className="justify-content-center">
|
||||
<CCol md="8">
|
||||
<img
|
||||
className={[styles.logo, 'c-sidebar-brand-full'].join(' ')}
|
||||
className={[styles.logo, 'sidebar-brand-full'].join(' ')}
|
||||
src={logo}
|
||||
alt="OpenWifi"
|
||||
/>
|
||||
|
||||
@@ -7,7 +7,3 @@
|
||||
float: right;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.forgotPassword {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@ export const ToastProvider = ({ children }) => {
|
||||
<CToast
|
||||
key={`toast${toast.key}`}
|
||||
autohide={toast.autohide ? 5000 : null}
|
||||
fade
|
||||
animation
|
||||
color={toast.color}
|
||||
className="text-white align-items-center"
|
||||
show
|
||||
className="text-white align-items-center m-0 p-0"
|
||||
visible
|
||||
>
|
||||
<CToastHeader closeButton={toast.closeButton}>{toast.title}</CToastHeader>
|
||||
<div className="d-flex">
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CFooter } from '@coreui/react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const TheFooter = ({ t, version }) => (
|
||||
<CFooter fixed={false}>
|
||||
<CFooter>
|
||||
<div>
|
||||
{t('footer.version')} {version}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
CHeader,
|
||||
CToggler,
|
||||
CHeaderToggler,
|
||||
CHeaderBrand,
|
||||
CHeaderNav,
|
||||
CSubheader,
|
||||
@@ -9,11 +9,12 @@ import {
|
||||
CDropdown,
|
||||
CDropdownToggle,
|
||||
CDropdownMenu,
|
||||
CContainer,
|
||||
CDropdownItem,
|
||||
} from '@coreui/react';
|
||||
import PropTypes from 'prop-types';
|
||||
import CIcon from '@coreui/icons-react';
|
||||
import { cilAccountLogout } from '@coreui/icons';
|
||||
import { cilAccountLogout, cilMenu } from '@coreui/icons';
|
||||
import LanguageSwitcher from '../../components/LanguageSwitcher';
|
||||
import Avatar from '../../components/Avatar';
|
||||
|
||||
@@ -31,18 +32,11 @@ const Header = ({
|
||||
avatar,
|
||||
hideBreadcrumb,
|
||||
extraButton,
|
||||
hideSidebarButton,
|
||||
}) => {
|
||||
const [translatedRoutes, setTranslatedRoutes] = useState(routes);
|
||||
|
||||
const toggleSidebar = () => {
|
||||
const val = [true, 'responsive'].includes(showSidebar) ? false : 'responsive';
|
||||
setShowSidebar(val);
|
||||
};
|
||||
|
||||
const toggleSidebarMobile = () => {
|
||||
const val = [false, 'responsive'].includes(showSidebar) ? true : 'responsive';
|
||||
setShowSidebar(val);
|
||||
setShowSidebar(!showSidebar);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -50,55 +44,54 @@ const Header = ({
|
||||
}, [i18n.language]);
|
||||
|
||||
return (
|
||||
<CHeader withSubheader>
|
||||
{hideSidebarButton ? null : (
|
||||
<>
|
||||
<CToggler inHeader className="ml-md-3 d-lg-none" onClick={toggleSidebarMobile} />
|
||||
<CToggler inHeader className="ml-3 d-md-down-none" onClick={toggleSidebar} />
|
||||
</>
|
||||
)}
|
||||
<CHeaderBrand className="mx-auto d-lg-none" to="/">
|
||||
<img
|
||||
src={logo}
|
||||
alt="OpenWifi"
|
||||
className="c-sidebar-brand-full"
|
||||
style={{ height: '75px', width: '175px' }}
|
||||
/>
|
||||
</CHeaderBrand>
|
||||
|
||||
<CHeaderNav className="d-md-down-none mr-auto" />
|
||||
|
||||
<CHeaderNav>{extraButton}</CHeaderNav>
|
||||
|
||||
<CHeaderNav className="px-3">
|
||||
<LanguageSwitcher i18n={i18n} />
|
||||
</CHeaderNav>
|
||||
|
||||
<CHeaderNav className="px-1">
|
||||
<CDropdown inNav className="c-header-nav-items mx-2" direction="down">
|
||||
<CDropdownToggle className="c-header-nav-link" caret={false}>
|
||||
<Avatar src={avatar} fallback={user.email} />
|
||||
</CDropdownToggle>
|
||||
<CDropdownMenu className="pt-0" placement="bottom-end">
|
||||
<CDropdownItem to={() => '/myprofile'}>
|
||||
<div className="px-3">{t('user.my_profile')}</div>
|
||||
</CDropdownItem>
|
||||
<CDropdownItem onClick={() => logout(authToken, endpoints.owsec)}>
|
||||
<strong className="px-3">{t('common.logout')}</strong>
|
||||
<CIcon name="cilAccountLogout" content={cilAccountLogout} />
|
||||
</CDropdownItem>
|
||||
</CDropdownMenu>
|
||||
</CDropdown>
|
||||
</CHeaderNav>
|
||||
|
||||
{hideBreadcrumb ? null : (
|
||||
<CSubheader hidden={hideBreadcrumb} className="px-3 justify-content-between">
|
||||
<CBreadcrumbRouter
|
||||
className="border-0 c-subheader-nav m-0 px-0 px-md-3"
|
||||
routes={translatedRoutes}
|
||||
<CHeader position="fixed" className="py-0">
|
||||
<CContainer fluid>
|
||||
<CHeaderToggler onClick={toggleSidebar} className="ps-1">
|
||||
<CIcon icon={cilMenu} />
|
||||
</CHeaderToggler>
|
||||
<CHeaderBrand className="mx-auto d-md-none" to="/">
|
||||
<img
|
||||
src={logo}
|
||||
alt="OpenWifi"
|
||||
className="c-sidebar-brand-full"
|
||||
style={{ height: '75px', width: '175px' }}
|
||||
/>
|
||||
</CSubheader>
|
||||
)}
|
||||
</CHeaderBrand>
|
||||
|
||||
<CHeaderNav>{extraButton}</CHeaderNav>
|
||||
|
||||
<CHeaderNav className="px-1">
|
||||
<LanguageSwitcher i18n={i18n} />
|
||||
</CHeaderNav>
|
||||
|
||||
<CHeaderNav className="px-1">
|
||||
<CDropdown variant="nav-item">
|
||||
<CDropdownToggle className="c-header-nav-link" caret={false}>
|
||||
<Avatar src={avatar} fallback={user.email} />
|
||||
</CDropdownToggle>
|
||||
<CDropdownMenu className="pt-0" placement="bottom-end">
|
||||
<CDropdownItem href="/myprofile">
|
||||
<div className="px-3">{t('user.my_profile')}</div>
|
||||
</CDropdownItem>
|
||||
<CDropdownItem onClick={() => logout(authToken, endpoints.owsec)}>
|
||||
<strong className="px-3">{t('common.logout')}</strong>
|
||||
<CIcon icon={cilAccountLogout} />
|
||||
</CDropdownItem>
|
||||
</CDropdownMenu>
|
||||
</CDropdown>
|
||||
</CHeaderNav>
|
||||
|
||||
{hideBreadcrumb ? null : (
|
||||
<CContainer fluid>
|
||||
<CSubheader hidden={hideBreadcrumb} className="px-3 justify-content-between">
|
||||
<CBreadcrumbRouter
|
||||
className="border-0 c-subheader-nav m-0 px-0 px-md-3"
|
||||
routes={translatedRoutes}
|
||||
/>
|
||||
</CSubheader>
|
||||
</CContainer>
|
||||
)}
|
||||
</CContainer>
|
||||
</CHeader>
|
||||
);
|
||||
};
|
||||
@@ -117,13 +110,11 @@ Header.propTypes = {
|
||||
avatar: PropTypes.string.isRequired,
|
||||
hideBreadcrumb: PropTypes.bool,
|
||||
extraButton: PropTypes.node,
|
||||
hideSidebarButton: PropTypes.bool,
|
||||
};
|
||||
|
||||
Header.defaultProps = {
|
||||
extraButton: null,
|
||||
hideBreadcrumb: false,
|
||||
hideSidebarButton: false,
|
||||
};
|
||||
|
||||
export default React.memo(Header);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import React, { Suspense } from 'react';
|
||||
import { Redirect, Route, Switch } from 'react-router-dom';
|
||||
import { v4 as createUuid } from 'uuid';
|
||||
import { CContainer, CFade } from '@coreui/react';
|
||||
import { CContainer } from '@coreui/react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const loading = (
|
||||
@@ -12,31 +12,29 @@ const loading = (
|
||||
);
|
||||
|
||||
const PageContainer = ({ t, routes, redirectTo }) => (
|
||||
<main className="c-main py-2">
|
||||
<CContainer className="px-2" fluid>
|
||||
<Suspense fallback={loading}>
|
||||
<Switch>
|
||||
{routes.map(
|
||||
(route) =>
|
||||
route.component && (
|
||||
<Route
|
||||
key={createUuid()}
|
||||
path={route.path}
|
||||
exact={route.exact}
|
||||
name={t(route.name)}
|
||||
render={(props) => (
|
||||
<CFade>
|
||||
<route.component {...props} />
|
||||
</CFade>
|
||||
)}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
<Redirect from="/" to={redirectTo} />
|
||||
</Switch>
|
||||
</Suspense>
|
||||
</CContainer>
|
||||
</main>
|
||||
<CContainer fluid>
|
||||
<Suspense fallback={loading}>
|
||||
<Switch>
|
||||
{routes.map(
|
||||
(route) =>
|
||||
route.component && (
|
||||
<Route
|
||||
key={createUuid()}
|
||||
path={route.path}
|
||||
exact={route.exact}
|
||||
name={t(route.name)}
|
||||
render={(props) => (
|
||||
<>
|
||||
<route.component {...props} />
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
<Redirect from="/" to={redirectTo} />
|
||||
</Switch>
|
||||
</Suspense>
|
||||
</CContainer>
|
||||
);
|
||||
|
||||
PageContainer.propTypes = {
|
||||
|
||||
66
src/layout/Sidebar/CreateElements.js
Normal file
66
src/layout/Sidebar/CreateElements.js
Normal file
@@ -0,0 +1,66 @@
|
||||
import React from 'react';
|
||||
import { NavLink, useLocation } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CBadge } from '@coreui/react';
|
||||
|
||||
const CreateElements = ({ items }) => {
|
||||
const location = useLocation();
|
||||
const navLink = (name, icon, badge) => (
|
||||
<>
|
||||
{icon && icon}
|
||||
{name && name}
|
||||
{badge && (
|
||||
<CBadge color={badge.color} className="ms-auto">
|
||||
{badge.text}
|
||||
</CBadge>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
const navItem = (item, index) => {
|
||||
const { component, name, badge, icon, ...rest } = item;
|
||||
const Component = component;
|
||||
return (
|
||||
<Component
|
||||
{...(rest.to &&
|
||||
!rest.items && {
|
||||
component: NavLink,
|
||||
activeClassName: 'active',
|
||||
})}
|
||||
key={index}
|
||||
{...rest}
|
||||
>
|
||||
{navLink(name, icon, badge)}
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
const navGroup = (item, index) => {
|
||||
const { component, name, icon, to, ...rest } = item;
|
||||
const Component = component;
|
||||
return (
|
||||
<Component
|
||||
idx={String(index)}
|
||||
key={index}
|
||||
toggler={navLink(name, icon)}
|
||||
visible={location.pathname.startsWith(to)}
|
||||
{...rest}
|
||||
>
|
||||
{item.items?.map((it, i) => (it.items ? navGroup(it, i) : navItem(it, i)))}
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{items &&
|
||||
items.map((item, index) => (item.items ? navGroup(item, index) : navItem(item, index)))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
CreateElements.propTypes = {
|
||||
items: PropTypes.arrayOf(PropTypes.any).isRequired,
|
||||
};
|
||||
|
||||
export default CreateElements;
|
||||
@@ -1,17 +1,8 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
CCreateElement,
|
||||
CSidebar,
|
||||
CSidebarBrand,
|
||||
CSidebarNav,
|
||||
CSidebarNavDivider,
|
||||
CSidebarNavTitle,
|
||||
CSidebarMinimizer,
|
||||
CSidebarNavDropdown,
|
||||
CSidebarNavItem,
|
||||
} from '@coreui/react';
|
||||
import { CSidebar, CSidebarBrand, CSidebarNav } from '@coreui/react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './index.module.scss';
|
||||
import CreateElements from './CreateElements';
|
||||
|
||||
const Sidebar = ({
|
||||
showSidebar,
|
||||
@@ -22,33 +13,24 @@ const Sidebar = ({
|
||||
logoHeight,
|
||||
logoWidth,
|
||||
}) => (
|
||||
<CSidebar show={showSidebar} onShowChange={(val) => setShowSidebar(val)}>
|
||||
<CSidebarBrand className="d-md-down-none" to={redirectTo}>
|
||||
<CSidebar
|
||||
size="sm"
|
||||
position="fixed"
|
||||
unfoldable={false}
|
||||
visible={showSidebar}
|
||||
onVisibleChange={(val) => setShowSidebar(val)}
|
||||
>
|
||||
<CSidebarBrand className="d-none d-md-flex" to={redirectTo}>
|
||||
<img
|
||||
className={[styles.sidebarImgFull, 'c-sidebar-brand-full'].join(' ')}
|
||||
style={{ height: logoHeight ?? undefined, width: logoWidth ?? undefined }}
|
||||
src={logo}
|
||||
alt="OpenWifi"
|
||||
/>
|
||||
<img
|
||||
className={[styles.sidebarImgMinimized, 'c-sidebar-brand-minimized'].join(' ')}
|
||||
style={{ height: logoHeight ?? undefined, width: logoWidth ?? undefined }}
|
||||
src={logo}
|
||||
alt="OpenWifi"
|
||||
/>
|
||||
</CSidebarBrand>
|
||||
<CSidebarNav>
|
||||
<CCreateElement
|
||||
items={options}
|
||||
components={{
|
||||
CSidebarNavDivider,
|
||||
CSidebarNavDropdown,
|
||||
CSidebarNavItem,
|
||||
CSidebarNavTitle,
|
||||
}}
|
||||
/>
|
||||
<CreateElements items={options} />
|
||||
</CSidebarNav>
|
||||
<CSidebarMinimizer className="c-d-md-down-none" />
|
||||
</CSidebar>
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user