created Filament View with Livewire

This commit is contained in:
2025-04-22 18:45:56 +02:00
parent 77b1b85f1e
commit cf81ce810b
7 changed files with 434 additions and 19 deletions
+70
View File
@@ -0,0 +1,70 @@
<?php
namespace App\Livewire\Filament;
use Livewire\Component;
use App\Models\Filament as Model;
use App\Models\Color as Color;
use App\Models\FilamentType as Type;
use App\Models\Manufacturer as Manufacturer;
use Livewire\WithPagination;
use Livewire\Attributes\title;
use Livewire\Attributes\Validate;
use Flux\Flux;
use Illuminate\Support\Facades\Auth;
#[title('Filaments')]
class Filament extends Component
{
use WithPagination;
#[Validate('required')]
public $name = '';
public $description = '';
public $diameter = '1.75';
public $color_id = '';
public $type_id = '';
public $manufacturer_id = '';
public $weight = '1000';
public $price = '0';
public $stock = '0';
public $search = '';
public $editid = '';
public $deleteid = '';
public function create() {
@Auth::check();
// Validate
$this->validate();
$filament = new Model();
$filament->name = $this->name;
$filament->description = $this->description;
$filament->diameter = $this->diameter;
$filament->color_id = Color::Find($this->color_id);
$filament->filament_type_id = Type::Find($this->type_id);
$filament->manufacturer_id = Manufacturer::Find($this->manufacturer_id);
$filament->weight = $this->weight;
$filament->price = $this->price;
$filament->stock = $this->stock;
$filament->save();
// Clear the form
$this->resetInputFields();
// Close the modal
Flux::modal('createModal')->close();
}
public function render()
{
return view('livewire.filament.filament', [
'filaments' => Model::search('name', $this->search)->paginate(10),
'colors' => Color::all(),
'manufacturers' => Manufacturer::all(),
'types' => Type::all()
]);
}
}
+102 -3
View File
@@ -3,11 +3,110 @@
namespace App\Livewire\Filament;
use Livewire\Component;
use Livewire\WithPagination;
use App\Models\Manufacturer as Model;
use Livewire\Attributes\title;
use Livewire\Attributes\Validate;
use Flux\Flux;
use Illuminate\Support\Facades\Auth;
#[title('Manufacturer List')]
class Manufacturer extends Component{
use WithPagination;
#[Validate('required')]
public $name = '';
public $description = '';
public $website = '';
public $search ='';
public $editid = '';
public $deleteid = '';
public function create() {
@Auth::check();
// Validate
$this->validate();
$manufacturer = new Model();
$manufacturer->name = $this->name;
$manufacturer->description = $this->description;
$manufacturer->website = $this->website;
$manufacturer->save();
// Clear the form
$this->resetInputFields();
// Close the modal
Flux::modal('createModal')->close();
}
public function edit($manufacturerid) {
@Auth::check();
$editid = $manufacturerid;
$this->editid = $editid;
$manufacturer = Model::findOrFail($editid);
$this->name = $manufacturer->name;
$this->description = $manufacturer->description;
$this->website = $manufacturer->website;
Flux::modal('editModal')->show();
}
public function save($editid) {
@Auth::check();
$manufacturer = Model::findOrFail($editid);
$manufacturer->name = $this->name;
$manufacturer->description = $this->description;
$manufacturer->website = $this->website;
$manufacturer->save();
$this->resetInputFields();
Flux::modal('editModal')->close();
}
public function deleteModal($manufacturerid) {
@Auth::check();
$deleteid = $manufacturerid;
$this->deleteid = $deleteid;
$manufacturer = Model::findOrFail($deleteid);
$this->name = $manufacturer->name;
$this->description = $manufacturer->description;
$this->website = $manufacturer->website;
Flux::modal('deleteModal')->show();
}
public function delete($deleteid) {
@Auth::check();
$manufacturer = Model::findOrFail($deleteid)->delete();
$this->deleteid = $deleteid;
Flux::modal('deleteModal')->close();
// Clear the form
$this->resetInputFields();
}
public function cancel() {
$this->resetInputFields();
Flux::modals()->close();
}
public function resetInputFields() {
$this->reset(['name', 'description', 'website', 'deleteid', 'editid']);
}
class Manufacturer extends Component
{
public function render()
{
return view('livewire.filament.manufacturer');
return view('livewire.filament.manufacturer', [
'manufacturers' => Model::search('name', $this->search)->paginate(10)
]);
}
}
+3 -3
View File
@@ -31,19 +31,19 @@ class Filament extends Model
// Filament belongs to a type
public function type()
{
return $this->belongsTo(FilamentType::class);
return $this->hasOne(FilamentType::class);
}
// Filament belongs to a manufacturer
public function manufacturer()
{
return $this->belongsTo(Manufacturer::class);
return $this->hasOne(Manufacturer::class);
}
// Filament belongs to a color
public function color()
{
return $this->belongsTo(Color::class);
return $this->hasOne(Color::class);
}
}
@@ -15,9 +15,9 @@ return new class extends Migration
$table->id();
$table->string('name')->required();
$table->string('description')->nullable();
$table->foreignId('color_id')->constrained();
$table->foreignId('manufacturer_id')->constrained();
$table->foreignId('filament_type_id')->constrained();
$table->foreignId('color_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
$table->foreignId('manufacturer_id')->constrained()->onUpdate('cascade')->onDelete('cascade');;
$table->foreignId('filament_type_id')->constrained()->onUpdate('cascade')->onDelete('cascade');;
$table->string('weight')->required();
$table->string('diameter')->required();
$table->string('price')->nullable();
@@ -0,0 +1,136 @@
<section>
<x-header>
{{ __('Filaments') }}
<x-slot name="headerleft">
<input type="text" placeholder="Search..." wire:model.live="search" class="bg-zinc-800 rounded focus:border-accent focus:ring-accent" />
</x-slot>
<x-slot name="headerright">
<flux:modal.trigger name="createModal">
<flux:button variant="primary" class="bg-nuke-400 hover:bg-nuke-300">Create Filament</flux:button>
</flux:modal.trigger>
</x-slot>
</x-header>
<div class="container m-auto my-8">
<x-table>
<x-slot name="tableheader">
<x-table.header>Name</x-table.header>
<x-table.header>Description</x-table.header>
<x-table.header>Color</x-table.header>
<x-table.header>Manufacturer</x-table.header>
<x-table.header>Material</x-table.header>
<x-table.header>Diameter</x-table.header>
<x-table.header>Weight</x-table.header>
<x-table.header>Price</x-table.header>
<x-table.header>Rolls</x-table.header>
<x-table.header class="w-1/6"></x-table.header>
</x-slot>
@foreach ($filaments as $filament)
<tr wire:key="{{ $filament->id }}" class="border-b border-blackout-950">
<x-table.item><p class="p-4 px-3 pl-6 font-bold">{{ $filament->name }}</p></x-table.item>
<x-table.item><p class="p-4 px-3">{{ $filament->description }}</p></x-table.item>
<x-table.item><p class="p-4 px-3"></p></x-table.item>
<x-table.item>
<div class="flex flex-row gap-4 justify-end pr-8">
<flux:button wire:click="edit({{ $filament->id }})" icon="pencil">Edit</flux:button>
<flux:button wire:click="deleteModal({{ $filament->id }})" icon="x-mark">Delete</flux:button>
</div>
</x-table.item>
</tr>
@endforeach
<x-slot name="pagination">
{{ $filaments->links() }}
</x-slot>
</x-table>
</div>
<!-- Create Form -->
<flux:modal wire:model.self='createModal' name="createModal" class="md:w-128">
<form wire:submit.prevent="create">
<div class="space-y-6">
<div>
<flux:heading size="lg" class="text-nuke-400">Create filament</flux:heading>
<flux:text class="mt-2">Create a new filament.</flux:text>
</div>
<flux:input label="Name" wire:model="name" placeholder="Filament Name" required />
<flux:textarea label="Description" wire:model="description" placeholder="Description" />
<flux:select wire:model="manufacturer" label="Manufacturer">
@foreach ($manufacturers as $manufacturer)
<option value="{{ $manufacturer->id }}">{{ $manufacturer->name }}</option>
@endforeach
</flux:select>
<flux:select wire:model="type" label="Type">
@foreach ($types as $type)
<option value="{{ $type->id }}">{{ $type->name }}</option>
@endforeach
</flux:select>
<flux:select wire:model="color" label="Color" >
@foreach ($colors as $color)
<option value="{{ $color->id }}">{{ $color->name }}</option>
@endforeach
</flux:select>
<flux:input label="Diameter" wire:model="diameter" placeholder="Diameter" required />
<flux:input label="Weight" wire:model="weight" placeholder="Weight" required />
<flux:input label="Price" wire:model="price" placeholder="Price" required />
<div class="flex gap-2">
<flux:spacer />
<flux:button variant="ghost" wire:click='cancel'>Cancel</flux:button>
<flux:button type="submit" variant="primary" class="bg-nuke-400 hover:bg-nuke-500">Create</flux:button>
</div>
</div>
</form>
</flux:modal>
<!-- Edit Form -->
@empty($filament)
@else
<flux:modal wire:model.self='editModal' name="editModal" class="md:w-128">
<form wire:submit.prevent="save({{ $editid }})">
<div class="space-y-6">
<div>
<flux:heading size="lg" class="text-etheral-300">Edit manufacturer</flux:heading>
<flux:text class="mt-2">Edit an existing manufacturer.</flux:text>
</div>
<flux:input label="Name" wire:model="name" placeholder="Manufacturer Name" required />
<flux:textarea label="Description" wire:model="description" placeholder="Description" />
<div class="flex gap-2">
<flux:spacer />
<flux:button variant="ghost" wire:click='cancel'>Cancel</flux:button>
<flux:button type="submit" variant="primary" class="bg-etheral-300 hover:bg-etheral-400">Save</flux:button>
</div>
</div>
</form>
</flux:modal>
@endempty
<!-- Delete Form -->
<flux:modal wire:model.self='deleteModal' name="deleteModal" class="md:w-128">
<form wire:submit.prevent="delete({{ $deleteid }})">
<div class="space-y-6">
<div>
<flux:heading size="lg" class="text-red-500">Delete filament?</flux:heading>
<flux:text class="mt-2">
<p>You're about to delete this filament.</p>
<p>This action cannot be reversed.</p>
</flux:text>
</div>
<flux:input label="Name" wire:model="name" disabled placeholder="Filament Name" required />
<flux:textarea label="Description" disabled wire:model="description" placeholder="Description" />
<div class="flex gap-2">
<flux:spacer />
<flux:button variant="ghost" wire:click='cancel'>Cancel</flux:button>
<flux:button type="submit" variant="danger">Delete filament</flux:button>
</div>
</div>
</form>
</flux:modal>
</section>
@@ -1,3 +1,116 @@
<div>
{{-- The whole world belongs to you. --}}
<section>
<x-header>
{{ __('Manufacturers') }}
<x-slot name="headerleft">
<input type="text" placeholder="Search..." wire:model.live="search" class="bg-zinc-800 rounded focus:border-accent focus:ring-accent" />
</x-slot>
<x-slot name="headerright">
<flux:modal.trigger name="createModal">
<flux:button variant="primary" class="bg-nuke-400 hover:bg-nuke-300">Create Manufacturer</flux:button>
</flux:modal.trigger> </x-slot>
</x-header>
<div class="container m-auto my-8">
<x-table>
<x-slot name="tableheader">
<x-table.header>Name</x-table.header>
<x-table.header>Description</x-table.header>
<x-table.header>Website</x-table.header>
<x-table.header>Rolls</x-table.header>
<x-table.header class="w-1/6"></x-table.header>
</x-slot>
@foreach ($manufacturers as $manufacturer)
<tr wire:key="{{ $manufacturer->id }}" class="border-b border-blackout-950">
<x-table.item><p class="p-4 px-3 pl-6 font-bold">{{ $manufacturer->name }}</p></x-table.item>
<x-table.item><p class="p-4 px-3">{{ $manufacturer->description }}</p></x-table.item>
<x-table.item><p class="p-4 px-3"><a href="{{ $manufacturer->website }}" target="_blank">{{ $manufacturer->website }}</a></p></x-table.item>
<x-table.item><p class="p-4 px-3"></p></x-table.item>
<x-table.item>
<div class="flex flex-row gap-4 justify-end pr-8">
<flux:button wire:click="edit({{ $manufacturer->id }})" icon="pencil">Edit</flux:button>
<flux:button wire:click="deleteModal({{ $manufacturer->id }})" icon="x-mark">Delete</flux:button>
</div>
</x-table.item>
</tr>
@endforeach
<x-slot name="pagination">
{{ $manufacturers->links() }}
</x-slot>
</x-table>
</div>
<!-- Create Form -->
<flux:modal wire:model.self='createModal' name="createModal" class="md:w-128">
<form wire:submit.prevent="create">
<div class="space-y-6">
<div>
<flux:heading size="lg" class="text-nuke-400">Create manufacturer</flux:heading>
<flux:text class="mt-2">Create a new manufacturer.</flux:text>
</div>
<flux:input label="Name" wire:model="name" placeholder="Manufacturer Name" required />
<flux:textarea label="Description" wire:model="description" placeholder="Description" />
<flux:input label="Website" wire:model="website" placeholder="Website" />
<div class="flex gap-2">
<flux:spacer />
<flux:button variant="ghost" wire:click='cancel'>Cancel</flux:button>
<flux:button type="submit" variant="primary" class="bg-nuke-400 hover:bg-nuke-500">Create</flux:button>
</div>
</div>
</form>
</flux:modal>
<!-- Edit Form -->
@empty($manufacturer)
@else
<flux:modal wire:model.self='editModal' name="editModal" class="md:w-128">
<form wire:submit.prevent="save({{ $editid }})">
<div class="space-y-6">
<div>
<flux:heading size="lg" class="text-etheral-300">Edit manufacturer</flux:heading>
<flux:text class="mt-2">Edit an existing manufacturer.</flux:text>
</div>
<flux:input label="Name" wire:model="name" placeholder="Manufacturer Name" required />
<flux:textarea label="Description" wire:model="description" placeholder="Description" />
<flux:input label="Website" wire:model="website" placeholder="Website" />
<div class="flex gap-2">
<flux:spacer />
<flux:button variant="ghost" wire:click='cancel'>Cancel</flux:button>
<flux:button type="submit" variant="primary" class="bg-etheral-300 hover:bg-etheral-400">Save</flux:button>
</div>
</div>
</form>
</flux:modal>
@endempty
<!-- Delete Form -->
<flux:modal wire:model.self='deleteModal' name="deleteModal" class="md:w-128">
<form wire:submit.prevent="delete({{ $deleteid }})">
<div class="space-y-6">
<div>
<flux:heading size="lg" class="text-red-500">Delete manufacturer?</flux:heading>
<flux:text class="mt-2">
<p>You're about to delete this manufacturer.</p>
<p>This action cannot be reversed.</p>
</flux:text>
</div>
<flux:input label="Name" wire:model="name" disabled placeholder="Manufacturer Name" required />
<flux:textarea label="Description" disabled wire:model="description" placeholder="Description" />
<flux:input label="Website" wire:model="website" disabled placeholder="Website" />
<div class="flex gap-2">
<flux:spacer />
<flux:button variant="ghost" wire:click='cancel'>Cancel</flux:button>
<flux:button type="submit" variant="danger">Delete type</flux:button>
</div>
</div>
</form>
</flux:modal>
</section>
+4 -7
View File
@@ -1,14 +1,12 @@
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\FilamentTypeController;
use App\Http\Controllers\FilamentController;
use App\Http\Controllers\ManufacturerController;
use App\Http\Controllers\ColorController;
use App\Livewire\Dashboard;
use App\Livewire\Filament\Color;
use App\Livewire\Filament\Type;
use App\Livewire\Filament\Manufacturer;
use App\Livewire\Filament\Filament;
Route::get('/', function () {
return view('welcome');
@@ -27,9 +25,8 @@ Route::middleware([
// Types
Route::get('types', Type::class)->name('types.index');
// Filaments
Route::resource('filaments', FilamentController::class);
Route::get('filaments', Filament::class)->name('filaments.index');
// Manufacturers
Route::resource('manufacturers', ManufacturerController::class);
Route::get('refresh', [ManufacturerController::class, 'refresh'])->name('refresh');
Route::get('manufacturers', Manufacturer::class)->name('manufacturers.index');
});