initial commit
This commit is contained in:
12 files changed
+315
-66
No files matched your search
+1
-2
@@ -4,8 +4,7 @@ node_modules
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
.env
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
|
||||
Generated
+47
-30
@@ -2685,6 +2685,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/cli-service/node_modules/dotenv": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
|
||||
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/cli-shared-utils": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-5.0.8.tgz",
|
||||
@@ -5023,15 +5032,6 @@
|
||||
"tslib": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
|
||||
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv-expand": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
|
||||
@@ -13456,7 +13456,8 @@
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-5.0.8.tgz",
|
||||
"integrity": "sha512-HSYWPqrunRE5ZZs8kVwiY6oWcn95qf/OQabwLfprhdpFWAGtLStShjsGED2aDpSSeGAskQETrtR/5h7VqgIlBA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@vue/cli-service": {
|
||||
"version": "5.0.8",
|
||||
@@ -13519,6 +13520,14 @@
|
||||
"webpack-merge": "^5.7.3",
|
||||
"webpack-virtual-modules": "^0.4.2",
|
||||
"whatwg-fetch": "^3.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"dotenv": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
|
||||
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@vue/cli-shared-utils": {
|
||||
@@ -13982,13 +13991,15 @@
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
|
||||
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"acorn-jsx": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"acorn-walk": {
|
||||
"version": "8.2.0",
|
||||
@@ -14047,7 +14058,8 @@
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
|
||||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"ansi-colors": {
|
||||
"version": "4.1.3",
|
||||
@@ -14844,7 +14856,8 @@
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
|
||||
"integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"css-loader": {
|
||||
"version": "6.7.3",
|
||||
@@ -15030,7 +15043,8 @@
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
|
||||
"integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"csso": {
|
||||
"version": "4.2.0",
|
||||
@@ -15289,12 +15303,6 @@
|
||||
"tslib": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"dotenv": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
|
||||
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
|
||||
"dev": true
|
||||
},
|
||||
"dotenv-expand": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
|
||||
@@ -16516,7 +16524,8 @@
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
|
||||
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
@@ -17891,25 +17900,29 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
|
||||
"integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-discard-duplicates": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
|
||||
"integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-discard-empty": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
|
||||
"integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-discard-overridden": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
|
||||
"integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-loader": {
|
||||
"version": "6.2.1",
|
||||
@@ -18014,7 +18027,8 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
|
||||
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-modules-local-by-default": {
|
||||
"version": "4.0.0",
|
||||
@@ -18049,7 +18063,8 @@
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
|
||||
"integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-normalize-display-values": {
|
||||
"version": "5.1.0",
|
||||
@@ -19893,7 +19908,8 @@
|
||||
"version": "8.12.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz",
|
||||
"integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -20020,7 +20036,8 @@
|
||||
"version": "7.5.9",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
|
||||
"integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
|
||||
+1
-28
@@ -1,30 +1,3 @@
|
||||
<template>
|
||||
<nav>
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/about">About</router-link>
|
||||
</nav>
|
||||
<router-view/>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
nav {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
nav a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
nav a.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
</template>
|
||||
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div>
|
||||
<nav>
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/" @click="logout()">Logout</router-link>
|
||||
</nav>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DashboardNav',
|
||||
data() {
|
||||
return {
|
||||
API_URL: process.env.VUE_APP_API_URL,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
logout() {
|
||||
const res = fetch(`${this.API_URL}/logout`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then(response =>
|
||||
response.json().then(data => ({
|
||||
data: data,
|
||||
status: response.status,
|
||||
})).then(res => res)
|
||||
);
|
||||
|
||||
// if (res.status != 200) // do something
|
||||
|
||||
if (res.data.success) this.$router.push('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
nav {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
nav a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
nav a.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
@@ -1,4 +1,11 @@
|
||||
<template>
|
||||
<nav>
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/student/login">Student Login</router-link> |
|
||||
<router-link to="/teacher/login">Teacher Login</router-link> |
|
||||
<router-link to="/admin/login">Admin Login</router-link> |
|
||||
<router-link to="/about">About</router-link>
|
||||
</nav>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
<!--
|
||||
LoginComp.vue is the general login page that handles
|
||||
logging in for any user type such as Student, Teacher and Admin
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<h1 style="text-transform: capitalize;">{{user}} login</h1>
|
||||
<form @submit.prevent="login">
|
||||
<input v-model="uid" :placeholder="user.charAt(0).toUpperCase() + user.slice(1) + ' ID'"/>
|
||||
<br/>
|
||||
<br/>
|
||||
<input v-model="password" type="password" placeholder="Password"/>
|
||||
<br/>
|
||||
<br/>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
<h3>{{message}}</h3>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'LoginComp',
|
||||
props: {
|
||||
user: String,
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
API_URL: process.env.VUE_APP_API_URL,
|
||||
message: "", // where we store any error messages etc.
|
||||
uid: "",
|
||||
password: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async login() {
|
||||
const res = await fetch(`${this.API_URL}/${this.user}/login`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
uid: this.uid,
|
||||
password: this.password,
|
||||
}),
|
||||
}).then(response =>
|
||||
response.json().then(data => ({
|
||||
data: data,
|
||||
status: response.status,
|
||||
})).then(res => res)
|
||||
);
|
||||
|
||||
// if (!res.status == 200) // do something
|
||||
|
||||
if (res.data.success) this.$router.push(`/${this.user}/dashboard`)
|
||||
else this.message = res.data.message;
|
||||
},
|
||||
|
||||
async isAuthenticated() {
|
||||
const res = await fetch(`${this.API_URL}/${this.user}`, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
}).then(response =>
|
||||
response.json().then(data => ({
|
||||
data: data,
|
||||
status: response.status,
|
||||
})).then(res => res)
|
||||
);
|
||||
|
||||
// if (!res.status == 200) // do something
|
||||
|
||||
if (res.data.success) this.$router.push(`/${this.user}/dashboard`)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.isAuthenticated()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- Profile image renderer -->
|
||||
<div v-if="photo!={}">
|
||||
</div>
|
||||
<!-- Default profile image render if none -->
|
||||
<div v-else>
|
||||
<p>No photo</p>
|
||||
</div>
|
||||
|
||||
<!-- General user data-->
|
||||
<h2 v-if="user.personal">{{ user.personal.firstname + ' ' + user.personal.lastname }}</h2>
|
||||
<h2 v-else>{{ user.firstname + ' ' + user.lastname }}</h2>
|
||||
<h2>{{ uid }}</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UserModel',
|
||||
props: {
|
||||
user: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
photo: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
uid: String
|
||||
},
|
||||
}
|
||||
</script>
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
import store from './store';
|
||||
|
||||
createApp(App).use(store).use(router).mount('#app')
|
||||
createApp(App).use(store).use(router).mount('#app');
|
||||
@@ -14,6 +14,16 @@ const routes = [
|
||||
// this generates a separate chunk (about.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
|
||||
},
|
||||
{
|
||||
path: '/student/login',
|
||||
name: 'studentLogin',
|
||||
component: () => import('../views/StudentLogin.vue')
|
||||
},
|
||||
{
|
||||
path: '/student/dashboard',
|
||||
name: 'studentDashboard',
|
||||
component: () => import('../views/StudentDashboard.vue')
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<img alt="Vue logo" src="../assets/logo.png">
|
||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
||||
<HelloWorld msg="Welcome to Your Vue.js Application"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<DashboardNav />
|
||||
<h1>Dashboard</h1>
|
||||
<UserModel v-if="student!={}" :user="student" :photo="photo" :uid="student.School.sid"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserModel from '@/components/UserModel.vue';
|
||||
import DashboardNav from '@/components/DashboardNav.vue';
|
||||
|
||||
export default {
|
||||
name: 'StudentDashboard',
|
||||
components: {
|
||||
UserModel,
|
||||
DashboardNav,
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
API_URL: process.env.VUE_APP_API_URL,
|
||||
student: {},
|
||||
locker: {},
|
||||
contacts: [],
|
||||
photo: {},
|
||||
message: "", // where we store any error messages etc.
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async isAuthenticated() {
|
||||
const res = await fetch(`${this.API_URL}/student`, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
}).then(response =>
|
||||
response.json().then(data => ({
|
||||
data: data,
|
||||
status: response.status,
|
||||
})).then(res => res)
|
||||
);
|
||||
|
||||
// if (!res.status == 200) // do something
|
||||
|
||||
if (res.data.success) {
|
||||
// set local data
|
||||
this.student = res.data.response.student;
|
||||
this.locker = res.data.response.locker;
|
||||
this.contacts = res.data.response.contacts;
|
||||
this.photo = res.data.response.photo;
|
||||
} else this.$router.push('/student/login');
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.isAuthenticated()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<LoginComp user="student"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LoginComp from '@/components/LoginComp.vue'
|
||||
|
||||
export default {
|
||||
name: 'StudentLogin',
|
||||
components: {
|
||||
LoginComp,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
Reference in new issue
Block a user