Skip to content

Commit

Permalink
Titus tasks for gerolstein (#512)
Browse files Browse the repository at this point in the history
* Update ddates

* Improve Module seeder logic

* Fix naming

* Add state logic

* Add modules to inertia share

* Linting

* Add random generaot backend

* Generate components

* Sort user by firstname

* Proof of Concept up and download from s3

* Image to s3 nearly done (req to controller not working)

* s3 Image Upload in user register and s3 show image funciton ready for use

* Remove outdated docs

* Add spatie permissions

* Remove dev code

* Migrate to rbac

* Update routes

* Fix drop col

* All comments implemented

* Add super admin role to prevent erros

* Add edit view

* Add link to old register/assigne page

* Add special role

* Add disabled flag

* Fix namings

* Add public api

* Improve user view

* Add missing if

* Add missing dependencies

* Improve S3 Implmentation

* Improvee admin ui

* Fix s3 logic

* Fix S3 logic

* Allow to edit super admins (except roles)

---------

Co-authored-by: DontEdit <vitor.macedo@outlook.de>
Co-authored-by: DontEdit <115659871+DontEdit@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 20, 2023
1 parent 9406f39 commit fa63d92
Show file tree
Hide file tree
Showing 123 changed files with 2,573 additions and 8,354 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ APP_URL=http://localhost
APP_FORCE_HTTPS=false
APP_EVENT_TYPE=demo

APP_PUBLIC_API_SECRET=secret

TUTOR_PASSWORD=password
ADMIN_PASSWORD=admin

Expand Down
51 changes: 49 additions & 2 deletions app/Http/Controllers/Api/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
use App\Models\Course;
use App\Models\Event;
use App\Models\Registration;
use App\Models\State;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

Expand Down Expand Up @@ -211,7 +213,7 @@ public function coursesUserAmount(): JsonResponse
foreach ($courses as $course) {
$result[] = [
'id' => $course->id,
'amount' => $course->users()->where('is_tutor', false)->count(),
'amount' => $course->users()->doesntHave('roles')->count(),
];
}

Expand Down Expand Up @@ -242,10 +244,55 @@ public function coursesUserAmountPerEvent(Request $request): JsonResponse
foreach ($courses as $course) {
$result[] = [
'id' => $course->id,
'amount' => $course->users()->where('is_tutor', false)->whereIn('id', $userIds)->count(),
'amount' => $course->users()->doesntHave('roles')->whereIn('id', $userIds)->count(),
];
}

return response()->json($result);
}

/**
* Return the current state of the random generator.
* The state is structured like this:
* {
* "state": "setup", // setup, idle, running, stopped
* "user": null | User, // default null and if stopped, the user that was selected by the random generator
* }
*
* The definition of the states is as follows:
* setup: The random generator is not set up yet
* idle: The random generator is set up, but not running yet
* running: The random generator is running
* stopped: The random generator is stopped and a user was selected
*/
public function randomGeneratorState(): JsonResponse
{
// get state with key randomGenerator
$state = State::where('key', 'randomGenerator')->first();

// if state does not exist, return setup
if (! $state) {
return response()->json([
'state' => 'setup',
]);
}

return response()->json(json_decode($state->value));
}

/**
* Fresh users data
*/
public function users(): JsonResponse
{
$users = User::with('course', 'roles')->get()->map(function ($user) {
$user->avatarUrl = $user->avatarUrl();

return $user;
});

return response()->json([
'users' => $users,
]);
}
}
28 changes: 28 additions & 0 deletions app/Http/Controllers/Api/PublicApiController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\JsonResponse;

class PublicApiController extends Controller
{
/**
* Returns all users.
*/
public function users(): JsonResponse
{
// get all users and get execute avatarUrl
$users = User::with('course', 'roles')->get()->map(function ($user) {
$user->avatarUrl = $user->avatarUrl();

return $user;
});

return response()->json([
'success' => true,
'users' => $users,
]);
}
}
127 changes: 121 additions & 6 deletions app/Http/Controllers/DashboardAdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
use App\Models\Slot;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request as IlluminateRequest;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;
use Spatie\Permission\Models\Role;

