
We will complete the mailbox module in this part and we will finish the remaining actions that we need for the mailbox like, forwarding, replying and trashing emails.
Series Topics:
- Part 1: Preparation
- Part 2: Database
- Part 3: Models & Relations
- Part 4: Preparing Login Page
- Part 5: Users Module
- Part 6: Roles & Permissions
- Part 7: Documents Module
- Part 8: Contacts Module
- Part 9: Tasks Module
- Part 10: Mailbox Module
- Part 11: Mailbox Module Complete
- Part 12: Calendar Module
- Part 13: Finishing
Email Toggle Important
Let’s update method toggleImportant() like this:
/** * toggle important * * * * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function toggleImportant(Request $request) { if(!$request->mailbox_flag_ids || count($request->mailbox_flag_ids) == 0) return response()->json(['state' => 0, 'msg' => 'required mailbox_flag_ids'], 500); $updated = []; foreach ($request->mailbox_flag_ids as $id) { $mailbox_flag = MailboxFlags::find($id); $mailbox_flag->is_important = ($mailbox_flag->is_important==0?1:0); $mailbox_flag->save(); $updated[] = $mailbox_flag; } return response()->json(['state' => 1, 'msg' => 'updated sucessfully', 'updated' => $updated], 200); }
This method accepts an array of mailbox_flag_ids then we use a simple for each loop to update each id.
Now we will update functions.js file so open public/theme/views/mailbox/functions.js inside toggleImportant() function add this code:
$.ajax({ url: BASE_URL + "/admin/mailbox-toggle-important", method: "PUT", data: {mailbox_flag_ids: ids, method: "PUT", _token: $("meta[name='csrf_token']").attr("content")}, dataType: "json", success: function (response) { cb(response); } });
Also update public/theme/views/mailbox/index.js add this code inside $(function() {Â }).
//Handle starring $(".mailbox-star").click(function (e) { e.preventDefault(); handleImportant([$(this).parents("tr").attr("data-mailbox-flag-id")]); }); // handle starring for checked inputs $(".mailbox-star-all").on("click", function (e) { if(!checkboxCheck()) { return; } var checked = new Array(); $(".check-message:checked").each(function (val) { checked.push($(this).parents("tr").attr("data-mailbox-flag-id")); }); handleImportant(checked); });
Add this function at the end of public/theme/views/mailbox/index.js
function handleImportant(data) { Mailbox.toggleImportant(data, function (response) { if(response.state == 0) { alert(response.msg); } else { response.updated.map(function(value) { if(value.is_important == 1) { //Switch states $("tr[data-mailbox-flag-id='"+value.id+"'] td.mailbox-star").find("a > i").removeClass("fa-star-o").addClass("fa-star"); } else { //Switch states $("tr[data-mailbox-flag-id='"+value.id+"'] td.mailbox-star").find("a > i").removeClass("fa-star").addClass("fa-star-o"); } }); alert(response.msg); } }); }
This above javascript code manipulates when the user click the star button whether it’s one row or when checked mulitple rows. I have created another function “handleImportant()” which receives a response of updated ids and using the map() javascript function i iterated over them to toggle each star.
Email Trash
Update the trash() method in the Mailbox controller as follows:
/** * trash email * * * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function trash(Request $request) { if(!$request->mailbox_user_folder_ids || count($request->mailbox_user_folder_ids) == 0) return response()->json(['state' => 0, 'msg' => 'required mailbox_user_folder_id'], 500); $updated = []; $trashFolder = MailboxFolder::where('title', 'Trash')->first(); foreach ($request->mailbox_user_folder_ids as $id) { $mailbox_user_folder = MailboxUserFolder::find($id); $mailbox_user_folder->folder_id = $trashFolder->id; $mailbox_user_folder->save(); $updated[] = $mailbox_user_folder; } return response()->json(['state' => 1, 'msg' => 'messages moved to trashed folder', 'updated' => $updated], 200); }
This method also accepts an array of folder ids. Trashing a message is a matter of adding it to the Trash folder, and this is the above code do, I loop over the array of ids then i update each folder to the Trash folder id.
update functions.js file, inside trash() function add this code:
$.ajax({ url: BASE_URL + "/admin/mailbox-trash", method: "DELETE", data: {mailbox_user_folder_ids: ids, method: "DELETE", _token: $("meta[name='csrf_token']").attr("content")}, dataType: "json", success: function (response) { cb(response); } });
In the same way update public/theme/views/mailbox/index.js add this code inside $(function() {Â }).
// handle trash $(".mailbox-trash-all").on("click", function (e) { if(!checkboxCheck()) { return; } var checked = new Array(); $(".check-message:checked").each(function (val) { checked.push($(this).parents("tr").attr("data-user-folder-id")); }); handleTrash(checked); });
Add this function at the end of public/theme/views/mailbox/index.js
function handleTrash(data) { Mailbox.trash(data, function (response) { if(response.state == 0) { alert(response.msg); } else { alert(response.msg); setInterval(function () { location.reload(); }, 3000); } }); }
Now the code for trashing and set important is complete. Let’s continue the mailbox actions and add the reply, forward and send draft.
Email Reply
To reply to an email the process is identical to sending the email except that the receiver in this case is the sender of the parent message.
Update those two methods in the Mailbox controller as follows:
/** * getReply * * show reply form * * @param $id * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function getReply($id) { $mailbox = Mailbox::find($id); $folders = $this->folders; $unreadMessages = count(getUnreadMessages()); return view('pages.mailbox.reply', compact('folders', 'unreadMessages', 'mailbox')); } /** * postReply * * * send the reply * * @param Request $request * @param $id * @return \Illuminate\Http\RedirectResponse */ public function postReply(Request $request, $id) { $this->validate($request, [ 'body' => 'required' ]); try { $this->validateAttachments($request); } catch (\Exception $ex) { return redirect('admin/mailbox-reply/' . $id)->with('flash_error', $ex->getMessage()); } // save message $old_mailbox = Mailbox::find($id); $mailbox = new Mailbox(); $mailbox->subject = starts_with($old_mailbox->subject, "RE:")?$old_mailbox->subject:"RE: " . $old_mailbox->subject; $mailbox->body = $request->body; $mailbox->sender_id = Auth::user()->id; $mailbox->time_sent = date("Y-m-d H:i:s"); $mailbox->parent_id = $old_mailbox->id; $mailbox->save(); // save receivers and flags $receiver_ids = [$old_mailbox->sender_id]; $this->save(1, $receiver_ids, $mailbox); // save attachments if found $this->uploadAttachments($request, $mailbox); // send email $this->mailer->sendMailboxEmail($mailbox); return redirect('admin/mailbox-show/' . $id)->with('flash_message', 'Reply sent'); }
Here the process is quite similar to the store() method that we discussed in the previous part. But in the reply the subject is added automatically from parent message and appended with “RE”. Also is save the parent id which is the id of the message to reply to.
resources/views/pages/mailbox/reply.blade.php
@extends('layout.app') @section('title', ' | Mailbox | Reply message') @section('content') <section class="content-header"> <h1> Mailbox @if($unreadMessages) <small>{{$unreadMessages}} new messages</small> @endif </h1> <ol class="breadcrumb"> <li><a href="{{ url('/admin') }}"><i class="fa fa-dashboard"></i> Dashboard</a></li> <li><a href="{{ url('/admin/mailbox') }}"> Mailbox</a></li> <li class="active">Reply</li> </ol> </section> <section class="content"> <div class="row"> <div class="col-md-3"> <a href="{{ url('admin/mailbox') }}" class="btn btn-primary btn-block margin-bottom">Back to inbox</a> @include('pages.mailbox.includes.folders_panel') </div> <div class="col-md-9"> <form method="post" action="{{ url('admin/mailbox-reply/' . $mailbox->id) }}" enctype="multipart/form-data"> {{ csrf_field() }} <div class="box box-primary"> <div class="box-header with-border"> <h3 class="box-title">Reply to {{ $mailbox->sender->name }}</h3> </div> @if ($errors->any()) <ul class="alert alert-danger"> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> @endif <!-- /.box-header --> <div class="box-body"> <div class="form-group"> <textarea id="compose-textarea" class="form-control" name="body" style="height: 300px"> {{ old("body")!=null?old("body"):"" }} </textarea> </div> <div class="form-group"> <div class="btn btn-default btn-file"> <i class="fa fa-paperclip"></i> Attachments <input type="file" name="attachments[]" multiple> </div> <p class="help-block">Max. {{ (int)(ini_get('upload_max_filesize')) }}M</p> </div> </div> <!-- /.box-body --> <div class="box-footer"> <div class="pull-right"> <button type="submit" class="btn btn-primary"><i class="fa fa-reply"></i> Reply</button> </div> </div> <!-- /.box-footer --> </div> <!-- /. box --> </form> </div> <!-- /.col --> </div> <!-- /.row --> </section> @endsection @section('scripts') <script> $(function () { //Add text editor $("#compose-textarea").wysihtml5(); }); </script> @endsection
Email Forward
Forwarding the message is the same as sending the message so update those two methods in the Mailbox controller.
/** * getForward * * show forward form * * @param $id * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function getForward($id) { $mailbox = Mailbox::find($id); $folders = $this->folders; $unreadMessages = count(getUnreadMessages()); $users = User::where('is_active', 1)->where('id', '!=', Auth::user()->id)->get(); return view('pages.mailbox.forward', compact('folders', 'unreadMessages', 'mailbox', 'users')); } /** * postForward * * forward the message * * @param Request $request * @param $id * @return \Illuminate\Http\RedirectResponse */ public function postForward(Request $request, $id) { $this->validate($request, [ 'subject' => 'required', 'receiver_id' => 'required', 'body' => 'required' ]); try { $this->validateAttachments($request); } catch (\Exception $ex) { return redirect('admin/mailbox-forward/' . $id)->with('flash_error', $ex->getMessage()); } $receiver_ids = $request->receiver_id; $subject = $request->subject; $body = $request->body; // save message $old_mailbox = Mailbox::find($id); $mailbox = new Mailbox(); $mailbox->subject = $subject; $mailbox->body = $body; $mailbox->sender_id = Auth::user()->id; $mailbox->time_sent = date("Y-m-d H:i:s"); $mailbox->parent_id = 0; $mailbox->save(); // save receivers and flags $this->save(1, $receiver_ids, $mailbox); // save attachments if found $this->uploadAttachments($request, $mailbox); // if the old mailbox has attachments copy them into the new mailbox $this->copyAttachments($old_mailbox, $mailbox); // send email $this->mailer->sendMailboxEmail($mailbox); return redirect('admin/mailbox/Sent')->with('flash_message', 'Message sent'); }
resources/views/pages/mailbox/forward.blade.php
@extends('layout.app') @section('title', ' | Mailbox | Forward message') @section('content') <section class="content-header"> <h1> Mailbox @if($unreadMessages) <small>{{$unreadMessages}} new messages</small> @endif </h1> <ol class="breadcrumb"> <li><a href="{{ url('/admin') }}"><i class="fa fa-dashboard"></i> Dashboard</a></li> <li><a href="{{ url('/admin/mailbox') }}"> Mailbox</a></li> <li class="active">Forward</li> </ol> </section> <section class="content"> <div class="row"> <div class="col-md-3"> <a href="{{ url('admin/mailbox') }}" class="btn btn-primary btn-block margin-bottom">Back to inbox</a> @include('pages.mailbox.includes.folders_panel') </div> <div class="col-md-9"> <form method="post" action="{{ url('admin/mailbox-forward/' . $mailbox->id) }}" enctype="multipart/form-data"> {{ csrf_field() }} <div class="box box-primary"> <div class="box-header with-border"> <h3 class="box-title">Forward Message</h3> </div> @if ($errors->any()) <ul class="alert alert-danger"> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> @endif <!-- /.box-header --> <div class="box-body"> <div class="form-group"> <?php $selected_receivers = old('receiver_id') ?> <select name="receiver_id[]" id="receiver_id" multiple class="form-control"> @foreach($users as $user) <option value="{{ $user->id }}" {{ $selected_receivers!=null && in_array($user->id, $selected_receivers)?"selected":"" }}>{{ $user->name }}</option> @endforeach </select> </div> <div class="form-group"> <input class="form-control" name="subject" placeholder="Subject:" value="{{ old("subject")!=null?old("subject"):$mailbox->subject }}"> </div> <div class="form-group"> <textarea id="compose-textarea" class="form-control" name="body" style="height: 300px"> {{ old("body")!=null?old("body"):$mailbox->body }} </textarea> </div> <div class="form-group"> @include('pages.mailbox.includes.attachments', ['mailbox' => $mailbox]) <div class="btn btn-default btn-file"> <i class="fa fa-paperclip"></i> Attachments <input type="file" name="attachments[]" multiple> </div> <p class="help-block">Max. {{ (int)(ini_get('upload_max_filesize')) }}M</p> </div> </div> <!-- /.box-body --> <div class="box-footer"> <div class="pull-right"> <button type="submit" class="btn btn-default"><i class="fa fa-reply"></i> Send</button> </div> </div> <!-- /.box-footer --> </div> <!-- /. box --> </form> </div> <!-- /.col --> </div> <!-- /.row --> </section> @endsection @section('scripts') <script> $(function () { //Add text editor $("#compose-textarea").wysihtml5(); $("#receiver_id").select2({placeholder: "To:"}); }); </script> @endsection
Sending the draft Emails
You remember the compose form it has two buttons, the first which sends the message immediately and the other which save the message as a Draft which means that the message is saved but not sent to the recipients.
update the send() method in Mailbox controller
/** * send * * used to send a Draft message * * @param $id * @return \Illuminate\Http\RedirectResponse */ public function send($id) { $mailbox = Mailbox::find($id); $receiver_ids = $mailbox->tmpReceivers->pluck('receiver_id')->toArray(); //1. for sender // update user folder to be "Sent" $mailbox_user_folder = MailboxUserFolder::where('mailbox_id', $mailbox->id) ->where('user_id', Auth::user()->id)->first(); $mailbox_user_folder->folder_id = MailboxFolder::where("title", "Sent")->first()->id; $mailbox_user_folder->save(); //2. for the receivers // copy the receiver ids from tmp receiver table to the receiver table foreach ($receiver_ids as $receiver_id) { $mailbox_receiver = new MailboxReceiver(); $mailbox_receiver->mailbox_id = $mailbox->id; $mailbox_receiver->receiver_id = $receiver_id; $mailbox_receiver->save(); // save folder as "Inbox" $mailbox_user_folder = new MailboxUserFolder(); $mailbox_user_folder->mailbox_id = $mailbox->id; $mailbox_user_folder->user_id = $receiver_id; $mailbox_user_folder->folder_id = MailboxFolder::where("title", "Inbox")->first()->id; $mailbox_user_folder->save(); // save flags "is_unread=1" $mailbox_flag = new MailboxFlags(); $mailbox_flag->mailbox_id = $mailbox->id; $mailbox_flag->user_id = $receiver_id; $mailbox_flag->is_unread = 1; $mailbox_flag->save(); } // delete tmp receivers foreach ($mailbox->tmpReceivers as $tmpReceiver) { $tmpReceiver->delete(); } // send email $this->mailer->sendMailboxEmail($mailbox); return redirect('admin/mailbox/Sent')->with('flash_message', 'Message sent'); }
As you can see above i am doing the same steps as we have done in the store() methods. First we fetched the tmp receivers. Then for the sender we update the folder to be “Sent”, for the receivers i have looped over them inserting records in the receiver table, and receiver folders and receiver flags tables. Note that this method called for draft emails only.
Displaying single Email
Let’s update the show() method as shown:
/** * show email * * @param $id * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function show($id) { $folders = $this->folders; $unreadMessages = count(getUnreadMessages()); $mailbox = Mailbox::find($id); // $folder = $mailbox->userFolder()->folder()->first(); // if this message from "Inbox" then set is_unread=0 if(($flag = $mailbox->flag()) && isset($flag->is_unread) && $flag->is_unread == 1) { $flag->is_unread = 0; $flag->save(); } return view('pages.mailbox.show', compact('folders', 'unreadMessages', 'mailbox')); }
I make a check for the “is_unread” property and if it’s equal to “1” i update it to be “0” and save.
resources/views/pages/mailbox/show.blade.php
@extends('layout.app') @section('title', ' | Mailbox | Show Mail') @section('content') <section class="content-header"> <h1> Show Mail </h1> <ol class="breadcrumb"> <li><a href="{{ url('/admin') }}"><i class="fa fa-dashboard"></i> Dashboard</a></li> <li><a href="{{ url('/admin/mailbox') }}"> Mailbox</a></li> <li class="active">Show Mail</li> </ol> </section> <section class="content"> <div class="row"> <div class="col-md-3"> <a href="{{ url('admin/mailbox') }}" class="btn btn-primary btn-block margin-bottom">Back to inbox</a> @include('pages.mailbox.includes.folders_panel') </div> <div class="col-md-9"> <div class="box box-primary"> <div class="box-header with-border"> <h3 class="box-title">Read Mail</h3> </div> @include('includes.flash_message') <!-- /.box-header --> <div class="box-body no-padding"> <div class="mailbox-read-info"> <h3>{{ $mailbox->subject }}</h3> <h5>From: {{ $mailbox->sender->email }} <span class="mailbox-read-time pull-right">{{ !empty($mailbox->time_sent)?date("d M. Y h:i A", strtotime($mailbox->time_sent)):"not sent yet" }}</span></h5> </div> <!-- /.mailbox-controls --> <div class="mailbox-read-message"> {!! $mailbox->body !!} </div> <!-- /.mailbox-read-message --> </div> <!-- /.box-body --> <div class="box-footer"> @include('pages.mailbox.includes.attachments', ['mailbox' => $mailbox]) </div> </div> <!-- /. box --> @if($mailbox->replies->count() > 0) <h3>Replies</h3> @foreach($mailbox->replies as $reply) <div class="box box-primary"> <div class="box-header with-border"> <h3 class="box-title"><strong>From: </strong>{{ $reply->sender->name }}</h3> </div> <div class="box-body no-padding"> <div class="mailbox-read-info"> <h3>{{ $reply->subject }}</h3> <h5>From: {{ $reply->sender->email }} <span class="mailbox-read-time pull-right">{{ !empty($reply->time_sent)?date("d M. Y h:i A", strtotime($reply->time_sent)):"not sent yet" }}</span></h5> </div> <div class="mailbox-read-message"> {!! $reply->body !!} </div> </div> <div class="box-footer"> @include('pages.mailbox.includes.attachments', ['mailbox' => $reply]) </div> </div> @endforeach @endif </div> <!-- /.col --> </div> <!-- /.row --> </section> @endsection
resources/views/pages/mailbox/includes/attachments.blade.php
<ul class="mailbox-attachments clearfix"> @if($mailbox->attachments->count()) @foreach($mailbox->attachments as $attachment) <li> <span class="mailbox-attachment-icon"><i class="fa {{ in_array(pathinfo(public_path('uploads/mailbox/' . $attachment->attachment), PATHINFO_EXTENSION), ["jpg", "jpeg", "png", "gif"])?'fa-image':'fa-file' }}"></i></span> <div class="mailbox-attachment-info"> <a href="{{ url('uploads/mailbox/' . $attachment->attachment) }}" class="mailbox-attachment-name"><i class="fa fa-paperclip"></i> {{ $attachment->attachment }}</a> <span class="mailbox-attachment-size"> {{ filesize(public_path('uploads/mailbox/' . $attachment->attachment))/1024 }} KB <a href="{{ url('uploads/mailbox/' . $attachment->attachment) }}" class="btn btn-default btn-xs pull-right"><i class="fa fa-cloud-download"></i></a> </span> </div> </li> @endforeach @endif </ul>
Adjusting Permissions
Now after we finished the core functions of the mailbox let’s update the permissions so that authorized users only can access the mailbox so update the below files.
Update the Mailbox controller constructor to be like this:
public function __construct(MailerFactory $mailer) { $this->middleware('admin:index-list_emails|create-compose_email|show-view_email|toggleImportant-toggle_important_email|trash-trash_email|getReply-reply_email|getForward-forward_email|send-send_email', ['except' => ['store', 'postReply', 'postForward']]); $this->mailer = $mailer; $this->getFolders(); }
Open resources/views/pages/mailbox/index.blade.php replace this line
<a href="{{ url('admin/mailbox-create') }}" class="btn btn-primary btn-block margin-bottom">Compose</a>
with this line
@if(user_can('compose_email')) <a href="{{ url('admin/mailbox-create') }}" class="btn btn-primary btn-block margin-bottom">Compose</a> @endif
update resources/views/pages/includes/mailbox_controls.blade.php
<div class="mailbox-controls"> <!-- Check all button --> @if(Request::segment(3) != 'Trash') <button type="button" class="btn btn-default btn-sm checkbox-toggle"><i class="fa fa-square-o"></i> </button> @endif <div class="btn-group"> @if(Request::segment(3)==''||Request::segment(3)=='Inbox') @if(user_can("toggle_important_email")) <button type="button" class="btn btn-default btn-sm mailbox-star-all" title="toggle important state" style="display: {{user_can("toggle_important_email")?'inline':'none'}}"><i class="fa fa-star"></i></button> @endif @if(user_can("trash_email")) <button type="button" class="btn btn-default btn-sm mailbox-trash-all" title="add to trash" style="display: {{user_can("trash_email")?'inline':'none'}}"><i class="fa fa-trash-o"></i></button> @endif @if(user_can("reply_email")) <button type="button" class="btn btn-default btn-sm mailbox-reply" title="reply" style="display: {{user_can("reply_email")?'inline':'none'}}"><i class="fa fa-reply"></i></button> @endif @if(user_can("forward_email")) <button type="button" class="btn btn-default btn-sm mailbox-forward" title="forward" style="display: {{user_can("forward_email")?'inline':'none'}}"><i class="fa fa-mail-forward"></i></button> @endif @elseif(Request::segment(3) == 'Sent') @if(user_can("toggle_important_email")) <button type="button" class="btn btn-default btn-sm mailbox-star-all" title="toggle important state" style="display: {{user_can("toggle_important_email")?'inline':'none'}}"><i class="fa fa-star"></i></button> @endif @if(user_can("trash_email")) <button type="button" class="btn btn-default btn-sm mailbox-trash-all" title="add to trash" style="display: {{user_can("trash_email")?'inline':'none'}}"><i class="fa fa-trash-o"></i></button> @endif @if(user_can("forward_email")) <button type="button" class="btn btn-default btn-sm mailbox-forward" title="forward" style="display: {{user_can("forward_email")?'inline':'none'}}"><i class="fa fa-mail-forward"></i></button> @endif @elseif(Request::segment(3) == 'Drafts') @if(user_can("toggle_important_email")) <button type="button" class="btn btn-default btn-sm mailbox-star-all" title="toggle important state" style="display: {{user_can("toggle_important_email")?'inline':'none'}}"><i class="fa fa-star"></i></button> @endif @if(user_can("trash_email")) <button type="button" class="btn btn-default btn-sm mailbox-trash-all" title="add to trash" style="display: {{user_can("trash_email")?'inline':'none'}}"><i class="fa fa-trash-o"></i></button> @endif @if(user_can("send_email")) <button type="button" class="btn btn-default btn-sm mailbox-send" title="send" style="display: {{user_can("send_email")?'inline':'none'}}"><i class="fa fa-mail-forward"></i></button> @endif @endif </div> <div class="pull-right"> {{$messages->currentPage()}}-{{$messages->perPage()}}/{{$messages->total()}} <div class="btn-group"> {!! $messages->appends(['search' => Request::get('search')])->render('vendor.pagination.mailbox') !!} </div> <!-- /.btn-group --> </div> <!-- /.pull-right --> </div>
Sidebar
Update resources/views/layout/sidebar.blade.php
<!-- Left side column. contains the logo and sidebar --> <aside class="main-sidebar"> <!-- sidebar: style can be found in sidebar.less --> <section class="sidebar"> <!-- Sidebar user panel --> <div class="user-panel"> <div class="pull-left image"> @if(\Auth::user()->image != null) <img src="{{ url('uploads/users/' . \Auth::user()->image) }}" class="img-circle" alt="User Image"> @else <img src="{{ url('theme/dist/img/image_placeholder.png') }}" class="img-circle" alt="User Image"> @endif </div> <div class="pull-left info"> <p>{{ \Auth::user()->name }}</p> </div> </div> <!-- sidebar menu: : style can be found in sidebar.less --> <ul class="sidebar-menu" data-widget="tree"> <li class="header">MAIN NAVIGATION</li> <li class="{{ Request::segment(2) == ""?"active":"" }}"> <a href="{{ url('/admin') }}"> <i class="fa fa-dashboard"></i> <span>Dashboard</span> </a> </li> @if(user_can('list_contacts')) <li class="treeview {{ Request::segment(2) == 'contacts'? 'active':'' }}"> <a href="#"> <i class="fa fa-address-card"></i> <span>Accounts</span> <span class="pull-right-container"> <i class="fa fa-angle-left pull-right"></i> </span> </a> <ul class="treeview-menu"> <li class="{{ Request::segment(2) == "contacts" && request('status_name') == null?"active":"" }}"> <a href="{{ url('/admin/contacts') }}"><i class="fa fa-list"></i> All contacts</a> </li> <li class="{{ Request::segment(2) == "contacts" && request('status_name') == 'Lead'?"active":"" }}"> <a href="{{ url('/admin/contacts?status_name=Lead') }}"><i class="fa fa-leaf"></i> Leads</a> </li> <li class="{{ Request::segment(2) == "contacts" && request('status_name') == 'Opportunity'?"active":"" }}"> <a href="{{ url('/admin/contacts?status_name=Opportunity') }}"><i class="fa fa-flag"></i> Opportunities</a> </li> <li class="{{ Request::segment(2) == "contacts" && request('status_name') == 'Customer'?"active":"" }}"> <a href="{{ url('/admin/contacts?status_name=Customer') }}"><i class="fa fa-user-circle"></i> Customers</a> </li> <li class="{{ Request::segment(2) == "contacts" && request('status_name') == 'Close'?"active":"" }}"> <a href="{{ url('/admin/contacts?status_name=Close') }}"><i class="fa fa-ban"></i> Close</a> </li> </ul> </li> @endif @if(user_can('list_documents')) <li class="{{ Request::segment(2) == "documents"?"active":"" }}"> <a href="{{ url('/admin/documents') }}"> <i class="fa fa-file-word-o"></i> <span>Documents</span> </a> </li> @endif @if(user_can('list_tasks')) <li class="{{ Request::segment(2) == "tasks"?"active":"" }}"> <a href="{{ url('/admin/tasks') }}"> <i class="fa fa-tasks"></i> <span>Tasks</span> </a> </li> @endif @if(user_can('list_emails') || user_can('compose_email')) <li class="treeview {{ Request::segment(2) == 'mailbox' || strpos(Request::segment(2), "mailbox")!==FALSE? 'active':'' }}"> <a href="#"> <i class="fa fa-envelope"></i> <span>Mailbox</span> <span class="pull-right-container"> <i class="fa fa-angle-left pull-right"></i> </span> </a> <ul class="treeview-menu"> @if(user_can('list_emails')) <li class="{{ Request::segment(2) == "mailbox" || Request::segment(3)=="" || Request::segment(3)=="Inbox"?"active":"" }}"> <a href="{{ url('/admin/mailbox') }}"> Inbox @if(count(getUnreadMessages()) > 0) <span class="pull-right-container"> <span class="label label-primary pull-right">{{count(getUnreadMessages())}}</span> </span> @endif </a> </li> @endif @if(user_can('compose_email')) <li class="{{ Request::segment(2) == "mailbox-create"?"active":"" }}"> <a href="{{ url('/admin/mailbox-create') }}"> Compose </a> </li> @endif </ul> </li> @endif @if(\Auth::user()->is_admin == 1) <li class="{{ in_array(Request::segment(2), ['users', 'permissions', 'roles'])?"active":"" }} treeview"> <a href="#"> <i class="fa fa-users"></i> <span>User Managment</span> <span class="pull-right-container"> <i class="fa fa-angle-left pull-right"></i> </span> </a> <ul class="treeview-menu"> <li class="{{ Request::segment(2) == "users"?"active":"" }}"> <a href="{{ url('/admin/users') }}"><i class="fa fa-user-o"></i> Users</a> </li> <li class="{{ Request::segment(2) == "permissions"?"active":"" }}"> <a href="{{ url('/admin/permissions') }}"><i class="fa fa-ban"></i> Permissions</a> </li> <li class="{{ Request::segment(2) == "roles"?"active":"" }}"> <a href="{{ url('/admin/roles') }}"><i class="fa fa-list"></i> Roles</a> </li> </ul> </li> @endif </ul> </section> <!-- /.sidebar --> </aside>
Email Header Notifications
To finish up this part we will show the email header notifications which display in the top icon located in the header. This icon shows a count for the unread messages according to the current logged in user and if you click on it it will show these messages.
Update resources/views/layout/header.blade.php
<header class="main-header"> <!-- Logo --> <a href="{{ url('/admin') }}" class="logo"> <!-- mini logo for sidebar mini 50x50 pixels --> <span class="logo-mini"><b>M</b>CRM</span> <!-- logo for regular state and mobile devices --> <span class="logo-lg"><b>Mini</b>CRM</span> </a> <!-- Header Navbar: style can be found in header.less --> <nav class="navbar navbar-static-top"> <!-- Sidebar toggle button--> <a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button"> <span class="sr-only">Toggle navigation</span> </a> <div class="navbar-custom-menu"> <ul class="nav navbar-nav"> <!-- Messages: style can be found in dropdown.less--> @if(user_can("show_email_notifications")) <li class="dropdown messages-menu"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <i class="fa fa-envelope-o"></i> <span class="label label-success">{{ count(getUnreadMessages()) }}</span> </a> <ul class="dropdown-menu"> @if(count(getUnreadMessages()) == 0) <li class="header">You have no messages</li> @else <li class="header">You have {{ count(getUnreadMessages()) }} messages</li> <li> <!-- inner menu: contains the actual data --> <ul class="menu"> @foreach(getUnreadMessages() as $message) <li><!-- start message --> <a href="{{ url('/admin/mailbox-show/' . $message->id) }}"> <div class="pull-left"> @if(!empty($message->sender->image) && file_exists(public_path('uploads/users/' . $message->sender->image))) <img src="{{ url('uploads/users/' . $message->sender->image) }}" class="img-circle" alt="User Image"> @else <img src="{{ url('theme/dist/img/image_placeholder.png') }}" class="img-circle" alt="User Image"> @endif </div> <h4> {{ $message->sender->name }} <small><i class="fa fa-clock-o"></i> {{ Carbon\Carbon::parse($message->time_sent)->diffForHumans() }}</small> </h4> <p>{{ $message->subject }}</p> </a> </li> @endforeach <!-- end message --> </ul> </li> <li class="footer"><a href="{{ url('admin/mailbox/Inbox') }}">See All Messages</a></li> @endif </ul> </li> @endif <!-- User Account: style can be found in dropdown.less --> <li class="dropdown user user-menu"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> @if(\Auth::user()->image != null) <img src="{{ url('uploads/users/' . \Auth::user()->image) }}" width="160" height="160" class="user-image" alt="User Image"> @else <img src="{{ url('theme/dist/img/image_placeholder.png') }}" class="user-image" alt="User Image"> @endif <span class="hidden-xs">{{ \Auth::user()->name }}</span> </a> <ul class="dropdown-menu"> <!-- User image --> <li class="user-header"> @if(\Auth::user()->image != null) <img src="{{ url('uploads/users/' . \Auth::user()->image) }}" width="160" height="160" class="img-circle" alt="User Image"> @else <img src="{{ url('theme/dist/img/image_placeholder.png') }}" class="img-circle" alt="User Image"> @endif <p> {{ \Auth::user()->name . (\Auth::user()->position_title!=''?' - ' . \Auth::user()->position_title:'') }} @if(\Auth::user()->created_at != null) <small>Member since {{ \Auth::user()->created_at->diffForHumans() }}</small> @endif </p> </li> <!-- Menu Footer--> <li class="user-footer"> <div class="pull-left"> <a href="{{ url('admin/my-profile') }}" class="btn btn-default btn-flat">Profile</a> </div> <div class="pull-right"> <a href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();" class="btn btn-default btn-flat">Sign out</a> <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;"> @csrf </form> </div> </li> </ul> </li> </ul> </div> </nav> </header>
Continue to Part 12: Calendar Module>>>