- add category management
This commit is contained in:
parent
d47c719d13
commit
8974721c9c
@ -9,6 +9,7 @@ use App\Models\Category;
|
||||
use App\Repository\Interfaces\CategoryRepository;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\View\View;
|
||||
use Inertia\Response as InertiaResponse;
|
||||
|
||||
class CategoryController
|
||||
{
|
||||
@ -21,42 +22,35 @@ class CategoryController
|
||||
{
|
||||
$validate = $request->validated();
|
||||
if ($this->categoryRepository->update($category, $validate)) {
|
||||
return back()->with('message', 'Zaktualizowano kategorię!');
|
||||
return back()
|
||||
->with('success', 'Zaktualizowano kategorię!');
|
||||
}
|
||||
|
||||
return back()->withError(['message_error', 'Wystąpił błąd podczas aktualizacji!']);
|
||||
return back()
|
||||
->with(['error', 'Wystąpił błąd podczas aktualizacji!']);
|
||||
}
|
||||
|
||||
public function store(CategoryRequest $request)
|
||||
{
|
||||
// $validate = $request->validated();
|
||||
// if ($category = $this->categoryRepository->create($validate)) {
|
||||
// return redirect()
|
||||
// ->route('admin.category.update', compact('category'))
|
||||
// ->with('message', 'Utworzono kategorię!');
|
||||
// }
|
||||
|
||||
// return back()->withError(['message_error', 'Wystąpił błąd podczas tworzenia!']);
|
||||
|
||||
$category = $this->categoryRepository->create($request->validated());
|
||||
return redirect()
|
||||
->route('admin.category.update', compact('category'))
|
||||
->with('message', 'Utworzono kategorię!');
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
public function create(): InertiaResponse
|
||||
{
|
||||
return view('dashboard.categories.create');
|
||||
return inertia('Categories/Create');
|
||||
}
|
||||
|
||||
public function edit(Category $category): View
|
||||
public function edit(Category $category): InertiaResponse
|
||||
{
|
||||
return view('dashboard.categories.edit', compact('category'));
|
||||
return inertia('Categories/Edit', compact('category'));
|
||||
}
|
||||
|
||||
public function delete(Category $category): View
|
||||
public function delete(Category $category): InertiaResponse
|
||||
{
|
||||
return view('dashboard.categories.delete', compact('category'));
|
||||
return inertia('Categories/ConfirmDelete', compact('category'));
|
||||
}
|
||||
|
||||
public function destroy(Category $category): RedirectResponse
|
||||
@ -64,7 +58,9 @@ class CategoryController
|
||||
$name = $category->name;
|
||||
$category->delete();
|
||||
|
||||
return redirect()->route('admin.home')->with('message', 'Usunięto kategorię "'. $name .'"');
|
||||
return redirect()
|
||||
->route('admin.home')
|
||||
->with('info', 'Usunięto kategorię "'. $name .'"');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Dashboard;
|
||||
|
||||
use App\Http\Requests\ProjectRequest;
|
||||
|
@ -48,7 +48,7 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
public function update(Category $category, array $data = []): bool
|
||||
{
|
||||
$data = $this->parseToArray($data);
|
||||
if (!$category->default && isset($data['default']) && $data['default'] === true)
|
||||
if (!$category->default && $data['default'] === true)
|
||||
$this->unsetDefault();
|
||||
|
||||
return $category
|
||||
@ -58,7 +58,7 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
public function create(array $data = []): Category
|
||||
{
|
||||
$data = $this->parseToArray($data);
|
||||
if (isset($data['default']) && $data['default'] === true)
|
||||
if ($data['default'] === true)
|
||||
$this->unsetDefault();
|
||||
|
||||
return $this->category
|
||||
@ -85,18 +85,12 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
if (isset($data['priority']) && !is_integer($data['priority']))
|
||||
$toSave['priority'] = (int)$data['priority'];
|
||||
|
||||
if (
|
||||
isset($data['default']) &&
|
||||
in_array($data['default'], ['yes', 'on', 1, true])
|
||||
) $toSave['default'] = true;
|
||||
else $toSave['default'] = false;
|
||||
$toSave['default'] = $data['default'];
|
||||
|
||||
if (
|
||||
(isset($toSave['default']) && $toSave['default'] === true) ||
|
||||
(isset($data['visible']) &&
|
||||
in_array($data['visible'], ['yes', 'on', 1, true]))
|
||||
) $toSave['visible'] = true;
|
||||
else $toSave['visible'] = false;
|
||||
if ($toSave['default'] === true)
|
||||
$toSave['visible'] = true;
|
||||
else
|
||||
$toSave['visible'] = $data['visible'];
|
||||
|
||||
return $toSave;
|
||||
}
|
||||
|
37
resources/js/Pages/Categories/ConfirmDelete.vue
Normal file
37
resources/js/Pages/Categories/ConfirmDelete.vue
Normal file
@ -0,0 +1,37 @@
|
||||
<script setup>
|
||||
import { router } from '@inertiajs/vue3';
|
||||
|
||||
const props = defineProps({
|
||||
category: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
function confirmDelete() {
|
||||
router.delete(`/dashboard/category/${props.category.id}/delete`);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<InertiaHead title="Usuwanie kategorii" />
|
||||
<div class="p-4">
|
||||
<header class="pb-4">
|
||||
<h1 class="text-3xl font-roboto font-light">Usuwanie kategorii</h1>
|
||||
</header>
|
||||
<div class="max-w-[600px]">
|
||||
<p class="mb-4">Na pewno usunąć kategorię o nazwie {{ category.name }}?</p>
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
<InertiaLink
|
||||
as="button"
|
||||
href="/dashboard"
|
||||
class="col-span-1 flex justify-center items-center gap-3 w-full px-2 py-1 border-t-4 border-b-4 border-transparent hover:border-b-black"
|
||||
><FontAwesomeIcon :icon="['fas', 'backward']" />Anuluj</InertiaLink>
|
||||
<button
|
||||
@click.prevent="confirmDelete"
|
||||
class="col-span-2 flex justify-center items-center gap-3 w-full px-2 py-1 rounded-md bg-red-600 border-4 border-red-600 text-white text-lg hover:bg-transparent hover:text-red-600"
|
||||
><FontAwesomeIcon :icon="['fas', 'trash']" />Usuń kategorię {{ category.name }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
64
resources/js/Pages/Categories/Create.vue
Normal file
64
resources/js/Pages/Categories/Create.vue
Normal file
@ -0,0 +1,64 @@
|
||||
<script setup>
|
||||
import { useForm } from '@inertiajs/inertia-vue3';
|
||||
import Input from '../../Share/Components/Input.vue';
|
||||
|
||||
const form = useForm({
|
||||
name: null,
|
||||
slug: null,
|
||||
priority: Number(0),
|
||||
default: Boolean(false),
|
||||
visible: Boolean(false),
|
||||
});
|
||||
|
||||
function createCategory() {
|
||||
form.post('/dashboard/category');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<InertiaHead title="Nowa kategoria" />
|
||||
<div class="p-4">
|
||||
<header class="pb-4">
|
||||
<h1 class="text-3xl font-roboto font-light">Nowa kategoria</h1>
|
||||
</header>
|
||||
<div>
|
||||
<form class="flex flex-col gap-4" @submit.prevent="createCategory">
|
||||
<Input
|
||||
id="name"
|
||||
label="Nazwa"
|
||||
placeholder="Nazwa kategorii"
|
||||
v-model="form.name"
|
||||
:error="form.errors.name"
|
||||
/>
|
||||
<Input
|
||||
id="slug"
|
||||
label="Slug"
|
||||
placeholder="Slug dla kategorii"
|
||||
v-model="form.slug"
|
||||
:error="form.errors.slug"
|
||||
/>
|
||||
<Input
|
||||
id="priority"
|
||||
label="Priorytet"
|
||||
type="number"
|
||||
placeholder="Priorytet dla danej kategorii"
|
||||
v-model="form.priority"
|
||||
:error="form.errors.priority"
|
||||
/>
|
||||
<Input
|
||||
id="visible"
|
||||
label="Widoczny"
|
||||
type="checkbox"
|
||||
v-model="form.visible"
|
||||
/>
|
||||
<Input
|
||||
id="default"
|
||||
label="Domyślny"
|
||||
type="checkbox"
|
||||
v-model="form.default"
|
||||
/>
|
||||
<button class="px-0.5 py-1 rounded-lg bg-[#436da7] border-4 border-[#436da7] text-white text-lg hover:bg-transparent hover:text-[#436da7]">Dodaj kategorię</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
78
resources/js/Pages/Categories/Edit.vue
Normal file
78
resources/js/Pages/Categories/Edit.vue
Normal file
@ -0,0 +1,78 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useForm } from '@inertiajs/inertia-vue3';
|
||||
import Input from '../../Share/Components/Input.vue';
|
||||
|
||||
const props = defineProps({
|
||||
category: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const visibleCheckbox = ref(props.category.visible);
|
||||
const defaultCheckbox = ref(props.category.default);
|
||||
|
||||
const form = useForm({
|
||||
name: props.category.name,
|
||||
slug: props.category.slug,
|
||||
priority: props.category.priority,
|
||||
visible: visibleCheckbox,
|
||||
default: defaultCheckbox,
|
||||
});
|
||||
|
||||
function updateProject() {
|
||||
form.clearErrors();
|
||||
form.put(`/dashboard/category/${props.category.id}`);
|
||||
if (defaultCheckbox.value)
|
||||
visibleCheckbox.value = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<InertiaHead title="Nowy projekt" />
|
||||
<div class="p-4">
|
||||
<header class="pb-4">
|
||||
<h1 class="text-3xl font-roboto font-light">Edytuj {{ category.name }}</h1>
|
||||
</header>
|
||||
<div>
|
||||
<form class="flex flex-col gap-4" @submit.prevent="updateProject">
|
||||
<Input
|
||||
id="name"
|
||||
label="Nazwa"
|
||||
placeholder="Nazwa kategorii"
|
||||
v-model="form.name"
|
||||
:error="form.errors.name"
|
||||
/>
|
||||
<Input
|
||||
id="slug"
|
||||
label="Slug"
|
||||
placeholder="Slug dla kategorii"
|
||||
v-model="form.slug"
|
||||
:error="form.errors.slug"
|
||||
/>
|
||||
<Input
|
||||
id="priority"
|
||||
label="Priorytet"
|
||||
type="number"
|
||||
placeholder="Priorytet dla danej kategorii"
|
||||
v-model="form.priority"
|
||||
:error="form.errors.priority"
|
||||
/>
|
||||
<Input
|
||||
id="visible"
|
||||
label="Widoczny"
|
||||
type="checkbox"
|
||||
v-model="form.visible"
|
||||
/>
|
||||
<Input
|
||||
id="default"
|
||||
label="Domyślny"
|
||||
type="checkbox"
|
||||
v-model="form.default"
|
||||
/>
|
||||
<button class="px-0.5 py-1 rounded-lg bg-[#436da7] border-4 border-[#436da7] text-white text-lg hover:bg-transparent hover:text-[#436da7]">Aktualizuj kategorię</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
@ -9,16 +9,33 @@ defineProps({
|
||||
|
||||
<template>
|
||||
<section class="bg-gray-100 rounded-md p-4">
|
||||
<header class="pb-4">
|
||||
<h2 class="text-2xl font-roboto font-light">Categories</h2>
|
||||
<header class="flex justify-between items-center pb-4">
|
||||
<h2 class="text-2xl font-roboto font-light">Kategorie</h2>
|
||||
<InertiaLink
|
||||
as="button"
|
||||
href="/dashboard/category/create"
|
||||
class="bg-blue-400 hover:bg-blue-500 text-white px-2.5 py-1 rounded-full"><FontAwesomeIcon :icon="['fas', 'plus']" /></InertiaLink>
|
||||
</header>
|
||||
<ul class="flex flex-col gap-2">
|
||||
<li
|
||||
v-for="(category, key) in categories"
|
||||
:key="key"
|
||||
class="px-3 py-2 bg-white hover:bg-zinc-300"
|
||||
class="flex items-center justify-between px-3 py-2 bg-white hover:bg-neutral-200"
|
||||
>
|
||||
{{ category.name }}
|
||||
<InertiaLink :href="`/dashboard/category/${category.id}`">{{ category.name }}</InertiaLink>
|
||||
<div class="flex items-center gap-1">
|
||||
<InertiaLink
|
||||
as="button"
|
||||
class="px-1 py-0.5 text-lime-600 hover:text-lime-800 border-t-2 border-b-2 border-transparent hover:border-b-lime-600"
|
||||
:href="`/dashboard/category/${category.id}`"
|
||||
title="Edytuj kategorię"><FontAwesomeIcon :icon="['fas', 'pen-to-square']" /></InertiaLink>
|
||||
<InertiaLink
|
||||
v-if="!category.default"
|
||||
as="button"
|
||||
class="px-1 py-0.5 text-red-600 hover:text-red-800"
|
||||
:href="`/dashboard/category/${category.id}/delete`"
|
||||
title="Usuń kategorię z listy"><FontAwesomeIcon :icon="['fas', 'trash']" /></InertiaLink>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
@ -20,7 +20,7 @@ defineProps({
|
||||
default: null,
|
||||
}
|
||||
});
|
||||
defineEmits(['update:modelValue']);
|
||||
defineEmits(['update:model-value']);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -32,19 +32,21 @@ defineEmits(['update:modelValue']);
|
||||
:id="id"
|
||||
:class="['w-full min-w-full max-w-full h-[200px] min-h-[200px] px-2.5 py-2 border-b-2 rounded-md', error ? 'border-red-300 focus:border-red-400 hover:border-red-500 outline-none text-red-900 placeholder-red-400' : 'border-neutral-300 focus:border-neutral-400 hover:border-neutral-500 outline-none text-gray-900 placeholder-gray-400']"
|
||||
:value="modelValue"
|
||||
@input="$emit('update:modelValue', $event.target.value)"
|
||||
@input="$emit('update:model-value', $event.target.value)"
|
||||
:placeholder="placeholder"></textarea>
|
||||
<input v-else-if="type === 'checkbox'"
|
||||
:id="id"
|
||||
:value="modelValue"
|
||||
@input="$emit('update:modelValue', $event.target.value)"
|
||||
:checked="modelValue"
|
||||
@input="$emit('update:model-value', $event.target.checked)"
|
||||
:true-value="true"
|
||||
:false-value="false"
|
||||
type="checkbox" />
|
||||
<input v-else
|
||||
:id="id"
|
||||
:class="['w-full px-2.5 py-2 border-b-2 rounded-md', error ? 'border-red-300 focus:border-red-400 hover:border-red-500 outline-none text-red-900 placeholder-red-400' : 'border-neutral-300 focus:border-neutral-400 hover:border-neutral-500 outline-none text-gray-900 placeholder-gray-400']"
|
||||
:type="type"
|
||||
:value="modelValue"
|
||||
@input="$emit('update:modelValue', $event.target.value)"
|
||||
@input="$emit('update:model-value', $event.target.value)"
|
||||
:placeholder="placeholder" />
|
||||
<span class="text-red-400" v-if="error">{{ error }}</span>
|
||||
</div>
|
||||
|
@ -11,7 +11,11 @@ defineProps({
|
||||
<section class="bg-gray-100 rounded-md p-4">
|
||||
<header class="flex justify-between items-center pb-4">
|
||||
<h2 class="text-2xl font-roboto font-light">Projekty</h2>
|
||||
<InertiaLink as="button" href="/dashboard/project/create" class="bg-blue-400 hover:bg-blue-500 text-white px-2 py-1">Dodaj nowy</InertiaLink>
|
||||
<InertiaLink
|
||||
as="button"
|
||||
href="/dashboard/project/create"
|
||||
class="bg-blue-400 hover:bg-blue-500 text-white px-2.5 py-1 rounded-full"
|
||||
><FontAwesomeIcon :icon="['fas', 'plus']" /></InertiaLink>
|
||||
</header>
|
||||
<ul v-if="projects.length" class="flex flex-col gap-2">
|
||||
<li
|
||||
|
Loading…
x
Reference in New Issue
Block a user