new Changes

This commit is contained in:
saeid
2019-08-21 13:59:18 +04:30
parent b9cadbedc5
commit f7c3e87e5f
127 changed files with 216 additions and 21 deletions
@@ -0,0 +1,70 @@
<template>
<v-form ref="form">
<v-container grid-list-xs>
<v-layout row wrap class="justify-center">
<v-flex xs12 md3 sm3 class="WM-WidthScreen-SM WM-WidthScreen-XS">
<material-card color="black" title="Login Page">
<v-layout row wrap class="px-3">
<v-flex xs12 md12 sm12>
<v-text-field
v-model="form.cell_number"
name="cellnumber"
label="Cell Number"
color="black"
:rules="[rules.required, rules.cellNumberCounter]"
mask="#### ### ####"
></v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap class="px-3">
<v-flex xs12 md6 sm6 class="text-md-left text-sm-center text-xs-center">
<v-btn
class="WM-CyanBlueGradient-BG"
style="padding:10px 60px"
@click="handleSubmit"
>
<v-icon class="white--text mr-2 caption">fas fa-sign-in-alt</v-icon>
<span class="white--text">Send</span>
</v-btn>
</v-flex>
<v-flex xs12 md6 sm6 class="text-md-right text-sm-center text-xs-center">
<router-link class="black--text" :to="{name: 'Login'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text mr-2 caption">fas fa-sign-in-alt</v-icon>
<span class="black--text">Login</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
</material-card>
</v-flex>
</v-layout>
</v-container>
</v-form>
</template>
<script>
import { mapActions, mapMutations } from "vuex";
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
export default {
data() {
return {
form :{
cell_number: ""
},
rules: {
required: value => !!value || "Required.",
cellNumberCounter: value => (value && value.length == 11) || "must 11 characters"
}
};
},
methods: {
...mapActions("auth", ["forgotPassword"]),
async handleSubmit() {
if (this.$refs.form.validate()) {
this.forgotPassword({form : this.form});
}
}
}
};
</script>
@@ -0,0 +1,97 @@
<template>
<v-form ref="form" >
<v-container grid-list-xs>
<v-layout row wrap class="justify-center">
<v-flex xs12 md3 sm3 class="WM-WidthScreen-SM WM-WidthScreen-XS">
<material-card
color="black"
title="Login Page">
<v-layout row wrap class="px-3">
<v-flex xs12 md12 sm12>
<v-text-field
v-model="cell_number"
name="cellnumber"
label="Cell Number"
color="black"
:rules="[rules.required, rules.cellNumberCounter]"
mask="#### ### ####"
></v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap class="px-3">
<v-flex xs12 md12 sm12>
<v-text-field
name="password"
label="Password"
v-model="password"
:type="show1 ? 'text' : 'password'"
:append-icon="show1 ? 'visibility' : 'visibility_off'"
@click:append="show1 = !show1"
:rules="[rules.required, rules.passCounter]"
color="black"
class="pa-2"
></v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap class="px-3">
<v-flex xs12 md6 sm6 class="text-md-left text-sm-center text-xs-center">
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="handleSubmit">
<v-icon class="white--text mr-2 caption">fas fa-sign-in-alt</v-icon>
<span class="white--text">Login</span>
</v-btn>
</v-flex>
</v-layout>
<v-layout row wrap class="text-md-left text-sm-center text-xs-center">
<v-flex xs12 md6 sm6 class="px-4 py-3">
<router-link :to="{name: 'ForgotPassword'}">
<span class="black--text" style="border-bottom:1px solid #000;">Forgot Password ?</span>
</router-link>
</v-flex>
</v-layout>
</material-card>
</v-flex>
</v-layout>
</v-container>
</v-form>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
export default {
data() {
return {
cell_number: "",
password: "",
show1: false,
rules: {
required: value => !!value || "Required.",
passCounter: value => (value && value.length >= 8) || "Min 8 characters",
cellNumberCounter: value => (value && value.length == 11) || "must 11 characters"
}
};
},
computed: {
...mapGetters('auth', [
'authenticating',
'authenticationError',
'authenticationErrorCode'
])
},
methods: {
...mapActions('auth', [
'login'
]),
async handleSubmit() {
// Perform a simple validation that cell_number and password have been typed in
if (this.$refs.form.validate()) {
const response = await this.login({cell_number: this.cell_number, password: this.password});
if (!response.status || response.status !== 200) {
this.password = "";
}
}
}
}
};
</script>
<style lang="scss" scoped>
</style>
@@ -0,0 +1,133 @@
<template>
<v-form ref="form">
<v-container grid-list-xs>
<v-layout row wrap class="justify-center">
<v-flex xs12 md3 sm6 class="WM-WidthScreen-SM WM-WidthScreen-XS">
<material-card color="black" title="Register Page">
<v-layout column>
<v-flex xs12 md2 sm2>
<v-text-field
name="name"
label="Name"
v-model="form.name"
color="black"
class="pa-2"
:rules="[rules.required, rules.nameCounter]"
></v-text-field>
</v-flex>
<v-flex xs12 md2 sm2>
<v-select
:items="items"
label="Gender"
name="gender"
v-model="form.gender"
single-line
class="pa-2"
color="black"
:rules="[rules.required]"
></v-select>
</v-flex>
<v-flex xs2 md2 sm2>
<v-text-field
v-model="country_code"
name="country_code"
label="Country Code"
color="black"
:rules="[rules.required, rules.countryCode]"
mask="####"
></v-text-field>
</v-flex>
<v-flex xs10 md10 sm10>
<v-text-field
v-model="cell_number"
name="cellnumber"
label="Cell Number"
color="black"
:rules="[rules.required, rules.cellNumberCounter]"
mask="#### ### ####"
></v-text-field>
</v-flex>
<v-flex xs12 md2 sm2>
<v-text-field
name="password"
label="Password"
v-model="form.password"
:type="show1 ? 'text' : 'password'"
:append-icon="show1 ? 'visibility' : 'visibility_off'"
@click:append="show1 = !show1"
color="black"
class="pa-2"
:rules="[rules.required, rules.passCounter]"
></v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap>
<v-flex xs12 md6 sm6 class="text-md-left text-sm-center text-xs-center">
<v-btn @click="register" class="WM-CyanBlueGradient-BG" style="padding:10px 60px">
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>
<span class="white--text">Register</span>
</v-btn>
</v-flex>
<v-flex
v-if="!isLogin"
xs12
md6
sm6
class="text-md-right text-sm-center text-xs-center"
>
<router-link to="/login">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text mr-2 caption">fas fa-sign-in-alt</v-icon>
<span class="black--text">Login</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
</material-card>
</v-flex>
</v-layout>
</v-container>
</v-form>
</template>
<script>
import { TokenService, ApiService } from "@/services";
export default {
data() {
const defaultForm = Object.freeze({
cell_number: "",
password: "",
name: "",
gender: "",
medical_center_id: this.$route.params.medicalCenter
? this.$route.params.medicalCenter
: ''
});
return {
form: Object.assign({}, defaultForm),
show1: false,
items: ["Male", "FeMale"],
isLogin: TokenService.getInfo(),
rules: {
required: value => !!value || "Required.",
nameCounter: value => (value && value.length >= 5) || "Min 5 characters",
passCounter: value => (value && value.length >= 8) || "Min 8 characters",
cellNumberCounter: value => (value && value.length == 11) || "must 11 characters",
countryCode: value => (value && value.length == 4) || "must 4 characters for example (0098)"
}
};
},
methods: {
async register() {
if (this.$refs.form.validate()) {
var result = await ApiService.post(`register`, this.form);
if (result && result.status == 200) {
this.$router.push(
{name:`OperatorList`, params: { medicalCenter: this.form.medical_center_id }}
);
}
}
}
}
};
</script>
@@ -0,0 +1,130 @@
<template>
<v-form ref="form">
<v-container grid-list-xs fluid>
<material-card color="black" title="Add Cycle">
<v-layout align-center justify-center wrap class="px-5 my-3">
<v-flex xs12 sm4 md4>
<v-text-field
name="name"
label="Name"
color="black"
v-model="formData.name"
:rules="[rules.required, rules.counter]"
class="pa-2"
></v-text-field>
</v-flex>
<v-flex xs12 sm4 md4>
<v-select
:items="result"
label="Result"
name="result"
v-model="formData.result"
single-line
:rules="[rules.required]"
class="pa-2"
color="black"
></v-select>
</v-flex>
</v-layout>
<v-layout align-center justify-center wrap class="px-5 mb-3">
<v-flex xs12 sm12 md12>
<v-autocomplete
multiple
:items="packages"
item-text="name"
v-model="formData.packages"
item-value="id"
label="Select Packages For Cycle"
></v-autocomplete>
</v-flex>
</v-layout>
<v-layout row wrap justify-center align-center>
<v-flex xs12 md2 sm2 class="text-md-center text-xs-center">
<v-btn
class="WM-CyanBlueGradient-BG"
style="padding:10px 60px"
@click="submitForm()"
>
<v-icon class="white--text mr-2 caption">fas fa-check</v-icon>
<span class="white--text">SAVE</span>
</v-btn>
</v-flex>
<v-flex xs12 md2 sm2 class="text-md-center text-sm-center text-xs-center">
<router-link :to="{name: 'AllCycle'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text">keyboard_arrow_left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
</material-card>
</v-container>
</v-form>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations } from "vuex";
export default {
data() {
return {
formData: {
name: "",
result: "",
description: "",
packages: []
},
packages: [],
result: ["Pass", "Fail"],
rules: {
required: value => !!value || "Required.",
counter: value =>
!value ||
value.length == 0 ||
value.length >= 5 ||
"Min 5 characters"
}
};
},
created() {
if (this.$route.params.cycle) {
this.load(this.$route.params.cycle);
}
this.loadPackages();
},
methods: {
async load(id) {
const result = await ApiService.get(urls.editCycle(id));
if (result.status == 200) {
this.formData = result.data.data;
}
},
async loadPackages() {
const result = await ApiService.get(urls.listAllPackage());
if (result.status == 200) {
this.Packages = result.data.data;
}
},
async submitForm() {
let result;
if (this.$route.params.cycle) {
result = await ApiService.put(
urls.updateCycle(this.$route.params.cycle),
this.formData
);
} else {
result = await ApiService.post(
urls.storeCycle,
this.formData
);
}
if (result && result.status == 200) {
this.$router.push({ name: "AllCycle" });
}
}
}
};
</script>
+243
View File
@@ -0,0 +1,243 @@
<template>
<div class>
<v-container fluid>
<material-card class color="black" title="All Cycles" text>
<v-layout align-center wrap class="my-3">
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
v-model="filter.name"
label="Name"
color="black"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-autocomplete
class="pa-2"
v-model="filter.result"
label="Result"
color="black"
:items="result"
></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
v-model="filter.unique_id"
label="uniqueID"
color="black"
></v-text-field>
</v-flex>
<v-flex class xs12 md2 sm3>
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="load()">
<v-icon class="white--text mr-2 caption">fas fa-search</v-icon>
<span class="white--text">Filter</span>
</v-btn>
</v-flex>
<v-spacer></v-spacer>
<v-flex xs12 md2 sm2 class="text-xs-right">
<router-link :to="{name: 'AddCycle'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text mr-2 caption">fas fa-plus</v-icon>
<span class="black--text">Add</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
<v-divider></v-divider>
<v-layout align-center wrap class="my-3">
<v-flex md12>
<v-data-table :headers="headers" :items="packages" hide-actions>
<template slot="headerCell" slot-scope="{ header }">
<span
class="subheading font-weight-light text-white text--darken-3"
v-text="header.text"
/>
</template>
<template slot="items" slot-scope="{ item }">
<td class="headline font-weight-light">{{ item.unique_id }}</td>
<td class="title font-weight-light">{{ item.name }}</td>
<td class="title font-weight-light">{{ item.result }}</td>
<td class="title font-weight-light">{{ item.created_at }}</td>
<td class="text-xs-right">
<v-btn color="cyan" class="mr-2" @click="show(item.id)">
<v-icon class="white--text mr-1 caption">fas fa-eye</v-icon>
<span>Show</span>
</v-btn>
<router-link
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
:to="{name: 'EditCycle', params: {cycle: item.id}}"
>
<v-btn color="orange" class="mr-2">
<v-icon class="white--text mr-1 caption">fas fa-pen</v-icon>
<span>Edit</span>
</v-btn>
</router-link>
<v-btn
color="pink"
class="WM-ActionButton"
@click="remove(item.id)"
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
>
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
<span>Remove</span>
</v-btn>
<v-btn color="orange darken-1" @click="generateBarcode(item.unique_id)">
<v-icon class="white--text mr-1 caption">fas fa-barcode</v-icon>
<span>Generate Barcode</span>
</v-btn>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination v-model="currentPage" :length="lastPage" :total-visible="6"></v-pagination>
</div>
<v-layout row wrap align-center justify-center class="mt-3">
<router-link to="/dashboard">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</div>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations, mapGetters } from "vuex";
export default {
data: () => ({
headers: [
{
sortable: true,
text: "Unique ID",
value: "Unique ID"
},
{
sortable: true,
text: "Name",
value: "name"
},
{
sortable: false,
text: "Result",
value: "result"
},
{
sortable: false,
text: "Date",
value: "date"
},
{
sortable: false,
text: "Action",
value: "action",
align: "right"
}
],
filter: {
unique_id: '',
name: '',
result: '',
},
result: ['Pass', 'Fail'],
packages: [],
currentPage: 1,
lastPage: 1,
}),
created() {
this.load();
},
methods: {
...mapMutations("modal", ["changeCurrentModal"]),
async load(page = 1) {
let filter = '?';
for (const key in this.filter) {
if (this.filter.hasOwnProperty(key)) {
filter += `${key}=${this.filter[key]}&`;
}
}
filter += (page) ? `page=${page}` : `page=1`;
const result = await ApiService.get(
urls.listCycle(filter)
);
if (result && result.status == 200) {
this.packages = result.data.data.data;
this.currentPage = result.data.data.current_page;
this.lastPage = result.data.data.last_page;
}
},
async show(testResultId) {
const result = await ApiService.get(
urls.showCycle(testResultId)
);
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-cycle-show",
properties: { result }
});
}
},
async remove(testResultId) {
const result = await ApiService.delete(
urls.removeCycle(testResultId)
);
if (result && result.status == 200) {
for (const key in this.packages) {
if (
this.packages.hasOwnProperty(key) &&
this.packages[key].id == testResultId
) {
this.packages.splice(key, 1);
}
}
}
},
async generateBarcode(code) {
const result = await ApiService.post(urls.Barcode(code));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
properties: { result }
});
}
}
},
computed: {
...mapGetters("modal", ["getModalResult"])
},
watch: {
currentPage(page) {
this.load(page);
},
getModalResult(testResult) {
for (const key in this.packages) {
if (
this.packages.hasOwnProperty(key) &&
this.packages[key].id == testResult.id
) {
this.packages[key] = testResult;
}
}
}
}
};
</script>
<style>
.v-btn--floating {
padding: 0!important;
}
.theme--light.v-btn.v-btn--flat {
color: rgba(0,0,0,.87)!important;
}
.v-btn--floating, .v-btn--icon:before {
border-radius: 50%!important;
}
</style>
+106
View File
@@ -0,0 +1,106 @@
<template>
<v-container fluid>
<material-card class=""
v-if="$hasRole('Admin')"
color="black"
title="Admin"
text=""
>
<v-layout row wrap >
<template v-for="(AdminCard, Key ) in AdminCards">
<v-flex v-if="!AdminCard.role || $hasRole(AdminCard.role)" :class="[AdminCard.column , 'pa-2']" :key="Key">
<router-link :to="AdminCard.route">
<material-cards
:title="AdminCard.title"
:icon="AdminCard.icon"
:color="AdminCard.color"
:text="AdminCard.text"
:aligntext="AdminCard.aligntext"
:alignimg="AdminCard.alignimg"
/>
</router-link>
</v-flex>
</template>
</v-layout>
</material-card>
<material-card
v-if="$hasRole('Supervisor|Admin')"
color="black"
title="Supervisor"
text=""
>
<v-layout row wrap >
<template v-for="(SupervisorCard, Key ) in SupervisorCards">
<v-flex v-if="!SupervisorCard.role || $hasRole(SupervisorCard.role)" :class="[SupervisorCard.column , 'pa-2']" :key="Key">
<router-link :to="SupervisorCard.route">
<material-cards
:title="SupervisorCard.title"
:icon="SupervisorCard.icon"
:color="SupervisorCard.color"
:text="SupervisorCard.text"
:aligntext="SupervisorCard.aligntext"
:alignimg="SupervisorCard.alignimg"
/>
</router-link>
</v-flex>
</template>
</v-layout>
</material-card>
<material-card
color="black"
title="User"
text=""
>
<v-layout row wrap >
<template v-for="(UsersCard, Key ) in UsersCards">
<v-flex v-if="!UsersCard.role || $hasRole(UsersCard.role)" :class="[UsersCard.column , 'pa-2']" :key="Key">
<router-link :to="UsersCard.route">
<material-cards
:title="UsersCard.title"
:icon="UsersCard.icon"
:color="UsersCard.color"
:text="UsersCard.text"
:aligntext="UsersCard.aligntext"
:alignimg="UsersCard.alignimg"
/>
</router-link>
</v-flex>
</template>
</v-layout>
</material-card>
</v-container>
</template>
<script>
export default {
data() {
return {
AdminCards :[
{title:'Manage Users', text:'You can Manage the users information',icon:'/img/Static/Dashboard/ipad.png',color:'WM-YellowPinkGradient-BG',route:{name: 'ManageUsers'},aligntext:'text-md-center',alignimg:'text-md-left',column:'xs12 md12 sm12', role: 'Admin|Supervisor'},
{title:'Manage Medical Center', text:'You can edit the medical center information',icon:'/img/Static/Dashboard/Macbook.png',color:'WM-MuskGradient-BG',route:{name: 'ManageMedicalCenter'},aligntext:'text-md-left',alignimg:'text-md-right',column:'xs12 md7 sm7', role: 'Admin'},
{title:'List Test Type', text:'You can simply add your test type',icon:'/img/Static/Dashboard/Book-and-Pen.png',color:'WM-GreyGradient-BG',route:{name: 'ListTestType'},aligntext:'text-md-left',alignimg:'text-md-right',column:'xs12 md5 sm5', role: 'Admin'}
],
SupervisorCards :[
{title:'Manage Users', text:'You can Manage the users information',icon:'/img/Static/Dashboard/ipad.png',color:'WM-YellowPinkGradient-BG',route:{name: 'ManageUsers'},aligntext:'text-md-center',alignimg:'text-md-left',column:'xs12 md12 sm12', role: 'Admin|Supervisor'},
{title:'Test to Verify', text:'You can simply verify your own medical center test result in this section of website',icon:'/img/Static/Dashboard/notepad-colorful.png',color:'WM-PinkGradient-BG',route:{name: 'NotVerifyTestResult'},aligntext:'text-md-center',alignimg:'text-md-left',column:'xs12 md12 sm12', role: 'Admin|Supervisor'},
],
UsersCards :[
{title:'My Info', text:'You can easily edit your registration information',icon:'/img/Static/Dashboard/darkmug.png',color:'WM-OrangeGradient-BG',route:{name: 'MyInfo'},aligntext:'text-md-left',alignimg:'text-md-right', column:'xs12 md6 sm6'},
{title:'All Test Result', text:'You can see all user tests and own tests',icon:'/img/Static/Dashboard/pad.png',color:'WM-GreenGradient-BG',route:{name: 'AllResultTest'},aligntext:'text-md-left',alignimg:'text-md-right',column:'xs12 md6 sm6'},
{title:'Add a Test Result', text:'You can add the test result',icon:'/img/Static/Dashboard/ipad.png',color:'WM-YellowPinkGradient-BG',route:{name: 'SubmitTestResult'},aligntext:'text-md-center',alignimg:'text-md-left',column:'xs12 md12 sm12'},
],
}
}
}
</script>
<style lang="scss">
</style>
@@ -0,0 +1,112 @@
<template>
<v-form ref="form">
<v-container grid-list-xs fluid>
<material-card color="black" title="Add Item">
<v-layout align-center justify-center wrap class="px-5 my-3">
<v-flex xs12 sm4 md4>
<v-text-field
name="name"
label="Name"
color="black"
v-model="formData.name"
:rules="[rules.required, rules.counter]"
class="pa-2"
></v-text-field>
</v-flex>
<v-flex xs12 sm4 md4>
<v-select
:items="result"
label="Result"
name="result"
v-model="formData.result"
single-line
:rules="[rules.required]"
class="pa-2"
color="black"
></v-select>
</v-flex>
</v-layout>
<v-layout align-center justify-center wrap class="px-5 mb-3">
<v-flex xs12 sm12 md12>
<v-textarea
color="black"
:rules="[rules.counter]"
v-model="formData.description"
class="pa-2"
name="address"
>
<template v-slot:label>
<div>description</div>
</template>
</v-textarea>
</v-flex>
</v-layout>
<v-layout row wrap justify-center align-center>
<v-flex xs12 md2 sm2 class="text-md-center text-xs-center">
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="submitForm()">
<v-icon class="white--text mr-2 caption">fas fa-check</v-icon>
<span class="white--text">SAVE</span>
</v-btn>
</v-flex>
<v-flex xs12 md2 sm2 class="text-md-center text-sm-center text-xs-center">
<router-link :to="{name: 'AllItem'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text">keyboard_arrow_left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
</material-card>
</v-container>
</v-form>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations } from 'vuex';
export default {
data() {
return {
formData: {
name: "",
unique_id: "",
result: "",
description: "",
},
result: ["Pass", "Fail"],
rules: {
required: value => !!value || "Required.",
counter: value =>
!value || value.length == 0 || value.length >= 5 || "Min 5 characters",
}
};
},
created() {
if (this.$route.params.Item) {
this.load(this.$route.params.Item);
}
},
methods: {
async load(id) {
const result = await ApiService.get(urls.editItem(id));
if (result.status == 200) {
this.formData = result.data.data;
}
},
async submitForm() {
let result;
if (this.$route.params.Item) {
result = await ApiService.put(urls.updateItem(this.$route.params.Item), this.formData);
} else {
result = await ApiService.post(urls.storeItem, this.formData);
}
if (result && result.status == 200) {
this.$router.push({name: 'AllItem'})
}
},
}
};
</script>
+224
View File
@@ -0,0 +1,224 @@
<template>
<div class>
<v-container fluid>
<material-card class color="black" title="All Items" text>
<v-layout align-center wrap class="my-3">
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
v-model="filter.name"
label="Name"
color="black"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-autocomplete
class="pa-2"
v-model="filter.result"
label="Result"
color="black"
:items="result"
></v-autocomplete>
</v-flex>
<v-flex class xs12 md2 sm3>
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="load()">
<v-icon class="white--text mr-2 caption">fas fa-search</v-icon>
<span class="white--text">Filter</span>
</v-btn>
</v-flex>
<v-spacer></v-spacer>
<v-flex xs12 md2 sm2 class="text-xs-right">
<router-link :to="{name: 'AddItem'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text mr-2 caption">fas fa-plus</v-icon>
<span class="black--text">Add</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
<v-divider></v-divider>
<v-layout align-center wrap class="my-3">
<v-flex md12>
<v-data-table :headers="headers" :items="items" hide-actions>
<template slot="headerCell" slot-scope="{ header }">
<span
class="subheading font-weight-light text-white text--darken-3"
v-text="header.text"
/>
</template>
<template slot="items" slot-scope="{ item }">
<td class="title font-weight-light">{{ item.name }}</td>
<td class="title font-weight-light">{{ item.result }}</td>
<td class="title font-weight-light">{{ item.created_at }}</td>
<td class="text-xs-right">
<v-btn color="cyan" class="mr-2" @click="show(item.id)">
<v-icon class="white--text mr-1 caption">fas fa-eye</v-icon>
<span>Show</span>
</v-btn>
<router-link
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
:to="{name: 'EditItem', params: {Item: item.id}}"
>
<v-btn color="orange" class="mr-2">
<v-icon class="white--text mr-1 caption">fas fa-pen</v-icon>
<span>Edit</span>
</v-btn>
</router-link>
<v-btn
color="pink"
class="WM-ActionButton"
@click="remove(item.id)"
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
>
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
<span>Remove</span>
</v-btn>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination v-model="currentPage" :length="lastPage" :total-visible="6"></v-pagination>
</div>
<v-layout row wrap align-center justify-center class="mt-3">
<router-link to="/dashboard">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</div>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations, mapGetters } from "vuex";
export default {
data: () => ({
headers: [
{
sortable: true,
text: "Name",
value: "name"
},
{
sortable: false,
text: "Result",
value: "result"
},
{
sortable: false,
text: "Date",
value: "date"
},
{
sortable: false,
text: "Action",
value: "action",
align: "right"
}
],
filter: {
name: '',
result: '',
},
result: ['Pass', 'Fail'],
items: [],
currentPage: 1,
lastPage: 1,
}),
created() {
this.load();
},
methods: {
...mapMutations("modal", ["changeCurrentModal"]),
async load(page = 1) {
let filter = '?';
for (const key in this.filter) {
if (this.filter.hasOwnProperty(key)) {
filter += `${key}=${this.filter[key]}&`;
}
}
filter += (page) ? `page=${page}` : `page=1`;
const result = await ApiService.get(
urls.listItem(filter)
);
if (result && result.status == 200) {
this.items = result.data.data.data;
this.currentPage = result.data.data.current_page;
this.lastPage = result.data.data.last_page;
}
},
async show(testResultId) {
const result = await ApiService.get(
urls.showItem(testResultId)
);
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-item-show",
properties: { result }
});
}
},
async remove(testResultId) {
const result = await ApiService.delete(
urls.removeItem(testResultId)
);
if (result && result.status == 200) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == testResultId
) {
this.items.splice(key, 1);
}
}
}
},
async generateBarcode(code) {
const result = await ApiService.post(urls.Barcode(code));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
properties: { result }
});
}
}
},
computed: {
...mapGetters("modal", ["getModalResult"])
},
watch: {
currentPage(page) {
this.load(page);
},
getModalResult(testResult) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == testResult.id
) {
this.items[key] = testResult;
}
}
}
}
};
</script>
<style>
.v-btn--floating {
padding: 0!important;
}
.theme--light.v-btn.v-btn--flat {
color: rgba(0,0,0,.87)!important;
}
.v-btn--floating, .v-btn--icon:before {
border-radius: 50%!important;
}
</style>
@@ -0,0 +1,81 @@
<template>
<v-form ref="form">
<v-container grid-list-xs>
<material-card class color="black" title="Add Medical Center" text>
<v-layout row wrap class="px-5 mb-3">
<v-flex xs12 md3 xs3>
<v-text-field
v-model="medicalCenter.name"
label="Name"
color="black"
class="pa-2"
:rules="[rules.required, rules.counter]"
></v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap align-center justify-center class="mt-3">
<v-btn class="WM-CyanBlueGradient-BG" @click="AddMedicalCenter" style="padding:10px 60px">
<template v-if="$route.params.medicalCenter">
<v-icon class="white--text mr-2 caption">fas fa-edit</v-icon>
<span class="white--text">Edit</span>
</template>
<template v-else>
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>
<span class="white--text">Add</span>
</template>
</v-btn>
<router-link :to="{name:'ManageMedicalCenter'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</v-form>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
export default {
data() {
return {
medicalCenter: {
name: ""
},
rules: {
required: value => !!value || "Required.",
counter: value => value.length <= 30 || "Max 30 characters"
}
};
},
created() {
if (this.$route.params.medicalCenter) {
this.load(this.$route.params.medicalCenter);
}
},
methods: {
async load(id) {
const result = await ApiService.get(urls.editMedicalCenter(id));
if (result && result.status == 200) {
this.medicalCenter = result.data.data;
}
},
async AddMedicalCenter() {
if (this.$refs.form.validate()) {
if (this.$route.params.medicalCenter) {
var result = await ApiService.put(urls.updateMedicalCenter(this.$route.params.medicalCenter), this.medicalCenter);
} else {
var result = await ApiService.post(urls.storeMedicalCenter, this.medicalCenter);
}
if (result && result.status == 200) {
this.$router.push({name : "ManageMedicalCenter"});
}
}
}
}
};
</script>
<style lang="scss" scoped>
</style>
@@ -0,0 +1,147 @@
<template>
<v-container fluid>
<material-card class color="black" title="Medical Centers List" text>
<v-layout wrap class="px-5 mb-3">
<v-flex xs12 md3 sm3 class="pr-3">
<v-text-field label="Name" v-model="filter.name" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md2 sm2 class="text-xs-right">
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="load">
<v-icon class="white--text mr-2 caption">fas fa-search</v-icon>
<span class="white--text">Filter</span>
</v-btn>
</v-flex>
<v-spacer></v-spacer>
<v-flex xs12 md2 sm2 class="text-xs-right">
<router-link :to="{name: 'AddMedicalCenter'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text mr-2 caption">fas fa-plus</v-icon>
<span class="black--text">Add</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
<v-layout class="px-4 my-3">
<v-divider></v-divider>
</v-layout>
<v-layout align-center justify-center wrap class="px-5 mt-3">
<v-flex md12>
<v-data-table :headers="headers" :items="items" hide-actions>
<template slot="headerCell" slot-scope="{ header }">
<span
class="subheading font-weight-light text-white text--darken-3"
v-text="header.text"
/>
</template>
<template slot="items" slot-scope="{ item }">
<td class="headline font-weight-light WM-NoLetterSpacing">{{ item.name }}</td>
<td class="title font-weight-light">{{ item.created_at }}</td>
<td class="title font-weight-light">{{ item.users_count }} Operator</td>
<td class="text-xs-right">
<router-link :to="{name : 'EditMedicalCenter', params : {medicalCenter : item.id}}">
<v-btn color="cyan" class="mr-2 WM-ActionButton">
<v-icon class="white--text mr-2 caption">fas fa-pen</v-icon>
<span>Edit</span>
</v-btn>
</router-link>
<router-link :to="{name : 'OperatorList', params : {medicalCenter : item.id}}">
<v-btn color="orange darken-1" class="mr-2 WM-ActionButton">
<v-icon class="white--text mr-2 caption">fas fa-user</v-icon>
<span>Operator</span>
</v-btn>
</router-link>
<v-btn color="pink" @click="remove(item.id)" class="WM-ActionButton">
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
<span>Remove</span>
</v-btn>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination v-model="currentPage" :length="lastPage" :total-visible="6"></v-pagination>
</div>
<v-layout row wrap align-center justify-center class="mt-3">
<router-link :to="{name: 'Dashboard'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
export default {
data: () => ({
headers: [
{
sortable: false,
text: "Hospital Name",
value: "name"
},
{
sortable: false,
text: "Date",
value: "date"
},
{
sortable: false,
text: "Operator",
value: "operator"
},
{
sortable: false,
text: "Action",
value: "action",
align: "right"
}
],
filter: {
name: ''
},
items: [],
currentPage: 1,
lastPage: 1
}),
created() {
this.load();
},
methods: {
async load(page = 1) {
let filter = `?page=${page}&name=${this.filter.name}`;
const result = await ApiService.get(urls.listMedicalCenter(filter));
this.items = result.data.data.data;
this.currentPage = result.data.data.current_page;
this.lastPage = result.data.data.last_page;
},
async remove(id) {
const result = await ApiService.delete(urls.deleteMedicalCenter(id));
if (result && result.status == 200) {
for (const key in this.items) {
if (this.items.hasOwnProperty(key) && this.items[key].id == id) {
this.items.splice(key, 1);
}
}
}
}
},
watch: {
currentPage(page) {
this.load(page);
}
}
};
</script>
<style lang="css" scoped>
.WM-ActionButton {
padding: 8px 22px;
}
</style>
@@ -0,0 +1,201 @@
<template>
<v-container grid-list-xs>
<material-card class color="black" :title="`Operator List ${name}`" text>
<v-layout row wrap class="px-5 mb-3">
<v-flex xs12 md3 xs3>
<v-text-field name="Name" v-model="filter.name" label="Name" class="pa-2" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 xs3>
<v-text-field name="cell_number" v-model="filter.cell_number" label="Cell Number" class="pa-2" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md2 xs3>
<v-select :items="roles" name="roles" v-model="filter.role" label="Roles" class="pa-2" color="black"></v-select>
</v-flex>
<v-flex xs12 md2 sm2 class="text-xs-right">
<v-btn class="WM-CyanBlueGradient-BG" @click="load" style="padding:10px 60px">
<v-icon class="white--text mr-2 caption">fas fa-search</v-icon>
<span class="white--text">Filter</span>
</v-btn>
</v-flex>
<v-spacer></v-spacer>
<v-flex xs12 md2 sm2 class="text-xs-right">
<router-link :to="`/add-operator/${$route.params.medicalCenter}`">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text mr-2 caption">fas fa-plus</v-icon>
<span class="black--text">Add</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
<v-layout row align-center justify-center wrap class="px-5 mt-3">
<v-flex md12>
<v-data-table :headers="headers" :items="items" hide-actions>
<template slot="headerCell" slot-scope="{ header }">
<span
class="subheading font-weight-light text-white text--darken-3"
v-text="header.text"
/>
</template>
<template slot="items" slot-scope="{ item }">
<td class="headline font-weight-light">{{ item.name }}</td>
<td class="title font-weight-light">
<span v-for="(role, key) in item.roles" :key="key">{{ role.name }}</span>
</td>
<td class="title font-weight-light">{{ item.cell_number }}</td>
<td class="title font-weight-light">{{ item.status }}</td>
<td class="text-xs-right">
<v-btn
:color="item.status == 'Active' ? 'red' : 'green'"
@click="changeStatus(item.id)"
class="mr-2 WM-ActionButton"
>
<template v-if="item.status == 'Active'">
<v-icon class="white--text mr-2 caption">fas fa-user-tag</v-icon>
<span v-if="item.status == 'Active'">Susspended</span>
</template>
<template v-else>
<v-icon class="white--text mr-2 caption">fas fa-user-tag</v-icon>
<span>Active</span>
</template>
</v-btn>
<v-btn
color="orange darken-1"
@click="changeRoleModal(item)"
class="mr-2 WM-ActionButton"
>
<v-icon class="white--text mr-2 caption">fas fa-user-tag</v-icon>
<span>Role</span>
</v-btn>
<v-btn color="pink" class="WM-ActionButton" @click="remove(item.id)">
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
<span>Remove</span>
</v-btn>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<v-layout row wrap align-center justify-center class="mt-3">
<router-link to="/manage-medical-center">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</template>
<script>
import { ApiService } from "@/services";
import { mapMutations, mapGetters } from "vuex";
import { urls } from "@/config/urls";
import { roles } from "@/config/utils";
export default {
data: () => ({
headers: [
{
sortable: true,
text: "Operator Name",
value: "name"
},
{
sortable: false,
text: "Role",
value: "role"
},
{
sortable: false,
text: "Number",
value: "number"
},
{
sortable: false,
text: "Status",
value: "status"
},
{
sortable: false,
text: "Action",
value: "action",
align: "right"
}
],
filter: {
name: '',
cell_number: '',
role: '',
},
items: [],
name: "",
roles,
}),
created() {
if (this.$route.params.medicalCenter) {
this.load();
}
},
methods: {
async load() {
let medicalCenterId = this.$route.params.medicalCenter;
let filter = "?";
for (const key in this.filter) {
if (this.filter.hasOwnProperty(key)) {
filter += `${key}=${this.filter[key]}&`;
}
}
const result = await ApiService.get(
urls.listOpertorMedicalCenter(medicalCenterId, filter)
);
if (result && result.status == 200) {
this.items = result.data.data.users;
this.name = result.data.data.name;
} else {
this.$router.push({name:`Dashboard`});
}
},
async changeStatus(userId) {
const result = await ApiService.post(urls.changeStatusUser(userId));
if (result && result.status == 200) {
for (let user of this.items) {
if (user.id == userId) {
user.status = result.data.data.status;
}
}
} else {
this.$router.push({name:`Dashboard`});
}
},
...mapMutations("modal", ["changeCurrentModal"]),
changeRoleModal(user) {
this.changeCurrentModal({
modal: "modal-user-role",
properties: { user }
});
},
async remove(userId) {
const result = await ApiService.delete(urls.deleteUser(userId));
if (result && result.status == 200) {
for (const key in this.items) {
if (this.items.hasOwnProperty(key) && this.items[key].id == userId) {
this.items.splice(key, 1);
}
}
}
}
},
computed: {
...mapGetters("modal", ["getModalResult"])
},
watch: {
getModalResult(user) {
for (const userList of this.items) {
if (userList.id == user.id) {
userList.roles = user.roles;
}
}
}
}
};
</script>
@@ -0,0 +1,198 @@
<template>
<v-container fluid>
<material-card class=""
color="black"
title="Add a New Test"
>
<v-layout wrap class="ma-2">
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
label="Test Name"
color="black">
</v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
label="Unique ID"
color="black">
</v-text-field>
</v-flex>
</v-layout>
<v-layout wrap class="pa-3 my-4 mx-3 WM-Border WM-Border-Black WM-Relative">
<v-layout wrap class="pa-3 my-4 mx-3 WM-Border WM-Border-Gray WM-Relative WM-Color-LightGrey">
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
label="Input Name"
color="black">
</v-text-field>
</v-flex>
<v-flex xs12 md2 sm2>
<v-select
class="pa-2"
v-model="select"
:hint="`${select.state}, ${select.abbr}`"
:items="items"
item-text="state"
item-value="abbr"
label="Type"
return-object
single-line
color="black"
></v-select>
</v-flex>
<v-flex xs12 md2 sm2>
<v-select
class="pa-2"
v-model="select"
:hint="`${select.state}, ${select.abbr}`"
:items="items"
item-text="state"
item-value="abbr"
label="Size"
return-object
single-line
color="black"
></v-select>
</v-flex>
<v-flex xs12 md5 sm5>
<v-text-field
class="pa-2"
label="Value"
color="black">
</v-text-field>
</v-flex>
</v-layout>
<v-layout v-for="(Div, Key) in ArrayDiv" wrap :key="Key" class="pa-3 my-4 mx-3 WM-Border WM-Border-Gray WM-Relative WM-Color-LightGrey Form">
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
label="Input Name"
color="black">
</v-text-field>
</v-flex>
<v-flex xs12 md2 sm2>
<v-select
class="pa-2"
v-model="select"
:hint="`${select.state}, ${select.abbr}`"
:items="items"
item-text="state"
item-value="abbr"
label="Type"
return-object
single-line
color="black"
></v-select>
</v-flex>
<v-flex xs12 md2 sm2>
<v-select
class="pa-2"
v-model="select"
:hint="`${select.state}, ${select.abbr}`"
:items="items"
item-text="state"
item-value="abbr"
label="Size"
return-object
single-line
color="black"
></v-select>
</v-flex>
<v-flex xs12 md5 sm5>
<v-text-field
class="pa-2"
label="Value"
color="black">
</v-text-field>
</v-flex>
<v-btn
absolute
small
right
top
color="pink"
@click="Remove()"
id="RemoveFormBuilder"
>
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
REMOVE</v-btn>
</v-layout>
<v-btn
absolute
small
right
bottom
color="cyan"
@click="Duplicator"
id="FormBuilder"
>
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>
ADD</v-btn>
</v-layout>
<div id="WM-FormBuilder"></div>
<v-flex class="text-xs-center" xs12 md12 sm12 >
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px">
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>
<span class="white--text">Add</span>
</v-btn>
</v-flex>
</material-card>
</v-container>
</template>
<script>
export default {
data () {
return {
ArrayDiv : [],
select: { state: 'Florida', abbr: 'FL' },
items: [
{ state: 'Florida', abbr: 'FL' },
{ state: 'Georgia', abbr: 'GA' },
{ state: 'Nebraska', abbr: 'NE' },
{ state: 'California', abbr: 'CA' },
{ state: 'New York', abbr: 'NY' }
]
}
},
methods : {
Duplicator () {
var Forms = document.getElementsByClassName('Form');
var ArrayForm = [];
for(var i=0; i<Forms.length; i++) {
ArrayForm.push(Forms[i]);
}
this.ArrayDiv.push(ArrayForm);
},
Remove () {
var ID = document.getElementById('RemoveFormBuilder');
var Element = ID.parentNode;
Element.remove();
}
}
}
</script>
<style lang="css" scoped>
.WM-Border {
border: 1px solid;
}
.WM-Border-Black {
border-color: #2f353b !important;
}
.WM-Border-Gray {
border-color: #aaa !important;
}
.WM-Color-LightGrey {
background-color : #F5F5F5;
}
.WM-Relative {
position: relative;
}
.v-btn--top.v-btn--absolute.v-btn--small {
top: -25px !important;
}
</style>
@@ -0,0 +1,281 @@
<template>
<v-container
fill-height
fluid
style="flex-wrap: wrap;"
>
<material-card color="green">
<div
slot="header"
>
<div class="title font-weight-light mb-2">Material Design Icons</div>
<div class="category font-weight-thin">
See all available
<a
class="white--text"
href="https://materialdesignicons.com/"
target="_blank"
>
Icons
</a>
</div>
</div>
<v-layout
align-center
justify-center
wrap
>
<v-flex
v-for="icon in icons"
:key="icon"
ma-2
>
<v-tooltip
top
content-class="top">
<v-icon slot="activator">
{{ icon }}
</v-icon>
<span>{{ icon }}</span>
</v-tooltip>
</v-flex>
</v-layout>
</material-card>
<div class="mx-auto">
<v-btn
large
class="mx-0 font-weight-light"
color="success"
href="https://materialdesignicons.com/"
target="_blank"
round
>
<v-icon left>mdi-material-design</v-icon>
<span>See all icons</span>
</v-btn>
</div>
</v-container>
</template>
<script>
export default {
data: () => ({
icons: [
'mdi-access-point',
'mdi-access-point-network',
'mdi-account',
'mdi-account-alert',
'mdi-account-box',
'mdi-account-box-multiple',
'mdi-account-box-outline',
'mdi-account-card-details',
'mdi-account-check',
'mdi-account-circle',
'mdi-account-convert',
'mdi-account-edit',
'mdi-account-group',
'mdi-account-heart',
'mdi-account-key',
'mdi-account-location',
'mdi-account-minus',
'mdi-account-multiple',
'mdi-account-multiple-check',
'mdi-account-multiple-minus',
'mdi-account-multiple-outline',
'mdi-account-multiple-plus',
'mdi-account-multiple-plus-outline',
'mdi-account-network',
'mdi-account-off',
'mdi-account-outline',
'mdi-account-plus',
'mdi-account-plus-outline',
'mdi-account-remove',
'mdi-account-search',
'mdi-account-search-outline',
'mdi-account-settings',
'mdi-account-settings-variant',
'mdi-account-star',
'mdi-account-switch',
'mdi-accusoft',
'mdi-adjust',
'mdi-adobe',
'mdi-air-conditioner',
'mdi-airballoon',
'mdi-airplane',
'mdi-airplane-landing',
'mdi-airplane-off',
'mdi-airplane-takeoff',
'mdi-airplay',
'mdi-airport',
'mdi-alarm',
'mdi-alarm-bell',
'mdi-alarm-check',
'mdi-alarm-light',
'mdi-alarm-multiple',
'mdi-alarm-off',
'mdi-alarm-plus',
'mdi-alarm-snooze',
'mdi-album',
'mdi-alert',
'mdi-alert-box',
'mdi-alert-circle',
'mdi-alert-circle-outline',
'mdi-alert-decagram',
'mdi-alert-octagon',
'mdi-alert-octagram',
'mdi-alert-outline',
'mdi-alien',
'mdi-all-inclusive',
'mdi-alpha',
'mdi-alphabetical',
'mdi-altimeter',
'mdi-amazon',
'mdi-amazon-alexa',
'mdi-amazon-drive',
'mdi-ambulance',
'mdi-amplifier',
'mdi-anchor',
'mdi-android',
'mdi-android-debug-bridge',
'mdi-android-head',
'mdi-android-studio',
'mdi-angle-acute',
'mdi-angle-obtuse',
'mdi-angle-right',
'mdi-angular',
'mdi-angularjs',
'mdi-animation',
'mdi-animation-play',
'mdi-anvil',
'mdi-apple',
'mdi-apple-finder',
'mdi-apple-icloud',
'mdi-apple-ios',
'mdi-apple-keyboard-caps',
'mdi-apple-keyboard-command',
'mdi-apple-keyboard-control',
'mdi-apple-keyboard-option',
'mdi-apple-keyboard-shift',
'mdi-apple-safari',
'mdi-application',
'mdi-approval',
'mdi-apps',
'mdi-arch',
'mdi-archive',
'mdi-arrange-bring-forward',
'mdi-arrange-bring-to-front',
'mdi-arrange-send-backward',
'mdi-arrange-send-to-back',
'mdi-arrow-all',
'mdi-arrow-bottom-left',
'mdi-arrow-bottom-left-bold-outline',
'mdi-arrow-bottom-left-thick',
'mdi-arrow-bottom-right',
'mdi-arrow-bottom-right-bold-outline',
'mdi-arrow-bottom-right-thick',
'mdi-arrow-collapse',
'mdi-arrow-collapse-all',
'mdi-arrow-collapse-down',
'mdi-arrow-collapse-horizontal',
'mdi-arrow-collapse-left',
'mdi-arrow-collapse-right',
'mdi-arrow-collapse-up',
'mdi-arrow-collapse-vertical',
'mdi-arrow-decision',
'mdi-arrow-decision-auto',
'mdi-arrow-decision-auto-outline',
'mdi-arrow-decision-outline',
'mdi-arrow-down',
'mdi-arrow-down-bold',
'mdi-arrow-down-bold-box',
'mdi-arrow-down-bold-box-outline',
'mdi-arrow-down-bold-circle',
'mdi-arrow-down-bold-circle-outline',
'mdi-arrow-down-bold-hexagon-outline',
'mdi-arrow-down-bold-outline',
'mdi-arrow-down-box',
'mdi-arrow-down-drop-circle',
'mdi-arrow-down-drop-circle-outline',
'mdi-arrow-down-thick',
'mdi-arrow-expand',
'mdi-arrow-expand-all',
'mdi-arrow-expand-down',
'mdi-arrow-expand-horizontal',
'mdi-arrow-expand-left',
'mdi-arrow-expand-right',
'mdi-arrow-expand-up',
'mdi-arrow-expand-vertical',
'mdi-arrow-left',
'mdi-arrow-left-bold',
'mdi-arrow-left-bold-box',
'mdi-arrow-left-bold-box-outline',
'mdi-arrow-left-bold-circle',
'mdi-arrow-left-bold-circle-outline',
'mdi-arrow-left-bold-hexagon-outline',
'mdi-arrow-left-bold-outline',
'mdi-arrow-left-box',
'mdi-arrow-left-drop-circle',
'mdi-arrow-left-drop-circle-outline',
'mdi-arrow-left-right-bold-outline',
'mdi-arrow-left-thick',
'mdi-arrow-right',
'mdi-arrow-right-bold',
'mdi-arrow-right-bold-box',
'mdi-arrow-right-bold-box-outline',
'mdi-arrow-right-bold-circle',
'mdi-arrow-right-bold-circle-outline',
'mdi-arrow-right-bold-hexagon-outline',
'mdi-arrow-right-bold-outline',
'mdi-arrow-right-box',
'mdi-arrow-right-drop-circle',
'mdi-arrow-right-drop-circle-outline',
'mdi-arrow-right-thick',
'mdi-arrow-split-horizontal',
'mdi-arrow-split-vertical',
'mdi-arrow-top-left',
'mdi-arrow-top-left-bold-outline',
'mdi-arrow-top-left-thick',
'mdi-arrow-top-right',
'mdi-arrow-top-right-bold-outline',
'mdi-arrow-top-right-thick',
'mdi-arrow-up',
'mdi-arrow-up-bold',
'mdi-arrow-up-bold-box',
'mdi-arrow-up-bold-box-outline',
'mdi-arrow-up-bold-circle',
'mdi-arrow-up-bold-circle-outline',
'mdi-arrow-up-bold-hexagon-outline',
'mdi-arrow-up-bold-outline',
'mdi-arrow-up-box',
'mdi-arrow-up-down-bold-outline',
'mdi-arrow-up-drop-circle',
'mdi-arrow-up-drop-circle-outline',
'mdi-arrow-up-thick',
'mdi-artist',
'mdi-assistant',
'mdi-asterisk',
'mdi-at',
'mdi-atlassian',
'mdi-atom',
'mdi-attachment',
'mdi-audio-video',
'mdi-audiobook',
'mdi-augmented-reality',
'mdi-auto-fix',
'mdi-auto-upload',
'mdi-autorenew',
'mdi-av-timer',
'mdi-axe',
'mdi-azure',
'mdi-baby',
'mdi-baby-buggy',
'mdi-backburger',
'mdi-backspace',
'mdi-backup-restore',
'mdi-badminton'
]
})
}
</script>
@@ -0,0 +1,33 @@
<template>
<div>
<div class="mapouter">
<div class="gmap_canvas">
<iframe
id="gmap_canvas"
width="100%"
height="100%"
src="https://maps.google.com/maps?q=google&t=&z=13&ie=UTF8&iwloc=&output=embed"
frameborder="0"
scrolling="no"
marginheight="0"
marginwidth="0"
/>
</div>
</div>
</div>
</template>
<style>
.mapouter {
text-align:right;
height:100%;
width:100%;
position: absolute;
}
.gmap_canvas {
overflow:hidden;
background:none!important;
height:100%;
width:100%;
}
</style>
@@ -0,0 +1,269 @@
<template>
<v-container
fluid
grid-list-xl
fill-height>
<v-layout
justify-center
align-center
>
<v-flex xs12>
<material-card
color="green">
<div
slot="header"
>
<div class="title font-weight-light mb-2">Notifications</div>
<div class="category">
Handcrafted by us with
<v-icon
size="17"
>
mdi-heart
</v-icon>
</div>
</div>
<v-card-text>
<v-layout
row
wrap>
<v-flex
md6
sm12>
<h2 class="title font-weight-light mb-3">Notifications Style</h2>
<material-notification
class="mb-3"
color="info"
>
This is a plain notification
</material-notification>
<material-notification
class="mb-3"
color="info"
dismissible
>
This is a notification with close button.
</material-notification>
<material-notification
class="mb-3"
color="info"
dismissible
icon="mdi-bell-plus"
>
This is a notification with close button and icon.
</material-notification>
<material-notification
class="mb-3"
color="info"
dismissible
icon="mdi-bell-plus"
>
This is a notification with close button and icon and have many lines. You can see that the icon and the close button are always vertically aligned. This is a beautiful notification. So you don't have to worry about the style.
</material-notification>
</v-flex>
<v-flex
md6
sm12>
<h2 class="title font-weight-light">Notifcation States</h2>
<material-notification
class="mb-3"
color="info"
dismissible
>
<strong>INFO</strong> - This is a regular notification made with `color="info"`
</material-notification>
<material-notification
class="mb-3"
color="success"
dismissible
>
<strong>SUCCESS</strong> - This is a regular notification made with `color="success"`
</material-notification>
<material-notification
class="mb-3"
color="warning"
dismissible
>
<strong>WARNING</strong> - This is a regular notification made with `color="warning"`
</material-notification>
<material-notification
class="mb-3"
color="error"
dismissible
>
<strong>DANGER</strong> - This is a regular notification made with `color="error"`
</material-notification>
<material-notification
class="mb-3"
color="purple"
dismissible
>
<strong>PRIMARY</strong> - This is a regular notification made with `color="purple"`
</material-notification>
</v-flex>
</v-layout>
<div class="text-xs-center">
<h2 class="title font-weight-light mb-2">Notification Places</h2>
<span class=" subheading font-weight-light grey--text">Click to view notifications</span>
</div>
<v-container grid-list-lg>
<v-layout
justify-center
row
wrap>
<v-flex
xs12
sm4>
<v-btn
block
color="success"
@click="snack('top', 'left')"
>
Top Left
</v-btn>
</v-flex>
<v-flex
xs12
sm4>
<v-btn
block
color="success"
@click="snack('top')"
>
Top Center
</v-btn>
</v-flex>
</v-layout>
<v-layout
justify-center
row
wrap>
<v-flex
xs12
sm4>
<v-btn
block
color="success"
@click="snack('top', 'right')"
>
Top Right
</v-btn>
</v-flex>
<v-flex
xs12
sm4>
<v-btn
block
color="success"
@click="snack('bottom', 'left')"
>
Bottom Left
</v-btn>
</v-flex>
</v-layout>
<v-layout
justify-center
row
wrap>
<v-flex
xs12
sm4>
<v-btn
block
color="success"
@click="snack('bottom')"
>
Bottom Center
</v-btn>
</v-flex>
<v-flex
xs12
sm4>
<v-btn
block
color="success"
@click="snack('bottom', 'right')"
>
Bottom Right
</v-btn>
</v-flex>
</v-layout>
</v-container>
<v-snackbar
:color="color"
:bottom="bottom"
:top="top"
:left="left"
:right="right"
v-model="snackbar"
dark
>
<v-icon
color="white"
class="mr-3"
>
mdi-bell-plus
</v-icon>
<div>Welcome to <b>Vue Material Dashboard</b> - a beautiful freebie for every web developer.</div>
<v-icon
size="16"
@click="snackbar = false"
>
mdi-close-circle
</v-icon>
</v-snackbar>
</v-card-text>
</material-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
export default {
data: () => ({
color: null,
colors: [
'purple',
'info',
'success',
'warning',
'error'
],
top: true,
bottom: false,
left: false,
right: false,
snackbar: false
}),
methods: {
snack (...args) {
this.top = false
this.bottom = false
this.left = false
this.right = false
for (const loc of args) {
this[loc] = true
}
this.color = this.colors[Math.floor(Math.random() * this.colors.length)]
this.snackbar = true
}
}
}
</script>
@@ -0,0 +1,147 @@
<template>
<v-container
fill-height
fluid
grid-list-xl
>
<v-layout
justify-center
wrap
>
<v-flex
md12
>
<material-card
color="green"
title="Simple Table"
text="Here is a subtitle for this table"
>
<v-data-table
:headers="headers"
:items="items"
hide-actions
>
<template
slot="headerCell"
slot-scope="{ header }"
>
<span
class="subheading font-weight-light text-success text--darken-3"
v-text="header.text"
/>
</template>
<template
slot="items"
slot-scope="{ item }"
>
<td>{{ item.name }}</td>
<td>{{ item.country }}</td>
<td>{{ item.city }}</td>
<td class="text-xs-right">{{ item.salary }}</td>
</template>
</v-data-table>
</material-card>
</v-flex>
<v-flex
md12
>
<material-card
color="green"
flat
full-width
title="Table on Plain Background"
text="Here is a subtitle for this table"
>
<v-data-table
:headers="headers"
:items="items.slice(0, 7)"
hide-actions
>
<template
slot="headerCell"
slot-scope="{ header }"
>
<span
class="subheading font-weight-light text--darken-3"
v-text="header.text"
/>
</template>
<template
slot="items"
slot-scope="{ item }"
>
<td>{{ item.name }}</td>
<td>{{ item.country }}</td>
<td>{{ item.city }}</td>
<td class="text-xs-right">{{ item.salary }}</td>
</template>
</v-data-table>
</material-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
export default {
data: () => ({
headers: [
{
sortable: false,
text: 'Name',
value: 'name'
},
{
sortable: false,
text: 'Country',
value: 'country'
},
{
sortable: false,
text: 'City',
value: 'city'
},
{
sortable: false,
text: 'Salary',
value: 'salary',
align: 'right'
}
],
items: [
{
name: 'Dakota Rice',
country: 'Niger',
city: 'Oud-Tunrhout',
salary: '$35,738'
},
{
name: 'Minerva Hooper',
country: 'Curaçao',
city: 'Sinaai-Waas',
salary: '$23,738'
}, {
name: 'Sage Rodriguez',
country: 'Netherlands',
city: 'Overland Park',
salary: '$56,142'
}, {
name: 'Philip Chanley',
country: 'Korea, South',
city: 'Gloucester',
salary: '$38,735'
}, {
name: 'Doris Greene',
country: 'Malawi',
city: 'Feldkirchen in Kārnten',
salary: '$63,542'
}, {
name: 'Mason Porter',
country: 'Chile',
city: 'Gloucester',
salary: '$78,615'
}
]
})
}
</script>
@@ -0,0 +1,106 @@
<template>
<v-container
fill-height
fluid
>
<v-layout
justify-center
align-center
>
<v-flex xs12>
<material-card
color="green"
title="Material Dashboard Heading"
text="Created using Roboto Font Family"
>
<v-card-text>
<h2 class="font-weight-light mb-4">Typography</h2>
<v-container
class="pa-0"
grid-list-xl
fluid
>
<v-layout
v-for="(t, i) in typography"
:key="i"
align-end
wrap
>
<v-flex
xs1
md3>
<span
class="tim-note"
v-text="t[0]"
/>
</v-flex>
<v-flex xs8>
<component
:is="t[2]"
:class="i"
>
<template v-if="i !== 'quote'">
{{ t[1] }}
</template>
<p v-if="i === 'quote'">{{ t[1] }}</p>
<small v-if="i === 'quote'">Kanye West, Musician</small>
<template v-if="i === 'small'">
<br>
<small>Use 'small' tag for the headers</small>
</template>
</component>
</v-flex>
</v-layout>
</v-container>
</v-card-text>
</material-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
const leader = 'I will be the leader of a company that ends up being worth billions of dollars, because I got the answers. I understand culture. I am the nucleus. I think that’s a responsibility that I have, to push possibilities, to show people, this is the level that things could be at.'
const leaderShort = leader.slice(0, 105) + '...'
const material = 'The Life of Material Dashboard'
const small = 'Header with small subtitle'
export default {
data: () => ({
typography: {
'heading-1': ['Header 1', material, 'h1'],
'heading-2': ['Header 2', material, 'h2'],
'heading-3': ['Header 3', material, 'h3'],
'heading-4': ['Header 4', material, 'h4'],
'heading-5': ['Header 5', material, 'h5'],
'heading-6 text-uppercase': ['Header 6', material, 'h6'],
'': ['Paragraph', leader, 'p'],
'quote': ['Quote', leader, 'blockquote'],
'text--disabled': ['Muted Text', leaderShort, 'p'],
'text-primary': ['Primary Text', leaderShort, 'p'],
'text-info': ['Info Text', leaderShort, 'p'],
'text-success': ['Success Text', leaderShort, 'p'],
'text-warning': ['Warning Text', leaderShort, 'p'],
'text-danger': ['Danger Text', leaderShort, 'p'],
'small': ['Small Tag', small, 'h2']
}
})
}
</script>
<style lang="scss">
.tim-note {
bottom: 10px;
color: #c0c1c2;
display: block;
font-weight: 400;
font-size: 13px;
line-height: 13px;
left: 0;
margin-left: 20px;
width: 260px;
}
</style>
@@ -0,0 +1,87 @@
<template>
<v-container>
<v-layout justify-center>
<v-flex
xs12
sm10
md8
>
<material-card
color="primary"
title="Vue Material Dashboard PRO"
text="Are you looking for more components? Please check our Premium Version of Vue Material Dashboard."
>
<table class="v-table">
<thead>
<tr>
<th/>
<th class="subheading font-weight-light">Free</th>
<th class="subheading font-weight-light">PRO</th>
</tr>
</thead>
<tbody class="text-xs-center">
<tr>
<th class="text-xs-left font-weight-light subheading">Components</th>
<td>60</td>
<td>200</td>
</tr>
<tr>
<th class="text-xs-left font-weight-light subheading">Plugins</th>
<td>2</td>
<td>15</td>
</tr>
<tr>
<th class="text-xs-left font-weight-light subheading">Example Pages</th>
<td>3</td>
<td>27</td>
</tr>
<tr>
<th class="text-xs-left font-weight-light subheading">Login, Register, Pricing, Lock Pages</th>
<td>
<v-icon color="error">mdi-close</v-icon>
</td>
<td>
<v-icon color="success">mdi-check</v-icon>
</td>
</tr>
<tr>
<th class="text-xs-left font-weight-light subheading">Premium Support</th>
<td>
<v-icon color="error">mdi-close</v-icon>
</td>
<td>
<v-icon color="success">mdi-check</v-icon>
</td>
</tr>
<tr>
<th/>
<td>Free</td>
<td>Just $59</td>
</tr>
<tr>
<th/>
<td>
<v-btn
class="subheading white--text font-weight-light"
round
large
color="grey"
disabled
>Current Version</v-btn>
</td>
<td>
<v-btn
class="subheading white--text font-weight-light"
round
large
color="cyan"
>Upgrade to Pro</v-btn>
</td>
</tr>
</tbody>
</table>
</material-card>
</v-flex>
</v-layout>
</v-container>
</template>
@@ -0,0 +1,141 @@
<template>
<v-container
fill-height
fluid
grid-list-xl>
<v-layout
justify-center
wrap
>
<v-flex
xs12
md8
>
<material-card
color="green"
title="Edit Profile"
text="Complete your profile"
>
<v-form>
<v-container py-0>
<v-layout wrap>
<v-flex
xs12
md4
>
<v-text-field
label="Company (disabled)"
disabled/>
</v-flex>
<v-flex
xs12
md4
>
<v-text-field
class="purple-input"
label="User Name"
/>
</v-flex>
<v-flex
xs12
md4
>
<v-text-field
label="Email Address"
class="purple-input"/>
</v-flex>
<v-flex
xs12
md6
>
<v-text-field
label="First Name"
class="purple-input"/>
</v-flex>
<v-flex
xs12
md6
>
<v-text-field
label="Last Name"
class="purple-input"/>
</v-flex>
<v-flex
xs12
md12
>
<v-text-field
label="Adress"
class="purple-input"/>
</v-flex>
<v-flex
xs12
md4>
<v-text-field
label="City"
class="purple-input"/>
</v-flex>
<v-flex
xs12
md4>
<v-text-field
label="Country"
class="purple-input"/>
</v-flex>
<v-flex
xs12
md4>
<v-text-field
class="purple-input"
label="Postal Code"
type="number"/>
</v-flex>
<v-flex xs12>
<v-textarea
class="purple-input"
label="About Me"
value="Lorem ipsum dolor sit amet, consectetur adipiscing elit."
/>
</v-flex>
<v-flex
xs12
text-xs-right
>
<v-btn
class="mx-0 font-weight-light"
color="success"
>
Update Profile
</v-btn>
</v-flex>
</v-layout>
</v-container>
</v-form>
</material-card>
</v-flex>
<v-flex xs12 md4>
<material-card class="v-card-profile">
<v-avatar slot="offset" class="mx-auto d-block" size="130" >
<img src="/img/" >
</v-avatar>
<v-card-text class="text-xs-center">
<h6 class="category text-gray font-weight-thin mb-3">CEO / CO-FOUNDER</h6>
<h4 class="card-title font-weight-light">Alec Thompson</h4>
<p class="card-description font-weight-light">Don't be scared of the truth because we need to restart the human foundation in truth And I love you like Kanye loves Kanye I love Rick Owens’ bed design but the back is...</p>
<v-btn
color="success"
round
class="font-weight-light"
>Follow</v-btn>
</v-card-text>
</material-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
export default {
//
}
</script>
@@ -0,0 +1,130 @@
<template>
<v-form ref="form">
<v-container grid-list-xs fluid>
<material-card color="black" title="Add Package">
<v-layout align-center justify-center wrap class="px-5 my-3">
<v-flex xs12 sm4 md4>
<v-text-field
name="name"
label="Name"
color="black"
v-model="formData.name"
:rules="[rules.required, rules.counter]"
class="pa-2"
></v-text-field>
</v-flex>
<v-flex xs12 sm4 md4>
<v-select
:items="result"
label="Result"
name="result"
v-model="formData.result"
single-line
:rules="[rules.required]"
class="pa-2"
color="black"
></v-select>
</v-flex>
</v-layout>
<v-layout align-center justify-center wrap class="px-5 mb-3">
<v-flex xs12 sm12 md12>
<v-autocomplete
multiple
:items="items"
item-text="name"
v-model="formData.items"
item-value="id"
label="Select Items For Package"
></v-autocomplete>
</v-flex>
</v-layout>
<v-layout row wrap justify-center align-center>
<v-flex xs12 md2 sm2 class="text-md-center text-xs-center">
<v-btn
class="WM-CyanBlueGradient-BG"
style="padding:10px 60px"
@click="submitForm()"
>
<v-icon class="white--text mr-2 caption">fas fa-check</v-icon>
<span class="white--text">SAVE</span>
</v-btn>
</v-flex>
<v-flex xs12 md2 sm2 class="text-md-center text-sm-center text-xs-center">
<router-link :to="{name: 'AllPackage'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text">keyboard_arrow_left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
</material-card>
</v-container>
</v-form>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations } from "vuex";
export default {
data() {
return {
formData: {
name: "",
result: "",
description: "",
items: []
},
items: [],
result: ["Pass", "Fail"],
rules: {
required: value => !!value || "Required.",
counter: value =>
!value ||
value.length == 0 ||
value.length >= 5 ||
"Min 5 characters"
}
};
},
created() {
if (this.$route.params.package) {
this.load(this.$route.params.package);
}
this.loadItems();
},
methods: {
async load(id) {
const result = await ApiService.get(urls.editPackage(id));
if (result.status == 200) {
this.formData = result.data.data;
}
},
async loadItems() {
const result = await ApiService.get(urls.listAllItem());
if (result.status == 200) {
this.items = result.data.data;
}
},
async submitForm() {
let result;
if (this.$route.params.package) {
result = await ApiService.put(
urls.updatePackage(this.$route.params.package),
this.formData
);
} else {
result = await ApiService.post(
urls.storePackage,
this.formData
);
}
if (result && result.status == 200) {
this.$router.push({ name: "AllPackage" });
}
}
}
};
</script>
@@ -0,0 +1,243 @@
<template>
<div class>
<v-container fluid>
<material-card class color="black" title="All Packages" text>
<v-layout align-center wrap class="my-3">
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
v-model="filter.name"
label="Name"
color="black"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-autocomplete
class="pa-2"
v-model="filter.result"
label="Result"
color="black"
:items="result"
></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
v-model="filter.unique_id"
label="uniqueID"
color="black"
></v-text-field>
</v-flex>
<v-flex class xs12 md2 sm3>
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="load()">
<v-icon class="white--text mr-2 caption">fas fa-search</v-icon>
<span class="white--text">Filter</span>
</v-btn>
</v-flex>
<v-spacer></v-spacer>
<v-flex xs12 md2 sm2 class="text-xs-right">
<router-link :to="{name: 'AddPackage'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text mr-2 caption">fas fa-plus</v-icon>
<span class="black--text">Add</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
<v-divider></v-divider>
<v-layout align-center wrap class="my-3">
<v-flex md12>
<v-data-table :headers="headers" :items="items" hide-actions>
<template slot="headerCell" slot-scope="{ header }">
<span
class="subheading font-weight-light text-white text--darken-3"
v-text="header.text"
/>
</template>
<template slot="items" slot-scope="{ item }">
<td class="headline font-weight-light">{{ item.unique_id }}</td>
<td class="title font-weight-light">{{ item.name }}</td>
<td class="title font-weight-light">{{ item.result }}</td>
<td class="title font-weight-light">{{ item.created_at }}</td>
<td class="text-xs-right">
<v-btn color="cyan" class="mr-2" @click="show(item.id)">
<v-icon class="white--text mr-1 caption">fas fa-eye</v-icon>
<span>Show</span>
</v-btn>
<router-link
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
:to="{name: 'EditPackage', params: {package: item.id}}"
>
<v-btn color="orange" class="mr-2">
<v-icon class="white--text mr-1 caption">fas fa-pen</v-icon>
<span>Edit</span>
</v-btn>
</router-link>
<v-btn
color="pink"
class="WM-ActionButton"
@click="remove(item.id)"
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
>
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
<span>Remove</span>
</v-btn>
<v-btn color="orange darken-1" @click="generateBarcode(item.unique_id)">
<v-icon class="white--text mr-1 caption">fas fa-barcode</v-icon>
<span>Generate Barcode</span>
</v-btn>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination v-model="currentPage" :length="lastPage" :total-visible="6"></v-pagination>
</div>
<v-layout row wrap align-center justify-center class="mt-3">
<router-link to="/dashboard">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</div>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations, mapGetters } from "vuex";
export default {
data: () => ({
headers: [
{
sortable: true,
text: "Unique ID",
value: "Unique ID"
},
{
sortable: true,
text: "Name",
value: "name"
},
{
sortable: false,
text: "Result",
value: "result"
},
{
sortable: false,
text: "Date",
value: "date"
},
{
sortable: false,
text: "Action",
value: "action",
align: "right"
}
],
filter: {
unique_id: '',
name: '',
result: '',
},
result: ['Pass', 'Fail'],
items: [],
currentPage: 1,
lastPage: 1,
}),
created() {
this.load();
},
methods: {
...mapMutations("modal", ["changeCurrentModal"]),
async load(page = 1) {
let filter = '?';
for (const key in this.filter) {
if (this.filter.hasOwnProperty(key)) {
filter += `${key}=${this.filter[key]}&`;
}
}
filter += (page) ? `page=${page}` : `page=1`;
const result = await ApiService.get(
urls.listPackage(filter)
);
if (result && result.status == 200) {
this.items = result.data.data.data;
this.currentPage = result.data.data.current_page;
this.lastPage = result.data.data.last_page;
}
},
async show(testResultId) {
const result = await ApiService.get(
urls.showPackage(testResultId)
);
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-package-show",
properties: { result }
});
}
},
async remove(testResultId) {
const result = await ApiService.delete(
urls.removePackage(testResultId)
);
if (result && result.status == 200) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == testResultId
) {
this.items.splice(key, 1);
}
}
}
},
async generateBarcode(code) {
const result = await ApiService.post(urls.Barcode(code));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
properties: { result }
});
}
}
},
computed: {
...mapGetters("modal", ["getModalResult"])
},
watch: {
currentPage(page) {
this.load(page);
},
getModalResult(testResult) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == testResult.id
) {
this.items[key] = testResult;
}
}
}
}
};
</script>
<style>
.v-btn--floating {
padding: 0!important;
}
.theme--light.v-btn.v-btn--flat {
color: rgba(0,0,0,.87)!important;
}
.v-btn--floating, .v-btn--icon:before {
border-radius: 50%!important;
}
</style>
@@ -0,0 +1,174 @@
<template>
<div>
<v-form ref="form">
<v-container grid-list-xs>
<material-card color="black" title="Search Result">
<v-layout align-center justify-center wrap class="px-5 my-3">
<v-flex xs12 sm4 md4>
<v-autocomplete :items="medicalCenters" item-text="name" item-value="id" v-model="form.medicalCenterId" @change="fillUsers" label="Hospital" color="black" class="pa-2"></v-autocomplete>
</v-flex>
<v-flex xs12 sm4 md4>
<v-autocomplete :items="users" item-text="name" item-value="id" v-model="form.userId" label="User" color="black" class="pa-2"></v-autocomplete>
</v-flex>
<v-flex xs12 sm4 md4>
<v-autocomplete :items="testTypes" item-text="name" item-value="id" v-model="form.testTypeId" label="TestType" color="black" class="pa-2"></v-autocomplete>
</v-flex>
<v-flex xs12 sm4 md4>
<v-autocomplete :items="result" v-model="form.result" label="Result" color="black" class="pa-2"></v-autocomplete>
</v-flex>
<v-flex xs12 sm4 md4>
<v-autocomplete :items="verify" v-model="form.verify" label="Verify" color="black" class="pa-2"></v-autocomplete>
</v-flex>
<v-flex xs12 sm4 md4>
<v-autocomplete :items="type" v-model="form.type" label="Type" color="black" class="pa-2"></v-autocomplete>
</v-flex>
<v-flex xs12 sm6 md5>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="fromMenu"
>
<v-text-field required slot="activator" label="FromDate" v-model="form.fromPicker"></v-text-field>
<v-date-picker
color="pink"
no-title
v-model="form.fromPicker"
:date-format="date => new Date(date).toDateString()"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs12 sm6 md5>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="upToMenu"
>
<v-text-field required slot="activator" label="UpToDate" v-model="form.upToPicker"></v-text-field>
<v-date-picker
color="pink"
no-title
v-model="form.upToPicker"
:date-format="date => new Date(date).toDateString()"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs12 md2 sm2 class="text-xs-center text-sm-center text-md-center">
<v-btn
class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black"
style="padding:10px 60px;"
@click="submitForm"
>
<v-icon class="black--text mr-2 caption">fas fa-chevron-right</v-icon>
<span class="black--text">GO</span>
</v-btn>
</v-flex>
</v-layout>
<v-layout row wrap class="px-5 my-3" v-if="!$route.params.testResult">
<v-divider></v-divider>
</v-layout>
</material-card>
</v-container>
</v-form>
<div v-if="chart" class="small">
<pie-chart v-if="form.type == 'PieChart'" :chart-data="datacollection"></pie-chart>
<bar-chart v-else :chart-data="datacollection"></bar-chart>
</div>
</div>
</template>
<script>
import BarChart from "@/plugins/chart/BarChart.js";
import PieChart from "@/plugins/chart/PieChart.js";
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
export default {
components: {
BarChart,
PieChart
},
data() {
return {
datacollection: null,
fromMenu: '',
upToMenu: '',
verify: ['Verified', 'NotVerified'],
result: ['Accept', 'Failed'],
type: ['BarChart', 'PieChart'],
users: [],
medicalCenters: [],
testTypes: [],
form: {
medicalCenterId: null,
userId: null,
testTypeId: null,
result: null,
verify: null,
type: 'PieChart',
fromPicker: '',
upToPicker: '',
},
chart: false
};
},
created() {
this.load();
},
methods: {
fillData(options) {
this.datacollection = {
labels: options.labels,
// labels: [this.getRandomInt(), this.getRandomInt()],
datasets: [
{
label: "Data One",
backgroundColor: ["#f87979", "#ccc"],
data: options.data,
// data: [this.getRandomInt(), this.getRandomInt()],
}
]
};
},
async load() {
const result = await ApiService.get(urls.listFilterItemsTestResult);
if (result && result.status == 200) {
this.medicalCenters = result.data.data.MedicalCenters;
this.testTypes = result.data.data.TestTypes;
}
},
async fillUsers() {
const result = await ApiService.get(urls.listOpertorMedicalCenter(this.form.medicalCenterId));
if (result && result.status == 200) {
this.users = result.data.data.users;
}
},
async submitForm() {
const result = await ApiService.post(urls.statistics, this.form);
if (result && result.status == 200) {
this.fillData(result.data.data);
this.chart = true;
}
},
}
};
</script>
<style>
.small {
max-width: 600px;
margin: 150px auto;
}
.v-btn--floating {
padding: 0!important;
}
.theme--light.v-btn.v-btn--flat {
color: rgba(0,0,0,.87)!important;
}
.v-btn--floating, .v-btn--icon:before {
border-radius: 50%!important;
}
</style>
@@ -0,0 +1,513 @@
<template>
<v-form ref="form">
<v-container grid-list-xs>
<material-card color="black" title="Submit Test Result">
<v-layout align-center justify-center wrap class="px-5 my-3" v-if="!$route.params.testResult">
<v-flex xs12 sm4 md4>
<v-autocomplete
:search-input.sync="searchInput"
:items="testTypeNames"
v-model="filter.name"
label="Choose Test Type"
color="black"
class="pa-2"
></v-autocomplete>
</v-flex>
<v-flex xs12 sm3 md3>
<v-text-field
name="testcode"
v-model="filter.unique_code"
label="Or Enter Test Unique Code"
color="black"
class="pa-2"
></v-text-field>
</v-flex>
<v-flex xs12 md2 sm2 class="text-xs-center text-sm-center text-md-center">
<v-btn
class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black"
@click="selectTestType"
style="padding:10px 60px;"
>
<v-icon class="black--text mr-2 caption">fas fa-chevron-right</v-icon>
<span class="black--text">Select Test Result</span>
</v-btn>
</v-flex>
</v-layout>
<v-layout row wrap class="px-5 my-3" v-if="!$route.params.testResult && form.length">
<v-divider></v-divider>
</v-layout>
<v-layout align-center justify-center wrap class="px-5 my-3" v-if="form.length">
<v-flex xs12 sm12 md12>
<h3>{{testTypeNameSelected}}</h3>
</v-flex>
<v-flex xs12 sm4 md4>
<v-text-field
name="autoclave"
v-model="formData.device_id"
:label="formData.device_label"
color="black"
class="pa-2"
></v-text-field>
</v-flex>
<v-flex xs12 sm4 md4>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="menu"
>
<v-text-field
prepend-icon="far fa-clock"
required
slot="activator"
label="Date"
v-model="formData.date"
></v-text-field>
<v-date-picker
color="pink"
no-title
v-model="formData.date"
:date-format="date => new Date(date).toDateString()"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs12 sm4 md4>
<v-switch color="green" v-model="result" :label="'Result: ' + formData.result"></v-switch>
</v-flex>
<v-flex xs12 sm12 md12>
<div>
<input type="file" class="inputfile" @change="onFileChange" multiple />
<label for="file">
<v-icon class="v-icon greylighten-3--text mr-2 caption IconHover">fas fa-chevron-right</v-icon>Choose a file
</label>
</div>
<v-layout>
<v-flex v-for="(img, key) in images" :key="key" xs12 sm6 md3>
<img :src="img" style="width:100%;" />
<v-btn class="black" @click.native.stop="removeImage(key)">Remove image</v-btn>
</v-flex>
</v-layout>
</v-flex>
<v-flex :class="['pa-2', item.size]" v-for="(item, key) in form" :key="key">
<v-text-field
v-if="item.type == 'Text'"
v-model="formData[item.name+'_'+item.id]"
:label="item.name"
color="black"
></v-text-field>
<v-container fluid v-if="item.type == 'Temperature'">
<p>{{ item.name }}</p>
<v-flex xs12>
<v-slider
step="0.1"
prepend-icon="fas fa-temperature-high"
v-model="formData[item.name+'_'+item.id]"
min="0"
max="200"
thumb-label="always"
></v-slider>
</v-flex>
</v-container>
<v-container fluid v-if="item.type == 'Pressure'">
<p>{{ item.name }}</p>
<v-flex xs12>
<v-slider
prepend-icon="fa fa-tachometer"
step="0.001"
v-model="formData[item.name+'_'+item.id]"
min="-1"
max="3"
thumb-label="always"
></v-slider>
</v-flex>
</v-container>
<v-select
multiple
v-if="item.type == 'Select'"
:items="item.options"
v-model="formData[item.name+'_'+item.id]"
:label="item.name"
color="black"
item-text="title"
item-value="id"
></v-select>
<v-container fluid v-if="item.type == 'Checkbox'">
<p>{{ item.name }}</p>
<v-checkbox
v-for="(optionValue, keyOption) in item.options"
:key="keyOption"
:label="optionValue.title"
v-model="formData[item.name+'_'+item.id]"
:value="optionValue.id"
></v-checkbox>
</v-container>
<v-container fluid v-if="item.type == 'Radiobutton'">
<p>{{ item.name }}</p>
<v-radio-group v-model="formData[item.name+'_'+item.id]">
<v-radio
v-for="(optionValue, keyOption) in item.options"
:key="keyOption"
:label="optionValue.title"
:value="optionValue.id"
></v-radio>
</v-radio-group>
</v-container>
<v-container fluid v-if="item.type == 'Switch'">
<v-switch
color="green"
v-model="formData[item.name+'_'+item.id]"
:label="item.name + ': ' + formData[item.name+'_'+item.id].toString()"
></v-switch>
</v-container>
<v-container fluid v-if="item.type == 'Range'">
<p>{{ item.name }}</p>
<v-flex xs12>
<v-slider
v-model="formData[item.name+'_'+item.id]"
:min="item.options[0].title"
:max="item.options[1].title"
thumb-label="always"
></v-slider>
</v-flex>
</v-container>
<v-container fluid v-if="item.type == 'Time'">
<v-flex xs12>
<v-text-field
v-model="formData[item.name+'_'+item.id]"
:label="item.name"
class="WM-Font-30"
mask="##:##"
></v-text-field>
</v-flex>
</v-container>
<template v-if="item.type == 'Form'">
<v-container row md-12 sm-12 xs-12>
<v-layout row wrap>
<h3>{{ item.name }}</h3>
</v-layout>
<v-layout row wrap>
<v-flex
:class="['pa-2', children.size]"
v-for="(children, keyChildren) in item.children"
:key="keyChildren"
>
<v-text-field
v-if="children.type == 'Text'"
v-model="formData[children.name+'_'+children.id]"
:label="children.name"
color="black"
></v-text-field>
<v-container fluid v-if="children.type == 'Temperature'">
<p>{{ children.name }}</p>
<v-flex xs12>
<v-slider
prepend-icon="fas fa-temperature-high"
step="0.1"
v-model="formData[children.name+'_'+children.id]"
min="0"
max="200"
thumb-label="always"
></v-slider>
</v-flex>
</v-container>
<v-container step="0.001" fluid v-if="children.type == 'Pressure'">
<p>{{ children.name }}</p>
<v-flex xs12>
<v-slider
v-model="formData[children.name+'_'+children.id]"
min="-1"
max="3"
prepend-icon="fa fa-tachometer"
thumb-label="always"
></v-slider>
</v-flex>
</v-container>
<v-select
multiple
v-if="children.type == 'Select'"
:items="children.options"
v-model="formData[children.name+'_'+children.id]"
:label="children.name"
color="black"
item-text="title"
item-value="id"
></v-select>
<v-container fluid v-if="children.type == 'Checkbox'">
<p>{{ children.name }}</p>
<v-checkbox
v-for="(optionValue, keyOption) in children.options"
:key="keyOption"
:label="optionValue.title"
v-model="formData[children.name+'_'+children.id]"
:value="optionValue.id"
></v-checkbox>
</v-container>
<v-container fluid v-if="children.type == 'Radiobutton'">
<p>{{ children.name }}</p>
<v-radio-group v-model="formData[children.name+'_'+children.id]">
<v-radio
v-for="(optionValue, keyOption) in children.options"
:key="keyOption"
:label="optionValue.title"
:value="optionValue.id"
></v-radio>
</v-radio-group>
</v-container>
<v-container fluid v-if="children.type == 'Switch'">
<v-switch
color="green"
v-model="formData[children.name+'_'+children.id]"
:label="children.name + ': ' + formData[children.name+'_'+children.id].toString()"
></v-switch>
</v-container>
<v-container fluid v-if="children.type == 'Range'">
<p>{{ item.name }}</p>
<v-flex xs12>
<v-slider
v-model="formData[children.name+'_'+children.id]"
:min="children.options[0].title"
:max="children.options[1].title"
thumb-label="always"
></v-slider>
</v-flex>
</v-container>
<v-container fluid v-if="children.type == 'Time'">
<v-flex xs12>
<v-text-field
v-model="formData[children.name+'_'+children.id]"
:label="children.name"
class="WM-Font-30"
mask="##:##"
></v-text-field>
</v-flex>
</v-container>
</v-flex>
</v-layout>
</v-container>
</template>
</v-flex>
</v-layout>
<v-layout row wrap class="px-5 my-3">
<v-divider></v-divider>
</v-layout>
<v-layout align-center justify-center wrap class="px-5 mt-2">
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="submitForm">
<v-icon class="white--text mr-2 caption">fas fa-check</v-icon>
<span class="white--text">SAVE</span>
</v-btn>
<router-link :to="{name: 'Dashboard'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</v-form>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
export default {
data: () => ({
testTypeNames: [],
testTypeNameSelected: "",
searchInput: "",
form: [],
filter: {
test_result_id: "",
name: "",
unique_code: ""
},
result: false,
formData: {
device_id: "",
device_label: "ID",
result: "Reject",
img: null,
test_type_id: ""
},
images: [],
menu: ""
}),
created() {
if (this.$route.params.testResult) {
this.filter.test_result_id = this.$route.params.testResult;
this.selectTestType();
}
this.load();
},
methods: {
async load() {
const result = await ApiService.get(urls.listTestTypeName);
this.testTypeNames = result.data.data;
},
async selectTestType() {
const result = await ApiService.post(urls.getInputs, this.filter);
if (result && result.status == 200) {
this.testTypeNameSelected = result.data.data.testType.name;
this.form = result.data.data.inputs;
this.formData.test_type_id = result.data.data.testType.id;
this.formData.device_label =
result.data.data.testType.device_label;
for (const key in result.data.data.inputs) {
if (result.data.data.inputs.hasOwnProperty(key)) {
if (result.data.data.inputs[key].type == "Form") {
for (const keyForm in result.data.data.inputs[key]
.children) {
if (
result.data.data.inputs[
key
].children.hasOwnProperty(keyForm)
) {
if (
result.data.data.inputs[key].children[
keyForm
].type == "Checkbox" ||
result.data.data.inputs[key].children[
keyForm
].type == "Select"
) {
this.formData[
result.data.data.inputs[key]
.children[keyForm].name +
"_" +
result.data.data.inputs[key]
.children[keyForm].id
] = [];
} else {
this.formData[
result.data.data.inputs[key]
.children[keyForm].name +
"_" +
result.data.data.inputs[key]
.children[keyForm].id
] = "";
}
}
}
} else if (
result.data.data.inputs[key].type == "Checkbox" ||
result.data.data.inputs[key].type == "Select"
) {
this.formData[
result.data.data.inputs[key].name +
"_" +
result.data.data.inputs[key].id
] = [];
} else {
this.formData[
result.data.data.inputs[key].name +
"_" +
result.data.data.inputs[key].id
] = "";
}
}
}
if (this.$route.params.testResult) {
const result = await ApiService.get(
urls.editTestResult(this.$route.params.testResult)
);
if (result && result.status == 200) {
this.formData = result.data.data;
for (const key in result.data.data.imagesPath) {
if (
result.data.data.imagesPath.hasOwnProperty(key)
) {
result.data.data.imagesPath[key] =
"/" + result.data.data.imagesPath[key];
}
}
this.images = result.data.data.imagesPath;
}
}
}
},
async submitForm() {
let result;
if (this.$route.params.testResult) {
result = await ApiService.put(
urls.updateTestResult(this.$route.params.testResult),
this.formData
);
} else {
result = await ApiService.post(
urls.storeTestResult,
this.formData
);
}
if (result && result.status == 200) {
this.$router.push({ name: "AllResultTest" });
}
},
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length) return;
for (const key in files) {
if (files.hasOwnProperty(key)) {
this.createImage(files[key], key);
}
}
},
createImage(file, index) {
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = e => {
vm.images.push(e.target.result);
};
reader.readAsDataURL(file);
},
removeImage(index) {
this.images.splice(index, 1);
}
},
watch: {
images(img) {
this.formData.imgs = img;
},
result(value) {
if (value) {
this.formData.result = "Accept";
} else {
this.formData.result = "Reject";
}
},
formData(value) {
if (value.result == "Accept") {
this.result = true;
} else {
this.result = false;
}
}
}
};
</script>
<style >
.WM-Font-30 input {
font-size: 30px !important;
}
.v-input--switch__track:not(.green--text) {
color: red !important;
}
.v-input--switch__thumb:not(.green--text) {
background-color: red !important;
}
.v-btn--floating {
padding: 0 !important;
}
.theme--light.v-btn.v-btn--flat {
color: rgba(0, 0, 0, 0.87) !important;
}
.v-btn--floating,
.v-btn--icon:before {
border-radius: 50% !important;
}
</style>
@@ -0,0 +1,343 @@
<template>
<div class>
<v-container fluid>
<material-card class color="black" title="All Test Resualt" text>
<v-layout align-center wrap class="my-3">
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
v-model="filter.device_id"
label="AutoclaveID or WaherID"
color="black"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-autocomplete
class="pa-2"
v-model="filter.testType_id"
label="TestType Name"
color="black"
:items="testTypes"
item-text="name"
item-value="id"
></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3>
<v-autocomplete
class="pa-2"
v-model="filter.medicalCenter_id"
label="Hospital"
color="black"
:items="medicalCenters"
item-text="name"
item-value="id"
></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
v-model="filter.user_name"
label="User Name"
color="black"
></v-text-field>
</v-flex>
<v-flex xs12 sm6 md3>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="fromMenu"
>
<v-text-field
required
slot="activator"
label="FromDate"
v-model="filter.fromPicker"
></v-text-field>
<v-date-picker
color="pink"
no-title
v-model="filter.fromPicker"
:date-format="date => new Date(date).toDateString()"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs12 sm6 md3>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="upToMenu"
>
<v-text-field
required
slot="activator"
label="UpToDate"
v-model="filter.upToPicker"
></v-text-field>
<v-date-picker
color="pink"
no-title
v-model="filter.upToPicker"
:date-format="date => new Date(date).toDateString()"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex class xs12 md2 sm3>
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="load(null, null)">
<v-icon class="white--text mr-2 caption">fas fa-search</v-icon>
<span class="white--text">Filter</span>
</v-btn>
</v-flex>
<v-spacer></v-spacer>
<v-flex xs12 md2 sm2 class="text-xs-right">
<router-link :to="{name: 'SubmitTestResult'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text mr-2 caption">fas fa-plus</v-icon>
<span class="black--text">Add</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
<v-divider></v-divider>
<v-layout align-center wrap class="my-3">
<v-flex md12>
<v-data-table :headers="headers" :items="items" hide-actions>
<template slot="headerCell" slot-scope="{ header }">
<span
class="subheading font-weight-light text-white text--darken-3"
v-text="header.text"
/>
</template>
<template slot="items" slot-scope="{ item }">
<td class="headline font-weight-light">{{ item.device_id }}</td>
<td
class="title font-weight-light"
>{{ item.test_type ? item.test_type.name : 'Archived Test' }}</td>
<td
class="title font-weight-light"
>{{ item.user.medical_center.name }}</td>
<td class="title font-weight-light">{{ item.user.name }}</td>
<td class="title font-weight-light">{{ item.result }}</td>
<td class="title font-weight-light">{{ item.created_at }}</td>
<td class="title font-weight-light">{{ item.verified }}</td>
<td class="text-xs-right">
<v-btn color="cyan" class="mr-2" @click="show(item.id)">
<v-icon class="white--text mr-1 caption">fas fa-eye</v-icon>
<span>Show</span>
</v-btn>
<v-btn color="orange" class="mr-2" @click="generateBarcode(item.id)">
<v-icon class="white--text mr-1 caption">fas fa-eye</v-icon>
<span>generate Barcode</span>
</v-btn>
<router-link
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
:to="{name: 'EditTestResult', params: {testResult: item.id}}"
>
<v-btn color="orange" class="mr-2">
<v-icon class="white--text mr-1 caption">fas fa-pen</v-icon>
<span>Edit</span>
</v-btn>
</router-link>
<v-btn
color="pink"
class="WM-ActionButton"
@click="remove(item.id)"
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
>
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
<span>Remove</span>
</v-btn>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination v-model="currentPage" :length="lastPage" :total-visible="6"></v-pagination>
</div>
<v-layout row wrap align-center justify-center class="mt-3">
<router-link to="/dashboard">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</div>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations, mapGetters } from "vuex";
export default {
data: () => ({
headers: [
{
sortable: false,
text: "AutoClave Or Washer Id",
value: "name"
},
{
sortable: false,
text: "Test Type",
value: "TestType"
},
{
sortable: false,
text: "Hospital",
value: "Hospital"
},
{
sortable: false,
text: "User",
value: "Users"
},
{
sortable: false,
text: "Result",
value: "result"
},
{
sortable: false,
text: "Date",
value: "date"
},
{
sortable: false,
text: "Verify",
value: "verify"
},
{
sortable: false,
text: "Action",
value: "action",
align: "right"
}
],
filter: {
device_id:'',
testType_id: '',
medicalCenter_id: '',
user_name: '',
fromPicker: '',
upToPicker: '',
},
fromMenu: '',
upToMenu: '',
items: [],
currentPage: 1,
lastPage: 1,
testTypes: [],
medicalCenters: [],
}),
created() {
this.fillSelectFilter();
if (this.$route.name == "NotVerifyTestResult") {
this.load(1, "NotVerified");
} else {
this.load();
}
},
methods: {
...mapMutations("modal", ["changeCurrentModal"]),
async load(page = 1, verified = null) {
let filter = '?';
for (const key in this.filter) {
if (this.filter.hasOwnProperty(key)) {
filter += `${key}=${this.filter[key]}&`;
}
}
if (verified) {
filter += `verified=${verified}&`;
}
filter += (page) ? `page=${page}` : `page=1`;
const result = await ApiService.get(
urls.listTestResult(filter)
);
if (result && result.status == 200) {
this.items = result.data.data.data;
this.currentPage = result.data.data.current_page;
this.lastPage = result.data.data.last_page;
}
},
async show(testResultId) {
const result = await ApiService.get(
urls.showTestResult(testResultId)
);
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-testresult-show",
properties: { result }
});
}
},
async remove(testResultId) {
const result = await ApiService.delete(
urls.removeTestResult(testResultId)
);
if (result && result.status == 200) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == testResultId
) {
this.items.splice(key, 1);
}
}
}
},
async fillSelectFilter() {
const result = await ApiService.get(urls.listFilterItemsTestResult);
if (result && result.status == 200) {
this.medicalCenters = result.data.data.MedicalCenters;
this.testTypes = result.data.data.TestTypes;
}
},
async generateBarcode(id) {
const result = await ApiService.post(urls.QRcode(`${id}`));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
properties: { result }
});
}
}
},
computed: {
...mapGetters("modal", ["getModalResult"])
},
watch: {
currentPage(page) {
this.load(page);
},
getModalResult(testResult) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == testResult.id
) {
this.items[key] = testResult;
}
}
}
}
};
</script>
<style>
.v-btn--floating {
padding: 0!important;
}
.theme--light.v-btn.v-btn--flat {
color: rgba(0,0,0,.87)!important;
}
.v-btn--floating, .v-btn--icon:before {
border-radius: 50%!important;
}
</style>
@@ -0,0 +1,564 @@
<template>
<v-form ref="form">
<v-container grid-list-xs>
<material-card color="black" title="Add a New Test" class>
<v-layout row wrap class="ma-2">
<v-flex xs12 md3 sm3>
<v-text-field
name="name"
v-model="form.name"
label="Name"
color="black"
class="pa-2"
:rules="[rules.required]"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-text-field
:rules="[rules.required]"
name="uniquecode"
v-model="form.unique_code"
label="Unique Code"
color="black"
class="pa-2"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-autocomplete
:rules="[rules.required]"
:items="deviceLabels"
item-value="id"
item-name="name"
v-model="form.device_label"
label="ID Label"
color="black"
class="pa-2"
></v-autocomplete>
</v-flex>
</v-layout>
<v-layout
row
wrap
class="pb-4 ma-2 WM-Border WM-Border-Gray WM-BG-White WM-Relative"
:key="keyForm"
v-for="(info, keyForm) in form.info"
>
<v-layout row wrap class="ma-2">
<v-flex xs12 md3 sm3>
<v-text-field
name="inputname"
v-model="info.name"
label="Input Name"
color="black"
class="pa-2"
:rules="[rules.required]"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-select
:items="type"
item-text="state"
item-value="abbr"
label="Type"
v-bind="info.id !== 0 ? {disabled: true} : {disabled: false}"
v-model="info.type"
single-line
color="black"
class="pa-2"
@change="changeType(keyForm, info.type)"
></v-select>
</v-flex>
<!-- Text Input Section -->
<v-flex xs12 md3 sm3>
<v-select
:items="size"
item-text="state"
item-value="abbr"
label="Size"
v-model="info.size"
v-if="info.type !== 'Form'"
single-line
color="black"
class="pa-2"
></v-select>
</v-flex>
</v-layout>
<!-- SelectBox Section -->
<v-layout
class="ma-3 pa-3 WM-Border WM-Border-Black WM-Relative WM-Width-Full"
row
wrap
v-if="info.type === 'Select' || info.type === 'Checkbox' || info.type === 'Radiobutton'"
>
<v-layout
row
wrap
class="WM-Relative WM-Width-Full"
v-if="info['options'].length > 0"
>
<v-flex
xs12
md3
sm3
v-for="(selectbox , keySelect) in info['options']"
:key="keySelect"
class="pb-4 ma-2 WM-Border WM-Border-Gray WM-BG-White WM-Width-Full WM-Relative"
>
<v-text-field
:rules="[rules.required]"
name="title"
label="Title"
color="black"
class="pa-2 Input"
v-model="selectbox.title"
></v-text-field>
<v-btn
absolute
small
right
bottom
color="pink"
v-if="keySelect >= 1"
@click="removeSelectbox(keyForm, keySelect)"
>
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>REMOVE
</v-btn>
</v-flex>
</v-layout>
<v-btn
absolute
right
bottom
small
@click="addSelectbox(keyForm)"
color="black"
class="mb-2"
>
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>
<span class="white--text">Add</span>
</v-btn>
</v-layout>
<v-layout
class="ma-3 pa-3 WM-Border WM-Border-Black WM-Relative WM-Width-Full"
row
wrap
v-if="info.type === 'Range'"
>
<v-layout
row
wrap
class="WM-Relative WM-Width-Full"
>
<v-flex
xs12
md3
sm3
class="pb-4 ma-2 WM-Border WM-Border-Gray WM-BG-White WM-Width-Full WM-Relative"
>
<v-text-field
:rules="[rules.required]"
name="from"
label="From"
color="black"
class="pa-2 Input"
v-model="info['options'][0].title"
></v-text-field>
</v-flex>
<v-flex
xs12
md3
sm3
class="pb-4 ma-2 WM-Border WM-Border-Gray WM-BG-White WM-Width-Full WM-Relative"
>
<v-text-field
:rules="[rules.required]"
name="to"
label="To"
color="black"
class="pa-2 Input"
v-model="info['options'][1].title"
></v-text-field>
</v-flex>
</v-layout>
</v-layout>
<!-- Form Section -->
<v-layout
row
wrap
v-if="info.type === 'Form'"
class="pa-3 my-4 mx-3 WM-Border WM-Border-Black WM-Relative"
>
<v-layout
row
wrap
v-for="(children , keychildren) in info.children"
:key="keychildren"
class="pa-3 my-4 mx-3 WM-Border WM-Border-Gray WM-Color-LightGrey WM-Width-Full WM-Relative Form"
>
<v-flex xs12 md3 sm3>
<v-text-field
:rules="[rules.required]"
name="name"
v-model="children.name"
label="Input Name"
color="black"
class="pa-2"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-select
:items="type"
item-text="state"
item-value="abbr"
label="Type"
v-model="children.type"
v-bind="children.id !== 0 ? {disabled: true} : {disabled: false}"
single-line
color="black"
class="pa-2"
@change="changeTypeForm(keyForm, children.type, keychildren)"
></v-select>
</v-flex>
<v-flex xs12 md3 sm3>
<v-select
:items="size"
item-text="state"
item-value="abbr"
label="Size"
v-if="children.type !== 'Form'"
v-model="children.size"
single-line
color="black"
class="pa-2"
></v-select>
</v-flex>
<!-- Inner Form Selectbox Section -->
<v-layout
row
wrap
class="pa-3 mb-3 WM-Border WM-Border-Black WM-Relative WM-Width-Full"
v-if="children.type === 'Select' || children.type === 'Checkbox' || children.type === 'Radiobutton'"
>
<v-layout
row
wrap
class="WM-Relative WM-Width-Full"
v-if="children['options'].length > 0"
>
<v-flex
xs12
md3
sm3
v-for="(selectbox , keySelect) in children['options']"
:key="keySelect"
class="pb-4 ma-2 WM-Border WM-Border-Gray WM-BG-White WM-Width-Full WM-Relative"
>
<v-text-field
name="title"
label="Title"
color="black"
class="pa-2 Input"
v-model="selectbox.title"
:rules="[rules.required]"
></v-text-field>
<v-btn
absolute
small
right
bottom
color="pink"
@click="removeSelectboxForm(keyForm, keySelect, keychildren)"
v-if="keySelect >= 1"
>
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>REMOVE
</v-btn>
</v-flex>
</v-layout>
<v-btn
absolute
right
bottom
small
@click="addSelectboxForm(keyForm, keychildren)"
color="black"
>
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>
<span class="white--text">Add</span>
</v-btn>
</v-layout>
<v-btn
absolute
small
right
top
color="pink"
@click="removeForm(keyForm, keychildren)"
>
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>REMOVE
</v-btn>
</v-layout>
<v-btn
absolute
small
right
bottom
color="cyan"
@click="duplicateForm(keyForm)"
>
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>ADD
</v-btn>
</v-layout>
<v-btn
v-if="keyForm > 0 || form.info.length > 1"
absolute
small
right
top
color="pink"
@click="removeInput(keyForm)"
>
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>REMOVE
</v-btn>
<v-layout
row
wrap
align-center
justify-center
class="mt-4"
v-if="(form.info.length -1) == keyForm"
>
<v-btn
absolute
right
bottom
small
@click="addInput"
color="pink"
class="mb-2"
>
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>
<span class="white--text">Add</span>
</v-btn>
</v-layout>
</v-layout>
<v-layout row wrap align-center justify-center class="mt-4">
<v-btn
class="WM-CyanBlueGradient-BG"
style="padding:10px 60px"
@click="registerForm"
>
<v-icon class="white--text mr-2 caption">fas fa-check</v-icon>
<span class="white--text">Generate Form</span>
</v-btn>
<router-link to="/dashboard">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</v-form>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
export default {
data() {
return {
form: {
name: "",
unique_code: "",
info: [
{
id: 0,
name: "",
type: "",
size: ""
}
]
},
type: [
{ state: "Text", abbr: "Text" },
{ state: "Checkbox", abbr: "Checkbox" },
{ state: "Select", abbr: "Select" },
{ state: "Radiobutton", abbr: "Radiobutton" },
{ state: "Switch", abbr: "Switch" },
{ state: "Range", abbr: "Range" },
{ state: "Time", abbr: "Time" },
{ state: "Temperature", abbr: "Temperature" },
{ state: "Pressure", abbr: "Pressure" },
{ state: "Form", abbr: "Form" },
],
size: [
{ state: "not Selected", abbr: "" },
{ state: "2 from 12", abbr: "md2 xs12" },
{ state: "3 from 12", abbr: "md3 xs12" },
{ state: "4 from 12", abbr: "md4 xs12" },
{ state: "6 from 12", abbr: "md6 xs12" },
{ state: "8 from 12", abbr: "md8 xs12" },
{ state: "10 from 12", abbr: "md10 xs12" },
{ state: "12 from 12", abbr: "md12 xs12" }
],
rules: {
required: value => !!value || "Required."
},
deviceLabels: [
{ name: "Washer ID", id: "WasherID" },
{ name: "Autoclave ID", id: "AutoclaveID" },
{ name: "Sterilizer ID", id: "SterilizerID" },
{ name: "WasherMachine ID", id: "WasherMachineID" },
{ name: "SealMachine ID", id: "SealMachineID" },
{ name: "Patient ID", id: "PatientID" },
{ name: "Set/Pack ID", id: "Set/PackID" },
{ name: "MD ID", id: "MDID" },
{ name: "OR ID", id: "ORID" },
{ name: "Personal ID", id: "PersonalID" },
{ name: "Instrument ID", id: "InstrumentID" },
{ name: "ID", id: "ID" },
]
};
},
created() {
if (this.$route.params.testType) {
this.load(this.$route.params.testType);
}
},
methods: {
changeType(infoIndex, selectedboxType) {
if (selectedboxType == "Select" || selectedboxType == "Checkbox" || selectedboxType == "Radiobutton") {
this.form.info[infoIndex]["options"] = [{ id: 0, title: "" }];
} else if(selectedboxType == "Range") {
this.form.info[infoIndex]["options"] = [{ id: 0, title: ""}, { id: 0, title: ""}];
} else {
this.form.info[infoIndex]["options"] = [];
}
if (selectedboxType == "Form") {
this.form.info[infoIndex]["children"] = [
{ id: 0, name: "", type: "", size: "" }
];
}
},
removeSelectbox(infoIndex, selectboxOptions) {
let form = this.form;
this.form = [];
form.info[infoIndex]["options"].splice(selectboxOptions, 1);
this.form = form;
},
addSelectbox(infoIndex) {
let form = this.form;
this.form = [];
form.info[infoIndex]["options"].push({ id: 0, title: "" });
this.form = form;
},
addInput() {
this.form.info.push({ id: 0, name: "", type: "", size: "" });
},
changeTypeForm(infoIndex, type, formLevel) {
if (type == "Select" || type == "Checkbox" || type == "Radiobutton") {
let form = this.form;
this.form = "";
form.info[infoIndex]["children"][formLevel]["options"] = [
{ id: 0, title: "" }
];
this.form = form;
} else if(type == "Range") {
let form = this.form;
this.form = "";
form.info[infoIndex]["children"][formLevel]["options"] = [
{ id: 0, title: "" },
{ id: 0, title: "" },
];
this.form = form;
} else {
let form = this.form;
this.form = "";
form.info[infoIndex]["children"][formLevel]["options"] = [];
this.form = form;
}
},
removeSelectboxForm(infoIndex, selectboxOptions, formLevel) {
let form = this.form;
this.form = [];
form.info[infoIndex]["children"][formLevel]["options"].splice(
selectboxOptions,
1
);
this.form = form;
},
addSelectboxForm(infoIndex, formLevel) {
let form = this.form;
this.form = [];
form.info[infoIndex]["children"][formLevel]["options"].push({
id: 0,
title: ""
});
this.form = form;
},
duplicateForm(infoIndex) {
let form = this.form;
this.form = [];
form.info[infoIndex]["children"].push({
id: 0,
name: "",
type: "",
size: ""
});
this.form = form;
},
removeForm(infoIndex, formLevel) {
let form = this.form;
this.form = [];
form.info[infoIndex]["children"].splice(formLevel, 1);
this.form = form;
},
removeInput(infoIndex) {
let form = this.form;
this.form = [];
form.info.splice(infoIndex, 1);
this.form = form;
},
async registerForm() {
if (this.$refs.form.validate()) {
let result = null;
if (this.$route.params.testType) {
result = await ApiService.put(
urls.updateTestType(this.$route.params.testType),
this.form
);
} else {
result = await ApiService.post(
urls.storeTestType,
this.form
);
}
if (result && result.status == 200) {
this.$router.push({ name: `Dashboard` });
}
}
},
async load(id) {
const result = await ApiService.get(urls.editTestType(id));
if (result.status == 200) {
this.form = result.data.data;
}
}
}
};
</script>
<style lang="css" scoped>
.WM-Border-Gray {
border-color: #aaa !important;
}
.WM-Color-LightGrey {
background-color: #f5f5f5;
}
.v-btn--top.v-btn--absolute.v-btn--small {
top: -25px !important;
}
.v-btn--bottom.v-btn--absolute.v-btn--small {
bottom: -24px !important;
}
</style>
@@ -0,0 +1,230 @@
<template>
<v-container fluid>
<material-card class color="black" title="TestType List" text>
<v-layout wrap class="px-5 mb-3">
<v-flex xs12 md4 sm3 class="pr-3">
<v-text-field label="Name" v-model="filter.name" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md4 sm3 class="pr-3">
<v-text-field label="UniqueId" v-model="filter.unique_id" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md4 sm3 class="pr-3">
<v-text-field label="UserName" v-model="filter.user_name" color="black"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md3>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="fromMenu"
>
<v-text-field
required
slot="activator"
label="FromDate"
v-model="filter.fromPicker"
></v-text-field>
<v-date-picker
color="pink"
no-title
v-model="filter.fromPicker"
:date-format="date => new Date(date).toDateString()"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs12 sm6 md3>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="upToMenu"
>
<v-text-field
required
slot="activator"
label="UpToDate"
v-model="filter.upToPicker"
></v-text-field>
<v-date-picker
color="pink"
no-title
v-model="filter.upToPicker"
:date-format="date => new Date(date).toDateString()"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs12 md2 sm2 class="text-xs-right">
<v-btn
class="WM-CyanBlueGradient-BG"
style="padding:10px 60px"
@click="load(undefined)"
>
<v-icon class="white--text mr-2 caption">fas fa-search</v-icon>
<span class="white--text">Filter</span>
</v-btn>
</v-flex>
<v-spacer></v-spacer>
<v-flex xs12 md2 sm2 class="text-xs-right">
<router-link :to="{name: 'AddTestType'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text mr-2 caption">fas fa-plus</v-icon>
<span class="black--text">Add</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
<v-layout class="px-4 my-3">
<v-divider></v-divider>
</v-layout>
<v-layout align-center justify-center wrap class="px-5 mt-3">
<v-flex md12>
<v-data-table :headers="headers" :items="items" hide-actions>
<template slot="headerCell" slot-scope="{ header }">
<span
class="subheading font-weight-light text-white text--darken-3"
v-text="header.text"
/>
</template>
<template slot="items" slot-scope="{ item }">
<td class="headline font-weight-light">{{ item.name }}</td>
<td class="title font-weight-light">{{ item.unique_code }}</td>
<td class="title font-weight-light">{{ item.user.name }}</td>
<td class="title font-weight-light">{{ item.created_at }}</td>
<td class="text-xs-right">
<router-link
v-if="item.test_results_count == 0"
:to="{name : 'EditTestType', params : {testType : item.id}}"
>
<v-btn color="cyan" class="mr-2 WM-ActionButton">
<v-icon class="white--text mr-2 caption">fas fa-pen</v-icon>
<span>Edit</span>
</v-btn>
</router-link>
<v-btn color="black" class="mr-2" @click="remove(item.id)">
<v-icon class="white--text mr-1 caption">fas fa-folder</v-icon>
<span>Archive</span>
</v-btn>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination v-model="currentPage" :length="lastPage" :total-visible="6"></v-pagination>
</div>
<v-layout row wrap align-center justify-center class="mt-3">
<router-link to="/dashboard">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
export default {
data: () => ({
headers: [
{
sortable: false,
text: "TestType Name",
value: "name"
},
{
sortable: false,
text: "TestType UniqueId",
value: "uniqueId"
},
{
sortable: false,
text: "Register TestType",
value: "users"
},
{
sortable: false,
text: "Date",
value: "date"
},
{
sortable: false,
text: "Action",
value: "action",
align: "right"
}
],
items: [],
filter: {
name: "",
unique_id: "",
user_name: "",
fromPicker: "",
upToPicker: ""
},
fromMenu: "",
upToMenu: "",
currentPage: 1,
lastPage: 1
}),
created() {
this.load();
},
methods: {
async load(page = 1) {
let filter = "?";
for (const key in this.filter) {
if (this.filter.hasOwnProperty(key)) {
filter += `${key}=${this.filter[key]}&`;
}
}
filter += page ? `page=${page}` : `page=1`;
const result = await ApiService.get(urls.listTestType(filter));
if (result && result.status == 200) {
this.items = result.data.data.data;
this.currentPage = result.data.data.current_page;
this.lastPage = result.data.data.last_page;
}
},
async remove(id) {
const result = await ApiService.delete(urls.deleteTestType(id));
if (result.status == 200) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == id
) {
this.items.splice(key, 1);
}
}
}
},
},
watch: {
currentPage(page) {
this.load(page);
}
}
};
</script>
<style lang="css" scoped>
.WM-ActionButton {
padding: 8px 22px;
}
.v-btn--floating {
padding: 0!important;
}
.theme--light.v-btn.v-btn--flat {
color: rgba(0,0,0,.87)!important;
}
.v-btn--floating, .v-btn--icon:before {
border-radius: 50%!important;
}
</style>
@@ -0,0 +1,203 @@
<template>
<v-container fluid>
<material-card class color="black" title="My Recent ChatList" text>
<v-toolbar flat color="white">
<v-toolbar-title></v-toolbar-title>
<v-divider class="mx-2" inset vertical></v-divider>
<v-spacer></v-spacer>
<v-btn color="black" @click="newmessage" class="WM-ActionButton mb-2">
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>
<span>New Message</span>
</v-btn>
</v-toolbar>
<v-layout class="px-4 my-3">
<v-divider></v-divider>
</v-layout>
<v-layout align-center justify-center wrap class="px-5 mt-3">
<v-flex md12>
<v-data-table :headers="headers" :items="items" hide-actions>
<template slot="headerCell" slot-scope="{ header }">
<span
class="subheading font-weight-light text-white text--darken-3"
v-text="header.text"
/>
</template>
<template slot="items" slot-scope="{ item }">
<td
class="headline font-weight-light WM-NoLetterSpacing"
>{{ item.name }}</td>
<td class="title font-weight-light">
<span class="Chip">
<span class="Count Content">{{ item.messages_count }} count</span>
</span>
</td>
<td class="title font-weight-light">
<span class="Chip">
<span
class="Unread Content"
>{{ item.unread_messages_count }} unread</span>
</span>
</td>
<td class="text-xs-right">
<v-btn
color="pink"
@click="showmessages(item.id)"
class="WM-ActionButton"
>
<v-icon class="white--text mr-2 caption">fas fa-chevron-right</v-icon>
<span>Show Message</span>
</v-btn>
<v-btn
color="pink"
@click="remove(item.id)"
class="WM-ActionButton"
>
<v-icon class="white--text mr-2 caption">fas fa-trash</v-icon>
<span>delete</span>
</v-btn>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination v-model="currentPage" :length="lastPage" :total-visible="6"></v-pagination>
</div>
<v-layout row wrap align-center justify-center class="mt-3">
<router-link :to="{name: 'Dashboard'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations, mapGetters } from "vuex";
export default {
data: () => ({
headers: [
{
sortable: false,
text: "Name",
value: "name"
},
{
sortable: false,
text: "Count Messages",
value: "operator"
},
{
sortable: false,
text: "Unread Message",
value: "operator"
},
{
sortable: false,
text: "Action",
value: "action",
align: "right"
}
],
filter: {
name: ""
},
items: [],
refresh: "",
currentPage: 1,
lastPage: 1
}),
created() {
this.load();
},
methods: {
async load(page = 1) {
const result = await ApiService.get(urls.listMessages(page));
if (result && result.data.data) {
this.items = result.data.data.data;
this.currentPage = result.data.data.current_page;
this.lastPage = result.data.data.last_page;
}
},
...mapMutations("modal", ["changeCurrentModal"]),
newmessage() {
this.changeCurrentModal({ modal: "modal-ticket-new-message" });
},
showmessages(user_id) {
this.changeCurrentModal({
modal: "modal-ticket-show-messages",
properties: { user_id: user_id }
});
},
async remove(user_id) {
const result = await ApiService.delete(
urls.removeUserMessage(user_id)
);
if (result && result.status == 200) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == user_id
) {
this.items.splice(key, 1);
}
}
}
}
},
computed: {
...mapGetters("modal", ["getModalResult"])
},
watch: {
currentPage(page) {
this.load(page);
},
getModalResult() {
this.load();
}
}
};
</script>
<style lang="css" scoped>
.WM-ActionButton {
padding: 8px 22px;
}
.Chip {
align-items: center;
border-radius: 28px;
display: inline-flex;
font-size: 13px;
margin: 4px;
outline: none;
position: relative;
transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
vertical-align: middle;
height: 24px;
color: #000;
}
.Chip .Content {
align-items: center;
border-radius: 24px;
cursor: default;
display: inline-flex;
height: 32px;
justify-content: space-between;
padding: 0 12px;
vertical-align: middle;
white-space: nowrap;
z-index: 1;
}
.Chip .Content.Count {
background-color: #b2dfdb;
}
.Chip .Content.Unread {
background-color: #ffcdd2;
}
</style>
+324
View File
@@ -0,0 +1,324 @@
<template>
<v-container grid-list-xs>
<material-card color="black" title="Member List">
<v-layout align-center justify-center wrap class="px-5 mb-3">
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
color="black"
name="name"
label="Name"
v-model="filter.name"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-autocomplete
class="pa-2"
v-model="filter.medicalCenter_id"
label="Hospital"
color="black"
:items="medicalCenters"
item-text="name"
item-value="id"
></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3>
<v-text-field
class="pa-2"
color="black"
name="CellPhone"
label="CellPhone"
v-model="filter.cell_number"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3>
<v-select
class="pa-2"
color="black"
name="role"
label="Role"
:items="roles"
v-model="filter.role"
></v-select>
</v-flex>
<v-flex xs12 sm6 md3>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="fromMenu"
>
<v-text-field
required
slot="activator"
label="FromDate"
v-model="filter.fromPicker"
></v-text-field>
<v-date-picker
color="pink"
no-title
v-model="filter.fromPicker"
:date-format="date => new Date(date).toDateString()"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs12 sm6 md3>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="upToMenu"
>
<v-text-field
required
slot="activator"
label="UpToDate"
v-model="filter.upToPicker"
></v-text-field>
<v-date-picker
color="pink"
no-title
v-model="filter.upToPicker"
:date-format="date => new Date(date).toDateString()"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs12 md3 sm3>
<v-btn
class="WM-CyanBlueGradient-BG"
style="padding:10px 60px"
@click="load(undefined)"
>
<v-icon class="white--text mr-2 caption">fas fa-search</v-icon>
<span class="white--text">Filter</span>
</v-btn>
</v-flex>
</v-layout>
<v-layout class="px-4 my-3">
<v-divider></v-divider>
</v-layout>
<v-layout align-center justify-center wrap class="px-5 my-2">
<v-flex xs12 md12 sm12>
<v-data-table :headers="headers" :items="items" hide-actions>
<template slot="headerCell" slot-scope="{ header }">
<span
class="subheading font-weight-light text-white text--darken-3"
v-text="header.text"
/>
</template>
<template slot="items" slot-scope="{ item }">
<td class="headline font-weight-light">
{{item.name}}
<br>
<span class="WM-Font-14">{{item.cell_number}}</span>
</td>
<td class="title font-weight-light">{{item.created_at}}</td>
<td class="title font-weight-light">
<span v-for="(role, key) in item.roles" :key="key">{{ role.name }}</span>
</td>
<td class="title font-weight-light">{{item.medical_center.name}}</td>
<td class="text-xs-right">
<v-btn
:color="item.status == 'Active' ? 'red' : 'green'"
@click="changeStatus(item.id)"
class="mr-2 WM-ActionButton"
v-if="$hasRole('Admin|Supervisor')"
>
<template v-if="item.status == 'Active'">
<v-icon class="white--text mr-2 caption">fas fa-user-tag</v-icon>
<span v-if="item.status == 'Active'">Susspended</span>
</template>
<template v-else>
<v-icon class="white--text mr-2 caption">fas fa-user-tag</v-icon>
<span>Active</span>
</template>
</v-btn>
<v-btn
color="orange darken-1"
@click="changeRoleModal(item)"
class="mr-2 WM-ActionButton"
v-if="$hasRole('Admin')"
>
<v-icon class="white--text mr-2 caption">fas fa-user-tag</v-icon>
<span>Role</span>
</v-btn>
<v-btn
color="pink"
v-if="$hasRole('Admin')"
class="WM-ActionButton"
@click="remove(item.id)"
>
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
<span>Remove</span>
</v-btn>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-layout class="px-4 my-3">
<v-divider></v-divider>
</v-layout>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination
color="black"
circle
v-model="currentPage"
:length="lastPage"
:total-visible="6"
></v-pagination>
</div>
<v-layout row wrap align-center justify-center class="mt-3">
<router-link :to="{name: 'Dashboard'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black ml-5">
<v-icon class="black--text mr-2 caption">fas fa-chevron-left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</template>
<script>
import { urls } from "@/config/urls";
import { ApiService } from "@/services";
import { mapMutations, mapGetters } from "vuex";
import { roles } from "@/config/utils";
export default {
data: () => ({
headers: [
{
sortable: true,
text: "Operator",
value: "name"
},
{
sortable: false,
text: "Date",
value: "date"
},
{
sortable: false,
text: "Role",
value: "role"
},
{
sortable: true,
text: "Hospital",
value: "hospital"
},
{
sortable: false,
text: "Action",
value: "action",
align: "right"
}
],
filter: {
name: "",
cell_number: "",
medicalCenter_id: "",
role: "",
fromPicker: "",
upToPicker: ""
},
fromMenu: "",
upToMenu: "",
items: [],
roles,
currentPage: 1,
lastPage: 1,
medicalCenters: []
}),
created() {
this.fillSelectFilter();
this.load();
},
methods: {
async load(page = 1) {
let filter = "?";
for (const key in this.filter) {
if (this.filter.hasOwnProperty(key)) {
filter += `${key}=${this.filter[key]}&`;
}
}
filter += page ? `page=${page}` : `page=1`;
const result = await ApiService.get(urls.listOpertor(filter));
if (result && result.status == 200) {
this.items = result.data.data.data;
this.currentPage = result.data.data.current_page;
this.lastPage = result.data.data.last_page;
} else {
this.$router.push({ name: `Dashboard` });
}
},
async changeStatus(userId) {
const result = await ApiService.post(urls.changeStatusUser(userId));
if (result && result.status == 200) {
for (let user of this.items) {
if (user.id == userId) {
user.status = result.data.data.status;
}
}
} else {
this.$router.push({ name: `Dashboard` });
}
},
...mapMutations("modal", ["changeCurrentModal"]),
changeRoleModal(user) {
this.changeCurrentModal({
modal: "modal-user-role",
properties: { user }
});
},
async remove(userId) {
const result = await ApiService.delete(urls.deleteUser(userId));
if (result && result.status == 200) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == userId
) {
this.items.splice(key, 1);
}
}
}
},
async fillSelectFilter() {
const result = await ApiService.get(urls.listFilterItemsTestResult);
if (result && result.status == 200) {
this.medicalCenters = result.data.data.MedicalCenters;
}
}
},
computed: {
...mapGetters("modal", ["getModalResult"])
},
watch: {
getModalResult(user) {
for (const userList of this.items) {
if (userList.id == user.id) {
userList.roles = user.roles;
}
}
},
currentPage(page) {
this.load(page);
}
}
};
</script>
<style>
.v-btn--floating {
padding: 0!important;
}
.theme--light.v-btn.v-btn--flat {
color: rgba(0,0,0,.87)!important;
}
.v-btn--floating, .v-btn--icon:before {
border-radius: 50%!important;
}
</style>
@@ -0,0 +1,141 @@
<template>
<v-form ref="form">
<v-container grid-list-xs fluid>
<material-card color="black" title="My Info">
<v-layout align-center justify-center wrap class="px-5 my-3">
<v-flex xs12 sm4 md4>
<v-text-field
name="name"
label="Name"
color="black"
v-model="user.name"
:rules="[rules.required, rules.counter]"
class="pa-2"
></v-text-field>
</v-flex>
<v-flex xs12 sm4 md4>
<v-select
:items="items"
label="Gender"
name="gender"
v-model="user.gender"
single-line
:rules="[rules.required]"
class="pa-2"
color="black"
></v-select>
</v-flex>
<v-flex xs12 sm4 md4>
<v-text-field
name="cellnumber"
label="Cell Number"
v-model="user.cell_number"
color="black"
class="pa-2"
disabled
></v-text-field>
</v-flex>
</v-layout>
<v-layout align-center justify-center wrap class="px-5 mb-3">
<v-flex xs12 sm4 md4>
<v-text-field
name="emailaddress"
label="Email Address"
v-model="user.email"
:rules="[rules.email]"
class="px-2"
color="black"
style="padding-top:75px"
></v-text-field>
</v-flex>
<v-flex xs12 sm8 md8>
<v-textarea
color="black"
:rules="[rules.counter]"
v-model="user.address"
class="pa-2"
name="address"
>
<template v-slot:label>
<div>Address</div>
</template>
</v-textarea>
</v-flex>
</v-layout>
<v-layout row wrap justify-center align-center>
<v-flex xs12 md2 sm2 class="text-md-center text-xs-center">
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="saveInfo()">
<v-icon class="white--text mr-2 caption">fas fa-check</v-icon>
<span class="white--text">SAVE</span>
</v-btn>
</v-flex>
<v-flex xs12 md2 sm2 class="text-md-center text-sm-center text-xs-center">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black" @click="changePassword">
<v-icon class="black--text">fas fa-refresh</v-icon>
<span class="black--text"> Change Password </span>
</v-btn>
</v-flex>
<v-flex xs12 md2 sm2 class="text-md-center text-sm-center text-xs-center">
<router-link :to="{name: 'Dashboard'}">
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black">
<v-icon class="black--text">keyboard_arrow_left</v-icon>
<span class="black--text">Back</span>
</v-btn>
</router-link>
</v-flex>
</v-layout>
</material-card>
</v-container>
</v-form>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations } from 'vuex';
export default {
data() {
return {
user: {
cell_number: "",
gender: "",
name: "",
email: "",
address: ""
},
items: ["Male", "FeMale"],
rules: {
required: value => !!value || "Required.",
counter: value =>
!value || value.length == 0 || value.length >= 5 || "Min 5 characters",
email: value => {
if (value && value.length > 0) {
const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return pattern.test(value) || "Invalid e-mail.";
} else{
return true;
}
}
}
};
},
created() {
this.user = this.$store.state.user;
},
methods: {
async saveInfo() {
if (this.$refs.form.validate()) {
const result = await ApiService.post(urls.updateInfo, this.user);
if (result && result.status == 200) {
this.$store.dispatch("info", {}, { root: true });
this.$router.push({ name: `Dashboard` });
}
}
},
...mapMutations('modal',['changeCurrentModal']),
changePassword() {
this.changeCurrentModal({ modal: "modal-auth-change-password" });
}
}
};
</script>