瀏覽代碼

fixed admin patient blades

= 3 年之前
父節點
當前提交
9beffc15e8

+ 1 - 1
app/Http/Controllers/AdminController.php

@@ -107,7 +107,7 @@ class AdminController extends Controller
         }
 
         $patients = $patients->orderBy('created_at', 'DESC')->paginate(50);
-        return view('app.mcp.patients', compact('patients', 'filters'));
+        return view('app.admin.patients', compact('patients', 'filters'));
     }
 
     public function notes(Request $request)

+ 113 - 0
resources/views/app/admin/patients-table.blade.php

@@ -0,0 +1,113 @@
+<div class="table-responsive">
+	<table class="table table-striped p-0 m-0 table-sm border-top border-bottom text-nowrap">
+		<thead class="bg-light">
+			<tr>
+				<th class="border-0">#</th>
+				<th class="border-0">Name</th>
+				<th class="border-0">DOB</th>
+				<th class="border-0">Age</th>
+				<th class="border-0">Sex</th>
+				<th class="border-0">BMI</th>
+				<th class="border-0">Insurance</th>
+				<th class="border-0">Last Visit</th>
+				<th class="border-0">Next Appt.</th>
+				<th class="border-0">Status</th>
+
+				<th class="border-0">BP</th>
+				<th class="border-0"> <i class="fa fa-heartbeat"></i> </th>
+				<th class="border-0">Pulse</th>
+				<th class="border-0">BP/Pulse Timestamp</th>
+				<th class="border-0">Weight</th>
+				<th class="border-0">Weight Timestamp</th>
+
+				{{-- <th>Scale <i class="fa fa-battery"></i></th>--}}
+				{{-- <th class="border-0">RPM</th>--}}
+				{{-- <th class="border-0">CCM</th>--}}
+				{{-- <th class="border-0 d-none">Last Weight-In</th>--}}
+				{{-- <th class="border-0 d-none">Last BP</th>--}}
+				<th class="border-0">Assigned On</th>
+
+				@if($pro->pro_type == 'ADMIN')
+				<th class="border-0">MCP</th>
+				<th class="border-0">Initiative</th>
+				@endif
+			</tr>
+		</thead>
+		<tbody>
+			@foreach($patients as $patient)
+			<tr>
+				<td>
+					<a native target="_blank" href="{{route('patients.view.dashboard', $patient)}}">
+						{{$patient->chart_number}}
+					</a>
+				</td>
+				<td>{{$patient->displayName()}}</td>
+				<td>{{ friendly_date_time($patient->dob, false) }}</td>
+				<td>{{ $patient->age_in_years ?  $patient->age_in_years : '-' }}</td>
+				<td>{{ $patient->sex }}</td>
+				<td>
+					<div class="d-none d-dflex flex-column">
+						@if($patient->usual_bmi_min && $patient->usual_bmi_max)
+						<small class="text-muted">BMI (Usual): <b>{{ $patient->usual_bmi_min }}</b> {{ $patient->usual_bmi_min_category }} to <b>{{ $patient->usual_bmi_max }}</b> {{ $patient->usual_bmi_max_category }}</small>
+						@endif
+						@if($patient->ideal_bmi)
+						<small class="text-muted">BMI (Ideal) <b>{{ $patient->ideal_bmi }}</b> {{ $patient->ideal_bmi_category }}</small>
+						@endif
+					</div>
+				</td>
+				<td>
+					@include('app.patient.coverage_column_renderer', ['patient'=>$patient])
+				</td>
+				<td>
+					{{ friendly_date($patient->most_recent_completed_mcp_note_date) }}
+					{{-- {{$patient->lastMcpAppointment ? friendly_date_time($patient->lastMcpAppointment->raw_date.' '.$patient->lastMcpAppointment->raw_start_time) : '-'}}--}}
+				</td>
+				<td>{{$patient->nextMcpAppointment ? friendly_date_time($patient->nextMcpAppointment->raw_date.' '.$patient->nextMcpAppointment->raw_start_time) : '-'}}</td>
+				<td>{{$patient->nextMcpAppointment ? $patient->nextMcpAppointment->status : '-'}}</td>
+
+				<td>
+					@if($patient->most_recent_cellular_bp_measurement_at)
+					{{ $patient->most_recent_cellular_bp_sbp_mm_hg }} / {{ $patient->most_recent_cellular_bp_dbp_mm_hg }}
+					@endif
+				</td>
+
+				<td><?= $patient->most_recent_cellular_bp_value_irregular ? '<i class="fa fa-heartbeat"></i>' : '' ?></td>
+
+				<td>{{ $patient->most_recent_cellular_bp_value_pulse }}</td>
+
+				<td>{{ friendlier_date_time($patient->most_recent_cellular_bp_measurement_at, false) }}</td>
+
+				<td>{{ $patient->most_recent_cellular_weight_value ? round($patient->most_recent_cellular_weight_value, 2) : '--' }}</td>
+
+				<td>{{ friendlier_date_time($patient->most_recent_cellular_weight_measurement_at, false) }}</td>
+
+				{{-- <td>{{$patient->is_enrolled_in_cm ? 'Yes' : 'No'}}</td>--}}
+				{{-- <td>{{$patient->is_enrolled_in_rm ? 'Yes' : 'No'}}</td>--}}
+				<td class="d-none text-nowrap">
+					<?php $m = $patient->lastMeasurementOfType('Wt. (lbs.)'); ?>
+					{{$m && $m->value ? round($m->value, 2) : '-'}}
+				</td>
+				<td class="d-none text-nowrap">
+					<?php $m = $patient->lastMeasurementOfType('BP'); ?>
+					{{$m && $m->value ? $m->value : '-'}}
+				</td>
+				<td>{{$patient->getMcpAssignedOn()}}</td>
+				@if($pro->pro_type == 'ADMIN')
+				<td>{{$patient->mcp->display_name ?? '--'}}</td>
+				<td>{{$patient->initiative}}</td>
+				@endif
+			</tr>
+			@endforeach
+
+			@if(count($patients) === 0)
+			<tr>
+				<td colspan="24">No records found!</td>
+			</tr>
+			@endif
+		</tbody>
+
+	</table>
+</div>
+<div class="p-3">
+	{{$patients->withQueryString()->links()}}
+</div>

