Skip to content

Commit

Permalink
Merge pull request #7 from SethSharp/sharpie/dev-212-category-crud
Browse files Browse the repository at this point in the history
Sharpie/dev 212 category crud
  • Loading branch information
SethSharp authored Dec 2, 2023
2 parents 8e1a6ce + 5d36a45 commit 9fab537
Show file tree
Hide file tree
Showing 32 changed files with 1,022 additions and 67 deletions.
20 changes: 20 additions & 0 deletions app/Domain/Categories/Models/Category.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Domain\Categories\Models;

use App\Domain\Files\Models\File;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Category extends Model
{
use HasFactory;

protected $guarded = [];

public function file(): BelongsTo
{
return $this->belongsTo(File::class);
}
}
32 changes: 32 additions & 0 deletions app/Domain/Files/Actions/StoreFileAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace App\Domain\Files\Actions;

use App\Domain\Files\Models\File;
use Illuminate\Http\UploadedFile;
use Intervention\Image\Facades\Image;
use Illuminate\Support\Facades\Storage;

class StoreFileAction
{
public function __invoke(UploadedFile $file): File
{
$img = Image::make($file)
->fit(300)
->encode();

$path = $file->hashName(path: 'categories');

Storage::disk(
app()->environment('local')
? 'public'
: config('filesystems.default')
)->put($path, $img, 'public');

return File::create([
'path' => app()->environment('local')
? $path
: Storage::url($path)
]);
}
}
14 changes: 14 additions & 0 deletions app/Http/Controllers/Categories/CreateCategoryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Http\Controllers\Categories;

use Inertia\Inertia;
use App\Http\Controllers\Controller;

class CreateCategoryController extends Controller
{
public function __invoke()
{
return Inertia::render('Categories/CreateEdit');
}
}
17 changes: 17 additions & 0 deletions app/Http/Controllers/Categories/DeleteCategoryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Http\Controllers\Categories;

use App\Http\Controllers\Controller;
use App\Domain\Categories\Models\Category;

class DeleteCategoryController extends Controller
{
public function __invoke(Category $category)
{
// What happens with products with this category?
$category->delete();

return redirect()->back()->with('success', 'Successfully deleted category!');
}
}
17 changes: 17 additions & 0 deletions app/Http/Controllers/Categories/EditCategoryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Http\Controllers\Categories;

use Inertia\Inertia;
use App\Http\Controllers\Controller;
use App\Domain\Categories\Models\Category;

class EditCategoryController extends Controller
{
public function __invoke(Category $category)
{
return Inertia::render('Categories/CreateEdit', [
'category' => $category->load('file')
]);
}
}
17 changes: 17 additions & 0 deletions app/Http/Controllers/Categories/IndexCategoryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Http\Controllers\Categories;

use Inertia\Inertia;
use App\Http\Controllers\Controller;
use App\Domain\Categories\Models\Category;

class IndexCategoryController extends Controller
{
public function __invoke()
{
return Inertia::render('Categories/Index', [
'categories' => Category::with('file')->get()
]);
}
}
31 changes: 31 additions & 0 deletions app/Http/Controllers/Categories/StoreCategoryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Http\Controllers\Categories;

use App\Http\Controllers\Controller;
use App\Domain\Categories\Models\Category;
use App\Domain\Files\Actions\StoreFileAction;
use App\Http\Requests\Categories\StoreCategoryRequest;

class StoreCategoryController extends Controller
{
public function __invoke(
StoreCategoryRequest $request,
StoreFileAction $storeFileAction
) {
$category = Category::create([
'name' => $request->input('name'),
'description' => $request->input('description'),
]);

if ($request->file('file')) {
$file = $storeFileAction($request->file('file'));

$category->update([
'file_id' => $file->id
]);
}

return redirect()->back()->with('success', 'Successfully created new category!');
}
}
32 changes: 32 additions & 0 deletions app/Http/Controllers/Categories/UpdateCategoryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace App\Http\Controllers\Categories;

use App\Http\Controllers\Controller;
use App\Domain\Categories\Models\Category;
use App\Domain\Files\Actions\StoreFileAction;
use App\Http\Requests\Categories\UpdateCategoryRequest;

class UpdateCategoryController extends Controller
{
public function __invoke(
UpdateCategoryRequest $request,
Category $category,
StoreFileAction $storeFileAction
) {
$category->update([
'name' => $request->input('name'),
'description' => $request->input('description'),
]);

if ($request->file('file')) {
$file = $storeFileAction($request->file('file'));

$category->update([
'file_id' => $file->id
]);
}

return redirect()->back()->with('success', 'Successfully updated category!');
}
}
22 changes: 22 additions & 0 deletions app/Http/Requests/Categories/StoreCategoryRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace App\Http\Requests\Categories;

