Přihlašování.
parent
ea6ada8ce6
commit
5f2bb30ee4
|
|
@ -19,31 +19,53 @@ class Authenticator implements IAuthenticator
|
|||
$this->passwords = $passwords;
|
||||
}
|
||||
|
||||
public function authenticate(string $user, string $password): SimpleIdentity
|
||||
/**
|
||||
* Nette předává přihlašovací údaje jako pole [$email, $password]
|
||||
*/
|
||||
public function authenticate(array $credentials): SimpleIdentity
|
||||
{
|
||||
// 1. Dotaz do centrální Master DB
|
||||
[$email, $password] = $credentials;
|
||||
|
||||
// 1. Načtení uživatele podle tvého přesného schématu UZIVATEL
|
||||
$row = $this->masterDb->fetch(
|
||||
'SELECT ID, EMAIL, HESLO_HASH, JMENO, PRIJMENI, DATABASE_HOST, DATABASE_NAME, DEFAULT_FIRMA_ID
|
||||
'SELECT ID, EMAIL, HESLO_HASH, JMENO, PRIJMENI, DATABASE_NAME, CONNECTION_STRING_KEY
|
||||
FROM dbo.UZIVATEL
|
||||
WHERE EMAIL = ? AND AKTIVNI = 1',
|
||||
$user
|
||||
$email
|
||||
);
|
||||
|
||||
// $passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
|
||||
// bdump($passwords->hash('admin1234'));
|
||||
|
||||
if (!$row || !$this->passwords->verify($password, $row->HESLO_HASH)) {
|
||||
throw new AuthenticationException('Nespravný e-mail nebo heslo.');
|
||||
}
|
||||
|
||||
// 2. Všechny potřebné parametry pro KufrikConnectionFactory zabalíme do Nette Identity
|
||||
// 2. Aktualizace času posledního přihlášení
|
||||
$this->masterDb->query(
|
||||
'UPDATE dbo.UZIVATEL SET POSLEDNI_PRIHLASENI = SYSDATETIME() WHERE ID = ?',
|
||||
$row->ID
|
||||
);
|
||||
|
||||
// 3. Načtení výchozí FIRMA_ID z vazební tabulky UZIVATEL_FIRMA (pokud existuje)
|
||||
$firmaRow = $this->masterDb->fetch(
|
||||
'SELECT TOP 1 FIRMA_ID FROM dbo.UZIVATEL_FIRMA WHERE UZIVATEL_ID = ?',
|
||||
$row->ID
|
||||
);
|
||||
|
||||
// Fallback: Pokud vazební tabulka ještě není/nepoužívá se, použije se ID uživatele
|
||||
$firmaId = $firmaRow ? $firmaRow->FIRMA_ID : $row->ID;
|
||||
|
||||
// 4. Předání dat do Nette Identity
|
||||
return new SimpleIdentity(
|
||||
$row->ID,
|
||||
null, // role (volitelně)
|
||||
null, // role
|
||||
[
|
||||
'email' => $row->EMAIL,
|
||||
'jmeno' => $row->JMENO . ' ' . $row->PRIJMENI,
|
||||
// Kufrik parametry:
|
||||
'db_host' => $row->DATABASE_HOST ?? '127.0.0.1', // Umožňuje i RŮZNÉ SERVERY!
|
||||
'db_name' => $row->DATABASE_NAME ?? 'Fakturace_MainDB',
|
||||
'firma_id' => $row->DEFAULT_FIRMA_ID,
|
||||
'jmeno' => trim(($row->JMENO ?? '') . ' ' . ($row->PRIJMENI ?? '')),
|
||||
'db_name' => $row->DATABASE_NAME, // Nulllable -> KufrikConnectionFactory použije default_db
|
||||
'connection_key' => $row->CONNECTION_STRING_KEY,
|
||||
'firma_id' => $firmaId,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,159 +22,171 @@
|
|||
<body>
|
||||
|
||||
<!-- 1. HORNÍ LIŠTA -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark app-header">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#"><i class="bi bi-briefcase-fill me-2"></i>Kufřík</a>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark app-header">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#"><i class="bi bi-briefcase-fill me-2"></i>Kufřík</a>
|
||||
|
||||
<button class="navbar-toggler border-0" type="button" data-bs-toggle="collapse" data-bs-target="#mainNavbar">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<button class="navbar-toggler border-0" type="button" data-bs-toggle="collapse" data-bs-target="#mainNavbar">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="mainNavbar">
|
||||
<!-- Hlavní kategorie -->
|
||||
<ul class="navbar-nav me-auto nav nav-tabs" id="mainCategoryTabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<button class="nav-link active" id="cat-invoices-tab" data-bs-toggle="tab" data-bs-target="#toolbar-invoices" type="button" role="tab">
|
||||
<i class="bi bi-file-earmark-text me-1"></i> Faktury
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" id="cat-customers-tab" data-bs-toggle="tab" data-bs-target="#toolbar-customers" type="button" role="tab">
|
||||
<i class="bi bi-people me-1"></i> Zákazníci
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" id="cat-profile-tab" data-bs-toggle="tab" data-bs-target="#toolbar-profile" type="button" role="tab">
|
||||
<i class="bi bi-building me-1"></i> Moje OSVČ
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" id="cat-briefcase-tab" data-bs-toggle="tab" data-bs-target="#toolbar-briefcase" type="button" role="tab">
|
||||
<i class="bi bi-box me-1"></i> Kufřík
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="collapse navbar-collapse" id="mainNavbar">
|
||||
<!-- Hlavní kategorie - viditelné pouze pro přihlášené -->
|
||||
{if $user->isLoggedIn()}
|
||||
<ul class="navbar-nav me-auto nav nav-tabs" id="mainCategoryTabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="cat-invoices-tab" data-bs-toggle="tab" data-bs-target="#toolbar-invoices" type="button" role="tab">
|
||||
<i class="bi bi-file-earmark-text me-1"></i> Faktury
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="cat-customers-tab" data-bs-toggle="tab" data-bs-target="#toolbar-customers" type="button" role="tab">
|
||||
<i class="bi bi-people me-1"></i> Zákazníci
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="cat-profile-tab" data-bs-toggle="tab" data-bs-target="#toolbar-profile" type="button" role="tab">
|
||||
<i class="bi bi-building me-1"></i> Moje OSVČ
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="cat-briefcase-tab" data-bs-toggle="tab" data-bs-target="#toolbar-briefcase" type="button" role="tab">
|
||||
<i class="bi bi-box me-1"></i> Kufřík
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
{/if}
|
||||
|
||||
<!-- Uživatel a Odhlášení -->
|
||||
<div class="user-panel">
|
||||
<span class="text-white d-none d-sm-inline">
|
||||
<i class="bi bi-person-circle me-1"></i> Jan Novák
|
||||
</span>
|
||||
<a href="#" class="btn btn-sm btn-outline-light" title="Odhlásit se">
|
||||
<i class="bi bi-box-arrow-right me-1"></i> Odhlásit
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- Uživatel a Odhlášení / Přihlášení -->
|
||||
<div class="user-panel ms-auto">
|
||||
{if $user->isLoggedIn()}
|
||||
{* Přihlášený uživatel *}
|
||||
<span class="text-white d-none d-sm-inline me-2">
|
||||
<i class="bi bi-person-circle me-1"></i> {$user->identity->jmeno ?: $user->identity->email}
|
||||
</span>
|
||||
<a n:href="Sign:out" class="btn btn-sm btn-outline-light" title="Odhlásit se">
|
||||
<i class="bi bi-box-arrow-right me-1"></i> Odhlásit
|
||||
</a>
|
||||
{else}
|
||||
{* Odhlášený / Nepřihlášený uživatel *}
|
||||
<a n:href="Sign:in" class="btn btn-sm btn-outline-light" title="Přihlásit se">
|
||||
<i class="bi bi-box-arrow-in-right me-1"></i> Přihlásit se
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 2. AKČNÍ LIŠTA (PODKATEGORIE) -->
|
||||
<div class="action-toolbar">
|
||||
<div class="container-fluid">
|
||||
<!-- 2. AKČNÍ LIŠTA (PODKATEGORIE - zobrazeno jen přihlášeným) -->
|
||||
{if $user->isLoggedIn()}
|
||||
<div class="action-toolbar">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Tlačítko pro mobilní rozbalení -->
|
||||
<div class="d-lg-none d-flex justify-content-between align-items-center">
|
||||
<span class="fw-bold text-muted small">Nástroje</span>
|
||||
<button class="btn btn-outline-secondary btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#actionToolbarCollapse">
|
||||
<i class="bi bi-three-dots-vertical"></i> Podkategorie
|
||||
</button>
|
||||
</div>
|
||||
<!-- Tlačítko pro mobilní rozbalení -->
|
||||
<div class="d-lg-none d-flex justify-content-between align-items-center">
|
||||
<span class="fw-bold text-muted small">Nástroje</span>
|
||||
<button class="btn btn-outline-secondary btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#actionToolbarCollapse">
|
||||
<i class="bi bi-three-dots-vertical"></i> Podkategorie
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="collapse d-lg-block mt-2 mt-lg-0" id="actionToolbarCollapse">
|
||||
<div class="tab-content" id="actionToolbarContent">
|
||||
<div class="collapse d-lg-block mt-2 mt-lg-0" id="actionToolbarCollapse">
|
||||
<div class="tab-content" id="actionToolbarContent">
|
||||
|
||||
<!-- FAKTURY -->
|
||||
<div class="tab-pane fade show active" id="toolbar-invoices" role="tabpanel">
|
||||
<div class="toolbar-group">
|
||||
<!-- FAKTURY -->
|
||||
<div class="tab-pane fade show active" id="toolbar-invoices" role="tabpanel">
|
||||
<div class="toolbar-group">
|
||||
<div class="action-buttons">
|
||||
<button type="button" class="btn btn-outline-primary btn-action">
|
||||
<i class="bi bi-folder-fill"></i>
|
||||
<span>Seznam faktur</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-success btn-action">
|
||||
<i class="bi bi-plus-square-fill"></i>
|
||||
<span>Přidat fakturu</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-action" onclick="window.print()">
|
||||
<i class="bi bi-printer-fill"></i>
|
||||
<span>Tisk</span>
|
||||
</button>
|
||||
|
||||
<div class="v-divider d-none d-sm-block"></div>
|
||||
|
||||
<button type="button" class="btn btn-outline-secondary btn-action">
|
||||
<i class="bi bi-bar-chart-line-fill text-warning"></i>
|
||||
<span>Grafy</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-action">
|
||||
<i class="bi bi-file-earmark-pdf-fill text-danger"></i>
|
||||
<span>Tiskové sestavy</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Filtr pro Faktury -->
|
||||
<form class="filter-panel ms-auto ms-lg-0">
|
||||
<i class="bi bi-funnel-fill text-muted fs-5 ms-1"></i>
|
||||
<select class="form-select form-select-sm" style="width: 85px;">
|
||||
<option selected>2026</option>
|
||||
<option>2025</option>
|
||||
</select>
|
||||
<select class="form-select form-select-sm" style="width: 140px;">
|
||||
<option selected>(všechny měsíce)</option>
|
||||
<option>Leden</option>
|
||||
<option>Únor</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ZÁKAZNÍCI -->
|
||||
<div class="tab-pane fade" id="toolbar-customers" role="tabpanel">
|
||||
<div class="action-buttons">
|
||||
<a href="#" class="btn btn-outline-primary btn-action">
|
||||
<i class="bi bi-folder-fill"></i>
|
||||
<span>Seznam faktur</span>
|
||||
</a>
|
||||
<a href="#" class="btn btn-success btn-action">
|
||||
<i class="bi bi-plus-square-fill"></i>
|
||||
<span>Přidat fakturu</span>
|
||||
</a>
|
||||
<a href="#" class="btn btn-outline-secondary btn-action">
|
||||
<i class="bi bi-printer-fill"></i>
|
||||
<span>Tisk</span>
|
||||
</a>
|
||||
<button type="button" class="btn btn-outline-primary btn-action">
|
||||
<i class="bi bi-people-fill"></i>
|
||||
<span>Seznam</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-success btn-action">
|
||||
<i class="bi bi-person-plus-fill"></i>
|
||||
<span>Přidat zákazníka</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="v-divider d-none d-sm-block"></div>
|
||||
<!-- MOJE OSVČ -->
|
||||
<div class="tab-pane fade" id="toolbar-profile" role="tabpanel">
|
||||
<div class="action-buttons">
|
||||
<button type="button" class="btn btn-outline-primary btn-action">
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
<span>Upravit moje OSVČ</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-action">
|
||||
<i class="bi bi-gear-fill"></i>
|
||||
<span>Nastavení</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="#" class="btn btn-outline-secondary btn-action">
|
||||
<i class="bi bi-bar-chart-line-fill text-warning"></i>
|
||||
<span>Grafy</span>
|
||||
</a>
|
||||
<a href="#" class="btn btn-outline-secondary btn-action">
|
||||
<i class="bi bi-file-earmark-pdf-fill text-danger"></i>
|
||||
<span>Tiskové sestavy</span>
|
||||
<!-- KUFŘÍK -->
|
||||
<div class="tab-pane fade" id="toolbar-briefcase" role="tabpanel">
|
||||
<div class="action-buttons">
|
||||
<button type="button" class="btn btn-outline-info btn-action">
|
||||
<i class="bi bi-question-circle-fill"></i>
|
||||
<span>Nápověda</span>
|
||||
</button>
|
||||
<a href="https://facebook.com" target="_blank" rel="noopener noreferrer" class="btn btn-outline-primary btn-action">
|
||||
<i class="bi bi-facebook"></i>
|
||||
<span>Stránky - FB</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Filtr pro Faktury -->
|
||||
<form class="filter-panel ms-auto ms-lg-0">
|
||||
<i class="bi bi-funnel-fill text-muted fs-5 ms-1"></i>
|
||||
<select class="form-select form-select-sm" style="width: 85px;">
|
||||
<option selected>2026</option>
|
||||
<option>2025</option>
|
||||
</select>
|
||||
<select class="form-select form-select-sm" style="width: 140px;">
|
||||
<option selected>(všechny měsíce)</option>
|
||||
<option>Leden</option>
|
||||
<option>Únor</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ZÁKAZNÍCI -->
|
||||
<div class="tab-pane fade" id="toolbar-customers" role="tabpanel">
|
||||
<div class="action-buttons">
|
||||
<a href="#" class="btn btn-outline-primary btn-action">
|
||||
<i class="bi bi-people-fill"></i>
|
||||
<span>Seznam</span>
|
||||
</a>
|
||||
<a href="#" class="btn btn-success btn-action">
|
||||
<i class="bi bi-person-plus-fill"></i>
|
||||
<span>Přidat zákazníka</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MOJE OSVČ -->
|
||||
<div class="tab-pane fade" id="toolbar-profile" role="tabpanel">
|
||||
<div class="action-buttons">
|
||||
<a href="#" class="btn btn-outline-primary btn-action">
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
<span>Upravit moje OSVČ</span>
|
||||
</a>
|
||||
<a href="#" class="btn btn-outline-secondary btn-action">
|
||||
<i class="bi bi-gear-fill"></i>
|
||||
<span>Nastavení</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- KUFŘÍK -->
|
||||
<div class="tab-pane fade" id="toolbar-briefcase" role="tabpanel">
|
||||
<div class="action-buttons">
|
||||
<a href="#" class="btn btn-outline-info btn-action">
|
||||
<i class="bi bi-question-circle-fill"></i>
|
||||
<span>Nápověda</span>
|
||||
</a>
|
||||
<a href="https://facebook.com" target="_blank" class="btn btn-outline-primary btn-action">
|
||||
<i class="bi bi-facebook"></i>
|
||||
<span>Stránky - FB</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- 3. HLAVNÍ OBSAH -->
|
||||
<main class="main-content">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\UI;
|
||||
|
||||
use Nette\Application\UI\Presenter;
|
||||
|
||||
abstract class BasePresenter extends Presenter
|
||||
{
|
||||
protected function startup(): void
|
||||
{
|
||||
parent::startup();
|
||||
|
||||
// Pokud uživatel není přihlášen a nepokouší se právě přihlásit
|
||||
if (!$this->getUser()->isLoggedIn() && !$this->isLinkCurrent('Sign:in')) {
|
||||
$this->redirect('Sign:in');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,9 +4,10 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\UI\Home;
|
||||
|
||||
use App\UI\BasePresenter;
|
||||
use Nette;
|
||||
|
||||
|
||||
final class HomePresenter extends Nette\Application\UI\Presenter
|
||||
final class HomePresenter extends BasePresenter
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,42 @@
|
|||
{block content}
|
||||
<div class="login-page">
|
||||
<div class="login-card">
|
||||
|
||||
{* {control signInForm} *}
|
||||
<div class="container-fluid">
|
||||
<section class="w-100 p-4 d-flex justify-content-center pb-4">
|
||||
<form n:name=signInForm style="width: 22rem;">
|
||||
<div class="p-3 container-fluid ramecek-chyba" n:if="$form->hasErrors()" n:foreach="$form->getErrors() as $error">
|
||||
<span>{$error}</span>
|
||||
</div>
|
||||
<!-- Hlavička karty s logem/názvem -->
|
||||
<div class="login-header">
|
||||
<h1 class="login-title">Kufřík</h1>
|
||||
<p class="login-subtitle">Přihlášení do fakturačního systému</p>
|
||||
</div>
|
||||
|
||||
<!-- Zobrazení Chybových zpráv -->
|
||||
<div n:foreach="$flashes as $flash" class="alert alert-{$flash->type}">
|
||||
{$flash->message}
|
||||
</div>
|
||||
|
||||
<!-- Nette Formulář -->
|
||||
<form n:name="signInForm" class="login-form">
|
||||
<!-- Chybové zprávy samotného formuláře -->
|
||||
<ul class="error-list" n:ifcontent>
|
||||
<li n:foreach="$form->ownErrors as $error">{$error}</li>
|
||||
</ul>
|
||||
|
||||
<div class="form-group">
|
||||
<label n:name=username for="inputUser">Uživatel</label>
|
||||
<input n:name=username type="text" class="form-control" id="inputUser" placeholder="Uživatel" required>
|
||||
<label n:name="email">E-mailová adresa</label>
|
||||
<input n:name="email" class="form-control" autofocus placeholder="jan@novak.cz">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label n:name=password for="inputHeslo" n:if="$salt == 0">Heslo</label>
|
||||
<input n:name=password type="{if $salt == 0}password{else}hidden{/if}" class="form-control" id="inputHeslo" placeholder="Heslo" autofocus="autofocus" required>
|
||||
<label n:name="password">Heslo</label>
|
||||
<input n:name="password" class="form-control" placeholder="••••••••">
|
||||
</div>
|
||||
<button type="submit" n:name=send class="btn btn-primary btn-xlarge w-100" style="margin-top: 10px;">Přihlásit</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<div class="form-actions">
|
||||
<button n:name="send" class="btn btn-primary btn-block">
|
||||
Přihlásit se
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
|
|
@ -237,3 +237,44 @@ ADD FILTER PREDICATE Security.fn_SecurityPredicate(FIRMA_ID) ON dbo.POLOZKA,
|
|||
ADD BLOCK PREDICATE Security.fn_SecurityPredicate(FIRMA_ID) ON dbo.POLOZKA
|
||||
WITH (STATE = ON);
|
||||
GO
|
||||
|
||||
|
||||
-- ==========================================
|
||||
-- Cvičná data a UZIVATEL
|
||||
-- ==========================================
|
||||
|
||||
-- Vygenerovaný platný BCrypt hash (cost: 12) pro heslo: admin1234
|
||||
DECLARE @HesloHash NVARCHAR(255) = N'$2y$12$9SAWctZKp/JpYl7K.awSRehXOXVyRpu0ofReqvbm1jVjvdz41zH7a';
|
||||
DECLARE @Email NVARCHAR(100) = N'admin@kmetix.cz';
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.UZIVATEL WHERE EMAIL = @Email)
|
||||
BEGIN
|
||||
INSERT INTO dbo.UZIVATEL (
|
||||
[EMAIL],
|
||||
[HESLO_HASH],
|
||||
[JMENO],
|
||||
[PRIJMENI],
|
||||
[TELEFON],
|
||||
[DATABASE_NAME],
|
||||
[CONNECTION_STRING_KEY],
|
||||
[AKTIVNI]
|
||||
)
|
||||
VALUES (
|
||||
@Email,
|
||||
@HesloHash,
|
||||
N'Pavel',
|
||||
N'Kowalski',
|
||||
N'+420123456789',
|
||||
N'', -- Cílová databáze pro klientská data
|
||||
NULL,
|
||||
1 -- AKTIVNI = 1
|
||||
);
|
||||
|
||||
PRINT 'Uživatel admin@kmetix.cz byl úspěšně vytvořen s heslem: admin1234';
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
PRINT 'Uživatel s tímto e-mailem již v databázi existuje.';
|
||||
END
|
||||
GO
|
||||
|
||||
|
|
|
|||
|
|
@ -209,3 +209,121 @@ body {
|
|||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* --- 6. SIGN-IN PAGE --- */
|
||||
.login-page {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1.5rem;
|
||||
background-color: var(--app-bg);
|
||||
}
|
||||
|
||||
.login-card {
|
||||
width: 100%;
|
||||
max-width: 380px;
|
||||
background-color: var(--card-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 2rem;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.login-header {
|
||||
text-align: center;
|
||||
margin-bottom: 1.75rem;
|
||||
}
|
||||
|
||||
.login-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--header-bg); /* Tmavě břidlicová ze stejné palety */
|
||||
margin: 0 0 0.25rem 0;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.login-subtitle {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.login-form .form-group {
|
||||
margin-bottom: 1.15rem;
|
||||
}
|
||||
|
||||
.login-form label {
|
||||
display: block;
|
||||
font-weight: 500;
|
||||
font-size: 0.825rem;
|
||||
color: var(--text-main);
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
|
||||
.login-form .form-control {
|
||||
width: 100%;
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-main);
|
||||
background-color: #fff;
|
||||
border: 1px solid #cbd5e1;
|
||||
border-radius: var(--radius-sm);
|
||||
box-sizing: border-box;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.login-form .form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary-accent);
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
|
||||
}
|
||||
|
||||
.login-form .btn-primary {
|
||||
width: 100%;
|
||||
padding: 0.6rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
background-color: var(--primary-accent);
|
||||
border: 1px solid var(--primary-accent);
|
||||
border-radius: var(--radius-sm);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease-in-out;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.login-form .btn-primary:hover {
|
||||
background-color: #2563eb;
|
||||
border-color: #2563eb;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* Chybové zprávy */
|
||||
.error-list {
|
||||
list-style: none;
|
||||
padding: 0.5rem 0.75rem;
|
||||
margin: 0 0 1rem 0;
|
||||
background-color: #fef2f2;
|
||||
border: 1px solid #fecaca;
|
||||
border-radius: var(--radius-sm);
|
||||
color: #dc2626;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 0.65rem 0.85rem;
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 0.825rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.alert-danger, .alert-error {
|
||||
background-color: #fef2f2;
|
||||
border: 1px solid #fecaca;
|
||||
color: #991b1b;
|
||||
}
|
||||
.alert-success {
|
||||
background-color: #ecfdf5;
|
||||
border: 1px solid #a7f3d0;
|
||||
color: #065f46;
|
||||
}
|
||||
Loading…
Reference in New Issue