Skip to content

Commit

Permalink
Feature/admin improvements (#6)
Browse files Browse the repository at this point in the history
* Fixed image export

* Added user/profile relations to application page

* Fixed image export

* Added user/profile relations to application page

* Fixed button text.

* Fixed image export

* Added user/profile relations to application page

* Fixed button text.

* Fixed case StatusNotificationResult::SharesInvalid

* make users sort- and filterable

* Move mapping from Application to ApplicationStatus

* make more columns for applications sort- and filterable

* fix application status filter by syncing rules

* fix filter users for missing reg id

* Added application relation to user and profile

* Fixed image export, 2nd try

---------

Co-authored-by: Fenrikur <[email protected]>
  • Loading branch information
julsteele and Fenrikur authored Jun 4, 2023
1 parent 7e1cf89 commit 3e684f9
Show file tree
Hide file tree
Showing 13 changed files with 452 additions and 82 deletions.
86 changes: 86 additions & 0 deletions app/Enums/ApplicationStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,90 @@ enum ApplicationStatus: string
case TableOffered = 'table_offered';
case TableAccepted = 'table_accepted';
case CheckedIn = 'checked_in';

static function for(\App\Models\Application $application): ApplicationStatus
{
if (!is_null($application->canceled_at)) {
return ApplicationStatus::Canceled;
} elseif (!is_null($application->checked_in_at)) {
return ApplicationStatus::CheckedIn;
} elseif (!is_null($application->waiting_at)) {
return ApplicationStatus::Waiting;
} elseif (!is_null($application->offer_accepted_at)) {
return ApplicationStatus::TableAccepted;
} elseif (!is_null($application->offer_sent_at)) {
return ApplicationStatus::TableOffered;
} elseif (($application->type !== \App\Enums\ApplicationType::Dealer || !is_null($application->table_type_assigned)) && !empty($application->table_number)) {
return ApplicationStatus::TableAssigned;
} else {
return ApplicationStatus::Open;
}
}

function orWhere(\Illuminate\Database\Eloquent\Builder $query)
{
return match ($this) {
ApplicationStatus::Canceled => $query->orWhere(
fn (\Illuminate\Database\Eloquent\Builder $query) =>
$query->where('canceled_at', '!=', null)
),
ApplicationStatus::CheckedIn => $query->orWhere(
fn (\Illuminate\Database\Eloquent\Builder $query) =>
$query->where('canceled_at', '=', null)
->where('checked_in_at', '!=', null)
),
ApplicationStatus::Waiting => $query->orWhere(
fn (\Illuminate\Database\Eloquent\Builder $query) =>
$query->where('canceled_at', '=', null)
->where('checked_in_at', '=', null)
->where('waiting_at', '!=', null)
),
ApplicationStatus::TableAccepted => $query->orWhere(
fn (\Illuminate\Database\Eloquent\Builder $query) =>
$query->where('canceled_at', '=', null)
->where('checked_in_at', '=', null)
->where('waiting_at', '=', null)
->where('offer_accepted_at', '!=', null)
),
ApplicationStatus::TableOffered => $query->orWhere(
fn (\Illuminate\Database\Eloquent\Builder $query) =>
$query->where('canceled_at', '=', null)
->where('checked_in_at', '=', null)
->where('waiting_at', '=', null)
->where('offer_accepted_at', '=', null)
->where('offer_sent_at', '!=', null)
),
ApplicationStatus::TableAssigned => $query->orWhere(
fn (\Illuminate\Database\Eloquent\Builder $query) =>
$query->where('canceled_at', '=', null)
->where('checked_in_at', '=', null)
->where('waiting_at', '=', null)
->where('offer_accepted_at', '=', null)
->where('offer_sent_at', '=', null)
->where('table_number', '!=', null)
->where(
fn (\Illuminate\Database\Eloquent\Builder $query) =>
$query->orWhere('table_type_assigned', '!=', null)
->orWhere('type', '!=', \App\Enums\ApplicationType::Dealer->value)
)
),
ApplicationStatus::Open => $query->orWhere(
fn (\Illuminate\Database\Eloquent\Builder $query) =>
$query->where('canceled_at', '=', null)
->where('checked_in_at', '=', null)
->where('waiting_at', '=', null)
->where('offer_accepted_at', '=', null)
->where('offer_sent_at', '=', null)
->where(
fn (\Illuminate\Database\Eloquent\Builder $query) =>
$query->orWhere('table_number', '=', null)
->orWhere(
fn (\Illuminate\Database\Eloquent\Builder $query) =>
$query->where('table_type_assigned', '=', null)
->where('type', '=', \App\Enums\ApplicationType::Dealer->value)
)
)
),
};
}
}
135 changes: 98 additions & 37 deletions app/Filament/Resources/ApplicationResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ApplicationResource extends Resource
{
Expand Down Expand Up @@ -109,36 +108,66 @@ public static function table(Table $table): Table
return $table
->columns([
Tables\Columns\TextColumn::make('id')->label("ID"),
Tables\Columns\TextColumn::make('user.name')->searchable(),
Tables\Columns\BadgeColumn::make('status')->enum(ApplicationStatus::cases())->formatStateUsing(function (Application $record) {
return $record->status->name;
})->colors([
'secondary',
'success' => ApplicationStatus::TableAccepted->value,
'danger' => ApplicationStatus::Canceled->value
]),
Tables\Columns\TextColumn::make('requestedTable.name')->icon(fn($record) => $record->type === ApplicationType::Dealer && $record->table_type_requested !== $record->table_type_assigned ? 'heroicon-o-exclamation' : '')->iconPosition('after')->color(fn($record) => $record->type === ApplicationType::Dealer && $record->table_type_requested !== $record->table_type_assigned ? 'warning' : ''),
Tables\Columns\SelectColumn::make('tableTypeAssignedAutoNull')->label('Assigned table')->options(TableType::pluck('name', 'id')->toArray()),
Tables\Columns\TextColumn::make('type')->formatStateUsing(function (string $state) {
return ucfirst($state);
})->sortable(),
Tables\Columns\TextInputColumn::make('table_number')->sortable()->searchable(),
Tables\Columns\IconColumn::make('is_ready')->label('Ready')->getStateUsing(function (Application $record) {
return $record->isReady();
})->boolean(),
Tables\Columns\TextColumn::make('dlrshp')->getStateUsing(function (Application $record) {
return $record->parent ?: $record->id;
})->sortable(query: function (Builder $query, string $direction): Builder {
return $query
->orderBy(DB::raw('IF(`type` = \'dealer\', `id`,`parent`)'), $direction);
})->searchable(query: function (Builder $query, string $search): Builder {
return $query
->where('id', '=', $search)
->orWhere('parent', '=', $search);
}),
Tables\Columns\TextColumn::make('display_name')->searchable(),
Tables\Columns\IconColumn::make('wanted_neighbors')->label('N Wanted')->default(false)->boolean(),
Tables\Columns\IconColumn::make('comment')->default(false)->boolean(),
Tables\Columns\TextColumn::make('user.name')
->searchable(),
Tables\Columns\BadgeColumn::make('status')
->enum(ApplicationStatus::cases())
->formatStateUsing(function (Application $record) {
return $record->status->name;
})
->colors([
'secondary',
'success' => ApplicationStatus::TableAccepted->value,
'danger' => ApplicationStatus::Canceled->value
]),
Tables\Columns\TextColumn::make('requestedTable.name')
->icon(fn ($record) => $record->type === ApplicationType::Dealer && $record->table_type_requested !== $record->table_type_assigned ? 'heroicon-o-exclamation' : '')
->iconPosition('after')
->color(fn ($record) => $record->type === ApplicationType::Dealer && $record->table_type_requested !== $record->table_type_assigned ? 'warning' : '')
->sortable(),
Tables\Columns\SelectColumn::make('tableTypeAssignedAutoNull')
->label('Assigned table')
->options(TableType::pluck('name', 'id')->toArray())
->sortable(query: function (Builder $query, string $direction): Builder {
return $query
->orderBy('table_type_assigned', $direction);
}),
Tables\Columns\TextColumn::make('type')
->formatStateUsing(function (string $state) {
return ucfirst($state);
})
->sortable(),
Tables\Columns\TextInputColumn::make('table_number')
->sortable()
->searchable(),
Tables\Columns\IconColumn::make('is_ready')
->label('Ready')
->getStateUsing(function (Application $record) {
return $record->isReady();
})
->boolean(),
Tables\Columns\TextColumn::make('dlrshp')
->getStateUsing(function (Application $record) {
return $record->parent ?: $record->id;
})
->sortable(query: function (Builder $query, string $direction): Builder {
return $query
->orderBy(DB::raw('IF(`type` = \'dealer\', `id`,`parent`)'), $direction);
})
->searchable(query: function (Builder $query, string $search): Builder {
return $query
->where('id', '=', $search)
->orWhere('parent', '=', $search);
}),
Tables\Columns\TextColumn::make('display_name')
->searchable(),
Tables\Columns\IconColumn::make('wanted_neighbors')
->label('N Wanted')
->default(false)
->boolean(),
Tables\Columns\IconColumn::make('comment')
->default(false)
->boolean(),
Tables\Columns\IconColumn::make('is_afterdark')
->label('AD')
->sortable()
Expand All @@ -155,11 +184,41 @@ public static function table(Table $table): Table
->dateTime(),
])
->filters([
Tables\Filters\Filter::make('parent')->query(fn (Builder $query): Builder => $query->where('type', 'dealer'))->label('Only Dealerships'),
Tables\Filters\Filter::make('assignedTable')->query(fn (Builder $query): Builder => $query->whereNull('table_type_assigned'))->label('Missing assigned table'),
Tables\Filters\Filter::make('table_number')->query(fn (Builder $query): Builder => $query->whereNull('table_number'))->label('Missing table number'),
Tables\Filters\Filter::make('is_afterdark')->query(fn (Builder $query): Builder => $query->where('is_afterdark', '=', '1'))->label('Is Afterdark'),
Tables\Filters\Filter::make('table_assigned')->query(fn (Builder $query): Builder => $query->whereNotNull('offer_sent_at'))->label('Table assigned'),
Tables\Filters\Filter::make('parent')
->query(fn (Builder $query): Builder => $query->where('type', 'dealer'))
->label('Only Dealerships'),
Tables\Filters\Filter::make('assignedTable')
->query(fn (Builder $query): Builder => $query->whereNull('table_type_assigned'))
->label('Missing assigned table'),
Tables\Filters\Filter::make('table_number')
->query(fn (Builder $query): Builder => $query->whereNull('table_number'))
->label('Missing table number'),
Tables\Filters\Filter::make('is_afterdark')
->query(fn (Builder $query): Builder => $query->where('is_afterdark', '=', '1'))
->label('Is Afterdark'),
Tables\Filters\Filter::make('table_assigned')
->query(fn (Builder $query): Builder => $query->whereNotNull('offer_sent_at'))
->label('Table assigned'),
Tables\Filters\SelectFilter::make('requestedTable')
->relationship('requestedTable', 'name')
->multiple(),
Tables\Filters\SelectFilter::make('assignedTable')
->relationship('assignedTable', 'name')
->multiple(),
Tables\Filters\SelectFilter::make('status')
->options(array_combine(array_column(ApplicationStatus::cases(), 'value'), array_column(ApplicationStatus::cases(), 'name')))
->query(function (Builder $query, array $data) {
\Illuminate\Support\Facades\Log::debug(print_r($data, true));
if (!key_exists('values', $data)) {
return;
}
$query->where(function (Builder $query) use ($data) {
foreach ($data['values'] as $value) {
ApplicationStatus::tryFrom($value)?->orWhere($query);
}
});
})
->multiple(),
])
->actions([
Tables\Actions\EditAction::make(),
Expand Down Expand Up @@ -237,7 +296,9 @@ public static function getRelations(): array
{
return [
RelationManagers\ChildrenRelationManager::class,
RelationManagers\ParentRelationManager::class
RelationManagers\ParentRelationManager::class,
RelationManagers\UserRelationManager::class,
RelationManagers\ProfileRelationManager::class,
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function sendStatusNotification()
->body("Notified application {$application->id} of user {$user->name} about being put on the waiting list.")
->success();
break;
case StatusNotificationResult::SharesInvalid->name:
case StatusNotificationResult::SharesInvalid:
$frontendNotification->title('Notification not sent')
->body("Application not notified because some uncanceled shares have not been assigned to the same table number!")
->danger();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace App\Filament\Resources\ApplicationResource\RelationManagers;

use App\Filament\Resources\ProfileResource;
use App\Filament\Resources\UserResource;
use App\Http\Controllers\Client\RegSysClientController;
use App\Models\Profile;
use App\Models\User;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Table;
use Filament\Tables;


class ProfileRelationManager extends RelationManager
{
protected static string $relationship = 'profile';

protected static ?string $title = "Profile";
protected static ?string $label = "profile";
protected static ?string $recordTitleAttribute = 'short_desc';

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('short_desc')
->required()
->maxLength(255),
]);
}

public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('short_desc'),
Tables\Columns\TextColumn::make('website'),
Tables\Columns\TextColumn::make('attends_thu'),
Tables\Columns\TextColumn::make('attends_fri'),
Tables\Columns\TextColumn::make('attends_sat'),
])
->filters([
//
])
->headerActions([
])
->actions([
Tables\Actions\Action::make('Show')
->url(fn(Profile $record): string => ProfileResource::getUrl('edit', ['record' => $record])),

])
->bulkActions([
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace App\Filament\Resources\ApplicationResource\RelationManagers;

use App\Filament\Resources\UserResource;
use App\Http\Controllers\Client\RegSysClientController;
use App\Models\User;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Resources\Table;
use Filament\Tables;

class UserRelationManager extends RelationManager
{
protected static string $relationship = 'user';

protected static ?string $title = "User";
protected static ?string $label = "user";
protected static ?string $recordTitleAttribute = 'name';

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')
->required()
->maxLength(255),
]);
}

public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('reg_id'),
Tables\Columns\TextColumn::make('email'),

Tables\Columns\BadgeColumn::make('packages booked')
->formatStateUsing(fn(?User $record): string => implode(RegSysClientController::getPackages($record->reg_id)) ?? ''),
Tables\Columns\BadgeColumn::make('reg status')
->formatStateUsing(fn(?User $record): string => RegSysClientController::getSingleReg($record->reg_id)['status'] ?? '')
->colors([
'secondary',
'success' => 'paid',
'danger' => 'cancelled',
])

])
->filters([
//
])
->headerActions([
])
->actions([
Tables\Actions\Action::make('Show')
->url(fn(User $record): string => UserResource::getUrl('edit', ['record' => $record])),

])
->bulkActions([
]);
}
}
Loading

0 comments on commit 3e684f9

Please sign in to comment.