Added visitor controller page and badge blade file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
This commit is contained in:
21
app/Http/Controllers/VisitorBadgeController.php
Normal file
21
app/Http/Controllers/VisitorBadgeController.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\VisitorEntry;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class VisitorBadgeController extends Controller
|
||||||
|
{
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
$visitor = VisitorEntry::with('employeeMaster')->findOrFail($id);
|
||||||
|
|
||||||
|
$photoUrl = $visitor->photo
|
||||||
|
? Storage::disk('public')->url($visitor->photo)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return view('visitor.badge', compact('visitor', 'photoUrl'));
|
||||||
|
}
|
||||||
|
}
|
||||||
222
resources/views/visitor/badge.blade.php
Normal file
222
resources/views/visitor/badge.blade.php
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Visitor Badge</title>
|
||||||
|
<style>
|
||||||
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
|
||||||
|
@page {
|
||||||
|
size: 80mm 50mm;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
width: 80mm;
|
||||||
|
height: 50mm;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 7pt;
|
||||||
|
background: #fff;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
width: 80mm;
|
||||||
|
height: 50mm;
|
||||||
|
border: 1px solid #333;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Header bar ── */
|
||||||
|
.badge-header {
|
||||||
|
background: #1a1a2e;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
padding: 2mm 2mm 1.5mm;
|
||||||
|
font-size: 8pt;
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-header .type {
|
||||||
|
font-size: 9pt;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-header .badge-id {
|
||||||
|
font-size: 7pt;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Body ── */
|
||||||
|
.badge-body {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
padding: 2mm;
|
||||||
|
gap: 2mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Fields (left) ── */
|
||||||
|
.badge-fields {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.2mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 1mm;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-label {
|
||||||
|
color: #555;
|
||||||
|
min-width: 14mm;
|
||||||
|
font-size: 6.5pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-value {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 6.5pt;
|
||||||
|
color: #111;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Photo (right) ── */
|
||||||
|
.badge-photo {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1mm;
|
||||||
|
width: 18mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-photo img {
|
||||||
|
width: 16mm;
|
||||||
|
height: 18mm;
|
||||||
|
object-fit: cover;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-photo .no-photo {
|
||||||
|
width: 16mm;
|
||||||
|
height: 18mm;
|
||||||
|
border: 1px dashed #aaa;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 5.5pt;
|
||||||
|
color: #aaa;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.host-sign {
|
||||||
|
font-size: 5.5pt;
|
||||||
|
color: #555;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 0.5px solid #aaa;
|
||||||
|
padding-top: 0.5mm;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Footer ── */
|
||||||
|
.badge-footer {
|
||||||
|
border-top: 0.5px solid #ddd;
|
||||||
|
padding: 1mm 2mm;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 5.5pt;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||||
|
.no-print { display: none !important; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body onload="window.print()">
|
||||||
|
|
||||||
|
{{-- ── Print button (visible on screen only, hidden when printing) ── --}}
|
||||||
|
<div class="no-print" style="padding: 8px; text-align:center; background:#f3f4f6;">
|
||||||
|
<button onclick="window.print()" style="padding:6px 18px; background:#1a1a2e; color:#fff; border:none; border-radius:6px; cursor:pointer; font-size:13px;">
|
||||||
|
🖨️ Print Badge
|
||||||
|
</button>
|
||||||
|
<button onclick="window.close()" style="padding:6px 18px; background:#e5e7eb; color:#333; border:none; border-radius:6px; cursor:pointer; font-size:13px; margin-left:8px;">
|
||||||
|
✕ Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="badge">
|
||||||
|
|
||||||
|
{{-- Header --}}
|
||||||
|
<div class="badge-header">
|
||||||
|
<span class="type">{{ strtoupper($visitor->type ?? 'VISITOR') }}</span>
|
||||||
|
<span class="badge-id">#{{ str_pad($visitor->id, 5, '0', STR_PAD_LEFT) }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Body --}}
|
||||||
|
<div class="badge-body">
|
||||||
|
|
||||||
|
{{-- Left: fields --}}
|
||||||
|
<div class="badge-fields">
|
||||||
|
<div class="field-row">
|
||||||
|
<span class="field-label">Name:</span>
|
||||||
|
<span class="field-value">{{ strtoupper($visitor->name) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<span class="field-label">Company:</span>
|
||||||
|
<span class="field-value">{{ $visitor->company }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<span class="field-label">To Meet:</span>
|
||||||
|
<span class="field-value">{{ strtoupper($visitor->employeeMaster?->name ?? '—') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<span class="field-label">Dept:</span>
|
||||||
|
<span class="field-value">
|
||||||
|
{{ strtoupper($visitor->employeeMaster?->department ?? $visitor->department ?? '—') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<span class="field-label">Valid upto:</span>
|
||||||
|
<span class="field-value">
|
||||||
|
{{ $visitor->out_time ? \Carbon\Carbon::parse($visitor->out_time)->format('d/m/Y H:i') : '—' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<span class="field-label">Date&Time:</span>
|
||||||
|
<span class="field-value">
|
||||||
|
{{ $visitor->in_time ? \Carbon\Carbon::parse($visitor->in_time)->format('d/m/Y H:i') : '—' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-row">
|
||||||
|
<span class="field-label">No of Visitor:</span>
|
||||||
|
<span class="field-value">{{ $visitor->number_of_person ?? 1 }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Right: photo + host sign --}}
|
||||||
|
<div class="badge-photo">
|
||||||
|
@if($photoUrl)
|
||||||
|
<img src="{{ $photoUrl }}" alt="Visitor Photo" />
|
||||||
|
@else
|
||||||
|
<div class="no-photo">No Photo</div>
|
||||||
|
@endif
|
||||||
|
<div class="host-sign">Host Sign</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Footer --}}
|
||||||
|
<div class="badge-footer">Mobile: {{ $visitor->mobile_number }}</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
use App\Http\Controllers\CharacteristicApprovalController;
|
use App\Http\Controllers\CharacteristicApprovalController;
|
||||||
use App\Http\Controllers\ProductionOrderController;
|
use App\Http\Controllers\ProductionOrderController;
|
||||||
// use App\Http\Controllers\FileUploadController;
|
// use App\Http\Controllers\FileUploadController;
|
||||||
|
use App\Http\Controllers\VisitorBadgeController;
|
||||||
use App\Models\EquipmentMaster;
|
use App\Models\EquipmentMaster;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Filament\Facades\Filament;
|
use Filament\Facades\Filament;
|
||||||
@@ -65,6 +66,8 @@ Route::get('production-orders/{production_order}/{plant_code}/printItemSerial',
|
|||||||
[ProductionOrderController::class, 'printItemSerial']
|
[ProductionOrderController::class, 'printItemSerial']
|
||||||
)->name('production-orders.printItemSerial');
|
)->name('production-orders.printItemSerial');
|
||||||
|
|
||||||
|
Route::get('/visitor-badge/{id}', [VisitorBadgeController::class, 'show'])
|
||||||
|
->name('visitor.badge');
|
||||||
// Route::get('/characteristic/approve', [CharacteristicApprovalController::class, 'approve'])
|
// Route::get('/characteristic/approve', [CharacteristicApprovalController::class, 'approve'])
|
||||||
// ->name('characteristic.approve')
|
// ->name('characteristic.approve')
|
||||||
// ->middleware('signed');
|
// ->middleware('signed');
|
||||||
|
|||||||
Reference in New Issue
Block a user