Skip to content
This repository was archived by the owner on Jan 6, 2026. It is now read-only.

Commit 49b976b

Browse files
Add filtering support for user filaments on the homepage through new request validation and dynamic dropdown updates.
1 parent 7438ad1 commit 49b976b

File tree

4 files changed

+134
-12
lines changed

4 files changed

+134
-12
lines changed

app/Http/Controllers/HomeController.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,24 @@
44

55
namespace App\Http\Controllers;
66

7+
use App\Http\Requests\HomeFilterRequest;
78
use App\Services\Pages\HomeService;
89
use Inertia\Inertia;
910

1011
class HomeController
1112
{
12-
public function __invoke(HomeService $home)
13+
public function __invoke(HomeFilterRequest $request, HomeService $home)
1314
{
1415
return Inertia::render('welcome', [
15-
'userFilaments' => $home->userFilaments(),
16+
'userFilaments' => $home->userFilaments(
17+
$request->integer('machine_id'),
18+
$request->integer('filament_type_id'),
19+
$request->integer('color_id'),
20+
),
1621
'machines' => $home->machines(),
1722
'filamentTypes' => $home->filamentTypes(),
1823
'colors' => $home->colors(),
24+
'filters' => $request->validated(),
1925
]);
2026
}
2127
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Http\Requests;
6+
7+
use Illuminate\Foundation\Http\FormRequest;
8+
9+
class HomeFilterRequest extends FormRequest
10+
{
11+
public function rules(): array
12+
{
13+
return [
14+
'machine_id' => ['nullable', 'integer', 'min:0'],
15+
'filament_type_id' => ['nullable', 'integer', 'min:0'],
16+
'color_id' => ['nullable', 'integer', 'min:0'],
17+
];
18+
}
19+
}

app/Services/Pages/HomeService.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use App\Models\FilamentType;
99
use App\Models\Machine;
1010
use App\Models\UserFilament;
11+
use Illuminate\Database\Eloquent\Builder;
1112
use Illuminate\Database\Eloquent\Collection;
1213

1314
class HomeService
@@ -38,7 +39,7 @@ public function colors(): Collection
3839
->get(['id', 'title', 'hex']);
3940
}
4041