+ 18 - 2
resources/views/app/admin/patients.blade.php

@@ -1,6 +1,22 @@
 @extends ('layouts/template')
 
 @section('content')
-    <h1>Hi</h1>
-@endsection
+<div class="p-3 mcp-theme-1" id="patients-list">
+    <div class="card">
+
+        <div class="card-header px-3 py-2 d-flex align-items-center">
+            <strong class="mr-4">
+                <i class="fas fa-user"></i>
+                Patients
+            </strong>
+        </div>
 
+        <div class="card-body p-0">
+            <div class="p-3">
+                @include('app.admin.patients_filters')
+            </div>
+            @include('app.admin.patients-table')
+        </div>
+    </div>
+</div>
+@endsection

+ 284 - 0
resources/views/app/admin/patients_filters.blade.php

@@ -0,0 +1,284 @@
+<style>
+	#admin-patients-filters label {
+		font-weight: bold;
+	}
+
+	#admin-patients-filters .mw-100px {
+		min-width: 100px;
+	}
+	.filter-container{
+		display: flex;
+		align-items: flex-start;
+		flex-wrap: wrap;
+	}
+	.filter-container >div {
+		width: 165px;
+	}
+	.filter-container >div:not(:last-child) {
+		margin-right: 15px;
+	}
+	.sm-section {
+		width: 125px !important;
+	}
+</style>
+<form id="admin-patients-filters" method="GET" action="{{ route('admin.patients') }}" class="filter-container" v-cloak>
+	<div class="sm-section">
+		<div class="form-group">
+			<label>Name:</label>
+			<input name="name" class="form-control input-sm" v-model="filters.name">
+		</div>
+	</div>
+	<!-- AGE	 -->
+	<div class="sm-section">
+		<div class="form-group">
+			<label>Age:</label>
+			<select name="age_category" class="form-control input-sm" v-model="filters.age_category">
+				<option value="">All</option>
+				<option value="EXACTLY">Exactly</option>
+				<option value="LESS_THAN">Less Than</option>
+				<option value="GREATER_THAN">Greater Than</option>
+				<option value="BETWEEN">Between</option>
+				<option value="NOT_BETWEEN">Not Between</option>
+			</select>
+			<div v-show="filters.age_category" class="mt-2">
+				<div>
+					<input  name="age_value_1" v-model="filters.age_value_1" type="number" class="form-control input-sm" :placeholder="(filters.age_category === 'BETWEEN' || filters.age_category === 'NOT_BETWEEN') ? 'From' : 'Age'" />
+				</div>
+				<div v-show="filters.age_category === 'BETWEEN' || filters.age_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="age_value_2" v-model="filters.age_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div>
+	<!-- SEX -->
+	<div class="sm-section">
+		<div class="form-group">
+			<label>Sex:</label>
+			<select name="sex" class="form-control input-sm" v-model="filters.sex">
+				<option value="">All</option>
+				<option value="M">Male</option>
+				<option value="F">Female</option>
+			</select>
+		</div>
+	</div>
+	<!-- BMI -->
+	<div class="sm-section">
+		<div class="form-group">
+			<label>BMI:</label>
+			<select name="bmi_category" class="form-control input-sm" v-model="filters.bmi_category">
+				<option value="">All</option>
+				<option value="EXACTLY">Exactly</option>
+				<option value="LESS_THAN">Less Than</option>
+				<option value="GREATER_THAN">Greater Than</option>
+				<option value="BETWEEN">Between</option>
+				<option value="NOT_BETWEEN">Not Between</option>
+			</select>
+			<div v-show="filters.bmi_category" class="mt-2">
+				<div>
+					<input  name="bmi_value_1" v-model="filters.bmi_value_1" type="number" class="form-control input-sm" :placeholder="(filters.bmi_category === 'BETWEEN' || filters.bmi_category === 'NOT_BETWEEN') ? 'From' : 'BMI'" />
+				</div>
+				<div v-show="filters.bmi_category === 'BETWEEN' || filters.bmi_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="bmi_value_2" v-model="filters.bmi_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div>
+
+	<!-- LAST VISIT -->
+	<div class="sm-section">
+		<div class="form-group">
+			<label>Last Visit:</label>
+			<select name="last_visit_category" class="form-control input-sm" v-model="filters.last_visit_category">
+				<option value="">All</option>
+				<option value="EXACTLY">Exactly</option>
+				<option value="LESS_THAN">Less Than</option>
+				<option value="GREATER_THAN">Greater Than</option>
+				<option value="BETWEEN">Between</option>
+				<option value="NOT_BETWEEN">Not Between</option>
+			</select>
+			<div v-show="filters.last_visit_category" class="mt-2">
+				<div>
+					<input  name="last_visit_value_1" v-model="filters.last_visit_value_1" type="number" class="form-control input-sm" :placeholder="(filters.last_visit_category === 'BETWEEN' || filters.last_visit_category === 'NOT_BETWEEN') ? 'From' : 'Last Visit'" />
+				</div>
+				<div v-show="filters.last_visit_category === 'BETWEEN' || filters.last_visit_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="last_visit_value_2" v-model="filters.last_visit_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div>
+
+	<!-- NEXT APPOINTMENT -->
+	<div>
+		<div class="form-group">
+			<label>Next Appointment:</label>
+			<select name="next_appointment_category" class="form-control input-sm" v-model="filters.next_appointment_category">
+				<option value="">All</option>
+				<option value="EXACTLY">Exactly</option>
+				<option value="LESS_THAN">Less Than</option>
+				<option value="GREATER_THAN">Greater Than</option>
+				<option value="BETWEEN">Between</option>
+				<option value="NOT_BETWEEN">Not Between</option>
+			</select>
+			<div v-show="filters.next_appointment_category" class="mt-2">
+				<div>
+					<input  name="next_appointment_value_1" v-model="filters.next_appointment_value_1" type="number" class="form-control input-sm" :placeholder="(filters.next_appointment_category === 'BETWEEN' || filters.next_appointment_category === 'NOT_BETWEEN') ? 'From' : 'Next Appt.'" />
+				</div>
+				<div v-show="filters.next_appointment_category === 'BETWEEN' || filters.next_appointment_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="next_appointment_value_2" v-model="filters.next_appointment_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div>
+
+	<!-- STATUS -->
+	<div class="sm-section">
+		<div class="form-group">
+			<label>Status:</label>
+			<select name="status" class="form-control input-sm" v-model="filters.status">
+				<option value="">All</option>
+				<option value="ACTIVE">Active</option>
+				<option value="AWAITING_VISIT">Awaiting Visit</option>
+				<option value="INACTIVE">Inactive</option>
+			</select>
+		</div>
+	</div>
+
+	@if($performer->pro->pro_type == 'ADMIN')
+	<div class="sm-section">
+		<div class="form-group">
+			<label>Initiative:</label>
+			<input type="text" name="initiative" class="form-control input-sm" v-model="filters.initiative">
+		</div>
+	</div>
+	@endif
+
+	@if($performer->pro->pro_type == 'ADMIN')
+	<div class="sm-section">
+		<div class="form-group">
+			<div class="checkbox mt-4 pt-2">
+				<label>
+					<input type="checkbox" name="include_test_records"  v-model="filters.include_test_records">
+					Include Test Records
+				</label>
+			</div>
+		</div>
+	</div>
+	@endif
+
+	<!-- LAST WEIGHED-IN -->
+	<!-- <div class="col-md-2 d-none">
+		<div class="form-group">
+			<label>Last Weighed-In:</label>
+			<select name="last_weighed_in_category" class="form-control input-sm" v-model="filters.last_weighed_in_category">
+				<option value="">All</option>
+				<option value="EXACTLY">Exactly</option>
+				<option value="LESS_THAN">Less Than</option>
+				<option value="GREATER_THAN">Greater Than</option>
+				<option value="BETWEEN">Between</option>
+				<option value="NOT_BETWEEN">Not Between</option>
+			</select>
+			<div v-show="filters.last_weighed_in_category" class="mt-2">
+				<div>
+					<input  name="last_weighed_in_value_1" v-model="filters.last_weighed_in_value_1" type="number" class="form-control input-sm" :placeholder="(filters.last_weighed_in_category === 'BETWEEN' || filters.last_weighed_in_category === 'NOT_BETWEEN') ? 'From' : 'Last Weighed'" />
+				</div>
+				<div v-show="filters.last_weighed_in_category === 'BETWEEN' || filters.last_weighed_in_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="last_weighed_in_value_2" v-model="filters.last_weighed_in_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div> -->
+
+	<!-- LAST BP -->
+	<!-- <div class="col-md-2 d-none">
+		<div class="form-group">
+			<label>Last BP:</label>
+			<select name="last_bp_category" class="form-control input-sm" v-model="filters.last_bp_category">
+				<option value="">All</option>
+				<option value="EXACTLY">Exactly</option>
+				<option value="LESS_THAN">Less Than</option>
+				<option value="GREATER_THAN">Greater Than</option>
+				<option value="BETWEEN">Between</option>
+				<option value="NOT_BETWEEN">Not Between</option>
+			</select>
+			<div v-show="filters.last_bp_category" class="mt-2">
+				<div>
+					<input  name="last_bp_value_1" v-model="filters.last_bp_value_1" type="number" class="form-control input-sm" :placeholder="(filters.last_bp_category === 'BETWEEN' || filters.last_bp_category === 'NOT_BETWEEN') ? 'From' : 'Last BP'" />
+				</div>
+				<div v-show="filters.last_bp_category === 'BETWEEN' || filters.last_bp_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="last_bp_value_2" v-model="filters.last_bp_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div> -->
+
+	<div>
+		<div class="form-group">
+			<label>&nbsp;</label>
+			<div class=" d-flex">
+				<button type="button" v-on:click.prevent="doSubmit()" class="btn btn-primary btn-sm mr-2"><i class="fas fa-filter"></i> Filter</button>
+				<a href="#" v-on:click.prevent="fastLoad('{{route('admin.patients')}}')" class="btn btn-link btn-sm text-danger">Clear Filters</a>
+			</div>
+		</div>
+	</div>
+</form>
+
+<?php
+$loadedFilters = $filters;
+$allFilterKeys = [
+	'name',
+	'age_category',
+	'age_value_1',
+	'age_value_2',
+	'bmi_category',
+	'bmi_value_1',
+	'bmi_value_2',
+	'last_bp_category',
+	'last_bp_value_1',
+	'last_bp_value_2',
+	'last_visit_category',
+	'last_visit_value_1',
+	'last_visit_value_2',
+	'last_weighed_in_category',
+	'last_weighed_in_value_1',
+	'next_appointment_category',
+	'next_appointment_value_1',
+	'sex',
+	'status',
+	'initiative',
+	'include_test_records',
+];
+for ($i=0; $i < count($allFilterKeys); $i++) {
+	if (!isset($loadedFilters[$allFilterKeys[$i]]) || !$loadedFilters[$allFilterKeys[$i]]) {
+		$loadedFilters[$allFilterKeys[$i]] = '';
+	}
+}
+?>
+<script>
+	(function() {
+		function init() {
+			new Vue({
+				el: '#admin-patients-filters',
+				delimiters: ['@{{', '}}'],
+				data: {
+					filters: <?= json_encode($loadedFilters) ?>
+				},
+				methods: {
+					init: function() {
+
+					},
+					doSubmit: function() {
+						fastLoad('{{ route('admin.patients') }}?' + $('#admin-patients-filters').serialize());
+						return false;
+					}
+				},
+				mounted: function() {
+					console.log(this.filters);
+					this.init();
+				},
+			});
+
+
+		}
+		addMCInitializer('admin-patients-filters', init, '#admin-patients-filters');
+	})();
+</script>