remove not used class, add header and footer for christines design, start changing checkTransaction in new design

This commit is contained in:
Dario 2020-06-11 17:56:20 +02:00
parent fc526934bf
commit 582aba5bcd
13 changed files with 168 additions and 435 deletions

View File

@ -1,146 +0,0 @@
#include "MysqlTable.h"
#include "Poco/Mutex.h"
#include <time.h>
#include "../ServerConfig.h"
MysqlTable::MysqlTable(size_t fieldCount)
: mFieldCount(fieldCount), mHeader(nullptr)
{
mHeader = new MysqlTableColumn[fieldCount];
}
MysqlTable::~MysqlTable()
{
if (mHeader) {
delete[] mHeader;
mHeader = nullptr;
}
for (auto it = mRows.begin(); it != mRows.end(); it++) {
for (auto sub_it = (*it)->begin(); sub_it != (*it)->end(); sub_it++) {
delete *sub_it;
}
delete *it;
}
mRows.clear();
}
bool MysqlTable::setHeader(int index, const char* name, MysqlRowType type)
{
if (index < 0 || index >= mFieldCount) {
return false;
}
if (!mHeader) {
return false;
}
mHeader[index].name = name;
mHeader[index].type = type;
return true;
}
bool MysqlTable::addCellToCurrentRow(MysqlTableCell* cell)
{
if (!cell) {
addError(new Error(__FUNCTION__, "zero pointer"));
return false;
}
if (mRows.size() == 0) {
addError(new Error(__FUNCTION__, "row container is empty"));
return false;
}
auto last_row = mRows.back();
auto fieldIndex = last_row->size();
if (fieldIndex >= mFieldCount) {
addError(new Error(__FUNCTION__, "invalid Cell count"));
delete cell;
return false;
}
if (cell->getType() != MYSQL_ROW_NULL && cell->getType() != mHeader[fieldIndex].type) {
addError(new Error(__FUNCTION__, "field type mismatch"));
delete cell;
return false;
}
last_row->push_back(cell);
return true;
}
//using namespace Poco::Data::Keywords
// new Binding<T>(t, name, AbstractBinding::PD_IN);
int MysqlTable::connectToStatement(Poco::Data::Statement* stmt, int rowIndex/* = 0*/)
{
std::string strCopy;
for (auto itRow = mRows.begin(); itRow != mRows.end(); itRow++) {
if (0 == rowIndex) {
for (auto itCell = (*itRow)->begin(); itCell != (*itRow)->end(); itCell++) {
MysqlTableCell* cell = (*itCell);
switch ((*itCell)->getType()) {
case MYSQL_ROW_STRING:
strCopy = (const char*)(*cell);
stmt->bind(strCopy);
break;
case MYSQL_ROW_INT: stmt->bind((Poco::Int32)(*cell)); break;
case MYSQL_ROW_LONG: stmt->bind((Poco::Int64)(*cell)); break;
case MYSQL_ROW_BINARY:
// Poco::Data::BLOB data(std::vector<unsigned char>({ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' }));
Poco::Data::BLOB data((unsigned char*)(*cell), cell->size());
stmt->bind(data);
break;
}
}
break;
}
rowIndex--;
}
return 0;
}
size_t MysqlTable::getFieldTypeSize(MysqlRowType type)
{
switch (type) {
case MYSQL_ROW_DECIMAL: return sizeof(double);
case MYSQL_ROW_INT: return sizeof(long);
case MYSQL_ROW_LONG: return sizeof(long long);
case MYSQL_ROW_STRING: return sizeof(std::string);
}
return 0;
}
time_t MysqlTable::parseFromMysqlDateTime(const char* mysql_date_time)
{
struct tm * parsedTime;
// used because localtime return an internal pointer, not thread safe
Poco::Mutex& timeMutex = ServerConfig::g_TimeMutex;
int year, month, day, hour, minute, second;
// ex: 2009-10-29
if (sscanf(mysql_date_time, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second) != EOF) {
time_t rawTime;
time(&rawTime);
// static, used for every thread
timeMutex.lock();
parsedTime = localtime(&rawTime);
// tm_year is years since 1900
parsedTime->tm_year = year - 1900;
// tm_months is months since january
parsedTime->tm_mon = month - 1;
parsedTime->tm_mday = day;
parsedTime->tm_hour = hour;
parsedTime->tm_min = minute;
parsedTime->tm_sec = second;
rawTime = mktime(parsedTime);
timeMutex.unlock();
return rawTime;
}
return 0;
}

