Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions src/MultiFlexi/UiII/AppShell.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace MultiFlexi\UiII;

class AppShell extends \Ease\Html\DivTag
{
/**
* @var Sidebar Postranní panel.
*/
public Sidebar $sidebar;

/**
* @var \Ease\Html\MainTag Hlavní obsahová oblast.
*/
public \Ease\Html\MainTag $contentArea;

/**
* @var \Ease\Html\DivTag Kontejner s maximální šířkou pro obsah.
*/
public \Ease\Html\DivTag $pageMax;

public function __construct($properties = [])
{
parent::__construct(null, ['class' => 'app-shell'] + $properties);

// Vytvoření postranního panelu
$this->sidebar = new Sidebar();
$this->addItem($this->sidebar);

// Vytvoření hlavní obsahové oblasti
$this->contentArea = $this->addItem(new \Ease\Html\MainTag(null, ['class' => 'content-area']));
$this->pageMax = $this->contentArea->addItem(new \Ease\Html\DivTag(null, ['class' => 'page-max']));
}

/**
* Přidá obsah do hlavní části stránky.
*
* @param mixed $content Obsah k přidání.
*
* @return mixed
*/
public function addContent($content)
{
return $this->pageMax->addItem($content);
}
}
205 changes: 205 additions & 0 deletions src/MultiFlexi/UiII/RunTemplatePage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
<?php

declare(strict_types=1);

namespace MultiFlexi\UiII;

