1
0

Filters handling

This commit is contained in:
Richard Dern 2024-04-25 15:44:29 +02:00
parent 32e6c4dae1
commit d6542a09b8
10 changed files with 412 additions and 46 deletions

View File

@ -10,6 +10,8 @@ class BundleRendererServiceProvider extends ServiceProvider
protected array $bundleRenderers = [
\App\Services\BundleRenderers\Renderers\DossiersListRenderer::class,
\App\Services\BundleRenderers\Renderers\DossierRenderer::class,
\App\Services\BundleRenderers\Renderers\DateBasedListRenderer::class,
\App\Services\BundleRenderers\Renderers\ProductBasedListRenderer::class,
];
/**

View File

@ -20,6 +20,16 @@ public function __construct(protected Bundle $bundle)
$this->shareCommonDataWithView();
}
/**
* Renders a complete HTML view of the bundle
*/
public function render()
{
$this->prepareRender();
return view('article', $this->viewData);
}
/**
* Renders a card HTML view of the bundle, suitable to display in lists
*/
@ -153,6 +163,12 @@ protected function handlePagination()
];
data_set($this->viewData, 'pagination', $data);
$this->handleFilters($subBundles);
}
protected function handleFilters($subBundles)
{
}
protected function collectSubBundles()

View File

@ -0,0 +1,172 @@
<?php
namespace App\Services\BundleRenderers\Renderers;
use App\Classes\Bundle;
use Carbon\Carbon;
class DateBasedListRenderer extends ListRenderer
{
/**
* Renders a complete HTML view of the bundle
*/
public function render()
{
$this->prepareRender();
$parts = preg_split('#/#', $this->bundle->getPath(), -1, PREG_SPLIT_NO_EMPTY);
$count = count($parts);
switch ($count) {
case 2:
// A year is specified
$date = sprintf('%s-%s-%s', $parts[1], '01', '01');
$date = Carbon::parse($date);
$articleTitle = $date->isoFormat('YYYY');
$siteTitle = sprintf('Articles publiés en %s', $date->isoFormat('YYYY'));
break;
case 3:
// A month is specified
$date = sprintf('%s-%s-%s', $parts[1], $parts[2], '01');
$date = Carbon::parse($date);
$articleTitle = $date->isoFormat('MMMM YYYY');
$siteTitle = sprintf('Articles publiés en %s %s', $date->isoFormat('MMMM'), $date->isoFormat('YYYY'));
break;
case 4:
// A day is specified
$date = sprintf('%s-%s-%s', $parts[1], $parts[2], $parts[3]);
$date = Carbon::parse($date);
$articleTitle = $date->isoFormat('DD MMMM YYYY');
$siteTitle = sprintf('Articles publiés le %s %s %s', $date->isoFormat('DD'), $date->isoFormat('MMMM'), $date->isoFormat('YYYY'));
break;
}
if (!empty($articleTitle)) {
data_set($this->viewData, 'articleTitle', $articleTitle);
data_set($this->viewData, 'siteTitle', $siteTitle);
}
return view('article', $this->viewData);
}
/**
* Return a boolean value indicating if this creator in particular can
* create bundles for specified section
*/
public static function handles(Bundle $bundle): bool
{
$parts = preg_split('#/#', $bundle->getPath(), -1, PREG_SPLIT_NO_EMPTY);
$count = count($parts);
$sections = ['blog', 'liens-interessants'];
return $count > 0
&& in_array($parts[0], $sections)
&& $count < 5;
}
protected function handleFilters($subBundles)
{
$url = $this->bundle->getPath();
$parts = preg_split('#/#', $url, -1, PREG_SPLIT_NO_EMPTY);
// $parts[0] is section
$selectedYear = $parts[1] ?? null;
$selectedMonth = $parts[2] ?? null;
$selectedDay = $parts[3] ?? null;
$filters = [
'Année' => [
'values' => [],
'selected' => $selectedYear ?? 'Toutes',
'visible' => true,
],
'Mois' => [
'values' => [],
'selected' => $selectedMonth ?? 'Tous',
'visible' => $selectedYear !== null,
],
'Jour' => [
'values' => [],
'selected' => $selectedDay ?? 'Tous',
'visible' => $selectedMonth !== null,
],
];
$prefix = sprintf('%s/', $parts[0]);
if ($selectedYear) {
$prefix .= $selectedYear . '/';
if ($selectedMonth) {
$prefix .= $selectedMonth . '/';
if ($selectedDay) {
$prefix .= $selectedDay . '/';
}
}
}
foreach ($subBundles as $subBundle) {
$fileParts = preg_split('#/#', $subBundle, -1, PREG_SPLIT_NO_EMPTY);
// $parts[0] is section
$year = $fileParts[1] ?? null;
$month = $fileParts[2] ?? null;
$day = $fileParts[3] ?? null;
if ($year) {
$filters['Année']['values'][$year] = [
'title' => $year,
'path' => sprintf('/%s/%s/', $parts[0], $year),
];
if ($month && $selectedYear !== null) {
$date = Carbon::parse(sprintf('%s-%s-%s', $year, $month, '01'));
$monthName = $date->isoFormat('MMMM');
$filters['Mois']['values'][$month] = [
'title' => $monthName,
'path' => sprintf('/%s/%s/%s/', $parts[0], $year, $month),
];
if ($day && $selectedMonth !== null) {
$filters['Jour']['values'][$day] = [
'title' => $day,
'path' => sprintf('/%s/%s/%s/%s/', $parts[0], $year, $month, $day),
];
}
}
}
}
ksort($filters['Année']['values']);
ksort($filters['Mois']['values']);
ksort($filters['Jour']['values']);
$filters['Année']['values'] = [
'Toutes' => [
'title' => 'Toutes',
'path' => sprintf('/%s/', $parts[0]),
],
]
+ $filters['Année']['values'];
$filters['Mois']['values'] = [
'Tous' => [
'title' => 'Tous',
'path' => sprintf('/%s/%s/', $parts[0], $selectedYear),
],
]
+ $filters['Mois']['values'];
$filters['Jour']['values'] = [
'Tous' => [
'title' => 'Tous',
'path' => sprintf('/%s/%s/%s/', $parts[0], $selectedYear, $selectedMonth),
],
]
+ $filters['Jour']['values'];
data_set($this->viewData['pagination'], 'filters', $filters);
}
}

