10 Commits

Author SHA1 Message Date
dhanabalan
2dd3b35eb5 added profile logo in visitor
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
2026-05-26 15:56:46 +05:30
dhanabalan
4129a7a251 added default avatar ui image in visitor
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
2026-05-26 15:31:10 +05:30
dhanabalan
d6aea93d00 removed default image url in visitor
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
2026-05-26 15:28:23 +05:30
dhanabalan
fb91bea7c4 changed logic in visito entry
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-05-26 15:27:25 +05:30
dhanabalan
f970d6eb0f Changed logic in create visitor entry
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
2026-05-26 15:14:14 +05:30
dhanabalan
b567f3ee02 Changed image path of visitor photos
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
2026-05-26 14:33:06 +05:30
dhanabalan
e7fa446fc3 changed logic in create visitor
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
2026-05-26 14:21:09 +05:30
dhanabalan
f399808249 Added photo column in table section
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
2026-05-25 17:20:32 +05:30
dhanabalan
575d3675cf Added logic to show captured image
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
2026-05-25 15:55:45 +05:30
dhanabalan
7435928fcf changed logic in livewire
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
2026-05-25 15:48:42 +05:30
5 changed files with 113 additions and 25 deletions

View File

@@ -82,6 +82,9 @@ class ItemResource extends Resource
Forms\Components\TextInput::make('category') Forms\Components\TextInput::make('category')
->label('Category') ->label('Category')
->placeholder('Scan the Category'), ->placeholder('Scan the Category'),
Forms\Components\TextInput::make('category')
->label('Category')
->placeholder('Scan the Category'),
Forms\Components\TextInput::make('code') Forms\Components\TextInput::make('code')
->required() ->required()
->placeholder('Scan the valid code') ->placeholder('Scan the valid code')

View File

@@ -165,6 +165,15 @@ class VisitorEntryResource extends Resource
return ($currentPage - 1) * $perPage + $rowLoop->iteration; return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}), }),
Tables\Columns\ImageColumn::make('photo')
->label('Photo')
->disk('public')
->height(50)
->width(50)
// ->defaultImageUrl('https://ui-avatars.com/api/?name=Visitor&background=555&color=fff')
->defaultImageUrl(asset('images/profile.png'))
->alignCenter()
->extraImgAttributes(['style' => 'border-radius: 6px; object-fit: cover;']),
Tables\Columns\TextColumn::make('type') Tables\Columns\TextColumn::make('type')
->label('Visitor Type') ->label('Visitor Type')
->alignCenter() ->alignCenter()

View File