class DashboardAdminController extends Controller
{
Expand All @@ -27,18 +31,113 @@ public function index(): Response
$courses = Course::all();

foreach ($courses as $course) {
$course->users = $course->users()->where('is_tutor', false)->get();
$course->users = $course->users()->doesntHave('roles')->get();
}

return Inertia::render('Dashboard/Admin/Index', [
'courses' => $courses,
]);
}

/**
* Display the dashboard admin users page
*/
public function users(): Response
{
$roles = Role::where('name', '!=', 'super admin')->get();
$coures = Course::all();

return Inertia::render('Dashboard/Admin/Users', [
'roles' => $roles,
'courses' => $coures,
]);
}

/**
* Submit edit a user
*/
public function editUser(IlluminateRequest $request): RedirectResponse
{
$user = User::find($request->user);

if (! $user) {
Session::flash('error', 'Der angegebene User existiert nicht');

return Redirect::back();
}

// validate the request
$validated = Request::validate([
'firstname' => ['required', 'string', 'min:2', 'max:255'],
'lastname' => ['required', 'string', 'min:2', 'max:255'],
'email' => ['required', 'string', 'email', 'min:3', 'max:255', 'unique:users,email,'.$user->id],
'email_confirm' => ['required', 'string', 'email', 'min:3', 'max:255', 'same:email'],
'course_id' => ['required', 'integer', 'exists:courses,id'],
'role_id' => ['array'],
'is_disabled' => ['boolean'],
'remove_avatar' => ['boolean'],
'avatar.*.file' => ['nullable', 'image', 'mimes:jpeg,png,jpg,gif'],
]);

// check if all roles exists and not super admin if so add to roles array
$roles = [];
if (array_key_exists('role_id', $validated) && ! $user->hasRole('super admin')) {
foreach ($validated['role_id'] as $role) {
if (! Role::find($role)) {
Session::flash('error', 'Die angegebene Rolle existiert nicht');

return Redirect::back();
}
$roleObject = Role::find($role);
if ($roleObject->name == 'super admin') {
Session::flash('error', 'Der User kann nicht zu Super Admin gemacht werden');

return Redirect::back();
}
$roles[] = $role;
}
}

// check if remove_avatar is set
if (array_key_exists('remove_avatar', $validated) && $validated['remove_avatar']) {
// seet avatar to null
$validated['avatar'] = null;
} elseif (array_key_exists('avatar', $validated) && $validated['avatar'][0]) {
// get avatar file
$avatarFile = Request::file('avatar')[0]['file'];

// generate a uuid
$uuid = Str::uuid()->toString();

// store file in s3 bucket
$path = Storage::disk('s3')->put('/avatars/'.$uuid, $avatarFile);

// add avatar to validated array
$validated['avatar'] = $path;
}

// remove email_confirm, role_id and remove_avatar from array
unset($validated['email_confirm']);
unset($validated['role_id']);
unset($validated['remove_avatar']);

// update the user
$user->update($validated);

// sync roles
if (! $user->hasRole('super admin')) {
$user->syncRoles($roles);
}

Session::flash('success', 'Der Account <strong>'.$user->email.'</strong> wurde erfolgreich bearbeitet. Die Tabelle aktualisiert sich in wenigen Sekunden automatisch.');

return Redirect::back();
}

