Compare commits
24 commits
admin-secu
...
testing
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24579674c5 | ||
|
|
d67fa6ff76 | ||
|
|
ea8541209a | ||
|
|
8988559c68 | ||
|
|
1420bb52e6 | ||
|
|
1039d91f18 | ||
|
|
28f4baa8e3 | ||
|
|
ce62ad8020 | ||
|
|
53a77e8a0e | ||
|
|
7f1cf742a7 | ||
|
|
6043f7c8cc | ||
|
|
6fbad46d90 | ||
|
|
5cfbb17f7b | ||
|
|
c9ca0b17bf | ||
|
|
8d83cd3b4d | ||
|
|
d58d0e5f2a | ||
|
|
0417c73d4a | ||
|
|
c1369ea508 | ||
|
|
9ce41966bc | ||
|
|
67e1273128 | ||
|
|
3857f1ab79 | ||
|
|
998f7e0a8a | ||
|
|
568ebb9f2d | ||
|
|
0468e10854 |
76 changed files with 3542 additions and 1237 deletions
164
app/Http/Controllers/Bo/NewsController.php
Normal file
164
app/Http/Controllers/Bo/NewsController.php
Normal file
|
|
@ -0,0 +1,164 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Bo;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\Bo\News\StoreNewsRequest;
|
||||||
|
use App\Http\Requests\Bo\News\UpdateNewsRequest;
|
||||||
|
use App\Models\News;
|
||||||
|
use App\Traits\Controllers\ChangesModelOrder;
|
||||||
|
use App\Traits\Controllers\UpdateModelStatus;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class NewsController extends Controller
|
||||||
|
{
|
||||||
|
use ChangesModelOrder;
|
||||||
|
use UpdateModelStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Builder $news */
|
||||||
|
$news = News::query();
|
||||||
|
|
||||||
|
if ($request->search) {
|
||||||
|
$this->searchQuery(
|
||||||
|
$news,
|
||||||
|
$request->search,
|
||||||
|
null,
|
||||||
|
'seo_title',
|
||||||
|
'name',
|
||||||
|
'title',
|
||||||
|
'subtitle',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sortQuery($news);
|
||||||
|
$searchFields = trans('Name');
|
||||||
|
|
||||||
|
$newsListModels = $news->paginate(10);
|
||||||
|
|
||||||
|
return view('bo.pages.news.index', compact('newsListModels', 'searchFields'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('bo.pages.news.create');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\News\StoreNewsRequest $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store(StoreNewsRequest $request)
|
||||||
|
{
|
||||||
|
return DB::transaction(function () use ($request) {
|
||||||
|
$news = new News();
|
||||||
|
$news->data = News::getEmptyData();
|
||||||
|
$news->fill(array_replace_recursive(
|
||||||
|
\json_decode(\json_encode($news->toArray()), true),
|
||||||
|
$request->validated()
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($news->saveOrFail()) {
|
||||||
|
return redirect()
|
||||||
|
->route('bo.news.edit', $news)
|
||||||
|
->with('success', trans(
|
||||||
|
'crud.messages.has_been_created',
|
||||||
|
['model' => Str::singular(trans('models.classes.news'))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->with('error', trans(
|
||||||
|
'crud.messages.cannot_be_created',
|
||||||
|
['model' => Str::singular(trans('models.classes.news'))]
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*
|
||||||
|
* @param \App\Models\News $news
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function edit(News $news)
|
||||||
|
{
|
||||||
|
return view('bo.pages.news.edit', [
|
||||||
|
'newsModel' => $news
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\Bo\News\UpdateNewsRequest $request
|
||||||
|
* @param \App\Models\News $news
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function update(UpdateNewsRequest $request, News $news)
|
||||||
|
{
|
||||||
|
return DB::transaction(function () use ($request, $news) {
|
||||||
|
$news->fill(array_replace_recursive(
|
||||||
|
\json_decode(\json_encode($news->toArray()), true),
|
||||||
|
$request->validated()
|
||||||
|
));
|
||||||
|
$news->locales = $request->locales;
|
||||||
|
if ($news->saveOrFail()) {
|
||||||
|
return redirect()
|
||||||
|
->route('bo.news.edit', $news)
|
||||||
|
->with('success', trans(
|
||||||
|
'crud.messages.has_been_updated',
|
||||||
|
['model' => Str::singular(trans('models.classes.news'))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->with('error', trans(
|
||||||
|
'crud.messages.cannot_be_updated',
|
||||||
|
['model' => Str::singular(trans('models.classes.news'))]
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param \App\Models\News $news
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function destroy(News $news)
|
||||||
|
{
|
||||||
|
if ($news->deleteOrFail()) {
|
||||||
|
return redirect()
|
||||||
|
->route('bo.news.index')
|
||||||
|
->with('success', trans(
|
||||||
|
'crud.messages.has_been_deleted',
|
||||||
|
['model' => Str::singular(trans('models.classes.news'))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->with('error', trans(
|
||||||
|
':crud.messages.cannot_be_deleted',
|
||||||
|
['model' => Str::singular(trans('models.classes.news'))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
78
app/Http/Controllers/Fo/NewsController.php
Normal file
78
app/Http/Controllers/Fo/NewsController.php
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Fo;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\News;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
class NewsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* News index
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
if ($request->wantsJson()) {
|
||||||
|
$currentLocale = app()->currentLocale();
|
||||||
|
$newsList = News::query()
|
||||||
|
->where('status', true)
|
||||||
|
->whereJsonContains('locales', $currentLocale)
|
||||||
|
->orderBy('order')
|
||||||
|
->paginate();
|
||||||
|
return \response()->json(\collect($newsList->items())
|
||||||
|
->map(fn ($newsModel) => $this->renderNews($newsModel)));
|
||||||
|
}
|
||||||
|
return view('fo.pages.news.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Product show
|
||||||
|
*
|
||||||
|
* @param \App\Models\News $publishedNews
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function show(News $publishedNews)
|
||||||
|
{
|
||||||
|
$currentLocale = app()->currentLocale();
|
||||||
|
$relatedNewsList = News::query()
|
||||||
|
->where('id', '!=', $publishedNews->id)
|
||||||
|
->where('status', true)
|
||||||
|
->whereJsonContains('locales', $currentLocale)
|
||||||
|
->orderBy('order', 'DESC')
|
||||||
|
->limit(2)->get();
|
||||||
|
return view('fo.pages.news.show', [
|
||||||
|
'newsModel' => $publishedNews,
|
||||||
|
'relatedNewsList' => $relatedNewsList
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a news for JS usage (ajax)
|
||||||
|
*
|
||||||
|
* @param \App\Models\News $newsModel
|
||||||
|
* @return string Base64 rendered view.
|
||||||
|
*/
|
||||||
|
private function renderNews(News $newsModel): string
|
||||||
|
{
|
||||||
|
$locale = \app()->currentLocale();
|
||||||
|
return Cache::remember(
|
||||||
|
"NewsRendered_{$locale}_{$newsModel->id}_{$newsModel->updated_at}",
|
||||||
|
60,
|
||||||
|
function () use ($newsModel) {
|
||||||
|
$pictures = $newsModel->picture_list;
|
||||||
|
return \base64_encode(\view(
|
||||||
|
'fo.pages.news.bloc',
|
||||||
|
[
|
||||||
|
'newsModel' => $newsModel,
|
||||||
|
'pictures' => $pictures
|
||||||
|
]
|
||||||
|
)->render());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,6 +38,7 @@ class Kernel extends HttpKernel
|
||||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||||
\CodeZero\LocalizedRoutes\Middleware\SetLocale::class,
|
\CodeZero\LocalizedRoutes\Middleware\SetLocale::class,
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
|
\App\Http\Middleware\Lang::class,
|
||||||
\App\Http\Middleware\SecureHeaders::class,
|
\App\Http\Middleware\SecureHeaders::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@ class Lang
|
||||||
app()->setLocale(session()->get('lang', config('app.locale')));
|
app()->setLocale(session()->get('lang', config('app.locale')));
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
if (Route::current()->getName() == null && count($request->all()) > 0) {
|
||||||
|
return redirect()->route('home', $request->all());
|
||||||
|
}
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
91
app/Http/Requests/Bo/News/StoreNewsRequest.php
Normal file
91
app/Http/Requests/Bo/News/StoreNewsRequest.php
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo\News;
|
||||||
|
|
||||||
|
use App\Http\Requests\Bo\UpdateMiniCrudRequest;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class StoreNewsRequest extends UpdateMiniCrudRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The model parameter name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $modelName = 'news';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return auth('backend')->check();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the data for validation.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function prepareForValidation()
|
||||||
|
{
|
||||||
|
$this->merge([
|
||||||
|
'slug' => Str::slug(strip_tags($this->name)),
|
||||||
|
'status' => $this->status ? true : false,
|
||||||
|
'publish_at' => $this->publish_at ? \str_replace('T', ' ', $this->publish_at) : null,
|
||||||
|
'unpublish_at' => $this->unpublish_at ? \str_replace('T', ' ', $this->unpublish_at) : null,
|
||||||
|
'locales' => \collect($this->locales)->filter()->unique()->all()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
$rules = [
|
||||||
|
'seo_title' => 'required|min:3|max:70',
|
||||||
|
'seo_description' => 'required|min:50|max:160',
|
||||||
|
|
||||||
|
'slug' => 'unique_translation:news',
|
||||||
|
'title' => 'required|min:3|max:70',
|
||||||
|
'subtitle' => 'required|min:3|max:70',
|
||||||
|
'content' => 'required|string|min:15',
|
||||||
|
'locales' => 'required|array',
|
||||||
|
'locales.*' => ['required', \sprintf('in:%s', \implode(',', \config('app.locales')))],
|
||||||
|
'data' => 'present|array',
|
||||||
|
'data.*' => 'required|array',
|
||||||
|
|
||||||
|
'status' => 'required|boolean',
|
||||||
|
'publish_at' => 'sometimes|nullable|date',
|
||||||
|
'unpublish_at' => 'sometimes|nullable|date'
|
||||||
|
];
|
||||||
|
return \array_merge(
|
||||||
|
parent::rules(),
|
||||||
|
$rules
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get custom attributes for validator errors.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function attributes()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'seo_title' => trans('titre') . ' seo',
|
||||||
|
'seo_description' => trans('description') . ' seo',
|
||||||
|
|
||||||
|
'slug' => trans('slug of the news'),
|
||||||
|
'subtitle' => trans('subtitle of the news'),
|
||||||
|
'content' => trans('content of the news'),
|
||||||
|
'data' => trans('values of the data'),
|
||||||
|
'data.*.value' => trans('value of the data'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
25
app/Http/Requests/Bo/News/UpdateNewsRequest.php
Normal file
25
app/Http/Requests/Bo/News/UpdateNewsRequest.php
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Bo\News;
|
||||||
|
|
||||||
|
use App\Http\Requests\Bo\News\StoreNewsRequest;
|
||||||
|
use CodeZero\UniqueTranslation\UniqueTranslationRule;
|
||||||
|
|
||||||
|
class UpdateNewsRequest extends StoreNewsRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
$rules = [
|
||||||
|
'slug' => UniqueTranslationRule::for('news')->ignore($this->news->id),
|
||||||
|
];
|
||||||
|
return \array_merge(
|
||||||
|
parent::rules(),
|
||||||
|
$rules,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,11 +27,11 @@ class StoreStoreRequest extends FormRequest
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
$rules = [
|
$rules = [
|
||||||
'state' => 'required|min:3|max:255',
|
'state' => 'required|string|min:3|max:255',
|
||||||
'type_id' => 'required|exists:store_types,id',
|
'type_id' => 'required|exists:store_types,id',
|
||||||
'street' => 'required|min:3|max:255',
|
'street' => 'required|string|min:3|max:255',
|
||||||
'zipcode' => 'required|min:0|max:5',
|
'zipcode' => 'required|min:1|max:5',
|
||||||
'city' => 'required|min:3|max:255',
|
'city' => 'required|string|min:3|max:255',
|
||||||
'latitude' => 'required|between:-90,90|decimal:0,8',
|
'latitude' => 'required|between:-90,90|decimal:0,8',
|
||||||
'longitude' => 'required|between:-180,180|decimal:0,8',
|
'longitude' => 'required|between:-180,180|decimal:0,8',
|
||||||
'region_id' => 'required|exists:store_regions,id',
|
'region_id' => 'required|exists:store_regions,id',
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ namespace App\Http\Requests\Bo;
|
||||||
|
|
||||||
use App\Enums\InputType;
|
use App\Enums\InputType;
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
use App\Lib\Helpers\ToolboxHelper;
|
||||||
|
use App\Models\Concept;
|
||||||
|
use App\Models\News;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
|
|
@ -30,14 +32,23 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
|
||||||
* @phpcs:disable Generic.Metrics.NestingLevel.TooHigh
|
* @phpcs:disable Generic.Metrics.NestingLevel.TooHigh
|
||||||
|
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
// phpcs:enable
|
// phpcs:enable
|
||||||
$rules = [];
|
$rules = [];
|
||||||
foreach ($this->{$this->modelName}->data as $iptName => $input) {
|
$data = $this->{$this->modelName}->data ?? null;
|
||||||
|
if (!$data and $this->route()->getName() === 'bo.concepts.store') {
|
||||||
|
$data = Concept::getEmptyData();
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!$data and $this->route()->getName() === 'bo.news.store'
|
||||||
|
) {
|
||||||
|
$data = News::getEmptyData();
|
||||||
|
}
|
||||||
|
foreach ($data as $iptName => $input) {
|
||||||
$input = \json_decode(\json_encode($input), true);
|
$input = \json_decode(\json_encode($input), true);
|
||||||
switch ($input['inputType']) {
|
switch ($input['inputType']) {
|
||||||
case InputType::number->value:
|
case InputType::number->value:
|
||||||
|
|
@ -80,7 +91,7 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return $rule;
|
return $rule;
|
||||||
});
|
})->all();
|
||||||
$rules = array_merge($rules, [
|
$rules = array_merge($rules, [
|
||||||
"data.$iptName.value" => $mergeRules
|
"data.$iptName.value" => $mergeRules
|
||||||
]);
|
]);
|
||||||
|
|
@ -107,26 +118,17 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
||||||
'maxWith' => $dim['width'],
|
'maxWith' => $dim['width'],
|
||||||
];
|
];
|
||||||
$rules = array_merge($rules, [
|
$rules = array_merge($rules, [
|
||||||
"data.$iptName.value" => [
|
"data.$iptName.value" => $this->compileValidate(
|
||||||
function (string $attribute, $value, callable $fail) use ($sizes) {
|
$required,
|
||||||
return ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
|
|
||||||
}
|
|
||||||
],
|
|
||||||
$this->compileValidate(
|
|
||||||
implode('|', [
|
|
||||||
$required,
|
|
||||||
'image',
|
|
||||||
'mimes:png,jpg,jpeg',
|
|
||||||
sprintf(
|
|
||||||
'dimensions:%s=%d,%s=%d',
|
|
||||||
$max ? 'max_height' : 'height',
|
|
||||||
$dim['height'],
|
|
||||||
$max ? 'max_width' : 'width',
|
|
||||||
$dim['width']
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
$input
|
$input
|
||||||
),
|
),
|
||||||
|
"data.$iptName.value" => [
|
||||||
|
function (string $attribute, $value, callable $fail) use ($sizes) {
|
||||||
|
if ($value) {
|
||||||
|
return ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"data.$iptName.alt" => $this->compileValidate("$required|string|min:5", $input),
|
"data.$iptName.alt" => $this->compileValidate("$required|string|min:5", $input),
|
||||||
"data.$iptName.title" => $this->compileValidate("$required|string|min:5", $input)
|
"data.$iptName.title" => $this->compileValidate("$required|string|min:5", $input)
|
||||||
]);
|
]);
|
||||||
|
|
@ -170,9 +172,11 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
||||||
* @param string|array $inputTypeValidate
|
* @param string|array $inputTypeValidate
|
||||||
* @param array $input
|
* @param array $input
|
||||||
* @return array
|
* @return array
|
||||||
|
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||||
*/
|
*/
|
||||||
public function compileValidate(string|array $inputTypeValidate, array $input): array
|
public function compileValidate(string|array $inputTypeValidate, array $input): array
|
||||||
{
|
{
|
||||||
|
// phpcs:enable
|
||||||
if (\is_string($inputTypeValidate)) {
|
if (\is_string($inputTypeValidate)) {
|
||||||
$inputTypeValidate = explode('|', $inputTypeValidate);
|
$inputTypeValidate = explode('|', $inputTypeValidate);
|
||||||
}
|
}
|
||||||
|
|
@ -185,36 +189,46 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$test = \collect($inputTypeValidate)->all();
|
$rules = \collect($inputTypeValidate)->unique()->sort(function ($valueA, $valueB) {
|
||||||
$test = \collect($inputTypeValidate)->sort(function ($valueA, $valueB) {
|
$valueA = $this->ruleHasToComeFirst($valueA);
|
||||||
$valueA = $this->ruleHasToComeFirst($valueA) ? 0 : 2;
|
$valueB = $this->ruleHasToComeFirst($valueB);
|
||||||
$valueB = $this->ruleHasToComeFirst($valueB) ? 1 : 2;
|
|
||||||
return $valueA - $valueB;
|
return $valueA - $valueB;
|
||||||
})->unique()->all();
|
});
|
||||||
|
|
||||||
return \collect($inputTypeValidate)->unique()->sort(function ($valueA, $valueB) {
|
$hasRequire = $rules->first(fn ($rule) => $rule === 'required') ? true : false;
|
||||||
$valueA = $this->ruleHasToComeFirst($valueA) ? 0 : 2;
|
$hasRequireCond = $rules->first(fn ($rule) => \strpos($rule, 'required_') !== false) ? true : false;
|
||||||
$valueB = $this->ruleHasToComeFirst($valueB) ? 1 : 2;
|
$hasNullable = $rules->first(fn ($rule) => \strpos($rule, 'nullable') !== false) ? true : false;
|
||||||
return $valueA - $valueB;
|
$hasSometime = $rules->first(fn ($rule) => \strpos($rule, 'sometimes') !== false) ? true : false;
|
||||||
})->all();
|
$hasPresent = $rules->first(fn ($rule) => \strpos($rule, 'present') !== false) ? true : false;
|
||||||
|
|
||||||
|
if ($hasRequire and ($hasRequireCond or $hasNullable or $hasSometime or $hasPresent)) {
|
||||||
|
$rules = $rules->reject(fn ($rule) => $rule === 'required');
|
||||||
|
}
|
||||||
|
return $rules->all();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the rulle need to come first ?
|
* Does the rulle need to come first ?
|
||||||
*
|
*
|
||||||
* @param string $rule
|
* @param string $rule
|
||||||
* @return boolean
|
* @return integer
|
||||||
*/
|
*/
|
||||||
private function ruleHasToComeFirst(string $rule): bool
|
private function ruleHasToComeFirst(string $rule): int
|
||||||
{
|
{
|
||||||
$rule = \collect(\explode(':', $rule, 1))->filter()->first(null, '');
|
$rule = \collect(\explode(':', $rule, 2))->filter()->first(null, '');
|
||||||
return \collect([
|
$rules = \collect([
|
||||||
'nullable', 'present', 'required', 'required_if',
|
'required_if',
|
||||||
'required_unless', 'required_with', 'required_with_all',
|
'required_unless', 'required_with', 'required_with_all',
|
||||||
'required_without', 'required_without_all', 'required_with_all',
|
'required_without', 'required_without_all', 'required_with_all',
|
||||||
'missing', 'missing_if', 'missing_unless',
|
'missing', 'missing_if', 'missing_unless',
|
||||||
'missing_with', 'missing_with_all',
|
'missing_with', 'missing_with_all',
|
||||||
])->first(fn (string $firstRule) => \strpos($rule, $firstRule) === 0) ? true : false;
|
'nullable', 'sometimes', 'present', 'required'
|
||||||
|
]);
|
||||||
|
$itemKey = $rules->search(fn (string $firstRule) => \strpos($rule, $firstRule) === 0);
|
||||||
|
if (\is_bool($itemKey)) {
|
||||||
|
return $rules->count() + 1;
|
||||||
|
}
|
||||||
|
return $itemKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
43
app/Jobs/NewsStatusUpdate.php
Normal file
43
app/Jobs/NewsStatusUpdate.php
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use App\Models\News;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update status attribute reading its
|
||||||
|
* publish_at and unpublish_at attributes.
|
||||||
|
*/
|
||||||
|
class NewsStatusUpdate
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Called when the job will be executed.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Collection<array-key, \App\Models\News> */
|
||||||
|
$newsListToPublish = News::query()->where('publish_at', '<=', Carbon::now()->toDateTime())
|
||||||
|
->whereNotNull('publish_at')
|
||||||
|
->where('status', false)->get();
|
||||||
|
Log::debug(__CLASS__ . " news to publish " . $newsListToPublish->count());
|
||||||
|
foreach ($newsListToPublish as $news) {
|
||||||
|
$news->publish_at = null;
|
||||||
|
$news->status = true;
|
||||||
|
$news->saveOrFail();
|
||||||
|
}
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Collection<array-key, \App\Models\News> */
|
||||||
|
$newsListToUnPublish = News::query()->where('unpublish_at', '<=', Carbon::now()->toDateTime())
|
||||||
|
->whereNotNull('unpublish_at')
|
||||||
|
->where('status', true)->get();
|
||||||
|
Log::debug(__CLASS__ . " news to unpublish " . $newsListToPublish->count());
|
||||||
|
foreach ($newsListToUnPublish as $news) {
|
||||||
|
$news->unpublish_at = null;
|
||||||
|
$news->status = false;
|
||||||
|
$news->saveOrFail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -250,13 +250,17 @@ class Concept extends Model
|
||||||
'label' => "Bloc {$index} - Title",
|
'label' => "Bloc {$index} - Title",
|
||||||
'inputType' => InputType::string->value,
|
'inputType' => InputType::string->value,
|
||||||
'value' => $title,
|
'value' => $title,
|
||||||
'validate' => 'required|min:4|max:100'
|
'validate' => ($index > 4 ? "required_if:bloc_{$index}_use_bloc,true" : 'required') . '|min:4|max:100'
|
||||||
];
|
];
|
||||||
$data["bloc_{$index}_color"] = [
|
$data["bloc_{$index}_color"] = [
|
||||||
'label' => "Bloc {$index} - Color",
|
'label' => "Bloc {$index} - Color",
|
||||||
'inputType' => InputType::selectEnum->value,
|
'inputType' => InputType::selectEnum->value,
|
||||||
'value' => $color,
|
'value' => $color,
|
||||||
'validate' => ['required', 'integer', new Enum(ColorsEnum::class)]
|
'validate' => [
|
||||||
|
($index > 4 ? "required_if:bloc_{$index}_use_bloc,true" : 'required'),
|
||||||
|
'integer',
|
||||||
|
new Enum(ColorsEnum::class)
|
||||||
|
]
|
||||||
];
|
];
|
||||||
$data["bloc_{$index}_text"] = [
|
$data["bloc_{$index}_text"] = [
|
||||||
'label' => "Bloc {$index} - Text",
|
'label' => "Bloc {$index} - Text",
|
||||||
|
|
@ -271,7 +275,7 @@ class Concept extends Model
|
||||||
'alt' => $imgAlt,
|
'alt' => $imgAlt,
|
||||||
'title' => $imgTitle,
|
'title' => $imgTitle,
|
||||||
'value' => $img,
|
'value' => $img,
|
||||||
'validate' => "required_if:data.bloc_{$index}_has_video.value,false",
|
'validate' => ($index > 4 ? "required_if:bloc_{$index}_use_bloc,true" : '') . '',
|
||||||
];
|
];
|
||||||
|
|
||||||
$data["bloc_{$index}_video"] = [
|
$data["bloc_{$index}_video"] = [
|
||||||
|
|
@ -280,7 +284,7 @@ class Concept extends Model
|
||||||
'value' => '',
|
'value' => '',
|
||||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||||
'validate' => [
|
'validate' => [
|
||||||
'required_if:data.bloc_{$i}_has_video.value,true',
|
"required_if:data.bloc_{$index}_has_video.value,true",
|
||||||
'nullable',
|
'nullable',
|
||||||
'regex:%([0-9]{8,10}|[^\"&?\/\s]{11})%i'
|
'regex:%([0-9]{8,10}|[^\"&?\/\s]{11})%i'
|
||||||
],
|
],
|
||||||
|
|
@ -293,6 +297,18 @@ class Concept extends Model
|
||||||
'value' => false,
|
'value' => false,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ($index > 4) {
|
||||||
|
$data["bloc_{$index}_title"]['required'] = false;
|
||||||
|
$data["bloc_{$index}_title"]['validate'] .= '|nullable';
|
||||||
|
$data["bloc_{$index}_color"]['required'] = false;
|
||||||
|
$data["bloc_{$index}_text"]['required'] = false;
|
||||||
|
$data["bloc_{$index}_text"]['validate'] .= '|nullable';
|
||||||
|
$data["bloc_{$index}_image"]['required'] = false;
|
||||||
|
$data["bloc_{$index}_image"]['validate'] .= '|nullable';
|
||||||
|
$data["bloc_{$index}_video"]['required'] = false;
|
||||||
|
$data["bloc_{$index}_has_video"]['required'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
354
app/Models/News.php
Normal file
354
app/Models/News.php
Normal file
|
|
@ -0,0 +1,354 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Enums\InputType;
|
||||||
|
use App\Lib\Helpers\FileStorageHelper;
|
||||||
|
use App\Lib\Helpers\ToolboxHelper;
|
||||||
|
use App\Traits\Models\HasTranslations;
|
||||||
|
use App\Traits\Models\MiniCrudModel;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property string $seo_title
|
||||||
|
* @property string $seo_description
|
||||||
|
* @property string $title
|
||||||
|
* @property string $slug
|
||||||
|
* @property string $subtitle
|
||||||
|
* @property string $content
|
||||||
|
* @property \Illuminate\Support\Collection $picture_list
|
||||||
|
* @property object $data
|
||||||
|
* @property integer $order
|
||||||
|
* @property boolean $status
|
||||||
|
* @property \Carbon\Carbon|null $publish_at
|
||||||
|
* @property \Carbon\Carbon|null $unpublish_at
|
||||||
|
* @property \Carbon\Carbon $created_at
|
||||||
|
* @property \Carbon\Carbon $updated_at
|
||||||
|
*/
|
||||||
|
class News extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
use HasTranslations;
|
||||||
|
use MiniCrudModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'seo_title',
|
||||||
|
'seo_description',
|
||||||
|
'title',
|
||||||
|
'slug',
|
||||||
|
'subtitle',
|
||||||
|
'content',
|
||||||
|
'data',
|
||||||
|
'locales',
|
||||||
|
'order',
|
||||||
|
'status',
|
||||||
|
'publish_at',
|
||||||
|
'unpublish_at'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be cast.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $casts = [
|
||||||
|
'data' => 'object',
|
||||||
|
'locales' => 'array',
|
||||||
|
'status' => 'bool',
|
||||||
|
'publish_at' => 'datetime',
|
||||||
|
'unpublish_at' => 'datetime'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The translatable columns.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $translatable = [
|
||||||
|
'seo_title',
|
||||||
|
'seo_description',
|
||||||
|
'title',
|
||||||
|
'slug',
|
||||||
|
'subtitle',
|
||||||
|
'content',
|
||||||
|
'data'
|
||||||
|
];
|
||||||
|
|
||||||
|
// * EVENTS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform any actions required after the model boots.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected static function booted()
|
||||||
|
{
|
||||||
|
static::creating(function (self $model) {
|
||||||
|
// * ASSERTIONS
|
||||||
|
static::assertTitleIsUnique($model->title);
|
||||||
|
ToolboxHelper::assertNoInternalBoUrls('content', $model->content);
|
||||||
|
|
||||||
|
// * TRANSFORMATIONS
|
||||||
|
$model->slug = Str::slug($model->title);
|
||||||
|
$model->content = FileStorageHelper::storeModelFilesFromHtml($model, $model->content);
|
||||||
|
$model->makeStatusSense();
|
||||||
|
self::setOrder($model);
|
||||||
|
});
|
||||||
|
static::created(function (self $model) {
|
||||||
|
$model->flashMessages();
|
||||||
|
});
|
||||||
|
static::updating(function (self $model) {
|
||||||
|
// * ASSERTIONS
|
||||||
|
static::assertTitleIsUnique($model->title);
|
||||||
|
ToolboxHelper::assertNoInternalBoUrls('content', $model->content);
|
||||||
|
|
||||||
|
// * TRANSFORMATIONS
|
||||||
|
$model->slug = Str::slug($model->title);
|
||||||
|
$model->content = FileStorageHelper::storeModelFilesFromHtml($model, $model->content);
|
||||||
|
$model->makeStatusSense();
|
||||||
|
});
|
||||||
|
static::updated(function (self $model) {
|
||||||
|
FileStorageHelper::removeOldModelFilesFromHtml(
|
||||||
|
$model->content,
|
||||||
|
ToolboxHelper::getOriginal($model, 'content')
|
||||||
|
);
|
||||||
|
$model->flashMessages();
|
||||||
|
});
|
||||||
|
static::deleted(function (self $model) {
|
||||||
|
FileStorageHelper::removeModelFilesOfHtml($model->content);
|
||||||
|
$model->minicrudDeleted();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// * METHODS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply function on data typed text while on deleted event
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function minicrudDeleted()
|
||||||
|
{
|
||||||
|
/** @var array */
|
||||||
|
foreach ($this->data as $input) {
|
||||||
|
switch ($input['inputType']) {
|
||||||
|
case InputType::text->value:
|
||||||
|
FileStorageHelper::removeModelFilesOfHtml($input['text']);
|
||||||
|
break;
|
||||||
|
} //end switch
|
||||||
|
} //end foreach
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get picture_list attribute
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function getPictureListAttribute(): Collection
|
||||||
|
{
|
||||||
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||||
|
return \collect($this->data)->filter(fn ($value, $key) => \preg_match('/bloc[0-9]+/u', $key) !== false)
|
||||||
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||||
|
->groupBy(fn ($value, $key) => \collect(\explode('_', $key))->take(2)->implode('_'))
|
||||||
|
->filter(fn (Collection $blocks) => \collect($blocks->first())->get('value'))
|
||||||
|
->map(function (Collection $blocks) {
|
||||||
|
$pictureBlock = (object)$blocks->last();
|
||||||
|
return (object)[
|
||||||
|
'value' => $pictureBlock->value,
|
||||||
|
'title' => $pictureBlock->title,
|
||||||
|
'alt' => $pictureBlock->alt
|
||||||
|
];
|
||||||
|
})->values();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts model status using current status and publish dates
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function makeStatusSense(): void
|
||||||
|
{
|
||||||
|
/** @var \Carbon\Carbon|null */
|
||||||
|
$publish_at = $this->publish_at;
|
||||||
|
/** @var \Carbon\Carbon|null */
|
||||||
|
$unpublish_at = $this->unpublish_at;
|
||||||
|
$wantedStatus = $this->status;
|
||||||
|
if ($publish_at or $unpublish_at) {
|
||||||
|
$this->status = $this->planificated_status;
|
||||||
|
}
|
||||||
|
if ($wantedStatus !== $this->status) {
|
||||||
|
$previousMessage = session()->get('bo.info', '');
|
||||||
|
session()->flash('bo.info', \trans(
|
||||||
|
'La publication est modifiée en concordance avec les dates enregistrées donc
|
||||||
|
pour modifier l\'état de publication, veuillez modifier ou enlever les dates correspondantes.'
|
||||||
|
) . " \n{$previousMessage}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter the current status following planification dates planificated_status
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function getPlanificatedStatusAttribute(): bool
|
||||||
|
{
|
||||||
|
/** @var \Carbon\Carbon|null */
|
||||||
|
$publish_at = $this->publish_at;
|
||||||
|
/** @var \Carbon\Carbon|null */
|
||||||
|
$unpublish_at = $this->unpublish_at;
|
||||||
|
if ($publish_at and $unpublish_at) {
|
||||||
|
return $unpublish_at->greaterThanOrEqualTo(now()) and $publish_at->lessThan(now());
|
||||||
|
}
|
||||||
|
if ($publish_at) {
|
||||||
|
return $publish_at->lessThan(now());
|
||||||
|
}
|
||||||
|
if ($unpublish_at) {
|
||||||
|
return $unpublish_at->greaterThanOrEqualTo(now());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash boolean attributes modification messages
|
||||||
|
*
|
||||||
|
* @param boolean $old Ignore old attribute comparison.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function flashMessages(bool $old = true)
|
||||||
|
{
|
||||||
|
$booleanChecks = [
|
||||||
|
'status' => [
|
||||||
|
'bo.info' => trans(':model est maintenant publié', [
|
||||||
|
'model' => Str::singular(trans('models.classes.products'))
|
||||||
|
]),
|
||||||
|
'bo.warning' => trans(':model est maintenant dépublié', [
|
||||||
|
'model' => Str::singular(trans('models.classes.products'))
|
||||||
|
])
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$sessionMessages = [];
|
||||||
|
|
||||||
|
// * Merge messages
|
||||||
|
foreach ($booleanChecks as $attribute => $booleanCheck) {
|
||||||
|
if ($old and $this->getOriginal($attribute) == $this->{$attribute}) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/** @var string $flashType */
|
||||||
|
$flashType = \array_keys($booleanCheck)[$this->{$attribute} ? 0 : 1];
|
||||||
|
if (!\array_key_exists($flashType, $sessionMessages)) {
|
||||||
|
$sessionMessages[$flashType] = [];
|
||||||
|
}
|
||||||
|
$sessionMessages[$flashType][] = $booleanCheck[$flashType];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($sessionMessages as $flashType => $messages) {
|
||||||
|
session()->flash($flashType, collect($messages)->implode("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the slug.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private static function setSlug(Model $model)
|
||||||
|
{
|
||||||
|
$model->slug = Str::slug($model->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set order after the last element of the list.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private static function setOrder(Model $model): void
|
||||||
|
{
|
||||||
|
$model->order = \intval(self::query()->max('order')) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts using validation that the title is unique
|
||||||
|
*
|
||||||
|
* @param string|integer|float|boolean|null|array $title
|
||||||
|
* @param integer|null $id
|
||||||
|
* @return void
|
||||||
|
* @throws \Illuminate\Validation\ValidationException If an news title already exists.
|
||||||
|
*/
|
||||||
|
private static function assertTitleIsUnique(string|int|float|bool|null|array $title, ?int $id = null)
|
||||||
|
{
|
||||||
|
$table = (new self())->getTable();
|
||||||
|
ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id);
|
||||||
|
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($title), $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the structure necessary of data.
|
||||||
|
*
|
||||||
|
* @param string $img
|
||||||
|
* @param string $imgAlt
|
||||||
|
* @param string $imgTitle
|
||||||
|
* @return ((string|\App\Enums\InputType)[]|(string|int[]|\App\Enums\InputType)[]|(string|\App\Enums\InputType|int|(string|\Illuminate\Validation\Rules\Enum)[])[])[]
|
||||||
|
*/
|
||||||
|
public static function getEmptyData(
|
||||||
|
string $img = '',
|
||||||
|
string $imgAlt = '',
|
||||||
|
string $imgTitle = ''
|
||||||
|
) {
|
||||||
|
$data = [];
|
||||||
|
for ($i = 1; $i <= 3; $i++) {
|
||||||
|
$data = self::emptyDataBloc(
|
||||||
|
$i,
|
||||||
|
$data,
|
||||||
|
$img,
|
||||||
|
$imgAlt,
|
||||||
|
$imgTitle
|
||||||
|
);
|
||||||
|
} //end for
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty data bloc
|
||||||
|
*
|
||||||
|
* @param string $index
|
||||||
|
* @param array $data
|
||||||
|
* @param string $img
|
||||||
|
* @param string $imgAlt
|
||||||
|
* @param string $imgTitle
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function emptyDataBloc(
|
||||||
|
string $index,
|
||||||
|
array $data,
|
||||||
|
string $img = '',
|
||||||
|
string $imgAlt = '',
|
||||||
|
string $imgTitle = ''
|
||||||
|
): array {
|
||||||
|
$data["bloc_{$index}_display_picture"] = [
|
||||||
|
'label' => "Bloc {$index} - Display picture",
|
||||||
|
'inputType' => InputType::boolean->value,
|
||||||
|
'value' => false,
|
||||||
|
];
|
||||||
|
$data["bloc_{$index}_image"] = [
|
||||||
|
'label' => "Bloc {$index} - Image",
|
||||||
|
'dimensions' => ['width' => 770, 'height' => 770],
|
||||||
|
'inputType' => InputType::image->value,
|
||||||
|
'alt' => $imgAlt,
|
||||||
|
'title' => $imgTitle,
|
||||||
|
'value' => $img,
|
||||||
|
'validate' => "required_if:data.bloc_{$index}_display_picture.value,true|nullable",
|
||||||
|
'required' => false
|
||||||
|
];
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -67,7 +67,7 @@ class AppServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
private function sharetoView()
|
private function sharetoView()
|
||||||
{
|
{
|
||||||
if (app()->runningInConsole()) {
|
if (app()->runningInConsole()&& !\app()->runningUnitTests()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ namespace App\Providers;
|
||||||
|
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
use App\Lib\Helpers\ToolboxHelper;
|
||||||
use App\Models\Concept;
|
use App\Models\Concept;
|
||||||
|
use App\Models\News;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use App\Models\Range;
|
use App\Models\Range;
|
||||||
use App\Models\Recipe;
|
use App\Models\Recipe;
|
||||||
|
|
@ -75,7 +76,20 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
$value
|
$value
|
||||||
)->firstOrFail();
|
)->firstOrFail();
|
||||||
});
|
});
|
||||||
|
Route::bind('publishedNews', function ($value) use ($defaultLocale) {
|
||||||
|
$currentLocale = app()->currentLocale();
|
||||||
|
$query = News::query()
|
||||||
|
->whereJsonContains('locales', $currentLocale)
|
||||||
|
->where('status', true);
|
||||||
|
return ToolboxHelper::queryColumnWithLocales(
|
||||||
|
$defaultLocale,
|
||||||
|
$query,
|
||||||
|
'slug',
|
||||||
|
$value
|
||||||
|
)->firstOrFail();
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::model('news', News::class);
|
||||||
Route::model('concept', Concept::class);
|
Route::model('concept', Concept::class);
|
||||||
Route::model('range', Range::class);
|
Route::model('range', Range::class);
|
||||||
Route::model('product', Product::class);
|
Route::model('product', Product::class);
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ trait MiniCrudModel
|
||||||
case InputType::string->value:
|
case InputType::string->value:
|
||||||
case InputType::text->value:
|
case InputType::text->value:
|
||||||
case InputType::url->value:
|
case InputType::url->value:
|
||||||
ToolboxHelper::assertNoInternalBoUrls('content', $input['value']);
|
ToolboxHelper::assertNoInternalBoUrls('content', $input['value'] ?? '');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new \ErrorException(sprintf(
|
throw new \ErrorException(sprintf(
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
"codezero/laravel-unique-translation": "^4.1",
|
"codezero/laravel-unique-translation": "^4.1",
|
||||||
"diglactic/laravel-breadcrumbs": "^8.0",
|
"diglactic/laravel-breadcrumbs": "^8.0",
|
||||||
"guzzlehttp/guzzle": "^7.2",
|
"guzzlehttp/guzzle": "^7.2",
|
||||||
|
"kwaadpepper/image-resizer": "^2.1",
|
||||||
"kwaadpepper/refresh-sitemap": "^2.0",
|
"kwaadpepper/refresh-sitemap": "^2.0",
|
||||||
"laravel/framework": "^10.0",
|
"laravel/framework": "^10.0",
|
||||||
"laravel/tinker": "^2.8",
|
"laravel/tinker": "^2.8",
|
||||||
|
|
@ -32,6 +33,7 @@
|
||||||
"fakerphp/faker": "^1.9.1",
|
"fakerphp/faker": "^1.9.1",
|
||||||
"kitloong/laravel-migrations-generator": "^6.8",
|
"kitloong/laravel-migrations-generator": "^6.8",
|
||||||
"krlove/eloquent-model-generator": "dev-l10-compatibility",
|
"krlove/eloquent-model-generator": "dev-l10-compatibility",
|
||||||
|
"laradumps/laradumps": "^2.0",
|
||||||
"laravel-lang/common": "^3.1",
|
"laravel-lang/common": "^3.1",
|
||||||
"laravel/pint": "^1.0",
|
"laravel/pint": "^1.0",
|
||||||
"laravel/sail": "^1.18",
|
"laravel/sail": "^1.18",
|
||||||
|
|
|
||||||
331
composer.lock
generated
331
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "f0a8cc66fa344af2f43f9225aa53c315",
|
"content-hash": "66d26db4ee5163489b262f58b4f47f6b",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "bacon/bacon-qr-code",
|
"name": "bacon/bacon-qr-code",
|
||||||
|
|
@ -1887,6 +1887,73 @@
|
||||||
],
|
],
|
||||||
"time": "2022-05-21T17:30:32+00:00"
|
"time": "2022-05-21T17:30:32+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "intervention/imagecache",
|
||||||
|
"version": "2.6.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Intervention/imagecache.git",
|
||||||
|
"reference": "86136575a62d3634b51f196a998fce4a583b49bb"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Intervention/imagecache/zipball/86136575a62d3634b51f196a998fce4a583b49bb",
|
||||||
|
"reference": "86136575a62d3634b51f196a998fce4a583b49bb",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/cache": "^5.5|~6|~7|~8|~9|~10",
|
||||||
|
"illuminate/filesystem": "^5.5|~6|~7|~8|~9|~10",
|
||||||
|
"intervention/image": "~2.2",
|
||||||
|
"nesbot/carbon": "^2.39",
|
||||||
|
"opis/closure": "^3.5",
|
||||||
|
"php": "~7.2|~8"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^8.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Intervention\\Image\\": "src/Intervention/Image"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Oliver Vogel",
|
||||||
|
"email": "oliver@intervention.io",
|
||||||
|
"homepage": "http://intervention.io/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Caching extension for the Intervention Image Class",
|
||||||
|
"homepage": "https://image.intervention.io",
|
||||||
|
"keywords": [
|
||||||
|
"cache",
|
||||||
|
"gd",
|
||||||
|
"image",
|
||||||
|
"imagick",
|
||||||
|
"laravel"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Intervention/imagecache/issues",
|
||||||
|
"source": "https://github.com/Intervention/imagecache/tree/2.6.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://paypal.me/interventionio",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/Intervention",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2023-02-25T19:40:47+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "jean85/pretty-package-versions",
|
"name": "jean85/pretty-package-versions",
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
|
|
@ -1946,6 +2013,66 @@
|
||||||
},
|
},
|
||||||
"time": "2021-10-08T21:21:46+00:00"
|
"time": "2021-10-08T21:21:46+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "kwaadpepper/image-resizer",
|
||||||
|
"version": "2.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Kwaadpepper/image-resizer.git",
|
||||||
|
"reference": "2a14ad153b34916f437af50549bad47c018902df"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Kwaadpepper/image-resizer/zipball/2a14ad153b34916f437af50549bad47c018902df",
|
||||||
|
"reference": "2a14ad153b34916f437af50549bad47c018902df",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/support": "~10",
|
||||||
|
"intervention/image": "^2.7.2",
|
||||||
|
"intervention/imagecache": "^2.6",
|
||||||
|
"laravel/framework": "~10"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"slevomat/coding-standard": "^8.11"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Kwaadpepper\\ImageResizer\\ImageResizerServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Kwaadpepper\\ImageResizer\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jérémy Munsch",
|
||||||
|
"email": "github@jeremydev.ovh",
|
||||||
|
"homepage": "https://jeremydev.ovh"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Resize images on the fly and cache them",
|
||||||
|
"homepage": "https://github.com/kwaadpepper/image-resizer",
|
||||||
|
"keywords": [
|
||||||
|
"images",
|
||||||
|
"laravel",
|
||||||
|
"resize"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Kwaadpepper/image-resizer/issues",
|
||||||
|
"source": "https://github.com/Kwaadpepper/image-resizer/tree/2.1.0"
|
||||||
|
},
|
||||||
|
"time": "2023-06-08T12:07:24+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "kwaadpepper/refresh-sitemap",
|
"name": "kwaadpepper/refresh-sitemap",
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
|
|
@ -3614,6 +3741,71 @@
|
||||||
],
|
],
|
||||||
"time": "2023-05-02T11:26:24+00:00"
|
"time": "2023-05-02T11:26:24+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "opis/closure",
|
||||||
|
"version": "3.6.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/opis/closure.git",
|
||||||
|
"reference": "3d81e4309d2a927abbe66df935f4bb60082805ad"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/opis/closure/zipball/3d81e4309d2a927abbe66df935f4bb60082805ad",
|
||||||
|
"reference": "3d81e4309d2a927abbe66df935f4bb60082805ad",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^5.4 || ^7.0 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"jeremeamia/superclosure": "^2.0",
|
||||||
|
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.6.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"functions.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Opis\\Closure\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Marius Sarca",
|
||||||
|
"email": "marius.sarca@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sorin Sarca",
|
||||||
|
"email": "sarca_sorin@hotmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.",
|
||||||
|
"homepage": "https://opis.io/closure",
|
||||||
|
"keywords": [
|
||||||
|
"anonymous functions",
|
||||||
|
"closure",
|
||||||
|
"function",
|
||||||
|
"serializable",
|
||||||
|
"serialization",
|
||||||
|
"serialize"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/opis/closure/issues",
|
||||||
|
"source": "https://github.com/opis/closure/tree/3.6.3"
|
||||||
|
},
|
||||||
|
"time": "2022-01-27T09:35:39+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "php-http/client-common",
|
"name": "php-http/client-common",
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
|
|
@ -9727,6 +9919,143 @@
|
||||||
},
|
},
|
||||||
"time": "2023-01-30T20:15:06+00:00"
|
"time": "2023-01-30T20:15:06+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "laradumps/laradumps",
|
||||||
|
"version": "v2.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/laradumps/laradumps.git",
|
||||||
|
"reference": "6caaf20e7ef138a33ae4aeebe20f11650cc7329c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/laradumps/laradumps/zipball/6caaf20e7ef138a33ae4aeebe20f11650cc7329c",
|
||||||
|
"reference": "6caaf20e7ef138a33ae4aeebe20f11650cc7329c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/mail": "^9.0|^10.0",
|
||||||
|
"illuminate/support": "^9.0|^10.0",
|
||||||
|
"laradumps/laradumps-core": "^0.1.0",
|
||||||
|
"nunomaduro/termwind": "^1.15.1",
|
||||||
|
"php": "^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"laravel/pint": "^1.7",
|
||||||
|
"nunomaduro/larastan": "^2.4",
|
||||||
|
"orchestra/testbench": "^7.22 | ^8.0",
|
||||||
|
"pestphp/pest": "^2.2",
|
||||||
|
"symfony/var-dumper": "^5.0 | ^6.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"LaraDumps\\LaraDumps\\LaraDumpsServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/functions.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"LaraDumps\\LaraDumps\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Luan Freitas",
|
||||||
|
"email": "luanfreitas10@protonmail.com",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A Dump Component for Laravel.",
|
||||||
|
"homepage": "https://github.com/laradumps/laradumps",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/laradumps/laradumps/issues",
|
||||||
|
"source": "https://github.com/laradumps/laradumps/tree/v2.0.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/luanfreitasdev",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2023-06-23T21:06:45+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "laradumps/laradumps-core",
|
||||||
|
"version": "v0.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/laradumps/laradumps-core.git",
|
||||||
|
"reference": "1d01107db57a8dd6156ae054e147b521333c069e"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/laradumps/laradumps-core/zipball/1d01107db57a8dd6156ae054e147b521333c069e",
|
||||||
|
"reference": "1d01107db57a8dd6156ae054e147b521333c069e",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"nesbot/carbon": "^2.66",
|
||||||
|
"nunomaduro/termwind": "^1.15",
|
||||||
|
"php": "^8.0",
|
||||||
|
"ramsey/uuid": "^3.9|^4.7.4",
|
||||||
|
"symfony/console": "^5.0|^6.0",
|
||||||
|
"symfony/finder": "^5.0|^6.0",
|
||||||
|
"symfony/process": "^5.0|^6.0",
|
||||||
|
"symfony/var-dumper": "^5.0|^6.0",
|
||||||
|
"vlucas/phpdotenv": "^5.5"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"laravel/pint": "^1.10",
|
||||||
|
"pestphp/pest": "^2.6",
|
||||||
|
"phpstan/phpstan": "^1.10.14"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/laradumps"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/functions.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"LaraDumps\\LaraDumpsCore\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Luan Freitas",
|
||||||
|
"email": "luanfreitas10@protonmail.com",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A dump component for php code.",
|
||||||
|
"homepage": "https://github.com/laradumps/laradumps-core",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/laradumps/laradumps-core/issues",
|
||||||
|
"source": "https://github.com/laradumps/laradumps-core/tree/v0.1.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/luanfreitasdev",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2023-06-15T20:07:57+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel-lang/attributes",
|
"name": "laravel-lang/attributes",
|
||||||
"version": "v2.3.3",
|
"version": "v2.3.3",
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 'paths' => ['api/*', 'sanctum/csrf-cookie', '*/storefinder'],
|
|
||||||
'paths' => ['*'],
|
'paths' => ['*'],
|
||||||
|
|
||||||
'allowed_methods' => ['*'],
|
'allowed_methods' => ['*'],
|
||||||
|
|
|
||||||
73
config/image-resizer.php
Normal file
73
config/image-resizer.php
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
/**
|
||||||
|
* The php image driver to use
|
||||||
|
* this can be 'imagick' or 'gd'
|
||||||
|
*/
|
||||||
|
'driver' => 'imagick',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cache driver to use as defined
|
||||||
|
* in config/cache of your app
|
||||||
|
*/
|
||||||
|
'cache' => 'file',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path where to store image in cache
|
||||||
|
*/
|
||||||
|
'cachePath' => 'cache/images',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image cache life time
|
||||||
|
* This is given in minutes
|
||||||
|
* Here the cache for images is
|
||||||
|
* one hour
|
||||||
|
*/
|
||||||
|
'lifeTime' => 535680,
|
||||||
|
// 1 ans
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format can specifiy to which format save the image
|
||||||
|
* JPEG PNG GIF TIF BMP ICO PSD WebP
|
||||||
|
* GD ✔️ ✔️ ✔️ - - - - ✔️ *
|
||||||
|
* Imagick ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ *
|
||||||
|
* For WebP support GD driver must be used with PHP 5 >= 5.5.0 or PHP 7
|
||||||
|
* in order to use imagewebp(). If Imagick is used, it must be compiled
|
||||||
|
* with libwebp for WebP support.
|
||||||
|
* example :
|
||||||
|
* 'small' => [
|
||||||
|
* 'height' => 500,
|
||||||
|
* 'width' => 250,
|
||||||
|
* 'inCanvas' => true,
|
||||||
|
* ],
|
||||||
|
* 'smallWebp' => [
|
||||||
|
* 'height' => 500,
|
||||||
|
* 'width' => 250,
|
||||||
|
* 'inCanvas' => true,
|
||||||
|
* 'format' => 'webp'
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
'templates' => [
|
||||||
|
'foNewsIndexPicture' => [
|
||||||
|
'height' => 520,
|
||||||
|
'width' => 768,
|
||||||
|
'fit' => true,
|
||||||
|
'resize' => false,
|
||||||
|
'keepRatio' => false,
|
||||||
|
'inCanvas' => false,
|
||||||
|
'trim' => false,
|
||||||
|
'format' => 'png'
|
||||||
|
],
|
||||||
|
'foNewsShowPicture' => [
|
||||||
|
'height' => 600,
|
||||||
|
'width' => 600,
|
||||||
|
'fit' => false,
|
||||||
|
'resize' => true,
|
||||||
|
'keepRatio' => true,
|
||||||
|
'inCanvas' => false,
|
||||||
|
'trim' => false,
|
||||||
|
'format' => 'png'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
@ -57,7 +57,9 @@ return [
|
||||||
* ]
|
* ]
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
'queryConditions' => [],
|
'queryConditions' => [
|
||||||
|
'status' => true,
|
||||||
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default route frequency to use with sitemap generator
|
* The default route frequency to use with sitemap generator
|
||||||
|
|
|
||||||
42
database/factories/NewsFactory.php
Normal file
42
database/factories/NewsFactory.php
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\News;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Factory<\App\Models\News>
|
||||||
|
*/
|
||||||
|
final class NewsFactory extends Factory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name of the factory's corresponding model.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $model = News::class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the model's default state.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
$title = fake()->word;
|
||||||
|
$locales = \collect(\config('app.locales'))->shuffle();
|
||||||
|
$locales->shift(\rand(0, 1));
|
||||||
|
return [
|
||||||
|
'seo_title' => fake()->word,
|
||||||
|
'seo_description' => fake()->text(150),
|
||||||
|
'title' => $title,
|
||||||
|
'slug' => Str::slug($title),
|
||||||
|
'subtitle' => fake()->word,
|
||||||
|
'content' => fake()->text(150),
|
||||||
|
'status' => fake()->boolean(),
|
||||||
|
'locales' => $locales
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,7 +27,7 @@ final class StoreFactory extends Factory
|
||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'state' => fake()->word,
|
'state' => fake()->lexify('Store ???'),
|
||||||
'type_id' => fake()->randomElement(StoreType::pluck('id')),
|
'type_id' => fake()->randomElement(StoreType::pluck('id')),
|
||||||
'street' => fake()->streetName,
|
'street' => fake()->streetName,
|
||||||
'zipcode' => fake()->numberBetween(00001, 99999),
|
'zipcode' => fake()->numberBetween(00001, 99999),
|
||||||
|
|
|
||||||
BIN
database/factories/assets/news/default-picture-770x770.jpg
Normal file
BIN
database/factories/assets/news/default-picture-770x770.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
47
database/migrations/2023_06_06_122054_create_news_table.php
Normal file
47
database/migrations/2023_06_06_122054_create_news_table.php
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('news', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
$table->json('seo_title')->comment('Description SEO');
|
||||||
|
$table->json('seo_description')->comment('Description SEO');
|
||||||
|
$table->json('title')->comment('Titre de la news');
|
||||||
|
$table->json('slug')->comment('Slug de la news');
|
||||||
|
$table->json('subtitle')->comment('Sous-titre de la news');
|
||||||
|
$table->json('content')->comment('Contenu de la news');
|
||||||
|
$table->json('data')->comment('Minicrud pour pictures');
|
||||||
|
$table->json('locales')->comment('Pour quelle locale il faut afficher la news.');
|
||||||
|
$table->unsignedInteger('order')->comment('Dans quel order il faut afficher la news.');
|
||||||
|
$table->boolean('status')->comment('La news est-t-elle publiée ?');
|
||||||
|
$table->timestamp('publish_at')->nullable()
|
||||||
|
->comment('The date where the post published state should be changed to true.');
|
||||||
|
$table->timestamp('unpublish_at')->nullable()
|
||||||
|
->comment('The date where the post published state should be changed to false.');
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('news');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -31,6 +31,7 @@ class DatabaseSeeder extends Seeder
|
||||||
UserSeeder::class,
|
UserSeeder::class,
|
||||||
|
|
||||||
HomeSeeder::class,
|
HomeSeeder::class,
|
||||||
|
NewsSeeder::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
35
database/seeders/NewsSeeder.php
Normal file
35
database/seeders/NewsSeeder.php
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Lib\Helpers\FileStorageHelper;
|
||||||
|
use App\Models\News;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class NewsSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$jj = 1;
|
||||||
|
News::factory(60)->make()->each(function (News $news) use (&$jj) {
|
||||||
|
$dataImg = FileStorageHelper::storeFile($news, new \SplFileInfo(\resource_path(
|
||||||
|
'../database/factories/assets/news/default-picture-770x770.jpg'
|
||||||
|
)));
|
||||||
|
|
||||||
|
$news->data = News::getEmptyData(
|
||||||
|
$dataImg,
|
||||||
|
fake()->words(4, true),
|
||||||
|
fake()->words(4, true)
|
||||||
|
);
|
||||||
|
|
||||||
|
$news->order = $jj;
|
||||||
|
$news->saveOrFail();
|
||||||
|
$jj = $jj + 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
1976
package-lock.json
generated
1976
package-lock.json
generated
File diff suppressed because it is too large
Load diff
55
phpunit.xml
55
phpunit.xml
|
|
@ -1,31 +1,28 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true">
|
||||||
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
|
<testsuites>
|
||||||
bootstrap="vendor/autoload.php"
|
<testsuite name="Unit">
|
||||||
colors="true"
|
<directory suffix="Test.php">./tests/Unit</directory>
|
||||||
>
|
</testsuite>
|
||||||
<testsuites>
|
<testsuite name="Feature">
|
||||||
<testsuite name="Unit">
|
<directory suffix="Test.php">./tests/Feature</directory>
|
||||||
<directory suffix="Test.php">./tests/Unit</directory>
|
</testsuite>
|
||||||
</testsuite>
|
</testsuites>
|
||||||
<testsuite name="Feature">
|
<coverage/>
|
||||||
<directory suffix="Test.php">./tests/Feature</directory>
|
<php>
|
||||||
</testsuite>
|
<env name="APP_ENV" value="testing"/>
|
||||||
</testsuites>
|
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||||
<coverage>
|
<env name="CACHE_DRIVER" value="array"/>
|
||||||
<include>
|
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
|
||||||
<directory suffix=".php">./app</directory>
|
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
|
||||||
</include>
|
<env name="MAIL_MAILER" value="array"/>
|
||||||
</coverage>
|
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||||
<php>
|
<env name="SESSION_DRIVER" value="array"/>
|
||||||
<env name="APP_ENV" value="testing"/>
|
<env name="TELESCOPE_ENABLED" value="false"/>
|
||||||
<env name="BCRYPT_ROUNDS" value="4"/>
|
</php>
|
||||||
<env name="CACHE_DRIVER" value="array"/>
|
<source>
|
||||||
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
|
<include>
|
||||||
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
|
<directory suffix=".php">./app</directory>
|
||||||
<env name="MAIL_MAILER" value="array"/>
|
</include>
|
||||||
<env name="QUEUE_CONNECTION" value="sync"/>
|
</source>
|
||||||
<env name="SESSION_DRIVER" value="array"/>
|
|
||||||
<env name="TELESCOPE_ENABLED" value="false"/>
|
|
||||||
</php>
|
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
|
||||||
31
phpunit.xml.bak
Normal file
31
phpunit.xml.bak
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
|
||||||
|
bootstrap="vendor/autoload.php"
|
||||||
|
colors="true"
|
||||||
|
>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Unit">
|
||||||
|
<directory suffix="Test.php">./tests/Unit</directory>
|
||||||
|
</testsuite>
|
||||||
|
<testsuite name="Feature">
|
||||||
|
<directory suffix="Test.php">./tests/Feature</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
<coverage>
|
||||||
|
<include>
|
||||||
|
<directory suffix=".php">./app</directory>
|
||||||
|
</include>
|
||||||
|
</coverage>
|
||||||
|
<php>
|
||||||
|
<env name="APP_ENV" value="testing"/>
|
||||||
|
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||||
|
<env name="CACHE_DRIVER" value="array"/>
|
||||||
|
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
|
||||||
|
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
|
||||||
|
<env name="MAIL_MAILER" value="array"/>
|
||||||
|
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||||
|
<env name="SESSION_DRIVER" value="array"/>
|
||||||
|
<env name="TELESCOPE_ENABLED" value="false"/>
|
||||||
|
</php>
|
||||||
|
</phpunit>
|
||||||
BIN
resources/assets/images/Replace_me.png
Normal file
BIN
resources/assets/images/Replace_me.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
BIN
resources/assets/images/news_placeholder.png
Normal file
BIN
resources/assets/images/news_placeholder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
|
|
@ -51,6 +51,7 @@
|
||||||
"Go to recipes": "Zu den Rezepten",
|
"Go to recipes": "Zu den Rezepten",
|
||||||
"Goose": "Gans",
|
"Goose": "Gans",
|
||||||
"Guinea fowl": "Perlhuhn",
|
"Guinea fowl": "Perlhuhn",
|
||||||
|
"Headline more news": "Überschriften Sie weitere Neuigkeiten",
|
||||||
"Hello!": "Hallo!",
|
"Hello!": "Hallo!",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Homepage": "Startseite",
|
"Homepage": "Startseite",
|
||||||
|
|
@ -76,6 +77,7 @@
|
||||||
"LDC Sablé has used its best efforts to ensure the accuracy of the information on its website (hereinafter the website). However, LDC Sablé is not responsible for the accuracy, errors or omissions on the Website. The use of this information is the sole responsibility of the user.": "LDC Sablé hat sich nach besten Kräften bemüht, die Richtigkeit der Informationen auf seiner Website (im Folgenden die Website) zu gewährleisten. LDC Sablé ist jedoch nicht verantwortlich für die Richtigkeit, Fehler oder Auslassungen auf der Website. Für die Verwendung dieser Informationen ist allein der Benutzer verantwortlich.",
|
"LDC Sablé has used its best efforts to ensure the accuracy of the information on its website (hereinafter the website). However, LDC Sablé is not responsible for the accuracy, errors or omissions on the Website. The use of this information is the sole responsibility of the user.": "LDC Sablé hat sich nach besten Kräften bemüht, die Richtigkeit der Informationen auf seiner Website (im Folgenden die Website) zu gewährleisten. LDC Sablé ist jedoch nicht verantwortlich für die Richtigkeit, Fehler oder Auslassungen auf der Website. Für die Verwendung dieser Informationen ist allein der Benutzer verantwortlich.",
|
||||||
"LDC Sablé makes no warranty, express or implied, and assumes no liability arising out of access to or use of this site, including any degradation or viruses that may infect the user's computer equipment or other property.": "LDC Sablé gibt keine ausdrückliche oder stillschweigende Garantie und übernimmt keine Haftung, die sich aus dem Zugriff oder der Nutzung dieser Site ergeben könnte, einschließlich jeglicher Verschlechterung oder Viren, die Computerausrüstung oder anderes Eigentum des Benutzers infizieren könnten.",
|
"LDC Sablé makes no warranty, express or implied, and assumes no liability arising out of access to or use of this site, including any degradation or viruses that may infect the user's computer equipment or other property.": "LDC Sablé gibt keine ausdrückliche oder stillschweigende Garantie und übernimmt keine Haftung, die sich aus dem Zugriff oder der Nutzung dieser Site ergeben könnte, einschließlich jeglicher Verschlechterung oder Viren, die Computerausrüstung oder anderes Eigentum des Benutzers infizieren könnten.",
|
||||||
"LDC Sablé may unilaterally and at any time temporarily or permanently suspend access to all or part of the website, in particular to the content, functions or availability times, without liability being requested and this is possible damages of any kind.": "LDC Sablé kann einseitig und jederzeit vorübergehend oder dauerhaft den Zugriff auf die gesamte oder einen Teil der Website, insbesondere auf den Inhalt, die Funktionen oder die Verfügbarkeitszeiten, unterbrechen, ohne dass eine Haftung beantragt wird und dies möglich ist Schäden jeglicher Art.",
|
"LDC Sablé may unilaterally and at any time temporarily or permanently suspend access to all or part of the website, in particular to the content, functions or availability times, without liability being requested and this is possible damages of any kind.": "LDC Sablé kann einseitig und jederzeit vorübergehend oder dauerhaft den Zugriff auf die gesamte oder einen Teil der Website, insbesondere auf den Inhalt, die Funktionen oder die Verfügbarkeitszeiten, unterbrechen, ohne dass eine Haftung beantragt wird und dies möglich ist Schäden jeglicher Art.",
|
||||||
|
"Learn more": "Mehr erfahren",
|
||||||
"Legal information": "Rechtliche hinweise",
|
"Legal information": "Rechtliche hinweise",
|
||||||
"Legal notice": "Impressum",
|
"Legal notice": "Impressum",
|
||||||
"Limitation of the retention periods": "Begrenzung der aufbewahrungsfristen",
|
"Limitation of the retention periods": "Begrenzung der aufbewahrungsfristen",
|
||||||
|
|
@ -87,6 +89,7 @@
|
||||||
"Market finder": "Marktfinder",
|
"Market finder": "Marktfinder",
|
||||||
"may be linked to third party websites. Websites hosted by third parties are beyond our control. If you enter personal data on a third party website, the processing of that data will not take place on our website but on the relevant third party website s website. The personal data you provide will be collected and processed in accordance with the privacy policy of the relevant third party.": "kann mit Webseiten Dritter verbunden sein. Von Dritten gehostete Webseiten entziehen sich unserer Kontrolle. Wenn Sie auf einer Webseite eines Drittanbieters personenbezogene Daten eingeben, erfolgt die Verarbeitung dieser Daten nicht auf unserer Webseite, sondern auf der jeweiligen Webseite des Drittanbieters. Die von Ihnen angegebenen personenbezogenen Daten werden gemäß den Datenschutzbestimmungen des jeweiligen Dritten erhoben und verarbeitet.",
|
"may be linked to third party websites. Websites hosted by third parties are beyond our control. If you enter personal data on a third party website, the processing of that data will not take place on our website but on the relevant third party website s website. The personal data you provide will be collected and processed in accordance with the privacy policy of the relevant third party.": "kann mit Webseiten Dritter verbunden sein. Von Dritten gehostete Webseiten entziehen sich unserer Kontrolle. Wenn Sie auf einer Webseite eines Drittanbieters personenbezogene Daten eingeben, erfolgt die Verarbeitung dieser Daten nicht auf unserer Webseite, sondern auf der jeweiligen Webseite des Drittanbieters. Die von Ihnen angegebenen personenbezogenen Daten werden gemäß den Datenschutzbestimmungen des jeweiligen Dritten erhoben und verarbeitet.",
|
||||||
"Name": "Name",
|
"Name": "Name",
|
||||||
|
"News": "Aktuelles",
|
||||||
"No commercial exploitation, reproduction, representation, use, adaptation, modification, incorporation, translation, commercialisation, in whole or in part, of these elements (including those that can be downloaded or copied) may take place without the prior written consent of LDC, with the exception of use for private purposes, subject to other or more restrictive provisions of intellectual property law.": "Ohne die vorherige schriftliche Zustimmung der Firma LDC darf keine kommerzielle Verwertung, Reproduktion, Darstellung, Verwendung, Anpassung, Änderung, Aufnahme, Übersetzung, Vermarktung, teilweise oder vollständig dieser Elemente (einschließlich der herunterladbaren oder kopierbaren) erfolgen Ausnahme der Nutzung für den privaten Gebrauch vorbehaltlich anderer oder noch restriktiverer Bestimmungen des Gesetzes über geistiges Eigentum.",
|
"No commercial exploitation, reproduction, representation, use, adaptation, modification, incorporation, translation, commercialisation, in whole or in part, of these elements (including those that can be downloaded or copied) may take place without the prior written consent of LDC, with the exception of use for private purposes, subject to other or more restrictive provisions of intellectual property law.": "Ohne die vorherige schriftliche Zustimmung der Firma LDC darf keine kommerzielle Verwertung, Reproduktion, Darstellung, Verwendung, Anpassung, Änderung, Aufnahme, Übersetzung, Vermarktung, teilweise oder vollständig dieser Elemente (einschließlich der herunterladbaren oder kopierbaren) erfolgen Ausnahme der Nutzung für den privaten Gebrauch vorbehaltlich anderer oder noch restriktiverer Bestimmungen des Gesetzes über geistiges Eigentum.",
|
||||||
"No product found": "Kein Produkt gefunden",
|
"No product found": "Kein Produkt gefunden",
|
||||||
"Not Found": "Nicht gefunden",
|
"Not Found": "Nicht gefunden",
|
||||||
|
|
@ -97,8 +100,8 @@
|
||||||
"only with": "nur bei",
|
"only with": "nur bei",
|
||||||
"Our commitments": "Unsere verpflichtungen",
|
"Our commitments": "Unsere verpflichtungen",
|
||||||
"Our concept": "Unser Konzept",
|
"Our concept": "Unser Konzept",
|
||||||
"Our free range ": "Usere Freiland",
|
"Our free range ": "Unsere Freiland",
|
||||||
"Our Free-Range": "Usere Freiland",
|
"Our Free-Range": "Unsere Freiland",
|
||||||
"Our products": "Unsere Produkte",
|
"Our products": "Unsere Produkte",
|
||||||
"Our recipes": "Unsere Rezepte",
|
"Our recipes": "Unsere Rezepte",
|
||||||
"Page Expired": "Seite abgelaufen",
|
"Page Expired": "Seite abgelaufen",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ return [
|
||||||
'sliders' => 'Sliders',
|
'sliders' => 'Sliders',
|
||||||
'homes' => 'Startseite',
|
'homes' => 'Startseite',
|
||||||
'ranges' => 'Bereiche',
|
'ranges' => 'Bereiche',
|
||||||
|
'news' => 'Aktuelles',
|
||||||
'products' => 'Produkte',
|
'products' => 'Produkte',
|
||||||
'concepts' => 'Konzepte',
|
'concepts' => 'Konzepte',
|
||||||
'recipes' => 'Rezepte',
|
'recipes' => 'Rezepte',
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,6 @@ return [
|
||||||
'stores' => 'stores',
|
'stores' => 'stores',
|
||||||
'contact-us' => 'kontakt',
|
'contact-us' => 'kontakt',
|
||||||
'legals' => 'legals',
|
'legals' => 'legals',
|
||||||
'privacy' => 'privacy'
|
'privacy' => 'privacy',
|
||||||
|
'news' => 'aktuelles'
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ return [
|
||||||
'sliders' => 'Sliders',
|
'sliders' => 'Sliders',
|
||||||
'homes' => 'Homepage',
|
'homes' => 'Homepage',
|
||||||
'ranges' => 'Ranges',
|
'ranges' => 'Ranges',
|
||||||
|
'news' => 'News',
|
||||||
'products' => 'Products',
|
'products' => 'Products',
|
||||||
'concepts' => 'Concepts',
|
'concepts' => 'Concepts',
|
||||||
'recipes' => 'Recipes',
|
'recipes' => 'Recipes',
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,6 @@ return [
|
||||||
'stores' => 'stores',
|
'stores' => 'stores',
|
||||||
'contact-us' => 'contact-us',
|
'contact-us' => 'contact-us',
|
||||||
'legals' => 'legals',
|
'legals' => 'legals',
|
||||||
'privacy' => 'privacy'
|
'privacy' => 'privacy',
|
||||||
|
'news' => 'news'
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ return [
|
||||||
'minute' => 'minute',
|
'minute' => 'minute',
|
||||||
'mobile' => 'mobile',
|
'mobile' => 'mobile',
|
||||||
'month' => 'month',
|
'month' => 'month',
|
||||||
'name' => 'name',
|
'name' => 'Name',
|
||||||
'national_code' => 'national code',
|
'national_code' => 'national code',
|
||||||
'number' => 'number',
|
'number' => 'number',
|
||||||
'password' => 'password',
|
'password' => 'password',
|
||||||
|
|
@ -208,17 +208,17 @@ return [
|
||||||
'test_name' => 'test name',
|
'test_name' => 'test name',
|
||||||
'text' => 'text',
|
'text' => 'text',
|
||||||
'time' => 'time',
|
'time' => 'time',
|
||||||
'title' => 'title',
|
'title' => 'Title',
|
||||||
'updated_at' => 'updated at',
|
'updated_at' => 'Updated At',
|
||||||
'username' => 'username',
|
'username' => 'username',
|
||||||
'year' => 'year',
|
'year' => 'year',
|
||||||
|
|
||||||
// * CUSTOMIZED
|
// * CUSTOMIZED
|
||||||
'order' => 'order',
|
'order' => 'Order',
|
||||||
'subtitle' => 'subtitle',
|
'subtitle' => 'Subtitle',
|
||||||
'label' => 'label',
|
'label' => 'Label',
|
||||||
'region' => 'region',
|
'region' => 'Region',
|
||||||
'visibility' => 'visibility',
|
'visibility' => 'Visibility',
|
||||||
'type' => 'type',
|
'type' => 'Type',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
|
||||||
1
resources/sass/bo/vendor/_bootstrap.scss
vendored
1
resources/sass/bo/vendor/_bootstrap.scss
vendored
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
// 3. Include remainder of required Bootstrap stylesheets
|
// 3. Include remainder of required Bootstrap stylesheets
|
||||||
@import "~/bootstrap/scss/variables";
|
@import "~/bootstrap/scss/variables";
|
||||||
|
@import "~/bootstrap/scss/variables-dark";
|
||||||
|
|
||||||
// 4. Include remainder of required parts
|
// 4. Include remainder of required parts
|
||||||
@import "~/bootstrap/scss/maps";
|
@import "~/bootstrap/scss/maps";
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
@import "./utilities/variables";
|
@import "./utilities/variables";
|
||||||
|
|
||||||
// * VENDOR
|
// * VENDOR
|
||||||
|
@import "toastify-js/src/toastify.css";
|
||||||
@import "./vendor/tailwind";
|
@import "./vendor/tailwind";
|
||||||
@import "./vendor/ckEditorContent";
|
@import "./vendor/ckEditorContent";
|
||||||
@import "@ldc-web/cookie-notice";
|
@import "@ldc-web/cookie-notice";
|
||||||
|
|
@ -27,3 +28,14 @@
|
||||||
filter: drop-shadow(0 0 0.75rem #888);
|
filter: drop-shadow(0 0 0.75rem #888);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ck-content.scarlet-titles {
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-family: scarlet-wood, Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,10 @@
|
||||||
// * Import bootstrap reboot to counter count theme aggressive reset
|
// * Import bootstrap reboot to counter count theme aggressive reset
|
||||||
@import "~/bootstrap/scss/functions";
|
@import "~/bootstrap/scss/functions";
|
||||||
@import "~/bootstrap/scss/variables";
|
@import "~/bootstrap/scss/variables";
|
||||||
|
@import "~/bootstrap/scss/variables-dark";
|
||||||
|
|
||||||
|
@import "~/bootstrap/scss/maps";
|
||||||
@import "~/bootstrap/scss/mixins";
|
@import "~/bootstrap/scss/mixins";
|
||||||
$theme-colors-rgb: map-loop($theme-colors, to-rgb, "$value");
|
|
||||||
@import "~/bootstrap/scss/root";
|
@import "~/bootstrap/scss/root";
|
||||||
@import "~/bootstrap/scss/reboot";
|
@import "~/bootstrap/scss/reboot";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,7 @@
|
||||||
class="table-action"
|
class="table-action"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
v-if="
|
v-if="hasHeader"
|
||||||
displayHeaders.filter((header) => {
|
|
||||||
return header;
|
|
||||||
}).length > 1 && itemList.length > 1
|
|
||||||
"
|
|
||||||
@click.prevent="removeAllHeaders()"
|
@click.prevent="removeAllHeaders()"
|
||||||
class="btn btn-sm btn-danger"
|
class="btn btn-sm btn-danger"
|
||||||
:title="__('Remove all headers')"
|
:title="__('Remove all headers')"
|
||||||
|
|
@ -30,11 +26,7 @@
|
||||||
class="col-6 align-middle"
|
class="col-6 align-middle"
|
||||||
>
|
>
|
||||||
{{ __("Header") }}
|
{{ __("Header") }}
|
||||||
({{
|
({{ countHeaders }})
|
||||||
displayHeaders.filter((header) => {
|
|
||||||
return header;
|
|
||||||
}).length
|
|
||||||
}})
|
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
v-for="(column, columnIndex) of itemColumns"
|
v-for="(column, columnIndex) of itemColumns"
|
||||||
|
|
@ -107,7 +99,7 @@
|
||||||
:name="`${inputName}[${String(itemIndex)}][header]`"
|
:name="`${inputName}[${String(itemIndex)}][header]`"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="__('Recipe of chocolate cookies')"
|
:placeholder="__('Recipe of chocolate cookies')"
|
||||||
v-model="item['header' as keyof typeof item]"
|
v-model="item['header']"
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon="fa-solid fa-angles-right"
|
icon="fa-solid fa-angles-right"
|
||||||
|
|
@ -133,7 +125,7 @@
|
||||||
class="form-control form-control-sm"
|
class="form-control form-control-sm"
|
||||||
:name="`${inputName}[${String(itemIndex)}][${column[0]}]`"
|
:name="`${inputName}[${String(itemIndex)}][${column[0]}]`"
|
||||||
:type="itemType[columnIndex]"
|
:type="itemType[columnIndex]"
|
||||||
v-model="item[column[0] as keyof typeof item]"
|
v-model="item[column[0]]"
|
||||||
:placeholder="inputPlaceholder[columnIndex]"
|
:placeholder="inputPlaceholder[columnIndex]"
|
||||||
:min="itemType[columnIndex] == 'number' ? '0' : undefined"
|
:min="itemType[columnIndex] == 'number' ? '0' : undefined"
|
||||||
>
|
>
|
||||||
|
|
@ -195,7 +187,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
mixins: [trans, parseLaravelErrorMessages],
|
mixins: [trans, parseLaravelErrorMessages],
|
||||||
data(): {
|
data(): {
|
||||||
itemList: Object[];
|
itemList: Array<Record<string,string>>;
|
||||||
itemColumns: string[][];
|
itemColumns: string[][];
|
||||||
itemLimit: number[];
|
itemLimit: number[];
|
||||||
inputName: string;
|
inputName: string;
|
||||||
|
|
@ -207,11 +199,11 @@ export default defineComponent({
|
||||||
displayBtnAdd: boolean;
|
displayBtnAdd: boolean;
|
||||||
displayBtnRemove: boolean;
|
displayBtnRemove: boolean;
|
||||||
displayHeader: boolean;
|
displayHeader: boolean;
|
||||||
displayHeaders: boolean[];
|
displayHeaders: Array<boolean>;
|
||||||
tooltipList: HTMLButtonElement[];
|
tooltipList: HTMLButtonElement[];
|
||||||
} {
|
} {
|
||||||
return {
|
return {
|
||||||
itemList: [{}],
|
itemList: [],
|
||||||
itemColumns: [[""]],
|
itemColumns: [[""]],
|
||||||
itemLimit: [0, 0],
|
itemLimit: [0, 0],
|
||||||
inputName: "",
|
inputName: "",
|
||||||
|
|
@ -227,6 +219,18 @@ export default defineComponent({
|
||||||
tooltipList: [],
|
tooltipList: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed : {
|
||||||
|
hasHeader() {
|
||||||
|
return this.displayHeaders.filter((header : boolean) => {
|
||||||
|
return header;
|
||||||
|
}).length > 1 && this.itemList.length > 1;
|
||||||
|
},
|
||||||
|
countHeaders() {
|
||||||
|
return this.displayHeaders.filter((header: boolean) => {
|
||||||
|
return header;
|
||||||
|
}).length;
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
const json = String(this.$attrs.json ?? "{}");
|
const json = String(this.$attrs.json ?? "{}");
|
||||||
const data = JSON.parse(json);
|
const data = JSON.parse(json);
|
||||||
|
|
@ -258,7 +262,9 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.itemList.forEach((item: { header?: string }, key) => {
|
this.itemList.forEach((item: { header?: string }, key) => {
|
||||||
if (item.header) this.displayHeaders[key] = true;
|
if (item.header) {
|
||||||
|
this.displayHeaders[key] = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
130
resources/ts/fo/components/NewsInfiniteLoaderComponent.vue
Normal file
130
resources/ts/fo/components/NewsInfiniteLoaderComponent.vue
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
<template>
|
||||||
|
<div class="max-w-screen-2xl mx-auto">
|
||||||
|
<div
|
||||||
|
v-if="newsList.length"
|
||||||
|
class="flex flex-col gap-0 mt-24"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-for="(news, newsIndex) of newsList"
|
||||||
|
:key="newsIndex"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-html="news"
|
||||||
|
class="flex flex-wrap flex-row my-3 sm:my-0 sm:even:flex-row sm:odd:flex-row-reverse"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="text-left"
|
||||||
|
>
|
||||||
|
{{ __("No news for the moment") }}
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center mt-12 mb-48">
|
||||||
|
<button
|
||||||
|
v-if="!noMorePosts"
|
||||||
|
:disabled="loading"
|
||||||
|
class="button brown inline-flex items-center px-4 my-2 mt-6 mr-4 text-sm text-white"
|
||||||
|
@click.prevent="loadNextPage"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
v-if="loading"
|
||||||
|
icon="fa-solid fa-cog"
|
||||||
|
:spin="true"
|
||||||
|
/>
|
||||||
|
{{ __("Load more posts") }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import axios from "axios";
|
||||||
|
import parseLaravelErrorMessages from "./../../modules/parseLaravelErrorMessages";
|
||||||
|
import route from "./../../modules/route";
|
||||||
|
import toast from "./../../modules/toast";
|
||||||
|
import trans from "./../../modules/trans";
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "NewsInfiniteLoaderComponent",
|
||||||
|
mixins: [route, trans, toast, parseLaravelErrorMessages],
|
||||||
|
mounted() {
|
||||||
|
this.loadActu();
|
||||||
|
},
|
||||||
|
data(): {
|
||||||
|
pagination: number;
|
||||||
|
loading: boolean;
|
||||||
|
noMorePosts: boolean;
|
||||||
|
newsList: string[];
|
||||||
|
currentPage: number;
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
pagination: 15,
|
||||||
|
loading: false,
|
||||||
|
noMorePosts: false,
|
||||||
|
newsList: [],
|
||||||
|
currentPage: 1,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadNextPage(): void {
|
||||||
|
this.currentPage = this.currentPage + 1;
|
||||||
|
this.loadActu();
|
||||||
|
},
|
||||||
|
loadActu(): void {
|
||||||
|
const newsPaginateRoute = this.route("news.index", {
|
||||||
|
page: this.currentPage,
|
||||||
|
});
|
||||||
|
if (!newsPaginateRoute) {
|
||||||
|
throw Error("Undefined route 'news.index'");
|
||||||
|
}
|
||||||
|
this.loading = true;
|
||||||
|
axios
|
||||||
|
.get(newsPaginateRoute)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.data.length < this.pagination) {
|
||||||
|
this.noMorePosts = true;
|
||||||
|
}
|
||||||
|
for (const news of response.data) {
|
||||||
|
this.newsList.push(this.base64decode(String(news)));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => (this.loading = false))
|
||||||
|
.catch((e) => {
|
||||||
|
console.log(e);
|
||||||
|
let message = this.__("http-statuses.0");
|
||||||
|
if (e.response.status === 422) {
|
||||||
|
message =
|
||||||
|
this.parseValidationErrors(e.response?.data?.errors ?? {}) ||
|
||||||
|
message;
|
||||||
|
if (window.vueDebug) {
|
||||||
|
console.warn(e.response.data.errors);
|
||||||
|
}
|
||||||
|
} else if (e.response.status === 419) {
|
||||||
|
// * CSRF TOKEN MISMATCH (On ne pourrais plus faire d'appels AJAX sans recharger la page)
|
||||||
|
setTimeout(() => window.location.reload(), 2000);
|
||||||
|
} else if (e.response.status === 403) {
|
||||||
|
// * Access denied
|
||||||
|
setTimeout(() => window.location.reload(), 2000);
|
||||||
|
} else {
|
||||||
|
if (window.vueDebug) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.errorNotify(this.__(`http-statuses.${e.response.status}`));
|
||||||
|
this.errorNotify(message);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
base64decode(str: string): string {
|
||||||
|
let decode = atob(str).replace(
|
||||||
|
"/[\x80-\uffff]/g",
|
||||||
|
(m) => `%${m.charCodeAt(0).toString(16).padStart(2, "0")}`
|
||||||
|
);
|
||||||
|
return decodeURIComponent(decode);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: { FontAwesomeIcon },
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -38,8 +38,12 @@ import {
|
||||||
faMinus,
|
faMinus,
|
||||||
faHeader,
|
faHeader,
|
||||||
faCircleCheck,
|
faCircleCheck,
|
||||||
|
faCog,
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { faCircleXmark, faCirclePlay } from "@fortawesome/free-regular-svg-icons";
|
import {
|
||||||
|
faCircleXmark,
|
||||||
|
faCirclePlay,
|
||||||
|
} from "@fortawesome/free-regular-svg-icons";
|
||||||
|
|
||||||
config.autoReplaceSvg = false;
|
config.autoReplaceSvg = false;
|
||||||
library.add(faEraser);
|
library.add(faEraser);
|
||||||
|
|
@ -84,5 +88,6 @@ library.add(faCircleNotch);
|
||||||
library.add(faSliders);
|
library.add(faSliders);
|
||||||
library.add(faCircleCheck);
|
library.add(faCircleCheck);
|
||||||
library.add(faCirclePlay);
|
library.add(faCirclePlay);
|
||||||
|
library.add(faCog);
|
||||||
|
|
||||||
dom.watch();
|
dom.watch();
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link @if (Route::is('bo.sliders.*'))active @endif" href="{{ route('bo.sliders.index') }}" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.listall', ['model' => __('models.classes.sliders')]) }}">
|
<a class="nav-link @if (Route::is('bo.sliders.*'))active @endif" href="{{ route('bo.sliders.index') }}" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.sliders')]) }}">
|
||||||
{{ __('models.classes.sliders') }}
|
{{ __('models.classes.sliders') }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -15,22 +15,27 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link @if (Route::is('bo.concepts.*'))active @endif" href="{{ route('bo.concepts.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.listall', ['model' => __('models.classes.concepts')]) }}">
|
<a class="nav-link @if (Route::is('bo.news.*'))active @endif" href="{{ route('bo.news.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.news')]) }}">
|
||||||
|
{{ __('models.classes.news') }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link @if (Route::is('bo.concepts.*'))active @endif" href="{{ route('bo.concepts.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.concepts')]) }}">
|
||||||
{{ __('models.classes.concepts') }}
|
{{ __('models.classes.concepts') }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link @if (Route::is('bo.ranges.*'))active @endif" href="{{ route('bo.ranges.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.listall', ['model' => __('models.classes.ranges')]) }}">
|
<a class="nav-link @if (Route::is('bo.ranges.*'))active @endif" href="{{ route('bo.ranges.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.ranges')]) }}">
|
||||||
{{ __('models.classes.ranges') }}
|
{{ __('models.classes.ranges') }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link @if (Route::is('bo.products.*'))active @endif" href="{{ route('bo.products.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.listall', ['model' => __('models.classes.products')]) }}">
|
<a class="nav-link @if (Route::is('bo.products.*'))active @endif" href="{{ route('bo.products.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.products')]) }}">
|
||||||
{{ __('models.classes.products') }}
|
{{ __('models.classes.products') }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link @if (Route::is('bo.recipes.*'))active @endif" href="{{ route('bo.recipes.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.listall', ['model' => __('models.classes.recipes')]) }}">
|
<a class="nav-link @if (Route::is('bo.recipes.*'))active @endif" href="{{ route('bo.recipes.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.recipes')]) }}">
|
||||||
{{ __('models.classes.recipes') }}
|
{{ __('models.classes.recipes') }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -40,25 +45,25 @@
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item @if (Route::is('bo.stores.*'))active @endif" href="{{ route('bo.stores.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.listall', ['model' => __('models.classes.stores')]) }}">
|
<a class="dropdown-item @if (Route::is('bo.stores.*'))active @endif" href="{{ route('bo.stores.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.stores')]) }}">
|
||||||
{{ __('models.classes.stores') }}
|
{{ __('models.classes.stores') }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item @if (Route::is('bo.storegroups.*'))active @endif" href="{{ route('bo.storegroups.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.listall', ['model' => __('models.classes.storegroups')]) }}">
|
<a class="dropdown-item @if (Route::is('bo.storegroups.*'))active @endif" href="{{ route('bo.storegroups.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.storegroups')]) }}">
|
||||||
{{ __('models.classes.storegroups') }}
|
{{ __('models.classes.storegroups') }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item @if (Route::is('bo.storeregions.*'))active @endif" href="{{ route('bo.storeregions.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.listall', ['model' => __('models.classes.storeregions')]) }}">
|
<a class="dropdown-item @if (Route::is('bo.storeregions.*'))active @endif" href="{{ route('bo.storeregions.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.storeregions')]) }}">
|
||||||
{{ __('models.classes.storeregions') }}
|
{{ __('models.classes.storeregions') }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item @if (Route::is('bo.storetypes.*'))active @endif" href="{{ route('bo.storetypes.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.listall', ['model' => __('models.classes.storetypes')]) }}">
|
<a class="dropdown-item @if (Route::is('bo.storetypes.*'))active @endif" href="{{ route('bo.storetypes.index') }}?rst=1" role="button" data-bs-toggle="tooltip" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.storetypes')]) }}">
|
||||||
{{ __('models.classes.storetypes') }}
|
{{ __('models.classes.storetypes') }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@endauth
|
@endauth
|
||||||
|
|
@ -160,7 +160,7 @@
|
||||||
'hasWordCounter' => true,
|
'hasWordCounter' => true,
|
||||||
'name' => 'data['.$k.'][alt]',
|
'name' => 'data['.$k.'][alt]',
|
||||||
'value' => old("data.{$k}.alt", $input['alt'] ?? null),
|
'value' => old("data.{$k}.alt", $input['alt'] ?? null),
|
||||||
'required' => true,
|
'required' => is_bool($input['required'] ?? null) ? $input['required'] : true,
|
||||||
'model' => $model ?? null,
|
'model' => $model ?? null,
|
||||||
'helper' => __('crud.minicrud.picture_alt_helper') . '. ' . __('validation.min.string', [
|
'helper' => __('crud.minicrud.picture_alt_helper') . '. ' . __('validation.min.string', [
|
||||||
'attribute' => __('crud.minicrud.picture_alt_label'),
|
'attribute' => __('crud.minicrud.picture_alt_label'),
|
||||||
|
|
@ -179,7 +179,7 @@
|
||||||
'hasWordCounter' => true,
|
'hasWordCounter' => true,
|
||||||
'name' => 'data['.$k.'][title]',
|
'name' => 'data['.$k.'][title]',
|
||||||
'value' => old("data.{$k}.title", $input['title'] ?? null),
|
'value' => old("data.{$k}.title", $input['title'] ?? null),
|
||||||
'required' => true,
|
'required' => is_bool($input['required'] ?? null) ? $input['required'] : true,
|
||||||
'model' => $model ?? null,
|
'model' => $model ?? null,
|
||||||
'helper' => __('crud.minicrud.picture_title_helper') . '. ' . __('validation.min.string', [
|
'helper' => __('crud.minicrud.picture_title_helper') . '. ' . __('validation.min.string', [
|
||||||
'attribute' => __('crud.minicrud.picture_title_label'),
|
'attribute' => __('crud.minicrud.picture_title_label'),
|
||||||
|
|
@ -203,7 +203,7 @@
|
||||||
'width' => $input['dimensions']['width'],
|
'width' => $input['dimensions']['width'],
|
||||||
'height' => $input['dimensions']['height'],
|
'height' => $input['dimensions']['height'],
|
||||||
]),
|
]),
|
||||||
'required' => true,
|
'required' => is_bool($input['required'] ?? null) ? $input['required'] : true,
|
||||||
'preview' => true,
|
'preview' => true,
|
||||||
])
|
])
|
||||||
@include('modules.input-error', [
|
@include('modules.input-error', [
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@extends('bo.layout')
|
@extends('bo.layout')
|
||||||
|
|
||||||
@section('title', __('crud.helpers.listall', ['model' => __('models.classes.concepts')]))
|
@section('title', __('crud.helpers.list_all', ['model' => __('models.classes.concepts')]))
|
||||||
@section('description', __('crud.helpers.listall', ['model' => __('models.classes.concepts')]))
|
@section('description', __('crud.helpers.list_all', ['model' => __('models.classes.concepts')]))
|
||||||
@section('breadcrumb', request()->route()->getName())
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
@ -45,4 +45,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
36
resources/views/bo/pages/news/create.blade.php
Normal file
36
resources/views/bo/pages/news/create.blade.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
@extends('bo.layout')
|
||||||
|
|
||||||
|
@section('title', sprintf('%s - %s', Str::singular(__('models.classes.news')), Str::ucfirst(__('create'))))
|
||||||
|
@section('description', __('Creation of a new news.'))
|
||||||
|
|
||||||
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h1 class="col h2">
|
||||||
|
<a href="{{ route('bo.news.index') }}" class="btn btn-primary text-decoration-none m-0" data-bs="tooltip" data-bs-placement="top" title="{{ __('Return to the :model list', ['model' => __('models.classes.news')]) }}" data-bs-toggle="tooltip">
|
||||||
|
<i class="fa-solid fa-arrow-left"></i>
|
||||||
|
</a>
|
||||||
|
<span class="fw-bold">{{ Str::singular(__('models.classes.news')) }}</span> <small class="text-muted">{{ Str::ucfirst(__('create')) }}</small>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body bg-light">
|
||||||
|
<form id="formSubmit" action="{{ route('bo.news.store') }}" method="POST" enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
@include('bo.pages.news.form-inputs')
|
||||||
|
<div class="row">
|
||||||
|
<div class="col text-center">
|
||||||
|
<button type="submit" class="btn btn-primary" title="{{ __('Save :model', ['model' => Str::singular(__('models.classes.news'))]) }}" data-bs-toggle="tooltip">
|
||||||
|
{{ __('crud.actions.save') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
37
resources/views/bo/pages/news/edit.blade.php
Normal file
37
resources/views/bo/pages/news/edit.blade.php
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
@extends('bo.layout', ['brParam' => $newsModel])
|
||||||
|
|
||||||
|
@section('title', sprintf('%s - %s %s', Str::singular(__('models.classes.news')), Str::ucfirst(__('crud.actions.edit')), $newsModel->seo_title))
|
||||||
|
@section('description', $newsModel->seo_description)
|
||||||
|
|
||||||
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h1 class="col h2">
|
||||||
|
<a href="{{ route('bo.news.index') }}" class="btn btn-primary text-decoration-none m-0" data-bs="tooltip" data-bs-placement="top" title="{{ __('Return to the :model list', ['model' => __('models.classes.news')]) }}" data-bs-toggle="tooltip">
|
||||||
|
<i class="fa-solid fa-arrow-left"></i>
|
||||||
|
</a>
|
||||||
|
<span class="fw-bold">{{ Str::singular(__('models.classes.news')) }}</span> <small class="text-muted">{{ Str::ucfirst(__('crud.actions.edit')) }}</small>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body bg-light">
|
||||||
|
<form id="formSubmit" action="{{ route('bo.news.update', $newsModel->id) }}" method="POST" enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
@method('PUT')
|
||||||
|
@include('bo.pages.news.form-inputs', ['model' => $newsModel])
|
||||||
|
<div class="row">
|
||||||
|
<div class="col text-center">
|
||||||
|
<button type="submit" class="btn btn-primary" title="{{ __('Save :model', ['model' => Str::singular(__('models.classes.news'))]) }}" data-bs-toggle="tooltip">
|
||||||
|
{{ __('crud.actions.save') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
259
resources/views/bo/pages/news/form-inputs.blade.php
Normal file
259
resources/views/bo/pages/news/form-inputs.blade.php
Normal file
|
|
@ -0,0 +1,259 @@
|
||||||
|
<div class="row">
|
||||||
|
{{-- SEO_TITLE --}}
|
||||||
|
<div class="col-12 col-md-6 mb-3">
|
||||||
|
<fieldset class="border h-100 bg-white p-3">
|
||||||
|
<legend>{{ __('SEO Title') }}</legend>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 mb-3">
|
||||||
|
@include('bo.partials.inputs.varchar', [
|
||||||
|
'id' => 'newsSeoTitle',
|
||||||
|
'label' => __('SEO title of the :model', ['model' => Str::singular(__('models.classes.news'))]),
|
||||||
|
'hasWordCounter' => true,
|
||||||
|
'name' => 'seo_title',
|
||||||
|
'required' => true,
|
||||||
|
'model' => $newsModel ?? null,
|
||||||
|
'helper' => __('validation.between.string', [
|
||||||
|
'attribute' => __('SEO title of the :model', ['model' => Str::singular(__('models.classes.news'))]),
|
||||||
|
'min' => 3,
|
||||||
|
'max' => 255
|
||||||
|
]),
|
||||||
|
'placeholder' => __('A beautiful title'),
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
{{-- SEO_DESCRIPTION --}}
|
||||||
|
<div class="col-12 col-md-6 mb-3">
|
||||||
|
<fieldset class="border h-100 bg-white p-3">
|
||||||
|
<legend>{{ __('SEO Description') }}</legend>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
@include('bo.partials.inputs.varchar-multiline', [
|
||||||
|
'id' => 'newsSeoDescription',
|
||||||
|
'label' => __('SEO description of the :model', ['model' => Str::singular(__('models.classes.news'))]),
|
||||||
|
'name' => 'seo_description',
|
||||||
|
'model' => $newsModel ?? null,
|
||||||
|
'required' => true,
|
||||||
|
'helper' => __('validation.between.string', [
|
||||||
|
'attribute' => __('SEO description of the :model', ['model' => Str::singular(__('models.classes.products'))]),
|
||||||
|
'min' => 50,
|
||||||
|
'max' => 160
|
||||||
|
]),
|
||||||
|
'placeholder' => __('A description of the content for search engines.'),
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
{{-- TITLE --}}
|
||||||
|
<div class="col-12 col-md-6 mb-3">
|
||||||
|
<fieldset class="border h-100 bg-white p-3">
|
||||||
|
<legend>{{ __('Title') }}</legend>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 mb-3">
|
||||||
|
@include('bo.partials.inputs.varchar', [
|
||||||
|
'id' => 'newsTitle',
|
||||||
|
'label' => __('Title of the :model', ['model' => Str::singular(__('models.classes.news'))]),
|
||||||
|
'hasWordCounter' => true,
|
||||||
|
'name' => 'title',
|
||||||
|
'required' => true,
|
||||||
|
'model' => $newsModel ?? null,
|
||||||
|
'helper' => __('validation.between.string', [
|
||||||
|
'attribute' => __('Title of the :model', ['model' => Str::singular(__('models.classes.news'))]),
|
||||||
|
'min' => 3,
|
||||||
|
'max' => 255
|
||||||
|
]),
|
||||||
|
'placeholder' => __('A beautiful title'),
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
{{-- SUBTITLE --}}
|
||||||
|
<div class="col-12 col-md-6 mb-3">
|
||||||
|
<fieldset class="border h-100 bg-white p-3">
|
||||||
|
<legend>{{ __('Subtitle') }}</legend>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 mb-3">
|
||||||
|
@include('bo.partials.inputs.varchar', [
|
||||||
|
'id' => 'newsSubtitle',
|
||||||
|
'label' => __('Subtitle of the :model', ['model' => Str::singular(__('models.classes.news'))]),
|
||||||
|
'hasWordCounter' => true,
|
||||||
|
'name' => 'subtitle',
|
||||||
|
'required' => true,
|
||||||
|
'model' => $newsModel ?? null,
|
||||||
|
'helper' => __('validation.between.string', [
|
||||||
|
'attribute' => __('Subtitle of the :model', ['model' => Str::singular(__('models.classes.news'))]),
|
||||||
|
'min' => 3,
|
||||||
|
'max' => 255
|
||||||
|
]),
|
||||||
|
'placeholder' => __('A beautiful subtitle'),
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
{{-- CONTENT --}}
|
||||||
|
<div class="col-12 mb-3">
|
||||||
|
<fieldset class="border bg-white p-3">
|
||||||
|
<legend>{{ __('Content') }}</legend>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-12">
|
||||||
|
@include('bo.partials.inputs.text-html', [
|
||||||
|
'id' => 'newContent',
|
||||||
|
'label' => __('Description of the :model', ['model' => Str::singular(__('models.classes.news'))]),
|
||||||
|
'name' => 'content',
|
||||||
|
'model' => $newsModel ?? null,
|
||||||
|
'required' => true,
|
||||||
|
'helper' => __('Proofread your content before publishing it (minimum 15 characters).'),
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
{{-- MINICRUD --}}
|
||||||
|
<div class="col-12 mb-3">
|
||||||
|
<button class="btn btn-primary col-form-label rounded-0 dropdown-toggle w-100" type="button" data-bs-toggle="collapse" data-bs-target="#minicrud" aria-expanded="false" aria-controls="minicrud">
|
||||||
|
<b>{{ __('ALL BLOCS') }}</b>
|
||||||
|
</button>
|
||||||
|
<div class="collapse" id="minicrud">
|
||||||
|
<div class="card card-body bg-light rounded-0">
|
||||||
|
<div class="row">
|
||||||
|
@include('bo.modules.minicrud-form-inputs', [
|
||||||
|
'data' => $newsModel->data ?? \App\Models\News::getEmptyData()
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{-- PUBLICATION --}}
|
||||||
|
<div class="col-12 mb-3">
|
||||||
|
<fieldset class="border h-100 bg-white p-3">
|
||||||
|
<legend>{{ __('Publication') }}</legend>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<div class="form-group">
|
||||||
|
@include('bo.partials.inputs.publish-dates', [
|
||||||
|
'label' => __('Date de publication (Europe/Paris)'),
|
||||||
|
'id' => 'newsPublishedAt',
|
||||||
|
'name' => 'publish_at',
|
||||||
|
'model' => $newsModel ?? null,
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="form-group">
|
||||||
|
@include('bo.partials.inputs.publish-dates', [
|
||||||
|
'label' => __('Date de fin de publication (Europe/Paris)'),
|
||||||
|
'id' => 'newsUnPublishedAt',
|
||||||
|
'name' => 'unpublish_at',
|
||||||
|
'model' => $newsModel ?? null,
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
{{-- LOCALES --}}
|
||||||
|
<div class="col-12 col-md-6 mb-3">
|
||||||
|
<fieldset class="border h-100 bg-white p-3">
|
||||||
|
<legend>{{ __('Languages in which to display the news') }}</legend>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
@php
|
||||||
|
$itemsList = collect(config('app.locales'))->map(fn($locale) => (object)[
|
||||||
|
'label' => $locale, 'value' => $locale,
|
||||||
|
]);
|
||||||
|
$values = collect(old('locales', $newsModel->locales ?? []))->values();
|
||||||
|
$selectedItemList = collect($itemsList)->filter(fn($locale) =>
|
||||||
|
$values->filter(fn($value) => $value === $locale->value)->count())->values();
|
||||||
|
@endphp
|
||||||
|
@include('bo.partials.inputs.select-multiple-enum', [
|
||||||
|
'id' => 'newsLocales',
|
||||||
|
'label' => __('Locales in which to display the news'),
|
||||||
|
'name' => 'locales',
|
||||||
|
'itemsSelected' => $selectedItemList,
|
||||||
|
'itemsList' => $itemsList,
|
||||||
|
'itemLimit' => [0, count($itemsList)],
|
||||||
|
'placeholder' => __('Search a specific Locales'),
|
||||||
|
'helper' => __('Select Locales(s) among this list in which the news should display (minimum 1, maximum :max)', [
|
||||||
|
'max' => count($itemsList)
|
||||||
|
]),
|
||||||
|
'required' => true,
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
{{-- STATUS --}}
|
||||||
|
<div class="col-12 col-md-6 mb-3">
|
||||||
|
<fieldset class="border h-100 bg-white p-3">
|
||||||
|
<legend>{{ __('crud.minicrud.visibility_label') }}</legend>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
@include('bo.partials.inputs.tinyint-boolean', [
|
||||||
|
'id' => 'newsStatus',
|
||||||
|
'name' => 'status',
|
||||||
|
'model' => $newsModel ?? null,
|
||||||
|
'label' => __('crud.minicrud.visibility_label'),
|
||||||
|
'helper' => __('crud.minicrud.visibility_helper'),
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script nonce="{{ $nonce }}">
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const hasLoadedComponentsMarker = 'data[bloc_3_image][value]';
|
||||||
|
const displayBloc = function(index) {
|
||||||
|
const switchInput = document.querySelector(`input[name="data[bloc_${index}_display_picture][value]"]`);
|
||||||
|
const inputList = [
|
||||||
|
`data[bloc_${index}_image][value]`,
|
||||||
|
];
|
||||||
|
const inputs = [];
|
||||||
|
inputList.forEach((name) => {
|
||||||
|
const input = document.querySelector(`input[name="${name}"]`) ??
|
||||||
|
document.querySelector(`select[name="${name}"]`);
|
||||||
|
inputs.push(input);
|
||||||
|
});
|
||||||
|
|
||||||
|
inputs.forEach((input) => {
|
||||||
|
// * hide.
|
||||||
|
if (!switchInput.checked) {
|
||||||
|
input.closest('.minicrud-input ').classList.add('d-none');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
switchInput.addEventListener('change', function() {
|
||||||
|
inputs.forEach((input) => {
|
||||||
|
// * Toggle hide.
|
||||||
|
input.closest('.minicrud-input ').classList.toggle('d-none');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const waitForLoaded = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!document.querySelector(`input[name="${hasLoadedComponentsMarker}"]`)) {
|
||||||
|
waitForLoaded();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
displayBloc(1);
|
||||||
|
displayBloc(2);
|
||||||
|
displayBloc(3);
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
waitForLoaded();
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
64
resources/views/bo/pages/news/index-list.blade.php
Normal file
64
resources/views/bo/pages/news/index-list.blade.php
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table fix-action m-0">
|
||||||
|
<thead>
|
||||||
|
@php
|
||||||
|
$cols = [
|
||||||
|
'title' => __('validation.attributes.title'),
|
||||||
|
'subtitle' => __('validation.attributes.subtitle'),
|
||||||
|
'order' => __('validation.attributes.order'),
|
||||||
|
'updated_at' => __('validation.attributes.updated_at')];
|
||||||
|
@endphp
|
||||||
|
@include('bo.modules.table-col-sorter', ['cols' => $cols, 'mobileHide' => ['status']])
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@if($newsListModels->count())
|
||||||
|
@foreach ($newsListModels as $newsModels)
|
||||||
|
<tr>
|
||||||
|
<td class="align-middle">{{ $newsModels->title }}</td>
|
||||||
|
<td class="align-middle">{{ $newsModels->subtitle }}</td>
|
||||||
|
@php $routeName = request()->route()->getName(); @endphp
|
||||||
|
@if(empty(request()->search) and empty($noOrder) and Session::get("$routeName.sort_col") === 'order')
|
||||||
|
<td class="d-flex">
|
||||||
|
<form action="{{ route('bo.news.change-order', ['news' => $newsModels, 'action' => 'up']) }}" method="POST" class="text-center @if($loop->first and $newsListModels->onFirstPage()) invisible @endif">
|
||||||
|
@csrf
|
||||||
|
<button type="submit" class="btn btn-sm @if(($loop->first and $newsListModels->onFirstPage())) disabled @endif" title="{{ __('Change the order of appearance upwards') }}" data-bs-toggle="tooltip">
|
||||||
|
<i class="fas fa-arrow-alt-circle-up"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ route('bo.news.change-order', ['news' => $newsModels, 'action' => 'down']) }}" method="POST" class="text-center @if($loop->last and $newsListModels->currentPage() === $newsListModels->lastPage()) invisible @endif">
|
||||||
|
@csrf
|
||||||
|
<button type="submit" class="btn btn-sm @if($loop->last and $newsListModels->currentPage() === $newsListModels->lastPage()) disabled @endif" title="{{ __('Change the order of appearance downwards') }}" data-bs-toggle="tooltip">
|
||||||
|
<i class="fas fa-arrow-alt-circle-down"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
@endif
|
||||||
|
<td class="align-middle">
|
||||||
|
<span class="badge bg-warning text-dark text-wrap">{{ $newsModels->updated_at->formatLocalized('%d/%m/%Y à %H:%M') }}</span>
|
||||||
|
</td>
|
||||||
|
<td class="align-middle">
|
||||||
|
<form action="{{ route('bo.news.destroy', $newsModels->id) }}" method="POST" class="btn-group confirmDeleteJS" novalidate>
|
||||||
|
<a class="btn btn-sm btn-primary" href="{{ route('bo.news.edit', $newsModels->id) }}" title="{{ __('crud.helpers.update_model', ['model' => Str::singular(__('models.classes.news'))]) }}" data-bs-toggle="tooltip">
|
||||||
|
<i class="fa-solid fa-pencil"></i>
|
||||||
|
</a>
|
||||||
|
@method('DELETE')
|
||||||
|
@csrf
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<button class="btn btn-sm btn-danger" title="{{ __('crud.helpers.delete_model', ['model' => Str::singular(__('models.classes.news'))]) }}" data-bs-toggle="tooltip">
|
||||||
|
<i class="fa-solid fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
@else
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="text-center">
|
||||||
|
<span class="h3">{{ __('crud.helpers.no_results', ['models' => __('models.classes.news') ])}}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
48
resources/views/bo/pages/news/index.blade.php
Normal file
48
resources/views/bo/pages/news/index.blade.php
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
@extends('bo.layout')
|
||||||
|
|
||||||
|
@section('title', __('crud.helpers.list_all', ['model' => __('models.classes.news')]))
|
||||||
|
@section('description', __('crud.helpers.list_all', ['model' => __('models.classes.news')]))
|
||||||
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h1 class="h2 d-inline"><span class="fw-bold">{{ __('models.classes.news') }}</span> <small class="text-muted">{{ Str::ucfirst(__('crud.helpers.list')) }}</small> </h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3 d-flex align-items-center">
|
||||||
|
<div class="input-group justify-content-end">
|
||||||
|
<a href="{{ route('bo.news.create') }}" class="btn btn-primary" title="{{ __('crud.helpers.create_model', ['model' => Str::singular(__('models.classes.news'))]) }}" data-bs-toggle="tooltip">
|
||||||
|
<i class="fa-solid fa-plus"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@include('bo.modules.search-bar')
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-12 col-md-6 p-0">
|
||||||
|
{{ $newsListModels->withQueryString()->onEachSide(1)->links() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
@include('bo.pages.news.index-list')
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-12 col-md-6 p-0">
|
||||||
|
{{ $newsListModels->withQueryString()->onEachSide(1)->links() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@extends('bo.layout')
|
@extends('bo.layout')
|
||||||
|
|
||||||
@section('title', __('crud.helpers.listall', ['model' => __('models.classes.products')]))
|
@section('title', __('crud.helpers.list_all', ['model' => __('models.classes.products')]))
|
||||||
@section('description', __('crud.helpers.listall', ['model' => __('models.classes.products')]))
|
@section('description', __('crud.helpers.list_all', ['model' => __('models.classes.products')]))
|
||||||
@section('breadcrumb', request()->route()->getName())
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
@ -45,4 +45,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@extends('bo.layout')
|
@extends('bo.layout')
|
||||||
|
|
||||||
@section('title', __('crud.helpers.listall', ['model' => __('models.classes.ranges')]))
|
@section('title', __('crud.helpers.list_all', ['model' => __('models.classes.ranges')]))
|
||||||
@section('description', __('crud.helpers.listall', ['model' => __('models.classes.ranges')]))
|
@section('description', __('crud.helpers.list_all', ['model' => __('models.classes.ranges')]))
|
||||||
@section('breadcrumb', request()->route()->getName())
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
@ -45,4 +45,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@extends('bo.layout')
|
@extends('bo.layout')
|
||||||
|
|
||||||
@section('title', sprintf('%s - %s', __('models.classes.recipes'), Str::ucfirst(__('crud.helpers.list'))))
|
@section('title', sprintf('%s - %s', __('models.classes.recipes'), Str::ucfirst(__('crud.helpers.list'))))
|
||||||
@section('description', __('crud.helpers.listall', ['model' => __('models.classes.recipes')]))
|
@section('description', __('crud.helpers.list_all', ['model' => __('models.classes.recipes')]))
|
||||||
@section('breadcrumb', request()->route()->getName())
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
@ -45,4 +45,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@extends('bo.layout')
|
@extends('bo.layout')
|
||||||
|
|
||||||
@section('title', __('crud.helpers.listall', ['model' => __('models.classes.sliders')]))
|
@section('title', __('crud.helpers.list_all', ['model' => __('models.classes.sliders')]))
|
||||||
@section('description', __('crud.helpers.listall', ['model' => __('models.classes.sliders')]))
|
@section('description', __('crud.helpers.list_all', ['model' => __('models.classes.sliders')]))
|
||||||
@section('breadcrumb', request()->route()->getName())
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
@ -45,4 +45,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@extends('bo.layout')
|
@extends('bo.layout')
|
||||||
|
|
||||||
@section('title', __('crud.helpers.listall', ['model' => __('models.classes.storegroups')]))
|
@section('title', __('crud.helpers.list_all', ['model' => __('models.classes.storegroups')]))
|
||||||
@section('description', __('crud.helpers.listall', ['model' => __('models.classes.storegroups')]))
|
@section('description', __('crud.helpers.list_all', ['model' => __('models.classes.storegroups')]))
|
||||||
@section('breadcrumb', request()->route()->getName())
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
@ -45,4 +45,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@extends('bo.layout')
|
@extends('bo.layout')
|
||||||
|
|
||||||
@section('title', sprintf('%s - %s', __('models.classes.storeregions'), Str::ucfirst(__('crud.helpers.list'))))
|
@section('title', sprintf('%s - %s', __('models.classes.storeregions'), Str::ucfirst(__('crud.helpers.list'))))
|
||||||
@section('description', __('crud.helpers.listall', ['model' => __('models.classes.storeregions')]))
|
@section('description', __('crud.helpers.list_all', ['model' => __('models.classes.storeregions')]))
|
||||||
@section('breadcrumb', request()->route()->getName())
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
@ -45,4 +45,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@extends('bo.layout')
|
@extends('bo.layout')
|
||||||
|
|
||||||
@section('title', __('crud.helpers.listall', ['model' => __('models.classes.stores')]))
|
@section('title', __('crud.helpers.list_all', ['model' => __('models.classes.stores')]))
|
||||||
@section('description', __('crud.helpers.listall', ['model' => __('models.classes.stores')]))
|
@section('description', __('crud.helpers.list_all', ['model' => __('models.classes.stores')]))
|
||||||
@section('breadcrumb', request()->route()->getName())
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
@ -45,4 +45,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@extends('bo.layout')
|
@extends('bo.layout')
|
||||||
|
|
||||||
@section('title', __('crud.helpers.listall', ['model' => __('models.classes.storetypes')]))
|
@section('title', __('crud.helpers.list_all', ['model' => __('models.classes.storetypes')]))
|
||||||
@section('description', __('crud.helpers.listall', ['model' => __('models.classes.storetypes')]))
|
@section('description', __('crud.helpers.list_all', ['model' => __('models.classes.storetypes')]))
|
||||||
@section('breadcrumb', request()->route()->getName())
|
@section('breadcrumb', request()->route()->getName())
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
@ -45,4 +45,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
data-form-type="date"
|
data-form-type="date"
|
||||||
aria-describedby="{{ $id }}Help"
|
aria-describedby="{{ $id }}Help"
|
||||||
value="{{ old($name, ((isset($sliderModel) and $sliderModel->{$name}) ? $sliderModel->{$name}->format('Y-m-d\TH:i') : '')) }}">
|
value="{{ old($name, ((isset($model) and $model->{$name}) ? $model->{$name}->format('Y-m-d\TH:i') : '')) }}">
|
||||||
@include('modules.input-error', [
|
@include('modules.input-error', [
|
||||||
'inputName' => $name,
|
'inputName' => $name,
|
||||||
'helperId' => $id . 'Help',
|
'helperId' => $id . 'Help',
|
||||||
'helper' => (isset($sliderModel) and $sliderModel->{$name}) ? __('Leave empty for immediate display of the slider.') : __('Empty for immediate display of the slider.')
|
'helper' => (isset($model) and $model->{$name}) ? __('Leave empty for immediate display of the slider.') : __('Empty for immediate display of the slider.')
|
||||||
])
|
])
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
@include('fo.vendor/ldcweb-cookies')
|
@include('fo.vendor/ldcweb-cookies')
|
||||||
@stack('scripts-constants')
|
@stack('scripts-constants')
|
||||||
@include('modules.script-constants')
|
@include('modules.script-constants')
|
||||||
|
@include('modules.script-routes')
|
||||||
@stack('scripts')
|
@stack('scripts')
|
||||||
@vite(['resources/ts/fo.ts'])
|
@vite(['resources/ts/fo.ts'])
|
||||||
<script nonce="{{ $nonce }}">
|
<script nonce="{{ $nonce }}">
|
||||||
|
|
|
||||||
37
resources/views/fo/layout-minimal.blade.php
Normal file
37
resources/views/fo/layout-minimal.blade.php
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html dir="ltr" lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
@include('fo.layouts.head')
|
||||||
|
<meta name="p:domain_verify" content="5f89c5d6c41555aa17ff8d26cc6661f2" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="relative w-full min-h-screen font-roboto bg-hellgrau text-p lg:text-p-lg mt-[87px] scroll-smooth">
|
||||||
|
<a name="top" id="top"></a>
|
||||||
|
|
||||||
|
@include('fo.layouts.header')
|
||||||
|
|
||||||
|
@yield('content')
|
||||||
|
|
||||||
|
@include('fo.layouts.footer')
|
||||||
|
@include('fo.layouts.navigation')
|
||||||
|
|
||||||
|
|
||||||
|
@include('fo.vendor.ldcweb-cookies')
|
||||||
|
@stack('scripts-constants')
|
||||||
|
@include('modules.script-constants')
|
||||||
|
@stack('scripts')
|
||||||
|
@vite(['resources/ts/fo.ts'])
|
||||||
|
<script nonce="{{ $nonce }}">
|
||||||
|
let mobileMenuOpen = false;
|
||||||
|
|
||||||
|
function toggleMobileMenuOpen() {
|
||||||
|
mobileMenuOpen = !mobileMenuOpen;
|
||||||
|
const navMenu = document.getElementById('navigationModule');
|
||||||
|
navMenu.classList.toggle('hidden');
|
||||||
|
navMenu.classList.toggle('flex');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -27,8 +27,10 @@
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="mr-6 mb-4 relative">
|
<li class="mr-6 mb-4 relative">
|
||||||
@php $firstConcept = \App\Models\Concept::query()->firstOrFail(); @endphp
|
@php $firstConcept = \App\Models\Concept::query()->first(); @endphp
|
||||||
|
@if($firstConcept)
|
||||||
<a href="{{ route('concept.show', ['concept' => $firstConcept]) }}">{{ __('Our concept') }}</a>
|
<a href="{{ route('concept.show', ['concept' => $firstConcept]) }}">{{ __('Our concept') }}</a>
|
||||||
|
@endif
|
||||||
<ul class="xinvisible xgroup-hover:visible pl-8 lg:pl-0 lg:absolute lg:left-0 lg:right-auto w-max pt-2">
|
<ul class="xinvisible xgroup-hover:visible pl-8 lg:pl-0 lg:absolute lg:left-0 lg:right-auto w-max pt-2">
|
||||||
@foreach ($conceptListGlobal as $concept)
|
@foreach ($conceptListGlobal as $concept)
|
||||||
<li class="mt-2">
|
<li class="mt-2">
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="max-w-7xl w-full mx-auto relative flex items-center">
|
<div class="max-w-7xl w-full mx-auto relative flex items-center">
|
||||||
<a href="{{ route('home') }}" class="inline-block mx-auto absolute left-0 right-0 top-0 "><img src="{{ Vite::asset('resources/assets/images/Icons/logo-nature-respect.svg') }}" alt="Unternehmenslogo" class="w-16 sm:w-[120px] block mx-auto"></a>
|
<a href="{{ route('home') }}" class="inline-block mx-auto absolute left-0 right-0 top-0 "><img src="{{ Vite::asset('resources/assets/images/Icons/logo-nature-respect.svg') }}" alt="Unternehmenslogo" class="w-16 sm:w-[120px] block mx-auto"></a>
|
||||||
<nav class="text-lg text-braun absolute right-8 sm:right-12 flex items-center top-[8px]">
|
<nav class="text-lg text-braun absolute right-8 sm:right-12 flex items-center top-[8px]">
|
||||||
<a id="menu-burger-link" href="#" class="sm:mr-7 font-hobo font-semibold text-p-lg inline-flex items-center"><img class="w-4 mr-4" src="{{ Vite::asset('resources/assets/images/Icons/menu-burger.svg') }}">{{ __('Menu') }}</a>
|
<a id="menu-burger-link" href="#" class="md:mr-7 font-hobo font-semibold text-p-lg inline-flex items-center"><img class="w-4 mr-4" src="{{ Vite::asset('resources/assets/images/Icons/menu-burger.svg') }}">{{ __('Menu') }}</a>
|
||||||
@push('scripts')
|
@push('scripts')
|
||||||
<script nonce="{{ $nonce }}">
|
<script nonce="{{ $nonce }}">
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
@endpush
|
@endpush
|
||||||
<a href="https://www.instagram.com/nature_and_respect/" class="hidden sm:inline-block mr-2 ml-[36px]" target="_blank"><img src="{{ Vite::asset('resources/assets/images/Icons/instagram-icon.svg') }}" alt="Instagram" class="w-8"></a>
|
<a href="https://www.instagram.com/nature_and_respect/" class="hidden sm:inline-block mr-2 ml-[36px]" target="_blank"><img src="{{ Vite::asset('resources/assets/images/Icons/instagram-icon.svg') }}" alt="Instagram" class="w-8"></a>
|
||||||
<a href="https://www.pinterest.de/natureandrespect" class="hidden sm:inline-block mr-0" target="_blank"><img src="{{ Vite::asset('resources/assets/images/Icons/pinterest-icon.svg') }}" alt="Pinterest" class="w-8"></a>
|
<a href="https://www.pinterest.de/natureandrespect" class="hidden sm:inline-block mr-0" target="_blank"><img src="{{ Vite::asset('resources/assets/images/Icons/pinterest-icon.svg') }}" alt="Pinterest" class="w-8"></a>
|
||||||
<div class="ml-4 font-hobo text-p-lg">
|
<div class="ml-4 font-hobo text-p-lg hidden lg:inline-block">
|
||||||
@foreach (config('app.locales') as $locale)
|
@foreach (config('app.locales') as $locale)
|
||||||
@if (!$loop->first)
|
@if (!$loop->first)
|
||||||
|
|
|
|
||||||
|
|
|
||||||
|
|
@ -2,53 +2,66 @@
|
||||||
<nav class="main fixed top-0 left-0 z-[150] flex-col w-full h-screen font-semibold text-center bg-weiss p-0 hidden" id="navigationModule">
|
<nav class="main fixed top-0 left-0 z-[150] flex-col w-full h-screen font-semibold text-center bg-weiss p-0 hidden" id="navigationModule">
|
||||||
<div class="relative w-full h-screen max-w-7xl mx-auto text-braun flex items-center">
|
<div class="relative w-full h-screen max-w-7xl mx-auto text-braun flex items-center">
|
||||||
|
|
||||||
<a id="menu-burger-link-close" class="absolute right-10 top-[16px] sm:right-[144px] sm:top-[34px] font-hobo text-p-lg cursor-pointer inline-flex items-center"><img class="w-4 mr-4" src="{{ Vite::asset('resources/assets/images/Icons/menu-close.svg') }}"> {{ __('Menu') }}</a>
|
<a id="menu-burger-link-close" class="absolute right-10 top-[16px] sm:right-[11.25rem] md:right-[13rem] lg:right-[18.6rem] xl:right-[17rem] sm:top-[34px] font-hobo text-p-lg cursor-pointer inline-flex items-center"><img class="w-4 mr-4" src="{{ Vite::asset('resources/assets/images/Icons/menu-close.svg') }}"> {{ __('Menu') }}</a>
|
||||||
@push('scripts')
|
@push('scripts')
|
||||||
<script nonce="{{ $nonce }}">
|
<script nonce="{{ $nonce }}">
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
document.getElementById('menu-burger-link-close').addEventListener('click', () => toggleMobileMenuOpen());
|
document.getElementById('menu-burger-link-close').addEventListener('click', () => toggleMobileMenuOpen());
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@endpush
|
@endpush
|
||||||
<a href="">
|
<a href="">
|
||||||
<img src="{{ Vite::asset('resources/assets/images/Icons/logo-nature-respect.svg') }}" alt="{{ __('Unternehmenslogo') }}" class="w-16 sm:w-[120px] absolute left-0 right-0 mx-auto top-2 sm:top-6">
|
<img src="{{ Vite::asset('resources/assets/images/Icons/logo-nature-respect.svg') }}" alt="{{ __('Unternehmenslogo') }}" class="w-16 sm:w-[120px] absolute left-0 right-0 mx-auto top-2 sm:top-6">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<ul id="frontend_menu" class="font-hobo text-left md:text-h3-md lg:text-h3-lg xl:text-h3 ml-6 md:ml-12">
|
<ul id="frontend_menu" class="font-hobo text-left md:text-h3-md lg:text-h3-lg xl:text-h3 ml-6 md:ml-12">
|
||||||
<li class="mb-2 block leading-[180%] relative">
|
<li class="mb-2 block leading-[180%] relative">
|
||||||
<a href="">{{ __('Home') }}</a>
|
<a href="">{{ __('Home') }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="mb-2 block leading-[180%] relative">
|
<li class="mb-2 block leading-[180%] relative">
|
||||||
@php $concept = \App\Models\Concept::query()->firstOrFail(); @endphp
|
@php $concept = \App\Models\Concept::query()->first(); @endphp
|
||||||
<a href="{{ route('concept.show', ['concept' => $concept]) }}">{{ __('Our concept') }}</a>
|
@if($concept)
|
||||||
<ul class="pl-8 sm:absolute sm:top-0 sm:left-full sm:pl-24 w-max">
|
<a href="{{ route('concept.show', ['concept' => $concept]) }}">{{ __('Our concept') }}</a>
|
||||||
@foreach ($conceptListGlobal as $concept)
|
@endif
|
||||||
<li class="mb-2 block leading-[180%]">
|
<ul class="pl-8 sm:absolute sm:top-0 sm:left-full sm:pl-24 w-max">
|
||||||
<a class="block" href="{{ route('concept.show', ['concept' => $concept]) }}">{{ $concept->name }}</a>
|
@foreach ($conceptListGlobal as $concept)
|
||||||
</li>
|
<li class="mb-2 block leading-[180%]">
|
||||||
@endforeach
|
<a class="block" href="{{ route('concept.show', ['concept' => $concept]) }}">{{ $concept->name }}</a>
|
||||||
</ul>
|
</li>
|
||||||
</li>
|
@endforeach
|
||||||
<li class="mb-2 block leading-[180%] relative">
|
</ul>
|
||||||
<a href="{{ route('products.index') }}">{{ __('Our products') }}</a>
|
</li>
|
||||||
</li>
|
<li class="mb-2 block leading-[180%] relative">
|
||||||
<li class="mb-2 block leading-[180%] relative">
|
<a href="{{ route('news.index') }}">{{ __('News') }}</a>
|
||||||
<a href="{{ route('recipes.index') }}">{{ __('Our recipes') }}</a>
|
</li>
|
||||||
</li>
|
<li class="mb-2 block leading-[180%] relative">
|
||||||
<li class="mb-2 block leading-[180%] relative">
|
<a href="{{ route('products.index') }}">{{ __('Our products') }}</a>
|
||||||
<a href="{{ route('storefinder.index') }}">{{ __('Store finder') }}</a>
|
</li>
|
||||||
</li>
|
<li class="mb-2 block leading-[180%] relative">
|
||||||
<li class="mb-2 block leading-[180%] relative">
|
<a href="{{ route('recipes.index') }}">{{ __('Our recipes') }}</a>
|
||||||
<a href="{{ route('contact-form') }}">{{ __('Contact Us') }}</a>
|
</li>
|
||||||
</li>
|
<li class="mb-2 block leading-[180%] relative">
|
||||||
</ul>
|
<a href="{{ route('storefinder.index') }}">{{ __('Store finder') }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="mb-2 block leading-[180%] relative">
|
||||||
|
<a href="{{ route('contact-form') }}">{{ __('Contact Us') }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="absolute bottom-8 right-8 flex items-center font-hobo">
|
<div class="absolute bottom-16 right-8 flex items-center font-hobo">
|
||||||
{{ __('Follow us') }}
|
{{ __('Follow us') }}
|
||||||
|
|
||||||
<a href="https://www.instagram.com/nature_and_respect/" class="inline-block mr-2 ml-5" target="_blank"><img src="{{ Vite::asset('resources/assets/images/Icons/instagram-icon.svg') }}" alt="Instagram" class="w-6"></a>
|
<a href="https://www.instagram.com/nature_and_respect/" class="inline-block mr-2 ml-5" target="_blank"><img src="{{ Vite::asset('resources/assets/images/Icons/instagram-icon.svg') }}" alt="Instagram" class="w-6"></a>
|
||||||
<a href="https://www.pinterest.de/natureandrespect" class="inline-block mr-0" target="_blank"><img src="{{ Vite::asset('resources/assets/images/Icons/pinterest-icon.svg') }}" alt="Pinterest" class="w-6"></a>
|
<a href="https://www.pinterest.de/natureandrespect" class="inline-block mr-0" target="_blank"><img src="{{ Vite::asset('resources/assets/images/Icons/pinterest-icon.svg') }}" alt="Pinterest" class="w-6"></a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="absolute bottom-8 right-8 font-hobo text-p-lg">
|
||||||
|
@foreach (config('app.locales') as $locale)
|
||||||
|
@if (!$loop->first)
|
||||||
|
|
|
||||||
|
@endif
|
||||||
|
<a href="{{ route('home', [], true, $locale) }}" class="@if (app()->currentLocale() === $locale) text-hellgruen @endif">{{ Str::upper($locale) }}</a>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
||||||
35
resources/views/fo/pages/news/aside-news.blade.php
Normal file
35
resources/views/fo/pages/news/aside-news.blade.php
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
@if ($relatedNewsList->count() > 0)
|
||||||
|
<aside class="w-full text-braun py-16 mb-24">
|
||||||
|
<div class="container max-w-7xl mx-auto px-4 sm:px-8">
|
||||||
|
<div class="w-full mb-12">
|
||||||
|
<span class="block font-scarletwood text-h2-md lg:text-h2-lg xl:text-h2">{{
|
||||||
|
__('Headline more news')
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container max-w-7xl mx-auto px-4 sm:px-8">
|
||||||
|
<div class="w-full flex flex-col sm:flex-row gap-8 mt-12">
|
||||||
|
@foreach($relatedNewsList as $newsModel)
|
||||||
|
<article class="flex flex-col basis-full sm:basis-1/2 justify-start">
|
||||||
|
<div class="m-4 hover:scale-105 ease-in-out duration-300">
|
||||||
|
<a href="{{ route('news.show', $newsModel) }}" title="{{ __('Learn more') }}">
|
||||||
|
@php $picture = $newsModel->picture_list->first(); @endphp
|
||||||
|
@if ($picture)
|
||||||
|
<img src="{{ asset(resize($picture->value, 'foNewsIndexPicture')) }}" alt="{{ $picture->alt }}" title="{{ $picture->title }}">
|
||||||
|
@else
|
||||||
|
<img src="{{ Vite::asset('resources/assets/images/news_placeholder.png') }}" alt="{{ $newsModel->title }}" title="{{ $newsModel->title }}">
|
||||||
|
@endif
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="m-4">
|
||||||
|
<div class="font-scarletwood text-h3-md lg:text-h2-lg xl:text-h2">
|
||||||
|
<a href="{{ route('news.show', $newsModel) }}" title="{{ __('Learn more') }}">{{ $newsModel->title }}</a>
|
||||||
|
</div>
|
||||||
|
<div>{!! Str::limit(htmlentities(strip_tags($newsModel->content)), 250) !!}</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
@endif
|
||||||
20
resources/views/fo/pages/news/bloc.blade.php
Normal file
20
resources/views/fo/pages/news/bloc.blade.php
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<div class="basis-full sm:basis-1/2 flex">
|
||||||
|
@if(count($pictures))
|
||||||
|
@php $picture = collect($pictures)->first(); @endphp
|
||||||
|
<img src="{{ asset(resize($picture->value, 'foNewsIndexPicture')) }}" alt="{{ $picture->alt }}" title="{{ $picture->title }}">
|
||||||
|
@else
|
||||||
|
<img src="{{ Vite::asset('resources/assets/images/news_placeholder.png') }}" alt="{{ $newsModel->title }}" title="{{ $newsModel->title }}">
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<div class="bg-hellgruen basis-full sm:basis-1/2 order-2 text-weiss flex items-center">
|
||||||
|
<div class="p-6 sm:pl-6 sm:py-4 lg:pl-16 lg:py-8 xl:pl-32 xl:py-12 max-w-xl">
|
||||||
|
<h5 class="my-0.5">{{ $newsModel->updated_at->formatLocalized('%d.%m.%Y') }}</h5>
|
||||||
|
<h3 class="text-h2-sm md:text-h2-md lg:text-h2-lg xl:text-h2 mb-2 lg:mb-4 font-scarletwood">{{
|
||||||
|
$newsModel->title
|
||||||
|
}}</h3>
|
||||||
|
<div>{!! Str::limit(htmlentities(strip_tags($newsModel->content)), 250) !!}</div>
|
||||||
|
<a title="{{ __('Learn more') }}" class="button brown inline-flex items-center px-4 my-2 mt-6 mr-4 text-sm text-white" href="{{ route('news.show', ['publishedNews' => $newsModel->slug]) }}">
|
||||||
|
<span>{{ __('Learn more') }}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
24
resources/views/fo/pages/news/header.blade.php
Normal file
24
resources/views/fo/pages/news/header.blade.php
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="relative">
|
||||||
|
<img class="w-full" src="{{ Vite::asset('resources/assets/images/Replace_me.png') }}">
|
||||||
|
<div class="mx-auto max-w-7xl h-full w-full absolute top-0 left-0 right-0">
|
||||||
|
<div class="relative h-full w-full">
|
||||||
|
<svg class="absolute right-4 -bottom-3 sm:-bottom-4 md:-bottom-5 lg:-bottom-6 h-[40px] sm:h-[50px] md:h-[60px] text-weinrot" viewBox="0 0 313 45" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_219_44709)">
|
||||||
|
@php
|
||||||
|
$color = '#b4bd00';
|
||||||
|
@endphp
|
||||||
|
<path d="M312.425 3.98605C311.085 6.46369 309.583 8.59519 308.89 10.7631C308.128 13.095 307.319 13.6416 300.85 14.7346C301.474 15.937 301.474 17.1394 302.814 18.2143C304.131 19.2527 306.811 20.1272 307.088 21.0745C306.51 21.8214 305.748 22.5501 305.355 23.2971C304.593 24.7181 304.339 26.1937 303.16 27.5783C302.837 27.9609 299.995 28.1613 297.847 28.5256C300.088 29.309 302.698 30.2017 305.956 31.3494C304.616 31.7684 302.837 32.315 300.85 32.9162C302.028 33.2259 303.415 33.572 305.078 34.0092C301.543 35.4485 297.477 36.9423 309.075 37.9625C305.702 38.3998 304.085 38.6002 302.283 38.837C304.57 39.4018 305.864 39.7297 307.157 40.0394C304.223 40.9503 302.028 42.1162 298.678 42.5717C285.464 44.3206 272.249 45.5594 256.746 44.7214C243.809 44.0291 230.109 44.5574 216.778 44.4299C209.015 44.357 201.322 44.0291 193.559 43.8287C192.52 43.7923 191.434 43.8287 190.371 43.8287C178.265 43.9562 166.136 44.0473 154.053 44.2477C149.34 44.3206 144.72 44.8125 140.007 44.8489C125.983 44.9582 111.959 44.9582 97.9358 44.9582C81.2554 44.9582 64.5981 45.0311 47.9639 44.8854C41.726 44.8307 35.5344 44.3024 29.4352 43.8469C28.049 43.7376 27.0556 43.0453 26.2008 42.5899C25.138 41.9705 24.3063 41.2964 23.0587 40.4402C20.425 41.4422 18.5305 42.1709 16.6823 42.8632C12.6624 40.5495 9.12758 38.5091 5.5235 36.4504C3.97559 35.576 4.738 34.574 1.66529 33.6813C-1.82328 32.6611 0.972194 31.4587 6.2859 30.8211C4.55317 29.6734 2.63562 28.6167 1.43426 27.5054C0.71806 26.8678 0.879782 26.1209 1.0415 25.4286C1.68839 22.6595 2.47389 19.8721 3.2594 17.103C3.32871 16.8479 3.65215 16.6293 3.76767 16.3743C4.32214 15.2812 12.593 14.3885 4.738 13.095C9.54344 11.4918 1.27253 11.2186 1.45736 10.3623C4.32214 8.57697 7.55657 7.01023 9.38172 5.29774C10.6986 4.05892 12.8703 3.74921 16.8209 3.67634C40.6864 3.25733 64.5288 2.63792 88.4174 2.38287C119.306 2.07316 150.241 1.76346 181.153 1.83633C217.564 1.92742 253.974 2.4193 290.361 2.8201C296.669 2.89297 302.929 3.29376 309.19 3.58525C310.6 3.65812 311.94 3.91318 312.425 3.96783" fill="{{ $color }}" />
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_219_44709">
|
||||||
|
<rect width="312.305" height="44.0104" fill="white" transform="translate(0.695312 0.984375)" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<div class="absolute right-4 -bottom-1 sm:-bottom-2 lg:-bottom-3 text-white w-[280px] sm:w-[340px] md:w-[420px] flex justify-center font-scarletwood text-p sm:text-p-lg md:text-2xl">
|
||||||
|
{{ __('News') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
29
resources/views/fo/pages/news/index.blade.php
Normal file
29
resources/views/fo/pages/news/index.blade.php
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
@extends('fo.layout-frame')
|
||||||
|
{{-- FIXME: Add titles here --}}
|
||||||
|
@section('title', __('News'))
|
||||||
|
@section('description', __('News'))
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
@include('fo.pages.news.header')
|
||||||
|
|
||||||
|
<!-- Breadcrumb -->
|
||||||
|
<div x-show="false" class="container mx-auto max-w-7xl">
|
||||||
|
<ul class="px-4 sm:px-8 py-4 md:py-8 text-braun text-small md:text-size-17">
|
||||||
|
<li class="inline-block pr-1 after:content-['/'] after:pl-1"><a href="{{ route('home') }}" class="hover:underline">{{ __('models.classes.homes') }}</a></li>
|
||||||
|
<li class="inline-block font-bold font-robotobold">{{ __('models.classes.news') }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mx-auto max-w-7xl px-4 sm:px-8 mt-16 mb-8">
|
||||||
|
<h1 class="text-h1-md lg:text-h1-lg xl:text-h1 font-scarletwood text-braun mb-6">
|
||||||
|
{{ __('Lorem ipsum dolor sit') }}
|
||||||
|
<span class="block text-h2-md lg:text-h2-lg xl:text-h2">{{
|
||||||
|
__('Lorem ipsum dolor sit amet, consetetur')
|
||||||
|
}}</span>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- NEWS VUE JS --}}
|
||||||
|
<div id="news-infinite-loader" class="my-8"></div>
|
||||||
|
@endsection
|
||||||
90
resources/views/fo/pages/news/show.blade.php
Normal file
90
resources/views/fo/pages/news/show.blade.php
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
@extends('fo.layout-frame')
|
||||||
|
@section('title', $newsModel->seo_title)
|
||||||
|
@section('description', $newsModel->seo_description)
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
@include('fo.pages.news.header')
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<!-- Breadcrumb -->
|
||||||
|
<div class="container mx-auto max-w-7xl">
|
||||||
|
<ul class="px-4 sm:px-8 py-4 md:py-8 text-braun text-small md:text-size-17">
|
||||||
|
<li class="inline-block pr-1 after:content-['/'] after:pl-1"><a href="{{ route('home') }}" class="hover:underline">{{ __('models.classes.homes') }}</a></li>
|
||||||
|
<li class="inline-block pr-1 after:content-['/'] after:pl-1"><a href="{{ route('news.index') }}" class="hover:underline">{{ __('models.classes.news') }}</a></li>
|
||||||
|
<li class="inline-block font-bold font-robotobold">{{ $newsModel->title }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mx-auto max-w-7xl px-4 sm:px-8 mt-16 mb-8">
|
||||||
|
<h1 class="text-h1-md lg:text-h1-lg xl:text-h1 font-scarletwood text-braun mb-6">
|
||||||
|
{{ $newsModel->title }}
|
||||||
|
<span class="block text-h2-md lg:text-h2-lg xl:text-h2">{{
|
||||||
|
$newsModel->subtitle
|
||||||
|
}}</span>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@php $pictureList = $newsModel->picture_list; @endphp
|
||||||
|
@php $hasOnePicture = $pictureList->count() === 1; @endphp
|
||||||
|
@php $hasTwoPictures = $pictureList->count() === 2; @endphp
|
||||||
|
@php $hasMorePictures = $pictureList->count() > 2; @endphp
|
||||||
|
|
||||||
|
<div class="w-full bg-hellgruen text-weiss py-16 mb-24">
|
||||||
|
<div class="container max-w-7xl mx-auto px-4 sm:px-8">
|
||||||
|
<div class="w-full mb-12 ck-content scarlet-titles">
|
||||||
|
@if($hasOnePicture)
|
||||||
|
@php $picture = collect($pictureList)->first(); @endphp
|
||||||
|
<img class="m-3 float-right" src="{{ asset(resize($picture->value, 'foNewsShowPicture')) }}" alt="{{ $picture->alt }}" title="{{ $picture->title }}">
|
||||||
|
@endif
|
||||||
|
{!! clean($newsModel->content) !!}
|
||||||
|
</div>
|
||||||
|
@if($hasTwoPictures)
|
||||||
|
<div class="w-full flex flex-col sm:flex-row gap-2 mt-12">
|
||||||
|
<div class="flex flex-wrap basis-full sm:basis-1/2">
|
||||||
|
<img class="" src="{{ asset(resize($pictureList->get(0)->value, 'foNewsShowPicture')) }}" alt="{{ $pictureList->get(0)->alt }}" title="{{ $pictureList->get(0)->title }}">
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap basis-full sm:basis-1/2">
|
||||||
|
<img class="" src="{{ asset(resize($pictureList->get(1)->value, 'foNewsShowPicture')) }}" alt="{{ $pictureList->get(1)->alt }}" title="{{ $pictureList->get(1)->title }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@if($hasMorePictures)
|
||||||
|
<section class="splide">
|
||||||
|
<div class="splide__track">
|
||||||
|
<ul class="splide__list">
|
||||||
|
@foreach ($pictureList as $picture)
|
||||||
|
<li class="splide__slide">
|
||||||
|
<img class="object-contain p-10" src="{{ asset(resize($picture->value, 'foNewsShowPicture')) }}" alt="{{ $picture->alt }}" title="{{ $picture->title }}">
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@push('scripts')
|
||||||
|
<script nonce="{{ $nonce }}">
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
new Splide('.splide', {
|
||||||
|
type: 'loop',
|
||||||
|
perPage: 2,
|
||||||
|
autoplay: 'play',
|
||||||
|
pagination: false,
|
||||||
|
pauseOnHover: true,
|
||||||
|
autoWidth: false,
|
||||||
|
breakpoints: {
|
||||||
|
640: {
|
||||||
|
perPage: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).mount();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
@include('fo.pages.news.aside-news', ['relatedNewsList' => $relatedNewsList])
|
||||||
|
|
||||||
|
@endsection
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
@include('modules.script-constants')
|
|
||||||
<script @if(isset($nonce)) nonce="{{ $nonce }}" @endif>
|
<script @if(isset($nonce)) nonce="{{ $nonce }}" @endif>
|
||||||
if (!window.__SYSTEM._routes) {
|
if (!window.__SYSTEM._routes) {
|
||||||
window.__SYSTEM._routes = {};
|
window.__SYSTEM._routes = {};
|
||||||
}
|
}
|
||||||
|
window.__SYSTEM._routes['news.index'] = '{{ route('news.index') }}';
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
26
resources/views/vendor/errors/404.blade.php
vendored
26
resources/views/vendor/errors/404.blade.php
vendored
|
|
@ -1,14 +1,26 @@
|
||||||
@extends('fo.layout-frame')
|
@php $nonce = $nonce ?? uniqid(); @endphp
|
||||||
|
@extends('fo.layout-minimal')
|
||||||
|
|
||||||
@section('title', __('Not Found'))
|
@section('title', __('Not Found'))
|
||||||
@section('description', __('Not Found'))
|
@section('code', '404')
|
||||||
|
@section('message', __('Not Found'))
|
||||||
|
@section('submessage', __('We could not find the page'))
|
||||||
|
|
||||||
|
@section('image')
|
||||||
|
<img src="{{ Vite::asset('resources/assets/images/Icons/404-grafik.svg') }}" class="inline max-w-sm w-full px-4" alt="{{ config('app.name') }}">
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="mx-auto max-w-7xl py-6 px-4 sm:px-8 mb-24 mt-32 text-center pt-16 pb-16">
|
<div class="mx-auto max-w-7xl py-6 px-4 sm:px-8 mb-24 mt-32 text-center pt-16 pb-16">
|
||||||
<img class="inline max-w-sm w-full px-4" src="{{ Vite::asset('resources/assets/images/Icons/404-grafik.svg') }}">
|
@yield('image')
|
||||||
<h1 class="font-scarletwood text-hellgruen text-[100px] leading-[100px] mt-8">404</h1>
|
<h1 class="font-scarletwood text-hellgruen text-[100px] leading-[100px] mt-8">@yield('code', __('Oh no'))</h1>
|
||||||
<p class="font-scarletwood text-hellgruen">{{ __('We could not find the page') }}</p>
|
<p class="font-scarletwood text-hellgruen">@yield('message')</p>
|
||||||
<a href="/" class="button brown inline-flex items-center px-4 my-2 mt-12 mr-6 text-sm text-white">
|
<p class="font-scarletwood text-hellgruen">@yield('submessage')</p>
|
||||||
<span>{{ __('Back to home page') }}</span>
|
<a href="{{ app('router')->has('home') ? route('home') : url('/') }}" class="button brown inline-flex items-center px-4 my-2 mt-12 mr-6 text-sm text-white">
|
||||||
|
<span>{{ __('Go to page :page', [
|
||||||
|
'page' => __('home')
|
||||||
|
]) }}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
use App\Http\Controllers\Bo\ConceptController;
|
use App\Http\Controllers\Bo\ConceptController;
|
||||||
use App\Http\Controllers\Bo\DashboardController;
|
use App\Http\Controllers\Bo\DashboardController;
|
||||||
use App\Http\Controllers\Bo\HomeController;
|
use App\Http\Controllers\Bo\HomeController;
|
||||||
|
use App\Http\Controllers\Bo\NewsController;
|
||||||
use App\Http\Controllers\Bo\RangeController;
|
use App\Http\Controllers\Bo\RangeController;
|
||||||
use App\Http\Controllers\Bo\ProductController;
|
use App\Http\Controllers\Bo\ProductController;
|
||||||
use App\Http\Controllers\Bo\RecipeController;
|
use App\Http\Controllers\Bo\RecipeController;
|
||||||
|
|
@ -54,6 +55,13 @@ Route::prefix('bo')
|
||||||
->withoutMiddleware('htmlsanitize')
|
->withoutMiddleware('htmlsanitize')
|
||||||
->middleware(['htmlsanitize:part1_text_1,part1_text_2,part1_text_3,part2_text']);
|
->middleware(['htmlsanitize:part1_text_1,part1_text_2,part1_text_3,part2_text']);
|
||||||
|
|
||||||
|
// * NEWS
|
||||||
|
Route::resource('news', NewsController::class)->except(['show'])
|
||||||
|
->withoutMiddleware('htmlsanitize')
|
||||||
|
->middleware(['htmlsanitize:content']);
|
||||||
|
Route::post('/news/{news}/change-order', [NewsController::class, 'changeOrder'])
|
||||||
|
->name('news.change-order');
|
||||||
|
|
||||||
// * CONCEPTS
|
// * CONCEPTS
|
||||||
Route::resource('concepts', ConceptController::class)->except(['show'])
|
Route::resource('concepts', ConceptController::class)->except(['show'])
|
||||||
->withoutMiddleware('htmlsanitize')
|
->withoutMiddleware('htmlsanitize')
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
use App\Http\Controllers\Fo\ConceptController;
|
use App\Http\Controllers\Fo\ConceptController;
|
||||||
use App\Http\Controllers\Fo\ContactController;
|
use App\Http\Controllers\Fo\ContactController;
|
||||||
use App\Http\Controllers\Fo\HomeController;
|
use App\Http\Controllers\Fo\HomeController;
|
||||||
|
use App\Http\Controllers\Fo\NewsController;
|
||||||
use App\Http\Controllers\Fo\ProductController;
|
use App\Http\Controllers\Fo\ProductController;
|
||||||
use App\Http\Controllers\Fo\RecipeController;
|
use App\Http\Controllers\Fo\RecipeController;
|
||||||
use App\Http\Controllers\Fo\StoreController;
|
use App\Http\Controllers\Fo\StoreController;
|
||||||
|
|
@ -30,6 +31,13 @@ Route::namespace('\App\Http\Controllers\Fo')->middleware(['throttle:credentials'
|
||||||
[ProductController::class, 'show']
|
[ProductController::class, 'show']
|
||||||
)->name('product.show');
|
)->name('product.show');
|
||||||
|
|
||||||
|
// * NEWS
|
||||||
|
Route::get($trans->uri('news'), [NewsController::class, 'index'])->name('news.index');
|
||||||
|
Route::get(
|
||||||
|
$trans->uri('news/{publishedNews:slug}'),
|
||||||
|
[NewsController::class, 'show']
|
||||||
|
)->name('news.show');
|
||||||
|
|
||||||
Route::get($trans->uri('recipes'), [RecipeController::class, 'index'])->name('recipes.index');
|
Route::get($trans->uri('recipes'), [RecipeController::class, 'index'])->name('recipes.index');
|
||||||
|
|
||||||
Route::get(
|
Route::get(
|
||||||
|
|
@ -62,5 +70,4 @@ Route::namespace('\App\Http\Controllers\Fo')->middleware(['throttle:credentials'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Route::fallback(\CodeZero\LocalizedRoutes\Controllers\FallbackController::class);
|
Route::fallback(\CodeZero\LocalizedRoutes\Controllers\FallbackController::class);
|
||||||
|
|
|
||||||
138
tests/Feature/Bo/StoresTest.php
Normal file
138
tests/Feature/Bo/StoresTest.php
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Bo;
|
||||||
|
|
||||||
|
use App\Models\Store;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Foundation\Testing\WithFaker;
|
||||||
|
use Tests\TestCase;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class StoresTest extends TestCase
|
||||||
|
{
|
||||||
|
// FIXME : Test need to be logged for requesting
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test CRUD Index is OK
|
||||||
|
*/
|
||||||
|
public function test_index_ok(): void
|
||||||
|
{
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($user, 'backend')->get(\route('bo.stores.index'));
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test CRUD Store is OK
|
||||||
|
*/
|
||||||
|
public function test_store_ok(): void
|
||||||
|
{
|
||||||
|
$user = User::factory()->create();
|
||||||
|
$store = Store::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($user, 'backend')
|
||||||
|
->post(\route('bo.stores.store'), $store->toArray());
|
||||||
|
|
||||||
|
$response->assertRedirect();
|
||||||
|
$response->assertSessionHas('success');
|
||||||
|
$response->assertSessionHasNoErrors();
|
||||||
|
// FIXME : Test DB presence
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test CRUD Store is NOK
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @dataProvider invalidsStores
|
||||||
|
*/
|
||||||
|
public function test_store_nok($invalidData, $invalidFields): void
|
||||||
|
{
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($user, 'backend')
|
||||||
|
->post(\route('bo.stores.store'), $invalidData);
|
||||||
|
|
||||||
|
$response->assertRedirect();
|
||||||
|
$response->assertSessionHasErrors($invalidFields);
|
||||||
|
$response->assertInvalid($invalidFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function invalidsStores(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'state.required' => [
|
||||||
|
['state' => null],
|
||||||
|
['state']
|
||||||
|
],
|
||||||
|
'state.string' => [
|
||||||
|
['state' => null],
|
||||||
|
['state']
|
||||||
|
],
|
||||||
|
'state.min' => [
|
||||||
|
['state' => Str::random(2)],
|
||||||
|
['state']
|
||||||
|
],
|
||||||
|
'state.max' => [
|
||||||
|
['state' => Str::random(256)],
|
||||||
|
['state']
|
||||||
|
],
|
||||||
|
'type_id.required' => [
|
||||||
|
['type_id' => null],
|
||||||
|
['type_id']
|
||||||
|
],
|
||||||
|
'type_id.exists' => [
|
||||||
|
['type_id' => 100000000],
|
||||||
|
['type_id']
|
||||||
|
],
|
||||||
|
'street.required' => [
|
||||||
|
['street' => null],
|
||||||
|
['street']
|
||||||
|
],
|
||||||
|
'street.string' => [
|
||||||
|
['street' => null],
|
||||||
|
['street']
|
||||||
|
],
|
||||||
|
'street.min' => [
|
||||||
|
['street' => Str::random(2)],
|
||||||
|
['street']
|
||||||
|
],
|
||||||
|
'street.max' => [
|
||||||
|
['street' => Str::random(256)],
|
||||||
|
['street']
|
||||||
|
],
|
||||||
|
'zipcode.required' => [
|
||||||
|
['zipcode' => null],
|
||||||
|
['zipcode']
|
||||||
|
],
|
||||||
|
'zipcode.min' => [
|
||||||
|
['zipcode' => ''],
|
||||||
|
['zipcode']
|
||||||
|
],
|
||||||
|
'zipcode.max' => [
|
||||||
|
['zipcode' => Str::random(6)],
|
||||||
|
['zipcode']
|
||||||
|
],
|
||||||
|
'city.required' => [
|
||||||
|
['city' => null],
|
||||||
|
['city']
|
||||||
|
],
|
||||||
|
'city.string' => [
|
||||||
|
['city' => null],
|
||||||
|
['city']
|
||||||
|
],
|
||||||
|
'city.min' => [
|
||||||
|
['city' => Str::random(2)],
|
||||||
|
['city']
|
||||||
|
],
|
||||||
|
'city.max' => [
|
||||||
|
['city' => Str::random(256)],
|
||||||
|
['city']
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue