Added project files
This commit is contained in:
parent
efb857c08e
commit
affbd34f61
|
@ -0,0 +1,17 @@
|
||||||
|
import store from '@/store';
|
||||||
|
|
||||||
|
export function useRole() {
|
||||||
|
function hasAny(roles: string[]): boolean {
|
||||||
|
const roleStore: string[] = store.state.roles;
|
||||||
|
|
||||||
|
for (const role of roles) {
|
||||||
|
if (roleStore.indexOf(role) !== -1) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
hasAny,
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { useState } from './useState';
|
||||||
|
|
||||||
|
interface Session {
|
||||||
|
token: string;
|
||||||
|
keepLogin: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface useSession {
|
||||||
|
getToken: () => string;
|
||||||
|
setToken: (data: Session) => void;
|
||||||
|
destroy: () => void;
|
||||||
|
isLoggedIn: () => boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSession(): useSession {
|
||||||
|
function getToken(): string {
|
||||||
|
const localToken = localStorage.getItem('token');
|
||||||
|
const sessionToken = sessionStorage.getItem('token');
|
||||||
|
|
||||||
|
return localToken || sessionToken || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function setToken(data: Session): void {
|
||||||
|
if (data.keepLogin) {
|
||||||
|
localStorage.setItem('token', data.token);
|
||||||
|
} else {
|
||||||
|
sessionStorage.setItem('token', data.token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroy(): void {
|
||||||
|
localStorage.removeItem('token');
|
||||||
|
sessionStorage.getItem('token');
|
||||||
|
|
||||||
|
const { setUser } = useState();
|
||||||
|
|
||||||
|
setUser({
|
||||||
|
id: 0,
|
||||||
|
username: '',
|
||||||
|
nickname: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLoggedIn() {
|
||||||
|
const localToken = localStorage.getItem('token');
|
||||||
|
const sessionToken = sessionStorage.getItem('token');
|
||||||
|
|
||||||
|
return !!(localToken || sessionToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
getToken,
|
||||||
|
setToken,
|
||||||
|
destroy,
|
||||||
|
isLoggedIn,
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { ref, Ref, computed, ComputedRef } from 'vue';
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
id: number;
|
||||||
|
username: string;
|
||||||
|
nickname: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface useState {
|
||||||
|
getUser: () => ComputedRef<User>;
|
||||||
|
setUser: (data: User) => void;
|
||||||
|
getRoles: () => ComputedRef<string[]>;
|
||||||
|
setRoles: (data: string[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const user: Ref<User> = ref({
|
||||||
|
id: 0,
|
||||||
|
username: '',
|
||||||
|
nickname: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const roles: Ref<string[]> = ref([]);
|
||||||
|
|
||||||
|
export function useState(): useState {
|
||||||
|
function getUser(): ComputedRef<User> {
|
||||||
|
return computed(() => {
|
||||||
|
return {
|
||||||
|
id: user.value.id,
|
||||||
|
username: user.value.username,
|
||||||
|
nickname: user.value.nickname,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUser(data: User): void {
|
||||||
|
user.value = {
|
||||||
|
id: data.id,
|
||||||
|
username: data.username,
|
||||||
|
nickname: data.nickname,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRoles(): ComputedRef<string[]> {
|
||||||
|
return computed(() => {
|
||||||
|
return roles.value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setRoles(data: string[]): void {
|
||||||
|
roles.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
getUser,
|
||||||
|
setUser,
|
||||||
|
getRoles,
|
||||||
|
setRoles,
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
<template>
|
||||||
|
<q-layout view="hHh lpR fFf">
|
||||||
|
<Topbar @on-toggle-drawer="onToggleDrawer()" />
|
||||||
|
<q-drawer
|
||||||
|
v-model="drawer"
|
||||||
|
show-if-above
|
||||||
|
:mini="miniState"
|
||||||
|
@mouseover="miniState = false"
|
||||||
|
@mouseout="miniState = true"
|
||||||
|
mini-to-overlay
|
||||||
|
:width="200"
|
||||||
|
:breakpoint="500"
|
||||||
|
>
|
||||||
|
<q-scroll-area class="fit text-grey-8">
|
||||||
|
<q-list padding>
|
||||||
|
<q-item clickable v-ripple :to="{ path: '/dashboard' }" active-class="text-orange">
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon name="dashboard" />
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section> Dashboard</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item clickable v-ripple :to="{ path: '/customer' }" active-class="text-orange">
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon name="people" />
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section> Customers </q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item clickable v-ripple :to="{ path: '/ticket' }" active-class="text-orange">
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon name="vn:ticket" />
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section> Tickets </q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item clickable v-ripple>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon name="receipt" />
|
||||||
|
</q-item-section>
|
||||||
|
|
||||||
|
<q-item-section> Invoice Out </q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-item clickable v-ripple>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon name="shopping_cart" />
|
||||||
|
</q-item-section>
|
||||||
|
|
||||||
|
<q-item-section> Catalog </q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-separator />
|
||||||
|
|
||||||
|
<q-item clickable v-ripple>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon name="drafts" />
|
||||||
|
</q-item-section>
|
||||||
|
|
||||||
|
<q-item-section> Drafts </q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-scroll-area>
|
||||||
|
</q-drawer>
|
||||||
|
<q-page-container>
|
||||||
|
<router-view></router-view>
|
||||||
|
</q-page-container>
|
||||||
|
</q-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import Topbar from '@/components/Topbar.vue';
|
||||||
|
const drawer = ref(false);
|
||||||
|
const miniState = ref(true);
|
||||||
|
|
||||||
|
function onToggleDrawer(): void {
|
||||||
|
drawer.value = !drawer.value;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.bg-darker {
|
||||||
|
background-color: $darker;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,107 +0,0 @@
|
||||||
<template>
|
|
||||||
<q-layout view="lHh Lpr lFf">
|
|
||||||
<q-header elevated>
|
|
||||||
<q-toolbar>
|
|
||||||
<q-btn
|
|
||||||
flat
|
|
||||||
dense
|
|
||||||
round
|
|
||||||
icon="menu"
|
|
||||||
aria-label="Menu"
|
|
||||||
@click="toggleLeftDrawer"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<q-toolbar-title> Quasar App </q-toolbar-title>
|
|
||||||
|
|
||||||
<div>Quasar v{{ $q.version }}</div>
|
|
||||||
</q-toolbar>
|
|
||||||
</q-header>
|
|
||||||
|
|
||||||
<q-drawer v-model="leftDrawerOpen" show-if-above bordered>
|
|
||||||
<q-list>
|
|
||||||
<q-item-label header> Essential Links </q-item-label>
|
|
||||||
|
|
||||||
<EssentialLink
|
|
||||||
v-for="link in essentialLinks"
|
|
||||||
:key="link.title"
|
|
||||||
v-bind="link"
|
|
||||||
/>
|
|
||||||
</q-list>
|
|
||||||
</q-drawer>
|
|
||||||
|
|
||||||
<q-page-container>
|
|
||||||
<router-view />
|
|
||||||
</q-page-container>
|
|
||||||
</q-layout>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import EssentialLink from 'components/EssentialLink.vue';
|
|
||||||
|
|
||||||
const linksList = [
|
|
||||||
{
|
|
||||||
title: 'Docs',
|
|
||||||
caption: 'quasar.dev',
|
|
||||||
icon: 'school',
|
|
||||||
link: 'https://quasar.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Github',
|
|
||||||
caption: 'github.com/quasarframework',
|
|
||||||
icon: 'code',
|
|
||||||
link: 'https://github.com/quasarframework',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Discord Chat Channel',
|
|
||||||
caption: 'chat.quasar.dev',
|
|
||||||
icon: 'chat',
|
|
||||||
link: 'https://chat.quasar.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Forum',
|
|
||||||
caption: 'forum.quasar.dev',
|
|
||||||
icon: 'record_voice_over',
|
|
||||||
link: 'https://forum.quasar.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Twitter',
|
|
||||||
caption: '@quasarframework',
|
|
||||||
icon: 'rss_feed',
|
|
||||||
link: 'https://twitter.quasar.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Facebook',
|
|
||||||
caption: '@QuasarFramework',
|
|
||||||
icon: 'public',
|
|
||||||
link: 'https://facebook.quasar.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Quasar Awesome',
|
|
||||||
caption: 'Community Quasar projects',
|
|
||||||
icon: 'favorite',
|
|
||||||
link: 'https://awesome.quasar.dev',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
import { defineComponent, ref } from 'vue';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'MainLayout',
|
|
||||||
|
|
||||||
components: {
|
|
||||||
EssentialLink,
|
|
||||||
},
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
const leftDrawerOpen = ref(false);
|
|
||||||
|
|
||||||
return {
|
|
||||||
essentialLinks: linksList,
|
|
||||||
leftDrawerOpen,
|
|
||||||
toggleLeftDrawer() {
|
|
||||||
leftDrawerOpen.value = !leftDrawerOpen.value;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
<template>
|
||||||
|
<div class="row fit fixed">
|
||||||
|
<div class="col-2">
|
||||||
|
<q-card square>
|
||||||
|
<router-link :to="{ path: '/customer/list' }">
|
||||||
|
<q-icon name="arrow_back" size="md" color="primary" />
|
||||||
|
</router-link>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
<q-card>asd</q-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<template>
|
||||||
|
<router-view></router-view>
|
||||||
|
</template>
|
|
@ -0,0 +1,145 @@
|
||||||
|
<template>
|
||||||
|
<q-page class="q-pa-md">
|
||||||
|
<div class="column items-center q-gutter-y-md">
|
||||||
|
<q-card v-for="customer in customers" :key="customer.id" class="card">
|
||||||
|
<!-- v-ripple :to="{ path: '/dashboard' }" -->
|
||||||
|
<q-item v-ripple class="q-pa-none items-start cursor-pointer q-hoverable">
|
||||||
|
<q-item-section class="q-pa-md">
|
||||||
|
<div class="text-h6">{{ customer.name }}</div>
|
||||||
|
<q-item-label caption>@{{ customer.username }}</q-item-label>
|
||||||
|
<div class="q-mt-md">
|
||||||
|
<q-list>
|
||||||
|
<q-item class="q-pa-none">
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label caption>Email</q-item-label>
|
||||||
|
<q-item-label>{{ customer.email }}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item class="q-pa-none">
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label caption>Phone</q-item-label>
|
||||||
|
<q-item-label>{{ customer.phone }} </q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</div>
|
||||||
|
</q-item-section>
|
||||||
|
<q-btn color="grey-7" round flat icon="more_vert">
|
||||||
|
<q-menu cover auto-close>
|
||||||
|
<q-list>
|
||||||
|
<q-item clickable>
|
||||||
|
<q-item-section>Action 1</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item clickable>
|
||||||
|
<q-item-section>Action 2</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-menu>
|
||||||
|
</q-btn>
|
||||||
|
<q-separator vertical />
|
||||||
|
<q-card-actions vertical class="justify-between">
|
||||||
|
<q-btn flat round color="orange" icon="arrow_circle_right" @click="navigate(customer.id)" />
|
||||||
|
<q-btn flat round color="accent" icon="preview" />
|
||||||
|
<q-btn flat round color="accent" icon="vn:ticket" />
|
||||||
|
<q-card-actions>
|
||||||
|
<q-btn
|
||||||
|
color="grey"
|
||||||
|
round
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
:icon="customer.expanded.value ? 'keyboard_arrow_up' : 'keyboard_arrow_down'"
|
||||||
|
@click="customer.expanded.value = !customer.expanded.value"
|
||||||
|
/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-item>
|
||||||
|
<q-slide-transition>
|
||||||
|
<div v-show="customer.expanded.value">
|
||||||
|
<q-separator />
|
||||||
|
<q-card-section class="text-subitle2">
|
||||||
|
<q-list>
|
||||||
|
<q-item clickable>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>Address</q-item-label>
|
||||||
|
<q-item-label caption>Avenue 11</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-card-section>
|
||||||
|
</div>
|
||||||
|
</q-slide-transition>
|
||||||
|
<!-- <q-card-section horizontal>
|
||||||
|
<q-card-section vertical class="col">
|
||||||
|
<div class="text-h6">{{ customer.name }}</div>
|
||||||
|
<div class="text-subtitle2">@{{ customer.username }}</div>
|
||||||
|
|
||||||
|
<q-card-section vertical>text</q-card-section>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-separator vertical />
|
||||||
|
|
||||||
|
<q-card-actions vertical class="justify-around">
|
||||||
|
<q-btn flat round color="red" icon="favorite" />
|
||||||
|
<q-btn flat round color="accent" icon="bookmark" />
|
||||||
|
<q-btn color="grey-7" round flat icon="more_vert">
|
||||||
|
<q-menu cover auto-close>
|
||||||
|
<q-list>
|
||||||
|
<q-item clickable>
|
||||||
|
<q-item-section>Action 1</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item clickable>
|
||||||
|
<q-item-section>Action 2</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-menu>
|
||||||
|
</q-btn>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card-section> -->
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
</q-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, Ref } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
interface Customer {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
username: string;
|
||||||
|
email: string;
|
||||||
|
phone: string;
|
||||||
|
expanded: Ref<boolean>;
|
||||||
|
}
|
||||||
|
const customers: Customer[] = [
|
||||||
|
{
|
||||||
|
id: 1101,
|
||||||
|
name: 'Bruce Wayne',
|
||||||
|
username: 'batman',
|
||||||
|
email: 'batman@gotham',
|
||||||
|
phone: '555-555-5555',
|
||||||
|
expanded: ref(false),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1102,
|
||||||
|
name: 'James Gordon',
|
||||||
|
username: 'jamesgordon',
|
||||||
|
email: 'jamesgordon@gotham',
|
||||||
|
phone: '555-555-1111',
|
||||||
|
expanded: ref(false),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function navigate(id: number) {
|
||||||
|
router.push({ path: `/customer/${id}` });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 60em;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<q-page class="q-pa-md">
|
||||||
|
<q-card class="q-pa-md"> Dashboard page.. </q-card>
|
||||||
|
</q-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
|
@ -1,23 +0,0 @@
|
||||||
<template>
|
|
||||||
<!-- <q-page class="row items-center justify-evenly">
|
|
||||||
<example-component
|
|
||||||
title="Example component"
|
|
||||||
active
|
|
||||||
:todos="todos"
|
|
||||||
:meta="meta"
|
|
||||||
></example-component>
|
|
||||||
</q-page>-->
|
|
||||||
<div>asdasda</div>
|
|
||||||
<q-icon name="vn:ticket" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
// import { useQuasar } from 'quasar';
|
|
||||||
//const { t } = useI18n();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
div {
|
|
||||||
background-color: $primary;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
<template>
|
||||||
|
<q-layout>
|
||||||
|
<q-header class="transparent">
|
||||||
|
<q-toolbar>
|
||||||
|
<q-space></q-space>
|
||||||
|
<q-toggle
|
||||||
|
:label="t(`globals.lang['${locale}']`)"
|
||||||
|
icon="public"
|
||||||
|
color="orange"
|
||||||
|
false-value="es"
|
||||||
|
true-value="en"
|
||||||
|
v-model="locale"
|
||||||
|
/>
|
||||||
|
<q-toggle
|
||||||
|
v-model="darkMode"
|
||||||
|
checked-icon="dark_mode"
|
||||||
|
color="orange"
|
||||||
|
unchecked-icon="light_mode"
|
||||||
|
/>
|
||||||
|
</q-toolbar>
|
||||||
|
</q-header>
|
||||||
|
<q-page-container>
|
||||||
|
<q-page>
|
||||||
|
<div id="login">
|
||||||
|
<q-card class="login q-pa-xl">
|
||||||
|
<img src="@/assets/logo.svg" alt="Logo" class="logo q-mb-xl" />
|
||||||
|
<q-form @submit="onSubmit" class="q-gutter-md">
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
color="orange"
|
||||||
|
v-model="username"
|
||||||
|
:label="t('login.username')"
|
||||||
|
lazy-rules
|
||||||
|
:rules="[
|
||||||
|
(val: string) => (val && val.length > 0) || 'Please type something',
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
color="orange"
|
||||||
|
type="password"
|
||||||
|
v-model="password"
|
||||||
|
:label="t('login.password')"
|
||||||
|
lazy-rules
|
||||||
|
:rules="[
|
||||||
|
(val: string) => (val && val.length > 0) || 'Please type something',
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
<q-toggle
|
||||||
|
v-model="keepLogin"
|
||||||
|
:label="t('login.keepLogin')"
|
||||||
|
color="orange"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<q-btn :label="t('login.submit')" type="submit" color="orange" />
|
||||||
|
</div>
|
||||||
|
</q-form>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
</q-page>
|
||||||
|
</q-page-container>
|
||||||
|
</q-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { Dark, useQuasar } from 'quasar';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import { useSession } from '/components/Session';
|
||||||
|
|
||||||
|
const quasar = useQuasar();
|
||||||
|
const session = useSession();
|
||||||
|
const router = useRouter();
|
||||||
|
const { t, locale } = useI18n();
|
||||||
|
|
||||||
|
let username = ref('');
|
||||||
|
let password = ref('');
|
||||||
|
let keepLogin = ref(true);
|
||||||
|
|
||||||
|
const darkMode = computed({
|
||||||
|
get(): boolean {
|
||||||
|
return Dark.isActive;
|
||||||
|
},
|
||||||
|
set(value: boolean): void {
|
||||||
|
Dark.set(value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function onSubmit(): void {
|
||||||
|
axios
|
||||||
|
.post('/api/accounts/login', {
|
||||||
|
user: username.value,
|
||||||
|
password: password.value,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
session.setToken({
|
||||||
|
token: response.data.token,
|
||||||
|
keepLogin: keepLogin.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
quasar.notify({
|
||||||
|
message: t('login.loginSuccess'),
|
||||||
|
type: 'positive',
|
||||||
|
});
|
||||||
|
router.push('/dashboard');
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const errorCode = error.response.status;
|
||||||
|
if (errorCode === 401) {
|
||||||
|
quasar.notify({
|
||||||
|
message: t('login.loginFailed'),
|
||||||
|
type: 'negative',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
quasar.notify({
|
||||||
|
message: t('errors.statusInternalServerError'),
|
||||||
|
type: 'negative',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
#login {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login {
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,9 +1,9 @@
|
||||||
import { route } from 'quasar/wrappers';
|
import { route } from 'quasar/wrappers';
|
||||||
import {
|
import {
|
||||||
createMemoryHistory,
|
createMemoryHistory,
|
||||||
createRouter,
|
createRouter,
|
||||||
createWebHashHistory,
|
createWebHashHistory,
|
||||||
createWebHistory,
|
createWebHistory,
|
||||||
} from 'vue-router';
|
} from 'vue-router';
|
||||||
import routes from './routes';
|
import routes from './routes';
|
||||||
|
|
||||||
|
@ -17,23 +17,23 @@ import routes from './routes';
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default route(function (/* { store, ssrContext } */) {
|
export default route(function (/* { store, ssrContext } */) {
|
||||||
const createHistory = process.env.SERVER
|
const createHistory = process.env.SERVER
|
||||||
? createMemoryHistory
|
? createMemoryHistory
|
||||||
: process.env.VUE_ROUTER_MODE === 'history'
|
: process.env.VUE_ROUTER_MODE === 'history'
|
||||||
? createWebHistory
|
? createWebHistory
|
||||||
: createWebHashHistory;
|
: createWebHashHistory;
|
||||||
|
|
||||||
const Router = createRouter({
|
const Router = createRouter({
|
||||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||||
routes,
|
routes,
|
||||||
|
|
||||||
// Leave this as is and make changes in quasar.conf.js instead!
|
// Leave this as is and make changes in quasar.conf.js instead!
|
||||||
// quasar.conf.js -> build -> vueRouterMode
|
// quasar.conf.js -> build -> vueRouterMode
|
||||||
// quasar.conf.js -> build -> publicPath
|
// quasar.conf.js -> build -> publicPath
|
||||||
history: createHistory(
|
history: createHistory(
|
||||||
process.env.MODE === 'ssr' ? void 0 : process.env.VUE_ROUTER_BASE
|
process.env.MODE === 'ssr' ? void 0 : process.env.VUE_ROUTER_BASE
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
return Router;
|
return Router;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,18 +1,47 @@
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
const routes: RouteRecordRaw[] = [
|
const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/login',
|
||||||
component: () => import('layouts/MainLayout.vue'),
|
name: 'Login',
|
||||||
children: [{ path: '', component: () => import('pages/Index.vue') }],
|
component: () => import('../pages/Login/Login.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
// Always leave this as last one,
|
path: '/',
|
||||||
// but you can also remove it
|
name: 'Main',
|
||||||
{
|
component: () => import('../Layout/Main.vue'),
|
||||||
path: '/:catchAll(.*)*',
|
redirect: { name: 'Dashboard' },
|
||||||
component: () => import('pages/Error404.vue'),
|
children: [
|
||||||
},
|
{
|
||||||
|
path: '/dashboard',
|
||||||
|
name: 'Dashboard',
|
||||||
|
component: () => import('../pages/Dashboard/Dashboard.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/customer',
|
||||||
|
name: 'Customer',
|
||||||
|
component: () => import('../pages/Customer/Customer.vue'),
|
||||||
|
redirect: { name: 'List' },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'list',
|
||||||
|
name: 'List',
|
||||||
|
component: () => import('../pages/Customer/List.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':id',
|
||||||
|
name: 'Card',
|
||||||
|
component: () => import('../pages/Customer/Card/Card.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/:pathMatch(.*)*',
|
||||||
|
name: 'NotFound',
|
||||||
|
component: () => import('../pages/Layout/NotFound.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default routes;
|
export default routes;
|
||||||
|
|
Loading…
Reference in New Issue