diff --git a/app/Http/Controllers/Admin/ShipmentController.php b/app/Http/Controllers/Admin/ShipmentController.php index 0eab511..6feffef 100644 --- a/app/Http/Controllers/Admin/ShipmentController.php +++ b/app/Http/Controllers/Admin/ShipmentController.php @@ -224,5 +224,81 @@ class ShipmentController extends Controller return view('admin.view_shipment', compact('shipment', 'dummyData')); } + // App\Models\Shipment.php + +public function orders() +{ + return $this->belongsToMany(\App\Models\Order::class, 'shipment_items', 'shipment_id', 'order_id'); +} + +public function removeOrder(Shipment $shipment, Order $order) +{ + // Remove row from pivot table shipment_items + ShipmentItem::where('shipment_id', $shipment->id) + ->where('order_id', $order->id) + ->delete(); // removes link shipment <-> order [web:41][web:45] + + // Recalculate totals on this shipment (optional but recommended) + $orders = Order::whereIn( + 'id', + ShipmentItem::where('shipment_id', $shipment->id)->pluck('order_id') + )->get(); + + $shipment->total_ctn = $orders->sum('ctn'); + $shipment->total_qty = $orders->sum('qty'); + $shipment->total_ttl_qty = $orders->sum('ttl_qty'); + $shipment->total_cbm = $orders->sum('cbm'); + $shipment->total_ttl_cbm = $orders->sum('ttl_cbm'); + $shipment->total_kg = $orders->sum('kg'); + $shipment->total_ttl_kg = $orders->sum('ttl_kg'); + $shipment->total_amount = $orders->sum('ttl_amount'); + $shipment->save(); + + // Redirect back to preview page where your blade is loaded + return redirect() + ->route('admin.shipments.dummy', $shipment->id) + ->with('success', 'Order removed from shipment successfully.'); +} + +public function addOrders(Request $request, Shipment $shipment) +{ + $request->validate([ + 'order_ids' => 'required|array|min:1', + ]); + + // फक्त न वापरलेले orders घ्या + $orders = Order::whereIn('id', $request->order_ids)->get(); + + foreach ($orders as $order) { + // pivot मध्ये insert + ShipmentItem::create([ + 'shipment_id' => $shipment->id, + 'order_id' => $order->id, + 'order_ctn' => $order->ctn, + 'order_qty' => $order->qty, + 'order_ttl_qty' => $order->ttl_qty, + 'order_ttl_amount' => $order->ttl_amount, + 'order_ttl_kg' => $order->ttl_kg, + ]); + } + + // totals + $orderIds = ShipmentItem::where('shipment_id', $shipment->id)->pluck('order_id'); + $allOrders = Order::whereIn('id', $orderIds)->get(); + + $shipment->total_ctn = $allOrders->sum('ctn'); + $shipment->total_qty = $allOrders->sum('qty'); + $shipment->total_ttl_qty = $allOrders->sum('ttl_qty'); + $shipment->total_cbm = $allOrders->sum('cbm'); + $shipment->total_ttl_cbm = $allOrders->sum('ttl_cbm'); + $shipment->total_kg = $allOrders->sum('kg'); + $shipment->total_ttl_kg = $allOrders->sum('ttl_kg'); + $shipment->total_amount = $allOrders->sum('ttl_amount'); + $shipment->save(); + + return redirect() + ->route('admin.shipments.dummy', $shipment->id) + ->with('success', 'Orders added to shipment successfully.'); +} } \ No newline at end of file diff --git a/resources/views/admin/chat_support.blade.php b/resources/views/admin/chat_support.blade.php index 9add999..623fa65 100644 --- a/resources/views/admin/chat_support.blade.php +++ b/resources/views/admin/chat_support.blade.php @@ -1,96 +1,605 @@ @extends('admin.layouts.app') -@section('page-title', 'Chat Support') +@section('page-title', 'Chat Support Dashboard') @section('content') + + +
+ +
+

