feat: ✨ implement CRUD stickies
This commit is contained in:
parent
f3a4e2fc80
commit
a9201415c9
25 changed files with 878 additions and 53 deletions
157
app/Http/Controllers/Bo/StickyController.php
Normal file
157
app/Http/Controllers/Bo/StickyController.php
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Stickies\StoreStickyRequest;
|
||||
use App\Http\Requests\Bo\Stickies\UpdateStickyRequest;
|
||||
use App\Models\Sticky;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class StickyController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Sticky::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $stickyModels */
|
||||
$stickyModels = Sticky::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$stickyModels,
|
||||
$search,
|
||||
null,
|
||||
'title',
|
||||
);
|
||||
}
|
||||
$searchFields = \implode(', ', [
|
||||
Str::ucfirst(trans('validation.attributes.title')),
|
||||
]);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($stickyModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$stickyModels = $this->paginate($stickyModels);
|
||||
|
||||
return view('bo.pages.stickies.index', compact('stickyModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Sticky $sticky
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Sticky $sticky): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.stickies.create', ['stickyModel' => $sticky]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Stickies\StoreStickyRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreStickyRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$sticky = new Sticky();
|
||||
|
||||
if ($sticky->fill($request->validated())->saveOrFail()) {
|
||||
return redirect()->route('bo.stickies.edit', $sticky)
|
||||
->with('success', trans('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Sticky $sticky
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Sticky $sticky): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.stickies.edit', ['stickyModel' => $sticky]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Stickies\UpdateStickyRequest $request
|
||||
* @param \App\Models\Sticky $sticky
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateStickyRequest $request, Sticky $sticky): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $sticky) {
|
||||
if ($sticky->fill($request->validated())->saveOrFail()) {
|
||||
return redirect()->route('bo.stickies.edit', $sticky)
|
||||
->with('success', trans('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.stickies.edit', $sticky)
|
||||
->with('error', trans('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Sticky $sticky
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Sticky $sticky): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
if ($sticky->deleteOrFail()) {
|
||||
return redirect()->route('bo.stickies.index')
|
||||
->with('success', trans('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\Sticky $sticky
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(Sticky $sticky): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($sticky->replicate());
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ use App\Models\Section;
|
|||
use App\Models\Site;
|
||||
use App\Models\Slide;
|
||||
use App\Models\StaticPage;
|
||||
use App\Models\Sticky;
|
||||
use App\Models\Strip;
|
||||
use App\Models\Testimonial;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
|
@ -274,6 +275,7 @@ class StaticPageController extends Controller
|
|||
$testimonialSection = $sectionModels->where('section', PageSectionEnum::hire_grow)->first();
|
||||
$paritySection = $sectionModels->where('section', PageSectionEnum::hire_parity)->first();
|
||||
$findSection = $sectionModels->where('section', PageSectionEnum::hire_find)->first();
|
||||
$navLinks = Sticky::query()->where('type', StaticPageType::we_hire)->get();
|
||||
|
||||
return view('fo.pages.hire', \compact(
|
||||
'staticPageModel',
|
||||
|
|
@ -284,7 +286,8 @@ class StaticPageController extends Controller
|
|||
'formationSection',
|
||||
'testimonialSection',
|
||||
'paritySection',
|
||||
'findSection'
|
||||
'findSection',
|
||||
'navLinks'
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
|||
56
app/Http/Requests/Bo/Stickies/StoreStickyRequest.php
Normal file
56
app/Http/Requests/Bo/Stickies/StoreStickyRequest.php
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Stickies;
|
||||
|
||||
use App\Enums\StaticPageType;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class StoreStickyRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'type' => [
|
||||
Rule::requiredIf($this->user()->can('create', $this->sticky)),
|
||||
new Enum(StaticPageType::class)
|
||||
],
|
||||
'title' => 'required|string|between:3,255',
|
||||
'anchor' => [
|
||||
Rule::requiredIf($this->user()->can('create', $this->sticky)),
|
||||
'string',
|
||||
'between:3,255'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'type' => trans('validation.custom.type'),
|
||||
'title' => trans('validation.attributes.title'),
|
||||
'anchor' => trans('validation.custom.anchor'),
|
||||
];
|
||||
}
|
||||
}
|
||||
7
app/Http/Requests/Bo/Stickies/UpdateStickyRequest.php
Normal file
7
app/Http/Requests/Bo/Stickies/UpdateStickyRequest.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Stickies;
|
||||
|
||||
class UpdateStickyRequest extends StoreStickyRequest
|
||||
{
|
||||
}
|
||||
69
app/Models/Sticky.php
Normal file
69
app/Models/Sticky.php
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\StaticPageType;
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property \App\Enums\StaticPageType $type Page type (StaticPageEnum).
|
||||
* @property string $title Title for the sticky.
|
||||
* @property string $anchor Anchor for the sticky.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \App\Models\ActivityLog $activityLogs Activities logs One-to-many relationship.
|
||||
*/
|
||||
class Sticky extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'type',
|
||||
'title',
|
||||
'anchor',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'type' => StaticPageType::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
// * Prevent user elevation privileges
|
||||
throw_if(
|
||||
auth('backend')->user() and auth('backend')->user()->role->value() < RoleEnum::conceptor->value(),
|
||||
AuthorizationException::class
|
||||
);
|
||||
});
|
||||
static::deleting(function (self $model) {
|
||||
// // * Prevent user elevation privileges
|
||||
throw_if(
|
||||
auth('backend')->user() and auth('backend')->user()->role->value() < RoleEnum::conceptor->value(),
|
||||
AuthorizationException::class
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
98
app/Policies/StickyPolicy.php
Normal file
98
app/Policies/StickyPolicy.php
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
class StickyPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function viewAny(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::conceptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function create(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::conceptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::conceptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can duplicate the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function duplicate(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::conceptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can publish/unpublish the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function changePublished(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can change the order of the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function changeOrder(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Database\Seeders\Mandatory\StickySeeder;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('stickies', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedTinyInteger('type')->comment('Type of the static page (StaticPageEnum).');
|
||||
$table->string('title')->comment('Title of the sticky');
|
||||
$table->string('anchor')->comment('Anchor of the sticky');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Artisan::call('db:seed', [
|
||||
'class' => StickySeeder::class
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('stickies');
|
||||
}
|
||||
};
|
||||
52
database/seeders/Mandatory/StickySeeder.php
Normal file
52
database/seeders/Mandatory/StickySeeder.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders\Mandatory;
|
||||
|
||||
use App\Enums\StaticPageType;
|
||||
use App\Models\Sticky;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class StickySeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Sticky::query()->updateOrCreate(
|
||||
[
|
||||
'type' => StaticPageType::we_hire,
|
||||
'title' => 'La vie d\'entreprise',
|
||||
'anchor' => 'company-life'
|
||||
],
|
||||
);
|
||||
Sticky::query()->updateOrCreate(
|
||||
[
|
||||
'type' => StaticPageType::we_hire,
|
||||
'title' => 'L\'alternance et la formation',
|
||||
'anchor' => 'formation'
|
||||
],
|
||||
);
|
||||
Sticky::query()->updateOrCreate(
|
||||
[
|
||||
'type' => StaticPageType::we_hire,
|
||||
'title' => 'Nos collaborateurs témoignent',
|
||||
'anchor' => 'we-testimonials'
|
||||
],
|
||||
);
|
||||
Sticky::query()->updateOrCreate(
|
||||
[
|
||||
'type' => StaticPageType::we_hire,
|
||||
'title' => 'La parité',
|
||||
'anchor' => 'parity'
|
||||
],
|
||||
);
|
||||
Sticky::query()->updateOrCreate(
|
||||
[
|
||||
'type' => StaticPageType::we_hire,
|
||||
'title' => 'En savoir plus',
|
||||
'anchor' => 'on-se-retrouve'
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
namespace Database\Seeders;
|
||||
|
||||
use Database\Seeders\Mandatory\StaticPageSeeder;
|
||||
use Database\Seeders\Mandatory\StickySeeder;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class MandatorySeeder extends Seeder
|
||||
|
|
@ -15,7 +16,8 @@ class MandatorySeeder extends Seeder
|
|||
public function run(): void
|
||||
{
|
||||
$this->call([
|
||||
StaticPageSeeder::class
|
||||
StaticPageSeeder::class,
|
||||
StickySeeder::class
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,5 +17,6 @@ return [
|
|||
'network' => 'réseau|réseaux',
|
||||
'aisle' => 'rayon',
|
||||
'brand' => 'marque',
|
||||
'sticky' => 'menu d\'ancre|menu d\'ancres'
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -302,5 +302,6 @@ return [
|
|||
'title' => 'titre de l\'ancre',
|
||||
'link' => 'lien de l\'ancre',
|
||||
],
|
||||
'anchor' => 'ancre'
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -281,6 +281,47 @@ body {
|
|||
> main {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 0;
|
||||
|
||||
.sticky-navigation {
|
||||
@include media-breakpoint-up(md) {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
bottom: 4rem;
|
||||
left: 4rem;
|
||||
max-width: 15rem;
|
||||
|
||||
&-wrapper {
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
transform: translateY(25%);
|
||||
transition: .3s;
|
||||
visibility: hidden;
|
||||
|
||||
&.show {
|
||||
height: auto;
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.col-md-12 {
|
||||
@include media-breakpoint-up(md) {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.badge {
|
||||
width: .5rem;
|
||||
height: .5rem;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> footer {
|
||||
|
|
|
|||
|
|
@ -56,44 +56,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.commit-navigation {
|
||||
@include media-breakpoint-up(md) {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
bottom: 4rem;
|
||||
left: 4rem;
|
||||
max-width: 15rem;
|
||||
|
||||
&-wrapper {
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
transform: translateY(25%);
|
||||
transition: .3s;
|
||||
visibility: hidden;
|
||||
|
||||
&.show {
|
||||
height: 14rem;
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.col-md-12 {
|
||||
@include media-breakpoint-up(md) {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.badge {
|
||||
width: .5rem;
|
||||
height: .5rem;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const commit = document.querySelector("section.commit");
|
||||
if (commit === null) {
|
||||
const stickyNav = document.querySelector("div.sticky-navigation");
|
||||
if (stickyNav === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const button = document.querySelector(".commit-navigation .btn") as HTMLButtonElement;
|
||||
const navWrapper = document.querySelectorAll(".commit-navigation-wrapper ");
|
||||
const button = document.querySelector(".sticky-navigation .btn") as HTMLButtonElement;
|
||||
const navWrapper = document.querySelectorAll(".sticky-navigation-wrapper ");
|
||||
button.addEventListener("click", () => {
|
||||
navWrapper.forEach((element: Element) => {
|
||||
element.classList.toggle("show");
|
||||
});
|
||||
document.querySelectorAll(".commit-navigation .btn svg").forEach(icon => {
|
||||
document.querySelectorAll(".sticky-navigation .btn svg").forEach(icon => {
|
||||
icon.classList.toggle("d-none");
|
||||
});
|
||||
});
|
||||
|
|
@ -17,9 +17,9 @@ import "./utilities/vue-fo";
|
|||
// CUSTOM
|
||||
import "./base/common";
|
||||
import "./base/layout";
|
||||
import "./base/sticky";
|
||||
|
||||
// PAGES
|
||||
import "./pages/commitments";
|
||||
import "./pages/unveil";
|
||||
import "./pages/site";
|
||||
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@
|
|||
{{-- MORE --}}
|
||||
<li class="nav-item">
|
||||
<div class="dropdown">
|
||||
<a class="nav-link @if (request()->routeIs('bo.logos.*') || request()->is('bo/pages/2/edit') || request()->is('bo/pages/3/edit')) active @endif dropdown-toggle" data-bs-toggle="dropdown" type="button"
|
||||
<a class="nav-link @if (request()->routeIs('bo.logos.*') || request()->routeIs('bo.stickies.*') || request()->is('bo/pages/2/edit') || request()->is('bo/pages/3/edit')) active @endif dropdown-toggle" data-bs-toggle="dropdown" type="button"
|
||||
aria-expanded="false">
|
||||
{{ Str::of(__('Voir plus'))->ucfirst() }}
|
||||
</a>
|
||||
|
|
@ -360,6 +360,16 @@
|
|||
</a>
|
||||
</li>
|
||||
@endcan
|
||||
{{-- STICKY --}}
|
||||
@can('viewAny', \App\Models\Sticky::class)
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (request()->routeIs('bo.stickies.*')) active @endif" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.stickies.index') }}"
|
||||
title="{{ __('crud.helpers.list_all', ['model' => Str::of(trans_choice('models.classes.sticky', \INF))]) }}">
|
||||
{{ Str::of(trans_choice('models.classes.sticky', \INF))->ucfirst() }}
|
||||
</a>
|
||||
</li>
|
||||
@endcan
|
||||
{{-- CONFIDENTIALITY --}}
|
||||
@can('viewAny', \App\Models\StaticPage::class)
|
||||
<li class="nav-item">
|
||||
|
|
|
|||
36
resources/views/bo/pages/stickies/create.blade.php
Normal file
36
resources/views/bo/pages/stickies/create.blade.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
@extends('bo.layout', ['brParam' => $stickyModel])
|
||||
|
||||
@section('title', __('Création d\'un :model', ['model' => trans_choice('models.classes.sticky', 1)]))
|
||||
@section('description', __('Création d\'un tout nouveau :model', ['model' => trans_choice('models.classes.sticky', 1)]))
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">
|
||||
<div class="d-flex align-items-start flex-row">
|
||||
<a class="btn btn-primary text-decoration-none m-0" data-bs-toggle="tooltip" href="{{ route('bo.stickies.index') }}"
|
||||
title="{{ __('crud.helpers.list_all', ['model' => trans_choice('models.classes.sticky', 1)]) }}">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
@include('modules.breadcrumbs.breadcrumb-body', ['brParam' => $stickyModel])
|
||||
</div>
|
||||
<div class="mb-md-0 mb-2">
|
||||
<button class="btn btn-primary" id="formSubmitClone" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ __('crud.helpers.save_model', ['model' => trans_choice('models.classes.sticky', 1)]) }}">
|
||||
{{ Str::ucfirst(__('crud.actions.save')) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<form action="{{ route('bo.stickies.store') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@include('bo.pages.stickies.form')
|
||||
@include('bo.partials.script-button-clone')
|
||||
<div class="row mt-3">
|
||||
<div class="col text-center">
|
||||
<button class="btn btn-primary" id="formSubmit" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ __('crud.helpers.save_model', ['model' => trans_choice('models.classes.sticky', 1)]) }}">
|
||||
{{ Str::ucfirst(__('crud.actions.save')) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
52
resources/views/bo/pages/stickies/edit.blade.php
Normal file
52
resources/views/bo/pages/stickies/edit.blade.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
@extends('bo.layout', ['brParam' => $stickyModel])
|
||||
|
||||
@section('title', __('Édition d\'un :model', ['model' => trans_choice('models.classes.sticky', 1)]))
|
||||
@section('description', __('Édition d\'un :model déjà existant', ['model' => trans_choice('models.classes.sticky', 1)]))
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">
|
||||
<div class="d-flex align-items-start flex-row">
|
||||
<a class="btn btn-primary text-decoration-none m-0" data-bs-toggle="tooltip" href="{{ route('bo.stickies.index') }}"
|
||||
title="{{ __('crud.helpers.list_all', ['model' => trans_choice('models.classes.sticky', '*')]) }}">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
@include('modules.breadcrumbs.breadcrumb-body', ['brParam' => $stickyModel])
|
||||
</div>
|
||||
<div class="mb-md-0 mb-2">
|
||||
<form class="btn-group confirmDeleteTS" action="{{ route('bo.stickies.destroy', $stickyModel) }}" method="POST" novalidate>
|
||||
@can('duplicate', $stickyModel)
|
||||
<a class="btn btn-secondary" data-bs-toggle="tooltip" href="{{ route('bo.stickies.duplicate', ['sticky' => $stickyModel]) }}"
|
||||
title="{{ Str::ucfirst(__('crud.actions.duplicate')) }}">
|
||||
<i class="fa-solid fa-copy"></i>
|
||||
</a>
|
||||
@endcan
|
||||
<button class="btn btn-primary" id="formSubmitClone" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ __('crud.helpers.save_model', ['model' => trans_choice('models.classes.sticky', 1)]) }}">
|
||||
{{ Str::ucfirst(__('crud.actions.save')) }}
|
||||
</button>
|
||||
@can('delete', $stickyModel)
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button class="btn btn-danger" data-bs-toggle="tooltip" type="submit" title="{{ Str::ucfirst(__('crud.actions.delete')) }}">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
@endcan
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<form action="{{ route('bo.stickies.update', $stickyModel) }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
@include('bo.pages.stickies.form')
|
||||
@include('bo.partials.script-button-clone')
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<button class="btn btn-primary" id="formSubmit" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ __('crud.helpers.save_model', ['model' => trans_choice('models.classes.sticky', 1)]) }}">
|
||||
{{ Str::ucfirst(__('crud.actions.save')) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
92
resources/views/bo/pages/stickies/form.blade.php
Normal file
92
resources/views/bo/pages/stickies/form.blade.php
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<div class="row">
|
||||
{{-- TYPE --}}
|
||||
@can('create', \App\Models\Sticky::class)
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
<legend>{{ Str::ucfirst(__('validation.custom.type')) }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@include('bo.partials.inputs.tinyint-enum', [
|
||||
'id' => 'stickyType',
|
||||
'label' => __('Associer un type'),
|
||||
'name' => 'type',
|
||||
'model' => $stickyModel ?? null,
|
||||
'required' => true,
|
||||
'associatedModels' => \App\Enums\StaticPageType::toArray(),
|
||||
'helper' => __('Sélectionnez un type de page dans la liste déroulante.'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
@endcan
|
||||
{{-- TITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
<legend>{{ Str::ucfirst(__('validation.attributes.title')) }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'stickyTitle',
|
||||
'label' => __(':field :inter:model', [
|
||||
'field' => Str::ucfirst(__('validation.attributes.title')),
|
||||
'inter' => __('validation.custom.of_the.male'),
|
||||
'model' => trans_choice('models.classes.sticky', 1),
|
||||
]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'title',
|
||||
'required' => true,
|
||||
'model' => $stickyModel ?? null,
|
||||
'helper' => __('validation.between.string', [
|
||||
'attribute' => __(':field :inter:model', [
|
||||
'field' => __('validation.attributes.title'),
|
||||
'inter' => __('validation.custom.of_the.male'),
|
||||
'model' => trans_choice('models.classes.sticky', 1),
|
||||
]),
|
||||
'min' => 3,
|
||||
'max' => 255,
|
||||
]),
|
||||
'placeholder' => __('Un nom clair et concis'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- ANCHOR --}}
|
||||
@can('create', \App\Models\Sticky::class)
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
<legend>{{ Str::ucfirst(__('validation.custom.anchor')) }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'stickyAnchor',
|
||||
'label' => __(':field :inter:model', [
|
||||
'field' => Str::ucfirst(__('validation.custom.anchor')),
|
||||
'inter' => __('validation.custom.of_the.male'),
|
||||
'model' => trans_choice('models.classes.sticky', 1),
|
||||
]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'anchor',
|
||||
'required' => true,
|
||||
'model' => $stickyModel ?? null,
|
||||
'helper' => __('validation.between.string', [
|
||||
'attribute' => __(':field :inter:model', [
|
||||
'field' => __('validation.custom.anchor'),
|
||||
'inter' => __('validation.custom.of_the.male'),
|
||||
'model' => trans_choice('models.classes.sticky', 1),
|
||||
]),
|
||||
'min' => 3,
|
||||
'max' => 255,
|
||||
]),
|
||||
'placeholder' => __('Un nom clair et concis'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
@endcan
|
||||
<div class="col-12 text-center">
|
||||
<p><b>{{ __('validation.custom.required_fields') }}</b></p>
|
||||
</div>
|
||||
</div>
|
||||
62
resources/views/bo/pages/stickies/index-list.blade.php
Normal file
62
resources/views/bo/pages/stickies/index-list.blade.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<table class="table-hover table-fix-action m-0 table">
|
||||
@if (count($stickyModels) > 0)
|
||||
<thead>
|
||||
@include('bo.modules.table-col-sorter', [
|
||||
'cols' => [
|
||||
'type' => Str::ucfirst(__('validation.custom.type')),
|
||||
'title' => Str::ucfirst(__('validation.attributes.title')),
|
||||
'updated_at' => Str::ucfirst(__('validation.attributes.updated_at')),
|
||||
],
|
||||
])
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($stickyModels as $stickyModel)
|
||||
<tr class="border-bottom list-item">
|
||||
<td class="text-center align-middle">{{ $stickyModel->type->label() }}</td>
|
||||
<td class="text-center align-middle">{{ $stickyModel->title }}</td>
|
||||
<td class="text-center align-middle">
|
||||
<span class="badge bg-secondary">{{ $stickyModel->updated_at->isoFormat('LLLL') }}</span>
|
||||
</td>
|
||||
<td class="text-end align-middle">
|
||||
@canAny(['delete', 'duplicate', 'update'], $stickyModel)
|
||||
<form class="btn-group confirmDeleteTS" action="{{ route('bo.stickies.destroy', $stickyModel) }}" method="POST"
|
||||
novalidate>
|
||||
@can('duplicate', $stickyModel)
|
||||
<a class="btn btn-sm btn-secondary" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.stickies.duplicate', ['sticky' => $stickyModel]) }}"
|
||||
title="{{ Str::ucfirst(__('crud.actions.duplicate')) }}">
|
||||
<i class="fa-solid fa-copy"></i>
|
||||
</a>
|
||||
@endcan
|
||||
@can('update', $stickyModel)
|
||||
<a class="btn btn-sm btn-primary" data-bs-toggle="tooltip"
|
||||
href="{{ route('bo.stickies.edit', ['sticky' => $stickyModel]) }}"
|
||||
title="{{ Str::ucfirst(__('crud.actions.update')) }}">
|
||||
<i class="fa-solid fa-pencil"></i>
|
||||
</a>
|
||||
@endcan
|
||||
@can('delete', $stickyModel)
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button class="btn btn-sm btn-danger" data-bs-toggle="tooltip" type="submit"
|
||||
title="{{ Str::ucfirst(__('crud.actions.delete')) }}">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
@endcan
|
||||
</form>
|
||||
@else
|
||||
<span class="text-danger" data-bs-toggle="tooltip" title="{{ __('list.right') }}">
|
||||
<i class="fa-solid fa-ban"></i>
|
||||
</span>
|
||||
@endcan
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
@else
|
||||
<tr>
|
||||
<td class="border-0">{{ trans_choice('crud.other.no_model_found', 1, ['model' => trans_choice('models.classes.sticky', 1)]) }}
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
21
resources/views/bo/pages/stickies/index.blade.php
Normal file
21
resources/views/bo/pages/stickies/index.blade.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
@extends('bo.layout')
|
||||
|
||||
@section('title', Str::ucfirst(trans_choice('models.classes.sticky', \INF)))
|
||||
@section('description', __('Liste de tous les :model', ['model' => trans_choice('models.classes.sticky', \INF)]))
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap">
|
||||
@include('modules.breadcrumbs.breadcrumb-body')
|
||||
@can('create', \App\Models\Sticky::class)
|
||||
<a class="btn btn-primary float-right" data-bs-toggle="tooltip" href="{{ route('bo.stickies.create') }}"
|
||||
title="{{ __('crud.helpers.create_model', ['model' => __('models.classes.sticky')]) }}">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
@endcan
|
||||
</div>
|
||||
@include('bo.modules.search-bar')
|
||||
<div class="table-responsive mb-3">
|
||||
@include('bo.pages.stickies.index-list')
|
||||
</div>
|
||||
{{ $stickyModels->links() }}
|
||||
@endsection
|
||||
|
|
@ -19,8 +19,8 @@
|
|||
<section class="commit">
|
||||
{{-- AMBITION --}}
|
||||
<section class="ambition anchor-padding container my-4" id="introduction">
|
||||
<div class="commit-navigation z-2">
|
||||
<div class="commit-navigation-wrapper show row m-0 p-0">
|
||||
<div class="sticky-navigation z-2">
|
||||
<div class="sticky-navigation-wrapper show row m-0 p-0">
|
||||
{{-- blade-formatter-disable --}}
|
||||
@php
|
||||
$commitNav = [
|
||||
|
|
|
|||
|
|
@ -19,6 +19,47 @@
|
|||
<section class="we-hire">
|
||||
{{-- COMPAGNY LIFE --}}
|
||||
<section class="company-life anchor-padding" id="company-life">
|
||||
<div class="sticky-navigation z-2">
|
||||
<div class="sticky-navigation-wrapper show row m-0 p-0">
|
||||
@foreach ($navLinks as $key => $link)
|
||||
<div class="col-6 col-md-12 px-md-0 py-md-1 p-2">
|
||||
<div @class([
|
||||
'rounded-5 shadow-sm h-100',
|
||||
match($loop->index) {
|
||||
0 => 'bg-primary-light',
|
||||
1 => 'bg-secondary-light',
|
||||
2 => 'bg-quad-light',
|
||||
3 => 'bg-quint-light',
|
||||
4 => 'bg-sixt-light',
|
||||
default => 'bg-primary-light'
|
||||
}
|
||||
])>
|
||||
<a class="d-flex justify-content-start align-items-center text-primary text-decoration-none p-sm-3 p-2 h-100"
|
||||
data-bs-toggle="tooltip" href="#{{ $link->anchor }}"
|
||||
title="{{ __('Accéder à la partie :name de la page', ['name' => $link->title]) }}">
|
||||
<span @class([
|
||||
'badge rounded-pill d-block me-2',
|
||||
match($loop->index) {
|
||||
0 => 'bg-primary',
|
||||
1 => 'bg-secondary',
|
||||
2 => 'bg-quad',
|
||||
3 => 'bg-quint',
|
||||
4 => 'bg-sixt',
|
||||
default => 'bg-primary'
|
||||
}
|
||||
])></span>
|
||||
<small>{{ $link->title }}</small>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<button class="d-none d-md-block btn btn-primary rounded-pill mt-1 w-fit px-3"
|
||||
title="{{ __('Afficher/Masquer le menu des ancres') }}">
|
||||
<i class="fa-solid fa-plus d-none"></i>
|
||||
<i class="fa-solid fa-minus"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row position-relative">
|
||||
<div class="col-12 text-center">
|
||||
|
|
@ -114,7 +155,7 @@
|
|||
</div>
|
||||
</section>
|
||||
{{-- FORMATION --}}
|
||||
<section class="formation border-top-curved-upper-quad-light mb-5">
|
||||
<section class="formation border-top-curved-upper-quad-light mb-5" id="formation">
|
||||
<div class="container">
|
||||
<div class="row position-relative">
|
||||
<div class="col-12 text-center">
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use App\Models\Section;
|
|||
use App\Models\Site;
|
||||
use App\Models\Slide;
|
||||
use App\Models\StaticPage;
|
||||
use App\Models\Sticky;
|
||||
use App\Models\Strip;
|
||||
use App\Models\Testimonial;
|
||||
use App\Models\User;
|
||||
|
|
@ -296,3 +297,23 @@ Breadcrumbs::for('bo.brands.duplicate', function (Generator $trail) {
|
|||
$trail->parent('bo.brands.index');
|
||||
$trail->push(Str::ucfirst(trans('crud.actions.duplicate')));
|
||||
});
|
||||
|
||||
// * STICKIES
|
||||
Breadcrumbs::for('bo.stickies.index', function (Generator $trail) {
|
||||
$trail->push(
|
||||
Str::of(trans_choice('models.classes.sticky', 1))->plural()->ucfirst(),
|
||||
route('bo.stickies.index', ['sort_col' => 'updated_at', 'sort_way' => 'desc'])
|
||||
);
|
||||
});
|
||||
Breadcrumbs::for('bo.stickies.create', function (Generator $trail) {
|
||||
$trail->parent('bo.stickies.index');
|
||||
$trail->push(Str::ucfirst(trans('crud.actions.create')), route('bo.stickies.create'));
|
||||
});
|
||||
Breadcrumbs::for('bo.stickies.edit', function (Generator $trail, Sticky $sticky) {
|
||||
$trail->parent('bo.stickies.index');
|
||||
$trail->push(Str::ucfirst(trans('crud.actions.edit')), route('bo.stickies.edit', $sticky));
|
||||
});
|
||||
Breadcrumbs::for('bo.stickies.duplicate', function (Generator $trail) {
|
||||
$trail->parent('bo.stickies.index');
|
||||
$trail->push(Str::ucfirst(trans('crud.actions.duplicate')));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use App\Http\Controllers\Bo\SectionController;
|
|||
use App\Http\Controllers\Bo\SiteController;
|
||||
use App\Http\Controllers\Bo\SlideController;
|
||||
use App\Http\Controllers\Bo\StaticPageController;
|
||||
use App\Http\Controllers\Bo\StickyController;
|
||||
use App\Http\Controllers\Bo\StripController;
|
||||
use App\Http\Controllers\Bo\TestimonialController;
|
||||
use App\Http\Controllers\Bo\UploadController;
|
||||
|
|
@ -205,6 +206,13 @@ Route::middleware(['admin-secure'])->prefix('bo')
|
|||
'changePublished'
|
||||
])->name('brands.change-published');
|
||||
|
||||
// * stickies.
|
||||
Route::resource('stickies', StickyController::class)->except('show');
|
||||
Route::get('/stickies/{sticky}/duplicate', [
|
||||
StickyController::class,
|
||||
'duplicate'
|
||||
])->name('stickies.duplicate');
|
||||
|
||||
Route::middleware('can:isConceptor')->group(function () {
|
||||
// * ACTIVITY LOGS.
|
||||
Route::resource('activity_logs', ActivityLogController::class)->only(['index', 'show']);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue