mirror of
https://github.com/rico-vz/HeimerdingerLoL.git
synced 2025-12-06 10:10:48 +01:00
Add Champion model, form validation, and components for StreamerPanel.
- Added Champion model to StreamerPanelController. - Implemented form validation for champion_id, platform, username, and displayname in create and update methods. - Created StreamerCreateForm and StreamersTable components for better organization.
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Streamer;
|
use App\Models\Streamer;
|
||||||
|
use App\Models\Champion;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class StreamerPanelController extends Controller
|
class StreamerPanelController extends Controller
|
||||||
@@ -22,7 +23,9 @@ class StreamerPanelController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
//
|
return view('streamerpanel.streamer-create', [
|
||||||
|
'champions' => Champion::all(),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,7 +33,16 @@ class StreamerPanelController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
//
|
$request->validate([
|
||||||
|
'champion_id' => 'required|exists:champions,id',
|
||||||
|
'platform' => 'required|in:twitch,youtube,kick,douyu,huya',
|
||||||
|
'username' => 'required|string',
|
||||||
|
'displayname' => 'required|string',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Streamer::create($request->all());
|
||||||
|
|
||||||
|
return redirect()->route('streamerpanel.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +50,10 @@ class StreamerPanelController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function edit(Streamer $streamer)
|
public function edit(Streamer $streamer)
|
||||||
{
|
{
|
||||||
//
|
return view('streamerpanel.streamer-edit', [
|
||||||
|
'streamer' => $streamer,
|
||||||
|
'champions' => Champion::all(),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +61,16 @@ class StreamerPanelController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function update(Request $request, Streamer $streamer)
|
public function update(Request $request, Streamer $streamer)
|
||||||
{
|
{
|
||||||
//
|
$request->validate([
|
||||||
|
'champion_id' => 'required|exists:champions,id',
|
||||||
|
'platform' => 'required|in:twitch,youtube,kick,douyu,huya',
|
||||||
|
'username' => 'required|string',
|
||||||
|
'displayname' => 'required|string',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$streamer->update($request->all());
|
||||||
|
|
||||||
|
return redirect()->route('streamerpanel.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,6 +78,8 @@ class StreamerPanelController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function destroy(Streamer $streamer)
|
public function destroy(Streamer $streamer)
|
||||||
{
|
{
|
||||||
//
|
$streamer->delete();
|
||||||
|
|
||||||
|
return redirect()->route('streamerpanel.index');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
26
app/View/Components/Streamerpanel/StreamerCreateForm.php
Normal file
26
app/View/Components/Streamerpanel/StreamerCreateForm.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\View\Components\Streamerpanel;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\View\Component;
|
||||||
|
|
||||||
|
class StreamerCreateForm extends Component
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new component instance.
|
||||||
|
*/
|
||||||
|
public function __construct(public $champions)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the view / contents that represent the component.
|
||||||
|
*/
|
||||||
|
public function render(): View|Closure|string
|
||||||
|
{
|
||||||
|
return view('components.streamerpanel.streamer-create-form');
|
||||||
|
}
|
||||||
|
}
|
||||||
28
app/View/Components/Streamerpanel/StreamersTable.php
Normal file
28
app/View/Components/Streamerpanel/StreamersTable.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\View\Components\Streamerpanel;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\View\Component;
|
||||||
|
use App\Models\Streamer;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
class StreamersTable extends Component
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new component instance.
|
||||||
|
*/
|
||||||
|
public function __construct(public Collection $streamers)
|
||||||
|
{
|
||||||
|
$this->streamers = $streamers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the view / contents that represent the component.
|
||||||
|
*/
|
||||||
|
public function render(): View
|
||||||
|
{
|
||||||
|
return view('components.streamerpanel.streamers-table');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -118,4 +118,4 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
src: url('/fonts/inter-v13-latin-900.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
src: url('/fonts/inter-v13-latin-900.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,15 @@
|
|||||||
<ul
|
<ul
|
||||||
class="flex flex-col items-center p-2 md:flex-row md:space-x-6 md:mt-0 md:border-0 md:bg-white dark:bg-stone-800 md:dark:bg-stone-800 dark:border-stone-700">
|
class="flex flex-col items-center p-2 md:flex-row md:space-x-6 md:mt-0 md:border-0 md:bg-white dark:bg-stone-800 md:dark:bg-stone-800 dark:border-stone-700">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ route('champions.index') }}"
|
<a href="{{ route('streamerpanel.index') }}"
|
||||||
class="flex py-2 pl-3 pr-2 rounded hover:bg-stone-100 md:hover:bg-transparent md:border-0 md:p-0 md:dark:hover:text-orange-400 dark:hover:bg-stone-700 dark:hover:text-white md:dark:hover:bg-transparent">
|
class="flex py-2 pl-3 pr-2 rounded hover:bg-stone-100 md:hover:bg-transparent md:border-0 md:p-0 md:dark:hover:text-orange-400 dark:hover:bg-stone-700 dark:hover:text-white md:dark:hover:bg-transparent
|
||||||
|
{{ request()->routeIs('streamerpanel.*') ? 'text-orange-400 font-medium' : 'text-white' }}">
|
||||||
Streamers</a>
|
Streamers</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ route('skins.index') }}"
|
<a href="#"
|
||||||
class="flex py-2 pl-3 pr-2 rounded hover:bg-stone-100 md:hover:bg-transparent md:border-0 md:hover:text-orange-500 md:p-0 md:dark:hover:text-orange-400 dark:hover:bg-stone-700 dark:hover:text-white md:dark:hover:bg-transparent ">
|
class="flex py-2 pl-3 pr-2 rounded hover:bg-stone-100 md:hover:bg-transparent md:border-0 md:hover:text-orange-500 md:p-0 md:dark:hover:text-orange-400 dark:hover:bg-stone-700 dark:hover:text-white md:dark:hover:bg-transparent
|
||||||
|
{{ request()->routeIs('streamerrequests.*') ? 'text-orange-400 font-medium' : 'text-white' }}">
|
||||||
Streamer Requests</a>
|
Streamer Requests</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
11
resources/views/components/streamerpanel/home.blade.php
Normal file
11
resources/views/components/streamerpanel/home.blade.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<section class="max-w-screen-xl mx-auto mt-12">
|
||||||
|
<h1
|
||||||
|
class="text-2xl font-bold text-center text-transparent uppercase sm:text-4xl bg-gradient-to-bl from-orange-300 to-orange-500 bg-clip-text">
|
||||||
|
Streamers</h1>
|
||||||
|
<div class="flex justify-center mt-4">
|
||||||
|
<a href="{{ route('streamerpanel.streamers.create') }}"
|
||||||
|
class="flex items-center justify-center px-4 py-2 text-sm font-medium text-white bg-orange-500 rounded-md hover:bg-orange-600 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:ring-offset-2">
|
||||||
|
Add Streamer
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<form action="{{ route('streamerpanel.store') }}" method="POST" class="w-10/12 mx-auto ">
|
||||||
|
@csrf
|
||||||
|
<div class="flex flex-col space-y-4">
|
||||||
|
<div class="flex flex-col space-y-2">
|
||||||
|
<label for="champion_id" class="text-lg font-semibold text-orange-400">Champion</label>
|
||||||
|
<select name="champion_id" id="champion_id" class="w-full p-2 text-white rounded-md bg-stone-800">
|
||||||
|
@foreach ($champions as $champion)
|
||||||
|
<option value="{{ $champion->id }}">{{ $champion->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col space-y-2">
|
||||||
|
<label for="platform" class="text-lg font-semibold text-orange-400">Platform</label>
|
||||||
|
<select name="platform" id="platform" class="w-full p-2 text-white rounded-md bg-stone-800">
|
||||||
|
<option value="twitch">Twitch</option>
|
||||||
|
<option value="youtube">YouTube</option>
|
||||||
|
<option value="kick">Kick</option>
|
||||||
|
<option value="douyu">Douyu</option>
|
||||||
|
<option value="huya">Huya</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col space-y-2">
|
||||||
|
<label for="username" class="text-lg font-semibold text-orange-400">Username</label>
|
||||||
|
<input type="text" name="username" id="username" class="w-full p-2 text-white rounded-md bg-stone-800" />
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col space-y-2">
|
||||||
|
<label for="displayname" class="text-lg font-semibold text-orange-400">Display Name</label>
|
||||||
|
<input type="text" name="displayname" id="displayname"
|
||||||
|
class="w-full p-2 text-white rounded-md bg-stone-800" />
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<button type="submit" class="px-4 py-2 mt-3 text-white bg-orange-500 rounded-md">Add Streamer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
@push('top_scripts')
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/gridjs/dist/gridjs.umd.js"></script>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/gridjs/dist/theme/mermaid.min.css" rel="stylesheet" />
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
<div class="w-10/12 mx-auto">
|
||||||
|
<div id="streamers-wrapper"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@push('bottom_scripts')
|
||||||
|
<script>
|
||||||
|
new gridjs.Grid({
|
||||||
|
columns: [
|
||||||
|
"Champion",
|
||||||
|
"Streamer Name",
|
||||||
|
{
|
||||||
|
name: "URL",
|
||||||
|
formatter: (_, row) => gridjs.html(
|
||||||
|
`<a href="${row.cells[2].data}" target="_blank">${row.cells[2].data}</a>`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Actions",
|
||||||
|
formatter: (_, row) => gridjs.html(row.cells[3].data)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
data: [
|
||||||
|
@foreach ($streamers as $streamer)
|
||||||
|
["{{ $streamer->champion->name }}", "{{ $streamer->displayname }}",
|
||||||
|
"{{ $streamer->streamer_url }}", `<a href="/streamerpanel/edit/{{ $streamer->id }}">✏️</a> <a href="/streamerpanel/delete/{{ $streamer->id }}" onclick="event.preventDefault(); if (confirm('Are you sure you want to delete this streamer?')) { document.getElementById('delete-form-{{ $streamer->id }}').submit(); }">❌</a>
|
||||||
|
<form id="delete-form-{{ $streamer->id }}" action="/streamerpanel/delete/{{ $streamer->id }}" method="POST" style="display: none;">
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
</form>`
|
||||||
|
],
|
||||||
|
@endforeach
|
||||||
|
],
|
||||||
|
search: true,
|
||||||
|
pagination: {
|
||||||
|
limit: 20
|
||||||
|
},
|
||||||
|
language: {
|
||||||
|
'search': {
|
||||||
|
'placeholder': '🔍 Search streamers...'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).render(document.getElementById("streamers-wrapper"));
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
@@ -4,5 +4,6 @@
|
|||||||
@section('description', 'Heimerdinger.LoL: Streamer Panel for managing your streamer requests.')
|
@section('description', 'Heimerdinger.LoL: Streamer Panel for managing your streamer requests.')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
hello world
|
<x-streamerpanel.home />
|
||||||
|
<x-streamerpanel.streamerstable :streamers="$streamers" />
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
15
resources/views/streamerpanel/streamer-create.blade.php
Normal file
15
resources/views/streamerpanel/streamer-create.blade.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
@extends('layouts.streamerpanel')
|
||||||
|
|
||||||
|
@section('title', 'Streamer Panel • Heimerdinger.LoL')
|
||||||
|
@section('description', 'Heimerdinger.LoL: Streamer Panel for managing your streamer requests.')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<section class="max-w-screen-xl mx-auto mt-12">
|
||||||
|
<h1
|
||||||
|
class="text-2xl font-bold text-center text-transparent uppercase sm:text-4xl bg-gradient-to-bl from-orange-300 to-orange-500 bg-clip-text">
|
||||||
|
Add a new Streamer</h1>
|
||||||
|
<x-streamerpanel.streamer-create-form :champions="$champions" />
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
@endsection
|
||||||
@@ -18,6 +18,7 @@ use App\Models\SummonerIcon;
|
|||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Spatie\Honeypot\ProtectAgainstSpam;
|
use Spatie\Honeypot\ProtectAgainstSpam;
|
||||||
use Spatie\Sheets\Sheet;
|
use Spatie\Sheets\Sheet;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@@ -81,4 +82,9 @@ Route::get('/resource/sitemap', static fn () => (new HTMLSitemapController())->i
|
|||||||
Route::get(config('app.login_route'), static fn () => redirect('/pulse'))->name('login')->middleware('auth.basic');
|
Route::get(config('app.login_route'), static fn () => redirect('/pulse'))->name('login')->middleware('auth.basic');
|
||||||
|
|
||||||
// Streamer Panel
|
// Streamer Panel
|
||||||
Route::get('/streamerpanel', static fn () => (new \App\Http\Controllers\StreamerPanelController())->index())->name('streamers.index')->middleware('auth.basic');
|
Route::get('/streamerpanel', static fn () => (new \App\Http\Controllers\StreamerPanelController())->index())->name('streamerpanel.index')->middleware('auth.basic');
|
||||||
|
Route::get('/streamerpanel/add', static fn () => (new \App\Http\Controllers\StreamerPanelController())->create())->name('streamerpanel.streamers.create')->middleware('auth.basic');
|
||||||
|
Route::post('/streamerpanel/add', static fn (Request $request) => (new \App\Http\Controllers\StreamerPanelController())->store($request))->name('streamerpanel.store')->middleware('auth.basic');
|
||||||
|
Route::get('/streamerpanel/edit/{streamer}', static fn (\App\Models\Streamer $streamer) => (new \App\Http\Controllers\StreamerPanelController())->edit($streamer))->name('streamerpanel.edit')->middleware('auth.basic');
|
||||||
|
Route::post('/streamerpanel/edit/{streamer}', static fn (Request $request, \App\Models\Streamer $streamer) => (new \App\Http\Controllers\StreamerPanelController())->update($request, $streamer))->name('streamerpanel.update')->middleware('auth.basic');
|
||||||
|
Route::delete('/streamerpanel/delete/{streamer}', static fn (\App\Models\Streamer $streamer) => (new \App\Http\Controllers\StreamerPanelController())->destroy($streamer))->name('streamerpanel.destroy')->middleware('auth.basic');
|
||||||
|
|||||||
Reference in New Issue
Block a user