From b1e2ab89785800020cf89e2e867847da70326771 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 25 Jan 2026 11:49:17 +0100 Subject: [PATCH] Add Filaments module with Seeder, update Calculator UI for filament selection, and upgrade dependencies for Livewire Flux --- app/Livewire/Calculator/Calculator.php | 57 ++++++- app/Models/Filament.php | 8 +- composer.lock | 14 +- database/seeders/DatabaseSeeder.php | 1 + database/seeders/FilamentSeeder.php | 26 +++ resources/views/livewire/calculator.blade.php | 160 +++++++++++++++++- 6 files changed, 249 insertions(+), 17 deletions(-) create mode 100644 database/seeders/FilamentSeeder.php diff --git a/app/Livewire/Calculator/Calculator.php b/app/Livewire/Calculator/Calculator.php index d724360..b1ba74d 100644 --- a/app/Livewire/Calculator/Calculator.php +++ b/app/Livewire/Calculator/Calculator.php @@ -8,16 +8,71 @@ use App\Models\Calculationpreset as Model; use Livewire\WithPagination; use Livewire\Attributes\title; +use App\Models\Filament; +use App\Models\FilamentType; +use App\Models\Manufacturer; +use App\Models\Color; + #[title('Calculator')] class Calculator extends Component { use WithPagination; - public Model $calculationpreset ; + public string $selection = '1'; + public float $time = 0; + public string $timeunit = 'h'; + public float $additionalcost = 0; + public string $additionalcostunit = 'per Piece'; + public int $countonplate = 0; + public int $selcountonplate = 0; + public string $search_type = ''; + public string $search_manufacturer = ''; + public string $search_name = ''; + public string $search_color = ''; + + public array $selectedFilaments = []; // [filament_id => amount_g] + + public function toggleFilament($filamentId) + { + if (isset($this->selectedFilaments[$filamentId])) { + unset($this->selectedFilaments[$filamentId]); + } else { + $this->selectedFilaments[$filamentId] = 0; + } + } public function render() { + $filaments = Filament::query() + ->where(function ($query) { + $query->when($this->search_type, function ($query) { + $query->whereHas('type', function ($q) { + $q->where('name', $this->search_type); + }); + }) + ->when($this->search_manufacturer, function ($query) { + $query->whereHas('manufacturer', function ($q) { + $q->where('name', 'like', '%' . $this->search_manufacturer . '%'); + }); + }) + ->when($this->search_name, function ($query) { + $query->where('name', 'like', '%' . $this->search_name . '%'); + }) + ->when($this->search_color, function ($query) { + $query->whereHas('color', function ($q) { + $q->where('name', 'like', '%' . $this->search_color . '%'); + }); + }); + }) + ->orWhereIn('id', array_keys($this->selectedFilaments)) + ->with(['type', 'manufacturer', 'color']) + ->get(); + return view('livewire.calculator', [ + 'presets' => \App\Models\Calculationpreset::all(), + 'calculationpreset' => \App\Models\Calculationpreset::find($this->selection), + 'filaments' => $filaments, + 'filamenttypes' => FilamentType::all(), ]); } } diff --git a/app/Models/Filament.php b/app/Models/Filament.php index 91cf94e..20c379d 100644 --- a/app/Models/Filament.php +++ b/app/Models/Filament.php @@ -13,7 +13,7 @@ class Filament extends Model protected $fillable = [ 'name', 'description', - 'type_id', + 'filament_type_id', 'manufacturer_id', 'color_id', 'weight', @@ -31,19 +31,19 @@ class Filament extends Model // Filament belongs to a type public function type() { - return $this->hasOne(FilamentType::class); + return $this->belongsTo(FilamentType::class, 'filament_type_id'); } // Filament belongs to a manufacturer public function manufacturer() { - return $this->hasOne(Manufacturer::class); + return $this->belongsTo(Manufacturer::class); } // Filament belongs to a color public function color() { - return $this->hasOne(Color::class); + return $this->belongsTo(Color::class); } } diff --git a/composer.lock b/composer.lock index a372d61..80d988f 100644 --- a/composer.lock +++ b/composer.lock @@ -2318,16 +2318,16 @@ }, { "name": "livewire/flux", - "version": "v2.10.2", + "version": "v2.11.1", "source": { "type": "git", "url": "https://github.com/livewire/flux.git", - "reference": "e7a93989788429bb6c0a908a056d22ea3a6c7975" + "reference": "3ada3b2644215fd1ccb7003ce8e6bc185c22e70a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/flux/zipball/e7a93989788429bb6c0a908a056d22ea3a6c7975", - "reference": "e7a93989788429bb6c0a908a056d22ea3a6c7975", + "url": "https://api.github.com/repos/livewire/flux/zipball/3ada3b2644215fd1ccb7003ce8e6bc185c22e70a", + "reference": "3ada3b2644215fd1ccb7003ce8e6bc185c22e70a", "shasum": "" }, "require": { @@ -2335,7 +2335,7 @@ "illuminate/support": "^10.0|^11.0|^12.0", "illuminate/view": "^10.0|^11.0|^12.0", "laravel/prompts": "^0.1|^0.2|^0.3", - "livewire/livewire": "^3.7.3|^4.0", + "livewire/livewire": "^3.7.4|^4.0", "php": "^8.1", "symfony/console": "^6.0|^7.0" }, @@ -2378,9 +2378,9 @@ ], "support": { "issues": "https://github.com/livewire/flux/issues", - "source": "https://github.com/livewire/flux/tree/v2.10.2" + "source": "https://github.com/livewire/flux/tree/v2.11.1" }, - "time": "2025-12-19T02:11:45+00:00" + "time": "2026-01-21T17:09:56+00:00" }, { "name": "livewire/livewire", diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 8664edc..c5ad215 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -32,6 +32,7 @@ class DatabaseSeeder extends Seeder BuildplateSeeder::class, CalculationpresetSeeder::class, PrintertypeSeeder::class, + FilamentSeeder::class, ]); } diff --git a/database/seeders/FilamentSeeder.php b/database/seeders/FilamentSeeder.php new file mode 100644 index 0000000..e7fb04f --- /dev/null +++ b/database/seeders/FilamentSeeder.php @@ -0,0 +1,26 @@ + 'Bambu PLA Basic', 'manufacturer_id' => 1, 'filament_type_id' => 1, 'color_id' => 10, 'temp_max' => 230, 'temp_min' => 180, 'price' => 19.99, 'weight' => 1000, 'diameter' => '1.75'], + ['name' => 'Bambu PLA Basic', 'manufacturer_id' => 1, 'filament_type_id' => 1, 'color_id' => 11, 'temp_max' => 230, 'temp_min' => 180, 'price' => 19.99, 'weight' => 1000, 'diameter' => '1.75'], + + ]; + + foreach ($filaments as $filament) { + \App\Models\Filament::create($filament); + } + } +} diff --git a/resources/views/livewire/calculator.blade.php b/resources/views/livewire/calculator.blade.php index 82029ab..5021cab 100644 --- a/resources/views/livewire/calculator.blade.php +++ b/resources/views/livewire/calculator.blade.php @@ -3,15 +3,165 @@ {{ __('Calculator') }} - - @foreach ( \App\Models\Calculationpreset::all() as $preset) + + @foreach ( $presets as $preset) {{ $preset->name }} @endforeach -
- {{ $preset->name }} : {{ $preset->price_kwh }}€ -
+ @if($calculationpreset) +
+
+
+
+
+ Inputs + Enter your calculation data. +
+
+ + + Time + + + + h + min + + + +
+
+
+ Count on Plate + More Objects per Plate? +
+
+ + Enable + + +
+ @if($selcountonplate) +
+ + Count on Plate + + + + + Additional Cost + + + + per Piece + per Plate + + + +
+ @endif +
+
+ Filament Selection + Filter by manufacturer, filament type and color. + +
+ + + Select + Type + Manufacturer + Name + Color + Amount (g) + + + + + + + + + + + + + + + + + + + + @foreach ($filaments as $filament) + + + + + {{ $filament->type?->name ?? 'N/A' }} + {{ $filament->manufacturer?->name ?? 'N/A' }} + {{ $filament->name }} + +
+
+ {{ $filament->color?->name ?? 'N/A' }} +
+
+ + @if(isset($selectedFilaments[$filament->id])) + + @endif + +
+ @endforeach +
+
+
+
+
+
+
+
+
+ Outputs + Get your ready for use Prices. +
+ @php + $totalFilamentCost = 0; + foreach ($selectedFilaments as $id => $amount) { + $f = $filaments->firstWhere('id', $id); + if ($f && $f->price && $f->weight) { + $totalFilamentCost += ($f->price / $f->weight) * $amount; + } + } + $energyCost = ($calculationpreset->price_kwh ?? 0) * 0.25 * ($timeunit == 'h' ? $time : $time / 60); + $printerCost = ($calculationpreset->factor_printer ?? 0) * ($timeunit == 'h' ? $time : $time / 60); + $maintenanceCost = ($calculationpreset->factor_maintenance ?? 0) * ($timeunit == 'h' ? $time : $time / 60); + $totalCost = $totalFilamentCost + $energyCost + $printerCost + $maintenanceCost + ($additionalcostunit == 'per Piece' ? $additionalcost : $additionalcost / max(1, $countonplate ?? 1)); + @endphp +
+

Time: {{ $time }}{{ $timeunit }}

+

Filament Cost: {{ number_format($totalFilamentCost, 2) }}€

+

Energy Cost: {{ number_format($energyCost, 2) }}€

+

Printer Cost: {{ number_format($printerCost, 2) }}€

+

Maintenance Cost: {{ number_format($maintenanceCost, 2) }}€

+ + @if($countonplate > 0 ) +
+

Additional Cost: {{ $additionalcost }}€ ({{ $additionalcostunit }})

+ Per Item Cost: {{ number_format($totalCost / $countonplate, 2) }}€ | {{ number_format(($totalCost * ($calculationpreset->factor_price / 100)/ $countonplate), 2) }}€ +
+ @endif +
+ Total Cost: {{ number_format($totalCost, 2) }}€ | {{ number_format($totalCost * ($calculationpreset->factor_price / 100), 2) }}€ +
+
+
+
+
+
+ @endif