Compare commits
10 Commits
9b4b78301d
...
ranjith-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2dd3b35eb5 | ||
|
|
4129a7a251 | ||
|
|
d6aea93d00 | ||
|
|
fb91bea7c4 | ||
|
|
f970d6eb0f | ||
|
|
b567f3ee02 | ||
|
|
e7fa446fc3 | ||
|
|
f399808249 | ||
|
|
575d3675cf | ||
|
|
7435928fcf |
@@ -82,6 +82,9 @@ class ItemResource extends Resource
|
||||
Forms\Components\TextInput::make('category')
|
||||
->label('Category')
|
||||
->placeholder('Scan the Category'),
|
||||
Forms\Components\TextInput::make('category')
|
||||
->label('Category')
|
||||
->placeholder('Scan the Category'),
|
||||
Forms\Components\TextInput::make('code')
|
||||
->required()
|
||||
->placeholder('Scan the valid code')
|
||||
|
||||
@@ -165,6 +165,15 @@ class VisitorEntryResource extends Resource
|
||||
|
||||
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')
|
||||
->label('Visitor Type')
|
||||
->alignCenter()
|
||||
|
||||
@@ -14,12 +14,14 @@ class CreateVisitorEntry extends CreateRecord
|
||||
{
|
||||
protected static string $resource = VisitorEntryResource::class;
|
||||
|
||||
#[On('photo-captured')]
|
||||
public function handlePhotoCapture(string $photo): void
|
||||
{
|
||||
// Puts the Base64 photo into the form's data array
|
||||
$this->data['photo'] = $photo;
|
||||
}
|
||||
public $capturedPhoto;
|
||||
|
||||
// #[On('photo-captured')]
|
||||
// public function handlePhotoCapture(string $photo): void
|
||||
// {
|
||||
// // Puts the Base64 photo into the form's data array
|
||||
// $this->data['photo'] = $photo;
|
||||
// }
|
||||
|
||||
public function processMobile($mobile)
|
||||
{
|
||||
@@ -53,26 +55,96 @@ class CreateVisitorEntry extends CreateRecord
|
||||
}
|
||||
}
|
||||
|
||||
protected function mutateFormDataBeforeCreate(array $data): array
|
||||
{
|
||||
if (
|
||||
!empty($data['photo']) &&
|
||||
str_starts_with($data['photo'], 'data:image')
|
||||
) {
|
||||
// Step A: Strip the "data:image/jpeg;base64," prefix
|
||||
$imageData = explode(',', $data['photo'])[1];
|
||||
// protected function mutateFormDataBeforeCreate(array $data): array
|
||||
// {
|
||||
// if (
|
||||
// !empty($data['photo']) &&
|
||||
// str_starts_with($data['photo'], 'data:image')
|
||||
// ) {
|
||||
// // Step A: Strip the "data:image/jpeg;base64," prefix
|
||||
// $imageData = explode(',', $data['photo'])[1];
|
||||
|
||||
// Step B: Generate a unique filename
|
||||
$filename = 'visitor_' . time() . '_' . uniqid() . '.jpg';
|
||||
// // Step B: Generate a unique filename
|
||||
// $filename = 'visitor_' . time() . '_' . uniqid() . '.jpg';
|
||||
|
||||
// Step C: Decode Base64 and save as a real .jpg file
|
||||
$path = 'visitor-photos/' . $filename;
|
||||
Storage::disk('public')->put($path, base64_decode($imageData));
|
||||
// // Step C: Decode Base64 and save as a real .jpg file
|
||||
// $path = 'visitor-photos/' . $filename;
|
||||
// Storage::disk('public')->put($path, base64_decode($imageData));
|
||||
|
||||
// Step D: Replace the Base64 string with just the file path
|
||||
$data['photo'] = $path;
|
||||
// // Step D: Replace the Base64 string with just the file 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Visitor Photo
|
||||
</x-slot>
|
||||
|
||||
<livewire:webcam-capture />
|
||||
<livewire:webcam />
|
||||
|
||||
</x-filament::section>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
cameraActive: false,
|
||||
captured: false,
|
||||
errorMessage: '',
|
||||
photoData: '',
|
||||
|
||||
async startCamera() {
|
||||
this.errorMessage = '';
|
||||
@@ -38,6 +39,7 @@
|
||||
}
|
||||
this.cameraActive = false;
|
||||
this.captured = true;
|
||||
this.photoData = photoData;
|
||||
|
||||
// Send photo data to PHP via Livewire
|
||||
$wire.setPhoto(photoData);
|
||||
@@ -45,6 +47,7 @@
|
||||
|
||||
retake() {
|
||||
this.captured = false;
|
||||
this.photoData = '';
|
||||
$wire.clearPhoto();
|
||||
this.$nextTick(() => this.startCamera());
|
||||
}
|
||||
@@ -84,7 +87,8 @@
|
||||
{{-- ── Captured photo preview (shown after capture) ── --}}
|
||||
<div x-show="captured" style="position: relative;">
|
||||
<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="
|
||||
width: 100%;
|
||||
max-width: 480px;
|
||||
|
||||
Reference in New Issue
Block a user