Live Chat Dashboard

+

+ Monitor customer conversations with real-time updates +

- - - @endforeach - - - @endif - + +
+
+
💬
+
+

{{ $tickets->count() }}

+

Total Conversations

+
+
+
📈
+
+

{{ $tickets->where('status', 'open')->count() }}

+

Active Tickets

+
+
+
+
+
+

{{ $tickets->where('status', 'closed')->count() }}

+

Resolved Tickets

+
+
+
+ + +
+
+
+

+ 📋 Active Conversations + {{ $tickets->count() }} +

+
+
+ + @if($tickets->count() === 0) + +
+
💬
+

No Active Conversations

+

+ Customer conversations will appear here with real-time notifications. +

+
Ready for support requests
+
+ @else + +
+ @foreach($tickets as $ticket) +
+ @if($ticket->unread_count > 0) +
+ @endif + +
+
+ {{ strtoupper(substr($ticket->user->customer_name ?? $ticket->user->name, 0, 1)) }} +
+
+
+ {{ $ticket->user->customer_name ?? $ticket->user->name }} + @if($ticket->unread_count > 0) + + {{ $ticket->unread_count }} + + @endif +
+ + @php + $lastMsg = $ticket->messages()->latest()->first(); + @endphp + +
+ @if($lastMsg) + @if($lastMsg->message) + {{ Str::limit($lastMsg->message, 55) }} + @elseif(Str::startsWith($lastMsg->file_type, 'image')) + 📷 Photo shared + @else + 📎 File attached + @endif + @else + Conversation started + @endif +
+ + @if($lastMsg) +
+ + + + + {{ $lastMsg->created_at->diffForHumans() }} +
+ @endif +
+
#{{ $ticket->id }}
+
+ + +
+ @endforeach +
+ @endif
+@endsection + @section('scripts') -@endsection - - - -@endsection +@endsection \ No newline at end of file diff --git a/resources/views/admin/chat_window.blade.php b/resources/views/admin/chat_window.blade.php index 2dec287..d908aa8 100644 --- a/resources/views/admin/chat_window.blade.php +++ b/resources/views/admin/chat_window.blade.php @@ -3,132 +3,828 @@ @section('page-title', 'Chat With ' . ($ticket->user->customer_name ?? $ticket->user->name)) @section('content') - -
- -
-

- Chat With: {{ $ticket->user->customer_name ?? $ticket->user->name }} -