@@ -14,12 +14,14 @@ class CreateVisitorEntry extends CreateRecord
{ {
protected static string $resource = VisitorEntryResource::class; protected static string $resource = VisitorEntryResource::class;
#[On('photo-captured')] public $capturedPhoto;
public function handlePhotoCapture(string $photo): void
{ // #[On('photo-captured')]
// Puts the Base64 photo into the form's data array // public function handlePhotoCapture(string $photo): void
$this->data['photo'] = $photo; // {
} // // Puts the Base64 photo into the form's data array
// $this->data['photo'] = $photo;
// }
public function processMobile($mobile) public function processMobile($mobile)
{ {
@@ -53,26 +55,96 @@ class CreateVisitorEntry extends CreateRecord
} }
} }
protected function mutateFormDataBeforeCreate(array $data): array // protected function mutateFormDataBeforeCreate(array $data): array
{ // {
if ( // if (
!empty($data['photo']) && // !empty($data['photo']) &&
str_starts_with($data['photo'], 'data:image') // str_starts_with($data['photo'], 'data:image')
) { // ) {
// Step A: Strip the "data:image/jpeg;base64," prefix // // Step A: Strip the "data:image/jpeg;base64," prefix
$imageData = explode(',', $data['photo'])[1]; // $imageData = explode(',', $data['photo'])[1];
// Step B: Generate a unique filename // // Step B: Generate a unique filename
$filename = 'visitor_' . time() . '_' . uniqid() . '.jpg'; // $filename = 'visitor_' . time() . '_' . uniqid() . '.jpg';
// Step C: Decode Base64 and save as a real .jpg file // // Step C: Decode Base64 and save as a real .jpg file
$path = 'visitor-photos/' . $filename; // $path = 'visitor-photos/' . $filename;
Storage::disk('public')->put($path, base64_decode($imageData)); // Storage::disk('public')->put($path, base64_decode($imageData));
// Step D: Replace the Base64 string with just the file path // // Step D: Replace the Base64 string with just the file path
$data['photo'] = $path; // $data['photo'] = $path;
// }
// return $data;
// }
#[On('photo-captured')]
public function handlePhotoCapture(string $photo): void
{
$this->data['photo'] = $photo;
\Log::info('WEBCAM: photo-captured event received, length: ' . strlen($photo));
} }
return $data; // protected function mutateFormDataBeforeCreate(array $data): array
} // {
// \Log::info('WEBCAM: mutateFormDataBeforeCreate called, photo value: ' . substr($data['photo'] ?? 'NULL', 0, 50));
// if (
// !empty($data['photo']) &&
// str_starts_with($data['photo'], 'data:image')
// ) {
// $imageData = explode(',', $data['photo'])[1];
// $filename = 'visitor_' . time() . '_' . uniqid() . '.jpg';
// $path = 'visitor-photos/' . $filename;
// Storage::disk('public')->put($path, base64_decode($imageData));
// $data['photo'] = $path;
// \Log::info('WEBCAM: photo saved to ' . $path);
// }
// return $data;
// }
protected function mutateFormDataBeforeCreate(array $data): array
{
if (
!empty($data['photo']) &&
str_starts_with($data['photo'], 'data:image')
) {
try {
$imageData = explode(',', $data['photo'])[1];
$filename = 'visitor_' . time() . '_' . uniqid() . '.jpg';
$path = 'visitor-photos/' . $filename;
$decoded = base64_decode($imageData);
$saved = Storage::disk('public')->put($path, $decoded);
\Log::info('PHOTO UPLOAD (PUBLIC):', [
'filename' => $filename,
'path' => $path,
'size_bytes' => strlen($decoded),
'saved' => $saved ? 'SUCCESS' : 'FAILED',
]);
$data['photo'] = $path;
} catch (\Exception $e) {
\Log::error('PHOTO UPLOAD ERROR: ' . $e->getMessage());
}
}
return $data;
}
public function setPhoto(string $photo): void
{
$this->capturedPhoto = $photo;
// Change this ↓ to dispatch to parent explicitly
$this->dispatch('photo-captured', photo: $photo)->to(\App\Filament\Resources\VisitorEntryResource\Pages\CreateVisitorEntry::class);
}
} }

View File

@@ -4,7 +4,7 @@
Visitor Photo Visitor Photo
</x-slot> </x-slot>
<livewire:webcam-capture /> <livewire:webcam />
</x-filament::section> </x-filament::section>
</div> </div>

View File

@@ -3,6 +3,7 @@
cameraActive: false, cameraActive: false,
captured: false, captured: false,
errorMessage: '', errorMessage: '',
photoData: '',
async startCamera() { async startCamera() {
this.errorMessage = ''; this.errorMessage = '';
@@ -38,6 +39,7 @@
} }
this.cameraActive = false; this.cameraActive = false;
this.captured = true; this.captured = true;
this.photoData = photoData;
// Send photo data to PHP via Livewire // Send photo data to PHP via Livewire
$wire.setPhoto(photoData); $wire.setPhoto(photoData);
@@ -45,6 +47,7 @@
retake() { retake() {
this.captured = false; this.captured = false;
this.photoData = '';
$wire.clearPhoto(); $wire.clearPhoto();
this.$nextTick(() => this.startCamera()); this.$nextTick(() => this.startCamera());
} }
@@ -84,7 +87,8 @@
{{-- ── Captured photo preview (shown after capture) ── --}} {{-- ── Captured photo preview (shown after capture) ── --}}
<div x-show="captured" style="position: relative;"> <div x-show="captured" style="position: relative;">
<img <img
x-bind:src="$refs.canvas ? $refs.canvas.toDataURL('image/jpeg') : ''" {{-- x-bind:src="$refs.canvas ? $refs.canvas.toDataURL('image/jpeg') : ''" --}}
x-bind:src="photoData"
style=" style="
width: 100%; width: 100%;
max-width: 480px; max-width: 480px;