Skip to content

Commit

Permalink
Merge pull request #56 from fykosak/nicer-results-filtering
Browse files Browse the repository at this point in the history
Implement nicer results filtering
  • Loading branch information
vanekm authored Nov 18, 2023
2 parents 92d73c9 + 95b26db commit 6d5dc3e
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 55 deletions.
11 changes: 8 additions & 3 deletions app/Components/TeamResults/TeamResultsComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ protected function passesCountryFilter(ModelTeam $team): bool

return false;
}

/**
* @throws \Throwable
*/
Expand Down Expand Up @@ -151,17 +151,22 @@ protected function createComponentFilterForm(): Form

// countries
arsort($countryISOs);

$countryISOContainer = $form->addContainer('country_iso');
foreach ($countryISOs as $countryISO => $count) {
$countryISOContainer->addCheckbox($countryISO, sprintf(_('%s:%s participants'), $countryISO, $count));
}
$countryISOContainer->addCheckbox($countryISO, $countryISO)
->setOption('count', $count);
}


$form->addButton('reset')->setHtmlAttribute('type', 'reset')->setHtmlAttribute('class', 'btn btn-dark');

$form->addSubmit('applyFilters', 'Apply')->setHtmlAttribute('class', 'btn btn-primary');

$form->onSuccess[] = fn(Form $form) => $this->filterData = $form->getValues('array');

$form->setRenderer(new \App\Renderers\CustomFormRenderer());

return $form;
}
}
76 changes: 75 additions & 1 deletion app/Components/TeamResults/styles.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.team-results-control {
column-count: 4;
// column-count: 4;

form table tr {
@extend .form-check;
Expand Down Expand Up @@ -29,3 +29,77 @@
background-color: #00000010;
}
}

.team-results-control form {
display: flex;
flex-wrap: wrap;
align-items: center;
}

/* Container for each box */
.country-container {
display: flex;
align-items: center;
padding: 10px;
// border: 3px solid $primary-color;
background-color: $primary-color;
color: $text-on-primary;

input {
width: 20px;
height: 20px;
margin-right: 15px;
margin-left: 5px;
}

.text-country-container{
// border-left: 3px solid $primary-color;
border-left: 3px solid $text-on-primary;
padding-left: 10px;
}

.flag-icon {
margin-right: 5px; /* Space between flag and country code */
border: 1px solid black;
}
}


.button-collapse-header{
width: 100%;
text-align: center;
margin-top: 10px;
}

.toggle-content{
border: 3px solid $primary-color;
}

// .country-container {
// display: flex;
// align-items: flex-start;
// width: 200px; /* Adjust width as needed */
// border: 1px solid $primary-color; /* Border styling */
// background-color: $primary-color;
// color: $text-on-primary;
// padding: 8px;
// margin: 5px;
// vertical-align: top; /* To ensure blocks align at the top */
// box-sizing: border-box; /* This ensures that padding and border are included in the total width */
// text-align: center; /* Center text and flag icon */
// }


// .country-container.special {
// margin-bottom: 20px; /* This will give a larger gap after the "One member teams only" checkbox. */
// }

// .flag-icon {
// margin-right: 5px; /* Space between flag and country name */
// }

// input[type="checkbox"] {
// float: center; /* Position checkbox to the left */
// margin-right: 5px; /* Space between checkbox and flag */
// vertical-align: middle;
// }
126 changes: 75 additions & 51 deletions app/Components/TeamResults/teamResults.latte
Original file line number Diff line number Diff line change
@@ -1,61 +1,85 @@
{layout '../@layout.latte'}
{varType string $lang}
{block content}
<div class="team-results-control">
{control filterForm}

<div class="row">
<div class="col-12">

<!-- The button that triggers the collapsible content -->
<button class="btn btn-primary-inverted button-collapse-header" type="button" data-bs-toggle="collapse"
data-bs-target="#resultFilters" aria-expanded="false" aria-controls="resultFilters">
Toggle filters
</button>


