Refactor code to handle login/home/index page as in new layouts

pull/3890/head
Julio Montoya 4 years ago
parent c5033bd6b1
commit cab2a9335b
  1. 16
      assets/vue/components/ErrorMessage.vue
  2. 126
      assets/vue/components/Login.vue
  3. 27
      assets/vue/components/layout/DashboardLayout.vue
  4. 2
      assets/vue/components/layout/EmptyLayout.vue
  5. 1
      assets/vue/components/sidebar/Sidebar.vue
  6. 14
      assets/vue/pages/Home.vue
  7. 64
      assets/vue/pages/Index.vue
  8. 23
      assets/vue/pages/Login.vue
  9. 22
      assets/vue/router/index.js
  10. 136
      assets/vue/views/Login.vue
  11. 2
      assets/vue/views/course/Home.vue

@ -9,13 +9,13 @@
</template>
<script>
export default {
name: "ErrorMessage",
props: {
error: {
type: Error,
required: true
}
},
export default {
name: "ErrorMessage",
props: {
error: {
type: Error,
required: true
}
},
}
</script>

@ -0,0 +1,126 @@
<template>
<form class="mt-8 space-y-6" @submit.prevent="onSubmit">
<input type="hidden" name="remember" value="true" />
<div class="rounded-md shadow-sm -space-y-px">
<div>
<label for="login" class="sr-only">Username</label>
<input id="login" v-model="login" name="login" type="text" autocomplete="login" required=""
class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Username"/>
</div>
<div>
<label for="password" class="sr-only">Password</label>
<input id="password" v-model="password" name="password" type="password" autocomplete="current-password"
required=""
class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Password"/>
</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">
<input id="remember_me" name="remember_me" type="checkbox"
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"/>
<label for="remember_me" class="ml-2 block text-sm text-gray-900">
Remember me
</label>
</div>
<div class="text-sm">
<a href="/main/auth/lostPassword.php" id="forgot" class="font-medium text-blue-600 hover:text-blue-500">
Forgot your password?
</a>
</div>
</div>
<div>
<button
type="submit"
class="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
<span class="absolute left-0 inset-y-0 flex items-center pl-3">
<svg v-if="isLoading"
class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
<LockClosedIcon v-if="!isLoading" class="h-5 w-5 text-blue-500 group-hover:text-blue-400" aria-hidden="true" />
</span>
Sign in
</button>
</div>
</form>
</template>
<script>
import {mapGetters, useStore} from 'vuex';
import { LockClosedIcon } from '@heroicons/vue/solid'
import useState from "../hooks/useState";
import {ref} from "vue";
import {useRoute, useRouter} from "vue-router";
export default {
name: "Login",
components: {
//ErrorMessage,
LockClosedIcon
},
setup() {
const { isSidebarOpen } = useState();
const route = useRoute();
const router = useRouter();
const store = useStore();
const login = ref('');
const password = ref('');
let redirect = route.query.redirect;
if (store.getters["security/isAuthenticated"]) {
console.log(redirect);
if (typeof redirect !== "undefined") {
router.push({path: redirect});
} else {
router.push({path: "/"});
}
}
isSidebarOpen.value = false;
function onSubmit(evt) {
evt.preventDefault()
performLogin();
}
async function performLogin() {
console.log('performLogin');
let payload = {login: login.value, password: password.value};
let redirect = route.query.redirect;
await store.dispatch("security/login", payload);
if (!store.getters["security/hasError"]) {
isSidebarOpen.value = true;
if (typeof redirect !== "undefined") {
router.push({path: redirect});
} else {
router.push({path: "/courses"});
}
}
}
return {
onSubmit,
login,
password
}
},
computed: {
...mapGetters({
'isLoading': 'security/isLoading',
'hasError': 'security/hasError',
'error': 'security/error',
}),
}
}
</script>

@ -29,13 +29,24 @@
<!-- <q-route-tab no-caps icon="event" to="/main/calendar/agenda_js.php?type=personal" />-->
<!-- </q-tabs>-->
<!-- </div>-->
<q-space />
<div class="q-gutter-sm row items-center no-wrap">
<!-- <q-btn v-if="$q.screen.gt.sm" round dense flat color="text-grey-7" icon="apps">-->
<!-- <q-tooltip>Google Apps</q-tooltip>-->
<!-- </q-btn>-->
<q-btn v-if="isAuthenticated" round dense flat color="grey-8" icon="person">
<q-tooltip>Account</q-tooltip>
</q-btn>
<q-btn v-if="isAuthenticated" round dense flat color="grey-8" icon="inbox">
<q-badge color="red" text-color="white" floating>
2
</q-badge>
<q-tooltip>Inbox</q-tooltip>
</q-btn>
<q-btn v-if="isAuthenticated" round dense flat color="grey-8" icon="notifications">
<q-badge color="red" text-color="white" floating>
2
@ -181,7 +192,8 @@
<q-page
class="q-layout-padding"
>
<Breadcrumb :legacy="this.breadcrumb"/>
<Breadcrumb v-if="this.showBreadcrumb" :legacy="this.breadcrumb"/>
<router-view />
<slot></slot>
@ -196,20 +208,24 @@ import {mapGetters} from "vuex";
import isEmpty from "lodash/isEmpty";
import useState from "../../hooks/useState";
import {useRouter} from "vue-router";
import {computed, ref} from "vue";
import {computed, ref, toRefs} from "vue";
import axios from "axios";
import Breadcrumb from '../../components/Breadcrumb.vue';
export default {
name: "DashboardLayout",
components: {
Breadcrumb
},
setup () {
setup (props) {
const { isSidebarOpen, isSettingsPanelOpen, isSearchPanelOpen, isNotificationsPanelOpen } = useState();
const rightDrawerOpen = ref(false);
const { showBreadcrumb } = toRefs(props);
return {
showBreadcrumb,
isSettingsPanelOpen,
isSearchPanelOpen,
isNotificationsPanelOpen,
@ -225,6 +241,7 @@ export default {
user: {},
userAvatar: '',
moved: true,
showBreadcrumb: true,
linksUser: [
//{ icon: 'home', url: '/', text: 'Home' },
//{ icon: 'star_border', url: '/', text: 'News' },
@ -247,7 +264,7 @@ export default {
// { icon: 'open_in_new', text: 'open in new' },
],
linksAnon: [
{ icon: 'home', url: '/', text: 'Home' },
{ icon: 'home', url: '/home', text: 'Home' },
{ icon: 'compass', url: '/catalog', text: 'Explore' },
],
drawer: true,

@ -1,8 +1,6 @@
<template>
<div class="flex flex-col items-center justify-center min-h-screen p-4 space-y-4 antialiased text-gray-900 bg-white">
<router-view />
<slot></slot>
</div>
</template>
<script>

@ -21,7 +21,6 @@
</div>
</div>
<div class="overflow-y-auto overflow-x-hidden flex-grow">
<ul class="flex flex-col py-4 space-y-1">

@ -0,0 +1,14 @@
<template>
<q-page class="q-layout-padding">
<div class="flex justify-center lg:mt-16">
<img src="/img/document/images/mr_chamilo/svg/collaborative.svg" />
</div>
</q-page>
</template>
<script>
export default {
name: "Home",
}
</script>

@ -1,23 +1,57 @@
<template>
<div>
Welcome !
</div>
<q-layout view="hHh LpR lff" class="bg-grey-1">
<q-header bordered class="bg-white text-grey-8" height-hint="64">
<q-toolbar>
<q-toolbar-title v-if="$q.screen.gt.xs" shrink class="row items-center no-wrap">
<img style="width:200px" src="/build/css/themes/chamilo/images/header-logo.png" />
</q-toolbar-title>
<q-space />
<div class="q-gutter-sm row items-center no-wrap">
</div>
</q-toolbar>
</q-header>
<q-page-container>
<q-page class="q-layout-padding">
<div class="grid grid-cols-1 md:grid-cols-2">
<!-- Form-->
<div class="md:row-start-1 md:col-start-2 md:col-end-2 p-12">
<div class="mt-10 lg:mt-16 flex justify-center">
<div class="max-w-sm">
<div>
<h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
Sign in
</h2>
</div>
<Login />
</div>
</div>
</div>
<div class="md:row-start-1 md:col-start-1 md:col-end-1">
<div class="flex justify-center lg:mt-16">
<img src="/img/document/images/mr_chamilo/svg/teaching.svg" />
</div>
</div>
</div>
</q-page>
</q-page-container>
</q-layout>
</template>
<script>
import Login from '../components/Login';
export default {
name: "Index",
data() {
return {
};
},
computed: {
components: {
Login
},
created() {
},
methods: {
}
name: "Index",
data: () => ({
showBreadcrumb : false
})
}
</script>

@ -0,0 +1,23 @@
<template>
<div class=" flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<div class="max-w-md w-full space-y-8">
<div>
<h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
Sign in
</h2>
</div>
<Login />
</div>
</div>
</template>
<script>
import Login from '../components/Login';
export default {
components: {
Login
},
name: "LoginPage"
}
</script>

@ -5,7 +5,6 @@ import accountRoutes from './account';
//import courseCategoryRoutes from './coursecategory';
import documents from './documents';
import store from '../store';
import Login from '../views/Login.vue';
//import Legacy from '../views/Legacy.vue';
//import Home from '../views/Home.vue';
import MyCourseList from '../views/user/courses/List.vue';
@ -19,11 +18,30 @@ import SessionCatalog from '../views/course/CatalogSession.vue';
import CourseHome from '../views/course/Home.vue';
import Index from '../pages/Index.vue';
import Home from '../pages/Home.vue';
import Login from '../pages/Login.vue';
const router = createRouter({
history: createWebHistory(),
routes: [
{path: '/', name: 'Home', component: Index},
{
path: '/',
name: 'Index',
component: Index,
props: { showBreadcrumb: false },
meta: {
requiresAuth: false,
}
},
{
path: '/home',
name: 'Home',
component: Home,
props: { showBreadcrumb: false },
meta: {
requiresAuth: true
}
},
{
path: '/login',
name: 'Login',

@ -1,136 +0,0 @@
<template>
<div class=" flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<div class="max-w-md w-full space-y-8">
<div>
<!-- <img class="mx-auto h-12 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg" alt="Workflow" />-->
<h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
Sign in To Your Account
</h2>
</div>
<form class="mt-8 space-y-6" @submit.prevent="onSubmit">
<input type="hidden" name="remember" value="true" />
<div class="rounded-md shadow-sm -space-y-px">
<div>
<label for="login" class="sr-only">Username</label>
<input id="login" v-model="login" name="login" type="text" autocomplete="login" required=""
class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Username"/>
</div>
<div>
<label for="password" class="sr-only">Password</label>
<input id="password" v-model="password" name="password" type="password" autocomplete="current-password"
required=""
class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Password"/>
</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">
<input id="remember_me" name="remember_me" type="checkbox"
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"/>
<label for="remember_me" class="ml-2 block text-sm text-gray-900">
Remember me
</label>
</div>
<div class="text-sm">
<a href="/main/auth/lostPassword.php" id="forgot" class="font-medium text-blue-600 hover:text-blue-500">
Forgot your password?
</a>
</div>
</div>
<div>
<button
type="submit"
class="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
<span class="absolute left-0 inset-y-0 flex items-center pl-3">
<svg v-if="isLoading"
class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
<LockClosedIcon v-if="!isLoading" class="h-5 w-5 text-blue-500 group-hover:text-blue-400" aria-hidden="true" />
</span>
Sign in
</button>
</div>
</form>
</div>
</div>
</template>
<script>
import {mapGetters, useStore} from 'vuex';
import ErrorMessage from "../components/ErrorMessage.vue";
import { LockClosedIcon } from '@heroicons/vue/solid'
import useState from "../hooks/useState";
import {ref} from "vue";
import {useRoute, useRouter} from "vue-router";
import isEmpty from "lodash/isEmpty";
export default {
name: "Login",
components: {
ErrorMessage,
LockClosedIcon
},
setup() {
const { isSidebarOpen } = useState();
const route = useRoute();
const router = useRouter();
const store = useStore();
const login = ref('');
const password = ref('');
let redirect = route.query.redirect;
if (store.getters["security/isAuthenticated"]) {
console.log(redirect);
if (typeof redirect !== "undefined") {
router.push({path: redirect});
} else {
router.push({path: "/"});
}
}
isSidebarOpen.value = false;
function onSubmit(evt) {
evt.preventDefault()
performLogin();
}
async function performLogin() {
console.log('performLogin');
let payload = {login: login.value, password: password.value};
let redirect = route.query.redirect;
await store.dispatch("security/login", payload);
if (!store.getters["security/hasError"]) {
isSidebarOpen.value = true;
if (typeof redirect !== "undefined") {
router.push({path: redirect});
} else {
router.push({path: "/courses"});
}
}
}
return {
onSubmit,
login,
password
}
},
computed: {
...mapGetters({
'isLoading': 'security/isLoading',
'hasError': 'security/hasError',
'error': 'security/error',
}),
}
}
</script>

@ -35,7 +35,7 @@
/>
</div>
<h2 v-if="isCurrentTeacher">Settings</h2>
<h2 v-if="isCurrentTeacher && tools && course">Settings</h2>
<div
v-if="isCurrentTeacher"

Loading…
Cancel
Save