Initial import

This commit is contained in:
sas.fajri
2026-04-27 10:08:27 +07:00
commit 01c2963a43
356 changed files with 197152 additions and 0 deletions

118
mockup/fo/fo02/api.js Normal file
View File

@@ -0,0 +1,118 @@
// API :
// search bank
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t02/search_bank";
// export async function searchBank(query, page, rowPerPage = 15) {
// try {
// var resp = await axios.post(URL, {
// query: query,
// page: page,
// rowPerPage: rowPerPage
// });
// if (resp.status != 200) {
// return {
// status: "ERR",
// query: query,
// message: resp.statusText
// };
// }
// let data = resp.data;
// data.query = query;
// return data;
// } catch (e) {
// return {
// status: "ERR",
// query: query,
// message: e.message
// };
// }
// }
async function searchPatient(query, page, rowPerPage = 15) {
try {
if (page == 1) {
return {
query:query,
rows:[
{"nolab":"1902010001", "mr": "MR-18107237", "name": "Pasien Umum", "sex": "Perempuan", "address": "Klero\r\nKabupaten Semarang", "action":"", "selected":false},
{"nolab":"1902010002", "mr": "MR-18107238", "name": "Heri Suryawan", "sex": "Laki - laki", "address": "Ampel", "action":"", "selected":false},
{"nolab":"1902010003", "mr": "MR-18107239", "name": "LUKA MODRIC", "sex": "Laki - laki", "address": "Jl. Raya No 1", "action":"", "selected":false},
{"nolab":"1902010004", "mr": "MR-18107247", "name": "Tyas Medika Pranandita", "sex": "Laki - laki", "address": "KP. Karangpanas", "action":"", "selected":false},
{"nolab":"1902010005", "mr": "MR-18107248", "name": "Astrid", "sex": "Perempuan", "address": "Jl. Ketintang Raya No.81", "action":"", "selected":false},
{"nolab":"1902010006", "mr": "MR-18107249", "name": "Happy", "sex": "Perempuan", "address": "Karangpanas", "action":"", "selected":false},
{"nolab":"1902010007", "mr": "MR-18107251", "name": "Juan Alexis Sukir", "sex": "Laki - laki", "address": "Jl. Sawi", "action":"", "selected":false},
{"nolab":"1902010008", "mr": "MR-18107252", "name": "Alexander Wang", "sex": "Laki - laki", "address": "Jl. Mangga Muda No. 7", "action":"", "selected":false},
{"nolab":"1902010009", "mr": "MR-18107253", "name": "CILA CILANI", "sex": "Perempuan", "address": "Jl. Duren PInang No. 67", "action":"", "selected":false},
{"nolab":"1902010010", "mr": "MR-18107254", "name": "Untung Suropati", "sex": "Laki - laki", "address": "Pasar Kapling Semarang", "action":"", "selected":false}
],
page:1,
totalPage:2,
totalRecord:11,
midPages:1
}
} else if (page == 2) {
return {
query:query,
rows:[
{"nolab":"1902010011", "mr": "MR-18107255", "name": "M. Althaf Prawira Ananta", "sex": "Laki - laki", "address": "KP Karangpanas No 11", "action":"", "selected":false}
],
page:2,
totalPage:2,
totalRecord:11,
midPages:1
}
}
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}
async function searchPx(query, page, rowPerPage = 15) {
try {
// if (page == 1) {
return {
query:query,
rows:[
{"code": "0101", "name": "Hemoglobin"},
{"code": "0102", "name": "Leukosit"},
{"code": "0103", "name": "Eritrosit"},
// {"code": "0104", "name": "Trombosit"},
// {"code": "0105", "name": "Hematokrit"}
],
page:1,
totalPage:1,
totalRecord:5,
midPages:1
}
// } else if (page == 2) {
// return {
// query:query,
// rows:[
// {"nolab":"1902010011", "mr": "MR-18107255", "name": "M. Althaf Prawira Ananta", "sex": "Laki - laki", "address": "KP Karangpanas No 11", "action":""}
// ],
// page:2,
// totalPage:2,
// totalRecord:11,
// midPages:1
// }
// }
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}
export {
searchPatient,
searchPx
}

View File

@@ -0,0 +1,45 @@
var detailPatientComponent = {
template : `
<v-flex xs4 pt-1 pl-3 pr-3>
<v-text-field
v-model="p_mr"
label="MR"
readonly
></v-text-field>
<v-text-field
v-model="p_name"
label="Name"
readonly
></v-text-field>
<v-text-field
v-model="p_dob"
label="DOB / Age"
readonly
></v-text-field>
</v-flex>`,
data() {
return {
query: ""
};
},
computed : {
p_mr() {
// return "*";
return this.$store.state.patient.currSelected.mr;
},
p_name() {
// return "*";
return this.$store.state.patient.currSelected.name;
},
p_dob() {
// return "*";
return this.$store.state.patient.currSelected.dob;
}
}
}
export { detailPatientComponent }

View File

@@ -0,0 +1,135 @@
var listPatientComponent = {
template: `
<v-card class="xs12 md12 mt-2" >
<v-data-table :headers="headers" :items="patients"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':props.item.selected}" @click="selectMe(props.item)">{{ props.item.nolab }}</td>
<td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':props.item.selected}" @click="selectMe(props.item)">{{ props.item.mr }}</td>
<td class="pa-2" v-bind:class="{'amber lighten-4':props.item.selected}" @click="selectMe(props.item)">{{ props.item.name }}</td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "LAB NUMBER",
align: "left",
sortable: false,
value: "nolab",
width: "25%",
class: "pa-2 blue lighten-3 white--text"
},
{
text: "MR",
align: "left",
sortable: false,
value: "mr",
width: "25%",
class: "pa-2 blue lighten-3 white--text"
},
{
text: "NAME",
align: "left",
sortable: false,
value: "name",
class: "pa-2 blue lighten-3 white--text"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("patient/searchPatient", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
},
selectMe(item) {
this.$store.dispatch('patient/selectMe', item);
// let rows = this.$store.state.patient.rows;
// for (let i in rows) {
// // console.log(i);
// rows[i].selected = false;
// if (i.mr == item.mr) {
// rows[i].selected = true;
// }
// }
// this.$store.state.patient.rows = rows;
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.patient.isLoading,
isError: state => state.patient.isError,
errorMessage: state => state.patient.errorMessage,
patients: state => state.patient.rows,
totalRecord: state => state.patient.totalRecord,
page: state => state.patient.page,
totalPage: state => state.patient.totalPage
}),
isSelected() {
// for(let i of rows) {
// if (i.mr == "MR-18107238");
// return true;
// }
return false;
}
},
updated() {
console.log("Component Updated");
}
};
export { listPatientComponent };

View File

@@ -0,0 +1,90 @@
var listPxComponent = {
template: `
<v-card class="xs12 md12 mt-2" >
<v-data-table :headers="headers" :items="patients"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td class="text-xs-left pa-2 blue lighten-5">{{ props.item.code }}</td>
<td class="text-xs-left pa-2 blue lighten-5">{{ props.item.name }}</td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "CODE",
align: "left",
sortable: false,
value: "code",
width: "30%",
class: "pa-2 blue lighten-3 white--text"
},
{
text: "NAME",
align: "left",
sortable: false,
value: "name",
width: "70%",
class: "pa-2 blue lighten-3 white--text"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("px/searchPx", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.px.isLoading,
isError: state => state.px.isError,
errorMessage: state => state.px.errorMessage,
patients: state => state.px.rows,
totalRecord: state => state.px.totalRecord,
page: state => state.px.page,
totalPage: state => state.px.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listPxComponent };

View File

@@ -0,0 +1,27 @@
var sampleStationComponent = {
props : ['label'],
template : `
<v-select
:items="items"
:label="_label"
></v-select>`,
data () {
return {
items: ['Laboratorium', 'Lain - lain']
}
},
computed : {
_label () {
if (this.label)
return this.label;
return "Sample Station";
}
}
}
export { sampleStationComponent }

View File

@@ -0,0 +1,38 @@
var smartNavbarComponent = {
template: `
<span>
<v-navigation-drawer v-model="drawer" fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>home</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Home</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>contact_mail</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Contact</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar color="blue lighten-2" dark fixed app>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title>SAMPLING</v-toolbar-title>
</v-toolbar>
</span>
`,
data: function() {
return {
drawer: false
};
},
methods: {}
};
export { smartNavbarComponent };

View File

@@ -0,0 +1,49 @@
var startDateComponent = {
props : ['label'],
template : `
<v-menu
v-model="menu2"
:close-on-content-click="false"
:nudge-right="40"
lazy
transition="scale-transition"
offset-y
full-width
min-width="290px"
>
<v-text-field
slot="activator"
v-model="datez"
:label="labels"
prepend-icon="event"
readonly
>
</v-text-field>
<v-date-picker v-model="datez" @input="menu2 = false" prev-icon="false"></v-date-picker>
</v-menu>
`,
data () {
return {
datez: new Date().toISOString().substr(0, 10),
menu: false,
modal: false,
menu2: false
}
},
computed : {
labels() {
if (this.label) {
return this.label;
} else
return "Start Date";
}
}
}
export { startDateComponent };

247
mockup/fo/fo02/index.php Normal file
View File

@@ -0,0 +1,247 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ONE</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
<style>
table.v-table tbody td,table.v-table tbody th {
height: 40px;
}
table.v-table thead tr {
height: 40px;
}
</style>
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp">
<smart-navbar></smart-navbar>
<v-content class="blue lighten-5">
<v-container fluid fill-height style="height:inherit" pa-2>
<v-layout row wrap>
<v-flex xs12>
<template>
<v-tabs
centered
color="blue lighten-3"
dark
fixed-tabs
class="elevation-2"
>
<v-tabs-slider color="yellow"></v-tabs-slider>
<v-tab href="../fo01">
<v-icon>list</v-icon> &nbsp; PATIENT LIST
</v-tab>
<v-tab href="#tab-1" active-tab>
<v-icon>opacity</v-icon> &nbsp; SAMPLING
</v-tab>
<v-tab href="../fo03">
<v-icon>verified_user</v-icon> &nbsp; SAMPLE VERIFICATION
</v-tab>
<v-tab href="../fo03">
<v-icon>motorcycle</v-icon> &nbsp; SAMPLE DISTRIBUTION
</v-tab>
<!-- <v-tab-item
v-for="i in 4"
:key="i"
:value="'tab-' + i"
> -->
<!-- <v-card flat>
<v-card-text>{{ text }}</v-card-text>
</v-card>
</v-tab-item> -->
</v-tabs>
</template>
</v-flex>
<v-flex xs12>
<v-card class="pt-1 mt-2 pr-1 pl-1 elevation-2">
<v-layout>
<v-flex xs2>
<start-date></start-date>
</v-flex>
<v-flex xs2>
<start-date label="End Date"></start-date>
</v-flex>
<v-flex xs1>
&nbsp;
</v-flex>
<v-flex xs2>
<sample-station></sample-station>
</v-flex>
<v-flex xs1>
&nbsp;
</v-flex>
<v-flex xs4>
<v-text-field
label="Search"
placeholder=". . ."
></v-text-field>
</v-flex>
</v-layout>
</v-card>
</v-flex>
<v-flex xs12>
<v-layout>
<v-flex xs4>
<list-patient fill-height></list-patient>
</v-flex>
<v-flex xs8>
<v-layout row wrap>
<v-flex pa-2 xs12>
<v-card class="elevation-2">
<v-layout>
<v-flex xs2 ma-1 pa-1>
<v-card class="pa-1">
<img src="https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX19479590.jpg" width="100%" />
</v-card>
</v-flex>
<!-- DETAIL PATIENT HERE -->
<detail-patient></detail-patient>
<!-- <v-flex xs1 pa-1>&nbsp;
</v-flex> -->
<v-flex xs6 pa-1>
<list-px></list-px>
</v-flex>
</v-layout>
<!-- <v-card-actions>
<v-btn flat color="orange">Share</v-btn>
<v-btn flat color="orange">Explore</v-btn>
</v-card-actions> -->
</v-card>
</v-flex>
<v-flex xs12 pa-2>
<v-card>
<v-card-title primary-title class="pb-1 blue lighten-3 white--text pt-2">
<div>
<h5 class="headline mb-0">SAMPLES</h5>
</div>
</v-card-title>
<v-card-text class="pt-1">
<v-layout>
<v-flex xs2 pl-3 pr-3>
<v-card class="text-xs-center pa-2">
<img src="https://anggrek.aplikasi.web.id/smartklinik/assets/app/image/samplesystem/new/b2.png" height="75">
<h3>URINE</h3>
</v-card>
</v-flex>
</v-layout>
</v-card-text>
</v-card>
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</v-container>
</v-content>
<v-footer color="blue lighten-2" app>
<span class="white--text">&copy; 2017</span>
</v-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
import { smartNavbarComponent } from './components/smartNavbarComponent.js<?php echo $ts ?>';
import { listPatientComponent } from './components/listPatientComponent.js<?php echo $ts ?>';
import { listPxComponent } from './components/listPxComponent.js<?php echo $ts ?>';
import { startDateComponent } from './components/startDateComponent.js<?php echo $ts ?>';
import { sampleStationComponent } from './components/sampleStationComponent.js<?php echo $ts ?>';
import { detailPatientComponent } from './components/detailPatientComponent.js<?php echo $ts ?>';
// import { dialogFormComponent } from './components/dialogFormComponent.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'smart-navbar': smartNavbarComponent,
'list-patient': listPatientComponent,
'start-date': startDateComponent,
'sample-station': sampleStationComponent,
'list-px': listPxComponent,
'detail-patient': detailPatientComponent
// 'dialog-form':dialogFormComponent
},
data: {
drawer: false,
date: new Date().toISOString().substr(0, 10),
menu: false,
modal: false,
menu2: false,
patient_name: 'Heri Suryawan',
patient_mr: 'MR-090201001',
patient_dob: '09-09-1999 / 24yr 3mt 2dy'
},
computed : {
// binding () {
// const binding = {}
// if (this.$vuetify.breakpoint.mdAndUp) binding.column = true
// return binding
// }
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

View File

@@ -0,0 +1,97 @@
import * as api from "./api.js";
const module_patient = {
namespaced : true,
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 1,
totalPage: 2,
totalRecord: 11,
currSelected: {
mr: '-',
name: '-',
dob: '-'
}
},
mutations: {
updatePatient(state, data) {
// console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.db_error) {
state.errorMessage = data.db_error.message;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoading(state, flag) {
state.isLoading = flag;
},
resetError(state) {
state.isError = false;
state.errorMessage = "";
},
selectMe(state, item) {
let rows = state.rows;
for (let i in rows) {
// console.log(i);
rows[i].selected = false;
if (rows[i].mr == item.mr) {
rows[i].selected = true;
state.currSelected = rows[i];
}
}
state.rows = rows;
}
},
actions: {
async searchPatient(context, data) {
context.commit("updateLoading", true);
let resp = await api.searchPatient(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoading", false);
context.commit("updatePatient", resp);
setTimeout(function() {
context.commit("resetError");
}, 5000);
},
selectMe(context, item) {
context.commit("selectMe", item);
}
}
}
export { module_patient }

View File

@@ -0,0 +1,70 @@
import * as api from "./api.js";
const module_px = {
namespaced : true,
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 1,
totalPage: 2,
totalRecord: 11
},
mutations: {
updatePx(state, data) {
// console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.db_error) {
state.errorMessage = data.db_error.message;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoadingPx(state, flag) {
state.isLoading = flag;
},
resetErrorPx(state) {
state.isError = false;
state.errorMessage = "";
}
},
actions: {
async searchPx(context, data) {
context.commit("updateLoadingPx", true);
let resp = await api.searchPx(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoadingPx", false);
context.commit("updatePx", resp);
setTimeout(function() {
context.commit("resetErrorPx");
}, 5000);
}
}
}
export { module_px }

18
mockup/fo/fo02/store.js Normal file
View File

@@ -0,0 +1,18 @@
// State
// data ...
// Mutations
//
//
// Actions
import * as api from "./api.js";
// import * as api_px from "./api_px.js";
import { module_patient } from "./module_patient.js";
import { module_px } from "./module_px.js";
export const store = new Vuex.Store({
modules : {
patient : module_patient,
px : module_px
}
});