41-
public function userFilaments(int $count = 100): Collection
42+
public function userFilaments(int $machineId, int $filamentTypeId, int $colorId, int $count = 100): Collection
4243
{
4344
return UserFilament::query()
4445
->select([
@@ -51,6 +52,11 @@ public function userFilaments(int $count = 100): Collection
5152
->selectRaw('avg(filament_flow_ratio) as filament_flow_ratio')
5253
->selectRaw('avg(filament_max_volumetric_speed) as filament_max_volumetric_speed')
5354
->selectRaw('avg(nozzle_temperature) as nozzle_temperature')
55+
->when($machineId, fn (Builder $builder) => $builder->where('machine_id', $machineId))
56+
->when($colorId, fn (Builder $builder) => $builder->where('color_id', $colorId))
57+
->when($filamentTypeId, fn (Builder $builder) => $builder
58+
->whereRelation('filament', 'filament_type_id', $filamentTypeId)
59+
)
5460
->with([
5561
'machine.vendor',
5662
'filament' => ['vendor', 'type'],

resources/js/pages/welcome.tsx

Lines changed: 100 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,79 @@
1-
import { Head } from '@inertiajs/react';
1+
import { Head, router } from '@inertiajs/react';
2+
import { type ChangeEvent, useEffect, useState } from 'react';
3+
4+
type Machine = {
5+
id: number;
6+
title: string;
7+
vendor: {
8+
title: string;
9+
};
10+
};
11+
12+
type FilamentType = {
13+
id: number;
14+
title: string;
15+
};
16+
17+
type Color = {
18+
id: number;
19+
title: string;
20+
};
21+
22+
type UserFilament = {
23+
machine_id: number;
24+
filament_id: number;
25+
color_id: number;
26+
machine: Machine;
27+
filament: {
28+
vendor: {
29+
title: string;
30+
};
31+
type: FilamentType;
32+
};
33+
color: Color;
34+
pressure_advance: number;
35+
filament_flow_ratio: number;
36+
filament_max_volumetric_speed: number;
37+
nozzle_temperature: number;
38+
users_count: number;
39+
};
40+
41+
type Filters = {
42+
machine_id: number;
43+
filament_type_id: number;
44+
color_id: number;
45+
};
46+
47+
type WelcomeProps = {
48+
userFilaments: UserFilament[];
49+
machines: Machine[];
50+
filamentTypes: FilamentType[];
51+
colors: Color[];
52+
filters: Filters;
53+
};
54+
55+
export default function Welcome({ userFilaments, machines, filamentTypes, colors, filters }: WelcomeProps) {
56+
const [selectedFilters, setSelectedFilters] = useState<Filters>(filters);
57+
58+
useEffect(() => {
59+
setSelectedFilters(filters);
60+
}, [filters]);
61+
62+
const handleSelectChange = (key: keyof Filters) => (event: ChangeEvent<HTMLSelectElement>) => {
63+
const value = Number(event.target.value);
64+
const nextFilters: Filters = { ...selectedFilters, [key]: value };
65+
66+
setSelectedFilters(nextFilters);
67+
68+
router.visit('/', {
69+
method: 'get',
70+
data: nextFilters,
71+
preserveState: true,
72+
preserveScroll: true,
73+
replace: true
74+
});
75+
};
276

3-
export default function Welcome({ userFilaments, machines, filamentTypes, colors }) {
477
return (
578
<>
679
<Head title="Welcome" />
@@ -19,31 +92,49 @@ export default function Welcome({ userFilaments, machines, filamentTypes, colors
1992
<tbody>
2093
<tr>
2194
<td className="border border-gray-300 p-3 text-left text-gray-900 dark:border-gray-600 dark:text-gray-200">
22-
<select name="machines" className="w-full">
95+
<select
96+
name="machines"
97+
className="w-full"
98+
onChange={ handleSelectChange('machine_id') }
99+
value={ selectedFilters.machine_id }>
23100
<option value="0">- All -</option>
24101

25102
{ machines.map((item) => (
26-
<option value={ item.id }>{ item.vendor.title }&nbsp;{ item.title }</option>
103+
<option
104+
key={ item.id }
105+
value={ item.id }>{ item.vendor.title }&nbsp;{ item.title }</option>
27106
)) }
28107
</select>
29108
</td>
30109

31110
<td className="border border-gray-300 p-3 text-left text-gray-900 dark:border-gray-600 dark:text-gray-200">
32-
<select name="filamentTypes" className="w-full">
111+
<select
112+
name="filamentTypes"
113+
className="w-full"
114+
onChange={ handleSelectChange('filament_type_id') }
115+
value={ selectedFilters.filament_type_id }>
33116
<option value="0">- All -</option>
34117

35118
{ filamentTypes.map((item) => (
36-
<option value={ item.id }>{ item.title }</option>
119+
<option
120+
key={ item.id }
121+
value={ item.id }>{ item.title }</option>
37122
)) }
38123
</select>
39124
</td>
40125

41126
<td className="border border-gray-300 p-3 text-left text-gray-900 dark:border-gray-600 dark:text-gray-200">
42-
<select name="colors" className="w-full">
127+
<select
128+
name="colors"
129+
className="w-full"
130+
onChange={ handleSelectChange('color_id') }
131+
value={ selectedFilters.color_id }>
43132
<option value="0">- All -</option>
44133

45134
{ colors.map((item) => (
46-
<option value={ item.id }>{ item.title }</option>
135+
<option
136+
key={ item.id }
137+
value={ item.id }>{ item.title }</option>
47138
)) }
48139
</select>
49140
</td>
@@ -82,7 +173,7 @@ export default function Welcome({ userFilaments, machines, filamentTypes, colors
82173
</thead>
83174
<tbody>
84175
{ userFilaments.map((item) => (
85-
<tr>
176+
<tr key={ `${ item.machine_id }-${ item.filament_id }-${ item.color_id }` }>
86177
<td className="border border-gray-300 p-3 text-left text-gray-900 dark:border-gray-600 dark:text-gray-200">
87178
{ item.machine.vendor.title }&nbsp;
88179
{ item.machine.title }

0 commit comments

Comments
 (0)