- - {{ ucfirst($ticket->status) }} - -
- -
- - @foreach($messages as $msg) -
- - {{-- TEXT --}} - @if($msg->message) -
{{ $msg->message }}
- @endif - - {{-- FILE --}} - @if($msg->file_path) - - @php - $isImage = Str::startsWith($msg->file_type, 'image'); - $isVideo = Str::startsWith($msg->file_type, 'video'); - @endphp - - {{-- IMAGE --}} - @if($isImage) - - - {{-- VIDEO --}} - @elseif($isVideo) - - - {{-- PDF / EXCEL / OTHER --}} - @else - - 📎 View Attachment - - @endif - - @endif - - - - {{ $msg->created_at->format('d M h:i A') }} - +
+
+
+
+ +
+ + {{ ucfirst($ticket->status) }} + + + + + + Back + +
- @endforeach +
-
+ {{-- Messages --}} +
+
+ @foreach($messages as $msg) +
+ @if($msg->message) +
{{ $msg->message }}
+ @endif -
-
-
- - - + @if($msg->file_path) + @php + $isImage = Str::startsWith($msg->file_type, 'image'); + $isVideo = Str::startsWith($msg->file_type, 'video'); + $isPdf = Str::endsWith($msg->file_path, '.pdf'); + $isDocument = in_array(Str::lower(Str::afterLast($msg->file_path, '.')), ['doc', 'docx', 'txt']); + $fileName = basename($msg->file_path); + + // Get file size from storage if possible + $fileSize = 'N/A'; + try { + $fullPath = storage_path('app/public/' . $msg->file_path); + if (file_exists($fullPath)) { + $size = filesize($fullPath); + if ($size < 1024) { + $fileSize = $size . ' B'; + } elseif ($size < 1048576) { + $fileSize = round($size / 1024, 1) . ' KB'; + } else { + $fileSize = round($size / 1048576, 1) . ' MB'; + } + } + } catch (Exception $e) { + $fileSize = 'Unknown'; + } + + // Determine file class + if ($isImage) { + $fileClass = 'image-file'; + $fileIcon = '🖼️'; + } elseif ($isVideo) { + $fileClass = 'video-file'; + $fileIcon = '🎬'; + } elseif ($isPdf) { + $fileClass = 'pdf-file'; + $fileIcon = '📄'; + } elseif ($isDocument) { + $fileClass = 'document-file'; + $fileIcon = '📝'; + } else { + $fileClass = 'other-file'; + $fileIcon = '📎'; + } + @endphp + +
+ @if($isImage) + {{ $fileName }} + @elseif($isVideo) + + @endif + + +
+ {{ $fileIcon }} +
+
+
{{ $fileName }}
+
{{ $fileSize }}
+
+
+ + + +
+
+
+ @endif + + + {{ $msg->created_at->format('d M h:i A') }} + +
+ @endforeach + +
+ + + +
+
+
+ + {{-- Input --}} +
+
+ + +
+
+ + +
+ + +
+
+ +
-
- @endsection - @section('scripts') - - - - -@endsection +@endsection \ No newline at end of file diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index f2d54a5..4113081 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -333,6 +333,13 @@ body, .container-fluid { border-color: #f59e0b !important; } +.badge-loading { + background: linear-gradient(135deg, #e3f2fd, #90caf9) !important; + color: #1565c0 !important; + border-color: #2196f3 !important; + width: 110px; +} + /* In Transit Status - SAME SIZE WITH TRUCK ICON */ .badge-in_transit { background: linear-gradient(135deg, #dbeafe, #93c5fd) !important; @@ -1101,6 +1108,7 @@ body, .container-fluid { break-inside: avoid; } } +
diff --git a/resources/views/admin/orders_show.blade.php b/resources/views/admin/orders_show.blade.php index d430814..ca2b532 100644 --- a/resources/views/admin/orders_show.blade.php +++ b/resources/views/admin/orders_show.blade.php @@ -13,47 +13,54 @@

Order Details

+ @php + $status = strtolower($order->status ?? ''); + @endphp + Detailed view of this shipment order
{{-- ADD ITEM --}} @can('order.create') - + @if($status === 'pending') + + @endif @endcan +
+
+ {{-- Edit Order --}} + @if($status === 'pending') + + @endif - {{-- EDIT ORDER --}} --> - + {{-- Delete Order --}} + @if($status === 'pending') +
+ @csrf + @method('DELETE') + +
+ @endif +
- - - +
@@ -190,32 +197,33 @@ {{ $item->ttl_kg }} {{ $item->shop_no }} - + + @if($status === 'pending') + {{-- EDIT BUTTON --}} + @can('order.edit') + + @endcan - {{-- EDIT BUTTON --}} - @can('order.edit') - - @endcan + {{-- DELETE BUTTON --}} + @can('order.delete') +
+ @csrf + @method('DELETE') + +
+ @endcan + @endif + - @can('order.delete') - {{-- DELETE BUTTON --}} -
- @csrf - @method('DELETE') - -
- @endcan - @endforeach @@ -617,7 +625,7 @@ function fillFormFromDeleted(item) { box-shadow: 0 4px 15px 0 rgba(102, 126, 234, 0.3); position: relative; overflow: hidden; - margin-right: -800px; + margin-right: -650px; } .btn-add-item:hover { diff --git a/resources/views/admin/shipments.blade.php b/resources/views/admin/shipments.blade.php index 4fa2ad0..b3565a9 100644 --- a/resources/views/admin/shipments.blade.php +++ b/resources/views/admin/shipments.blade.php @@ -1297,9 +1297,10 @@ {{ \Carbon\Carbon::parse($ship->shipment_date)->format('d M Y') }} - + @@ -1596,13 +1597,13 @@ function renderTable() { ${new Date(shipment.shipment_date).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' })} - - +
-
-
- - {{-- Stage 2 --}} -
-
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
-
- - {{-- Stage 3 --}} -
-
- - -
If left blank employee id will be used.
-
- -
- - -
- -
- - -
-
- - {{-- Stage 4 --}} -
-
Permissions
- - @foreach($permissions as $group => $groupPerms) -
-
-
{{ ucfirst($group) }}
-
- + +
+ +
+
+
👨‍💼
+

Add New Staff Member

+

Complete all the steps below to add a new staff member to your team

-
- -
- @foreach($groupPerms as $perm) - - @endforeach -
- @endforeach -
- - -
+ +
+
+
1
+
Personal
+
+
+
2
+
Professional
+
+
+
3
+
Account
+
+
+
4
+
Permissions
+
+
+ + + @if($errors->any()) +
+
+ ⚠️ + Please fix the following errors +
+
    + @foreach($errors->all() as $err) +
  • {{ $err }}
  • + @endforeach +
+
+ @endif + + + @csrf + + +
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ + +
+ + +
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ + +
+
+ +
+ + +
+
+ + +
+ + +
+
+
+ + +
+ ℹ️ + If left blank, username will be generated from employee ID +
+
+ +
+ + +
+
+
+
+ 🔒 + Minimum 8 characters with letters and numbers +
+
+ +
+ + +
+
+ + +
+ + +
+
+

🔐 Set Access Permissions

+

Select the permissions you want to grant to this staff member.

+
+ +
+ @foreach($permissions as $group => $groupPerms) +
+
+

{{ ucfirst($group) }}

+ +
+
+ @foreach($groupPerms as $perm) + + @endforeach +
+
+ @endforeach +
+ + +
+
-
-@endsection +@endsection \ No newline at end of file diff --git a/resources/views/admin/staff/edit.blade.php b/resources/views/admin/staff/edit.blade.php index d6fc451..09bb26a 100644 --- a/resources/views/admin/staff/edit.blade.php +++ b/resources/views/admin/staff/edit.blade.php @@ -1,156 +1,896 @@ @extends('admin.layouts.app') -@section('page-title', 'Account Dashboard') +@section('page-title', 'Edit Staff') @section('content') -
-

Edit Staff — {{ $staff->display_name ?? $staff->name }}

- - @if($errors->any()) -
- There were some problems with your input: -
    - @foreach($errors->all() as $err) -
  • {{ $err }}
  • - @endforeach -
-
- @endif - -
- @csrf - @method('PUT') - -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- -
- - -
- -
- - -
- -
- -
Permissions
- - @foreach($permissions as $group => $groupPerms) -
-
-
{{ ucfirst($group) }}
-
- -
+
+ +
+ +
+
+
+ {{ strtoupper(substr($staff->name, 0, 2)) }} +
+
+

Edit Staff Profile

+
{{ $staff->name }}
+
{{ $staff->employee_id }}
-
- @foreach($groupPerms as $perm) - - @endforeach -
-
- @endforeach + + @if($errors->any()) +
+
+ ⚠️ + There were some problems with your input +
+
    + @foreach($errors->all() as $err) +
  • {{ $err }}
  • + @endforeach +
+
+ @endif -
- Cancel - + + @csrf + @method('PUT') + + +
+
+
👤
+

Personal Information

+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+ + +
+
+
💼
+

Professional Information

+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ + +
+
+
+
+ + +
+
+
🔐
+

Account Information

+
+
+
+ + +
+ +
+ + +
+
+
+
+ +
+ + +
+
+
+ + +
+
+
📝
+

Additional Information

+
+
+
+ + +
+
+
+ + +
+
+
🔑
+

Permissions & Access

+
+ +
+ @foreach($permissions as $group => $groupPerms) +
+
+

{{ ucfirst($group) }}

+ +
+
+ @foreach($groupPerms as $perm) + + @endforeach +
+
+ @endforeach +
+
+ + +
+ + + Cancel + + +
+
-
-@endsection +@endsection \ No newline at end of file diff --git a/resources/views/admin/staff/index.blade.php b/resources/views/admin/staff/index.blade.php index 479014d..184a2a2 100644 --- a/resources/views/admin/staff/index.blade.php +++ b/resources/views/admin/staff/index.blade.php @@ -1,65 +1,896 @@ @extends('admin.layouts.app') -@section('page-title', 'Account Dashboard') +@section('page-title', 'Staff Management Dashboard') @section('content') -
-

Staff

- Add Staff +
+ + @if(session('success')) +
+ {{ session('success') }} +
+ @endif + + {{-- Stats Cards --}} +
+
+
+ 👥 +
+
+

{{ $staff->count() }}

+

Total Staff

+
+
+
+
+ ✅ +
+
+

{{ $staff->where('status', 'active')->count() }}

+

Active Staff

+
+
+
+
+ 👑 +
+
+

{{ $staff->unique('role')->count() }}

+

Unique Roles

+
+
+
+ + {{-- Search Bar --}} +
+ 🔍 + +
+ +
+ + + + Add Staff + +
+ + {{-- Staff Table --}} +
+
+
Staff Management
+
+ +
+
+ + + + + + + + + + + + + + + + @php + $totalStaff = count($staff); + @endphp + @forelse($staff as $s) + + + + + + + + + + + @empty + + + + @endforelse + +
#Employee IDNameEmailPhoneRoleStatusActions
{{ $totalStaff - $loop->index }} + {{ $s->employee_id }} + +
+
+ {{ strtoupper(substr($s->name, 0, 1)) }} +
+ {{ $s->name }} +
+
{{ $s->email }}{{ $s->phone ?? '-' }} + @if($s->role) + {{ $s->role }} + @else + - + @endif + + + {{ ucfirst($s->status) }} + + +
+ + + Edit + +
+ @csrf + @method('DELETE') + +
+
+
+
+ No staff members found +
+
+
+ + {{-- Pagination --}} +
+
+ Showing 1 to {{ $staff->count() }} of {{ $staff->count() }} entries +
+
+ +
+ +
+ +
+
+
+
-
- @if(session('success')) -
{{ session('success') }}
- @endif + +@endsection \ No newline at end of file diff --git a/resources/views/admin/view_shipment.blade.php b/resources/views/admin/view_shipment.blade.php index f46f1cc..143f233 100644 --- a/resources/views/admin/view_shipment.blade.php +++ b/resources/views/admin/view_shipment.blade.php @@ -3,32 +3,964 @@ @section('page-title', 'Shipment Preview') @section('content') + + +
+
+
+

- Shipment Preview: {{ $shipment->shipment_id }} -

+ Shipment Details - {{ $shipment->shipment_id }} + + + {{-- SHOW BUTTON ONLY FOR PENDING --}} + @if($shipment->status === 'pending') + + @endif
-
- - -
- {{ $dummyData['title'] }}
- Generated On: {{ $dummyData['generated_on'] }}
- Note: {{ $dummyData['note'] }} -
- - -
Shipment Details
- +
+ + Shipment Information +
+
+ - - + + @@ -40,89 +972,608 @@ - + -
Shipment ID{{ $shipment->shipment_id }}Shipment ID{{ $shipment->shipment_id }}
Origin
Status{{ ucfirst($shipment->status) }} + @php + $statusColors = [ + 'pending' => 'warning', + 'loading' => 'info', + 'in_transit' => 'primary', + 'dispatched' => 'success', + 'delivered' => 'success', + ]; + $statusColor = $statusColors[$shipment->status] ?? 'secondary'; + @endphp + + {{ ucfirst(str_replace('_', ' ', $shipment->status)) }} + +
Date {{ \Carbon\Carbon::parse($shipment->shipment_date)->format('d M Y') }}
+ + - -
Orders Contained in Shipment
+
+ + Orders Contained in Shipment +
- @if($shipment->orders->isEmpty()) -

No orders found.

- @else -
- - - - - - - - - - - - - - - @foreach($shipment->orders as $order) - - - - - - - - - - - @endforeach + @if($shipment->orders->isEmpty()) +
+ + No orders found in this shipment. +
+ @else +
+
Order IDOriginDestinationCTNQTYTTL/QTYKGAmount
{{ $order->order_id }}{{ $order->origin }}{{ $order->destination }}{{ $order->ctn }}{{ $order->qty }}{{ $order->ttl_qty }}{{ $order->ttl_kg }}₹{{ number_format($order->ttl_amount, 2) }}
+ + + + + + + + + + + + + + + + + -
Order IDOriginDestinationMark NoDescriptionCTNQTYTTL/QTYKGTTL/KGAmountRemove
+ +
+ +
+
+ Showing 1 to 0 of + 0 entries
- @endif +
+ +
+
+ +
+
+ @endif - -
Shipment Totals
- - - - - - - - - - - - - - - - - - - - - - - - - -
Total CTN{{ $shipment->total_ctn }}
Total Quantity{{ $shipment->total_qty }}
Total TTL Quantity{{ $shipment->total_ttl_qty }}
Total CBM{{ $shipment->total_cbm }}
Total KG{{ $shipment->total_kg }}
Total Amount - ₹{{ number_format($shipment->total_amount, 2) }} -
+
+ + Shipment Totals +
+
+
+ + + + + + + + + + + + + + + +
Total CTN{{ $shipment->total_ctn }}
Total QTY{{ $shipment->total_qty }}
Total TTL QTY{{ $shipment->total_ttl_qty }}
+
+
+ + + + + + + + + + + + + + + +
Total CBM{{ $shipment->total_cbm }}
Total KG{{ $shipment->total_kg }}
Total TTL KG{{ $shipment->total_ttl_kg }}
+
+
- - ← Back to Shipments +
+
+ + Total Amount: + ₹{{ number_format($shipment->total_amount, 2) }} +
+
+ +
-@endsection + + + +@endsection \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 6f8c487..eb68c01 100644 --- a/routes/web.php +++ b/routes/web.php @@ -175,11 +175,21 @@ Route::prefix('admin') // Shipment Delete Route::delete('/shipments/{id}', [ShipmentController::class, 'destroy']) ->name('admin.shipments.destroy'); + + Route::get('/shipment/dummy/{id}', [ShipmentController::class, 'dummy']) + ->name('admin.shipments.dummy'); + // web.php + Route::delete('/shipments/{shipment}/orders/{order}', + [ShipmentController::class, 'removeOrder'] + )->name('admin.shipments.removeOrder'); + + Route::post('/shipments/{shipment}/add-orders', + [ShipmentController::class, 'addOrders'] + )->name('admin.shipments.addOrders'); Route::get('/shipment/dummy/{id}', [ShipmentController::class, 'dummy']) ->name('admin.shipments.dummy'); - // --------------------------- // INVOICES // --------------------------- @@ -207,8 +217,8 @@ Route::prefix('admin') ->name('admin.invoice.installment.delete'); - // //Add New Invoice - // Route::get('/admin/invoices/create', [InvoiceController::class, 'create'])->name('admin.invoices.create'); + //Add New Invoice + Route::get('/admin/invoices/create', [InvoiceController::class, 'create'])->name('admin.invoices.create'); // ---------------------------