Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#8 - semester crud #40

Merged
merged 15 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .env.ci
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ DB_PORT=5432
DB_DATABASE=keating
DB_USERNAME=keating
DB_PASSWORD=password
DB_ROOT_PASSWORD=example
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @blumilksoftware/blumilk
* @blumilksoftware/keating
35 changes: 35 additions & 0 deletions app/Actions/ActivateSemesterAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace App\Actions;

use App\Models\Semester;
use Exception;
use Illuminate\Database\ConnectionInterface;

class ActivateSemesterAction
{
public function __construct(
protected ConnectionInterface $db,
) {}

/**
* @throws Exception
*/
public function execute(Semester $semester): void
{
try {
$this->db->beginTransaction();

Semester::getActive()?->update(["active" => 0]);
$semester->update(["active" => 1]);

$this->db->commit();
} catch (Exception $exception) {
$this->db->rollBack();

throw $exception;
}
}
}
76 changes: 76 additions & 0 deletions app/Http/Controllers/Dashboard/SemesterController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Dashboard;

use App\Actions\ActivateSemesterAction;
use App\Http\Controllers\Controller;
use App\Http\Requests\SemesterRequest;
use App\Models\Semester;
use Exception;
use Illuminate\Http\RedirectResponse;
use Inertia\Response;

class SemesterController extends Controller
{
public function index(): Response
{
$semesters = Semester::query()->orderByDesc("created_at")->get();

return inertia("Dashboard/Semester/Index", [
"semesters" => $semesters,
]);
}

public function create(): Response
{
return inertia("Dashboard/Semester/Create");
}

public function store(SemesterRequest $request): RedirectResponse
{
Semester::query()->create($request->validated());

return redirect()
->route("semesters.index")
->with("success", "Dodano semestr");
}

public function edit(Semester $semester): Response
{
return inertia("Dashboard/Semester/Edit", [
"semester" => $semester,
]);
}

public function update(SemesterRequest $request, Semester $semester): RedirectResponse
{
$semester->update($request->validated());

return redirect()
->route("semesters.index")
->with("success", "Zaktualizowano semestr");
}

public function destroy(Semester $semester): RedirectResponse
{
$semester->delete();

return redirect()->back()
->with("success", "Usunięto semestr");
}

public function toggleActive(Semester $semester, ActivateSemesterAction $activateSemesterAction): RedirectResponse
{
try {
$activateSemesterAction->execute($semester);

return redirect()->back()
->with("success", "Semestr aktywny");
} catch (Exception $e) {
return redirect()->back()
->with("error", "Wystąpił nieoczekiwany problem");
}
}
}
4 changes: 2 additions & 2 deletions app/Http/Middleware/HandleInertiaRequests.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function share(Request $request): array
{
return array_merge(parent::share($request), [
"auth" => $this->getAuthData($request),
"flash" => $this->getFlashedData($request),
"flash" => $this->getFlashData($request),
]);
}

Expand All @@ -25,7 +25,7 @@ protected function getAuthData(Request $request): array
];
}

