Pārlūkot izejas kodu

Abandoned carts

Samson Mutunga 6 mēneši atpakaļ
vecāks
revīzija
5a9a4399b7

+ 11 - 0
app/Helpers.php

@@ -351,4 +351,15 @@ if ( !function_exists( 'get_lab_station_summary2' ) ) {
         ];
     }
 }
+
+function labAddress(array $selectedLab, $short = false){ 
+    $parts = [];
+    if(isset($selectedLab['lab_title'])) array_push($parts, $selectedLab['lab_title'] . '<br />');
+    if(isset($selectedLab['street'])) array_push($parts, $selectedLab['street'] . '<br />');
+    if(isset($selectedLab['city'])) array_push($parts, $selectedLab['city'] . ', ');
+    if(isset($selectedLab['state'])) array_push($parts, $selectedLab['state']);
+    if(isset($selectedLab['postcode'])) array_push($parts, $selectedLab['postcode']);
+
+    return implode($parts);
+}
 ?>

+ 16 - 0
app/Http/Controllers/AdminController.php

@@ -21,6 +21,8 @@ use Illuminate\Support\Facades\Storage;
 use Exception;
 use Ramsey\Uuid\Uuid;
 use App\Models\Lab2;
+use App\Models\GuestData;
+use Illuminate\Support\Facades\DB;
 
 class AdminController extends Controller
 {
@@ -642,4 +644,18 @@ class AdminController extends Controller
         $user->save();
         return $this->pass($user->uid);
     }
+
+    public function abandonedCarts(Request $request){
+        $records = GuestData::query();
+        $records = $records->whereRaw("detail_json->>'user_id' IS NOT NULL")->whereRaw("detail_json->>'submitted' IS NULL");
+        $records = $records->orderBy('id', 'DESC')->paginate(30);
+        return view('app.my-account.admin.abandoned-carts.index', compact('records'));
+    }
+
+    public function guestsData(Request $request){
+        $records = GuestData::query();
+        $records = $records->whereRaw("detail_json->>'user_id' IS NULL");
+        $records = $records->orderBy('id', 'DESC')->paginate(30);
+        return view('app.my-account.admin.abandoned-carts.index', compact('records'));
+    }
 }

+ 34 - 0
app/Models/GuestData.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use App\Models\BaseModel;
+
+class GuestData extends BaseModel
+{
+    use HasFactory;
+
+    protected $table = 'guest_data';
+
+    public function detailJson($toArray = false)
+    {
+        if ($toArray) {
+            return json_decode($this->detail_json ?? '{}', true);
+        }
+        return json_decode($this->detail_json ?? '{}');
+    }
+
+    public function getUserID(){
+        $detail = (array) $this->detailJson(true);
+        return @$detail['user_id'];
+    }
+
+    public function user(){
+        $userID = $this->getUserID();
+        if(!$userID) return null;
+        return User::where('id', $userID)->first();
+    }
+
+}

+ 106 - 0
resources/views/app/my-account/admin/abandoned-carts/filters.blade.php

@@ -0,0 +1,106 @@
+<?php
+	$url = route('admin.user-events');
+?>
+<style>
+	#recordsFilter label {
+		font-weight: bold;
+	}
+
+	#recordsFilter .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;
+	}
+</style>
+<form id="recordsFilter" method="GET" action="{{ $url }}" class="filter-container align-items-end mb-3" v-cloak>
+	<div class="sm-section">
+		<label class="text-secondary text-sm mb-1">Name:</label>
+		<input name="name" class="form-control form-control-sm min-width-unset" v-model="filters.name" />
+	</div>
+	<div class="sm-section">
+		<div class="form-group mb-0">
+			<label class="text-secondary text-sm mb-1">Date:</label>
+			<select name="created_at_date_category" class="form-control form-control-sm min-width-unset" v-model="filters.created_at_date_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.created_at_date_category" class="mt-2">
+				<div>
+					<input  name="created_at_date_value_1" v-model="filters.created_at_date_value_1" type="date" class="form-control form-control-sm min-width-unset" :placeholder="(filters.created_at_date_category === 'BETWEEN' || filters.created_at_date_category === 'NOT_BETWEEN') ? 'From' : 'Last Visit'" />
+				</div>
+				<div v-show="filters.created_at_date_category === 'BETWEEN' || filters.created_at_date_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="created_at_date_value_2" v-model="filters.created_at_date_value_2" type="date" class="form-control form-control-sm min-width-unset" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div>
+
+	<div class="">
+		<div class="form-group mb-0">
+			<label class="text-secondary text-sm mb-1">&nbsp;</label>
+			<div class="d-flex align-items-center">
+				<button type="submit" v-on:click.prevent="doSubmit()" class="btn btn-primary btn-sm mr-2">Filter</button>
+				<a href="#" v-on:click.prevent="fastLoad('{{ $url }}')" class="btn btn-link btn-sm text-danger">Clear Filters</a>
+			</div>
+		</div>
+	</div>
+</form>
+
+<?php
+$loadedFilters = $filters;
+$allFilterKeys = [
+	'name',
+	'created_at_date_category',
+	'created_at_date_value_1',
+	'created_at_date_value_2',
+];
+for ($i = 0; $i < count($allFilterKeys); $i++) {
+	if (!isset($loadedFilters[$allFilterKeys[$i]]) || !$loadedFilters[$allFilterKeys[$i]]) {
+		$loadedFilters[$allFilterKeys[$i]] = '';
+	}
+}
+?>
+
+<script>
+	$(document).ready(function(){
+		new Vue({
+				el: '#recordsFilter',
+				delimiters: ['@{{', '}}'],
+				data: {
+					filters: <?= json_encode($loadedFilters) ?>
+				},
+				methods: {
+					doSubmit: function() {
+						fastLoad('{{ $url }}?' + $('#recordsFilter').serialize());
+						return false;
+					},
+					initSelect2: function() {
+						$('[select2]').select2();
+					},
+					init: function() {
+						this.initSelect2();
+
+					}
+				},
+				mounted: function() {
+					this.init();
+				},
+			});
+	});
+</script>

