Drobnosti GUI + sloupeček Stav v Obvodech
parent
0e18b46a15
commit
acbdb6ba83
|
|
@ -61,6 +61,7 @@
|
|||
<a class='nav-link' n:href=":Sign:out">Odhlásit</a>
|
||||
{else}
|
||||
<a class='nav-link' n:href=':Home:'>Home</a>
|
||||
<a class='nav-link' n:href=':Nastaveni:'>Nastavení</a>
|
||||
<a class='nav-link' n:href=":Sign:in, backlink: (isset($navrat) ? $navrat : '')">Přihlásit</a>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,13 +5,20 @@ declare(strict_types=1);
|
|||
namespace App\Presentation\Nastaveni;
|
||||
|
||||
use App\Core\MapovyPodklad;
|
||||
use App\Presentation\BasePresenter;
|
||||
use Nette\Application\UI\Form;
|
||||
use Nette\Application\UI\Presenter;
|
||||
use Nette\Utils\ArrayHash;
|
||||
|
||||
|
||||
final class NastaveniPresenter extends BasePresenter
|
||||
final class NastaveniPresenter extends Presenter
|
||||
{
|
||||
public function beforeRender(): void
|
||||
{
|
||||
if (!$this->getUser()->isLoggedIn()) {
|
||||
$this->template->navrat = $this->storeRequest();
|
||||
}
|
||||
}
|
||||
|
||||
protected function createComponentPodkladForm(): Form
|
||||
{
|
||||
$form = new Form;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ namespace App\Presentation\Obvod;
|
|||
use App\Model\ObvodFacade;
|
||||
use App\Model\ZaznamFacade;
|
||||
use App\Presentation\BasePresenter;
|
||||
use App\Presentation\Mapa\MapaPresenter;
|
||||
use Nette;
|
||||
use Nette\Application\UI\Form;
|
||||
use Nette\Application\UI\Multiplier;
|
||||
|
|
@ -40,9 +41,21 @@ final class ObvodPresenter extends BasePresenter
|
|||
|
||||
public function renderList(): void
|
||||
{
|
||||
$stari = $this->zaznam->getStariObvodu();
|
||||
$obvody = [];
|
||||
foreach ($this->obvod->getObvody($this->skupina) as $obvod) {
|
||||
$info = $stari[(int) $obvod->CISLO] ?? null;
|
||||
$obvody[] = (object) [
|
||||
'ID' => (int) $obvod->ID,
|
||||
'CISLO' => (int) $obvod->CISLO,
|
||||
'NAZEV' => (string) $obvod->NAZEV,
|
||||
'stav' => $this->stavObvodu($info),
|
||||
];
|
||||
}
|
||||
|
||||
$this->template->skupina = $this->skupina;
|
||||
$this->template->skupiny = $this->obvod->getSkupiny();
|
||||
$this->template->obvody = $this->obvod->getObvody($this->skupina);
|
||||
$this->template->obvody = $obvody;
|
||||
}
|
||||
|
||||
public function renderView(int $id = null): void
|
||||
|
|
@ -198,6 +211,86 @@ final class ObvodPresenter extends BasePresenter
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{mesice: int|null, probiha: bool, prideleni: int|null}|null $info
|
||||
* @return object{popisek: string, barva: string, text: string}
|
||||
*/
|
||||
private function stavObvodu(?array $info): object
|
||||
{
|
||||
if ($info !== null && $info['probiha']) {
|
||||
$mesice = $info['prideleni'];
|
||||
return (object) [
|
||||
'popisek' => 'Rozpracován ' . $this->textMesicu($mesice),
|
||||
'barva' => $this->cssBarva($this->barvaStari($mesice, MapaPresenter::STUPNICE_PRIDELENI)),
|
||||
'text' => $this->cssBarva($this->barvaTextu($mesice, MapaPresenter::STUPNICE_PRIDELENI)),
|
||||
];
|
||||
}
|
||||
|
||||
if ($info !== null && $info['mesice'] !== null) {
|
||||
return (object) [
|
||||
'popisek' => 'Nepropracován ' . $this->textMesicu($info['mesice']),
|
||||
'barva' => $this->cssBarva($this->barvaStari($info['mesice'], MapaPresenter::STUPNICE_MESICU)),
|
||||
'text' => $this->cssBarva($this->barvaTextu($info['mesice'], MapaPresenter::STUPNICE_MESICU)),
|
||||
];
|
||||
}
|
||||
|
||||
return (object) [
|
||||
'popisek' => 'Bez záznamu',
|
||||
'barva' => '#b0bec5',
|
||||
'text' => '#1a1a1a',
|
||||
];
|
||||
}
|
||||
|
||||
private function cssBarva(string $barva): string
|
||||
{
|
||||
if (preg_match('/^rgb\((?:25[0-5]|2[0-4]\d|1?\d?\d),(?:25[0-5]|2[0-4]\d|1?\d?\d),(?:25[0-5]|2[0-4]\d|1?\d?\d)\)$/', $barva)) {
|
||||
return $barva;
|
||||
}
|
||||
if (preg_match('/^#[0-9a-fA-F]{3}(?:[0-9a-fA-F]{3})?$/', $barva)) {
|
||||
return $barva;
|
||||
}
|
||||
|
||||
return '#b0bec5';
|
||||
}
|
||||
|
||||
private function textMesicu(?int $mesice): string
|
||||
{
|
||||
return $mesice === null ? '—' : $mesice . ' měs.';
|
||||
}
|
||||
|
||||
private function barvaStari(?int $mesice, int $max): string
|
||||
{
|
||||
$t = $mesice === null || $max <= 0 ? 1 : max(0, min($mesice / $max, 1));
|
||||
$zelena = [27, 158, 62];
|
||||
$zluta = [230, 184, 0];
|
||||
$cervena = [198, 40, 40];
|
||||
$kanaly = $t < 0.5
|
||||
? $this->mixBarvy($zelena, $zluta, $t / 0.5)
|
||||
: $this->mixBarvy($zluta, $cervena, ($t - 0.5) / 0.5);
|
||||
|
||||
return 'rgb(' . implode(',', $kanaly) . ')';
|
||||
}
|
||||
|
||||
private function barvaTextu(?int $mesice, int $max): string
|
||||
{
|
||||
$t = $mesice === null || $max <= 0 ? 1 : max(0, min($mesice / $max, 1));
|
||||
return $t > 0.72 ? '#fff' : '#1a1a1a';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{0: int, 1: int, 2: int} $a
|
||||
* @param array{0: int, 1: int, 2: int} $b
|
||||
* @return array{0: int, 1: int, 2: int}
|
||||
*/
|
||||
private function mixBarvy(array $a, array $b, float $t): array
|
||||
{
|
||||
return [
|
||||
(int) round($a[0] + ($b[0] - $a[0]) * $t),
|
||||
(int) round($a[1] + ($b[1] - $a[1]) * $t),
|
||||
(int) round($a[2] + ($b[2] - $a[2]) * $t),
|
||||
];
|
||||
}
|
||||
|
||||
private function obvodId(): int
|
||||
{
|
||||
$id = $this->getParameter('id');
|
||||
|
|
|
|||
|
|
@ -19,14 +19,16 @@
|
|||
<tr>
|
||||
<th scope="col">Číslo</th>
|
||||
<th scope="col">Název</th>
|
||||
<th scope="col">Stav</th>
|
||||
<th scope="col">Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $obvody as $obvod}
|
||||
<tr>
|
||||
<td data-popisek="Číslo">{$obvod->CISLO}</td>
|
||||
<td data-popisek="Číslo"><span class="tabulka-cislo">{$obvod->CISLO}</span></td>
|
||||
<td data-popisek="Název">{$obvod->NAZEV}</td>
|
||||
<td data-popisek="Stav"><span class="stav-badge" style="background: {$obvod->stav->barva|noescape}; color: {$obvod->stav->text|noescape}">{$obvod->stav->popisek}</span></td>
|
||||
<td class="bunka-akce" data-popisek="Akce">
|
||||
<div class="akce-radek">
|
||||
<a n:href=":Obvod:view id:$obvod->ID" class="tlacitko">Otevřít</a>
|
||||
|
|
|
|||
|
|
@ -786,6 +786,35 @@ body:has(#map[data-max]) {
|
|||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.tabulka-cislo {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.75rem;
|
||||
height: 2.75rem;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #1d4f91;
|
||||
background: #2652a8;
|
||||
color: #fff;
|
||||
font-size: 1.05rem;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
box-shadow: 0 4px 10px rgba(29, 79, 145, 0.28);
|
||||
}
|
||||
|
||||
.stav-badge {
|
||||
display: inline-block;
|
||||
padding: 0.28rem 0.7rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.22);
|
||||
font-size: 0.82rem;
|
||||
font-weight: 800;
|
||||
line-height: 1.2;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
.bunka-akce .akce-radek {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
|
|
|||
Loading…
Reference in New Issue