This commit is contained in:
sajjad
2023-10-18 01:22:06 -07:00
parent b16da8ab41
commit 98aa208766
157 changed files with 28673 additions and 13308 deletions
+70
View File
@@ -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>
+97
View File
@@ -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>
+133
View File
@@ -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="form.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="form.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>
+227
View File
@@ -0,0 +1,227 @@
<template>
<v-form ref="form">
<v-container grid-list-xs fluid>
<material-card color="black" title="Add Cycle">
<v-layout wrap class="px-5 my-3">
<v-flex xs12 sm6 md4 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
name="sterilizer_id"
label="Sterilizer ID"
color="black"
v-model="formData.sterilizer_id"
class="py-3 pr-3"
></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
name="cycle_number"
label="Cycle Number"
color="black"
v-model="formData.cycle_number"
class="py-3 pr-3"
></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4 class="WM-FlexCenter">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="fromMenuDate"
>
<v-text-field
required
slot="activator"
label="Date"
color="black"
class="pr-3"
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></v-flex>
<v-flex xs12 sm6 md4 class="WM-FlexCenter WM-DuplicateInput" style="position: relative" v-for="(label, key) in formData.labels" :key="key">
<div class="Inner">
<v-icon class="fa fa-check mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete
color="black"
:items="labels"
item-text="id"
item-value="id"
v-model="label.id"
label="Select Label For Cycle"
></v-autocomplete>
<!-- <v-text-field
name="labels"
label="Label ID"
color="black"
v-model="label.id"
class="py-3 pr-3"
></v-text-field> -->
<v-btn
absolute
small
right
bottom
color="cyan"
@click="duplicateForm(key)"
>
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>ADD
</v-btn>
<v-btn v-if="key > 0"
absolute
small
right
top
color="pink"
@click="removeForm(key)"
>
<v-icon class="white--text mr-2 caption">fas fa-remove</v-icon>REMOVE
</v-btn>
</div>
</v-flex>
<v-spacer></v-spacer>
<v-flex xs12>
<hr class="v-divider theme--light" style="margin:30px 0 0 0 !important">
</v-flex>
<v-flex xs12 sm12 md12 class="WM-FlexCenter">
<!-- <v-icon class="fa fa-sort-amount-desc mr-2"></v-icon> -->
<v-textarea color="black" v-model="formData.note" class="py-3 pr-3" 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: '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 {
fromMenuDate: false,
formData: {
note: "",
labels: [
{
name:''
}
]
},
labels: [],
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.loadLabels();
},
methods: {
async load(id) {
const result = await ApiService.get(urls.editCycle(id));
if (result.status == 200) {
this.formData = result.data.data;
}
},
async loadLabels() {
const result = await ApiService.get(urls.listAllLabel());
if (result.status == 200) {
this.labels = 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" });
}
},
duplicateForm(infoIndex) {
this.formData.labels.push({
name: "",
});
},
removeForm(infoIndex) {
this.formData.labels.splice(infoIndex, 1);
},
}
};
</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;
}
.WM-DuplicateInput {
margin: 15px 0;
}
.WM-DuplicateInput .Inner {
padding: 15px 20px !important;
margin: 0 10px 0 0;
width: 100%;
border: 1px solid rgba(0,0,0,.2);
}
</style>
+312
View File
@@ -0,0 +1,312 @@
<template>
<div class>
<v-container fluid>
<material-card class color="black" title="All Cycles" text>
<v-layout align-center wrap class="px-5 my-3">
<v-flex xs12 md2 sm3 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
class="py-3 pr-3"
v-model="filter.cycle_id"
label="Cycle ID"
color="black"
></v-text-field>
</v-flex>
<v-flex xs12 md2 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
class="py-3 pr-3"
v-model="filter.sterilizer_id"
label="Sterilizer ID"
color="black"
></v-text-field>
</v-flex>
<v-flex xs12 md2 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
class="py-3 pr-3"
v-model="filter.cycle_number"
label="Cycle Number"
color="black"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3" v-if="$hasRole('Admin')">
<v-icon class="fa fa-hospital-o mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete
class="py-3 pr-3"
v-model="filter.medical_center_id"
item-text="name"
item-value="id"
label="Hospital"
color="black"
:items="medicalCenters"
:clearable="true"
></v-autocomplete>
</v-flex>
<v-flex xs12 sm2 md2 class="WM-FlexCenter pl-3">
<v-icon class="far fa-calendar-alt mr-2 WM-Margin-B-8"></v-icon>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="Menu"
>
<v-text-field style="padding-top:0 !important"
required
slot="activator"
label="Date"
color="black"
class=""
v-model="filter.date">
</v-text-field>
<v-date-picker
color="pink"
no-title
v-model="filter.date"
: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()">
<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-layout class="px-4 my-3">
<v-divider></v-divider>
</v-layout>
<v-layout align-center wrap class="px-5 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.id }}</td>
<td
class="title font-weight-light"
>{{ (item.user && item.user.medical_center) ? item.user.medical_center.name : '' }}</td>
<td class="title font-weight-light">{{ item.sterilizer_id }}</td>
<td class="title font-weight-light">{{ item.cycle_number }}</td>
<td class="title font-weight-light">{{ item.date }}</td>
<td class="text-xs-right FlexBtn Height-MD-60">
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Show</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<router-link
class="LinkBtn"
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
:to="{name: 'EditCycle', params: {cycle: item.id}}"
>
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Edit</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn
v-bind="attrs" v-on="on"
color="pink"
class="WM-ActionButton mr-2"
@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>
</template>
<span>Remove</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn
v-bind="attrs" v-on="on"
color="orange darken-1"
@click="generateBarcode(item.id, 'Cycle')">
<v-icon class="white--text mr-1 caption">fas fa-barcode</v-icon>
<span>Generate Barcode</span>
</v-btn>
</template>
<span>Generate Barcode</span>
</v-tooltip>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center mt-2" v-if="lastPage > 1">
<v-pagination color="black" 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: "Cycle ID",
value: "Cycle ID"
},
{
sortable: true,
text: "Hospital",
value: "Hospital"
},
{
sortable: true,
text: "Sterilizer ID",
value: "Sterilizer ID"
},
{
sortable: false,
text: "Cycle Number",
value: "Cycle Number"
},
{
sortable: false,
text: "Date",
value: "date"
},
{
sortable: false,
text: "Action",
value: "action",
align: "left"
}
],
filter: {},
Menu: false,
packages: [],
currentPage: 1,
lastPage: 1,
medicalCenters: []
}),
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;
}
this.loadMedicalCenters();
},
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 generateBarcode(code, type) {
const result = await ApiService.post(urls.Barcode(code, type));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
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 loadMedicalCenters() {
const result = await ApiService.get(urls.listFilterItemsTestResult);
if (result && result.status == 200) {
this.medicalCenters = result.data.data.MedicalCenters;
}
},
},
computed: {
...mapGetters("modal", ["getModalResult"])
},
watch: {
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>
+74
View File
@@ -0,0 +1,74 @@
<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>
import { UserService } from '@/services';
export default {
data() {
return {
AdminCards: [
{ title: 'Manage Users', text: 'You can Manage the users information', icon: '/img/Static/Dashboard/manageusers.png', color: 'WM-LightGreenGradient-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/settings.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/result.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/manageusers.png', color: 'WM-LightGreenGradient-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/verify.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/info.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/alltest.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/addtest.png', color: 'WM-YellowGradient-BG', route: { name: 'SubmitTestResult' }, aligntext: 'text-md-center', alignimg: 'text-md-left', column: 'xs12 md12 sm12' },
],
}
},
}
</script>
<style lang="scss"></style>
+178
View File
@@ -0,0 +1,178 @@
<template id="">
<div class="">
<v-toolbar color="white">
<v-toolbar-title v-text="title"></v-toolbar-title>
</v-toolbar>
<!-- _______________ Section 2::Begin _______________ -->
<section>
<v-parallax src="https://images.squarespace-cdn.com/content/v1/5bf5d5da506fbea76ffa4abe/1547249524951-CQ5U440SQYT23ODKL23G/ke17ZwdGBToddI8pDm48kKAwwdAfKsTlKsCcElEApLR7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z5QPOohDIaIeljMHgDF5CVlOqpeNLcJ80NK65_fV7S1UegTYNQkRo-Jk4EWsyBNhwKrKLo5CceA1-Tdpfgyxoog5ck0MD3_q0rY3jFJjjoLbQ/yenyi.jpg" height="600">
<v-layout
column
align-center
justify-center
class="white--text"
>
<!-- <img src="assets/vuetify.png" alt="Vuetify.js" height="200"> -->
<p class="display-4 mb-5">CSSD-DOC</p>
<h1 class="white--text mb-2 mt-5 display-1 text-center">Central Sterile Supply Department App & Software</h1>
<div class="subheading mb-4 text-center">Management & Traceability & Documentation solution for CSSD / SPD</div>
</v-layout>
</v-parallax>
</section>
<section>
<v-layout
column
wrap
class="my-12"
align-center
>
<v-flex xs12 sm4 class="my-4">
<div class="text-center">
<h2 class="headline">-Sterilization process monitoring</h2>
<span class="subheading">
- Sterilizer test records
</span>
</div>
</v-flex>
<v-flex xs12>
<v-container grid-list-xl>
<v-layout row wrap align-left>
<v-flex xs12 md4>
<v-card flat class="transparent">
<p v-for="(item , i) in items.items1" :key="i" class="headline text-left">item</p>
</v-card>
</v-flex>
<v-flex xs12 md4>
<v-card flat class="transparent">
<p v-for="(item , i) in items.items2" :key="i" class="headline text-left">item</p>
</v-card>
</v-flex>
<v-flex xs12 md4>
<v-card flat class="transparent">
<p v-for="(item , i) in items.items3" :key="i" class="headline text-left" v-text="item"></p>
</v-card>
</v-flex>
</v-layout>
</v-container>
</v-flex>
</v-layout>
</section>
<!-- _______________ Section 2::End _______________ -->
<!-- _______________ Section 7::Begin _______________ -->
<section>
<v-layout
column
wrap
class="my-12"
align-center
>
<v-flex xs12 sm4 class="my-4">
<div class="text-center">
<h2 class="headline">Product identification and traceability</h2>
<span class="subheading">
Cras facilisis mi vitae nunc
</span>
</div>
</v-flex>
<v-flex xs12>
<v-container grid-list-xl>
<v-layout row wrap align-center>
<v-flex xs12 md4>
<v-card flat class="transparent">
<v-card-text class="text-center">
<v-icon x-large class="blue--text text--lighten-2">mdi-palette</v-icon>
</v-card-text>
<v-card-title primary-title class="layout justify-center">
<div class="headline text-center">Item</div>
</v-card-title>
<v-card-text>
Define and identify every instrument.
</v-card-text>
</v-card>
</v-flex>
<v-flex xs12 md4>
<v-card flat class="transparent">
<v-card-text class="text-center">
<v-icon x-large class="blue--text text--lighten-2">mdi-flash</v-icon>
</v-card-text>
<v-card-title primary-title class="layout justify-center">
<div class="headline">Fast development</div>
</v-card-title>
<v-card-text>
Cras facilisis mi vitae nunc lobortis pharetra. Nulla volutpat tincidunt ornare.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Nullam in aliquet odio. Aliquam eu est vitae tellus bibendum tincidunt. Suspendisse potenti.
</v-card-text>
</v-card>
</v-flex>
<v-flex xs12 md4>
<v-card flat class="transparent">
<v-card-text class="text-center">
<v-icon x-large class="blue--text text--lighten-2">mdi-wrench</v-icon>
</v-card-text>
<v-card-title primary-title class="layout justify-center">
<div class="headline text-center">Completely Open Sourced</div>
</v-card-title>
<v-card-text>
Cras facilisis mi vitae nunc lobortis pharetra. Nulla volutpat tincidunt ornare.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Nullam in aliquet odio. Aliquam eu est vitae tellus bibendum tincidunt. Suspendisse potenti.
</v-card-text>
</v-card>
</v-flex>
</v-layout>
</v-container>
</v-flex>
</v-layout>
</section>
</div>
</template>
<script>
export default {
data: () => ({
items: [
{
items1 : [
'aaaaa',
'aaaaa',
'aaaaaa'
],
},
{
items2 : [
'aaaaa',
'aaaaa',
'aaaaaa'
],
},
{
items3 : [
'aaaaa',
'aaaaa',
'aaaaaa'
],
},
],
disabled: false,
dense: false,
twoLine: false,
threeLine: false,
shaped: false,
flat: false,
subheader: false,
inactive: false,
subGroup: false,
nav: false,
avatar: false,
rounded: false,
}),
components: {
},
created(){
},
}
</script>
+138
View File
@@ -0,0 +1,138 @@
<template>
<v-form ref="form">
<v-container grid-list-xs fluid>
<material-card color="black" title="Add Instrument">
<v-layout align-center justify-center wrap class="px-5 my-3">
<v-flex xs12 md4 sm4 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field name="name" label="Name" color="black" v-model="formData.name" :rules="[rules.required]"
class="py-3 pr-3"></v-text-field>
</v-flex>
<!-- <v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
name="unique_id"
label="Item ID"
color="black"
v-model="formData.unique_id"
:rules="[rules.required]"
class="py-3 pr-3"
></v-text-field>
</v-flex> -->
<v-flex xs12 md4 sm4 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-check mr-2 WM-Margin-B-8"></v-icon>
<v-text-field name="size" label="Size" color="black" v-model="formData.size" class="py-3 pr-3"></v-text-field>
</v-flex>
<v-flex xs12 md4 sm4 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-check mr-2 WM-Margin-B-8"></v-icon>
<v-text-field name="specific" label="Specific" color="black" v-model="formData.specific"
class="py-3 pr-3"></v-text-field>
</v-flex>
</v-layout>
<v-layout class="px-5 mb-3">
<v-flex xs12 md4 sm4 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field name="UDI" label="UDI" color="black" v-model="formData.udi" :rules="[rules.required]"
class="py-3 pr-3"></v-text-field>
</v-flex>
<v-flex xs12 md8 sm8 class="WM-FlexCenter" v-if="galleryDataLoaded">
<wm-Dropzone class="w-100" :Images="galleries" :BatchID="file_batch_id" :ModelID="$route.params.Item"
ModelType="Item"></wm-Dropzone>
</v-flex>
</v-layout>
<v-layout align-center wrap class="px-5 mb-3">
<v-flex xs12 sm12 md12>
<v-textarea color="black" v-model="formData.note" 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';
import Dropzone from '@/components/core/Dropzone'
export default {
components: {
'wm-Dropzone': Dropzone,
},
data() {
return {
galleries: [],
galleryDataLoaded: false,
file_batch_id: Math.floor(Math.random() * 9000000000) + 1000000000,
formData: {
name: "",
unique_id: "",
result: "",
note: "",
},
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);
} else {
this.galleryDataLoaded = true;
}
},
methods: {
async load(id) {
const result = await ApiService.get(urls.editItem(id));
if (result.status == 200) {
this.galleries = result.data.data.filesPath;
this.galleryDataLoaded = true;
this.formData = result.data.data;
}
},
async submitForm() {
let result;
this.formData['file_batch_id'] = this.file_batch_id;
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>
<style>
.w-100 {
width: 100%;
}
</style>
+313
View File
@@ -0,0 +1,313 @@
<template>
<div class>
<v-container fluid>
<material-card class color="black" title="All Items" text>
<v-layout align-center wrap class="my-3 px-5">
<v-flex xs12 md3 sm3 class="WM-FlexCenter">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.item_id" label="Item ID"
color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.name" label="Name" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3" v-if="$hasRole('Admin')">
<v-icon class="fa fa-hospital-o mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete class="py-3 pr-3" v-model="filter.medical_center_id" item-text="name"
item-value="id" label="Hospital" color="black" :items="medicalCenters"
:clearable="true"></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.size" label="Size" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl3">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.udi" label="UDI" color="black"></v-text-field>
</v-flex>
</v-layout>
<v-layout class="px-5 my-3">
<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 CSSD-font">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 CSSD-font">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 wrap class="my-3 px-5">
<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.id }}</td>
<!-- <td class="title font-weight-light">{{ item.unique_id }}</td> -->
<td class="title font-weight-light">{{ item.name }}</td>
<td class="title font-weight-light">{{ item.user ? item.user.name : '' }}</td>
<td class="title font-weight-light">{{ (item.user && item.user.medical_center) ?
item.user.medical_center.name : '' }}</td>
<td class="title font-weight-light">{{ item.udi }}</td>
<td class="title font-weight-light">{{ item.size }}</td>
<td class="text-xs-right FlexBtn Height-MD-60">
<v-tooltip bottom open-on-hover v-if="$hasRole('Supervisor|Admin')">
<template v-slot:activator="{ on, attrs }">
<v-btn :color="item.status ? 'red' : 'green'" class="mr-2"
@click="changeStatus(item.id)" v-bind="attrs" v-on="on">
<v-icon class="white--text mr-1 caption">fas {{ item.status ? 'fa-close' :
'fa-check' }}</v-icon>
<span>{{ item.status ? 'reject' : 'approve' }}</span>
</v-btn>
</template>
<span>{{ item.status ? 'reject' : 'approve' }}</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Show</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<router-link class="LinkBtn"
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
:to="{ name: 'EditItem', params: { Item: item.id } }">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Edit</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" color="pink" class="WM-ActionButton mr-2"
@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-trash</v-icon>
<span>Remove</span>
</v-btn>
</template>
<span>Remove</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn class="mr-2" v-bind="attrs" v-on="on" color="orange darken-1"
@click="generateBarcode(item, 'Item')">
<v-icon class="white--text mr-2 caption">fas fa-barcode</v-icon>
<span class="CSSD-font">Generate Barcode</span>
</v-btn>
</template>
<span>Generate Barcode</span>
</v-tooltip>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination color="black" 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 CSSD-font">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";
import toast from "@/services/global/toast.service";
export default {
data: () => ({
headers: [
// {
// sortable: true,
// text: "ID",
// value: "id"
// },
{
sortable: true,
text: "Item ID",
value: "id"
},
{
sortable: false,
text: "Name",
value: "name"
},
{
sortable: true,
text: "User",
value: "User"
},
{
sortable: true,
text: "Hospital",
value: "Hospital"
},
{
sortable: false,
text: "UDI",
value: "udi"
},
{
sortable: false,
text: "Size",
value: "size"
},
{
sortable: false,
text: "Action",
value: "action",
align: "left"
}
],
filter: {
name: '',
size: '',
item_id: '',
medical_center_id: ''
},
items: [],
currentPage: 1,
lastPage: 1,
medicalCenters: []
}),
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;
}
this.loadMedicalCenters();
},
async generateBarcode(item, type = null) {
let code = item.udi;
if (code) {
const result = await ApiService.post(urls.Barcode(code, type));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
properties: { result, item },
});
}
} else {
toast.error('please first set UDI');
}
},
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 changeStatus(id) {
const result = await ApiService.post(
urls.changeItemStatus(id)
);
if (result) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == id
) {
this.items[key].status = result.data.data.status;
}
}
}
},
async loadMedicalCenters() {
const result = await ApiService.get(urls.listFilterItemsTestResult);
if (result && result.status == 200) {
this.medicalCenters = result.data.data.MedicalCenters;
}
},
},
watch: {
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>
+180
View File
@@ -0,0 +1,180 @@
<template>
<v-form ref="form">
<v-container grid-list-xs fluid>
<material-card color="black" title="Add Label on Set ">
<v-layout wrap class="px-5 my-3">
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field name="sterilizerId" label="Sterilizer ID" color="black"
v-model="formData.sterilizer_id" class="py-3 pr-3"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field name="cycle_number" label="Cycle Number" color="black" v-model="formData.cycle_number"
class="py-3 pr-3"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field name="lot_number" label="Lot Number" color="black" readonly v-model="lotNumber"
class="py-3 pr-3"></v-text-field>
</v-flex>
<v-spacer></v-spacer>
<v-flex xs12 sm6 md3 class="WM-FlexCenter">
<v-icon class="fas fa-check mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete color="black" :items="items" item-text="name" v-model="formData.package_id"
item-value="id" label="Package ID" class="py-3 pr-3" :filter="customFilter">
<template v-slot:chip="{ item }">
{{ item.name }} - {{ item.udi }}
</template>
<template v-slot:item="{ item }">
{{ item.name }} - {{ item.udi }}
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 sm6 md2 class="WM-FlexCenter pl-3">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<v-menu lazy :close-on-content-click="true" transition="v-scale-transition" offset-y
v-model="fromMenuSterile">
<v-text-field required slot="activator" label="Sterile Date" color="black" class="pr-3"
v-model="formData.sterile_date">
</v-text-field>
<v-date-picker color="pink" no-title v-model="formData.sterile_date"
:date-format="date => new Date(date).toDateString()"></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs12 sm6 md2 class="WM-FlexCenter pl-3">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<v-menu lazy :close-on-content-click="true" transition="v-scale-transition" offset-y
v-model="fromMenuExpire">
<v-text-field required slot="activator" label="Expire Date" color="black" class="pr-3"
v-model="formData.expire_date">
</v-text-field>
<v-date-picker :show-current="showCurrent" min="2020-01-01" color="pink" no-title
v-model="formData.expire_date"
:date-format="date => new Date(date).toDateString()"></v-date-picker>
</v-menu>
</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: 'AllLabels' }">
<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 {
showCurrent: false,
fromMenuSterile: false,
fromMenuExpire: false,
formData: {
result: "",
package_id: "",
expire_date: "2020-01-01",
sterilizer_id: '',
cycle_number: '',
sterile_date: new Date().toISOString().substr(0, 10)
},
items: [],
rules: {
required: value => !!value || "Required.",
counter: value =>
!value ||
value.length == 0 ||
value.length >= 5 ||
"Min 5 characters"
}
};
},
created() {
if (this.$route.params.label) {
this.load(this.$route.params.label);
}
this.loadItems();
},
computed: {
lotNumber() {
return this.formData.sterilizer_id + ' - ' + this.formData.cycle_number;
}
},
methods: {
customFilter(item, queryText) {
const name = item.name.toLowerCase();
const udi = item.udi ? item.udi.toLowerCase() : null;
const searchText = queryText.toLowerCase();
if (udi) {
return name.indexOf(searchText) > -1 ||
udi.indexOf(searchText) > -1
}
return name.indexOf(searchText) > -1
},
async load(id) {
const result = await ApiService.get(urls.editLabel(id));
if (result.status == 200) {
this.formData = result.data.data;
}
},
async loadItems() {
const result = await ApiService.get(urls.listAllPackage());
if (result.status == 200) {
this.items = result.data.data;
}
},
async submitForm() {
let result;
this.formData['lot_number'] = this.lotNumber;
if (this.$route.params.label) {
result = await ApiService.put(
urls.updateLabel(this.$route.params.label),
this.formData
);
} else {
result = await ApiService.post(
urls.storeLabel,
this.formData
);
}
if (result && result.status == 200) {
window.location.href = "/Show/Label/" + result.data.data.id;
}
}
}
};
</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>
+283
View File
@@ -0,0 +1,283 @@
<template>
<div class>
<v-container fluid>
<material-card class color="black" title="All Labels" text>
<v-layout align-center wrap class="px-5 my-3">
<v-flex xs12 md3 sm3 class="WM-FlexCenter">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3" v-model="filter.label_id" label="Label ID" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3" v-if="$hasRole('Admin')">
<v-icon class="fa fa-hospital-o mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete
class="py-3 pr-3"
v-model="filter.medical_center_id"
@change="fillUsers"
item-text="name"
item-value="id"
label="Hospital"
color="black"
:items="medicalCenters"
:clearable="true"
></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3" v-model="filter.sterilizer_id" label="Sterilizer ID" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3" v-model="filter.cycle_number" label="Cycle Number" color="black"></v-text-field>
</v-flex>
<v-flex 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: 'AddLabel'}">
<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 wrap class="px-5 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.id }}</td>
<td
class="title font-weight-light"
>{{ (item.user && item.user.medical_center) ? item.user.medical_center.name : '' }}</td>
<td class="title font-weight-light">{{ item.user ? item.user.name : '' }}</td>
<td class="title font-weight-light">{{ item.cycle_number }}</td>
<td class="title font-weight-light">{{ item.sterilizer_id }}</td>
<td class="text-xs-right FlexBtn Height-MD-60">
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Show</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<router-link
class="LinkBtn"
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
:to="{name: 'EditLabel', params: {label: item.id}}"
>
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Edit</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn
v-bind="attrs" v-on="on"
color="pink"
class="WM-ActionButton mr-2"
@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>
</template>
<span>Remove</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" color="orange darken-1 mr-2" @click="generateBarcode(item.id, 'Label')">
<v-icon class="white--text mr-1 caption">fas fa-barcode</v-icon>
<span>Generate Barcode</span>
</v-btn>
</template>
<span>Generate Barcode</span>
</v-tooltip>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination color="black" 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: "Label ID",
value: "Label ID"
},
{
sortable: true,
text: "Hospital",
value: "Hospital"
},
{
sortable: false,
text: "User",
value: "User"
},
{
sortable: false,
text: "Cycle Number",
value: "Cycle Number"
},
{
sortable: false,
text: "SterilizerID",
value: "SterilizerID"
},
{
sortable: false,
text: "Action",
value: "action",
align: "left"
}
],
filter: {},
items: [],
medicalCenters: [],
users: [],
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.listLabel(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;
}
this.loadMedicalCenters();
},
async loadMedicalCenters() {
const result = await ApiService.get(urls.listFilterItemsTestResult);
if (result && result.status == 200) {
this.medicalCenters = result.data.data.MedicalCenters;
}
},
async fillUsers() {
const result = await ApiService.get(
urls.listOpertorMedicalCenter(this.form.medicalCenterId)
);
if (result && result.status == 200) {
this.users = result.data.data.users;
}
},
async show(testResultId) {
const result = await ApiService.get(urls.showLabel(testResultId));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-label-show",
properties: { result, width :40 }
});
}
},
async remove(testResultId) {
const result = await ApiService.delete(
urls.removeLabel(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, type) {
const result = await ApiService.post(urls.Barcode(code, type));
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, 0.87) !important;
}
.v-btn--floating,
.v-btn--icon:before {
border-radius: 50% !important;
}
</style>
+119
View File
@@ -0,0 +1,119 @@
<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-flex xs12 md3 xs3>
<v-select
:items="cities"
item-text="name_en"
item-value="id"
v-model="medicalCenter.city_id"
label="Select City"
></v-select>
</v-flex>
<v-flex xs12 md3 xs3>
<v-text-field
v-model="medicalCenter.address"
label="Address"
color="black"
class="pa-2"
:rules="[rules.required]"
></v-text-field>
</v-flex>
<v-flex xs12 md3 xs3>
<v-text-field
v-model="medicalCenter.phone_number"
label="Phone Number"
color="black"
class="pa-2"
:rules="[rules.required]"
></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: "",
address : "",
city_id : "",
phone_number : ""
},
rules: {
required: value => !!value || "Required.",
counter: value => value.length <= 30 || "Max 30 characters"
},
cities : []
};
},
created() {
if (this.$route.params.medicalCenter) {
this.load(this.$route.params.medicalCenter);
}
this.loadCities();
},
methods: {
async load(id) {
const result = await ApiService.get(urls.editMedicalCenter(id));
if (result && result.status == 200) {
this.medicalCenter = result.data.data;
}
},
async loadCities() {
const result = await ApiService.get(urls.allCities);
if (result.status == 200) {
this.cities = 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>
+162
View File
@@ -0,0 +1,162 @@
<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 FlexBtn Height-MD-80 Height-SM-48">
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<router-link class="LinkBtn" :to="{name : 'EditMedicalCenter', params : {medicalCenter : item.id}}">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Edit</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<router-link class="LinkBtn" :to="{name : 'OperatorList', params : {medicalCenter : item.id}}">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Operator</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Remove</span>
</v-tooltip>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center mt-2" v-if="lastPage > 1">
<v-pagination color="black" 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>
+201
View File
@@ -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'">Suspended</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>
+65
View File
@@ -0,0 +1,65 @@
<template>
<div class>
<v-container fluid>
<material-card class color="black" title="My Items" text>
<v-tabs centered color="cyan" dark icons-and-text>
<v-tabs-slider color="yellow"></v-tabs-slider>
<v-tab href="#tab-1">
My Items
<v-icon>fa-clone</v-icon>
</v-tab>
<v-tab href="#tab-2">
My Requests
<v-icon>fa-paper-plane</v-icon>
</v-tab>
<v-tab-item value="tab-1">
<v-card flat>
<MyItemsList />
</v-card>
</v-tab-item>
<v-tab-item value="tab-2">
<v-card flat>
<MyRequestsList />
</v-card>
</v-tab-item>
</v-tabs>
<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 CSSD-font">Back</span>
</v-btn>
</router-link>
</v-layout>
</material-card>
</v-container>
</div>
</template>
<script>
import MyItemsList from "./Tabs/MyItems.vue";
import MyRequestsList from "./Tabs/MyRequests.vue";
export default {
components: {
MyItemsList,
MyRequestsList,
}
};
</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>
+212
View File
@@ -0,0 +1,212 @@
<template>
<div>
<v-layout align-center wrap class="my-3 px-5">
<v-flex xs12 md3 sm3 class="WM-FlexCenter">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.item_id" label="Item ID" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.name" label="Name" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3" v-if="$hasRole('Admin')">
<v-icon class="fa fa-hospital-o mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete class="py-3 pr-3" v-model="filter.medical_center_id" item-text="name" item-value="id"
label="Hospital" color="black" :items="medicalCenters" :clearable="true"></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.size" label="Size" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl3">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.udi" label="UDI" color="black"></v-text-field>
</v-flex>
</v-layout>
<v-layout class="px-5 my-3">
<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 CSSD-font">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 CSSD-font">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 wrap class="my-3 px-5">
<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.id }}</td>
<!-- <td class="title font-weight-light">{{ item.unique_id }}</td> -->
<td class="title font-weight-light">{{ item.name }}</td>
<td class="title font-weight-light">{{ item.udi }}</td>
<td class="title font-weight-light">{{ item.size }}</td>
<td class="text-xs-right FlexBtn Height-MD-60">
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Show</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn class="mr-2" v-bind="attrs" v-on="on" color="orange darken-1"
@click="generateBarcode(item, 'Item')">
<v-icon class="white--text mr-2 caption">fas fa-barcode</v-icon>
<span class="CSSD-font">Generate Barcode</span>
</v-btn>
</template>
<span>Generate Barcode</span>
</v-tooltip>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination color="black" v-model="currentPage" :length="lastPage" :total-visible="6"></v-pagination>
</div>
</div>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations, mapGetters } from "vuex";
import toast from "@/services/global/toast.service";
export default {
data: () => ({
headers: [
// {
// sortable: true,
// text: "ID",
// value: "id"
// },
{
sortable: true,
text: "Item ID",
value: "id"
},
{
sortable: false,
text: "Name",
value: "name"
},
{
sortable: false,
text: "UDI",
value: "udi"
},
{
sortable: false,
text: "Size",
value: "size"
},
{
sortable: false,
text: "Action",
value: "action",
align: "left"
}
],
filter: {
name: '',
size: '',
item_id: '',
medical_center_id: ''
},
items: [],
currentPage: 1,
lastPage: 1,
medicalCenters: []
}),
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 generateBarcode(item, type = null) {
let code = item.udi;
if (code) {
const result = await ApiService.post(urls.Barcode(code, type));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
properties: { result, item },
});
}
} else {
toast.error('please first set UDI');
}
},
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 changeStatus(id) {
const result = await ApiService.post(
urls.changeItemStatus(id)
);
if (result) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == id
) {
this.items[key].status = result.data.data.status;
}
}
}
},
},
watch: {
currentPage(page) {
this.load(page);
},
}
};
</script>
+212
View File
@@ -0,0 +1,212 @@
<template>
<div>
<v-layout align-center wrap class="my-3 px-5">
<v-flex xs12 md3 sm3 class="WM-FlexCenter">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.request_id" label="Request ID" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.name" label="Name" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3" v-if="$hasRole('Admin')">
<v-icon class="fa fa-hospital-o mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete class="py-3 pr-3" v-model="filter.medical_center_id" item-text="name" item-value="id"
label="Hospital" color="black" :items="medicalCenters" :clearable="true"></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.size" label="Size" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl3">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.udi" label="UDI" color="black"></v-text-field>
</v-flex>
</v-layout>
<v-layout class="px-5 my-3">
<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 CSSD-font">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 CSSD-font">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 wrap class="my-3 px-5">
<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.id }}</td>
<!-- <td class="title font-weight-light">{{ item.unique_id }}</td> -->
<td class="title font-weight-light">{{ item.name }}</td>
<td class="title font-weight-light">{{ item.udi }}</td>
<td class="title font-weight-light">{{ item.size }}</td>
<td class="text-xs-right FlexBtn Height-MD-60">
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Show</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn class="mr-2" v-bind="attrs" v-on="on" color="orange darken-1"
@click="generateBarcode(item, 'Item')">
<v-icon class="white--text mr-2 caption">fas fa-barcode</v-icon>
<span class="CSSD-font">Generate Barcode</span>
</v-btn>
</template>
<span>Generate Barcode</span>
</v-tooltip>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination color="black" v-model="currentPage" :length="lastPage" :total-visible="6"></v-pagination>
</div>
</div>
</template>
<script>
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
import { mapMutations, mapGetters } from "vuex";
import toast from "@/services/global/toast.service";
export default {
data: () => ({
headers: [
// {
// sortable: true,
// text: "ID",
// value: "id"
// },
{
sortable: true,
text: "Item ID",
value: "id"
},
{
sortable: false,
text: "Name",
value: "name"
},
{
sortable: false,
text: "UDI",
value: "udi"
},
{
sortable: false,
text: "Size",
value: "size"
},
{
sortable: false,
text: "Action",
value: "action",
align: "left"
}
],
filter: {
name: '',
size: '',
request_id: '',
medical_center_id: ''
},
items: [],
currentPage: 1,
lastPage: 1,
medicalCenters: []
}),
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 generateBarcode(item, type = null) {
let code = item.udi;
if (code) {
const result = await ApiService.post(urls.Barcode(code, type));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
properties: { result, item },
});
}
} else {
toast.error('please first set UDI');
}
},
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 changeStatus(id) {
const result = await ApiService.post(
urls.changeItemStatus(id)
);
if (result) {
for (const key in this.items) {
if (
this.items.hasOwnProperty(key) &&
this.items[key].id == id
) {
this.items[key].status = result.data.data.status;
}
}
}
},
},
watch: {
currentPage(page) {
this.load(page);
},
}
};
</script>
+198
View File
@@ -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>
+281
View File
@@ -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>
+33
View File
@@ -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>
+269
View File
@@ -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>
+147
View File
@@ -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>
+106
View File
@@ -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>
+87
View File
@@ -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>
+141
View File
@@ -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>
+188
View File
@@ -0,0 +1,188 @@
<template>
<v-form ref="form">
<v-container grid-list-xs fluid>
<material-card color="black" title="Add Package">
<v-layout wrap class="px-5 my-3">
<v-flex xs12 md3 sm3 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field name="name" label="Name" color="black" v-model="formData.name"
:rules="[rules.required, rules.counter]" class="py-3 pr-3"></v-text-field>
</v-flex>
<!-- <v-flex xs12 md3 sm3 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
name="unique_id"
label="Package ID"
color="black"
v-model="formData.unique_id"
:rules="[rules.required, rules.counter]"
class="py-3 pr-3"
></v-text-field>
</v-flex> -->
<v-flex xs12 md12 sm12></v-flex>
<!-- <v-row style="position: relative" v-for="(item, key) in formData.items" :key="key"> -->
<v-flex xs12 md3 sm3 class="WM-FlexCenter WM-DuplicateInput" style="position: relative"
v-for="(item, key) in formData.items" :key="key">
<div class="Inner">
<v-icon class="fas fa-check mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete class="py-3 pr-3" :items="items" item-text="name" v-model="item.id"
item-value="id" label="Select Items For Package" color="black" :filter="customFilter">
<template v-slot:selection="{ item }">
{{ item.name }} - {{ item.udi }}
</template>
<template v-slot:item="{ item }">
{{ item.name }} - {{ item.udi }}
</template>
</v-autocomplete>
<v-btn absolute small right bottom color="cyan" @click="duplicateForm(key)">
<v-icon class="white--text mr-2 caption">fas fa-plus</v-icon>ADD
</v-btn>
<v-btn v-if="key > 0" absolute small right top color="pink" @click="removeForm(key)">
<v-icon class="white--text mr-2 caption">fas fa-remove</v-icon>REMOVE
</v-btn>
</div>
</v-flex>
<v-flex xs3 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field name="UDI" label="UDI" color="black" v-model="formData.udi" :rules="[rules.required]"
class="py-3"></v-text-field>
</v-flex>
<!-- </v-row> -->
<v-spacer></v-spacer>
<v-flex xs12>
<hr class="v-divider theme--light" style="margin-top:30px !important">
</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" v-model="formData.note" 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: '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: "",
note: "",
items: [
{
name: ''
}
]
},
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: {
customFilter(item, queryText) {
const name = item.name.toLowerCase();
const udi = item.udi ? item.udi.toLowerCase() : null;
const searchText = queryText.toLowerCase();
if (udi) {
return name.indexOf(searchText) > -1 ||
udi.indexOf(searchText) > -1
}
return name.indexOf(searchText) > -1
},
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" });
}
},
duplicateForm(infoIndex) {
this.formData.items.push({
name: "",
});
},
removeForm(infoIndex) {
this.formData.items.splice(infoIndex, 1);
},
}
};
</script>
<style media="screen">
.WM-DuplicateInput {
margin: 15px 0;
}
.WM-DuplicateInput .Inner {
padding: 15px 20px !important;
margin: 0 10px 0 0;
width: 100%;
border: 1px solid rgba(0, 0, 0, .2);
}
</style>
+297
View File
@@ -0,0 +1,297 @@
<template>
<div class>
<v-container fluid>
<material-card class color="black" title="All Packages" text>
<v-layout align-center wrap class="mt-3 px-5">
<v-flex xs12 md3 sm3 class="WM-FlexCenter">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.package_id" label="Package ID"
color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.name" label="Name" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3" v-if="$hasRole('Admin')">
<v-icon class="fa fa-hospital-o mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete class="py-3 pr-3" v-model="filter.medical_center_id" item-text="name"
item-value="id" label="Hospital" color="black" :items="medicalCenters"
:clearable="true"></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-spacer></v-spacer> -->
</v-layout>
<v-layout align-center wrap class="mb-3 px-5">
<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 ml-3">
<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-layout class="px-4 my-3">
<v-divider></v-divider>
</v-layout>
<v-layout align-center wrap class="my-3 px-5">
<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.id }}</td>
<!-- <td class="title font-weight-light">{{ item.unique_id }}</td> -->
<td class="title font-weight-light">{{ item.name }}</td>
<td class="title font-weight-light">{{ (item.user && item.user.medical_center) ?
item.user.medical_center.name : '' }}</td>
<td class="title font-weight-light">{{ item.user ? item.user.name : '' }}</td>
<td class="title font-weight-light">{{ item.udi }}</td>
<td class="title font-weight-light">{{ item.description }}</td>
<td class="text-xs-right FlexBtn Height-MD-60">
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Show</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<router-link class="LinkBtn"
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
:to="{ name: 'EditPackage', params: { package: item.id } }">
<v-btn v-bind="attrs" v-on="on" 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>
</template>
<span>Edit</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" color="pink" class="WM-ActionButton mr-2"
@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>
</template>
<span>Remove</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn class="mr-2" v-bind="attrs" v-on="on" color="orange darken-1"
@click="generateBarcode(item, 'Package')">
<v-icon class="white--text mr-1 caption">fas fa-barcode</v-icon>
<span>Generate Barcode</span>
</v-btn>
</template>
<span>Generate Barcode</span>
</v-tooltip>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination color="black" 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";
import toast from "@/services/global/toast.service";
export default {
data: () => ({
headers: [
// {
// sortable: true,
// text: " ID",
// value: " ID"
// },
{
sortable: true,
text: "Package ID",
value: "Package ID"
},
{
sortable: true,
text: "Name",
value: "name"
},
{
sortable: true,
text: "Hospital",
value: "Hospital"
},
{
sortable: true,
text: "User",
value: "User"
},
{
text: "UDI",
value: "udi"
},
{
sortable: true,
text: "Description",
value: "description"
},
{
sortable: false,
text: "Action",
value: "action",
align: "left"
}
],
filter: {
name: '',
package_id: '',
medical_center_id: ''
},
result: ['Pass', 'Fail'],
items: [],
currentPage: 1,
lastPage: 1,
medicalCenters: []
}),
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;
}
this.loadMedicalCenters();
},
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(item, type) {
const code = item.udi;
if (code) {
const result = await ApiService.post(urls.Barcode(code, type));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
properties: { result }
});
}
} else {
toast.error('please first set UDI');
}
},
async loadMedicalCenters() {
const result = await ApiService.get(urls.listFilterItemsTestResult);
if (result && result.status == 200) {
this.medicalCenters = result.data.data.MedicalCenters;
}
},
},
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>
+195
View File
@@ -0,0 +1,195 @@
<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 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<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 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-user mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete :items="users" item-text="name" item-value="id" v-model="form.userId" label="User" color="black" class="py-3 pr-3"></v-autocomplete>
</v-flex>
<v-flex xs12 sm4 md4 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete :items="testTypes" item-text="name" item-value="id" v-model="form.testTypeId" label="TestType" color="black" class="py-3 pr-3"></v-autocomplete>
</v-flex>
<v-flex xs12 sm4 md4 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-angle-right mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete :items="result" v-model="form.result" label="Result" color="black" class="py-3 pr-3"></v-autocomplete>
</v-flex>
<v-flex xs12 sm4 md4 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-angle-right mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete :items="verify" v-model="form.verify" label="Verify" color="black" class="py-3 pr-3"></v-autocomplete>
</v-flex>
<v-flex xs12 sm4 md4 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-line-chart mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete :items="type" v-model="form.type" label="Type" color="black" class="py-3 pr-3"></v-autocomplete>
</v-flex>
<v-flex xs12 sm6 md2 class="WM-FlexCenter pl-3">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<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"
color="black"
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 md2 class="WM-FlexCenter pl-3">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<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"
color="black"
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-spacer></v-spacer>
<v-flex xs12 md2 sm2 class="text-xs-center text-sm-center text-md-right">
<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>
+675
View File
@@ -0,0 +1,675 @@
<template>
<v-form ref="form">
<v-container grid-list-xs>
<material-card color="black" title="Submit Test Result">
<v-layout wrap class="px-5 my-3" v-if="!$route.params.testResult">
<v-flex xs12 md2 sm3 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete
:search-input.sync="searchInput"
:items="testTypeNames"
v-model="filter.name"
label="Choose Test Type"
color="black"
class="py-3 pr-3"
></v-autocomplete>
</v-flex>
<v-flex xs12 md2 sm3 class="WM-FlexCenter ml-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
name="testcode"
v-model="filter.unique_code"
label="Or Enter Test Unique Code"
color="black"
class="py-3 pr-3"
></v-text-field>
</v-flex>
<!-- <v-spacer></v-spacer> -->
<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 wrap class="px-5 my-3" v-if="form.length">
<v-flex xs12 sm12 md12>
<h3 class="WM-BorderLeftTitle">{{testTypeNameSelected}}</h3>
</v-flex>
<!-- <v-flex xs12 sm3 md3>
<v-text-field
name="id"
v-model="formData.device_id"
:label="device_label[formData.device_label]"
color="black"
class="pa-2"
prepend-icon="fas fa-sort-numeric-up"
></v-text-field>
</v-flex> -->
<v-flex xs12 sm2 md2>
<v-menu
lazy
:close-on-content-click="true"
transition="v-scale-transition"
offset-y
v-model="menu"
class="pa-2"
>
<v-text-field style="padding-top:0 !important"
prepend-icon="far fa-calendar-alt"
required
slot="activator"
label="Date"
v-model="formData.date"
color="black"
></v-text-field>
<v-date-picker
min="2020-01-01"
color="pink"
no-title
v-model="formData.date"
:date-format="date => new Date(formData.date).toDateString()"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs12 sm2 md2>
<v-switch color="light-green accent-3" v-model="result" :label="'Result: ' + formData.result"></v-switch>
</v-flex>
<v-spacer></v-spacer>
<v-flex xs12 sm12 md12>
<template v-if="galleryDataLoaded">
<wm-Dropzone :Images="galleries" :BatchID="file_batch_id" :ModelID="$route.params.testResult" ModelType="TestResult"></wm-Dropzone>
</template>
</v-flex>
</v-layout>
<!--______________________ DynamicComponent :: Began _______________________-->
<v-layout wrap class="px-5 my-3">
<v-flex :class="['pa-2', item.size]" v-for="(item, key) in form" :key="key">
<v-container row md-12 sm-12 xs-12 v-if="item.type == 'Temperature'">
<v-layout row wrap>
<h3 class="WM-BorderLeftTitle">{{ item.name }}</h3>
</v-layout>
<v-layout row wrap>
<v-container fluid class="WM-Padding-LR-0">
<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-layout>
</v-container>
<v-container row md-12 sm-12 xs-12 v-if="item.type == 'Text'">
<v-layout row wrap>
<h3 class="WM-BorderLeftTitle">{{ item.name }}</h3>
</v-layout>
<v-layout row wrap>
<v-container fluid class="WM-Padding-LR-0">
<v-text-field
v-model="formData[item.name+'_'+item.id]"
:label="item.name"
color="black"
prepend-icon="fa fa-align-left"
></v-text-field>
</v-container>
</v-layout>
</v-container>
<v-container row md-12 sm-12 xs-12 v-if="item.type == 'Pressure'">
<v-layout row wrap>
<h3 class="WM-BorderLeftTitle">{{ item.name }}</h3>
</v-layout>
<v-layout row wrap>
<v-container fluid class="WM-Padding-LR-0">
<v-flex xs12>
<v-slider
prepend-icon="fa fa-flask"
step="0.01"
v-model="formData[item.name+'_'+item.id]"
min="-1"
max="3"
thumb-label="always"
></v-slider>
</v-flex>
</v-container>
</v-layout>
</v-container>
<v-container row md-12 sm-12 xs-12 v-if="item.type == 'Select'">
<v-layout row wrap>
<h3 class="WM-BorderLeftTitle">{{ item.name }}</h3>
</v-layout>
<v-layout row wrap>
<v-container fluid class="WM-Padding-LR-0">
<v-flex xs12>
<v-select
multiple
prepend-icon="fa fa-check"
:items="item.options"
v-model="formData[item.name+'_'+item.id]"
:label="item.name"
color="black"
item-text="title"
item-value="id"
></v-select>
</v-flex>
</v-container>
</v-layout>
</v-container>
<v-container row md-12 sm-12 xs-12 v-if="item.type == 'Checkbox'">
<v-layout row wrap>
<h3 class="WM-BorderLeftTitle">{{ item.name }}</h3>
</v-layout>
<v-layout row wrap>
<v-container fluid class="WM-Padding-LR-0">
<v-flex xs12 class="WM-FlexWrap mr-3">
<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-flex>
</v-container>
</v-layout>
</v-container>
<v-container row md-12 sm-12 xs-12 v-if="item.type == 'Radiobutton'">
<v-layout row wrap>
<h3 class="WM-BorderLeftTitle">{{ item.name }}</h3>
</v-layout>
<v-layout row wrap>
<v-container fluid class="WM-Padding-LR-0">
<v-flex xs12 class="WM-FlexWrap">
<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-flex>
</v-container>
</v-layout>
</v-container>
<v-container row md-12 sm-12 xs-12 v-if="item.type == 'Switch'">
<v-layout row wrap>
<h3 class="WM-BorderLeftTitle">{{ item.name }}</h3>
</v-layout>
<v-layout row wrap>
<v-container fluid class="WM-Padding-LR-0">
<v-flex xs12>
<v-switch
color="light-green accent-3"
v-model="formData[item.name+'_'+item.id]"
:label="item.name + ': ' + formData[item.name+'_'+item.id].toString()"
></v-switch>
</v-flex>
</v-container>
</v-layout>
</v-container>
<v-container row md-12 sm-12 xs-12 v-if="item.type == 'Range'">
<v-layout row wrap>
<h3 class="WM-BorderLeftTitle">{{ item.name }}</h3>
</v-layout>
<v-layout row wrap>
<v-container fluid class="WM-Padding-LR-0">
<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"
color="black"
prepend-icon="fa fa-sliders"
></v-slider>
</v-flex>
</v-container>
</v-layout>
</v-container>
<v-container row md-12 sm-12 xs-12 v-if="item.type == 'Time'">
<v-layout row wrap>
<h3 class="WM-BorderLeftTitle">{{ item.name }}</h3>
</v-layout>
<v-layout row wrap>
<v-container fluid class="WM-Padding-LR-0">
<v-flex xs12>
<v-text-field
v-model="formData[item.name+'_'+item.id]"
:label="item.name"
class="WM-Font-30"
mask="##:##"
color="black"
prepend-icon="fa fa-clock-o"
></v-text-field>
</v-flex>
</v-container>
</v-layout>
</v-container>
<!-- <v-layout row wrap>
<template v-if="item.type == 'Form'"> -->
<v-container row md-12 sm-12 xs-12 class="WM-Border WM-Border-LightGray WM-Padding-10 WM-BorderRadius-5" v-if="item.type == 'Form'">
<v-layout row wrap>
<h3 class="WM-BorderLeftTitle">{{ 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-container fluid v-if="children.type == 'Text'" class="WM-Padding-LR-0">
<p>{{ children.name }}</p>
<v-flex xs12>
<v-text-field
prepend-icon="fa fa-align-left"
v-model="formData[children.name+'_'+children.id]"
:label="children.name"
color="black"
></v-text-field>
</v-flex>
</v-container>
<v-container fluid v-if="children.type == 'Temperature'" class="WM-Padding-LR-0">
<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 fluid v-if="children.type == 'Pressure'" class="WM-Padding-LR-0">
<p>{{ children.name }}</p>
<v-flex xs12>
<v-slider
prepend-icon="fa fa-flask"
v-model="formData[children.name+'_'+children.id]"
min="-1"
step="0.01"
max="3"
thumb-label="always"
></v-slider>
</v-flex>
</v-container>
<v-container fluid v-if="children.type == 'Select'" class="WM-Padding-LR-0">
<p>{{ children.name }}</p>
<v-flex xs12>
<v-select
multiple
prepend-icon="fa fa-check"
:items="children.options"
v-model="formData[children.name+'_'+children.id]"
:label="children.name"
color="black"
item-text="title"
item-value="id"
></v-select>
</v-flex>
</v-container>
<v-container fluid v-if="children.type == 'Checkbox'" class="WM-Padding-LR-0">
<p>{{ children.name }}</p>
<v-flex xs12 class="WM-FlexWrap mr-3">
<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-flex>
</v-container>
<v-container fluid v-if="children.type == 'Radiobutton'" class="WM-Padding-LR-0">
<p>{{ children.name }}</p>
<v-flex xs12 class="WM-FlexWrap">
<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-flex>
</v-container>
<v-container fluid v-if="children.type == 'Switch'" class="WM-Padding-LR-0">
<p>{{ children.name }}</p>
<v-flex xs12>
<v-switch
color="light-green accent-3"
v-model="formData[children.name+'_'+children.id]"
:label="children.name + ': ' + formData[children.name+'_'+children.id].toString()"
></v-switch>
</v-flex>
</v-container>
<v-container fluid v-if="children.type == 'Range'" class="WM-Padding-LR-0">
<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"
prepend-icon="fa fa-check"
></v-slider>
</v-flex>
</v-container>
<v-container fluid v-if="children.type == 'Time'" class="WM-Padding-LR-0">
<p>{{ children.name }}</p>
<v-flex xs12>
<v-text-field
v-model="formData[children.name+'_'+children.id]"
:label="children.name"
class="WM-Font-30"
mask="##:##"
prepend-icon="fa fa-clock-o"
></v-text-field>
</v-flex>
</v-container>
</v-flex>
</v-layout>
</v-container>
<!-- </template>
</v-layout> -->
</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: 'AllResultTest'}">
<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 Dropzone from '@/components/core/Dropzone'
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
export default {
components : {
'wm-Dropzone' : Dropzone,
},
data: () => ({
galleryDataLoaded: false,
galleries: [],
file_batch_id: Math.floor(Math.random() * 9000000000) + 1000000000,
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: "",
date : "2020-01-01"
},
images: [],
menu: "",
device_label: {
WasherID: "Washer ID",
AutoclaveID: "Autoclave ID",
SterilizerID: "Sterilizer ID",
WasherMachineID: "WasherMachine ID",
SealMachineID: "SealMachine ID",
PatientID: "Patient ID",
"Set/PackID": "Set/Pack ID",
MDID: "MD ID",
ORID: "OR ID",
PersonalID: "Personal ID",
InstrumentID: "Instrument ID",
ID: "ID"
}
}),
created() {
if (this.$route.params.testResult) {
this.filter.test_result_id = this.$route.params.testResult;
this.selectTestType();
}
else{
this.galleryDataLoaded= true;
}
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;
this.galleries = result.data.data.filesPath;
this.galleryDataLoaded = true;
}
}
}
},
async submitForm() {
let result;
this.formData['file_batch_id'] = this.file_batch_id;
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(.light-green--text) {
/* color: #F44336 !important; */
color: #ed1c24;
}
.v-input--switch__thumb:not(.light-green--text) {
/* background-color: #F44336 !important; */
background-color: #ed1c24;
}
.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;
}
.v-input--selection-controls__input {
margin-right :0;
}
.v-input--radio-group--column .v-radio:not(:last-child):not(:only-child) {
margin-bottom : 0;
}
.v-input--radio-group--column .v-input--radio-group__input {
flex-direction: row;
}
.v-input--selection-controls .v-input__control {
margin-right: 12px;
}
.v-input--selection-controls__input {
margin-right: 7px;
}
.accent--text {
color: #E91E63 !important;
caret-color: #E91E63 !important;
}
.WM-Padding-LR-0 {
padding:24px 0;
}
.WM-BorderLeftTitle {
border-left: 1px solid;
padding-left: 5px;
}
</style>
+447
View File
@@ -0,0 +1,447 @@
<template>
<div class>
<v-container fluid>
<material-card class color="black" title="All Test Result" text>
<v-layout align-center wrap class="px-5 mb-3 my-3">
<v-flex xs12 md2 sm3 class="WM-FlexCenter">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.device_id" label="ID" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete :items="deviceLabels" item-text="name" item-value="id" v-model="filter.device_label" label="ID Label" color="black" class="py-3 pr-3" :clearable="true"></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete class="py-3 pr-3" 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 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-hospital-o mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete class="py-3 pr-3" v-model="filter.medicalCenter_id" label="Hospital" color="black" :items="medicalCenters" item-text="name" item-value="id" :clearable="true"></v-autocomplete>
</v-flex>
<v-flex xs12 md2 sm3 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" v-model="filter.user_name" label="User Name" color="black"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md2 pl-3 class="WM-FlexCenter">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<v-menu lazy :close-on-content-click="true" transition="v-scale-transition" offset-y v-model="fromMenu">
<v-text-field class="py-3 pr-3" required slot="activator" label="FromDate" v-model="filter.fromPicker" color="black"></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 md2 pl-3 style="display: flex;align-items: center;">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<v-menu lazy :close-on-content-click="true" transition="v-scale-transition" offset-y v-model="upToMenu">
<v-text-field class="py-3 pr-3" required slot="activator" label="UpToDate" color="black" 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 class="WM-XL-Align-L text-lg-left">
<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 wrap xs12 md2 sm2 class="WM-Align-R">
<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-layout wrap class="px-5 mb-3 my-3">
<!-- <v-flex class xs12 md3 sm3 class="WM-XL-Align-L text-lg-left">
<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 wrap xs12 md2 sm2 class="WM-Align-R">
<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-layout class="px-4 my-3">
<v-divider></v-divider>
</v-layout>
<v-layout align-center wrap class="px-5 my-2">
<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.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">
<span v-if="item.result == 'Reject'" class="ResultMsg Reject">
{{ item.result }}
</span>
<span v-else-if="item.result == 'Accept'" class="ResultMsg Accept">
{{ item.result }}
</span>
</td>
<td class="title font-weight-light">{{ item.created_at }}</td>
<td class="title font-weight-light">
<span v-if="item.verified == 'NotVerified'" class="NotVerified">
<v-icon class="caption fa fa-times NotVerified"></v-icon>
</span>
<span v-if="item.verified == 'Verified'" class="">
<v-icon class="caption fa fa-check Verified"></v-icon>
</span>
<!-- {{ item.verified }} -->
</td>
<td class="text-xs-right FlexBtn">
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn color="cyan" class="mr-2" @click="show(item.id)" v-bind="attrs" v-on="on">
<v-icon class="white--text mr-1 caption">fas fa-eye</v-icon>
<span>Show</span>
</v-btn>
</template>
<span>Show</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn color="orange" class="mr-2" @click="generateBarcode(item.id, 'TestResult')" v-bind="attrs" v-on="on">
<v-icon class="white--text mr-1 caption">fa fa-bars</v-icon>
<span>generate Barcode</span>
</v-btn>
</template>
<span>generate Barcode</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<!-- v-if="$hasRole('Admin') || item.user_id == $store.state.user.id" -->
<router-link class="LinkBtn" v-if="$hasRole('Admin') || (item.user_id == $store.state.user.id && item.verified == 'None')" :to="{name: 'EditTestResult', params: {testResult: item.id}}">
<v-btn color="orange" class="mr-2" v-bind="attrs" v-on="on">
<v-icon class="white--text mr-1 caption">fas fa-pen</v-icon>
<span>Edit</span>
</v-btn>
</router-link>
</template>
<span>Edit</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<!-- v-if="$hasRole('Admin') || item.user_id == $store.state.user.id" -->
<v-btn color="pink" class="WM-ActionButton" @click="remove(item.id)" v-if="$hasRole('Admin') || (item.user_id == $store.state.user.id && item.verified == 'None')" v-bind="attrs" v-on="on">
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
<span>Remove</span>
</v-btn>
</template>
<span>Remove</span>
</v-tooltip>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center mt-2" v-if="lastPage > 1">
<v-pagination color="black" 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: "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: "left"
}
],
filter: {
device_id: '',
testType_id: '',
medicalCenter_id: '',
user_name: '',
fromPicker: '',
upToPicker: '',
device_label: ''
},
fromMenu: '',
upToMenu: '',
items: [],
currentPage: 1,
lastPage: 1,
testTypes: [],
medicalCenters: [],
deviceLabels: [{
name: "Washer ID",
id: "Washer ID"
},
{
name: "Autoclave ID",
id: "Autoclave ID"
},
{
name: "Sterilizer ID",
id: "Sterilizer ID"
},
{
name: "Seal Machine ID",
id: "Seal Machine ID"
},
{
name: "Patiant ID",
id: "Patiant ID"
},
{
name: "Set/Pack ID",
id: "Set/Pack ID"
},
{
name: "Medical Device ID",
id: "Medical Device ID"
},
{
name: "OR ID",
id: "OR ID"
},
{
name: "Personal ID",
id: "Personal ID"
},
{
name: "Instrument ID",
id: "Instrument ID"
},
{
name: "Basket ID",
id: "Basket ID"
},
{
name: "Implant ID",
id: "Implant ID"
},
]
}),
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, type) {
const result = await ApiService.post(urls.Barcode(id, type));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
properties: {
result
}
});
}
}
},
computed: {
...mapGetters("modal", ["getModalResult"])
},
watch: {
currentPage(page) {
if (this.$route.name == "NotVerifyTestResult") {
this.load(page, "NotVerified,None");
} else {
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].verified = testResult.verified;
}
}
}
}
};
</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;
}
/* --------------------------------------------------------
Tables :: Begin
-------------------------------------------------------- */
@media screen and (max-width: 1536px) {
.v-card .title {
font-size: 0.9rem !important;
}
}
/* .FlexBtn {
display: flex;
flex-wrap: nowrap;
padding: 10px 8px !important;
}
td.FlexBtn .theme--light.v-btn {
padding: 21px 20px;
}
td.FlexBtn a.LinkBtn .theme--light.v-btn {
padding: 12px 10px;
}
@media screen and (max-width:1536px) {
.FlexBtn {
padding: 30px 8px !important;
}
td.FlexBtn span {
display: none;
}
td.FlexBtn .theme--light.v-btn {
min-width: 30px;
padding: 15px 10px;
margin-right: 1 !important;
}
td.FlexBtn a.LinkBtn .theme--light.v-btn {
padding: 9px 10px;
}
td.FlexBtn .theme--light.v-icon {
margin-right: 0 !important;
}
} */
</style>
+183
View File
@@ -0,0 +1,183 @@
<template>
<v-container grid-list-xs>
<material-card color="black" title="Show Test Result" id="printMe">
<v-layout align-left justify-left wrap class="px-5 my-3">
<h3 class="ml-3">Common Info</h3>
<v-flex xs12>
<hr class="v-divider theme--light" />
</v-flex>
<v-layout row wrap class="ml-4">
<v-flex xs12 md6 sm6>
<div class>
<span class="title">{{ data.device_label || 'AutoclaveID' }} :</span>
<span class="headline SCCD-font ml-2" style="letter-spacing:0 !important">{{ data.device_id }}</span>
</div>
</v-flex>
<v-flex xs12 md6 sm6>
<div class>
<span class="title">Result :</span>
<v-icon class="green--text ml-2 caption">fas fa-check</v-icon>
<span class="headline SCCD-font ml-1" style="letter-spacing:0 !important">{{ data.result }}</span>
</div>
</v-flex>
<v-flex xs12 md6 sm6>
<div class>
<span class="title">verify :</span>
<v-icon class="pink--text ml-2 caption">fas fa-times</v-icon>
<span class="headline SCCD-font ml-1" style="letter-spacing:0 !important">{{ data.verified }}</span>
</div>
</v-flex>
<v-flex xs12 md6 sm6>
<div class>
<span class="title">Register User :</span>
<span class="headline SCCD-font ml-2" style="letter-spacing:0 !important">{{ data.user.name }}</span>
</div>
</v-flex>
<v-flex xs12 md6 sm6>
<div class>
<span class="title">Date :</span>
<span class="headline SCCD-font ml-2" style="letter-spacing:0 !important">{{ data.created_at }}</span>
</div>
</v-flex>
<v-flex xs12 md6 sm6>
<div class>
<span class="title">Medical Center :</span>
<span
class="headline SCCD-font ml-2"
style="letter-spacing:0 !important"
>{{ data.user.medical_center.name }}</span>
</div>
</v-flex>
</v-layout>
</v-layout>
<v-layout align-left justify-left wrap class="px-5 my-3">
<h3 class="ml-3">Special Info</h3>
<v-flex xs12>
<hr class="v-divider theme--light" />
</v-flex>
<v-layout row wrap class="ml-4">
<template v-if="data.inputs">
<v-flex xs12 md6 sm6 v-for="(inputData, keyInputs) in data.inputs" :key="keyInputs">
<span class="title">{{keyInputs}} :</span>
<span class="headline SCCD-font ml-2" style="letter-spacing:0 !important">{{inputData}}</span>
</v-flex>
</template>
<template v-if="data.options">
<v-flex xs12 md6 sm6 v-for="(optionData, keyOptions) in data.options" :key="keyOptions">
<span class="title">{{keyOptions}} :</span>
<span
style="letter-spacing:0 !important"
class="headline SCCD-font ml-2"
v-for="(data, dataKey) in optionData"
:key="dataKey"
>{{data}},</span>
</v-flex>
</template>
<template v-if="data.children">
<v-flex xs12 md6 sm6 v-for="(formData, keyForm) in data.children" :key="keyForm">
<h3 class="ml-3">{{keyForm}}</h3>
<div v-for="(childData, keyChild) in formData" :key="keyChild">
<div class="ml-4">
<span class="title">{{keyChild}} :</span>
<template v-if="Array.isArray(childData)">
<span
style="letter-spacing:0 !important"
class="headline SCCD-font ml-2"
v-for="(data, dataKey) in childData"
:key="dataKey"
>{{data}},</span>
</template>
<template v-else>
<span class="headline SCCD-font ml-2">{{childData}}</span>
</template>
</div>
</div>
</v-flex>
</template>
</v-layout>
</v-layout>
<v-layout align-left justify-left wrap class="px-5 my-3">
<h3 class="ml-3">Image</h3>
<v-flex xs12>
<hr class="v-divider theme--light" />
</v-flex>
<v-layout row wrap class="ml-4">
<!-- <LightBox :media="data.title_image.map(img => img.path)"></LightBox> -->
<!-- <v-flex xs12 md6 sm6 v-for="(img, key) in data.title_image" :key="key">
<img :src="'/'+img.path" style="width: 20%;height:auto" />
</v-flex> -->
</v-layout>
</v-layout>
</material-card>
<material-card>
<v-layout row wrap align-center justify-center >
<v-flex class xs12 md2 sm2>
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Gray" @click="print">
<v-icon class="black--text mr-2 caption">fas fa-print</v-icon>
<span class="black--text">Print</span>
</v-btn>
</v-flex>
</v-layout>
</material-card>
</v-container>
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
import { ApiService } from "@/services";
import { urls } from "@/config/urls";
export default {
data: () => ({
data: {
user: {
medical_center: {}
}
}
}),
methods: {
print() {
const prtHtml = document.getElementById("printMe").innerHTML;
// Get all stylesheets HTML
let stylesHtml = "";
for (const node of [
...document.querySelectorAll('link[rel="stylesheet"], style')
]) {
stylesHtml += node.outerHTML;
}
// Open the print window
const WinPrint = window.open(
"",
"",
"left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0"
);
WinPrint.document.write(`<!DOCTYPE html>
<html>
<head>
${stylesHtml}
</head>
<body>
${prtHtml}
</body>
</html>`);
WinPrint.document.close();
WinPrint.focus();
WinPrint.print();
WinPrint.close();
},
async load() {
const result = await ApiService.get(
urls.showTestResult(this.$route.params.testResult)
);
if (result && result.status == 200) {
this.data = result.data.data;
}
}
},
created() {
this.load();
}
};
</script>
+603
View File
@@ -0,0 +1,603 @@
<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 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
name="name"
v-model="form.name"
label="Name"
color="black"
class="py-3 pr-3"
:rules="[rules.required]"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
:rules="[rules.required]"
name="uniquecode"
v-model="form.unique_code"
label="Unique Code"
color="black"
class="py-3 pr-3"
></v-text-field>
</v-flex>
<!-- <v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete
:rules="[rules.required]"
:items="deviceLabels"
item-text="name"
item-value="id"
v-model="form.device_label"
label="ID Label"
color="black"
class="py-3 pr-3"
></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 WM-Width-Full">
<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]"
prepend-icon="fa fa-align-left"
></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"
prepend-icon="fa fa-filter"
@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"
prepend-icon="fa fa-sort-numeric-asc"
></v-select>
</v-flex>
<v-flex xs12 md3 sm3 v-if="info.type == 'Text'">
<v-layout row wrap>
<v-flex xs12 class="WM-FlexWrap ml-3">
<v-checkbox
label="require barcode scanner"
v-model="info.require_scanner"
></v-checkbox>
</v-flex>
</v-layout>
</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"
prepend-icon="fa fa-align-left"
></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"
prepend-icon="fa fa-angle-right"
></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"
prepend-icon="fa fa-angle-right"
></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 WM-Width-Full"
>
<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"
prepend-icon="fa fa-align-left"
></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)"
prepend-icon="fa fa-filter"
></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"
prepend-icon="fa fa-sort-numeric-asc"
></v-select>
</v-flex>
<v-flex xs12 md3 sm3 v-if="children.type == 'Text'">
<v-layout row wrap>
<v-flex xs12 class="WM-FlexWrap ml-3">
<v-checkbox
label="require barcode scanner"
v-model="children.require_scanner"
></v-checkbox>
</v-flex>
</v-layout>
</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]"
prepend-icon="fa fa-align-left"
></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="{name : 'ListTestType'}">
<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: "",
require_scanner: false
}
]
},
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 sm4 xs12" },
{ state: "3 from 12", abbr: "md3 sm6 xs12" },
{ state: "4 from 12", abbr: "md4 sm4 xs12" },
{ state: "6 from 12", abbr: "md6 sm12 xs12" },
{ state: "8 from 12", abbr: "md8 sm8 xs12" },
{ state: "10 from 12", abbr: "md10 sm10 xs12" },
{ state: "12 from 12", abbr: "md12 sm12 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 == "Text"){
// //--add checkbox
// }
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: `ListTestType` });
// }
}
},
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>
+274
View File
@@ -0,0 +1,274 @@
<template>
<v-container fluid>
<material-card class color="black" title="TestType List" text>
<v-layout wrap class="px-5 mb-3">
<v-flex xs12 md3 sm3 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" label="Name" v-model="filter.name" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" label="UniqueId" v-model="filter.unique_id" color="black"></v-text-field>
</v-flex>
<v-flex xs12 md36 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field class="py-3 pr-3" label="UserName" v-model="filter.user_name" color="black"></v-text-field>
</v-flex>
</v-layout>
<v-layout wrap class="px-5 mb-3">
<v-flex xs12 sm6 md2 class="WM-FlexCenter">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<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"
color="black"
></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 md2 class="WM-FlexCenter pl-3">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<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"
color="black"
></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 ml-4">
<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 FlexBtn">
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<router-link class="LinkBtn"
v-if="item.test_results_count == 0"
:to="{name : 'EditTestType', params : {testType : item.id}}"
>
<v-btn color="cyan" class="mr-2 WM-ActionButton" v-bind="attrs"
v-on="on">
<v-icon class="white--text mr-2 caption">fas fa-pen</v-icon>
<span>Edit</span>
</v-btn>
</router-link>
</template>
<span>Edit</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn color="black" class="mr-2" @click="remove(item.id)" v-bind="attrs"
v-on="on">
<v-icon class="white--text mr-1 caption">fas fa-folder</v-icon>
<span>Archive</span>
</v-btn>
</template>
<span>Archive</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn color="orange darken-1" @click="generateBarcode(item.unique_code, 'TestType')" v-bind="attrs"
v-on="on">
<v-icon class="white--text mr-1 caption">fas fa-barcode</v-icon>
<span>Generate Barcode</span>
</v-btn>
</template>
<span>Generate Barcode</span>
</v-tooltip>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center mt-2" v-if="lastPage > 1">
<v-pagination color="black" 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";
import { mapMutations, mapGetters } from "vuex";
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: {
...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.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);
}
}
}
},
async generateBarcode(code, type) {
const result = await ApiService.post(urls.Barcode(code, type));
if (result && result.status == 200) {
this.changeCurrentModal({
modal: "modal-barcode-barcode",
properties: { result }
});
}
}
},
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>
+217
View File
@@ -0,0 +1,217 @@
<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 mr-4">
<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-left FlexBtn">
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn
color="cyan"
@click="showmessages(item.id)"
class="WM-ActionButton"
v-bind="attrs"
v-on="on"
>
<v-icon class="white--text mr-2 caption">fas fa-eye</v-icon>
<span>Show Message</span>
</v-btn>
</template>
<span>Show Message</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn
color="pink"
@click="remove(item.id)"
class="WM-ActionButton"
v-bind="attrs"
v-on="on"
>
<v-icon class="white--text mr-2 caption">fas fa-trash</v-icon>
<span>delete</span>
</v-btn>
</template>
<span>delete</span>
</v-tooltip>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider></v-divider>
<div class="text-xs-center" v-if="lastPage > 1">
<v-pagination color="black" 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: "left"
}
],
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>
+355
View File
@@ -0,0 +1,355 @@
<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 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
class="py-3 pr-3"
color="black"
name="name"
label="Name"
v-model="filter.name"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-hospital-o mr-2 WM-Margin-B-8"></v-icon>
<v-autocomplete
class="py-3 pr-3"
v-model="filter.medical_center_id"
label="Hospital"
color="black"
:items="medicalCenters"
item-text="name"
item-value="id"
></v-autocomplete>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-phone mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
class="py-3 pr-3"
color="black"
name="CellPhone"
label="CellPhone"
v-model="filter.cell_number"
></v-text-field>
</v-flex>
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-check mr-2 WM-Margin-B-8"></v-icon>
<v-select
class="py-3 pr-3"
color="black"
name="role"
label="Role"
:items="roles"
v-model="filter.role"
></v-select>
</v-flex>
</v-layout>
<v-layout class="px-5 mb-3">
<v-flex xs12 sm12 md2 class="WM-FlexCenter">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<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"
color="black"
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 sm12 md2 class="WM-FlexCenter pl-3">
<v-icon class="far fa-calendar-alt mr-2"></v-icon>
<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"
color="black"
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-spacer></v-spacer> -->
<v-flex wrap xs12 md2 sm12 class="WM-Align-R ml-4">
<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 FlexBtn">
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn
v-bind="attrs" v-on="on"
:color="item.status == 'Active' ? 'green' : 'red'"
@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">fa fa-pause</v-icon>
<span v-if="item.status == 'Active'">Suspended</span>
</template>
<template v-else>
<v-icon class="white--text mr-2 caption">fa fa-pause</v-icon>
<span>Active</span>
</template>
</v-btn>
</template>
<span v-if="item.status == 'Active'">Suspended</span>
<span v-else>Active</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn
v-bind="attrs" v-on="on"
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>
</template>
<span>Role</span>
</v-tooltip>
<v-tooltip bottom open-on-hover>
<template v-slot:activator="{ on, attrs }">
<v-btn
v-bind="attrs" v-on="on"
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>
</template>
<span>Remove</span>
</v-tooltip>
</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 mt-2" v-if="lastPage > 1">
<v-pagination
color="black"
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: "",
medical_center_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>
+146
View File
@@ -0,0 +1,146 @@
<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 md4 sm4 class="WM-FlexCenter">
<v-icon class="fa fa-align-left mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
name="name"
label="Name"
color="black"
v-model="user.name"
:rules="[rules.required, rules.counter]"
class="py-3 pr-3"
></v-text-field>
</v-flex>
<v-flex xs12 sm4 md4 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-male mr-2 WM-Margin-B-8"></v-icon>
<v-select
:items="items"
label="Gender"
name="gender"
v-model="user.gender"
single-line
:rules="[rules.required]"
class="py-3 pr-3"
color="black"
></v-select>
</v-flex>
<v-flex xs12 sm4 md4 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-phone mr-2 WM-Margin-B-8"></v-icon>
<v-text-field
name="cellnumber"
label="Cell Number"
v-model="user.cell_number"
color="black"
class="py-3 pr-3"
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 class="WM-FlexCenter pl-3">
<v-icon class="fa fa-envelope mr-2 WM-Margin-B-8" style="margin-top:70px"></v-icon>
<v-text-field
name="emailaddress"
label="Email Address"
v-model="user.email"
:rules="[rules.email]"
class="px-2"
color="black"
style="margin-top:72px"
></v-text-field>
</v-flex>
<v-flex xs12 sm8 md8>
<v-textarea
prepend-icon="fa fa-sort-amount-desc"
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 md3 sm3 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 mr-1">fas fa-refresh</v-icon>
<span class="black--text"> Change Password </span>
</v-btn>
</v-flex>
<v-flex xs12 md1 sm1 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>