View File

@ -1,207 +0,0 @@
/*!
*
* \author: einhornimmond
*
* \date: 04.04.19
*
* \brief: Config Basic Structure
*/
#ifndef DR_LUA_WEB_MODULE_STRUCTURES_MYSQL_QUERY_RESULT__H
#define DR_LUA_WEB_MODULE_STRUCTURES_MYSQL_QUERY_RESULT__H
#include <list>
#include <string.h>
#include "../lib/ErrorList.h"
#include "mysql.h"
#include "Poco/Data/Session.h"
enum MysqlRowType {
MYSQL_ROW_STRING,
MYSQL_ROW_INT, // 32 Bit
MYSQL_ROW_LONG, // 64 Bit
MYSQL_ROW_DECIMAL, // double
MYSQL_ROW_TIMESTAMP,
MYSQL_ROW_DATETIME,
MYSQL_ROW_BINARY,
MYSQL_ROW_NULL,
MYSQL_ROW_TYPE_COUNT,
MYSQL_ROW_TYPE_NONE
};
struct MysqlTableColumn
{
MysqlTableColumn()
: type(MYSQL_ROW_NULL), name("null") {}
MysqlRowType type;
std::string name;
};
class MysqlTableCell
{
public:
MysqlTableCell(MysqlRowType type = MYSQL_ROW_NULL) : mType(type) {}
inline bool isString() const { return mType == MYSQL_ROW_STRING; }
inline bool isInt() const { return mType == MYSQL_ROW_INT; }
inline bool isLong() const { return mType == MYSQL_ROW_LONG; }
inline bool isDateTime() const { return mType == MYSQL_ROW_DATETIME; }
inline bool isNull() const { return mType == MYSQL_ROW_NULL; }
inline bool isDecimal() const { return mType == MYSQL_ROW_DECIMAL; }
inline bool isBinary() const { return mType == MYSQL_ROW_BINARY; }
inline MysqlRowType getType() const { return mType; }
virtual operator const char*() const { return ""; }
virtual operator Poco::Int32() const { return 0; }
virtual operator Poco::Int64() const { return 0; }
virtual operator unsigned char*() const { return nullptr; }
virtual size_t size() { return 0; }
protected:
MysqlRowType mType;
};
class MysqlTableCellString : public MysqlTableCell
{
public:
MysqlTableCellString(const char* content) : MysqlTableCell(MYSQL_ROW_STRING), mContent(content) {}
MysqlTableCellString(const char* content, size_t count) : MysqlTableCell(MYSQL_ROW_STRING), mContent(content, count) {}
virtual operator const char*() const { return mContent.data(); }
virtual size_t size() { return mContent.size(); }
protected:
std::string mContent;
};
class MysqlTableCellInt : public MysqlTableCell
{
public:
MysqlTableCellInt(Poco::Int32 value) : MysqlTableCell(MYSQL_ROW_INT), mContent(value) {}
virtual operator Poco::Int32() const { return mContent; }
protected:
Poco::Int32 mContent;
};
class MysqlTableCellLong : public MysqlTableCell
{
public:
MysqlTableCellLong(const Poco::Int64& value) : MysqlTableCell(MYSQL_ROW_LONG), mContent(value) {}
virtual operator Poco::Int64() const { return mContent; }
protected:
Poco::Int64 mContent;
};
class MysqlTableCellTimestamp : public MysqlTableCell
{
public:
MysqlTableCellTimestamp(const time_t& timestamp) : MysqlTableCell(MYSQL_ROW_TIMESTAMP), mTimestamp(timestamp) {}
protected:
time_t mTimestamp;
};
class MysqlTableCellDateTime : public MysqlTableCell
{
public:
MysqlTableCellDateTime(const MYSQL_TIME& mysql_time) : MysqlTableCell(MYSQL_ROW_DATETIME), mMysqlTime(mysql_time) {}
protected:
MYSQL_TIME mMysqlTime;
};
class MysqlTableCellDecimal : public MysqlTableCell
{
public:
MysqlTableCellDecimal(const double& value) : MysqlTableCell(MYSQL_ROW_DECIMAL), mDecimal(value) {}
protected:
double mDecimal;
};
class MysqlTableCellBinary : public MysqlTableCell
{
public:
MysqlTableCellBinary(const unsigned char* data, size_t _size) :MysqlTableCell(MYSQL_ROW_BINARY), m_data(nullptr), m_size(_size) {
m_data = (unsigned char*)malloc(m_size);
memcpy(m_data, data, m_size);
}
~MysqlTableCellBinary() {
if (m_data) free(m_data);
m_data = nullptr;
m_size = 0;
}
virtual operator unsigned char*() const { return m_data; }
virtual size_t size() { return m_size; }
protected:
unsigned char* m_data;
size_t m_size;
};
class MysqlTable : public ErrorList
{
public:
MysqlTable(size_t fieldCount);
~MysqlTable();
bool setHeader(int index, const char* name, MysqlRowType type);
inline MysqlRowType getHeaderType(int index) {
if (index > 0 && index < mFieldCount) {
return mHeader[index].type;
}
addError(new ParamError(__FUNCTION__, "invalid field index:", index));
return MYSQL_ROW_TYPE_NONE;
}
inline const char* getHeaderName(int index) {
if (index > 0 && index < mFieldCount) {
return mHeader[index].name.data();
}
addError(new ParamError(__FUNCTION__, "invalid field index:", index));
return nullptr;
}
inline bool addCellToCurrentRow(Poco::Int32 value) { return addCellToCurrentRow(new MysqlTableCellInt(value)); }
inline bool addCellToCurrentRow(const Poco::Int64& value) { return addCellToCurrentRow(new MysqlTableCellLong(value)); }
inline bool addCellToCurrentRow(const char* string) { return addCellToCurrentRow(new MysqlTableCellString(string)); }
inline bool addCellToCurrentRow(const double& value) { return addCellToCurrentRow(new MysqlTableCellDecimal(value)); }
inline bool addCellToCurrentRow(const unsigned char* bytes, size_t size) { return addCellToCurrentRow(new MysqlTableCellBinary(bytes, size)); }
inline bool addCellToCurrentRowTime(const time_t& time) { return addCellToCurrentRow(new MysqlTableCellTimestamp(time)); }
inline bool addCellToCurrentRow() { return addCellToCurrentRow(new MysqlTableCell); }
//bool copyColumnValues()
//! \brief free memory after not longer using it
bool addCellToCurrentRow(MysqlTableCell* cell);
inline void addRow() { mRows.push_back(new std::list<MysqlTableCell*>); }
inline size_t getRowCount() const { return mRows.size(); }
inline size_t getFieldCount() const { return mFieldCount; }
inline MysqlRowType getRowType(int fieldIndex) const {
if (fieldIndex >= mFieldCount || fieldIndex < 0) return MYSQL_ROW_TYPE_NONE;
return mHeader[fieldIndex].type;
}
inline void setTableName(const char* tableName) { mTableName = tableName; }
inline const char* getTableName() { return mTableName.data(); }
int connectToStatement(Poco::Data::Statement* stmt, int rowIndex = 0);
static size_t getFieldTypeSize(MysqlRowType type);
static time_t parseFromMysqlDateTime(const char* mysql_date_time);
protected:
size_t mFieldCount;
MysqlTableColumn* mHeader;
std::list<std::list<MysqlTableCell*>*> mRows;
std::string mTableName;
};
#endif //DR_LUA_WEB_MODULE_STRUCTURES_MYSQL_QUERY_RESULT__H

