Added filter logic and added type options in visitor resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled

This commit is contained in:
dhanabalan
2026-06-02 09:13:57 +05:30
parent 9799a391a4
commit b323ad0e3d
2 changed files with 205 additions and 5 deletions

View File

@@ -7,6 +7,7 @@ use App\Filament\Imports\VisitorEntryImporter;
use App\Filament\Resources\VisitorEntryResource\Pages; use App\Filament\Resources\VisitorEntryResource\Pages;
use App\Filament\Resources\VisitorEntryResource\RelationManagers; use App\Filament\Resources\VisitorEntryResource\RelationManagers;
use App\Models\VisitorEntry; use App\Models\VisitorEntry;
use App\Models\EmployeeMaster;
use Filament\Facades\Filament; use Filament\Facades\Filament;
use Filament\Forms; use Filament\Forms;
use Filament\Forms\Form; use Filament\Forms\Form;
@@ -22,6 +23,10 @@ use Filament\Infolists\Components\Section;
use Carbon\Carbon; use Carbon\Carbon;
use Filament\Tables\Actions\ExportAction; use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction; use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Filters\Filter;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
class VisitorEntryResource extends Resource class VisitorEntryResource extends Resource
{ {
@@ -86,7 +91,12 @@ class VisitorEntryResource extends Resource
->options([ ->options([
'Student' => 'Student', 'Student' => 'Student',
'Consultant' => 'Consultant', 'Consultant' => 'Consultant',
'Vendor' => 'Vendor', 'Supplier' => 'Supplier',
'InterviewCandidates' => 'Interview Candidates',
'Customers/Dealers' => 'Customers/Dealers',
'Bankers' => 'Bankers',
'ServiceProviders' => 'Service Providers',
'GovermentOfficials' => 'Government Officials',
'Other' => 'Other', 'Other' => 'Other',
]) ])
->required() ->required()
@@ -107,7 +117,7 @@ class VisitorEntryResource extends Resource
Forms\Components\Select::make('department') Forms\Components\Select::make('department')
->label('Employee Department') ->label('Employee Department')
->options( ->options(
\App\Models\EmployeeMaster::distinct() EmployeeMaster::distinct()
->pluck('department', 'department') ->pluck('department', 'department')
) )
->required() ->required()
@@ -148,15 +158,15 @@ class VisitorEntryResource extends Resource
$department = $get('department'); $department = $get('department');
// Always load ALL employees, filter by department if set // Always load ALL employees, filter by department if set
if ($department) { if ($department) {
return \App\Models\EmployeeMaster::where('department', $department) return EmployeeMaster::where('department', $department)
->pluck('name', 'id'); ->pluck('name', 'id');
} }
// Fallback: load all so fill() can always match the ID // Fallback: load all so fill() can always match the ID
return \App\Models\EmployeeMaster::pluck('name', 'id'); return EmployeeMaster::pluck('name', 'id');
}) })
->reactive() ->reactive()
->afterStateUpdated(function (callable $set, ?string $state) { ->afterStateUpdated(function (callable $set, ?string $state) {
$employee = \App\Models\EmployeeMaster::find($state); $employee = EmployeeMaster::find($state);
$set('code', $employee?->code ?? ''); $set('code', $employee?->code ?? '');
}), }),
@@ -301,7 +311,135 @@ class VisitorEntryResource extends Resource
]) ])
->filters([ ->filters([
Tables\Filters\TrashedFilter::make(), Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
TextInput::make('register_id')
->label('Register ID')
->reactive()
->placeholder('Enter Register ID')
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Rework', null);
}),
Select::make('type')
->label('Type')
->reactive()
->options([
'Student' => 'Student',
'Consultant' => 'Consultant',
'Vendor' => 'Vendor',
'Other' => 'Other',
])
->placeholder('Enter Type')
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Rework', null);
}),
TextInput::make('name')
->label('Visitor Name')
->reactive()
->placeholder('Enter Visitor Name')
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('company', null);
}),
TextInput::make('company')
->label('Visitor Company')
->reactive()
->placeholder('Enter Visitor Company')
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Rework', null);
}),
Select::make('employee_master_id')
->label('Employee Name')
->relationship('employeeMaster', 'name')
->searchable()
->preload()
->reactive()
->placeholder('Select Employee')
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Rework', null);
}),
DateTimePicker::make('created_from')
->label('Created From')
->placeholder('Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('created_to')
->label('Created To')
->placeholder('Select To DateTime')
->reactive()
->native(false),
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['register_id']) && empty($data['type']) && empty($data['name']) && empty($data['company']) && empty($data['employee_master_id']) && empty($data['created_from']) && empty($data['created_to'])) {
$query->where(function ($q) {
});
}
if (! empty($data['register_id'])) {
$query->where('register_id', $data['register_id']);
}
if (! empty($data['type'])) {
$query->where('type', $data['type']);
}
if (! empty($data['name'])) {
$query->where('name', 'like', '%'.$data['name'].'%');
}
if (! empty($data['company'])) {
$query->where('company', 'like', '%'.$data['company'].'%');
}
if (! empty($data['employee_master_id'])) {
$query->where('employee_master_id', $data['employee_master_id']);
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
// $query->orderBy('created_at', 'asc');
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['register_id'])) {
$indicators[] = 'Register ID: '.$data['register_id'];
}
if (! empty($data['type'])) {
$indicators[] = 'Type: '.$data['type'];
}
if (! empty($data['name'])) {
$indicators[] = 'Name: '.$data['name'];
}
if (! empty($data['company'])) {
$indicators[] = 'Company: '.$data['company'];
}
if (! empty($data['employee_master_id'])) {
$indicators[] = 'Employee Name: '.EmployeeMaster::where('id', $data['employee_master_id'])->value('name');
}
if (! empty($data['created_from'])) {
$indicators[] = 'From: '.$data['created_from'];
}
if (! empty($data['created_to'])) {
$indicators[] = 'To: '.$data['created_to'];
}
return $indicators;
}),
]) ])
->filtersFormMaxHeight('280px')
->actions([ ->actions([
Tables\Actions\ViewAction::make(), Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(), Tables\Actions\EditAction::make(),

62
app/Mail/VisitorMail.php Normal file
View File

@@ -0,0 +1,62 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class VisitorMail extends Mailable
{
use Queueable, SerializesModels;
public $visitor;
/**
* Create a new message instance.
*/
public function __construct($visitor)
{
$this->visitor = $visitor;
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: 'Visitor Arrival Notification',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
$greeting = '<b>Dear Sir</b>';
return new Content(
view: 'mail.visitor-arrival',
with: [
'company' => 'CRI Digital Manufacturing Solutions',
'greeting' => $greeting,
'wishes' => 'Thanks & Regards,<br>CRI Digital Manufacturing Solutions',
],
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}