class RunTemplatePage extends \Ease\Html\DivTag
{
public function __construct()
{
parent::__construct();

// Header
$this->addItem($this->createHeader());

// Filters card
$this->addItem($this->createFiltersCard());

// Table + chart row
$row = $this->addItem(new \Ease\TWB4\Row());
$col1 = $row->addColumn('12');
$col1->addItem($this->createTableCard());
$col2 = $row->addColumn('12');
$col2->addItem($this->createChartCard());

// Footer actions
$this->addItem($this->createFooterActions());

// Modal
\Ease\TWB4\WebPage::singleton()->body->addItem($this->createDetailModal());
}

private function createHeader()
{
$header = new \Ease\Html\DivTag(null, ['class' => 'd-flex align-items-center mb-3']);
$toggleBtn = '<button class="btn btn-light mr-3 sidebar-toggle-btn"><i class="fas fa-bars"></i></button>';
$header->addItem($toggleBtn . '<div class="mr-auto"><h2 class="mb-0">Výpisy do Pohody <small class="text-muted d-block">925 – 5230011904</small></h2></div>');
$actions = $header->addItem(new \Ease\Html\DivTag(null, ['class' => 'card-header-actions']));
$actions->addItem(new \Ease\TWB4\SubmitButton('Spustit', 'primary', ['id' => 'btnRun']));
$actions->addItem(new \Ease\TWB4\LinkButton('?refresh=1', 'Obnovit', 'outline-secondary', ['id' => 'btnRefresh']));

return $header;
}

private function createFiltersCard()
{
$card = new \Ease\TWB4\Card(null, ['class' => 'mb-3']);
$form = '
<form class="filters form-row align-items-center">
<div class="form-group col-md-3">
<label class="sr-only" for="dateFrom">Datum od</label>
<input id="dateFrom" type="date" class="form-control" placeholder="Datum od">
</div>
<div class="form-group col-md-3">
<label class="sr-only" for="dateTo">Datum do</label>
<input id="dateTo" type="date" class="form-control" placeholder="Datum do">
</div>
<div class="form-group col-md-3">
<label class="sr-only" for="type">Typ</label>
<select id="type" class="custom-select">
<option value="">Typ transakce</option>
<option value="prijem">Příjem</option>
<option value="vydaj">Výdaj</option>
</select>
</div>
<div class="form-group col-md-2">
<label class="sr-only" for="q">Hledat</label>
<input id="q" type="text" class="form-control" placeholder="Hledat...">
</div>
<div class="form-group col-md-1 text-right">
<button type="button" class="btn btn-success btn-block">Použít</button>
</div>
<div class="w-100"></div>
<div class="form-group col-md-3 mt-2">
<label class="sr-only" for="amountFrom">Částka od</label>
<input id="amountFrom" type="number" class="form-control" placeholder="Částka od">
</div>
<div class="form-group col-md-3 mt-2">
<label class="sr-only" for="amountTo">Částka do</label>
<input id="amountTo" type="number" class="form-control" placeholder="Částka do">
</div>
</form>';
$card->addItem(new \Ease\TWB4\CardBody($form));

return $card;
}

private function createTableCard()
{
$table = '
<div class="table-wrap">
<table class="table table-striped table-hover table-sm mb-0">
<thead class="thead-light">
<tr>
<th style="width:160px">Datum</th>
<th>Protiúčet / Popis</th>
<th style="width:160px">Variabilní symbol</th>
<th style="width:120px">Částka</th>
<th style="width:140px">Stav</th>
<th style="width:120px" class="text-center">Akce</th>
</tr>
</thead>
<tbody>
<tr>
<td>13.4.2023</td>
<td>T-shirt s potiskem</td>
<td>123456</td>
<td class="amount-negative">-12,00</td>
<td><span class="badge badge-success">Exportováno</span></td>
<td class="text-center"><button class="btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#detailModal">Detail</button></td>
</tr>
<tr>
<td>21.3.2023</td>
<td>Trhovin lenyd</td>
<td>654321</td>
<td class="amount-negative">-20,00</td>
<td><span class="badge badge-secondary">Čeká</span></td>
<td class="text-center"><button class="btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#detailModal">Detail</button></td>
</tr>
<tr>
<td>31.3.2023</td>
<td>Počtávea</td>
<td>987654</td>
<td class="amount-positive">51,00</td>
<td><span class="badge badge-success">Exportováno</span></td>
<td class="text-center"><button class="btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#detailModal">Detail</button></td>
</tr>
</tbody>
</table>
</div>';

$card = new \Ease\TWB4\Card(null, ['class' => 'mb-3']);
$card->addItem(new \Ease\TWB4\CardBody($table));

return $card;
}

private function createChartCard()
{
$chartHeader = '
<div class="d-flex justify-content-between align-items-center mb-3">
<h5 class="mb-0">Statistiky za období</h5>
<div class="btn-group btn-group-sm" role="group" aria-label="Period">
<button class="btn btn-outline-secondary active">7 dní</button>
<button class="btn btn-outline-secondary">1 měsíc</button>
<button class="btn btn-outline-secondary">1 rok</button>
</div>
</div>';

$chartBody = '<canvas id="runsChart" height="120"></canvas>';
$card = new \Ease\TWB4\Card(null, ['class' => 'chart-card mb-4']);
$card->addItem(new \Ease\TWB4\CardBody($chartHeader.$chartBody));

return $card;
}

private function createFooterActions()
{
$footer = new \Ease\Html\DivTag(null, ['class' => 'd-flex justify-content-between align-items-center mt-3']);
$footer->addItem('<div class="small text-muted">Zobrazeno 1–20 z 456 položek</div>');
$footer->addItem('
<nav aria-label="Page navigation">
<ul class="pagination pagination-sm mb-0">
<li class="page-item disabled"><a class="page-link" href="#">«</a></li>
<li class="page-item active"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">»</a></li>
</ul>
</nav>');

return $footer;
}

private function createDetailModal()
{
$modalContent = '
<dl class="row">
<dt class="col-sm-3">ID</dt>
<dd class="col-sm-9">925-5230011904-20230413-1</dd>
<dt class="col-sm-3">Datum</dt>
<dd class="col-sm-9">13.4.2023 10:07</dd>
<dt class="col-sm-3">Trvání</dt>
<dd class="col-sm-9">0.2s</dd>
<dt class="col-sm-3">Výstup</dt>
<dd class="col-sm-9">Soubor: výpis-20230413.xml</dd>
</dl>
<hr>
<h6>Log</h6>
<pre style="background:#f6f7f8;padding:12px;border-radius:4px;max-height:240px;overflow:auto;">
[INFO] 2023-04-13 10:07: Started...
[INFO] 2023-04-13 10:07: Exported 12 items
[ERROR] 2023-04-13 10:07: Missing mapping for account ...
</pre>';

$modal = new \Ease\TWB4\Modal(
'Detail běhu',
$modalContent,
['id' => 'detailModal', 'size' => 'lg']
);
$modal->modalFooter->addItem(new \Ease\TWB4\LinkButton('#', 'Stáhnout výstup', 'primary'));

return $modal;
}
}
23 changes: 23 additions & 0 deletions src/MultiFlexi/UiII/Sidebar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace MultiFlexi\UiII;

class Sidebar extends \Ease\Html\AsideTag
{
public function __construct($properties = [])
{
parent::__construct(null, ['class' => 'sidebar d-flex flex-column'] + $properties);
$this->addItem(new \Ease\Html\H3Tag('DARAM', ['class' => 'text-danger mb-4']));

$nav = $this->addItem(new \Ease\Html\NavTag(null, ['class' => 'nav flex-column']));
$nav->addItem(new \Ease\Html\ATag('#', '<i class="fas fa-grip-horizontal"></i> Dashboard', ['class' => 'nav-link active']));
$nav->addItem(new \Ease\Html\ATag('#', '<i class="fas fa-list"></i> Runs', ['class' => 'nav-link']));
$nav->addItem(new \Ease\Html\ATag('#', '<i class="fas fa-file-alt"></i> Logs', ['class' => 'nav-link']));
$nav->addItem(new \Ease\Html\ATag('#', '<i class="fas fa-chart-bar"></i> Statistiky', ['class' => 'nav-link']));
$nav->addItem(new \Ease\Html\ATag('#', '<i class="fas fa-cog"></i> Nastavení', ['class' => 'nav-link']));

$this->addItem('<div class="mt-auto pt-4 small text-muted">verze MultiFlexi • lokální</div>');
}
}
77 changes: 77 additions & 0 deletions src/MultiFlexi/UiII/WebPage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

declare(strict_types=1);

namespace MultiFlexi\UiII;

class WebPage extends \Ease\TWB4\WebPage
{
/**
* @var AppShell Vnější obálka stránky.
*/
public AppShell $appShell;

/**
* Sestaví základní strukturu stránky.
*
* @param string $pageTitle Titulek stránky.
*/
public function __construct($pageTitle = null)
{
parent::__construct($pageTitle);

// Přidání základních CSS
$this->addCss('https://stackpath.bootstrapcdn.com/bootstrap/4.6.2/css/bootstrap.min.css');
$this->addCss('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css'); // Font Awesome 6
$this->addCss(
'
html, body { height: 100%; }
.app-shell { min-height: 100vh; display: flex; background: #f7f8fa; }
.sidebar {
width: 220px;
background: #fff;
border-right: 1px solid #e6e9ef;
padding: 1.25rem 0.75rem;
position: sticky;
top: 0;
height: 100vh;
transition: margin-left 0.3s, width 0.3s;
}
.sidebar.collapsed { margin-left: -220px; }
.content-area {
flex: 1;
padding: 1.25rem;
display: flex;
justify-content: center;
transition: margin-left 0.3s;
}
.content-area.expanded {
margin-left: 0;
}
.page-max { width: 100%; max-width: 1200px; }
.card-header-actions { display:flex; gap: 0.5rem; align-items:center; }
@media (max-width: 768px) {
.sidebar { display:none; }
}
'
);

// Vytvoření hlavní obálky
$this->appShell = new AppShell();
$this->body->addItem($this->appShell);
}

/**
* Přidá do stránky základní JavaScript.
*/
public function finalize(): void
{
// Přidání základních JS souborů na konec <body>
$this->addJavaScript('https://code.jquery.com/jquery-3.5.1.slim.min.js', null, true);
$this->addJavaScript('https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js', null, true);
$this->addJavaScript('https://stackpath.bootstrapcdn.com/bootstrap/4.6.2/js/bootstrap.min.js', null, true);
$this->addJavaScript('https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js', null, true);

parent::finalize();
}
}
Loading
Loading