Przeglądaj źródła

Merge branch 'cleanup' of https://rav.triplestart.com/tigerphp/stagfe2 into cleanup

Peter Muturi 1 rok temu
rodzic
commit
95d2d398fe

+ 6 - 0
app/Helpers/helpers.php

@@ -1162,4 +1162,10 @@ if(!function_exists('camel_case')) {
     function camel_case($string, $dontStrip = []) {
         return lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-z0-9'.implode('',$dontStrip).']+/', ' ',$string))));
     }
+}
+
+if(!function_exists('getDefaultCompanyClientUidSession')) {
+    function getDefaultCompanyClientUidSession($patientID) {
+        return session()->get('DEFAULT_COMPANY_CLIENT_UID_'.$patientID);
+    }
 }

+ 34 - 0
app/Http/Controllers/CompanyClientController.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Support\Facades\Route;
+
+use Illuminate\Http\Request;
+use App\Models\Client;
+use App\Models\Company;
+
+
+
+class CompanyClientController extends Controller
+{
+    public function showSetCompanyClient(Request $request, Client $patient){
+        $companies = Company::all();
+        return view('app.patient.company-client.show-set-company-client', compact('patient', 'companies'));
+    }
+
+    public function setDefaultCompanyClient(Request $request, Client $patient){
+        $companyClientUid = $request->get('companyClientUid');
+        if(!$companyClientUid){
+            return redirect()->back();
+        }
+
+        $request->session()->put('DEFAULT_COMPANY_CLIENT_UID_'.$patient->id, $companyClientUid);
+        return redirect()->back();
+    }
+
+    public function showSetDefaultCompanyClient(Request $request, Client $patient){
+        return view('app.patient.company-client.show-set-default-company-client', compact('patient'));
+    }
+
+}

+ 6 - 0
app/Http/Controllers/Controller.php

@@ -3,6 +3,7 @@
 namespace App\Http\Controllers;
 
 use App\Models\AppSession;
+use App\Models\CompanyClient;
 use App\Models\Note;
 use App\Models\NoteTemplate;
 use App\Models\Pro;
@@ -154,4 +155,9 @@ class Controller extends BaseController
         return $response;
     }
 
+    public function getDefaultCompanyClientFromSession($patient){
+        $defaultCompanyClientUid = session()->get('DEFAULT_COMPANY_CLIENT_UID_'.$patient->id);
+        return CompanyClient::where('uid', $defaultCompanyClientUid)->first();
+    }
+
 }

+ 7 - 17
app/Http/Controllers/MessageController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
 use Illuminate\Support\Facades\Route;
 use App\Models\Client;
 use App\Models\Company;
+use App\Models\CompanyClient;
 use App\Models\Pro;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\DB;
@@ -22,6 +23,7 @@ class MessageController extends Controller
     protected $otSessionId;
     protected $otToken;
 
+
     public function __construct(Request $request)
     {
         parent::__construct();
@@ -35,29 +37,17 @@ class MessageController extends Controller
         view()->share('otSession',$this->otSession);
         view()->share('otSessionId',$this->otSessionId);
         view()->share('otToken',$this->otToken);
-
-
     }
 
-    public function messages(Request $request, Client $patient){
-        $defaultCompanyUid = $request->get('orgUid');
 
-        if(!$defaultCompanyUid){
-            $defaultCompany = $patient->companyClients->first();
-            $defaultCompanyUid = $defaultCompany->company->uid;
-            $defaultCompanyID = $defaultCompany->company->id;
-        }else{
-           $defaultCompany = Company::where('uid', $defaultCompanyUid)->first();
-            $defaultCompanyID = $defaultCompany->id;
-        }
-
-        if(!$defaultCompany) return view('app.patient.messages-no-company', compact('patient'));
-        
 
+    public function messages(Request $request, Client $patient){
+        $defaultCompanyClient = $this->getDefaultCompanyClientFromSession($patient);
+        $defaultCompany = $defaultCompanyClient->company;
         $regardingClient = $patient;
-        $messages = InternalMessage::where('regarding_company_id', $defaultCompanyID)->where('regarding_client_id', $patient->id)->orderBy('created_at', 'ASC')->paginate(25);
+        $messages = InternalMessage::where('regarding_company_id', $defaultCompany->id)->where('regarding_client_id', $patient->id)->orderBy('created_at', 'ASC')->paginate(100);
 
-        return view('app.patient.messages', compact('patient', 'regardingClient', 'messages', 'defaultCompany'));
+        return view('app.patient.company-client.messages', compact('patient', 'regardingClient', 'messages', 'defaultCompanyClient', 'defaultCompany'));
     }
 
     public function clientMessagesAttachments(Request $request, Client $patient, InternalMessage $message)

+ 1 - 0
app/Http/Kernel.php

@@ -70,5 +70,6 @@ class Kernel extends HttpKernel
         'pro.auth.mcp' => \App\Http\Middleware\EnsureMcpPro::class,
         'pro.auth.can-access-patient' => \App\Http\Middleware\EnsureProCanAccessPatient::class,
         'client.not-shadow-of-pro' => \App\Http\Middleware\EnsureClientIsNotShadowOfPro::class,
+        'client.has-company-client' => \App\Http\Middleware\EnsureCompanyClient::class,
     ];
 }