View File

@ -43,6 +43,7 @@ namespace ServerConfig {
EmailAccount g_EmailAccount; EmailAccount g_EmailAccount;
int g_SessionTimeout = SESSION_TIMEOUT_DEFAULT; int g_SessionTimeout = SESSION_TIMEOUT_DEFAULT;
std::string g_serverPath; std::string g_serverPath;
int g_serverPort = 0;
Languages g_default_locale; Languages g_default_locale;
std::string g_php_serverPath; std::string g_php_serverPath;
std::string g_php_serverHost; std::string g_php_serverHost;
@ -209,6 +210,7 @@ namespace ServerConfig {
g_serverPath = cfg.getString("loginServer.path", ""); g_serverPath = cfg.getString("loginServer.path", "");
replaceZeroIPWithLocalhostIP(g_serverPath); replaceZeroIPWithLocalhostIP(g_serverPath);
g_default_locale = LanguageManager::languageFromString(cfg.getString("loginServer.default_locale")); g_default_locale = LanguageManager::languageFromString(cfg.getString("loginServer.default_locale"));
g_serverPort = cfg.getInt("loginServer.port", 0);
// replace 0.0.0.0 with actual server ip // replace 0.0.0.0 with actual server ip
g_php_serverPath = cfg.getString("phpServer.url", ""); g_php_serverPath = cfg.getString("phpServer.url", "");

View File

@ -51,6 +51,7 @@ namespace ServerConfig {
extern EmailAccount g_EmailAccount; extern EmailAccount g_EmailAccount;
extern int g_SessionTimeout; extern int g_SessionTimeout;
extern std::string g_serverPath; extern std::string g_serverPath;
extern int g_serverPort;
extern Languages g_default_locale; extern Languages g_default_locale;
extern std::string g_php_serverPath; extern std::string g_php_serverPath;
extern std::string g_php_serverHost; extern std::string g_php_serverHost;

View File

@ -143,6 +143,7 @@ const std::string& TransactionTransfer::getKontoNameCell(int index)
return mKontoTable[index].kontoNameCell; return mKontoTable[index].kontoNameCell;
} }
const std::string& TransactionTransfer::getAmountCell(int index) const std::string& TransactionTransfer::getAmountCell(int index)
{ {
lock(); lock();
@ -154,3 +155,4 @@ const std::string& TransactionTransfer::getAmountCell(int index)
return mKontoTable[index].amountCell; return mKontoTable[index].amountCell;
} }

View File

@ -30,7 +30,9 @@ public:
protected: protected:
const static std::string mInvalidIndexMessage; const static std::string mInvalidIndexMessage;
struct KontoTableEntry {
struct KontoTableEntry
{
public: public:
KontoTableEntry(User* user, google::protobuf::int64 amount, bool negativeAmount = false); KontoTableEntry(User* user, google::protobuf::int64 amount, bool negativeAmount = false);
KontoTableEntry(const std::string& pubkeyHex, google::protobuf::int64 amount, bool negativeAmount = false); KontoTableEntry(const std::string& pubkeyHex, google::protobuf::int64 amount, bool negativeAmount = false);

View File

@ -7,7 +7,7 @@
#include "../../lib/MultithreadContainer.h" #include "../../lib/MultithreadContainer.h"
#include "../../tasks/CPUTask.h" #include "../../tasks/CPUTask.h"
#include "../../MySQL/MysqlTable.h" //#include "../../MySQL/MysqlTable.h"
#include "../../ServerConfig.h" #include "../../ServerConfig.h"

View File

@ -147,7 +147,10 @@ int SigningTransaction::run() {
try { try {
Profiler phpRequestTime; Profiler phpRequestTime;
Poco::Net::HTTPClientSession* clientSession = nullptr; Poco::Net::HTTPClientSession* clientSession = nullptr;
if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType || if (ServerConfig::g_serverPort) {
clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, ServerConfig::g_serverPort);
}
else if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType ||
ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) { ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) {
clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, 443); clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, 443);
} }

View File

@ -1,46 +0,0 @@
#include "WriteIntoDBTask.h"
WriteIntoDBTask::WriteIntoDBTask(ConnectionType type, std::vector<MysqlTable*> multipleData, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount/* = 0*/)
: UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mConnectionType(type), mDataToInsert(multipleData)
{
}
WriteIntoDBTask::~WriteIntoDBTask()
{
for (auto it = mDataToInsert.begin(); it != mDataToInsert.end(); it++) {
delete *it;
}
mDataToInsert.clear();
}
int WriteIntoDBTask::run()
{
auto cm = ConnectionManager::getInstance();
auto session = cm->getConnection(mConnectionType);
for (auto it = mDataToInsert.begin(); it != mDataToInsert.end(); it++) {
auto tableName = (*it)->getTableName();
Poco::Data::Statement insert(session);
/*insert << "INSERT INTO Person VALUES(?, ?, ?)",
use(person.name),
use(person.address),
use(person.age);*/
insert << "INSERT INTO " << tableName << " (";
for (int iField = 0; iField < (*it)->getFieldCount(); iField++) {
if (iField > 0) insert << ",";
insert << (*it)->getHeaderName(iField);
}
insert << ") VALUES(";
for (int iCell = 0; iCell < (*it)->getFieldCount(); iCell++) {
if (iCell > 0) insert << ",";
insert << "?";
}
insert << ")";
(*it)->connectToStatement(&insert);
insert.execute();
}
return 0;
}

View File

@ -1,30 +0,0 @@
#ifndef GRADIDO_LOGIN_SERVER_TASKS_WRITE_INTO_DB_TASK_INCLUDE
#define GRADIDO_LOGIN_SERVER_TASKS_WRITE_INTO_DB_TASK_INCLUDE
#include "CPUTask.h"
#include "../SingletonManager/ConnectionManager.h"
#include "../MySQL/MysqlTable.h"
#include "Poco/Tuple.h"
class WriteIntoDBTask : public UniLib::controller::CPUTask
{
public:
//! \param multipleData clear table in deconstruction, call delete for every entry
WriteIntoDBTask(ConnectionType type, std::vector<MysqlTable*> multipleData, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0);
virtual ~WriteIntoDBTask();
virtual int run();
virtual const char* getResourceType() const { return "WriteIntoDBTask"; };
protected:
private:
ConnectionType mConnectionType;
std::vector<MysqlTable*> mDataToInsert;
};
#endif //GRADIDO_LOGIN_SERVER_TASKS_WRITE_INTO_DB_TASK_INCLUDE

View File

@ -82,7 +82,82 @@ enum PageState {
%><%@ include file="header_navi.cpsp" %> %><%@ include file="header_navi_chr.cpsp" %>
<div class="col-md-10 equel-grid mb-3">
<small class="text-gray d-block mt-3">
<% if(sumTransactions > 0 && sumTransactions - notReadyTransactions != 1) { %>
<% if(notReadyTransactions > 0) { %>
<%= sumTransactions - notReadyTransactions %> <%= gettext("von") %> <%= sumTransactions %> <%= gettext("Transaktionen sind bereit zum best&auml;tigen") %>
<% } else { %>
<%= sumTransactions %> <%= gettext("Transaktionen warten darauf best&auml;tigt zu werden.") %>
<% } %>
<% } %>
<% if(state == PAGE_NO_TRANSACTIONS) { %>
<% if(sumTransactions == 0) { %>
<%= gettext("Es gibt zurzeit keine Transaktionen zum best&auml;tigen") %>
<% } else { %>
<%= gettext("Transaktion(en) werden noch vorbereitet, bitte lade die Seite in wenigen Augenblicken erneut.") %>
<% } %>
<% } %>
</small>
</div>
<div class="content-container main-container">
<div class="action-form">
<p class="form-header"><%= gettext("Transaktion Unterzeichnen") %></p>
<% if(state == PAGE_TRANSACTION_TRANSFER) {
auto transferTransaction = processingTransaction->getTransferTransaction();
memo = transferTransaction->getMemo();
%>
<div class="form-content">
<p><%= gettext("&Uuml;berweisung") %></p>
<div class="content-table">
<div class="content-row content-row-header">
<span class="content-cell"><%= gettext("Konto") %></span>
<span class="content-cell"><%= gettext("Gradido") %></span>
</div>
<% for(int i = 0; i < transferTransaction->getKontoTableSize(); i++) { %>
<%= transferTransaction->getKontoNameCellChr(i) %>
<%= transferTransaction->getAmountCellChr(i) %>
<% } %>
<div class="content-row content-row-bg">
<span class="content-cell">Normaler&nbsp;User&nbsp;&lt;info@software-labor.de&gt;</span>
<span class="content-cell alert-color">-10 GDD</span>
</div>
<div class="content-row">
<span class="content-cell">dario&nbsp;frodo&nbsp;&lt;dariofrodo@gmx.de&gt;</span>
<span class="content-cell success-color">10 GDD</span>
</div>
</div>
<div class="content-table">
<div class="content-row content-row-header">
<span class="content-cell">Aktives Konto</span>
</div>
<div class="content-row">
<span class="content-cell">Normaler User &lt;info@software-labor.de&gt;</span>
</div>
</div>
<div class="content-table">
<div class="content-row content-row-header">
<span class="content-cell">Verwendungszweck</span>
</div>
<div class="content-row content-row-bg">
<span class="content-cell">&nbsp;</span>
</div>
</div>
<form>
<button type="submit" class="form-button" name="ok" value="ok">
<i class="material-icons-outlined">verified_user</i>
Transaktion unterzeichnen
</button>
<button type="submit" class="form-button button-cancel" name="abort" value="abort">
<i class="material-icons-outlined">delete</i>
Transaktion verwerfen
</button>
</form>
</div>
</div>
</div>
<div class="col-md-10 equel-grid mb-3"> <div class="col-md-10 equel-grid mb-3">
<small class="text-gray d-block mt-3"> <small class="text-gray d-block mt-3">
<% if(sumTransactions > 0 && sumTransactions - notReadyTransactions != 1) { %> <% if(sumTransactions > 0 && sumTransactions - notReadyTransactions != 1) { %>
@ -125,7 +200,7 @@ enum PageState {
<%= transferTransaction->getKontoNameCell(i) %> <%= transferTransaction->getKontoNameCell(i) %>
<%= transferTransaction->getAmountCell(i) %> <%= transferTransaction->getAmountCell(i) %>
</tr> </tr>
<% } %> <% } %>
</tbody> </tbody>
</table> </table>
</div> </div>
@ -194,4 +269,4 @@ enum PageState {
</div> </div>
</div> </div>
</div> </div>
<% } %><%@ include file="footer_ripple.cpsp" %> <% } %><%@ include file="footer_chr.cpsp" %>

22
src/cpsp/footer_chr.cpsp Normal file
View File

@ -0,0 +1,22 @@
</div>
</div>
<div class="footer">
<ul class="nav-horizontal">
<li><a href="https://gradido.net/de/datenschutz/" target="_blank">Datenschutzerklärung</a></li>
<li><a href="https://gradido.net/de/impressum/" target="_blank">Impressum</a></li>
</ul>
</div>
<div class="nav-bottom">
<small class="">Copyright © 2020 Gradido</small>
</div>
<div class="bottomleft">
<%= mTimeProfiler.string() %>
</div>
<div class="bottomright">
<p>Community Server in Entwicklung</p>
<p>Alpha <%= ServerConfig::g_versionString %></p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Gradido Login Server: <%= pageName %></title>
<link href="<%= ServerConfig::g_php_serverPath %>favicon.ico" type="image/x-icon" rel="icon" />
<link href="<%= ServerConfig::g_php_serverPath %>favicon.ico" type="image/x-icon" rel="shortcut icon" />
<link rel="stylesheet" href="<%= ServerConfig::g_php_serverPath %>css/main.css" />
<script src="<%= ServerConfig::g_php_serverPath %>js/basic.js"></script>
</head>
<body>
<div class="layout">
<div class="header-notify">
</div>
<div class="sidebar1 nav-menu initial">
<a href="<%= ServerConfig::g_php_serverPath %>">
<picture class="logo big visible">
<source srcset="<%= ServerConfig::g_php_serverPath %>img/logo_schrift_half.webp" type="image/webp">
<source srcset="<%= ServerConfig::g_php_serverPath %>img/logo_schrift_half.png" type="image/png">
<img src="<%= ServerConfig::g_php_serverPath %>img/logo_schrift_half.png" class="logo big visible" alt="Logo">
</picture>
<picture class="logo small">
<source srcset="<%= ServerConfig::g_php_serverPath %>img/logo_half.webp" type="image/webp">
<source srcset="<%= ServerConfig::g_php_serverPath %>img/logo_half.png" type="image/png">
<img src="<%= ServerConfig::g_php_serverPath %>img/logo_half.png" class="logo small" alt="Logo">
</picture>
</a>
<div>
<i class="material-icons-outlined nav-main-button">menu</i>
</div>
<div class="flash-messages"><%= getErrorsHtml() %></div>
<div class="nav-vertical">
<ul>
<li><a href="<%= ServerConfig::g_php_serverPath %>state-balances/overview" class=""><i class="material-icons-outlined nav-icon " title="Kontoübersicht ( <%= TransactionBase::amountToString(userBalance) %> GDD )">account_balance_wallet</i><span
class="link-title">Kontoübersicht ( <%= TransactionBase::amountToString(userBalance) %> GDD )</span></a></li>
<li><a href="<%= ServerConfig::g_php_serverPath %>dashboard/index" class=""><i class="material-icons-outlined nav-icon " title="Startseite">home</i><span
class="link-title">Startseite</span></a></li>
<li class=' selected'><a href="<%= ServerConfig::g_php_serverPath %>transaction-send-coins/create" class=""><i class="material-icons-outlined nav-icon "
title="Überweisung">account_balance</i><span class="link-title">Überweisung</span></a></li>
<li><a href="https://elopage.com/s/gradido/sign_in" class="" target="_blank"><i class="material-icons-outlined nav-icon "
title="Mitgliederbereich">people_alt</i><span class="link-title">Mitgliederbereich</span></a></li>
</ul>
</div>
</div>
<div class="content">
<div class="nav-content">
<ul class='nav-content-list'>
<li><a href="/" class=""><span class="link-title">Startseite</span></a></li>
<li class='nav-content-separator'>-</li>
<li class='selected'><span class="link-title"><%= pageName %></span></li>
</ul>
</div>