mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
Migrate from Vue to React framework.
This commit is contained in:
@@ -1,19 +0,0 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App',
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import 'style/style.scss';
|
||||
|
||||
body{
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
2
client/src/actions/accounts/index.js
Normal file
2
client/src/actions/accounts/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
export const FETCH_ACCOUNTS_CHART = 'FETCH_ACCOUNTS_CHART';
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.7 KiB |
18
client/src/components/DashboardContent/index.js
Normal file
18
client/src/components/DashboardContent/index.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import dashboardRoutes from 'routes/dashboard'
|
||||
|
||||
export default function() {
|
||||
return (
|
||||
<Switch>
|
||||
{ dashboardRoutes.map((route, index) => (
|
||||
<Route
|
||||
key={index}
|
||||
path={route.path}
|
||||
exact={route.exact}
|
||||
component={route.component}
|
||||
/>
|
||||
))}
|
||||
</Switch>
|
||||
)
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>\{{ msg }}</h1>
|
||||
<h2>Essential Links</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="https://vuejs.org"
|
||||
target="_blank"
|
||||
>
|
||||
Core Docs
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://forum.vuejs.org"
|
||||
target="_blank"
|
||||
>
|
||||
Forum
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://chat.vuejs.org"
|
||||
target="_blank"
|
||||
>
|
||||
Community Chat
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://twitter.com/vuejs"
|
||||
target="_blank"
|
||||
>
|
||||
Twitter
|
||||
</a>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<a
|
||||
href="http://vuejs-templates.github.io/webpack/"
|
||||
target="_blank"
|
||||
>
|
||||
Docs for This Template
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Ecosystem</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="http://router.vuejs.org/"
|
||||
target="_blank"
|
||||
>
|
||||
vue-router
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="http://vuex.vuejs.org/"
|
||||
target="_blank"
|
||||
>
|
||||
vuex
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="http://vue-loader.vuejs.org/"
|
||||
target="_blank"
|
||||
>
|
||||
vue-loader
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/awesome-vue"
|
||||
target="_blank"
|
||||
>
|
||||
awesome-vue
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
data() {
|
||||
return {
|
||||
msg: 'Welcome to Your Vue.js App',
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h1, h2 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
9
client/src/components/Sideabr/SidebarContainer.js
Normal file
9
client/src/components/Sideabr/SidebarContainer.js
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
export default function() {
|
||||
return (
|
||||
<div class="sidebar" id="sidebar">
|
||||
|
||||
</div>
|
||||
)
|
||||
};
|
||||
19
client/src/components/Sideabr/SidebarHead.js
Normal file
19
client/src/components/Sideabr/SidebarHead.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function() {
|
||||
return (
|
||||
<div class="sidebar__head">
|
||||
<div class="sidebar__head-logo">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="sidebar__head-company-meta">
|
||||
<span class="comapny-name">
|
||||
|
||||
</span>
|
||||
|
||||
<span class="company-meta"></span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
30
client/src/components/Sideabr/index.js
Normal file
30
client/src/components/Sideabr/index.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
Switch,
|
||||
Route,
|
||||
} from 'react-router-dom';
|
||||
import SidebarContainer from './SidebarContainer';
|
||||
import SidebarHead from './SidebarHead';
|
||||
import sidebarRoutes from '../../routes/sidebar';
|
||||
|
||||
export default function Sidebar() {
|
||||
return (
|
||||
<SidebarContainer>
|
||||
<SidebarHead />
|
||||
|
||||
<div className="sidebar__menu">
|
||||
<Menu>
|
||||
{ sidebarRoutes.map((route, index) => (
|
||||
<Route
|
||||
key={index}
|
||||
path={route.path}
|
||||
exact={route.exact}
|
||||
children={<route.sidebar />}
|
||||
/>
|
||||
))}
|
||||
</Menu>
|
||||
</div>
|
||||
</SidebarContainer>
|
||||
)
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
<template>
|
||||
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
|
||||
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
|
||||
<use :xlink:href="iconName" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SvgIcon',
|
||||
props: {
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isExternal() {
|
||||
return Boolean(this.iconClass)
|
||||
},
|
||||
iconName() {
|
||||
return `#icon-${this.iconClass}`;
|
||||
},
|
||||
svgClass() {
|
||||
if (this.className) {
|
||||
return `svg-icon ${this.className}`;
|
||||
}
|
||||
return 'svg-icon';
|
||||
},
|
||||
styleExternalIcon() {
|
||||
return {
|
||||
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
|
||||
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.svg-external-icon {
|
||||
background-color: currentColor;
|
||||
mask-size: cover!important;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
17
client/src/enhancers/monitorReducer.js
Normal file
17
client/src/enhancers/monitorReducer.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const round = number => Math.round(number * 100) / 100
|
||||
const monitorReducerEnhancer = createStore => (
|
||||
reducer,
|
||||
initialState,
|
||||
enhancer
|
||||
) => {
|
||||
const monitoredReducer = (state, action) => {
|
||||
const start = performance.now()
|
||||
const newState = reducer(state, action)
|
||||
const end = performance.now()
|
||||
const diff = round(end - start)
|
||||
console.log('reducer process time:', diff)
|
||||
return newState
|
||||
}
|
||||
return createStore(monitoredReducer, initialState, enhancer)
|
||||
}
|
||||
export default monitorReducerEnhancer
|
||||
30
client/src/index.js
Normal file
30
client/src/index.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { createStore, applyMiddleware, compose } from 'redux';
|
||||
import { Provider } from 'react-redux';
|
||||
import rootReducer from './reducers';
|
||||
import thunkMiddleware from 'redux-thunk';
|
||||
import monitorReducerEnhancer from './enhancers/monitorReducer';
|
||||
// import axios from 'axios';
|
||||
import App from './pages/App';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
import loggerMiddleware from './middleware/logger'
|
||||
|
||||
const middlewareEnhancer = applyMiddleware(loggerMiddleware, thunkMiddleware)
|
||||
const composedEnhancers = compose(
|
||||
middlewareEnhancer,
|
||||
monitorReducerEnhancer,
|
||||
)
|
||||
const store = createStore(rootReducer, undefined, composedEnhancers);
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
@@ -1,22 +0,0 @@
|
||||
export default {
|
||||
login: 'Login',
|
||||
password: 'Password',
|
||||
username_password: 'Username or Email',
|
||||
with_your_account: 'With your Ratteb account.',
|
||||
if_you_forget_your_password: 'If you forgot your password, well, enter your Moosher ID than secret key to reset your password.',
|
||||
sign_in: 'Sign in',
|
||||
dashboard: 'Dashboard',
|
||||
reset_the_password: 'Reset the Password',
|
||||
enter_your_new_password: 'Enter You New Password',
|
||||
reset_password_link_is_invalid: 'The link is invalid or expired. Please reset your password again.',
|
||||
your_password_has_been_changed: 'Success Your password has been changed.',
|
||||
username_password_do_not_match: 'The username and password you entered did not match our records.',
|
||||
the_account_suspended_please_contact: 'This account is suspended, Please contact the administrator.',
|
||||
email_has_been_sent: 'An e-mail has been sent to {email} with further instructions.',
|
||||
there_is_no_email_with_that_address: 'There is no email with that address, Please try again.',
|
||||
reset_your_password: 'Reset Your Password',
|
||||
return_to_login: 'Return to Login',
|
||||
forget_password: 'Forget your password?',
|
||||
reset_password: 'Reset Password',
|
||||
email_password_do_not_match: 'Email and password do not match.',
|
||||
};
|
||||
7
client/src/logo.svg
Normal file
7
client/src/logo.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
|
||||
<g fill="#61DAFB">
|
||||
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
|
||||
<circle cx="420.9" cy="296.5" r="45.7"/>
|
||||
<path d="M520.5 78.1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -1,28 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
import {Form, FormItem, Input, Tabs, TabPane, Button, Alert} from 'element-ui';
|
||||
import App from '@/App';
|
||||
import router from '@/router';
|
||||
import store from '@/store';
|
||||
import '@/plugins/icons';
|
||||
|
||||
// Plugins
|
||||
import '@/plugins/i18n';
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
Vue.use(Form);
|
||||
Vue.use(FormItem);
|
||||
Vue.use(Input);
|
||||
Vue.use(Tabs);
|
||||
Vue.use(TabPane);
|
||||
Vue.use(Button);
|
||||
Vue.use(Alert);
|
||||
|
||||
const app = new Vue({
|
||||
el: '#app',
|
||||
render: h => h(App),
|
||||
router,
|
||||
store,
|
||||
});
|
||||
|
||||
export default app;
|
||||
9
client/src/middleware/logger.js
Normal file
9
client/src/middleware/logger.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const logger = store => next => action => {
|
||||
console.group(action.type)
|
||||
console.info('dispatching', action)
|
||||
let result = next(action)
|
||||
console.log('next state', store.getState())
|
||||
console.groupEnd()
|
||||
return result
|
||||
}
|
||||
export default logger
|
||||
@@ -1,20 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'reloadable',
|
||||
created() {
|
||||
this.$eventBus.$on('reload-data', this.onReloadData);
|
||||
},
|
||||
methods: {
|
||||
async onReloadData() {
|
||||
this.$nprogress.start();
|
||||
await this.reloadData();
|
||||
this.$nprogress.done();
|
||||
},
|
||||
|
||||
reloadData() {},
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$eventBus.$off('reload-data', this.onReloadData);
|
||||
},
|
||||
});
|
||||
12
client/src/pages/App.js
Normal file
12
client/src/pages/App.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import Authentication from 'pages/Authentication';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<h1>Hello World</h1>
|
||||
<Authentication />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default App;
|
||||
@@ -1,207 +0,0 @@
|
||||
<template>
|
||||
<div class="page-auth page-auth--login">
|
||||
<div class="page-auth__content-side">
|
||||
<div class="page-auth__content-header">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="page-auth__content-form">
|
||||
<transition name="fade" mode="out-in">
|
||||
<router-view></router-view>
|
||||
</transition>
|
||||
</div>
|
||||
|
||||
<AuthFooter></AuthFooter>
|
||||
</div>
|
||||
|
||||
<AuthMedia></AuthMedia>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AuthMedia from '@/pages/Auth/AuthMedia.vue';
|
||||
import AuthFooter from '@/pages/Auth/AuthFooter.vue';
|
||||
|
||||
export default {
|
||||
name: 'auth-container',
|
||||
components: {
|
||||
AuthMedia,
|
||||
AuthFooter,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.page-auth{
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
|
||||
&__content-side{
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
// @include media-breakpoint-up('lg'){
|
||||
width: 62%;
|
||||
// }
|
||||
|
||||
.remember-forget-wrapper{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 20px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.form-note{
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.btn-primary{
|
||||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
&__content{
|
||||
|
||||
&-header{
|
||||
max-width: 440px;
|
||||
width: 100%;
|
||||
padding: 0 30px;
|
||||
margin: 0 auto;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
// @include media-breakpoint-down('xs'){
|
||||
// padding-top: 25px;
|
||||
// padding-left: 25px;
|
||||
// padding-right: 25px;
|
||||
// }
|
||||
|
||||
.icon-logo{
|
||||
// @include media-breakpoint-down('xs'){
|
||||
// width: 140px;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
&-title{
|
||||
font-size: 42px;
|
||||
font-weight: 300;
|
||||
letter-spacing: -0.025em;
|
||||
color: #253992;
|
||||
line-height: 1.2;
|
||||
padding-bottom: 23px;
|
||||
font-size: 2.4em;
|
||||
|
||||
// @include media-breakpoint-down('xs'){
|
||||
// font-size: 2.2rem;
|
||||
// }
|
||||
|
||||
small{
|
||||
font-size: 0.46em;
|
||||
display: block;
|
||||
font-weight: 400;
|
||||
color: #495463;
|
||||
letter-spacing: normal;
|
||||
margin-top: 10px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.text-success{
|
||||
color: #00d285;
|
||||
font-size: 0.41em;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&-form{
|
||||
width: 440px;
|
||||
max-width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 40px 30px 50px;
|
||||
|
||||
// @include media-breakpoint-down('xs'){
|
||||
// padding-left: 25px;
|
||||
// padding-right: 25px;
|
||||
// }
|
||||
}
|
||||
|
||||
&-footer{
|
||||
margin: 0 auto;
|
||||
width: 440px;
|
||||
max-width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 0 30px;
|
||||
padding-bottom: 25px;
|
||||
|
||||
.footer-links{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
li{
|
||||
padding: 2px 15px;
|
||||
font-size: 13px;
|
||||
color: #758698;
|
||||
display: inline-block;
|
||||
|
||||
&:first-child{
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
&:last-child{
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a{
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
|
||||
&:hover{
|
||||
color: #2c80ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Media Side **/
|
||||
&__media-side{
|
||||
display: flex;
|
||||
width: 38%;
|
||||
background-image: url('/images/cover.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
position: relative;
|
||||
background-position: 50% 0;
|
||||
|
||||
// @include media-breakpoint-down('md'){
|
||||
// width: 38%;
|
||||
// }
|
||||
|
||||
// @include media-breakpoint-down('xs'){
|
||||
// display: none;
|
||||
// }
|
||||
}
|
||||
|
||||
&__media-overlay{
|
||||
position: absolute;
|
||||
background: #202141;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
opacity: 0.65;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,15 +0,0 @@
|
||||
<template>
|
||||
<div class="page-auth__content-footer">
|
||||
<ul class="footer-links">
|
||||
<li><a href="#">{{ $t('privacy_policy') }}</a></li>
|
||||
<li><a href="#">{{ $t('terms_and_conditions') }}</a></li>
|
||||
<li>© 2019 Moosher.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'auth-footer',
|
||||
}
|
||||
</script>
|
||||
@@ -1,11 +0,0 @@
|
||||
<template>
|
||||
<div class="page-auth__media-side">
|
||||
<div class="page-auth__media-overlay"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'auth-media',
|
||||
};
|
||||
</script>
|
||||
@@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<div id="reset-password">
|
||||
<h2 class="page-auth__content-title">
|
||||
{{ $t('reset_your_password') }}
|
||||
<small>{{ $t('if_you_forget_your_password') }}</small>
|
||||
</h2>
|
||||
|
||||
<el-form ref="form" class="form-container">
|
||||
<el-form-item :label="$t('username_password')" prop="title">
|
||||
<el-input v-model="form.crediential" :maxlength="100" name="name" required />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-button type="primary">{{ $t('reset_password') }}</el-button>
|
||||
|
||||
<div class="form-note">
|
||||
<router-link :to="{name: 'login'}">{{ $t('return_to_login') }}</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'forget-password',
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
crediential: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['login']),
|
||||
|
||||
/**
|
||||
* Handle the submitting the reset password form.
|
||||
*/
|
||||
onSubmit() {
|
||||
const form = {};
|
||||
|
||||
this.sendResetPassword({ form }).then(() => {
|
||||
// console.log(response);
|
||||
}).catch(() => {
|
||||
// console.log(error);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,90 +0,0 @@
|
||||
<template>
|
||||
<div class="login">
|
||||
<h2 class="page-auth__content-title">
|
||||
{{ $t('sign_in') }}
|
||||
<small>{{ $t('with_your_account') }}</small>
|
||||
</h2>
|
||||
|
||||
<el-alert :active="isCredentialError" :type="'error'">
|
||||
{{ $t('email_password_do_not_match') }}
|
||||
</el-alert>
|
||||
|
||||
<el-alert :isActive="isInactiveError" :type="'error'">
|
||||
{{ $t('the_account_suspended_please_contact') }}
|
||||
</el-alert>
|
||||
|
||||
<el-alert :isActive="isResetPasswordSuccess" type="success">
|
||||
{{ $t('your_password_has_been_changed') }}
|
||||
</el-alert>
|
||||
|
||||
<el-form ref="form" class="form-container">
|
||||
<el-form-item :label="$t('username_password')" prop="title">
|
||||
<el-input v-model="form.crediential" :maxlength="100" name="name" required />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('password')">
|
||||
<el-input v-model="form.password" name="password" />
|
||||
</el-form-item>
|
||||
|
||||
<el-button type="primary">{{ $t('login') }}</el-button>
|
||||
</el-form>
|
||||
|
||||
<div class="form-note">
|
||||
<div class="forget-password">
|
||||
<router-link :to="{name: 'forgetPassword'}">{{ $t('forget_password') }}</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex';
|
||||
|
||||
const STATE = {
|
||||
USER_NOT_ACTIVE: 1,
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'login',
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
username: '',
|
||||
password: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isCredentialError() {
|
||||
return false;
|
||||
},
|
||||
isInactiveError() {
|
||||
return false;
|
||||
},
|
||||
isResetPasswordSuccess() {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['login']),
|
||||
|
||||
/**
|
||||
* Handle the submitting the login form.
|
||||
*/
|
||||
onSubmit() {
|
||||
const form = {};
|
||||
|
||||
this.login({ form }).then(() => {
|
||||
this.$route.push({ name: 'dashboard.home' });
|
||||
}).catch((error) => {
|
||||
const { response } = error;
|
||||
const { data } = response;
|
||||
|
||||
if (data.error.type === 'USER_NOT_ACTIVE') {
|
||||
this.current_state = STATE.USER_NOT_ACTIVE;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,79 +0,0 @@
|
||||
|
||||
<template>
|
||||
<div class="reset-password" id="reset-password">
|
||||
<el-form ref="form" class="form-container">
|
||||
<el-form-item :label="$t('password')" prop="title">
|
||||
<el-input v-model="form.password" :maxlength="100" name="password" required />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('confirm_password')">
|
||||
<el-input v-model="form.confirm_password" name="confirm_password" />
|
||||
</el-form-item>
|
||||
|
||||
<el-button @click.prevent="onSubmit" type="primary">
|
||||
{{ $t('reset_the_password') }}
|
||||
</el-button>
|
||||
<el-link>{{ $t('forget_your_password') }}</el-link>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex';
|
||||
|
||||
const STATE = {
|
||||
SUCCESS: 1,
|
||||
TOKEN_INVALID: 2,
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'reset-password',
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
password: '',
|
||||
confirm_password: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
props: {
|
||||
token: {
|
||||
required: true,
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
||||
isSuccess() {
|
||||
return this.current_state === STATE.SUCCESS;
|
||||
},
|
||||
isTokenInvalid() {
|
||||
return this.current_state === STATE.TOKEN_INVALID;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['newPassword']),
|
||||
|
||||
/**
|
||||
* Handle the submitting the reset password form.
|
||||
*/
|
||||
onSubmit() {
|
||||
const form = {
|
||||
...this.form,
|
||||
token: this.token,
|
||||
};
|
||||
|
||||
this.newPassword({ form }).then(() => {
|
||||
this.$router.push({ name: 'login' });
|
||||
}).catch((error) => {
|
||||
const { response } = error;
|
||||
const { data } = response;
|
||||
|
||||
if (data.error.type === 'token.invalid') {
|
||||
this.current_status = STATE.TOKEN_INVALID;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
25
client/src/pages/Authentication/Login.js
Normal file
25
client/src/pages/Authentication/Login.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
Button,
|
||||
InputGroup,
|
||||
} from "@blueprintjs/core";
|
||||
|
||||
export default function Login() {
|
||||
return (
|
||||
<div class="login-page">
|
||||
<InputGroup
|
||||
leftIcon="filter"
|
||||
placeholder="Email or phone number"
|
||||
/>
|
||||
|
||||
<InputGroup
|
||||
leftIcon="filter"
|
||||
placeholder="Password"
|
||||
/>
|
||||
|
||||
<Button>
|
||||
{"Login"}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
20
client/src/pages/Authentication/ResetPassword.js
Normal file
20
client/src/pages/Authentication/ResetPassword.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
Button,
|
||||
InputGroup,
|
||||
} from "@blueprintjs/core";
|
||||
|
||||
export default function Login() {
|
||||
return (
|
||||
<div class="login-page">
|
||||
<InputGroup
|
||||
leftIcon="filter"
|
||||
placeholder="Email or phone number"
|
||||
/>
|
||||
|
||||
<Button>
|
||||
{"Reset password"}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
25
client/src/pages/Authentication/index.js
Normal file
25
client/src/pages/Authentication/index.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
|
||||
import authenticationRoutes from 'routes/authentication';
|
||||
|
||||
export default function() {
|
||||
return (
|
||||
<div class="authentication-page">
|
||||
<Router>
|
||||
<Link to="/login">{ "Login" }</Link>
|
||||
<Link to="/reset_password">{ "Reset Password" }</Link>
|
||||
|
||||
<Switch>
|
||||
{ authenticationRoutes.map((route, index) => (
|
||||
<Route
|
||||
key={index}
|
||||
path={route.path}
|
||||
exact={route.exact}
|
||||
component={route.component}
|
||||
/>
|
||||
))}
|
||||
</Switch>
|
||||
</Router>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<div class="">
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'account-form',
|
||||
data() {
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,11 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'accounts-list',
|
||||
};
|
||||
</script>
|
||||
@@ -1,31 +0,0 @@
|
||||
<template>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
|
||||
const STATE = {
|
||||
LOADING: 1,
|
||||
EMPTY_LIST: 2,
|
||||
NO_SEARCH_RESULTS: 3,
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'customers-list',
|
||||
data() {
|
||||
return {
|
||||
current_state: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
loading() {
|
||||
return this.current_state === STATE.LOADING;
|
||||
},
|
||||
emptyList() {
|
||||
return this.current_state === STATE.EMPTY_LIST;
|
||||
},
|
||||
noSearchResults() {
|
||||
return this.current_state === STATE.NO_SEARCH_RESULTS;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<div id="dashboard" class="dashboard">
|
||||
<DashboardSidebar />
|
||||
|
||||
<div class="dashboard__content">
|
||||
<DashboardTopbar></DashboardTopbar>
|
||||
|
||||
<div class="dashboard__content-inner">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DashboardSidebar from '@/views/Sidebar';
|
||||
import DashboardTopbar from '@/views/Topbar';
|
||||
|
||||
export default {
|
||||
name: 'dashboard',
|
||||
components: {
|
||||
DashboardTopbar,
|
||||
DashboardSidebar,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.dashboard{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
&__content{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,9 +0,0 @@
|
||||
<template>
|
||||
<div>Home</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'home',
|
||||
};
|
||||
</script>
|
||||
@@ -1,34 +0,0 @@
|
||||
<template>
|
||||
<div class="item-form" id="item-form">
|
||||
<el-form ref="form" class="form-container">
|
||||
<el-form-item :label="$t('item_name')" prop="title">
|
||||
<el-input v-model="form.name" :maxlength="100" name="name" required />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('SKU')" prop="title">
|
||||
<el-input v-model="form.SKU" :maxlength="100" name="SKU" required />
|
||||
</el-form-item>
|
||||
|
||||
<el-button type="primary">{{ $t('login') }}</el-button>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'item-form',
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
name: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
||||
onSubmit() {
|
||||
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,55 +0,0 @@
|
||||
|
||||
<template>
|
||||
<el-table v-loading="isLoading" :data="items.list" border fit highlight-current-row>
|
||||
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import Reloadable from '@/mixins/Reloadable';
|
||||
|
||||
const STATE = {
|
||||
LOADING: 1,
|
||||
};
|
||||
export default {
|
||||
name: 'items-datatable',
|
||||
mixins: [Reloadable],
|
||||
data() {
|
||||
return {
|
||||
current_state: 0,
|
||||
page: 1,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
items: 'getItems',
|
||||
}),
|
||||
isLoading() {
|
||||
return this.current_state === STATE.LOADING;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.current_state = STATE.LOADING;
|
||||
this.fetchData();
|
||||
this.current_state = 0;
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['fetchItems']),
|
||||
|
||||
/**
|
||||
* Handle the reload data.
|
||||
*/
|
||||
reloadData() {
|
||||
this.fetchData();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle the fetch data of datatable.
|
||||
*/
|
||||
async fetchData() {
|
||||
await this.fetchItems({ page: this.page });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,27 +0,0 @@
|
||||
<template>
|
||||
<el-card>
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="User" name="first" :lazy="true">User</el-tab-pane>
|
||||
<el-tab-pane label="Config" name="second" :lazy="true">Config</el-tab-pane>
|
||||
<el-tab-pane label="Role" name="third" :lazy="true">Role</el-tab-pane>
|
||||
<el-tab-pane label="Task" name="fourth" :lazy="true">Task</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'products-list',
|
||||
data() {
|
||||
return {
|
||||
activeName: 'first',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleClick(tab, event) {
|
||||
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<div class="">
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'item-category-form',
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,42 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table v-loading="isLoading" :data="items.list" border fit highlight-current-row>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'items-categories',
|
||||
data() {
|
||||
return {
|
||||
current_state: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
categories: 'getItemsCategories',
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['fetchItemsCategories']),
|
||||
|
||||
/**
|
||||
* Handle the reload data of the current view.
|
||||
*/
|
||||
async reloadData() {
|
||||
await this.fetchData();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle the fetch data of the datatable.
|
||||
*/
|
||||
async fetchData() {
|
||||
await this.fetchItemsCategories();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<div>Users List</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'users-list',
|
||||
afterRouteEnter(to, from, next) {
|
||||
debugger;
|
||||
this.$store.commit('setPageTitle', this.$t('users_list'));
|
||||
next();
|
||||
},
|
||||
}
|
||||
</script>
|
||||
15
client/src/pages/Dashboard/index.js
Normal file
15
client/src/pages/Dashboard/index.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import Sidebar from '../../components/Sidebar';
|
||||
import DashboardContent from '../../components/DashboardContent';
|
||||
|
||||
export default function() {
|
||||
return (
|
||||
<div class="dashboard" id="dashboard">
|
||||
<Router>
|
||||
<Sidebar />
|
||||
<DashboardContent />
|
||||
</Router>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
export default {
|
||||
|
||||
get(resource, params) {
|
||||
return Vue.axios.get(`api/${resource}`, params);
|
||||
},
|
||||
|
||||
post(resource, params) {
|
||||
return Vue.axios.post(`api/${resource}`, params);
|
||||
},
|
||||
|
||||
update(resource, slug, params) {
|
||||
return Vue.axios.put(`api/${resource}/${slug}`, params);
|
||||
},
|
||||
|
||||
put(resource, params) {
|
||||
return Vue.axios.put(`api/${resource}`, params);
|
||||
},
|
||||
|
||||
delete(resource) {
|
||||
return Vue.axios.delete(`api/${resource}`);
|
||||
}
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import store from '~/store';
|
||||
import swal from 'sweetalert2'
|
||||
import Vue from 'vue';
|
||||
import VueAxios from 'vue-axios';
|
||||
import router from '~/routes';
|
||||
|
||||
// Set config defaults when creating the instance
|
||||
const http = axios.create();
|
||||
|
||||
// request interceptor.
|
||||
http.interceptors.request.use((request) => {
|
||||
const token = store.getters.authToken;
|
||||
const locale = Vue.i18n.locale();
|
||||
|
||||
if (token) {
|
||||
request.headers.common['x-access-token'] = token;
|
||||
}
|
||||
if (locale) {
|
||||
request.headers.common['Accept-Language'] = locale;
|
||||
}
|
||||
return request;
|
||||
});
|
||||
|
||||
// response interceptor
|
||||
http.interceptors.response.use(response => response, (error) => {
|
||||
const { status } = error.response;
|
||||
|
||||
if (status >= 500) {
|
||||
swal({
|
||||
type: 'error',
|
||||
title: Vue.i18n.translate('error_alert_title'),
|
||||
text: Vue.i18n.translate('error_alert_text'),
|
||||
reverseButtons: true,
|
||||
confirmButtonText: Vue.i18n.translate('ok'),
|
||||
cancelButtonText: Vue.i18n.translate('cancel')
|
||||
});
|
||||
}
|
||||
|
||||
if (status === 401) {
|
||||
swal({
|
||||
type: 'warning',
|
||||
title: Vue.i18n.translate('token_expired_alert_title'),
|
||||
text: Vue.i18n.translate('token_expired_alert_text'),
|
||||
reverseButtons: true,
|
||||
confirmButtonText: Vue.i18n.translate('ok'),
|
||||
cancelButtonText: Vue.i18n.translate('cancel')
|
||||
}).then(() => {
|
||||
store.commit('removeToken');
|
||||
router.push({ name: 'login' });
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(error)
|
||||
});
|
||||
|
||||
Vue.use(VueAxios, http);
|
||||
|
||||
export default http;
|
||||
@@ -1,29 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
const defaultLocale = 'en';
|
||||
const loadedLangauges = [];
|
||||
const currentLocale = Vue.i18n.locale();
|
||||
|
||||
function setLanguage(locale, messages) {
|
||||
const localeMessages = messages.default;
|
||||
|
||||
Vue.i18n.add(locale, { ...localeMessages });
|
||||
|
||||
loadedLangauges.push(locale);
|
||||
Vue.i18n.set(locale);
|
||||
}
|
||||
|
||||
async function loadAsyncLanguage(locale) {
|
||||
if (locale !== currentLocale) {
|
||||
if (!loadedLangauges.includes(locale)) {
|
||||
const messages = await import(/* webpackChunkName: "lang-[request]" */ `@/lang/${locale}/app`);
|
||||
setLanguage(locale, messages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(async () => {
|
||||
await loadAsyncLanguage(defaultLocale);
|
||||
})();
|
||||
|
||||
export default loadAsyncLanguage;
|
||||
@@ -1,9 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
import SvgIcon from '@/components/SvgIcon';
|
||||
|
||||
// register globally
|
||||
Vue.component('svg-icon', SvgIcon)
|
||||
|
||||
const req = require.context('../../static/icons', false, /\.svg$/);
|
||||
const requireAll = requireContext => requireContext.keys().map(requireContext);
|
||||
requireAll(req);
|
||||
10
client/src/reducers/index.js
Normal file
10
client/src/reducers/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import { combineReducers } from 'redux';
|
||||
import accounts from './accounts';
|
||||
import authentication from './authentication';
|
||||
import users from './users';
|
||||
|
||||
export default combineReducers({
|
||||
authentication,
|
||||
users,
|
||||
accounts,
|
||||
});
|
||||
@@ -1,43 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
import Router from 'vue-router';
|
||||
import store from '@/store';
|
||||
import routes from './routes';
|
||||
|
||||
Vue.use(Router);
|
||||
|
||||
const router = new Router({
|
||||
mode: 'hash',
|
||||
routes: [
|
||||
...routes,
|
||||
],
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
const isAuthenticated = store.getters.authCheck;
|
||||
|
||||
if (to.matched.some(record => record.meta.requiresAuth)) {
|
||||
if (!isAuthenticated) {
|
||||
next({
|
||||
name: 'login',
|
||||
params: { nextUrl: to.fullPath },
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
} else if (to.matched.some(record => record.meta.guest)) {
|
||||
if (isAuthenticated) {
|
||||
next({
|
||||
name: 'dashboard.name',
|
||||
params: {
|
||||
nextUrl: to.fullPath,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
@@ -1,89 +0,0 @@
|
||||
|
||||
const routes = [
|
||||
{
|
||||
name: 'auth',
|
||||
path: '/',
|
||||
component: () => import(/* webpackChunkName: "auth_container" */
|
||||
'@/pages/Auth/AuthContainer.vue'),
|
||||
children: [
|
||||
{
|
||||
name: 'login',
|
||||
path: '/login',
|
||||
component: () => import(/* webpackChunkName: "login" */
|
||||
'@/pages/Auth/Login.vue'),
|
||||
},
|
||||
{
|
||||
name: 'forgetPassword',
|
||||
path: '/forget_password',
|
||||
component: () => import(/* webpackChunkName: "forget_password" */
|
||||
'@/pages/Auth/ForgetPassword.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'dashboard',
|
||||
path: '/dashboard',
|
||||
component: () => import(/* webpackChunkName: "dashboard" */
|
||||
'@/pages/Dashboard/Dashboard.vue'),
|
||||
children: [
|
||||
{
|
||||
name: 'dashboard.home',
|
||||
path: '/home',
|
||||
component: () => import(/* webpackChunkName: "dashboard_home" */
|
||||
'@/pages/Dashboard/Home.vue'),
|
||||
},
|
||||
|
||||
/**
|
||||
* Items. (Products/Services).
|
||||
* --------------------------------
|
||||
*/
|
||||
{
|
||||
name: 'dashboard.items.list',
|
||||
path: '/items',
|
||||
component: () => import(/* webpackChunkName: "items_list" */
|
||||
'@/pages/Dashboard/Items/ItemsList.vue'),
|
||||
accessControl: { resource: 'items', permissions: ['view'] },
|
||||
},
|
||||
{
|
||||
name: 'dashboard.items.new',
|
||||
path: '/items/new',
|
||||
component: () => import(/* webpackChunkName: "items_form" */
|
||||
'@/pages/Dashboard/Items/ItemForm.vue'),
|
||||
accessControl: { resource: 'items', permissions: ['create'] },
|
||||
},
|
||||
|
||||
/**
|
||||
* Accounts
|
||||
* ---------------------------
|
||||
*/
|
||||
{
|
||||
name: 'dashboard.accounts.list',
|
||||
path: '/accounts/list',
|
||||
component: () => import(/* webpackChunkName: "accounts_list" */
|
||||
'@/pages/Dashboard/Accounts/AccountsList.vue'),
|
||||
accessControl: { resource: 'accounts', permissions: ['view'] },
|
||||
},
|
||||
|
||||
/**
|
||||
* Users.
|
||||
* --------------------------------
|
||||
*/
|
||||
{
|
||||
name: 'dashboard.users.list',
|
||||
path: '/users',
|
||||
component: () => import(/* webpackChunkName: "users_list" */
|
||||
'@/pages/Dashboard/Users/UsersList.vue'),
|
||||
accessControl: { resource: 'users', permissions: ['view'] },
|
||||
},
|
||||
{
|
||||
name: 'dasboard.user.new',
|
||||
path: '/users',
|
||||
component: () => import(/* webpackChunkName: "user_form" */
|
||||
'@/pages/Dashboard/Users/UserForm.vue'),
|
||||
accessControl: { resource: 'users', permissions: ['create'] },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
||||
15
client/src/routes/authentication.js
Normal file
15
client/src/routes/authentication.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import Login from '../pages/Authentication/Login';
|
||||
import ResetPassword from '../pages/Authentication/ResetPassword';
|
||||
|
||||
export default [
|
||||
{
|
||||
path: '/login',
|
||||
exact: true,
|
||||
component: Login,
|
||||
},
|
||||
{
|
||||
path: '/reset_password',
|
||||
exact: true,
|
||||
component: ResetPassword,
|
||||
}
|
||||
];
|
||||
11
client/src/routes/dashboard.js
Normal file
11
client/src/routes/dashboard.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import AccountsChart from '../pages/Dashboard/AccountsChart';
|
||||
|
||||
export default [
|
||||
{
|
||||
path: '/accounts/list',
|
||||
component: AccountsChart,
|
||||
icon: 'cut',
|
||||
text: 'Chart of Accounts',
|
||||
label: 'Chart of Accounts'
|
||||
},
|
||||
];
|
||||
141
client/src/serviceWorker.js
Normal file
141
client/src/serviceWorker.js
Normal file
@@ -0,0 +1,141 @@
|
||||
// This optional code is used to register a service worker.
|
||||
// register() is not called by default.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on subsequent visits to a page, after all the
|
||||
// existing tabs open on the page have been closed, since previously cached
|
||||
// resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model and instructions on how to
|
||||
// opt-in, read https://bit.ly/CRA-PWA
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.0/8 are considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://bit.ly/CRA-PWA'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Is not localhost. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl, config) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
if (installingWorker == null) {
|
||||
return;
|
||||
}
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the updated precached content has been fetched,
|
||||
// but the previous service worker will still serve the older
|
||||
// content until all client tabs are closed.
|
||||
console.log(
|
||||
'New content is available and will be used when all ' +
|
||||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
|
||||
);
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.');
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl, {
|
||||
headers: { 'Service-Worker': 'script' }
|
||||
})
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (
|
||||
response.status === 404 ||
|
||||
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready
|
||||
.then(registration => {
|
||||
registration.unregister();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
5
client/src/setupTests.js
Normal file
5
client/src/setupTests.js
Normal file
@@ -0,0 +1,5 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
@@ -1,25 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import vuexI18n from 'vuex-i18n';
|
||||
import sidebar from '@/store/modules/sidebar';
|
||||
import app from '@/store/modules/app';
|
||||
import items from '@/store/modules/items';
|
||||
import customers from '@/store/modules/customers';
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
app,
|
||||
sidebar,
|
||||
items,
|
||||
customers,
|
||||
},
|
||||
strict: debug,
|
||||
});
|
||||
|
||||
Vue.use(vuexI18n.plugin, store);
|
||||
|
||||
export default store;
|
||||
@@ -1,41 +0,0 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
|
||||
const state = {
|
||||
appName: 'Ratteb',
|
||||
appVersion: '1.0.0',
|
||||
appBuild: '1000',
|
||||
|
||||
pageTitle: 'Welcome',
|
||||
actions: [],
|
||||
|
||||
contentState: 0,
|
||||
sidebarOpened: true,
|
||||
};
|
||||
|
||||
const getters = {
|
||||
getAppName: s => s.appName,
|
||||
getAppVersion: s => s.appVersion,
|
||||
getAppBuild: s => s.appBuild,
|
||||
getPageTitle: s => s.pageTitle,
|
||||
};
|
||||
|
||||
const actions = {
|
||||
|
||||
setPageTitle(s, title) {
|
||||
s.title = title;
|
||||
},
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
toggleSidebar() {
|
||||
state.sidebarOpened = !state.sidebarOpened;
|
||||
|
||||
if (state.sidebarOpened) {
|
||||
localStorage.set('sidebarStatus', 1)
|
||||
} else {
|
||||
localStorage.set('sidebarStatus', 0)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default { state, actions, mutations, getters };
|
||||
@@ -1,55 +0,0 @@
|
||||
import ApiService from '@/plugins/api-service';
|
||||
|
||||
const state = {
|
||||
token: localStorage.getItem('token') || '',
|
||||
errors: {},
|
||||
role: {},
|
||||
};
|
||||
|
||||
const getters = {
|
||||
authCheck: s => s.token,
|
||||
authToken: s => s.token,
|
||||
authorizedUserRole: s => s.role,
|
||||
};
|
||||
|
||||
const actions = {
|
||||
/**
|
||||
* User login login authentication request.
|
||||
*/
|
||||
async login({ commit }, { form }) {
|
||||
const response = await ApiService.post('auth/login', form);
|
||||
const { data } = response;
|
||||
|
||||
if (data.token) {
|
||||
commit('setToken', data.token);
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Send reset password via email or SMS.
|
||||
*/
|
||||
sendResetPassword({}, { email }) {
|
||||
return ApiService.post('auth/send_reset_password', { email });
|
||||
},
|
||||
|
||||
newPassword({}, { form }) {
|
||||
return ApiService.post('auth/new_password', form);
|
||||
},
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
|
||||
setToken(s, token) {
|
||||
localStorage.setItem('token', token);
|
||||
s.token = token;
|
||||
},
|
||||
|
||||
removeToken(s) {
|
||||
localStorage.removeItem('token');
|
||||
s.token = '';
|
||||
},
|
||||
};
|
||||
|
||||
export default { state, actions, mutations, getters };
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
import ApiService from '@/plugins/api-service';
|
||||
|
||||
const state = {
|
||||
list: {},
|
||||
details: [],
|
||||
};
|
||||
|
||||
const getters = {
|
||||
getCustomers: s => s.list,
|
||||
getCustomer: s => id => s.details.find(i => i.id === id),
|
||||
};
|
||||
|
||||
const actions = {
|
||||
/**
|
||||
* Fetches customers with current page.
|
||||
*/
|
||||
async fetchCustomers({ commit }, { query } = {}) {
|
||||
const response = await ApiService.post('customers', { params: query });
|
||||
const { data } = response;
|
||||
const { count } = data.pagination;
|
||||
|
||||
commit('setItems', data);
|
||||
|
||||
if (count) {
|
||||
commit('setSidebarItemCount', { name: 'customers', count });
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch the given customer details.
|
||||
*/
|
||||
async fetchCustomer({ commit }, { id }) {
|
||||
const response = await ApiService.get(`customers/${id}`);
|
||||
const { data } = response;
|
||||
|
||||
commit('setItem', data);
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete the given customer.
|
||||
*/
|
||||
async deleteCustomer({}, { id }) {
|
||||
return ApiService.delete(`customers/${id}`);
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit the new customer.
|
||||
*/
|
||||
async newCustomer({}, { form }) {
|
||||
return ApiService.post('customers', form);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update details the given customer.
|
||||
*/
|
||||
async updateCustomer({}, { form, id }) {
|
||||
return ApiService.post(`customers/${id}`, form);
|
||||
},
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
|
||||
setCustomers(s, items) {
|
||||
s.list = items;
|
||||
},
|
||||
|
||||
setCustomer(s, item) {
|
||||
s.details = s.details.filter(i => i.id !== item.id);
|
||||
s.details.push(item);
|
||||
},
|
||||
};
|
||||
|
||||
export default { state, actions, mutations, getters };
|
||||
@@ -1,28 +0,0 @@
|
||||
const state = {
|
||||
logs: [],
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
ADD_ERROR_LOG: (s, log) => {
|
||||
s.logs.push(log);
|
||||
},
|
||||
CLEAR_ERROR_LOG: (s) => {
|
||||
s.logs.splice(0);
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
addErrorLog({ commit }, log) {
|
||||
commit('ADD_ERROR_LOG', log);
|
||||
},
|
||||
clearErrorLog({ commit }) {
|
||||
commit('CLEAR_ERROR_LOG');
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
};
|
||||
@@ -1,119 +0,0 @@
|
||||
import ApiService from '@/plugins/api-service';
|
||||
|
||||
const state = {
|
||||
list: {},
|
||||
details: [],
|
||||
categories: {},
|
||||
categoriesDetails: [],
|
||||
};
|
||||
|
||||
const getters = {
|
||||
getItems: s => s.list,
|
||||
getItem: s => id => s.details.find(i => i.id === id),
|
||||
getItemsCategories: s => s.categories,
|
||||
getItemCategory: s => id => s.categoriesDetails.find(i => i.id === id),
|
||||
};
|
||||
|
||||
const actions = {
|
||||
/**
|
||||
* Fetches the products/services list.
|
||||
*/
|
||||
async fetchItems({ commit }, { query } = {}) {
|
||||
const response = await ApiService.post('items', { params: query });
|
||||
const { data } = response;
|
||||
const { count } = data.pagination;
|
||||
|
||||
commit('setItems', data);
|
||||
|
||||
if (count) {
|
||||
commit('setSidebarItemCount', {
|
||||
name: 'items', count,
|
||||
});
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch the given product/service details.
|
||||
*/
|
||||
async fetchItem({ commit }, { id }) {
|
||||
const response = await ApiService.get(`${id}`);
|
||||
const { data } = response;
|
||||
|
||||
commit('setItem', data);
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete the given product/service.
|
||||
*/
|
||||
async deleteItem({ commit }, { id }) {
|
||||
return ApiService.delete(`items/${id}`);
|
||||
},
|
||||
|
||||
async newItem({}, { form }) {
|
||||
return ApiService.post('items', form);
|
||||
},
|
||||
|
||||
async updateItem({}, { form, id }) {
|
||||
return ApiService.post(`items/${id}`, form);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches items categories paged list.
|
||||
*/
|
||||
async fetchItemsCategories({}, { query }) {
|
||||
return ApiService.get('/items_categories', { params: query });
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch details of the given item category.
|
||||
*/
|
||||
async fetchItemCategory({}, { id }) {
|
||||
return ApiService.get(`/item/${id}`);
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete the given item category.
|
||||
*/
|
||||
async deleteItemCategory({}, { id }) {
|
||||
return ApiService.delete(`/items_categories/${id}`);
|
||||
},
|
||||
|
||||
/**
|
||||
* Post a new item category.
|
||||
*/
|
||||
async newItemCategory({}, { form }) {
|
||||
return ApiService.post('/items_categories', form);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update details of the given item category.
|
||||
*/
|
||||
async updateItemCategory({}, { id, form }) {
|
||||
return ApiService.post(`/items_categories/${id}`, form);
|
||||
},
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
|
||||
setItems(s, items) {
|
||||
s.list = items;
|
||||
},
|
||||
|
||||
setItem(s, item) {
|
||||
s.details = s.details.filter(i => i.id !== item.id);
|
||||
s.details.push(item);
|
||||
},
|
||||
|
||||
setItemCategories(s, categories) {
|
||||
s.categories = categories;
|
||||
},
|
||||
|
||||
setItemCategory(s, category) {
|
||||
s.categoriesDetails = s.categoriesDetails.filter(i => i.id !== category.id);
|
||||
s.categoriesDetails.push(category);
|
||||
},
|
||||
};
|
||||
|
||||
export default { state, actions, mutations, getters };
|
||||
@@ -1,93 +0,0 @@
|
||||
|
||||
const state = {
|
||||
items: [
|
||||
{
|
||||
name: 'Home',
|
||||
to: 'dashboard.home',
|
||||
icon: 'home',
|
||||
count: null,
|
||||
},
|
||||
{
|
||||
name: 'Products',
|
||||
to: 'dashboard.items.list',
|
||||
},
|
||||
{
|
||||
name: 'Customers',
|
||||
to: 'dashboard.home',
|
||||
},
|
||||
{
|
||||
name: 'Suppliers',
|
||||
to: 'dashboard.home',
|
||||
},
|
||||
{
|
||||
name: 'Reports',
|
||||
to: 'dashboard.home',
|
||||
},
|
||||
{
|
||||
name: 'Users',
|
||||
to: 'dashboard.users.list',
|
||||
children: {
|
||||
name: 'New User',
|
||||
to: 'dashboard.user.new',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Accounting',
|
||||
to: 'dashboard.accounts.list',
|
||||
},
|
||||
],
|
||||
|
||||
quickActions: [
|
||||
{
|
||||
route: 'dashboard.items.list',
|
||||
actions: [
|
||||
{
|
||||
dialog: 'global-search',
|
||||
label: 'Search',
|
||||
icon: 'search',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
route: 'dashboard.items.list',
|
||||
actions: [
|
||||
{
|
||||
dialog: 'test',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const getters = {
|
||||
getSidebarItems: s => s.items,
|
||||
getSidebarItem: s => name => s.items.find(item => item.name === name),
|
||||
|
||||
getAllQuickActions: s => s.quickActions,
|
||||
getQuickActions: s => (route) => {
|
||||
const foundDefault = s.quickActions.find(q => q.default === true);
|
||||
const found = s.quickActions.find(q => q.route === route);
|
||||
const defaultActions = foundDefault ? foundDefault.actions : [];
|
||||
|
||||
return found ? [...defaultActions, found.actions] : defaultActions;
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
|
||||
/**
|
||||
* Set count to the given sidebar item.
|
||||
*/
|
||||
setSidebarItemCount(s, { name, count }) {
|
||||
s.items = s.items.map((item) => {
|
||||
const mapped = { ...item };
|
||||
|
||||
if (item.name === name) {
|
||||
mapped.count = count;
|
||||
}
|
||||
return mapped;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default { state, getters, actions };
|
||||
38
client/src/style/App.css
Normal file
38
client/src/style/App.css
Normal file
@@ -0,0 +1,38 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@@ -1,994 +0,0 @@
|
||||
/* Element Chalk Variables */
|
||||
|
||||
// Special comment for theme configurator
|
||||
// type|skipAutoTranslation|Category|Order
|
||||
// skipAutoTranslation 1
|
||||
|
||||
/* Transition
|
||||
-------------------------- */
|
||||
$--all-transition: all .3s cubic-bezier(.645,.045,.355,1) !default;
|
||||
$--fade-transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !default;
|
||||
$--fade-linear-transition: opacity 200ms linear !default;
|
||||
$--md-fade-transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1), opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !default;
|
||||
$--border-transition-base: border-color .2s cubic-bezier(.645,.045,.355,1) !default;
|
||||
$--color-transition-base: color .2s cubic-bezier(.645,.045,.355,1) !default;
|
||||
|
||||
/* Color
|
||||
-------------------------- */
|
||||
/// color|1|Brand Color|0
|
||||
$--color-primary: #409EFF !default;
|
||||
/// color|1|Background Color|4
|
||||
$--color-white: #FFFFFF !default;
|
||||
/// color|1|Background Color|4
|
||||
$--color-black: #000000 !default;
|
||||
$--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */
|
||||
$--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */
|
||||
$--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */
|
||||
$--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default; /* 8cc5ff */
|
||||
$--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default; /* a0cfff */
|
||||
$--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /* b3d8ff */
|
||||
$--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */
|
||||
$--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */
|
||||
$--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default; /* ecf5ff */
|
||||
/// color|1|Functional Color|1
|
||||
$--color-success: #67C23A !default;
|
||||
/// color|1|Functional Color|1
|
||||
$--color-warning: #E6A23C !default;
|
||||
/// color|1|Functional Color|1
|
||||
$--color-danger: #F56C6C !default;
|
||||
/// color|1|Functional Color|1
|
||||
$--color-info: #909399 !default;
|
||||
|
||||
$--color-success-light: mix($--color-white, $--color-success, 80%) !default;
|
||||
$--color-warning-light: mix($--color-white, $--color-warning, 80%) !default;
|
||||
$--color-danger-light: mix($--color-white, $--color-danger, 80%) !default;
|
||||
$--color-info-light: mix($--color-white, $--color-info, 80%) !default;
|
||||
|
||||
$--color-success-lighter: mix($--color-white, $--color-success, 90%) !default;
|
||||
$--color-warning-lighter: mix($--color-white, $--color-warning, 90%) !default;
|
||||
$--color-danger-lighter: mix($--color-white, $--color-danger, 90%) !default;
|
||||
$--color-info-lighter: mix($--color-white, $--color-info, 90%) !default;
|
||||
/// color|1|Font Color|2
|
||||
$--color-text-primary: #303133 !default;
|
||||
/// color|1|Font Color|2
|
||||
$--color-text-regular: #606266 !default;
|
||||
/// color|1|Font Color|2
|
||||
$--color-text-secondary: #909399 !default;
|
||||
/// color|1|Font Color|2
|
||||
$--color-text-placeholder: #C0C4CC !default;
|
||||
/// color|1|Border Color|3
|
||||
$--border-color-base: #DCDFE6 !default;
|
||||
/// color|1|Border Color|3
|
||||
$--border-color-light: #E4E7ED !default;
|
||||
/// color|1|Border Color|3
|
||||
$--border-color-lighter: #EBEEF5 !default;
|
||||
/// color|1|Border Color|3
|
||||
$--border-color-extra-light: #F2F6FC !default;
|
||||
|
||||
// Background
|
||||
/// color|1|Background Color|4
|
||||
$--background-color-base: #F5F7FA !default;
|
||||
|
||||
/* Link
|
||||
-------------------------- */
|
||||
$--link-color: $--color-primary-light-2 !default;
|
||||
$--link-hover-color: $--color-primary !default;
|
||||
|
||||
/* Border
|
||||
-------------------------- */
|
||||
$--border-width-base: 1px !default;
|
||||
$--border-style-base: solid !default;
|
||||
$--border-color-hover: $--color-text-placeholder !default;
|
||||
$--border-base: $--border-width-base $--border-style-base $--border-color-base !default;
|
||||
/// borderRadius|1|Radius|0
|
||||
$--border-radius-base: 4px !default;
|
||||
/// borderRadius|1|Radius|0
|
||||
$--border-radius-small: 2px !default;
|
||||
/// borderRadius|1|Radius|0
|
||||
$--border-radius-circle: 100% !default;
|
||||
/// borderRadius|1|Radius|0
|
||||
$--border-radius-zero: 0 !default;
|
||||
|
||||
// Box-shadow
|
||||
/// boxShadow|1|Shadow|1
|
||||
$--box-shadow-base: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04) !default;
|
||||
// boxShadow|1|Shadow|1
|
||||
$--box-shadow-dark: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .12) !default;
|
||||
/// boxShadow|1|Shadow|1
|
||||
$--box-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !default;
|
||||
|
||||
/* Fill
|
||||
-------------------------- */
|
||||
$--fill-base: $--color-white !default;
|
||||
|
||||
/* Typography
|
||||
-------------------------- */
|
||||
$--font-path: 'fonts' !default;
|
||||
$--font-display: 'auto' !default;
|
||||
/// fontSize|1|Font Size|0
|
||||
$--font-size-extra-large: 20px !default;
|
||||
/// fontSize|1|Font Size|0
|
||||
$--font-size-large: 18px !default;
|
||||
/// fontSize|1|Font Size|0
|
||||
$--font-size-medium: 16px !default;
|
||||
/// fontSize|1|Font Size|0
|
||||
$--font-size-base: 14px !default;
|
||||
/// fontSize|1|Font Size|0
|
||||
$--font-size-small: 13px !default;
|
||||
/// fontSize|1|Font Size|0
|
||||
$--font-size-extra-small: 12px !default;
|
||||
/// fontWeight|1|Font Weight|1
|
||||
$--font-weight-primary: 500 !default;
|
||||
/// fontWeight|1|Font Weight|1
|
||||
$--font-weight-secondary: 100 !default;
|
||||
/// fontLineHeight|1|Line Height|2
|
||||
$--font-line-height-primary: 24px !default;
|
||||
/// fontLineHeight|1|Line Height|2
|
||||
$--font-line-height-secondary: 16px !default;
|
||||
$--font-color-disabled-base: #bbb !default;
|
||||
/* Size
|
||||
-------------------------- */
|
||||
$--size-base: 14px !default;
|
||||
|
||||
/* z-index
|
||||
-------------------------- */
|
||||
$--index-normal: 1 !default;
|
||||
$--index-top: 1000 !default;
|
||||
$--index-popper: 2000 !default;
|
||||
|
||||
/* Disable base
|
||||
-------------------------- */
|
||||
$--disabled-fill-base: $--background-color-base !default;
|
||||
$--disabled-color-base: $--color-text-placeholder !default;
|
||||
$--disabled-border-base: $--border-color-light !default;
|
||||
|
||||
/* Icon
|
||||
-------------------------- */
|
||||
$--icon-color: #666 !default;
|
||||
$--icon-color-base: $--color-info !default;
|
||||
|
||||
/* Checkbox
|
||||
-------------------------- */
|
||||
/// fontSize||Font|1
|
||||
$--checkbox-font-size: 14px !default;
|
||||
/// fontWeight||Font|1
|
||||
$--checkbox-font-weight: $--font-weight-primary !default;
|
||||
/// color||Color|0
|
||||
$--checkbox-font-color: $--color-text-regular !default;
|
||||
$--checkbox-input-height: 14px !default;
|
||||
$--checkbox-input-width: 14px !default;
|
||||
/// borderRadius||Border|2
|
||||
$--checkbox-border-radius: $--border-radius-small !default;
|
||||
/// color||Color|0
|
||||
$--checkbox-background-color: $--color-white !default;
|
||||
$--checkbox-input-border: $--border-base !default;
|
||||
|
||||
/// color||Color|0
|
||||
$--checkbox-disabled-border-color: $--border-color-base !default;
|
||||
$--checkbox-disabled-input-fill: #edf2fc !default;
|
||||
$--checkbox-disabled-icon-color: $--color-text-placeholder !default;
|
||||
|
||||
$--checkbox-disabled-checked-input-fill: $--border-color-extra-light !default;
|
||||
$--checkbox-disabled-checked-input-border-color: $--border-color-base !default;
|
||||
$--checkbox-disabled-checked-icon-color: $--color-text-placeholder !default;
|
||||
|
||||
/// color||Color|0
|
||||
$--checkbox-checked-font-color: $--color-primary !default;
|
||||
$--checkbox-checked-input-border-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--checkbox-checked-background-color: $--color-primary !default;
|
||||
$--checkbox-checked-icon-color: $--fill-base !default;
|
||||
|
||||
$--checkbox-input-border-color-hover: $--color-primary !default;
|
||||
/// height||Other|4
|
||||
$--checkbox-bordered-height: 40px !default;
|
||||
/// padding||Spacing|3
|
||||
$--checkbox-bordered-padding: 9px 20px 9px 10px !default;
|
||||
/// padding||Spacing|3
|
||||
$--checkbox-bordered-medium-padding: 7px 20px 7px 10px !default;
|
||||
/// padding||Spacing|3
|
||||
$--checkbox-bordered-small-padding: 5px 15px 5px 10px !default;
|
||||
/// padding||Spacing|3
|
||||
$--checkbox-bordered-mini-padding: 3px 15px 3px 10px !default;
|
||||
$--checkbox-bordered-medium-input-height: 14px !default;
|
||||
$--checkbox-bordered-medium-input-width: 14px !default;
|
||||
/// height||Other|4
|
||||
$--checkbox-bordered-medium-height: 36px !default;
|
||||
$--checkbox-bordered-small-input-height: 12px !default;
|
||||
$--checkbox-bordered-small-input-width: 12px !default;
|
||||
/// height||Other|4
|
||||
$--checkbox-bordered-small-height: 32px !default;
|
||||
$--checkbox-bordered-mini-input-height: 12px !default;
|
||||
$--checkbox-bordered-mini-input-width: 12px !default;
|
||||
/// height||Other|4
|
||||
$--checkbox-bordered-mini-height: 28px !default;
|
||||
|
||||
/// color||Color|0
|
||||
$--checkbox-button-checked-background-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--checkbox-button-checked-font-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--checkbox-button-checked-border-color: $--color-primary !default;
|
||||
|
||||
|
||||
|
||||
/* Radio
|
||||
-------------------------- */
|
||||
/// fontSize||Font|1
|
||||
$--radio-font-size: $--font-size-base !default;
|
||||
/// fontWeight||Font|1
|
||||
$--radio-font-weight: $--font-weight-primary !default;
|
||||
/// color||Color|0
|
||||
$--radio-font-color: $--color-text-regular !default;
|
||||
$--radio-input-height: 14px !default;
|
||||
$--radio-input-width: 14px !default;
|
||||
/// borderRadius||Border|2
|
||||
$--radio-input-border-radius: $--border-radius-circle !default;
|
||||
/// color||Color|0
|
||||
$--radio-input-background-color: $--color-white !default;
|
||||
$--radio-input-border: $--border-base !default;
|
||||
/// color||Color|0
|
||||
$--radio-input-border-color: $--border-color-base !default;
|
||||
/// color||Color|0
|
||||
$--radio-icon-color: $--color-white !default;
|
||||
|
||||
$--radio-disabled-input-border-color: $--disabled-border-base !default;
|
||||
$--radio-disabled-input-fill: $--disabled-fill-base !default;
|
||||
$--radio-disabled-icon-color: $--disabled-fill-base !default;
|
||||
|
||||
$--radio-disabled-checked-input-border-color: $--disabled-border-base !default;
|
||||
$--radio-disabled-checked-input-fill: $--disabled-fill-base !default;
|
||||
$--radio-disabled-checked-icon-color: $--color-text-placeholder !default;
|
||||
|
||||
/// color||Color|0
|
||||
$--radio-checked-font-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--radio-checked-input-border-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--radio-checked-input-background-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--radio-checked-icon-color: $--color-primary !default;
|
||||
|
||||
$--radio-input-border-color-hover: $--color-primary !default;
|
||||
|
||||
$--radio-bordered-height: 40px !default;
|
||||
$--radio-bordered-padding: 12px 20px 0 10px !default;
|
||||
$--radio-bordered-medium-padding: 10px 20px 0 10px !default;
|
||||
$--radio-bordered-small-padding: 8px 15px 0 10px !default;
|
||||
$--radio-bordered-mini-padding: 6px 15px 0 10px !default;
|
||||
$--radio-bordered-medium-input-height: 14px !default;
|
||||
$--radio-bordered-medium-input-width: 14px !default;
|
||||
$--radio-bordered-medium-height: 36px !default;
|
||||
$--radio-bordered-small-input-height: 12px !default;
|
||||
$--radio-bordered-small-input-width: 12px !default;
|
||||
$--radio-bordered-small-height: 32px !default;
|
||||
$--radio-bordered-mini-input-height: 12px !default;
|
||||
$--radio-bordered-mini-input-width: 12px !default;
|
||||
$--radio-bordered-mini-height: 28px !default;
|
||||
|
||||
/// fontSize||Font|1
|
||||
$--radio-button-font-size: $--font-size-base !default;
|
||||
/// color||Color|0
|
||||
$--radio-button-checked-background-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--radio-button-checked-font-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--radio-button-checked-border-color: $--color-primary !default;
|
||||
$--radio-button-disabled-checked-fill: $--border-color-extra-light !default;
|
||||
|
||||
/* Select
|
||||
-------------------------- */
|
||||
$--select-border-color-hover: $--border-color-hover !default;
|
||||
$--select-disabled-border: $--disabled-border-base !default;
|
||||
/// fontSize||Font|1
|
||||
$--select-font-size: $--font-size-base !default;
|
||||
$--select-close-hover-color: $--color-text-secondary !default;
|
||||
|
||||
$--select-input-color: $--color-text-placeholder !default;
|
||||
$--select-multiple-input-color: #666 !default;
|
||||
/// color||Color|0
|
||||
$--select-input-focus-border-color: $--color-primary !default;
|
||||
/// fontSize||Font|1
|
||||
$--select-input-font-size: 14px !default;
|
||||
|
||||
$--select-option-color: $--color-text-regular !default;
|
||||
$--select-option-disabled-color: $--color-text-placeholder !default;
|
||||
$--select-option-disabled-background: $--color-white !default;
|
||||
/// height||Other|4
|
||||
$--select-option-height: 34px !default;
|
||||
$--select-option-hover-background: $--background-color-base !default;
|
||||
/// color||Color|0
|
||||
$--select-option-selected-font-color: $--color-primary !default;
|
||||
$--select-option-selected-hover: $--background-color-base !default;
|
||||
|
||||
$--select-group-color: $--color-info !default;
|
||||
$--select-group-height: 30px !default;
|
||||
$--select-group-font-size: 12px !default;
|
||||
|
||||
$--select-dropdown-background: $--color-white !default;
|
||||
$--select-dropdown-shadow: $--box-shadow-light !default;
|
||||
$--select-dropdown-empty-color: #999 !default;
|
||||
/// height||Other|4
|
||||
$--select-dropdown-max-height: 274px !default;
|
||||
$--select-dropdown-padding: 6px 0 !default;
|
||||
$--select-dropdown-empty-padding: 10px 0 !default;
|
||||
$--select-dropdown-border: solid 1px $--border-color-light !default;
|
||||
|
||||
/* Alert
|
||||
-------------------------- */
|
||||
$--alert-padding: 8px 16px !default;
|
||||
/// borderRadius||Border|2
|
||||
$--alert-border-radius: $--border-radius-base !default;
|
||||
/// fontSize||Font|1
|
||||
$--alert-title-font-size: 13px !default;
|
||||
/// fontSize||Font|1
|
||||
$--alert-description-font-size: 12px !default;
|
||||
/// fontSize||Font|1
|
||||
$--alert-close-font-size: 12px !default;
|
||||
/// fontSize||Font|1
|
||||
$--alert-close-customed-font-size: 13px !default;
|
||||
|
||||
$--alert-success-color: $--color-success-lighter !default;
|
||||
$--alert-info-color: $--color-info-lighter !default;
|
||||
$--alert-warning-color: $--color-warning-lighter !default;
|
||||
$--alert-danger-color: $--color-danger-lighter !default;
|
||||
|
||||
/// height||Other|4
|
||||
$--alert-icon-size: 16px !default;
|
||||
/// height||Other|4
|
||||
$--alert-icon-large-size: 28px !default;
|
||||
|
||||
/* MessageBox
|
||||
-------------------------- */
|
||||
/// color||Color|0
|
||||
$--messagebox-title-color: $--color-text-primary !default;
|
||||
$--msgbox-width: 420px !default;
|
||||
$--msgbox-border-radius: 4px !default;
|
||||
/// fontSize||Font|1
|
||||
$--messagebox-font-size: $--font-size-large !default;
|
||||
/// fontSize||Font|1
|
||||
$--messagebox-content-font-size: $--font-size-base !default;
|
||||
/// color||Color|0
|
||||
$--messagebox-content-color: $--color-text-regular !default;
|
||||
/// fontSize||Font|1
|
||||
$--messagebox-error-font-size: 12px !default;
|
||||
$--msgbox-padding-primary: 15px !default;
|
||||
/// color||Color|0
|
||||
$--messagebox-success-color: $--color-success !default;
|
||||
/// color||Color|0
|
||||
$--messagebox-info-color: $--color-info !default;
|
||||
/// color||Color|0
|
||||
$--messagebox-warning-color: $--color-warning !default;
|
||||
/// color||Color|0
|
||||
$--messagebox-danger-color: $--color-danger !default;
|
||||
|
||||
/* Message
|
||||
-------------------------- */
|
||||
$--message-shadow: $--box-shadow-base !default;
|
||||
$--message-min-width: 380px !default;
|
||||
$--message-background-color: #edf2fc !default;
|
||||
$--message-padding: 15px 15px 15px 20px !default;
|
||||
/// color||Color|0
|
||||
$--message-close-icon-color: $--color-text-placeholder !default;
|
||||
/// height||Other|4
|
||||
$--message-close-size: 16px !default;
|
||||
/// color||Color|0
|
||||
$--message-close-hover-color: $--color-text-secondary !default;
|
||||
|
||||
/// color||Color|0
|
||||
$--message-success-font-color: $--color-success !default;
|
||||
/// color||Color|0
|
||||
$--message-info-font-color: $--color-info !default;
|
||||
/// color||Color|0
|
||||
$--message-warning-font-color: $--color-warning !default;
|
||||
/// color||Color|0
|
||||
$--message-danger-font-color: $--color-danger !default;
|
||||
|
||||
/* Notification
|
||||
-------------------------- */
|
||||
$--notification-width: 330px !default;
|
||||
/// padding||Spacing|3
|
||||
$--notification-padding: 14px 26px 14px 13px !default;
|
||||
$--notification-radius: 8px !default;
|
||||
$--notification-shadow: $--box-shadow-light !default;
|
||||
/// color||Color|0
|
||||
$--notification-border-color: $--border-color-lighter !default;
|
||||
$--notification-icon-size: 24px !default;
|
||||
$--notification-close-font-size: $--message-close-size !default;
|
||||
$--notification-group-margin-left: 13px !default;
|
||||
$--notification-group-margin-right: 8px !default;
|
||||
/// fontSize||Font|1
|
||||
$--notification-content-font-size: $--font-size-base !default;
|
||||
/// color||Color|0
|
||||
$--notification-content-color: $--color-text-regular !default;
|
||||
/// fontSize||Font|1
|
||||
$--notification-title-font-size: 16px !default;
|
||||
/// color||Color|0
|
||||
$--notification-title-color: $--color-text-primary !default;
|
||||
|
||||
/// color||Color|0
|
||||
$--notification-close-color: $--color-text-secondary !default;
|
||||
/// color||Color|0
|
||||
$--notification-close-hover-color: $--color-text-regular !default;
|
||||
|
||||
/// color||Color|0
|
||||
$--notification-success-icon-color: $--color-success !default;
|
||||
/// color||Color|0
|
||||
$--notification-info-icon-color: $--color-info !default;
|
||||
/// color||Color|0
|
||||
$--notification-warning-icon-color: $--color-warning !default;
|
||||
/// color||Color|0
|
||||
$--notification-danger-icon-color: $--color-danger !default;
|
||||
|
||||
/* Input
|
||||
-------------------------- */
|
||||
$--input-font-size: $--font-size-base !default;
|
||||
/// color||Color|0
|
||||
$--input-font-color: $--color-text-regular !default;
|
||||
/// height||Other|4
|
||||
$--input-width: 140px !default;
|
||||
/// height||Other|4
|
||||
$--input-height: 40px !default;
|
||||
$--input-border: $--border-base !default;
|
||||
$--input-border-color: $--border-color-base !default;
|
||||
/// borderRadius||Border|2
|
||||
$--input-border-radius: $--border-radius-base !default;
|
||||
$--input-border-color-hover: $--border-color-hover !default;
|
||||
/// color||Color|0
|
||||
$--input-background-color: $--color-white !default;
|
||||
$--input-fill-disabled: $--disabled-fill-base !default;
|
||||
$--input-color-disabled: $--font-color-disabled-base !default;
|
||||
/// color||Color|0
|
||||
$--input-icon-color: $--color-text-placeholder !default;
|
||||
/// color||Color|0
|
||||
$--input-placeholder-color: $--color-text-placeholder !default;
|
||||
$--input-max-width: 314px !default;
|
||||
|
||||
$--input-hover-border: $--border-color-hover !default;
|
||||
$--input-clear-hover-color: $--color-text-secondary !default;
|
||||
|
||||
$--input-focus-border: $--color-primary !default;
|
||||
$--input-focus-fill: $--color-white !default;
|
||||
|
||||
$--input-disabled-fill: $--disabled-fill-base !default;
|
||||
$--input-disabled-border: $--disabled-border-base !default;
|
||||
$--input-disabled-color: $--disabled-color-base !default;
|
||||
$--input-disabled-placeholder-color: $--color-text-placeholder !default;
|
||||
|
||||
/// fontSize||Font|1
|
||||
$--input-medium-font-size: 14px !default;
|
||||
/// height||Other|4
|
||||
$--input-medium-height: 36px !default;
|
||||
/// fontSize||Font|1
|
||||
$--input-small-font-size: 13px !default;
|
||||
/// height||Other|4
|
||||
$--input-small-height: 32px !default;
|
||||
/// fontSize||Font|1
|
||||
$--input-mini-font-size: 12px !default;
|
||||
/// height||Other|4
|
||||
$--input-mini-height: 28px !default;
|
||||
|
||||
/* Cascader
|
||||
-------------------------- */
|
||||
/// color||Color|0
|
||||
$--cascader-menu-font-color: $--color-text-regular !default;
|
||||
/// color||Color|0
|
||||
$--cascader-menu-selected-font-color: $--color-primary !default;
|
||||
$--cascader-menu-fill: $--fill-base !default;
|
||||
$--cascader-menu-font-size: $--font-size-base !default;
|
||||
$--cascader-menu-radius: $--border-radius-base !default;
|
||||
$--cascader-menu-border: solid 1px $--border-color-light !default;
|
||||
$--cascader-menu-shadow: $--box-shadow-light !default;
|
||||
$--cascader-node-background-hover: $--background-color-base !default;
|
||||
$--cascader-node-color-disabled:$--color-text-placeholder !default;
|
||||
$--cascader-color-empty:$--color-text-placeholder !default;
|
||||
$--cascader-tag-background: #f0f2f5;
|
||||
|
||||
/* Group
|
||||
-------------------------- */
|
||||
$--group-option-flex: 0 0 (1/5) * 100% !default;
|
||||
$--group-option-offset-bottom: 12px !default;
|
||||
$--group-option-fill-hover: rgba($--color-black, 0.06) !default;
|
||||
$--group-title-color: $--color-black !default;
|
||||
$--group-title-font-size: $--font-size-base !default;
|
||||
$--group-title-width: 66px !default;
|
||||
|
||||
/* Tab
|
||||
-------------------------- */
|
||||
$--tab-font-size: $--font-size-base !default;
|
||||
$--tab-border-line: 1px solid #e4e4e4 !default;
|
||||
$--tab-header-color-active: $--color-text-secondary !default;
|
||||
$--tab-header-color-hover: $--color-text-regular !default;
|
||||
$--tab-header-color: $--color-text-regular !default;
|
||||
$--tab-header-fill-active: rgba($--color-black, 0.06) !default;
|
||||
$--tab-header-fill-hover: rgba($--color-black, 0.06) !default;
|
||||
$--tab-vertical-header-width: 90px !default;
|
||||
$--tab-vertical-header-count-color: $--color-white !default;
|
||||
$--tab-vertical-header-count-fill: $--color-text-secondary !default;
|
||||
|
||||
/* Button
|
||||
-------------------------- */
|
||||
/// fontSize||Font|1
|
||||
$--button-font-size: $--font-size-base !default;
|
||||
/// fontWeight||Font|1
|
||||
$--button-font-weight: $--font-weight-primary !default;
|
||||
/// borderRadius||Border|2
|
||||
$--button-border-radius: $--border-radius-base !default;
|
||||
/// padding||Spacing|3
|
||||
$--button-padding-vertical: 12px !default;
|
||||
/// padding||Spacing|3
|
||||
$--button-padding-horizontal: 20px !default;
|
||||
|
||||
/// fontSize||Font|1
|
||||
$--button-medium-font-size: $--font-size-base !default;
|
||||
/// borderRadius||Border|2
|
||||
$--button-medium-border-radius: $--border-radius-base !default;
|
||||
/// padding||Spacing|3
|
||||
$--button-medium-padding-vertical: 10px !default;
|
||||
/// padding||Spacing|3
|
||||
$--button-medium-padding-horizontal: 20px !default;
|
||||
|
||||
/// fontSize||Font|1
|
||||
$--button-small-font-size: 12px !default;
|
||||
$--button-small-border-radius: #{$--border-radius-base - 1} !default;
|
||||
/// padding||Spacing|3
|
||||
$--button-small-padding-vertical: 9px !default;
|
||||
/// padding||Spacing|3
|
||||
$--button-small-padding-horizontal: 15px !default;
|
||||
/// fontSize||Font|1
|
||||
$--button-mini-font-size: 12px !default;
|
||||
$--button-mini-border-radius: #{$--border-radius-base - 1} !default;
|
||||
/// padding||Spacing|3
|
||||
$--button-mini-padding-vertical: 7px !default;
|
||||
/// padding||Spacing|3
|
||||
$--button-mini-padding-horizontal: 15px !default;
|
||||
|
||||
/// color||Color|0
|
||||
$--button-default-font-color: $--color-text-regular !default;
|
||||
/// color||Color|0
|
||||
$--button-default-background-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--button-default-border-color: $--border-color-base !default;
|
||||
|
||||
/// color||Color|0
|
||||
$--button-disabled-font-color: $--color-text-placeholder !default;
|
||||
/// color||Color|0
|
||||
$--button-disabled-background-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--button-disabled-border-color: $--border-color-lighter !default;
|
||||
|
||||
/// color||Color|0
|
||||
$--button-primary-border-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--button-primary-font-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--button-primary-background-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--button-success-border-color: $--color-success !default;
|
||||
/// color||Color|0
|
||||
$--button-success-font-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--button-success-background-color: $--color-success !default;
|
||||
/// color||Color|0
|
||||
$--button-warning-border-color: $--color-warning !default;
|
||||
/// color||Color|0
|
||||
$--button-warning-font-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--button-warning-background-color: $--color-warning !default;
|
||||
/// color||Color|0
|
||||
$--button-danger-border-color: $--color-danger !default;
|
||||
/// color||Color|0
|
||||
$--button-danger-font-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--button-danger-background-color: $--color-danger !default;
|
||||
/// color||Color|0
|
||||
$--button-info-border-color: $--color-info !default;
|
||||
/// color||Color|0
|
||||
$--button-info-font-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--button-info-background-color: $--color-info !default;
|
||||
|
||||
$--button-hover-tint-percent: 20% !default;
|
||||
$--button-active-shade-percent: 10% !default;
|
||||
|
||||
|
||||
/* cascader
|
||||
-------------------------- */
|
||||
$--cascader-height: 200px !default;
|
||||
|
||||
/* Switch
|
||||
-------------------------- */
|
||||
/// color||Color|0
|
||||
$--switch-on-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--switch-off-color: $--border-color-base !default;
|
||||
/// fontSize||Font|1
|
||||
$--switch-font-size: $--font-size-base !default;
|
||||
$--switch-core-border-radius: 10px !default;
|
||||
// height||Other|4 TODO: width 代码写死的40px 所以下面这三个属性都没意义
|
||||
$--switch-width: 40px !default;
|
||||
// height||Other|4
|
||||
$--switch-height: 20px !default;
|
||||
// height||Other|4
|
||||
$--switch-button-size: 16px !default;
|
||||
|
||||
/* Dialog
|
||||
-------------------------- */
|
||||
$--dialog-background-color: $--color-white !default;
|
||||
$--dialog-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3) !default;
|
||||
/// fontSize||Font|1
|
||||
$--dialog-title-font-size: $--font-size-large !default;
|
||||
/// fontSize||Font|1
|
||||
$--dialog-content-font-size: 14px !default;
|
||||
/// fontLineHeight||LineHeight|2
|
||||
$--dialog-font-line-height: $--font-line-height-primary !default;
|
||||
/// padding||Spacing|3
|
||||
$--dialog-padding-primary: 20px !default;
|
||||
|
||||
/* Table
|
||||
-------------------------- */
|
||||
/// color||Color|0
|
||||
$--table-border-color: $--border-color-lighter !default;
|
||||
$--table-border: 1px solid $--table-border-color !default;
|
||||
/// color||Color|0
|
||||
$--table-font-color: $--color-text-regular !default;
|
||||
/// color||Color|0
|
||||
$--table-header-font-color: $--color-text-secondary !default;
|
||||
/// color||Color|0
|
||||
$--table-row-hover-background-color: $--background-color-base !default;
|
||||
$--table-current-row-background-color: $--color-primary-light-9 !default;
|
||||
/// color||Color|0
|
||||
$--table-header-background-color: $--color-white !default;
|
||||
$--table-fixed-box-shadow: 0 0 10px rgba(0, 0, 0, .12) !default;
|
||||
|
||||
/* Pagination
|
||||
-------------------------- */
|
||||
/// fontSize||Font|1
|
||||
$--pagination-font-size: 13px !default;
|
||||
/// color||Color|0
|
||||
$--pagination-background-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--pagination-font-color: $--color-text-primary !default;
|
||||
$--pagination-border-radius: 3px !default;
|
||||
/// color||Color|0
|
||||
$--pagination-button-color: $--color-text-primary !default;
|
||||
/// height||Other|4
|
||||
$--pagination-button-width: 35.5px !default;
|
||||
/// height||Other|4
|
||||
$--pagination-button-height: 28px !default;
|
||||
/// color||Color|0
|
||||
$--pagination-button-disabled-color: $--color-text-placeholder !default;
|
||||
/// color||Color|0
|
||||
$--pagination-button-disabled-background-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--pagination-hover-color: $--color-primary !default;
|
||||
|
||||
/* Popup
|
||||
-------------------------- */
|
||||
/// color||Color|0
|
||||
$--popup-modal-background-color: $--color-black !default;
|
||||
/// opacity||Other|1
|
||||
$--popup-modal-opacity: 0.5 !default;
|
||||
|
||||
/* Popover
|
||||
-------------------------- */
|
||||
/// color||Color|0
|
||||
$--popover-background-color: $--color-white !default;
|
||||
/// fontSize||Font|1
|
||||
$--popover-font-size: $--font-size-base !default;
|
||||
/// color||Color|0
|
||||
$--popover-border-color: $--border-color-lighter !default;
|
||||
$--popover-arrow-size: 6px !default;
|
||||
/// padding||Spacing|3
|
||||
$--popover-padding: 12px !default;
|
||||
$--popover-padding-large: 18px 20px !default;
|
||||
/// fontSize||Font|1
|
||||
$--popover-title-font-size: 16px !default;
|
||||
/// color||Color|0
|
||||
$--popover-title-font-color: $--color-text-primary !default;
|
||||
|
||||
/* Tooltip
|
||||
-------------------------- */
|
||||
/// color|1|Color|0
|
||||
$--tooltip-fill: $--color-text-primary !default;
|
||||
/// color|1|Color|0
|
||||
$--tooltip-color: $--color-white !default;
|
||||
/// fontSize||Font|1
|
||||
$--tooltip-font-size: 12px !default;
|
||||
/// color||Color|0
|
||||
$--tooltip-border-color: $--color-text-primary !default;
|
||||
$--tooltip-arrow-size: 6px !default;
|
||||
/// padding||Spacing|3
|
||||
$--tooltip-padding: 10px !default;
|
||||
|
||||
/* Tag
|
||||
-------------------------- */
|
||||
/// color||Color|0
|
||||
$--tag-info-color: $--color-info !default;
|
||||
/// color||Color|0
|
||||
$--tag-primary-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--tag-success-color: $--color-success !default;
|
||||
/// color||Color|0
|
||||
$--tag-warning-color: $--color-warning !default;
|
||||
/// color||Color|0
|
||||
$--tag-danger-color: $--color-danger !default;
|
||||
/// fontSize||Font|1
|
||||
$--tag-font-size: 12px !default;
|
||||
$--tag-border-radius: 4px !default;
|
||||
$--tag-padding: 0 10px !default;
|
||||
|
||||
/* Tree
|
||||
-------------------------- */
|
||||
/// color||Color|0
|
||||
$--tree-node-hover-background-color: $--background-color-base !default;
|
||||
/// color||Color|0
|
||||
$--tree-font-color: $--color-text-regular !default;
|
||||
/// color||Color|0
|
||||
$--tree-expand-icon-color: $--color-text-placeholder !default;
|
||||
|
||||
/* Dropdown
|
||||
-------------------------- */
|
||||
$--dropdown-menu-box-shadow: $--box-shadow-light !default;
|
||||
$--dropdown-menuItem-hover-fill: $--color-primary-light-9 !default;
|
||||
$--dropdown-menuItem-hover-color: $--link-color !default;
|
||||
|
||||
/* Badge
|
||||
-------------------------- */
|
||||
/// color||Color|0
|
||||
$--badge-background-color: $--color-danger !default;
|
||||
$--badge-radius: 10px !default;
|
||||
/// fontSize||Font|1
|
||||
$--badge-font-size: 12px !default;
|
||||
/// padding||Spacing|3
|
||||
$--badge-padding: 6px !default;
|
||||
/// height||Other|4
|
||||
$--badge-size: 18px !default;
|
||||
|
||||
/* Card
|
||||
--------------------------*/
|
||||
/// color||Color|0
|
||||
$--card-border-color: $--border-color-lighter !default;
|
||||
$--card-border-radius: 4px !default;
|
||||
/// padding||Spacing|3
|
||||
$--card-padding: 20px !default;
|
||||
|
||||
/* Slider
|
||||
--------------------------*/
|
||||
/// color||Color|0
|
||||
$--slider-main-background-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--slider-runway-background-color: $--border-color-light !default;
|
||||
$--slider-button-hover-color: mix($--color-primary, black, 97%) !default;
|
||||
$--slider-stop-background-color: $--color-white !default;
|
||||
$--slider-disable-color: $--color-text-placeholder !default;
|
||||
$--slider-margin: 16px 0 !default;
|
||||
$--slider-border-radius: 3px !default;
|
||||
/// height|1|Other|4
|
||||
$--slider-height: 6px !default;
|
||||
/// height||Other|4
|
||||
$--slider-button-size: 16px !default;
|
||||
$--slider-button-wrapper-size: 36px !default;
|
||||
$--slider-button-wrapper-offset: -15px !default;
|
||||
|
||||
/* Steps
|
||||
--------------------------*/
|
||||
$--steps-border-color: $--disabled-border-base !default;
|
||||
$--steps-border-radius: 4px !default;
|
||||
$--steps-padding: 20px !default;
|
||||
|
||||
/* Menu
|
||||
--------------------------*/
|
||||
/// fontSize||Font|1
|
||||
$--menu-item-font-size: $--font-size-base !default;
|
||||
/// color||Color|0
|
||||
$--menu-item-font-color: $--color-text-primary !default;
|
||||
/// color||Color|0
|
||||
$--menu-background-color: $--color-white !default;
|
||||
$--menu-item-hover-fill: $--color-primary-light-9 !default;
|
||||
|
||||
/* Rate
|
||||
--------------------------*/
|
||||
$--rate-height: 20px !default;
|
||||
/// fontSize||Font|1
|
||||
$--rate-font-size: $--font-size-base !default;
|
||||
/// height||Other|3
|
||||
$--rate-icon-size: 18px !default;
|
||||
/// margin||Spacing|2
|
||||
$--rate-icon-margin: 6px !default;
|
||||
$--rate-icon-color: $--color-text-placeholder !default;
|
||||
|
||||
/* DatePicker
|
||||
--------------------------*/
|
||||
$--datepicker-font-color: $--color-text-regular !default;
|
||||
/// color|1|Color|0
|
||||
$--datepicker-off-font-color: $--color-text-placeholder !default;
|
||||
/// color||Color|0
|
||||
$--datepicker-header-font-color: $--color-text-regular !default;
|
||||
$--datepicker-icon-color: $--color-text-primary !default;
|
||||
$--datepicker-border-color: $--disabled-border-base !default;
|
||||
$--datepicker-inner-border-color: #e4e4e4 !default;
|
||||
/// color||Color|0
|
||||
$--datepicker-inrange-background-color: $--border-color-extra-light !default;
|
||||
/// color||Color|0
|
||||
$--datepicker-inrange-hover-background-color: $--border-color-extra-light !default;
|
||||
/// color||Color|0
|
||||
$--datepicker-active-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--datepicker-hover-font-color: $--color-primary !default;
|
||||
$--datepicker-cell-hover-color: #fff !default;
|
||||
|
||||
/* Loading
|
||||
--------------------------*/
|
||||
/// height||Other|4
|
||||
$--loading-spinner-size: 42px !default;
|
||||
/// height||Other|4
|
||||
$--loading-fullscreen-spinner-size: 50px !default;
|
||||
|
||||
/* Scrollbar
|
||||
--------------------------*/
|
||||
$--scrollbar-background-color: rgba($--color-text-secondary, .3) !default;
|
||||
$--scrollbar-hover-background-color: rgba($--color-text-secondary, .5) !default;
|
||||
|
||||
/* Carousel
|
||||
--------------------------*/
|
||||
/// fontSize||Font|1
|
||||
$--carousel-arrow-font-size: 12px !default;
|
||||
$--carousel-arrow-size: 36px !default;
|
||||
$--carousel-arrow-background: rgba(31, 45, 61, 0.11) !default;
|
||||
$--carousel-arrow-hover-background: rgba(31, 45, 61, 0.23) !default;
|
||||
/// width||Other|4
|
||||
$--carousel-indicator-width: 30px !default;
|
||||
/// height||Other|4
|
||||
$--carousel-indicator-height: 2px !default;
|
||||
$--carousel-indicator-padding-horizontal: 4px !default;
|
||||
$--carousel-indicator-padding-vertical: 12px !default;
|
||||
$--carousel-indicator-out-color: $--border-color-hover !default;
|
||||
|
||||
/* Collapse
|
||||
--------------------------*/
|
||||
/// color||Color|0
|
||||
$--collapse-border-color: $--border-color-lighter !default;
|
||||
/// height||Other|4
|
||||
$--collapse-header-height: 48px !default;
|
||||
/// color||Color|0
|
||||
$--collapse-header-background-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--collapse-header-font-color: $--color-text-primary !default;
|
||||
/// fontSize||Font|1
|
||||
$--collapse-header-font-size: 13px !default;
|
||||
/// color||Color|0
|
||||
$--collapse-content-background-color: $--color-white !default;
|
||||
/// fontSize||Font|1
|
||||
$--collapse-content-font-size: 13px !default;
|
||||
/// color||Color|0
|
||||
$--collapse-content-font-color: $--color-text-primary !default;
|
||||
|
||||
/* Transfer
|
||||
--------------------------*/
|
||||
$--transfer-border-color: $--border-color-lighter !default;
|
||||
$--transfer-border-radius: $--border-radius-base !default;
|
||||
/// height||Other|4
|
||||
$--transfer-panel-width: 200px !default;
|
||||
/// height||Other|4
|
||||
$--transfer-panel-header-height: 40px !default;
|
||||
/// color||Color|0
|
||||
$--transfer-panel-header-background-color: $--background-color-base !default;
|
||||
/// height||Other|4
|
||||
$--transfer-panel-footer-height: 40px !default;
|
||||
/// height||Other|4
|
||||
$--transfer-panel-body-height: 246px !default;
|
||||
/// height||Other|4
|
||||
$--transfer-item-height: 30px !default;
|
||||
/// height||Other|4
|
||||
$--transfer-filter-height: 32px !default;
|
||||
|
||||
/* Header
|
||||
--------------------------*/
|
||||
$--header-padding: 0 20px !default;
|
||||
|
||||
/* Footer
|
||||
--------------------------*/
|
||||
$--footer-padding: 0 20px !default;
|
||||
|
||||
/* Main
|
||||
--------------------------*/
|
||||
$--main-padding: 20px !default;
|
||||
|
||||
/* Timeline
|
||||
--------------------------*/
|
||||
$--timeline-node-size-normal: 12px !default;
|
||||
$--timeline-node-size-large: 14px !default;
|
||||
$--timeline-node-color: $--border-color-light !default;
|
||||
|
||||
/* Backtop
|
||||
--------------------------*/
|
||||
/// color||Color|0
|
||||
$--backtop-background-color: $--color-white !default;
|
||||
/// color||Color|0
|
||||
$--backtop-font-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--backtop-hover-background-color: $--border-color-extra-light !default;
|
||||
|
||||
/* Link
|
||||
--------------------------*/
|
||||
/// fontSize||Font|1
|
||||
$--link-font-size: $--font-size-base !default;
|
||||
/// fontWeight||Font|1
|
||||
$--link-font-weight: $--font-weight-primary !default;
|
||||
/// color||Color|0
|
||||
$--link-default-font-color: $--color-text-regular !default;
|
||||
/// color||Color|0
|
||||
$--link-default-active-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--link-disabled-font-color: $--color-text-placeholder !default;
|
||||
/// color||Color|0
|
||||
$--link-primary-font-color: $--color-primary !default;
|
||||
/// color||Color|0
|
||||
$--link-success-font-color: $--color-success !default;
|
||||
/// color||Color|0
|
||||
$--link-warning-font-color: $--color-warning !default;
|
||||
/// color||Color|0
|
||||
$--link-danger-font-color: $--color-danger !default;
|
||||
/// color||Color|0
|
||||
$--link-info-font-color: $--color-info !default;
|
||||
/* Calendar
|
||||
--------------------------*/
|
||||
/// border||Other|4
|
||||
$--calendar-border: $--table-border !default;
|
||||
/// color||Other|4
|
||||
$--calendar-selected-background-color: #F2F8FE !default;
|
||||
$--calendar-cell-width: 85px !default;
|
||||
|
||||
/* Form
|
||||
-------------------------- */
|
||||
/// fontSize||Font|1
|
||||
$--form-label-font-size: $--font-size-base !default;
|
||||
|
||||
/* Avatar
|
||||
--------------------------*/
|
||||
/// color||Color|0
|
||||
$--avatar-font-color: #fff !default;
|
||||
/// color||Color|0
|
||||
$--avatar-background-color: #C0C4CC !default;
|
||||
/// fontSize||Font Size|1
|
||||
$--avatar-text-font-size: 14px !default;
|
||||
/// fontSize||Font Size|1
|
||||
$--avatar-icon-font-size: 18px !default;
|
||||
/// borderRadius||Border|2
|
||||
$--avatar-border-radius: $--border-radius-base !default;
|
||||
/// size|1|Avatar Size|3
|
||||
$--avatar-large-size: 40px !default;
|
||||
/// size|1|Avatar Size|3
|
||||
$--avatar-medium-size: 36px !default;
|
||||
/// size|1|Avatar Size|3
|
||||
$--avatar-small-size: 28px !default;
|
||||
|
||||
/* Break-point
|
||||
--------------------------*/
|
||||
$--sm: 768px !default;
|
||||
$--md: 992px !default;
|
||||
$--lg: 1200px !default;
|
||||
$--xl: 1920px !default;
|
||||
|
||||
$--breakpoints: (
|
||||
'xs' : (max-width: $--sm - 1),
|
||||
'sm' : (min-width: $--sm),
|
||||
'md' : (min-width: $--md),
|
||||
'lg' : (min-width: $--lg),
|
||||
'xl' : (min-width: $--xl)
|
||||
);
|
||||
|
||||
$--breakpoints-spec: (
|
||||
'xs-only' : (max-width: $--sm - 1),
|
||||
'sm-and-up' : (min-width: $--sm),
|
||||
'sm-only': "(min-width: #{$--sm}) and (max-width: #{$--md - 1})",
|
||||
'sm-and-down': (max-width: $--md - 1),
|
||||
'md-and-up' : (min-width: $--md),
|
||||
'md-only': "(min-width: #{$--md}) and (max-width: #{$--lg - 1})",
|
||||
'md-and-down': (max-width: $--lg - 1),
|
||||
'lg-and-up' : (min-width: $--lg),
|
||||
'lg-only': "(min-width: #{$--lg}) and (max-width: #{$--xl - 1})",
|
||||
'lg-and-down': (max-width: $--xl - 1),
|
||||
'xl-only' : (min-width: $--xl),
|
||||
);
|
||||
13
client/src/style/index.css
Normal file
13
client/src/style/index.css
Normal file
@@ -0,0 +1,13 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
@import 'element-variables';
|
||||
@import 'reboot';
|
||||
@@ -1,40 +0,0 @@
|
||||
const title = 'Ratteb';
|
||||
|
||||
export const getPageTitle = (pageTitle) => {
|
||||
if (pageTitle) {
|
||||
return `${pageTitle} - ${title}`;
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
||||
// const clipboardSuccess = () => {
|
||||
// Vue.prototype.$message({
|
||||
// message: 'Copy successfully',
|
||||
// type: 'success',
|
||||
// duration: 1500,
|
||||
// });
|
||||
// };
|
||||
|
||||
// const clipboardError = () => {
|
||||
// Vue.prototype.$message({
|
||||
// message: 'Copy failed',
|
||||
// type: 'error',
|
||||
// });
|
||||
// };
|
||||
|
||||
export const handleClipboard = (text, event) => {
|
||||
// const clipboard = new Clipboard(event.target, {
|
||||
// text: () => text
|
||||
// })
|
||||
// clipboard.on('success', () => {
|
||||
// clipboardSuccess()
|
||||
// clipboard.destroy()
|
||||
// })
|
||||
// clipboard.on('error', () => {
|
||||
// clipboardError()
|
||||
// clipboard.destroy()
|
||||
// })
|
||||
// clipboard.onClick(event)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export const set = property => (store, payload) => (store[property] = payload)
|
||||
export const toggle = property => store => (store[property] = !store[property])
|
||||
@@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'search-dialog',
|
||||
data() {
|
||||
return {
|
||||
current_state: 0,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,36 +0,0 @@
|
||||
<template>
|
||||
<div class="sidebar__menu-item" :class="computedClasses">
|
||||
<router-link class="sidebar__menu-item-anchor" :to="{name: to}">
|
||||
<span class="title">{{ name }}</span>
|
||||
<span v-if="count" class="count">{{ count }}</span>
|
||||
</router-link>
|
||||
|
||||
<div v-if="hasChildren" class="sidebar__menu-item-children">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'sidebar-item',
|
||||
props: {
|
||||
name: String,
|
||||
to: String,
|
||||
icon: String,
|
||||
children: Array,
|
||||
count: [Number, Boolean],
|
||||
},
|
||||
computed: {
|
||||
computedClasses() {
|
||||
return {
|
||||
[`sidebar__item--${this.name}`]: this.name,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
hasChildren() {
|
||||
return this.children.length > 0;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,129 +0,0 @@
|
||||
<template>
|
||||
<div class="dashboard__sidebar sidebar">
|
||||
|
||||
<div class="sidebar__app">
|
||||
<div class="sidebar__app-logo">
|
||||
<span class="logo"></span>
|
||||
</div>
|
||||
|
||||
<div class="sidebar__app-info">
|
||||
<h6 class="title">{{ appName }}</h6>
|
||||
<span class="version">{{ appVersion }} (build {{ appBuild }})</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="sidebar__menu">
|
||||
<SidebarItem
|
||||
v-for="(item, index) in sidebarItems" :key="index"
|
||||
:to="item.to"
|
||||
:name="item.name"
|
||||
:count="item.count || false"
|
||||
:children="item.children"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="sidebar__user">
|
||||
<div class="sidebar__user-avatar">
|
||||
<span class="logo"></span>
|
||||
</div>
|
||||
|
||||
<div class="sidebar__user-info">
|
||||
<h6 class="title">Ahmed Bouhuolia</h6>
|
||||
<span class="info">a.bouhuolia@gmail.com</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SidebarItem from '@/views/Sidebar/SidebarItem';
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'sidebar',
|
||||
components: {
|
||||
SidebarItem,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
appName: 'getAppName',
|
||||
appVersion: 'getAppVersion',
|
||||
appBuild: 'getAppBuild',
|
||||
sidebarItems: 'getSidebarItems',
|
||||
}),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.sidebar{
|
||||
width: 210px;
|
||||
min-width: 210px;
|
||||
background: #01092d;
|
||||
transition: width 0.3s;
|
||||
height: 100%;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
|
||||
// App info
|
||||
// -------------
|
||||
&__app{
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&-logo{
|
||||
|
||||
.logo {
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
border-radius: 35px;
|
||||
background: red;
|
||||
}
|
||||
}
|
||||
|
||||
&-info{
|
||||
|
||||
.title{
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.version{
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Menu List
|
||||
// -------------
|
||||
&__menu{
|
||||
|
||||
}
|
||||
|
||||
&__menu-item{
|
||||
|
||||
&-anchor{
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
// User info.
|
||||
// -------------
|
||||
&__user{
|
||||
border-top: 1px solid red;
|
||||
|
||||
&-info{
|
||||
|
||||
.title{
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info{
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<div class="topbar">
|
||||
<div class="topbar__sidebar-toggle">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="topbar__title">
|
||||
<h3>{{ pageTitle }}</h3>
|
||||
</div>
|
||||
|
||||
<div class="topbar__actions">
|
||||
<div class="topbar__actions-list">
|
||||
<div v-for="(action, index) in actions" :key="index">
|
||||
<button @click.prevent="onClickItem(action)">{{ action.label }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'dashboard-topbar',
|
||||
computed: {
|
||||
...mapGetters({
|
||||
pageTitle: 'getPageTitle',
|
||||
quickActions: 'getQuickActions',
|
||||
}),
|
||||
actions() {
|
||||
return this.quickActions(this.$route.name) || [];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
onClickItem(action) {
|
||||
return action;
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.topbar{
|
||||
padding-bottom: 12px;
|
||||
width: 100%;
|
||||
|
||||
&__title{
|
||||
|
||||
h3{
|
||||
margin: 0;
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
&__actions{
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user