+ 26 - 0
app/Http/Middleware/EnsureCompanyClient.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use App\Models\AppSession;
+use Closure;
+
+class EnsureCompanyClient
+{
+    public function handle($request, Closure $next)
+    {
+        $patient = $request->route()->parameter('patient');
+        if(!$patient) abort(403);
+
+        if(!count($patient->companyClients)){
+            return redirect()->to(route('patients.view.show-set-company-client', $patient));
+        }
+
+        $defaultCompanyClientUid = session()->get('DEFAULT_COMPANY_CLIENT_UID_'.@$patient->id);
+        if(!$defaultCompanyClientUid){
+            return redirect()->to(route('patients.view.show-set-default-company-client', $patient));
+        }
+
+        return $next($request);
+    }
+}

+ 17 - 4
public/css/messages.css

@@ -16,6 +16,7 @@
 .im-container {
   display: flex;
   align-items: stretch;
+  max-height: 55vh;
 }
 .im-container .im-lhs {
   min-width: 300px;
@@ -251,13 +252,25 @@
 .im-container .im-message .im-message-sender {
   position: relative;
 }
-.im-container .im-message .delete {
+.im-container .hidden {
+  display: none;
+}
+.im-container .im-message .delete,
+.im-container .im-message .edit {
   position: absolute;
   right: -14px;
-  top:0px;
+  top: 0px;
+}
+
+.im-container .im-message .edit {
+  right: -9px;
+  top: 3px;
 }
-.im-container .im-message:hover  .delete,
-.im-container .im-message:focus  .delete{
+
+.im-container .im-message:hover .edit,
+.im-container .im-message:focus .edit,
+.im-container .im-message:hover .delete,
+.im-container .im-message:focus .delete {
   display: block;
 }
 .circle-icon {

+ 390 - 0
resources/views/app/patient/company-client/messages.blade.php

@@ -0,0 +1,390 @@
+@extends ('layouts.company-client-layout')
+@section('company-client-content')
+    <script src="https://static.opentok.com/v2/js/opentok.min.js"></script>
+    <link rel="stylesheet" href="{{ asset('css/messages.css') }}">
+    <div class="">
+        <div class="d-flex align-items-center pb-2">
+            <h4 class="font-weight-bold m-0 mr-3">Messages</h4>
+        </div>
+        <div>
+            <div class="card-body p-0 shadow-sm h-100">
+                <div class="im-container">
+                    <div class="im-rhs p-2">
+                        @if ($regardingClient)
+                            @if (!$messages || !count($messages))
+                                <div class="py-4 text-center text-secondary">
+                                    <h3 class="mb-0"><i class="far fa-comment-dots"></i></h3>
+                                    No messages yet!
+                                </div>
+                            @endif
+                            <div class="im-messages">
+                                <div class="mh-100 overflow-auto opacity-0" id="im-scroller">
+                                    <?php $messageDates = []; ?>
+                                    @foreach ($messages as $k => $message)
+                                        @if (!in_array(friendly_date($message->created_at), $messageDates))
+                                            <?php array_push($messageDates, friendly_date($message->created_at)); ?>
+                                            <div class="text-center my-4">
+                                                <span style="background:#c2efff"
+                                                    class="py-1 px-3 text-secondary rounded text-sm">{{ friendly_date($message->created_at) }}</span>
+                                            </div>
+                                        @endif
+                                        <div class="d-flex align-items-start">
+                                            @if ($message->from_pro_id !== $performer->pro->id)
+                                                <div class="">
+                                                    @if (!$message->is_removed)
+                                                        @if ($k == 0 || $messages[$k - 1]->from_pro_id !== $messages[$k]->from_pro_id)
+                                                            <!-- remove unecessary timestamps -->
+                                                            <div class="circle-icon">
+                                                                @if ($message->fromPro)
+                                                                    {{ mb_substr($message->fromPro->name_first, 0, 1) }}
+                                                                @else
+                                                                    {{ mb_substr($message->regardingClient->name_first ?? '', 0, 1) }}
+                                                                @endif
+                                                            </div>
+                                                        @else
+                                                            <div class="circle-icon op">
+                                                                @if ($message->fromPro)
+                                                                    {{ mb_substr($message->fromPro->name_first, 0, 1) }}
+                                                                @else
+                                                                    {{ mb_substr($message->regardingClient->name_first ?? '', 0, 1) }}
+                                                                @endif
+                                                            </div>
+                                                        @endif
+                                                    @endif
+                                                </div>
+                                            @endif
+                                            <div class="w-100">
+                                                <div class="im-message mt-0 pr-5 {{ $message->from_pro_id === $performer->pro->id ? 'sent' : 'received' }}"
+                                                    data-uid="{{ $message->uid }}"
+                                                    data-mark-as-read="{{ $message->is_to_shadow_client && !$message->is_read ? 1 : 0 }}">
+                                                    <div class="im-message-sender align-items-center">
+                                                        @if (!$message->is_removed)
+                                                            @if ($k == 0 || $messages[$k - 1]->from_pro_id !== $messages[$k]->from_pro_id)
+                                                                <!-- remove unecessary timestamps -->
+                                                                @if ($message->from_pro_id !== $performer->pro->id)
+                                                                    @if ($message->fromPro)
+                                                                        <small
+                                                                            class="mr-2 text-secondary">{{ $message->fromPro->displayName() }},</small>
+                                                                    @else
+                                                                        <small
+                                                                            class="mr-2 text-secondary">{{ $message->regardingClient->displayName() }},</small>
+                                                                    @endif
+                                                                @endif
+                                                                <small
+                                                                    class="header-item text-secondary text-sm text-uppercase">{{ friendly_time($message->created_at) }}</small>
+                                                            @endif
+                                                            @if ($performer->pro->can_proofread && $performer->pro->id == $message->created_by_pro_id && $message->content_text)
+                                                                <div class="header-item hidden edit">
+                                                                    <div moe large relative>
+                                                                        @if ($k == 0 || $messages[$k - 1]->from_pro_id !== $messages[$k]->from_pro_id)
+                                                                            <a href="#" start show><i
+                                                                                    class="fa fa-edit on-hover-opaque text-pry text-sm hidden edit"
+                                                                                    style="top:18px;"></i></a>
+                                                                        @else
+                                                                            <a href="#" start show><i
+                                                                                    class="fa fa-edit on-hover-opaque text-pry text-sm hidden edit"></i></a>
+                                                                        @endif
+                                                                        <form url="/api/internalMessage/edit"
+                                                                            class="text-left" right>
+                                                                            <input type="hidden" name="uid"
+                                                                                value="{{ $message->uid }}">
+                                                                            <div class="mb-2">
+                                                                                <label class="mb-1 text-sm">Edit
+                                                                                    Message</label>
+                                                                                <textarea name="contentText" rows="3" class="form-control form-control-sm">{{ $message->content_text }}</textarea>
+                                                                            </div>
+                                                                            <div class="mt-3">
+                                                                                <button submit
+                                                                                    class="btn btn-sm btn-primary mr-2">Submit</button>
+                                                                                <button cancel
+                                                                                    class="btn btn-default btn-sm border">Cancel</button>
+                                                                            </div>
+                                                                        </form>
+                                                                    </div>
+                                                                </div>
+                                                            @endif
+                                                            @if ($message->from_pro_id === $performer->pro->id)
+                                                                <span class="header-item hidden delete">
+                                                                    <a href="#" native class="remove-message"
+                                                                        data-message-uid="{{ $message->uid }}"><i
+                                                                            class="fa fa-trash-alt text-danger text-sm"></i></a>
+                                                                </span>
+                                                            @endif
+                                                        @endif
+                                                    </div>
+                                                    @if ($message->is_removed)
+                                                        <div class="im-message-content text-secondary font-italic">Message removed.</div>
+                                                    @else
+                                                        @if (in_array($message->content_text, ['IV1', 'LH_WEBCAM_INTRO_1']))
+                                                            <div style="max-width: 500px">
+                                                                <script src="https://fast.wistia.com/embed/medias/xm42kdr0l6.jsonp" async></script>
+                                                                <script src="https://fast.wistia.com/assets/external/E-v1.js" async></script>
+                                                                <div class="wistia_responsive_padding"
+                                                                    style="padding:56.25% 0 0 0;position:relative;">
+                                                                    <div class="wistia_responsive_wrapper"
+                                                                        style="height:100%;left:0;position:absolute;top:0;width:100%;">
+                                                                        <div class="wistia_embed wistia_async_xm42kdr0l6 videoFoam=true"
+                                                                            style="height:100%;position:relative;width:100%">
+                                                                            <div class="wistia_swatch"
+                                                                                style="height:100%;left:0;opacity:0;overflow:hidden;position:absolute;top:0;transition:opacity 200ms;width:100%;">
+                                                                                <img src="https://fast.wistia.com/embed/medias/xm42kdr0l6/swatch"
+                                                                                    style="filter:blur(5px);height:100%;object-fit:contain;width:100%;"
+                                                                                    alt="" aria-hidden="true"
+                                                                                    onload="this.parentNode.style.opacity=1;" />
+                                                                            </div>
+                                                                        </div>
+                                                                    </div>
+                                                                </div>
+                                                            </div>
+                                                        @elseif($message->content_text)
+                                                            <?php
+                                                            $message->content_text = preg_replace_callback(
+                                                                '~(?:http|ftp)s?://(?:www\.)?([a-z0-9.-]+\.[a-z]{2,3}(?:/\S*)?)~i',
+                                                                function ($match) {
+                                                                    return '<a native target="_blank" href="' . $match[0] . '">' . $match[0] . '</a>';
+                                                                },
+                                                                $message->content_text,
+                                                            );
+                                                            ?>
+                                                            <div class="im-message-content">{!! $message->content_text !!}</div>
+                                                        @endif
+                                                        @if ($message->message_video_file_id)
+                                                            <div class="im-video-container">
+                                                                <video
+                                                                    src="{{ route('serve-system-file', ['uid' => $message->videoFile->uid]) }}"
+                                                                    controls playsinline></video>
+                                                            </div>
+                                                        @endif
+                                                    @endif
+                                                    @if (count($message->attachments) && !$message->is_removed)
+                                                        <div class="attachments-container mt-1 d-flex align-items-center flex-wrap {{ $message->from_pro_id === $performer->pro->id ? 'justify-content-end' : 'justify-content-start' }}"
+                                                            data-message-uid="{{ $message->uid }}"
+                                                            data-attachments-loaded="0">
+                                                            <span class="my-1 text-primary c-pointer text-sm">
+                                                                <i class="fa fa-paperclip"></i>
+                                                                {{ count($message->attachments) }}
+                                                                attachment{{ count($message->attachments) === 1 ? '' : 's' }}
+                                                            </span>
+                                                        </div>
+                                                    @endif
+                                                </div>
+                                            </div>
+                                        </div>
+                                    @endforeach
+                                </div>
+                            </div>
+                            <div class="im-input">
+                                <div class="d-flex align-items-end">
+                                    <div class="msg-input">
+                                        <textarea placeholder="Enter your message here..."></textarea>
+                                        <button class="btn btn-sm btn-input" id="im-btn-send"><i
+                                                class="fa fa-paper-plane"></i></button>
+                                    </div>
+                                    <div class="fabs ml-2">
+                                        <div moe-video moe-csrf="{{ csrf_token() }}" moe-question-key="hcp_intro"
+                                            moe-video-url="{{ route('video-test') }}"
+                                            moe-ot-api-key="{{ config('app.opentokApiKey') }}"
+                                            moe-ot-session-id="{{ $otSessionId }}"
+                                            moe-ot-client-token="{{ $otToken }}"
+                                            data-title="Upload or Record Video Message"
+                                            @if (isset($toPro)) to-pro-uid="{{ $toPro->uid }}" @endif
+                                            @if (isset($defaultCompany)) regarding-company-uid="{{ $defaultCompany->uid }}" @endif
+                                            @if (isset($regardingClient)) regarding-client-uid="{{ $regardingClient->uid }}" @endif>
+                                        </div>
+                                        <button class="btn btn-sm btn-info ml-2" id="im-btn-select-file"><i
+                                                class="fa fa-paperclip"></i></button>
+                                    </div>
+                                </div>
+                                <div class="d-flex align-items-end flex-wrap" id="selected-files">
+                                </div>
+                            </div>
+                        @else
+                            <div class="text-secondary">Nothing to show here!</div>
+                        @endif
+                        <div>
+                            {{ $messages->withQueryString()->links() }}
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <script>
+        $(document).ready(function() {
+            setTimeout(function() {
+                jQuery('.mark-as-read').click();
+            }, 1000);
+
+            let inProgress = false;
+
+            function showSelectedFiles() {
+                $('#selected-files').empty();
+                $('.im-file-upload').each(function() {
+                    if (this.files && this.files.length) {
+                        for (let i = 0; i < this.files.length; i++) {
+                            $('#selected-files').append($('<div class="selected-file" data-id="' + this.id +
+                                '" title="Click to remove">').text(this.files[i].name));
+                        }
+                    }
+                });
+            }
+
+            function hasError(_data) {
+                let msg = 'Unknown error!';
+                if (_data) {
+                    if (_data.success) return false;
+                    else if (_data.message) msg = _data.message;
+                }
+                toastr.error(msg);
+                return true;
+            }
+
+            function doSend(_elem) {
+                if (inProgress) return false;
+                inProgress = true;
+                showMask();
+                let text = $.trim(_elem.value);
+                let formData = new FormData();
+                formData.set('fromProUid', '{{ $performer->pro->uid }}');
+                formData.set('regardingClientUid', '{{ $regardingClient->uid }}');
+                formData.set('regardingCompanyUid', '{{ $defaultCompany->uid }}');
+                formData.set('contentText', text);
+
+                let hasFiles = false;
+                $('.im-file-upload').each(function() {
+                    if (this.files && this.files.length) {
+                        for (let i = 0; i < this.files.length; i++) {
+                            formData.append('attachments', this.files[i]);
+                            hasFiles = true;
+                        }
+                    }
+                });
+
+                if (!hasFiles && !text) { // either attachment or text or both should be there
+                    inProgress = false;
+                    hideMask();
+                    return false;
+                }
+
+                jQuery.ajax('/api/internalMessage/create', {
+                    dataType: 'json',
+                    data: formData,
+                    processData: false,
+                    contentType: false,
+                    type: 'POST',
+                }).done(function(_data) {
+                    if (!hasError(_data)) {
+                        fastLoad('/patients/view/{{ $patient->uid }}/messages');
+                    } else {
+                        $('.im-input textarea').val('');
+                        inProgress = false;
+                        hideMask();
+                    }
+                });
+                return false;
+            }
+
+
+            function init() {
+                @if ($regardingClient)
+                    $('.im-input textarea').on('keydown', function(_e) {
+                        if (_e.which === 13 && !_e.shiftKey) {
+                            return doSend(this);
+                        }
+                    });
+
+                    $('#im-btn-send').click(function() {
+                        return doSend($('.im-input textarea')[0]);
+                    });
+
+                    $('#plusBtn').click(function() {
+                        $('.hide').toggle();
+                        $('.show').toggle();
+                    });
+
+                    $('#im-btn-select-file').click(function() {
+                        let fiID = Math.floor(Math.random() * 10000);
+                        let fileInput = $('<input type="file" class="d-none im-file-upload" id="fu-' +
+                            fiID + '">');
+                        $('.im-input').append(fileInput)
+                        fileInput.click();
+                    });
+
+                    $(document).on('change', '.im-file-upload', function() {
+                        showSelectedFiles();
+                    });
+
+                    $(document)
+                        .off('click', '.selected-file')
+                        .on('click', '.selected-file', function() {
+                            $('#' + $(this).attr('data-id')).remove();
+                            showSelectedFiles();
+                        });
+
+                    $(document)
+                        .off('click.load-attachments', '.attachments-container[data-attachments-loaded="0"]>span')
+                        .on('click.load-attachments', '.attachments-container[data-attachments-loaded="0"]>span',
+                            function() {
+                                let container = $(this).closest('.attachments-container');
+                                if (inProgress) return false;
+                                inProgress = true;
+                                $.get('/patients/view/{{ $patient->uid }}/messages/' + container.attr(
+                                    'data-message-uid') + '/attachments', (_data) => {
+                                    container.html(_data).attr('data-attachments-loaded', 1);
+                                }).then(function() {
+                                    inProgress = false;
+                                });
+                            });
+
+                    $(document)
+                        .off('click', '.mark-as-read')
+                        .on('click', '.mark-as-read', function() {
+                            $.post('/api/internalMessage/markRead', {
+                                uid: $(this).attr('data-message-uid')
+                            }, () => {
+                                $(this).replaceWith(
+                                    '<i class="fa fa-check text-secondary on-hover-opaque text-sm"></i>'
+                                );
+                                let unreadBadge = $('.unread-badge[data-regarding-client-id="' +
+                                    {{ $regardingClient->id }} + '"]').first();
+                                if (unreadBadge.length) {
+                                    let newCount = (+unreadBadge.text()) - 1;
+                                    if (newCount) {
+                                        unreadBadge.text(newCount);
+                                    } else {
+                                        unreadBadge.remove();
+                                    }
+                                }
+                            }, 'json');
+                            return false;
+                        });
+
+                    $(document)
+                        .off('click', '.remove-message')
+                        .on('click', '.remove-message', function() {
+                            $.post('/api/internalMessage/remove', {
+                                uid: $(this).attr('data-message-uid')
+                            }, () => {
+                                $(this).closest('.im-message').html(
+                                    '<div class="im-message-content text-secondary font-italic">Message removed.</div>'
+                                );
+                            }, 'json');
+                            return false;
+                        });
+                @endif
+
+                setTimeout(function() {
+                    var imScroller = document.getElementById("im-scroller");
+                    imScroller.scrollTop = imScroller.scrollHeight;
+                    $(imScroller).removeClass('opacity-0');
+                }, 100);
+
+            }
+            init();
+        });
+    </script>
+    <link rel="stylesheet" href="{{ asset('moe-video/moe-video.css') }}">
+    <script src="{{ asset('moe-video/moe-video.js') }}"></script>
+
+@endsection

+ 11 - 0
resources/views/app/patient/company-client/partials/set-default-company-client-form.blade.php

@@ -0,0 +1,11 @@
+<form class="rounded" action="{{ route('patients.view.set-default-company-client', $patient) }}" method="POST">
+    @csrf
+    <select name="companyClientUid" class="form-control" onchange="this.form.submit()">
+        <option value=""></option>
+        @foreach ($patient->companyClients as $companyClient)
+            <option value="{{ $companyClient->uid }}"
+                <?= @$defaultCompanyClient->uid === $companyClient->uid ? 'selected' : '' ?>>
+                {{ $companyClient->company->name }}</option>
+        @endforeach
+    </select>
+</form>

+ 43 - 0
resources/views/app/patient/company-client/show-set-company-client.blade.php

@@ -0,0 +1,43 @@
+@extends ('layouts.patient')
+@section('inner-content')
+    <div>
+        <div class="d-flex align-items-end pb-3">
+            <h4 class="font-weight-bold m-0">
+                <i class="fa fa-link"></i>
+                Linked Companies
+            </h4>
+            <span class="mx-2 text-secondary">|</span>
+            <div moe relative class="">
+                <a href="#" start show class="col-2-button">
+                    + Add
+                </a>
+                <form url="/api/companyClient/create" class="mcp-theme-1">
+                    <input type="hidden" name="clientUid" value="{{ $patient->uid }}">
+                    <div class="mb-2">
+                        <label class="text-secondary text-sm">Company</label>
+                        <select name="companyUid" class="form-control form-control-sm" required>
+                            <option value="">--select--</option>
+                            @foreach ($companies as $company)
+                                @if ($company->name)
+                                    <!-- remove blank companies-->
+                                    <option value="{{ $company->uid }}">{{ $company->name }}</option>
+                                @endif
+                            @endforeach
+                        </select>
+                    </div>
+                    <div class="mb-2">
+                        <label for="" class="control-label">Date Referred</label>
+                        <input type="date" name="dateReferred" class="form-control">
+                    </div>
+                    <div>
+                        <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                        <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+    @if(!count($patient->companyClients))
+        <div class="alert alert-danger p-2 rounded-0">No linked companies set for this patient!</div>
+    @endif
+@endsection

+ 7 - 0
resources/views/app/patient/company-client/show-set-default-company-client.blade.php

@@ -0,0 +1,7 @@
+@extends ('layouts.patient')
+@section('inner-content')
+    <div>
+        <div class="alert alert-warning p-1 rounded-0">Set default company to proceed.</div>
+        @include('app.patient.company-client.partials.set-default-company-client-form')
+    </div>
+@endsection

+ 0 - 326
resources/views/app/patient/messages.blade.php

@@ -1,326 +0,0 @@
-@extends ('layouts.patient')
-@section('inner-content')
-<script src="https://static.opentok.com/v2/js/opentok.min.js"></script>
-<link rel="stylesheet" href="{{ asset('css/messages.css') }}">
-<div class="">
-    <div class="d-flex align-items-center pb-2">
-        <h4 class="font-weight-bold m-0 mr-3">Messages</h4>
-        <div>
-            <select name="orgUid" class="form-control" onchange="onCompanyChange(this)">
-                @foreach($patient->companyClients as $companyClient)
-                <option value="{{ $companyClient->company->uid }}" <?= $defaultCompany->uid === $companyClient->company->uid ? 'selected':'' ?>>{{ $companyClient->company->name }}</option>
-                @endforeach
-            </select>
-        </div>
-    </div>
-    <div>
-        <div class="card-body p-0 shadow-sm h-100">
-            <div class="im-container h-100">
-                <div class="im-rhs p-2">
-                    @if($regardingClient)
-                        @if(!$messages || !count($messages))
-                        <div class="py-4 text-center text-secondary">
-                            <h3 class="mb-0"><i class="far fa-comment-dots"></i></h3>
-                            No messages yet!
-                        </div>
-                        @endif
-                    <div class="im-messages">
-                        <div class="mh-100 overflow-auto opacity-0" id="im-scroller">
-                            <?php $messageDates = []; ?>
-                            @foreach($messages as $k => $message)
-                            @if(!in_array(friendly_date($message->created_at), $messageDates))
-                            <?php array_push($messageDates, friendly_date($message->created_at)); ?>
-                            <div class="text-center my-4">
-                                <span style="background:#c2efff" class="py-1 px-3 text-secondary rounded text-sm">{{friendly_date($message->created_at)}}</span>
-                            </div>
-                            @endif
-                            <div class="d-flex align-items-start">
-                                @if($message->from_pro_id !== $performer->pro->id)
-                                <div class="">
-                                    @if(!$message->is_removed)
-                                    @if($k == 0 || ($messages[$k - 1]->from_pro_id !== $messages[$k]->from_pro_id)) <!-- remove unecessary timestamps -->
-                                    <div class="circle-icon">
-                                        @if($message->fromPro)
-                                        {{mb_substr($message->fromPro->name_first, 0, 1)}}
-                                        @else
-                                        {{mb_substr($message->regardingClient->name_first ?? '', 0, 1)}}
-                                        @endif
-                                    </div>
-                                    @else
-                                    <div class="circle-icon op">
-                                        @if($message->fromPro)
-                                        {{mb_substr($message->fromPro->name_first, 0, 1)}}
-                                        @else
-                                        {{mb_substr($message->regardingClient->name_first ?? '', 0, 1)}}
-                                        @endif
-                                    </div>
-                                    @endif
-                                    @endif
-                                </div>
-                                @endif
-                                <div class="w-100">
-                                    <div class="im-message mt-0 pr-5 {{$message->from_pro_id === $performer->pro->id ? 'sent' : 'received'}}" data-uid="{{$message->uid}}" data-mark-as-read="{{$message->is_to_shadow_client && !$message->is_read ? 1 : 0}}">
-                                        <div class="im-message-sender align-items-center">
-                                            @if(!$message->is_removed)
-                                            @if($k == 0 || ($messages[$k - 1]->from_pro_id !== $messages[$k]->from_pro_id)) <!-- remove unecessary timestamps -->
-                                            @if($message->from_pro_id !== $performer->pro->id)
-                                            @if($message->fromPro)
-                                            <small class="mr-2 text-secondary">{{$message->fromPro->displayName()}},</small>
-                                            @else
-                                            <small class="mr-2 text-secondary">{{$message->regardingClient->displayName()}},</small>
-                                            @endif
-                                            @endif
-                                            <small class="header-item text-secondary text-sm text-uppercase">{{friendly_time($message->created_at)}}</small>
-                                            @endif
-                                            @if($message->from_pro_id === $performer->pro->id)
-                                            <span class="header-item hidden delete">
-                                                <a href="#" native class="remove-message" data-message-uid="{{$message->uid}}"><i class="fa fa-trash-alt text-danger text-sm"></i></a>
-                                            </span>
-                                            @endif
-                                            @endif
-                                        </div>
-                                        @if($message->is_removed)
-                                        <div class="im-message-content text-secondary font-italic">This message was removed.</div>
-                                        @else
-                                        @if(in_array($message->content_text, ['IV1', 'LH_WEBCAM_INTRO_1']))
-                                        <div style="max-width: 500px">
-                                            <script src="https://fast.wistia.com/embed/medias/xm42kdr0l6.jsonp" async></script>
-                                            <script src="https://fast.wistia.com/assets/external/E-v1.js" async></script>
-                                            <div class="wistia_responsive_padding" style="padding:56.25% 0 0 0;position:relative;">
-                                                <div class="wistia_responsive_wrapper" style="height:100%;left:0;position:absolute;top:0;width:100%;">
-                                                    <div class="wistia_embed wistia_async_xm42kdr0l6 videoFoam=true" style="height:100%;position:relative;width:100%">
-                                                        <div class="wistia_swatch" style="height:100%;left:0;opacity:0;overflow:hidden;position:absolute;top:0;transition:opacity 200ms;width:100%;"><img src="https://fast.wistia.com/embed/medias/xm42kdr0l6/swatch" style="filter:blur(5px);height:100%;object-fit:contain;width:100%;" alt="" aria-hidden="true" onload="this.parentNode.style.opacity=1;" /></div>
-                                                    </div>
-                                                </div>
-                                            </div>
-                                        </div>
-                                        @elseif($message->content_text)
-                                        <?php
-                                        $message->content_text = preg_replace_callback(
-                                            '~(?:http|ftp)s?://(?:www\.)?([a-z0-9.-]+\.[a-z]{2,3}(?:/\S*)?)~i',
-                                            function ($match) {
-                                                return '<a native target="_blank" href="' . $match[0] . '">' . $match[0] . '</a>';
-                                            },
-                                            $message->content_text
-                                        );
-                                        ?>
-                                        <div class="im-message-content">{!! $message->content_text !!}</div>
-                                        @endif
-                                        @if($message->message_video_file_id)
-                                        <div class="im-video-container">
-                                            <video src="{{route('serve-system-file', ['uid'=>$message->videoFile->uid])}}" controls playsinline></video>
-                                        </div>
-                                        @endif
-                                        @endif
-                                        @if(count($message->attachments) && !$message->is_removed)
-                                        <div class="attachments-container mt-1 d-flex align-items-center flex-wrap {{$message->from_pro_id === $performer->pro->id ? 'justify-content-end' : 'justify-content-start'}}" data-message-uid="{{$message->uid}}" data-attachments-loaded="0">
-                                            <span class="my-1 text-primary c-pointer text-sm">
-                                                <i class="fa fa-paperclip"></i>
-                                                {{count($message->attachments)}} attachment{{count($message->attachments) === 1 ? '' : 's'}}
-                                            </span>
-                                        </div>
-                                        @endif
-                                    </div>
-                                </div>
-                            </div>
-                            @endforeach
-                        </div>
-                    </div>
-                    <div class="im-input">
-                        <div class="d-flex align-items-end">
-                            <div class="msg-input">
-                                <textarea placeholder="Enter your message here..."></textarea>
-                                <button class="btn btn-sm btn-input" id="im-btn-send"><i class="fa fa-paper-plane"></i></button>
-                            </div>
-                            <div class="fabs ml-2">
-                                <div moe-video moe-csrf="{{ csrf_token() }}" moe-question-key="hcp_intro" moe-video-url="{{route('video-test')}}" moe-ot-api-key="{{ config('app.opentokApiKey') }}" moe-ot-session-id="{{ $otSessionId }}" moe-ot-client-token="{{ $otToken }}" data-title="Upload or Record Video Message" @if(isset($toPro)) to-pro-uid="{{$toPro->uid}}" @endif @if(isset($defaultCompany)) regarding-company-uid="{{$defaultCompany->uid}}" @endif @if(isset($regardingClient)) regarding-client-uid="{{$regardingClient->uid}}" @endif>
-                                </div>
-                                <button class="btn btn-sm btn-info ml-2" id="im-btn-select-file"><i class="fa fa-paperclip"></i></button>
-                            </div>
-                        </div>
-                        <div class="d-flex align-items-end flex-wrap" id="selected-files">
-                        </div>
-                    </div>
-                    @else
-                        <div class="text-secondary">Nothing to show here!</div>
-                    @endif
-                    <div>
-                        {{$messages->withQueryString()->links()}}
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
-
-<script>
-    function onCompanyChange(input){
-        var value = input.value;
-        var url = "/patients/view/{{ $patient->uid }}/messages?orgUid="+value;
-        fastLoad(url);
-    }
-        $(document).ready(function() {
-	    setTimeout(function(){jQuery('.mark-as-read').click();}, 1000);
-
-            let inProgress = false;
-
-            function showSelectedFiles() {
-                $('#selected-files').empty();
-                $('.im-file-upload').each(function() {
-                    if(this.files && this.files.length) {
-                        for (let i = 0; i < this.files.length; i++) {
-                            $('#selected-files').append($('<div class="selected-file" data-id="' + this.id + '" title="Click to remove">').text(this.files[i].name));
-                        }
-                    }
-                });
-            }
-            function hasError(_data) {
-                let msg = 'Unknown error!';
-                if (_data) {
-                    if (_data.success) return false;
-                    else if (_data.message) msg = _data.message;
-                }
-                toastr.error(msg);
-                return true;
-            }
-
-            function doSend(_elem) {
-                if(inProgress) return false;
-                inProgress = true;
-                showMask();
-                let text = $.trim(_elem.value);
-                let formData = new FormData();
-                formData.set('fromProUid', '{{$performer->pro->uid}}');
-                formData.set('regardingClientUid', '{{$regardingClient->uid}}');
-                formData.set('regardingCompanyUid', '{{$defaultCompany->uid}}');
-                formData.set('contentText', text);
-
-                let hasFiles = false;
-                $('.im-file-upload').each(function() {
-                    if(this.files && this.files.length) {
-                        for (let i = 0; i < this.files.length; i++) {
-                            formData.append('attachments', this.files[i]);
-                            hasFiles = true;
-                        }
-                    }
-                });
-
-                if(!hasFiles && !text) { // either attachment or text or both should be there
-                    inProgress = false;
-                    hideMask();
-                    return false;
-                }
-
-                jQuery.ajax('/api/internalMessage/create', {
-                    dataType: 'json',
-                    data: formData,
-                    processData: false,
-                    contentType: false,
-                    type: 'POST',
-                }).done(function (_data) {
-                    if(!hasError(_data)) {
-                        fastLoad('/patients/view/{{$patient->uid}}/messages?orgUid={{$defaultCompany->uid}}');
-                    }
-                    else {
-                        $('.im-input textarea').val('');
-                        inProgress = false;
-                        hideMask();
-                    }
-                });
-                return false;
-            }
-
-
-            function init() {
-                @if($regardingClient)
-                $('.im-input textarea').on('keydown', function(_e) {
-                    if(_e.which === 13 && !_e.shiftKey) {
-                        return doSend(this);
-                    }
-                });
-
-                $('#im-btn-send').click(function() {
-                    return doSend($('.im-input textarea')[0]);
-                });
-
-                $('#plusBtn').click(function() {
-                  $('.hide').toggle();
-                  $('.show').toggle();
-                });
-
-                $('#im-btn-select-file').click(function() {
-                    let fiID = Math.floor(Math.random() * 10000);
-                    let fileInput = $('<input type="file" class="d-none im-file-upload" id="fu-' + fiID + '">');
-                    $('.im-input').append(fileInput)
-                    fileInput.click();
-                });
-
-                $(document).on('change', '.im-file-upload', function() {
-                    showSelectedFiles();
-                });
-
-                $(document)
-                    .off('click', '.selected-file')
-                    .on('click', '.selected-file', function() {
-                        $('#' + $(this).attr('data-id')).remove();
-                        showSelectedFiles();
-                    });
-
-                $(document)
-                    .off('click.load-attachments', '.attachments-container[data-attachments-loaded="0"]>span')
-                    .on('click.load-attachments', '.attachments-container[data-attachments-loaded="0"]>span', function() {
-                        let container = $(this).closest('.attachments-container');
-                        if(inProgress) return false;
-                        inProgress = true;
-                        $.get('/patients/view/{{$patient->uid}}/messages/' + container.attr('data-message-uid') + '/attachments', (_data) => {
-                            container.html(_data).attr('data-attachments-loaded', 1);
-                        }).then(function() {
-                            inProgress = false;
-                        });
-                    });
-
-                $(document)
-                    .off('click', '.mark-as-read')
-                    .on('click', '.mark-as-read', function() {
-                        $.post('/api/internalMessage/markRead', {
-                            uid: $(this).attr('data-message-uid')
-                        }, () => {
-                            $(this).replaceWith('<i class="fa fa-check text-secondary on-hover-opaque text-sm"></i>');
-                            let unreadBadge = $('.unread-badge[data-regarding-client-id="' + {{$regardingClient->id}} + '"]').first();
-                            if(unreadBadge.length) {
-                                let newCount = (+unreadBadge.text()) - 1;
-                                if(newCount) {
-                                    unreadBadge.text(newCount);
-                                }
-                                else {
-                                    unreadBadge.remove();
-                                }
-                            }
-                        }, 'json');
-                        return false;
-                    });
-
-                $(document)
-                    .off('click', '.remove-message')
-                    .on('click', '.remove-message', function() {
-                        $.post('/api/internalMessage/remove', {
-                            uid: $(this).attr('data-message-uid')
-                        }, () => {
-                            $(this).closest('.im-message').html('<div class="im-message-content text-secondary font-italic">This message was removed.</div>');
-                        }, 'json');
-                        return false;
-                    });
-
-                var imScroller = document.getElementById("im-scroller");
-                imScroller.scrollTop = imScroller.scrollHeight;
-                $(imScroller).removeClass('opacity-0');
-                @endif
-
-            }
-            init();
-        });
-    </script>
-    <link rel="stylesheet" href="{{ asset('moe-video/moe-video.css') }}">
-    <script src="{{ asset('moe-video/moe-video.js') }}"></script>
-
-@endsection

+ 12 - 0
resources/views/layouts/company-client-layout.blade.php

@@ -0,0 +1,12 @@
+@extends ('layouts.patient')
+@section('inner-content')
+    <div class="mb-3 bg-light">
+       <div class="row">
+        <div class="col-md-2">
+            @include('app.patient.company-client.partials.set-default-company-client-form')
+        </div>
+       </div>
+    </div>
+    @yield('company-client-content')
+
+@endsection

+ 10 - 2
routes/web.php

@@ -6,6 +6,7 @@ use App\Http\Controllers\ManagementStatsController;
 use App\Http\Controllers\VideoTestController;
 use App\Http\Controllers\SystemFileController;
 use App\Http\Controllers\MessageController;
+use App\Http\Controllers\CompanyClientController;
 
 /*
 |--------------------------------------------------------------------------
@@ -541,8 +542,15 @@ Route::middleware('pro.auth')->group(function () {
             Route::get('sms', 'PatientController@sms')->name('sms');
             Route::get('outgoing-sms-log', 'PatientController@outgoingSmsLog')->name('outgoing-sms-log');
             Route::get('review-requests', 'PatientController@reviewRequests')->name('review-requests');
-            Route::get('messages', [MessageController::class, 'messages'])->name('messages');
-            Route::get('messages/{message}/attachments', [MessageController::class, 'clientMessagesAttachments'])->name('messages-attachments');
+
+            Route::get('show-set-company-client', [CompanyClientController::class, 'showSetCompanyClient'])->name('show-set-company-client');
+            Route::get('show-set-default-company-client', [CompanyClientController::class, 'showSetDefaultCompanyClient'])->name('show-set-default-company-client');
+            Route::post('set-default-company-client', [CompanyClientController::class, 'setDefaultCompanyClient'])->name('set-default-company-client');
+            Route::middleware(['client.has-company-client'])->group(function () {
+                Route::get('messages', [MessageController::class, 'messages'])->name('messages');
+                Route::get('messages/{message}/attachments', [MessageController::class, 'clientMessagesAttachments'])->name('messages-attachments');
+            });
+
             Route::get('sms-numbers', 'PatientController@smsNumbers')->name('sms-numbers');
             Route::get('immunizations', 'PatientController@immunizations')->name('immunizations');
             Route::get('allergies', 'PatientController@allergies')->name('allergies');