+ 11 - 0
resources/views/app/my-account/admin/abandoned-carts/index.blade.php

@@ -0,0 +1,11 @@
+@extends('app.my-account.layout-lite')
+@section('page')
+    <div class="px-3">
+        <div>
+            @include('app.my-account.admin.abandoned-carts.partials.table')
+        </div>
+        <div class="mt-3">
+            {{ $records->appends(request()->input())->links() }}
+        </div>
+    </div>
+@endsection

+ 47 - 0
resources/views/app/my-account/admin/abandoned-carts/partials/table.blade.php

@@ -0,0 +1,47 @@
+<div class="table-responsive">
+    <table class="table table-sm table-hover table-striped table-bordered mb-0">
+        <thead class="fw-bold text-secondary bg-light">
+            <tr>
+                <th>Created At</th>
+                <th>User ID</th>
+                <th>Lab</th>
+                <th>Tests</th>
+            </tr>
+        </thead>
+        <tbody>
+            @foreach ($records as $record)
+                <?php 
+                    $detailJson = (array) $record->detailJson(true);
+                    if(isset($detailJson['lab']) && isset($detailJson['lab']['hrs_of_operation'])){
+                        unset($detailJson['lab']['hrs_of_operation']);
+                    }  
+                    $lab = (array) @$detailJson['lab'];
+                    $tests = (array) @$detailJson['tests'];                     
+                ?>
+                <tr>
+                    <td>{{ friendly_date($record->created_at ?? $record->updated_at) }}</td>
+                    <td>
+                        @if($record->user())
+                            <?php $user = $record->user(); ?>
+                            <a href="{{ route('admin.users.view.dashboard', $user) }}">{{ $user->displayName() }}</a>
+                            <div class="d-flex" style="gap:16px;">
+                                <span>Sex: <b>{{ $user->getDetailJsonValue('sex') }}</b></span>
+                                <span>E: <b>{{ $user->getEmail() }}</b></span>
+                                <span>DOB: <b>{{ friendly_date($user->getDetailJsonValue('dob')) }}</b></span>
+                                <span>P: <b>{{ $user->getDetailJsonValue('phoneNumber') }}</b></span>
+                            </div>
+                        @else
+                            ---
+                        @endif
+                    </td>
+                    <td><?= labAddress($lab) ?></td>
+                    <td>
+                        @foreach($tests as $key =>$amount)
+                            <span><b>{{ getTestLabelByKey($key) }}</b> - ${{ $amount }}</span>
+                        @endforeach
+                    </td>
+                </tr>
+            @endforeach
+        </tbody>
+    </table>
+</div>

+ 2 - 0
resources/views/app/my-account/nav/admin.blade.php

@@ -11,3 +11,5 @@
 <a class="nav-link px-2 py-1 me-2 {{ $currentTab == 'financial-transactions' ? 'bg-secondary text-white rounded':'' }}" href="{{ route('admin.financial-transactions') }}">Financial Transactions</a>
 <a class="nav-link px-2 py-1 me-2 {{ $currentTab == 'sessions' ? 'bg-secondary text-white rounded':'' }}" href="{{ route('admin.sessions') }}">Sessions</a>
 <a class="nav-link px-2 py-1 me-2 {{ $currentTab == 'user-events' ? 'bg-secondary text-white rounded':'' }}" href="{{ route('admin.user-events') }}">User Events</a>
+<a class="nav-link px-2 py-1 me-2 {{ $currentTab == 'abandoned-carts' ? 'bg-secondary text-white rounded':'' }}" href="{{ route('admin.abandoned-carts') }}">Abandoned Carts</a>
+<a class="nav-link px-2 py-1 me-2 {{ $currentTab == 'guests-data' ? 'bg-secondary text-white rounded':'' }}" href="{{ route('admin.guests-data') }}">Guests Data</a>

+ 2 - 0
routes/web.php

@@ -101,6 +101,8 @@ Route::group(['middleware' => ['ensureUserLoggedIn']], function () {
             Route::get('/sessions', [AdminController::class, 'sessions'])->name('.sessions');
             Route::get('/user-events', [AdminController::class, 'userEvents'])->name('.user-events');
             Route::post('/email-attachment', [AdminController::class, 'emailAttachment'])->name('.email-attachment');
+            Route::get('/guests-data', [AdminController::class, 'guestsData'])->name('.guests-data');
+            Route::get('/abandoned-carts', [AdminController::class, 'abandonedCarts'])->name('.abandoned-carts');
         });
 
         Route::get('/search-users', [AppController::class, 'searchUsers'])->name('search-users');