<!-- The collapsible content -->
<div class="collapse toggle-content px-3" id="resultFilters">
{control filterForm}
</div>
</div>
</div>
<div class="team-results-control">
{foreach $teams AS $category => $teamsForCategory}
<h2 id="{$category}">{$category}</h2>
<button class="btn btn-primary button-collapse-header" type="button" data-bs-toggle="collapse"
data-bs-target="#collapse-category-{$category}" aria-expanded="false" aria-controls="collapse-category-{$category}">
Category {$category}
</button>

<div class="results-first-row results-header">
<div class="result-column" style="width: 5rem">#</div>
<div class="result-column" style="flex-grow: 1">{_'Team'}</div>
<div class="result-column" style="width: 5rem">{_'Points'}</div>
<div class="result-column" style="width: 5rem">{_'Rank total'}</div>
</div>
{do usort($teamsForCategory, fn($a, $b) => ($a->rankCategory ? $a->rankCategory : PHP_INT_MAX) <=> ($b->rankCategory ? $b->rankCategory : PHP_INT_MAX))}
{foreach $teamsForCategory AS $index => $team}
<div class="results-row">
<div class="results-first-row">
{varType Fykosak\NetteFKSDBDownloader\ORM\Models\ModelTeam $team}
<div class="result-column"
style="width: 5rem">{if $team->status === "disqualified"}DNQ{else}{$team->rankCategory}.{/if}</div>
<div class="result-column" style="flex-grow: 1"><strong>{$team->name}</strong></div>
<div class="result-column"
style="width: 5rem">{if $team->status === "disqualified"}{else}{$team->points}{/if}</div>
<div class="result-column"
style="width: 5rem">{if $team->status === "disqualified"}{else}{$team->rankTotal}.{/if}</div>
</div>
<div class="results-second-row">
<div class="result-column text-muted" style="flex-grow: 1; margin-left: 5rem; margin-right: 10rem">
{var $inSchool = 0}
{if $team->members && count($team->members)}
{do
$participants = $team->members;
usort($participants, fn($a, $b) => $a->schoolId <=> $b->schoolId)
}
{foreach $participants as $key => $participant}
{varType Fykosak\NetteFKSDBDownloader\ORM\Models\ModelParticipant $participant}
{$participant->name
}{do $inSchool++
}{if $iterator->isLast() || (!is_null($participants[$key + 1]) && $participant->schoolId != $participants[$key + 1]->schoolId)
}
<span class="text-muted"> ({if $inSchool > 1}{$inSchool}&nbsp;&times;&nbsp;{/if}{$participant->schoolName}{if ($participant->countryIso != "ZZ")} <span
class="flag-icon flag-icon-{$participant->countryIso|lower}"></span>{/if})</span>
{do $inSchool = 0
}{/if
}{if !$iterator->isLast()
}, {/if}
{/foreach}
{else}
{switch $lang}
{case cs}informace o členech týmu nejsou dostupné
{default}no info avaiable
{/switch}
{/if}
<!-- The collapsible content -->
<div class="collapse toggle-content" id="collapse-category-{$category}">
<!-- <h2 id="{$category}">{$category}</h2> -->