use Illuminate\Foundation\Http\FormRequest;

class StoreCategoryRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}

public function rules(): array
{
return [
'name' => ['required'],
'description' => ['nullable'],
'file' => ['required', 'image']
];
}
}
22 changes: 22 additions & 0 deletions app/Http/Requests/Categories/UpdateCategoryRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace App\Http\Requests\Categories;

use Illuminate\Foundation\Http\FormRequest;

class UpdateCategoryRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}

public function rules(): array
{
return [
'name' => ['required'],
'description' => ['nullable'],
'file' => ['nullable', 'image']
];
}
}
19 changes: 19 additions & 0 deletions database/factories/Domain/Categories/Models/CategoryFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Database\Factories\Domain\Categories\Models;

use App\Domain\Categories\Models\Category;
use Illuminate\Database\Eloquent\Factories\Factory;

class CategoryFactory extends Factory
{
protected $model = Category::class;

public function definition(): array
{
return [
'name' => fake()->name(),
'description' => fake()->words(6, true),
];
}
}
21 changes: 21 additions & 0 deletions database/migrations/2023_11_28_031044_create_categories_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

return new class() extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->foreignId('file_id')->nullable();
$table->string('name');
$table->string('description');
$table->timestamps();
});
}
};
17 changes: 16 additions & 1 deletion resources/js/Components/Button/DangerButton.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
<script setup>
import { Link } from '@inertiajs/vue3'
defineProps({
href: String,
})
</script>
<template>
<Link
v-if="href"
:href="href"
class="items-center my-3 px-4 py-2 my-auto bg-red-500 border rounded-md font-semibold text-sm text-white tracking-widest hover:bg-red-600 transition ease-in-out duration-150"
>
<slot />
</Link>
<button
class="inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 transition ease-in-out duration-150"
v-else
class="items-center my-3 px-4 py-2 my-auto bg-red-500 border rounded-md font-semibold text-sm text-white tracking-widest hover:bg-red-600 transition ease-in-out duration-150"
>
<slot />
</button>
Expand Down
12 changes: 8 additions & 4 deletions resources/js/Components/Button/SecondaryButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ defineProps({
</script>

<template>
<Link
:href="href"
<button
class="inline-flex items-center px-4 py-2 bg-white border border-gray-300 rounded-md font-semibold text-xs text-gray-700 tracking-widest shadow-sm hover:bg-gray-50 focus:outline-none transition ease-in-out duration-150"
>
<slot />
</Link>
<Link v-if="href" :href="href">
<slot />
</Link>
<div>
<slot />
</div>
</button>
</template>
62 changes: 62 additions & 0 deletions resources/js/Components/Card/CategoryCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script setup>
import { ref } from 'vue'
import { PencilIcon, EyeIcon } from '@heroicons/vue/24/outline/index.js'
import CreateEditCategoryModal from '@/Components/Modals/CreateEditCategoryModal.vue'
import ShowCategoryModal from '@/Components/Modals/ShowCategoryModal.vue'
defineProps({
category: Object,
})
const createEditState = ref(false)
const showState = ref(false)
const toggleCreateEdit = () => {
createEditState.value = !createEditState.value
}
const toggleShow = () => {
showState.value = !showState.value
}
</script>

<template>
<div class="relative overflow-hidden rounded-xl shadow-sm">
<div>
<div class="self-stretch flex-grow overflow-hidden">
<div class="aspect-1">
<img
:src="category.file.path"
:alt="category.name"
class="w-full h-full object-cover"
loading="lazy"
/>
</div>
</div>

<div class="absolute inset-0 flex justify-end z-30">
<div @click="toggleCreateEdit" class="bg-white/50 hover:bg-primary-100 p-2 h-fit">
<PencilIcon class="w-6 h-6" />
</div>
<div @click="toggleShow" class="bg-white/50 hover:bg-primary-100 p-2 h-fit">
<EyeIcon class="w-6 h-6" />
</div>
</div>
<div class="absolute inset-0 flex flex-col justify-end z-20">
<div
class="relative text-white p-4 font-bold bg-gradient-to-b from-transparent to-black/75 z-0"
>
<div class="text-sm z-50">{{ category.name }}</div>
</div>
</div>
</div>
</div>

<CreateEditCategoryModal
:state="createEditState"
@close="toggleCreateEdit"
:category="category"
/>

<ShowCategoryModal :state="showState" @close="toggleShow" :category="category" />
</template>
Loading

0 comments on commit 9fab537

Please sign in to comment.