diff --git a/app/Filament/Shelter/Resources/RequestResource/Widgets/ReferToShelterWidget.php b/app/Filament/Shelter/Resources/RequestResource/Widgets/ReferToShelterWidget.php
index 7e3f8cf..7fb714e 100644
--- a/app/Filament/Shelter/Resources/RequestResource/Widgets/ReferToShelterWidget.php
+++ b/app/Filament/Shelter/Resources/RequestResource/Widgets/ReferToShelterWidget.php
@@ -19,6 +19,7 @@
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget as BaseWidget;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\HtmlString;
@@ -30,6 +31,10 @@ class ReferToShelterWidget extends BaseWidget
public function table(Table $table): Table
{
+ $attributes = ShelterAttribute::query()
+ ->with('shelterVariables')
+ ->get();
+
return $table
->query(
fn () => Shelter::query()
@@ -76,6 +81,14 @@ public function table(Table $table): Table
SelectFilter::make('location')
->relationship('location', 'name'),
+ ...$attributes->map(
+ fn (ShelterAttribute $shelterAttribute) => SelectFilter::make("attribute.{$shelterAttribute->id}")
+ ->query(fn (Builder $query, array $state) => $query->whereHasShelterVariables($state))
+ ->options($shelterAttribute->shelterVariables->pluck('name', 'id'))
+ ->label($shelterAttribute->name)
+ ->multiple()
+ ),
+
], FiltersLayout::AboveContent)
->paginated(false);
}
diff --git a/app/Forms/Components/RadioCard.php b/app/Forms/Components/RadioCard.php
new file mode 100644
index 0000000..d180023
--- /dev/null
+++ b/app/Forms/Components/RadioCard.php
@@ -0,0 +1,15 @@
+whereListed()
- ->get(['id', 'name', 'address']);
+ ->with('shelterVariables')
+ ->when(
+ data_get($this->data, 'filters.variables'),
+ fn (Builder $query, array $variables) => $query->whereHasShelterVariables($variables)
+ )
+ ->when(
+ data_get($this->data, 'filters.locations'),
+ fn (Builder $query, array $locations) => $query->whereIn('location_id', $locations)
+ )
+ ->get();
+
+ $attributes = ShelterAttribute::query()
+ ->with('shelterVariables')
+ ->whereListed()
+ ->get();
return $form
->schema([
@@ -102,7 +121,6 @@ public function form(Form $form): Form
Checkbox::make('for_group')
->label(__('app.field.request_group'))
->live(),
-
]),
Section::make(__('app.field.requester'))
@@ -169,13 +187,52 @@ public function form(Form $form): Form
Section::make(__('app.field.request_shelter'))
->schema([
- Radio::make('shelter_id')
+ Grid::make()
+ ->statePath('filters')
+ ->columns(3)
+ ->schema([
+ Select::make('locations')
+ ->label(__('app.field.location'))
+ ->options(
+ Location::query()
+ ->whereHas('shelters')
+ ->get()
+ ->pluck('name', 'id')
+ )
+ ->searchable()
+ ->multiple()
+ ->lazy(),
+
+ ...$attributes->map(
+ fn (ShelterAttribute $shelterAttribute) => Select::make("variables.{$shelterAttribute->id}")
+ ->label($shelterAttribute->name)
+ ->options($shelterAttribute->shelterVariables->pluck('name', 'id'))
+ ->searchable()
+ ->multiple()
+ ->lazy(),
+ )->all(),
+ ]),
+
+ RadioCard::make('shelter_id')
->label(__('app.field.request_shelter'))
->columns()
->hiddenLabel()
->options($shelters->mapWithKeys(fn (Shelter $shelter) => [$shelter->id => $shelter->name]))
- ->descriptions($shelters->mapWithKeys(fn (Shelter $shelter) => [$shelter->id => $shelter->address]))
+ ->descriptions($shelters->mapWithKeys(fn (Shelter $shelter) => [
+ $shelter->id => view('forms.components.shelter-radio-card-content', [
+ 'shelter' => $shelter,
+ 'attributes' => $attributes,
+ ]),
+ ]))
->required(),
+
+ View::make('filament-tables::components.empty-state.index')
+ ->visible($shelters->isEmpty())
+ ->viewData([
+ 'icon' => 'heroicon-o-magnifying-glass',
+ 'heading' => __('app.shelter.empty_state.header'),
+ 'description' => __('app.shelter.empty_state.description'),
+ ]),
]),
Section::make(__('app.field.group'))
@@ -217,6 +274,7 @@ public function form(Form $form): Form
->schema([
DatePicker::make('start_date')
->label(__('app.field.start_date'))
+ ->afterOrEqual('today')
->required(),
DatePicker::make('end_date')
diff --git a/app/Models/Request.php b/app/Models/Request.php
index bc9a5bb..aacf0fa 100644
--- a/app/Models/Request.php
+++ b/app/Models/Request.php
@@ -143,7 +143,7 @@ public static function typesenseModelSettings(): array
],
[
'name' => 'shelter_id',
- 'type' => 'int64',
+ 'type' => 'string',
'optional' => true,
],
[
@@ -163,7 +163,7 @@ public function toSearchableArray(): array
return [
'id' => (string) $this->id,
'searchable_id' => (string) $this->id,
- 'shelter_id' => $this->shelter_id,
+ 'shelter_id' => (string) $this->shelter_id,
'beneficiary_name' => $this->beneficiary->name,
];
}
diff --git a/app/Models/Shelter.php b/app/Models/Shelter.php
index f82a933..32569c0 100644
--- a/app/Models/Shelter.php
+++ b/app/Models/Shelter.php
@@ -87,6 +87,21 @@ public function scopeWhereListed(Builder $query): Builder
});
}
+ public function scopeWhereHasShelterVariables(Builder $query, array $variables): Builder
+ {
+ $variables = collect($variables)
+ ->filter(fn (array $value) => filled($value));
+
+ if ($variables->isEmpty()) {
+ return $query;
+ }
+
+ return $query
+ ->whereHas('shelterVariables', function (Builder $query) use ($variables) {
+ $variables->each(fn (array $values) => $query->whereIn('shelter_variables.id', $values));
+ });
+ }
+
public function availableCapacity(): Attribute
{
return Attribute::make(
diff --git a/app/Models/ShelterAttribute.php b/app/Models/ShelterAttribute.php
index b1a733e..41d3794 100644
--- a/app/Models/ShelterAttribute.php
+++ b/app/Models/ShelterAttribute.php
@@ -26,6 +26,7 @@ class ShelterAttribute extends Model
'name',
'type',
'is_enabled',
+ 'is_listed',
];
public array $translatable = [
@@ -37,6 +38,7 @@ public function casts(): array
return [
'type' => AttributeType::class,
'is_enabled' => 'boolean',
+ 'is_listed' => 'boolean',
];
}
@@ -58,4 +60,11 @@ public function scopeWhereAttribute(Builder $query): Builder
{
return $query->where('type', AttributeType::ATTRIBUTE);
}
+
+ public function scopeWhereListed(Builder $query): Builder
+ {
+ return $query
+ ->where('is_enabled', true)
+ ->where('is_listed', true);
+ }
}
diff --git a/database/factories/ShelterAttributeFactory.php b/database/factories/ShelterAttributeFactory.php
index b0fbed8..494605e 100644
--- a/database/factories/ShelterAttributeFactory.php
+++ b/database/factories/ShelterAttributeFactory.php
@@ -25,6 +25,7 @@ public function definition(): array
'name' => fake()->word(),
'is_enabled' => true,
'type' => AttributeType::ATTRIBUTE,
+ 'is_listed' => fake()->boolean(),
];
}
diff --git a/database/migrations/0001_01_04_000009_add_is_listed_column_to_shelter_attributes_table.php b/database/migrations/0001_01_04_000009_add_is_listed_column_to_shelter_attributes_table.php
new file mode 100644
index 0000000..c625249
--- /dev/null
+++ b/database/migrations/0001_01_04_000009_add_is_listed_column_to_shelter_attributes_table.php
@@ -0,0 +1,19 @@
+boolean('is_listed')
+ ->default(false)
+ ->after('is_enabled');
+ });
+ }
+};
diff --git a/lang/en/app.php b/lang/en/app.php
index 89fb822..68e5bee 100644
--- a/lang/en/app.php
+++ b/lang/en/app.php
@@ -277,6 +277,10 @@
],
],
],
+ 'empty_state' => [
+ 'header' => 'No shelter found',
+ 'description' => 'Please try again with a different filter.',
+ ],
],
'user' => [
'label' => [
diff --git a/resources/views/forms/components/radio-card.blade.php b/resources/views/forms/components/radio-card.blade.php
new file mode 100644
index 0000000..d3d6aef
--- /dev/null
+++ b/resources/views/forms/components/radio-card.blade.php
@@ -0,0 +1,73 @@
+@php
+ $gridDirection = $getGridDirection() ?? 'column';
+ $id = $getId();
+ $isDisabled = $isDisabled();
+ $isInline = $isInline();
+ $statePath = $getStatePath();
+@endphp
+
+