protected function getFlashedData(Request $request): Closure
protected function getFlashData(Request $request): Closure
{
return fn(): array => [
"success" => $request->session()->get("success"),
Expand Down
17 changes: 17 additions & 0 deletions app/Http/Requests/SemesterRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class SemesterRequest extends FormRequest
{
public function rules(): array
{
return [
"name" => ["required", "max:255"],
];
}
}
45 changes: 45 additions & 0 deletions app/Models/Semester.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

/**
* @property string $id
* @property string $name
* @property boolean $active
* @property Carbon $created_at
* @property Carbon $updated_at
*/
class Semester extends Model
{
use HasFactory;
use HasUlids;

protected $fillable = [
"name",
"active",
];
protected $casts = [
"active" => "boolean",
];

public function scopeActive(Builder $query): Builder
{
return $query->where("active", true);
}

/**
* @return ?Semester
*/
public static function getActive(): ?Model
{
return self::active()->first();
}
}
9 changes: 9 additions & 0 deletions app/Models/Student.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

/**
* @property string $id
* @property string $name
* @property string $surname
* @property string $index_number
* @property Carbon $created_at
* @property Carbon $updated_at
*/
class Student extends Model
{
use HasFactory;
Expand Down
18 changes: 18 additions & 0 deletions database/factories/SemesterFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class SemesterFactory extends Factory
{
public function definition(): array
{
return [
"name" => "Semestr" . fake()->numberBetween(1, 7),
"active" => fake()->boolean,
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

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

return new class() extends Migration {
public function up(): void
{
Schema::create("semesters", function (Blueprint $table): void {
$table->ulid("id")->primary();
$table->string("name");
$table->boolean("active")->default(0);
$table->timestamps();
});
}

public function down(): void
{
Schema::dropIfExists("semesters");
}
};
2 changes: 1 addition & 1 deletion database/seeders/DatabaseSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ class DatabaseSeeder extends Seeder
{
public function run(): void
{
User::factory(1)->create();
User::factory()->create(["email" => "admin@example.com"]);
}
}
16 changes: 3 additions & 13 deletions resources/js/Layouts/DashboardLayout.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<script setup>
import { ref } from 'vue'
import { Dialog, DialogPanel, TransitionChild, TransitionRoot } from '@headlessui/vue'
import {
Bars3Icon,
ClockIcon,
BriefcaseIcon,
HomeIcon,
PowerIcon,
Expand All @@ -15,21 +13,15 @@ import {
BookmarkSquareIcon,
MagnifyingGlassIcon,
ClipboardIcon,
CodeBracketSquareIcon,
Cog6ToothIcon,
LockOpenIcon,
} from '@heroicons/vue/24/outline'
import { watch } from 'vue'
import { ref, watch } from 'vue'
import { useToast } from 'vue-toastification'

const toast = useToast()
const props = defineProps({
flash: {
type: Object,
default () {
return Object
},
},
flash: Object,
})

const navigation = [
Expand All @@ -56,9 +48,7 @@ const navigation = [
elements: [
{ name: 'Kursy', href: '#', icon: BriefcaseIcon, current: false },
{ name: 'Kierunki i specjalności', href: '#', icon: MagnifyingGlassIcon, current: false },
{ name: 'Semestry', href: '#', icon: ClipboardIcon, current: false },
{ name: 'Formy zajęć', href: '#', icon: CodeBracketSquareIcon, current: false },
{ name: 'Tryby studiów', href: '#', icon: ClockIcon, current: false },
{ name: 'Semestry', href: '/dashboard/semesters', icon: ClipboardIcon, current: false },
],
},
]
Expand Down
48 changes: 48 additions & 0 deletions resources/js/Pages/Dashboard/Semester/Create.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script setup>
import DashboardLayout from '@/Layouts/DashboardLayout.vue'
import Section from '@/Shared/Components/Section.vue'
import SubmitButton from '@/Shared/Components/Buttons/SubmitButton.vue'
import FormGroup from '@/Shared/Forms/FormGroup.vue'
import FormLabel from '@/Shared/Forms/FormLabel.vue'
import TextInput from '@/Shared/Forms/TextInput.vue'
import SecondaryButton from '@/Shared/Components/Buttons/SecondaryButton.vue'
import { useForm } from '@inertiajs/inertia-vue3'
import FormError from '@/Shared/Forms/FormError.vue'

const form = useForm({
name: '',
})

function createSemester() {
form.post('/dashboard/semesters')
}
</script>

<template>
<DashboardLayout>
<h3 class="text-base font-semibold leading-6 text-gray-900">
Dodawanie semestru
</h3>
<form @submit.prevent="createSemester">
<Section class="mt-3">
<div class="flex justify-between">
<FormGroup :full-width="false">
<FormLabel for="name">
Nazwa
</FormLabel>
<TextInput id="name" v-model="form.name" :error="form.errors.name" />
<FormError :error="form.errors.name" class="mt-2" />
</FormGroup>
</div>
<div class="flex justify-end space-x-3 py-3">
<SecondaryButton href="/dashboard/semesters">
Cofnij
</SecondaryButton>
<SubmitButton>
Utwórz
</SubmitButton>
</div>
</Section>
</form>
</DashboardLayout>
</template>
Loading