View File

@ -7,16 +7,6 @@
class DossiersListRenderer extends BaseRenderer
{
/**
* Renders a complete HTML view of the bundle
*/
public function render()
{
$this->prepareRender();
return view('article', $this->viewData);
}
/**
* Return a boolean value indicating if this creator in particular can
* create bundles for specified section

View File

@ -6,16 +6,6 @@
class ListRenderer extends BaseRenderer
{
/**
* Renders a complete HTML view of the bundle
*/
public function render()
{
$this->prepareRender();
return view('article', $this->viewData);
}
/**
* Return a boolean value indicating if this creator in particular can
* create bundles for specified section

View File

@ -0,0 +1,144 @@
<?php
namespace App\Services\BundleRenderers\Renderers;
use App\Classes\Bundle;
class ProductBasedListRenderer extends ListRenderer
{
/**
* Renders a complete HTML view of the bundle
*/
public function render()
{
$this->prepareRender();
$parts = preg_split('#/#', $this->bundle->getPath(), -1, PREG_SPLIT_NO_EMPTY);
$count = count($parts);
switch ($count) {
case 2:
// A brand is specified
$brandPath = sprintf('%s/%s', 'collections', $parts[1]);
$brandBundle = new Bundle($brandPath, $this->bundle->getDisk());
$articleTitle = $brandBundle->getArticleTitle();
$siteTitle = sprintf('Objets de ma collection %s', $articleTitle);
break;
case 3:
// A collection is specified
$brandPath = sprintf('%s/%s', 'collections', $parts[1]);
$brandBundle = new Bundle($brandPath, $this->bundle->getDisk());
$collectionPath = sprintf('%s/%s/%s', 'collections', $parts[1], $parts[2]);
$collectionBundle = new Bundle($collectionPath, $this->bundle->getDisk());
$articleTitle = sprintf('%s %s', $brandBundle->getArticleTitle(), $collectionBundle->getArticleTitle());
$siteTitle = sprintf('Objets de ma collection %s', $articleTitle);
break;
}
if (!empty($articleTitle)) {
data_set($this->viewData, 'articleTitle', $articleTitle);
data_set($this->viewData, 'siteTitle', $siteTitle);
}
return view('article', $this->viewData);
}
/**
* Return a boolean value indicating if this creator in particular can
* create bundles for specified section
*/
public static function handles(Bundle $bundle): bool
{
$parts = preg_split('#/#', $bundle->getPath(), -1, PREG_SPLIT_NO_EMPTY);
$count = count($parts);
$sections = ['collections'];
return $count > 0
&& in_array($parts[0], $sections)
&& $count < 4;
}
protected function handleFilters($subBundles)
{
$url = $this->bundle->getPath();
$parts = preg_split('#/#', $url, -1, PREG_SPLIT_NO_EMPTY);
// $parts[0] is section
$selectedBrand = $parts[1] ?? null;
$selectedCollection = $parts[2] ?? null;
$filters = [
'Marque' => [
'values' => [],
'selected' => $selectedBrand ?? 'Toutes',
'visible' => true,
],
'Collection' => [
'values' => [],
'selected' => $selectedCollection ?? 'Toutes',
'visible' => $selectedBrand !== null,
],
];
$prefix = sprintf('%s/', $parts[0]);
if ($selectedBrand) {
$prefix .= $selectedBrand . '/';
if ($selectedCollection) {
$prefix .= $selectedCollection . '/';
}
}
foreach ($subBundles as $subBundle) {
$fileParts = preg_split('#/#', $subBundle, -1, PREG_SPLIT_NO_EMPTY);
// $parts[0] is section
$brand = $fileParts[1] ?? null;
$collection = $fileParts[2] ?? null;
if ($brand) {
$brandPath = sprintf('/%s/%s/', $parts[0], $brand);
$bundle = new Bundle($brandPath, $this->bundle->getDisk());
$brandName = $bundle->getArticleTitle();
$filters['Marque']['values'][$brand] = [
'title' => $brandName,
'path' => $brandPath,
];
if ($collection && $selectedBrand !== null) {
$collectionPath = sprintf('/%s/%s/%s/', $parts[0], $brand, $collection);
$bundle = new Bundle($collectionPath, $this->bundle->getDisk());
$collectionName = $bundle->getArticleTitle();
$filters['Collection']['values'][$collection] = [
'title' => $collectionName,
'path' => $collectionPath,
];
}
}
}
ksort($filters['Marque']['values']);
ksort($filters['Collection']['values']);
$filters['Marque']['values'] = [
'Toutes' => [
'title' => 'Toutes',
'path' => sprintf('/%s/', $parts[0]),
],
]
+ $filters['Marque']['values'];
$filters['Collection']['values'] = [
'Toutes' => [
'title' => 'Toutes',
'path' => sprintf('/%s/%s/', $parts[0], $selectedBrand),
],
]
+ $filters['Collection']['values'];
data_set($this->viewData['pagination'], 'filters', $filters);
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\View\Components;
use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class PaginationFilters extends Component
{
/**
* Create a new component instance.
*/
public function __construct()
{
//
}
/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.pagination-filters');
}
}

View File

@ -44,7 +44,7 @@ .paginator {
.paginator-filters {
grid-column: 1 / 4;
font-size: .6rem;
font-size: .8rem;
display: flex;
align-items: center;
gap: 1rem;

View File

@ -0,0 +1,14 @@
<div class="paginator-filters">
<span>Filtrer par :</span>
@foreach($filters as $name => $options)
<details class="drop {{ $orientation }}">
<summary>{{ $name }}</summary>
<nav>
@foreach($options['values'] as $name => $data)
<a href="{{ $data['path'] }}" class="{{ !empty($options['selected']) && $options['selected'] == $name ? 'selected' : '' }}">{{ $data['title'] }}</a>
@endforeach
</nav>
</details>
@endforeach
</div>

View File

@ -1,13 +1,19 @@
@props(['orientation'])
@if ($totalPages > 1)
<div class="paginator">
@if ($totalPages > 1 || isset($filters))
<div class="paginator">
@if($orientation === 'up')
@isset($filters)
@include('components.pagination-filters', ['filters' => $filters, 'orientation' => $orientation])
@endisset
@endif
@if ($totalPages > 1)
@if ($currentPage > 1)
<div class="left">
<a href="{{ $root }}page/{{ $currentPage - 1 }}/" title="Articles plus récents">&larr;</a>
</div>
@endif
@if ($totalPages > 1)
<details class="drop {{ $orientation }}">
<summary>{{ $currentPage }}</summary>
<nav>
@ -18,12 +24,18 @@
@endfor
</nav>
</details>
@endif
@if ($currentPage < $totalPages)
<div class="right">
<a href="{{ $root }}page/{{ $currentPage + 1 }}/" title="Articles plus anciens">&rarr;</a>
</div>
@endif
</div>
@endif
@if($orientation === 'down')
@isset($filters)
@include('components.pagination-filters', ['filters' => $filters, 'orientation' => $orientation])
@endisset
@endif
</div>
@endif