<div class="results-first-row results-header">
<div class="result-column" style="width: 5rem">#</div>
<div class="result-column" style="flex-grow: 1">{_'Team'}</div>
<div class="result-column" style="width: 5rem">{_'Points'}</div>
<div class="result-column" style="width: 5rem">{_'Rank total'}</div>
</div>
{do usort($teamsForCategory, fn($a, $b) => ($a->rankCategory ? $a->rankCategory : PHP_INT_MAX) <=> ($b->rankCategory ? $b->rankCategory : PHP_INT_MAX))}
{foreach $teamsForCategory AS $index => $team}
<div class="results-row">
<div class="results-first-row">
{varType Fykosak\NetteFKSDBDownloader\ORM\Models\ModelTeam $team}
<div class="result-column"
style="width: 5rem">{if $team->status === "disqualified"}DNQ{else}{$team->rankCategory}.{/if}</div>
<div class="result-column" style="flex-grow: 1"><strong>{$team->name}</strong></div>
<div class="result-column"
style="width: 5rem">{if $team->status === "disqualified"}{else}{$team->points}{/if}</div>
<div class="result-column"
style="width: 5rem">{if $team->status === "disqualified"}{else}{$team->rankTotal}.{/if}</div>
</div>
<div class="results-second-row">
<div class="result-column text-muted" style="flex-grow: 1; margin-left: 5rem; margin-right: 10rem">
{var $inSchool = 0}
{if $team->members && count($team->members)}
{do
$participants = $team->members;
usort($participants, fn($a, $b) => $a->schoolId <=> $b->schoolId)
}
{foreach $participants as $key => $participant}
{varType Fykosak\NetteFKSDBDownloader\ORM\Models\ModelParticipant $participant}
{$participant->name
}{do $inSchool++
}{if $iterator->isLast() || (!is_null($participants[$key + 1]) && $participant->schoolId != $participants[$key + 1]->schoolId)
}
<span class="text-muted"> ({if $inSchool > 1}{$inSchool}&nbsp;&times;&nbsp;{/if}{$participant->schoolName}{if ($participant->countryIso != "ZZ")} <span
class="flag-icon flag-icon-{$participant->countryIso|lower}"></span>{/if})</span>
{do $inSchool = 0
}{/if
}{if !$iterator->isLast()
}, {/if}
{/foreach}
{else}
{switch $lang}
{case cs}informace o členech týmu nejsou dostupné
{default}no info avaiable
{/switch}
{/if}
</div>
</div>
</div>
</div>
{/foreach}
{/foreach}
</div>
{/foreach}
{/block}
</div>
7 changes: 7 additions & 0 deletions app/Modules/Fol/Core/styles/layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ body {
color: $text-on-primary;
}

.btn-primary-inverted {
@extend .btn-primary;
color: $primary-color;
background-color: $text-on-primary;
}


.btn-outline {
@extend .btn-outline;
text-align: center;
Expand Down
56 changes: 56 additions & 0 deletions app/Renderers/CustomFormRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace App\Renderers;

use Nette\Forms\IFormRenderer;
use Nette;
use Nette\Forms\Form;
use Nette\Utils\Html;
use Latte\Engine;

class CustomFormRenderer implements IFormRenderer
{
private $latte;

public function __construct()
{
$this->latte = new Engine();
}

public function render(Form $form, $mode = null): string
{
$controls = [
'buttons' => [],
'countries' => [],
'special' => []
];

foreach ($form->getControls() as $control) {
if ($control instanceof Nette\Forms\Controls\Button) {
$controls['buttons'][] = [
'control' => $control,
'html' => $control->getControl()
];
} elseif ($control->getName() === 'OneMemberTeams') {
$controls['special'][] = [
'control' => $control,
'html' => $control->getControl()
];
} elseif ($control instanceof Nette\Forms\Controls\Checkbox) {
$controls['countries'][] = [
'control' => $control,
'html' => $control->getControlPart()->addAttributes(['class' => 'checkbox-input'])
];
}
}


// Pass controls to the template
$params = ['controls' => $controls];

ob_start();
$this->latte->render(__DIR__ . '/templates/formRender.latte', $params);
return ob_get_clean();
}

}
33 changes: 33 additions & 0 deletions app/Renderers/templates/formRender.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

<form>
<div class="row">
{foreach $controls['special'] as $item}
<div class="col-12 p-3">
<div class="country-container special">
{$item['html']}
</div>
</div>
{/foreach}
</div>
<div class="row">
{foreach $controls['countries'] as $item}
<div class="col-lg-3 col-md-4 p-3">
<div class="country-container">
{$item['html']}
<div class="text-country-container">
<span class="flag-icon flag-icon-{strtolower($item['control']->getName())}"></span>
{$item['control']->getCaption()}<br>
{$item['control']->getOption('count')} participants
</div>
</div>
</div>
{/foreach}
</div>
<div class="row">
<div class="col-12 py-3">
{foreach $controls['buttons'] as $item}
{$item['html']}
{/foreach}
</div>
</div>
</form>

0 comments on commit 6d5dc3e

Please sign in to comment.