/**
* Display the dashboard admin registrations page
*/
public function registrations(\Illuminate\Http\Request $request): Response
public function registrations(IlluminateRequest $request): Response
{
$event = Event::with('groups')->with('slots')->find($request->event);
if (! $event) {
Expand All @@ -57,7 +156,7 @@ public function registrations(\Illuminate\Http\Request $request): Response
/**
* Display the dashboard admin event page
*/
public function event(\Illuminate\Http\Request $request): Response
public function event(IlluminateRequest $request): Response
{
$event = Event::find($request->event);
if (! $event) {
Expand All @@ -78,7 +177,7 @@ public function event(\Illuminate\Http\Request $request): Response
/**
* Display the dashboard admin event submit page
*/
public function eventSubmit(\Illuminate\Http\Request $request): Response
public function eventSubmit(IlluminateRequest $request): Response
{
$event = Event::find($request->event);
if (! $event) {
Expand Down Expand Up @@ -106,7 +205,7 @@ public function eventSubmit(\Illuminate\Http\Request $request): Response
/**
* Execute the dashboard admin event submit action
*/
public function eventExecuteSubmit(\Illuminate\Http\Request $request): RedirectResponse
public function eventExecuteSubmit(IlluminateRequest $request): RedirectResponse
{
$event = Event::find($request->event);
if (! $event) {
Expand Down Expand Up @@ -177,7 +276,7 @@ public function eventExecuteSubmit(\Illuminate\Http\Request $request): RedirectR
/**
* Display the register page
*/
public function register(): Response
public function register(Request $request): Response
{
// get courses ordered by name
$courses = Course::orderBy('name')->get();
Expand Down Expand Up @@ -211,11 +310,27 @@ public function registerUser(): RedirectResponse
'email' => ['required', 'string', 'email', 'min:3', 'max:255', 'unique:users'],
'email_confirm' => ['required', 'string', 'email', 'min:3', 'max:255', 'same:email'],
'course_id' => ['required', 'integer', 'exists:courses,id'],
'avatar.*.file' => ['nullable', 'image', 'mimes:jpeg,png,jpg,gif'],
]);

// remove email_confirm from array
unset($validated['email_confirm']);

// check if avatar is set
if (array_key_exists('avatar', $validated) && $validated['avatar'][0]) {
// get avatar file
$avatarFile = Request::file('avatar')[0]['file'];

// generate a uuid
$uuid = Str::uuid()->toString();

// store file in s3 bucket
$path = Storage::disk('s3')->put('/avatars/'.$uuid, $avatarFile);

// add avatar to validated array
$validated['avatar'] = $path;
}

// create the user
$user = User::create($validated);

Expand Down
85 changes: 85 additions & 0 deletions app/Http/Controllers/DashboardAdminRandomGeneratorController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

namespace App\Http\Controllers;

use App\Models\Course;
use App\Models\State;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Request;
use Inertia\Inertia;
use Inertia\Response;

class DashboardAdminRandomGeneratorController extends Controller
{
/**
* Display the dashboard admin random generator page
*/
public function index(): Response
{
// get all users except tutors and admins
$users = User::doesntHave('roles')->orderBy('firstname')->with('course')->get()->map(function ($user) {
$user->avatarUrl = $user->avatarUrl();

return $user;
});

// get all courses
$courses = Course::all();

return Inertia::render('Dashboard/Admin/RandomGenerator/Index', [
'users' => $users,
'courses' => $courses,
]);
}

/**
* Execute the dashboard admin random generator submit action
*/
public function indexExecuteSubmit(): JsonResponse
{
// validate the request
$request = Request::validate([
'state' => ['required', 'string', 'in:setup,idle,running,stopped'],
'user_id' => ['integer', 'exists:users,id'],
]);

// get the user
$user = null;
if ($request['state'] == 'stopped') {
$user = User::find($request['user_id']);

// check if no user was found
if (! $user) {
return response()->json([
'success' => false,
'message' => 'User not found',
]);
}

$user->avatarUrl = $user->avatarUrl();
}

// check if a state exists or we need to create a new one
$state = State::where('key', 'randomGenerator')->first();
if (! $state) {
$state = new State();
$state->key = 'randomGenerator';
}

// update the state
$state->value = json_encode([
'state' => $request['state'],
// return only id, firstname, lastname and avatarUrl
'user' => $user ? $user->only(['id', 'firstname', 'lastname', 'avatarUrl']) : null,
]);

// save the state
$state->save();

// return success
return response()->json([
'success' => true,
]);
}
}
Loading

0 comments on commit fa63d92

Please sign in to comment.