diff --git a/.env.example b/.env.example index f8ed3e0..ed1308c 100644 --- a/.env.example +++ b/.env.example @@ -54,3 +54,5 @@ VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" AUTO_LOGIN_CREDENTIALS="user%40example.com:password" + +APPROVING_USER_EMAIL= diff --git a/app/Filament/Resources/ItemResource.php b/app/Filament/Resources/ItemResource.php index 4fe4865..e79072a 100644 --- a/app/Filament/Resources/ItemResource.php +++ b/app/Filament/Resources/ItemResource.php @@ -5,6 +5,7 @@ use App\Filament\Resources\ItemResource\Pages; use App\Models\Item; use App\Models\StorageLocation; +use Filament\Forms\Components\Checkbox; use Filament\Forms\Components\CheckboxList; use Filament\Forms\Components\FileUpload; use Filament\Forms\Components\Select; @@ -14,7 +15,10 @@ use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Tables; +use Filament\Tables\Actions\Action; +use Filament\Tables\Filters\Filter; use Filament\Tables\Table; +use Illuminate\Contracts\Database\Eloquent\Builder; class ItemResource extends Resource { @@ -38,6 +42,7 @@ public static function form(Form $form): Form ->columns(2) ->gridDirection('row') ->relationship('tags', titleAttribute: 'title'), + Checkbox::make('approved')->name('Approved')->default(true), Select::make('storage_location_id') ->label('Storage Location') ->options(StorageLocation::all()->pluck('name', 'id')) @@ -58,13 +63,19 @@ public static function table(Table $table): Table ->columns([ Tables\Columns\TextColumn::make('name'), Tables\Columns\TextColumn::make('description')->limit(30), - Tables\Columns\TextColumn::make('borrow_state'), + Tables\Columns\TextColumn::make('approved'), ]) ->filters([ - // + Filter::make('approved')->toggle() + ->label('Not approved') + ->query(fn (Builder $query): Builder => $query->where('approved', false)), ]) ->actions([ Tables\Actions\EditAction::make(), + Action::make('approve') + ->label('Approve') + ->icon('heroicon-o-check-circle') + ->action(fn (Item $item) => $item->update(['approved' => true])), ]) ->bulkActions([ Tables\Actions\DeleteBulkAction::make(), diff --git a/app/Http/Controllers/ItemController.php b/app/Http/Controllers/ItemController.php index 5f4b9d4..61ede15 100644 --- a/app/Http/Controllers/ItemController.php +++ b/app/Http/Controllers/ItemController.php @@ -2,7 +2,11 @@ namespace App\Http\Controllers; +use App\Mail\ItemSuggested; use App\Models\Item; +use Illuminate\Http\RedirectResponse; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Mail; use Illuminate\View\View; class ItemController extends Controller @@ -36,4 +40,35 @@ public function extend(Item $item): View { return view('templates.item.extend', compact('item')); } + + public function suggest(): View + { + return view('templates.item.suggest'); + } + + public function storeSuggestion(Request $request): RedirectResponse + { + $request->validate([ + 'name' => 'required|string', + 'description' => 'required|string', + 'image' => 'image|mimes:jpeg,png,jpg,gif,svg', + ]); + + if ($request->image) { + $path = $request->file('image')->store('images', 'public'); + } + + $item = Item::create([ + 'name' => request()->input('name'), + 'description' => request()->input('description'), + 'image' => $path ?? null, + 'approved' => false, + ]); + + if (config('app.approvingUserEmail')) { + Mail::to(config('app.approvingUserEmail'))->queue(new ItemSuggested($item)); + } + + return redirect()->route('home'); + } } diff --git a/app/Livewire/IndexItems.php b/app/Livewire/IndexItems.php index 1688467..ad852ee 100644 --- a/app/Livewire/IndexItems.php +++ b/app/Livewire/IndexItems.php @@ -13,18 +13,17 @@ class IndexItems extends Component public function mount() { - $this->items = Item::all(); + $this->items = Item::approved()->get(); } public function render() { if ($this->term) { - $this->items = Item::where('name', 'like', '%'.$this->term.'%') + $this->items = Item::approved() + ->where('name', 'like', '%'.$this->term.'%') ->with('tags') ->get(); - } else { - $this->items = Item::with('tags')->get(); } return view('livewire.index-items'); diff --git a/app/Livewire/ItemsGuest.php b/app/Livewire/ItemsGuest.php index a323d17..aca6b31 100644 --- a/app/Livewire/ItemsGuest.php +++ b/app/Livewire/ItemsGuest.php @@ -2,18 +2,19 @@ namespace App\Livewire; -use Livewire\Component; use App\Models\Item; use App\Models\Tag; +use Livewire\Component; class ItemsGuest extends Component { public $items; + public $tags; public function mount() { - $this->items = Item::all(); + $this->items = Item::approved()->get(); $this->tags = Tag::all(); } @@ -25,10 +26,11 @@ public function render() public function filter($tagId = null) { if ($tagId == null) { - $this->items = Item::all(); + $this->items = Item::approved()->get(); + return; } - $this->items = Tag::find($tagId)->items; + $this->items = Tag::find($tagId)->items()->approved()->get(); } } diff --git a/app/Mail/ItemSuggested.php b/app/Mail/ItemSuggested.php new file mode 100644 index 0000000..c4482b8 --- /dev/null +++ b/app/Mail/ItemSuggested.php @@ -0,0 +1,53 @@ + + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Models/Item.php b/app/Models/Item.php index 7f7d4a4..1cb8e51 100644 --- a/app/Models/Item.php +++ b/app/Models/Item.php @@ -23,12 +23,19 @@ class Item extends Model 'manual_link', 'require_training', 'storage_location_id', + 'approved', ]; protected $casts = [ 'require_training' => 'boolean', + 'approved' => 'boolean', ]; + public function scopeApproved($query) + { + return $query->where('approved', true); + } + public function transactions(): HasMany { return $this->hasMany(Transaction::class); diff --git a/config/app.php b/config/app.php index ab68def..6dd3ce2 100644 --- a/config/app.php +++ b/config/app.php @@ -4,6 +4,8 @@ return [ + 'approvingUserEmail' => env('APPROVING_USER_EMAIL', null), + 'autoLoginCredentials' => env('AUTO_LOGIN_CREDENTIALS', null), /* diff --git a/database/migrations/2024_03_22_200023_add_approved_field_to_items.php b/database/migrations/2024_03_22_200023_add_approved_field_to_items.php new file mode 100644 index 0000000..65b5794 --- /dev/null +++ b/database/migrations/2024_03_22_200023_add_approved_field_to_items.php @@ -0,0 +1,31 @@ +boolean('approved')->default(false); + }); + + DB::table('items')->update(['approved' => true]); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('items', function (Blueprint $table) { + $table->dropColumn('approved'); + }); + } +}; diff --git a/public/images/1711142650-jpg b/public/images/1711142650-jpg new file mode 100644 index 0000000..9ee1f1e Binary files /dev/null and b/public/images/1711142650-jpg differ diff --git a/resources/views/emails/item-suggested.blade.php b/resources/views/emails/item-suggested.blade.php new file mode 100644 index 0000000..9884e1b --- /dev/null +++ b/resources/views/emails/item-suggested.blade.php @@ -0,0 +1,6 @@ +New item suggested! + +Titel: {{ $item->name }} +Beschreibung: {{ $item->description }} + +{{ __('Direct link') }} diff --git a/resources/views/livewire/items-guest.blade.php b/resources/views/livewire/items-guest.blade.php index 83dbef0..ff446e3 100644 --- a/resources/views/livewire/items-guest.blade.php +++ b/resources/views/livewire/items-guest.blade.php @@ -5,7 +5,7 @@ @endforeach -
+
@foreach ($items as $item) @endforeach diff --git a/resources/views/partials/header.blade.php b/resources/views/partials/header.blade.php index a8e4317..ec1083c 100644 --- a/resources/views/partials/header.blade.php +++ b/resources/views/partials/header.blade.php @@ -5,6 +5,7 @@
diff --git a/resources/views/templates/item/suggest.blade.php b/resources/views/templates/item/suggest.blade.php new file mode 100644 index 0000000..a67456b --- /dev/null +++ b/resources/views/templates/item/suggest.blade.php @@ -0,0 +1,46 @@ + +
+

{{ __('Suggest a new item') }}

+
+ @csrf + @method('POST') +
+ + + @error('name') +

{{ $message }}

+ @enderror +
+
+ + + @error('description') +

{{ $message }}

+ @enderror +
+
+ + + @error('image') +

{{ $message }}

+ @enderror +
+
+ + + @error('manual') +

{{ $message }}

+ @enderror +
+ +
+
+
diff --git a/routes/web.php b/routes/web.php index 07953c2..871b7bf 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,7 +3,6 @@ use App\Http\Controllers\ItemController; use App\Http\Controllers\StorageLocationController; use App\Http\Controllers\TransactionController; -use App\Models\Item; use Illuminate\Support\Facades\Route; /* @@ -19,6 +18,9 @@ Route::get('/', [ItemController::class, 'guest'])->name('home'); +Route::get('/items/suggest', [ItemController::class, 'suggest'])->name('item.suggest'); +Route::post('/items/suggest', [ItemController::class, 'storeSuggestion'])->name('item.storeSuggestion'); + Route::group(['middleware' => 'auth.basic'], function () { Route::group(['middleware' => 'auth.basic'], function () { Route::group(['prefix' => 'items'], function () {