diff --git a/client/scripts/database.js b/client/scripts/database.js
index 87c0935..bafa1ea 100644
--- a/client/scripts/database.js
+++ b/client/scripts/database.js
@@ -256,6 +256,147 @@ function dbGetResultCalculated(regatta) {
});
}
+function dbGetRanking(minDate, maxDate, jugend, jugstrict) {
+ return new Promise(async function(resolve) {
+ var rankNoResults = [];
+
+ var sailors = await dbGetData('sailors');
+ var regattas = await dbGetRegattasRange(minDate, maxDate);
+
+ var sailorIds = {};
+ for (s in sailors) {
+ sailorIds[sailors[s].id] = s;
+ }
+
+ for (var i in sailors) {
+ sailors[i].regattas = {};
+ sailors[i].tmp_rlp = [];
+ }
+
+ for (var i in regattas) {
+ var regatta = regattas[i];
+
+ // regatta has to be min. 2 days to be ranking regatta
+ if (regatta.length < 2) continue;
+
+ var results = await dbGetDataIndex('results', 'regatta', regatta.id);
+ if (results.length <= 0) {
+ if (regatta.dateTo <= getToday()) {
+ if (regatta.canceled == '0') {
+ rankNoResults.push(regatta);
+ }
+ }
+ continue;
+ }
+
+ // in one race there must be at least 10 boats started
+ var ok = false;
+ for (var j = 1; j <= regatta.races; j ++) {
+ var temp = 0;
+ for (var r in results) {
+ if ((results[r]['race' + j] != 'DNC') && (results[r]['race' + j] != 'DNS')) {
+ temp ++;
+ }
+ }
+ if (temp >= 10) {
+ ok = true;
+ break;
+ }
+ }
+ if (!ok) continue;
+
+ var fb = regatta.finishedBoats;
+
+ // calc m
+ var m;
+ if (regatta.m > 0) {
+ m = regatta.m;
+ } else if (regatta.races <= 4) {
+ m = regatta.races;
+ } else {
+ if ((regatta.length > 2) && (regatta.races >= 6)) {
+ m = 5;
+ } else {
+ m = 4;
+ }
+ }
+
+ // add regatta to each sailor
+ for (var r in results) {
+ var result = results[r];
+
+ if (result.rlp == 0) continue;
+
+ // check if crew is youth
+ // TODO: not used
+
+ sailors[sailorIds[result.steuermann]].regattas[regatta.id] = {
+ regatta: regatta.id,
+ boat: result.boat,
+ crew: result.crew,
+ place: result.place,
+ fb: fb,
+ rlp: result.rlp,
+ used: 0,
+ m: m
+ };
+ for (var j = 0; j < m; j ++) {
+ sailors[sailorIds[result.steuermann]].tmp_rlp.push([regatta.id, result.rlp]);
+ }
+ }
+ }
+
+ // remove not german or not youth sailors
+ for (var i = sailors.length - 1; i >= 0; i --) {
+ if (sailors[i].german == '0') {
+ sailors.splice(i, 1);
+ } else if (jugend) {
+ if (((sailors[i].year != null) && (sailors[i].year < (formatDate('Y', maxDate) - YOUTH_AGE))) ||
+ ((sailors[i].year == null) && (jugstrict))) {
+ sailors.splice(i, 1);
+ }
+ }
+ }
+
+ for (var i = sailors.length - 1; i >= 0; i --) {
+ // sort rlps desc
+ sailors[i].tmp_rlp.sort(function (a,b) {
+ return b[1] - a[1];
+ });
+
+ // calc mean rlp
+ var sum = 0;
+ var cnt = 0;
+ for (var t in sailors[i].tmp_rlp) {
+ var r = sailors[i].tmp_rlp[t];
+ sum += parseFloat(r[1]);
+ sailors[i].regattas[r[0]].used ++;
+ cnt ++;
+ if (cnt >= 9) break;
+ }
+ delete sailors[i].tmp_rlp;
+ if (cnt > 0) {
+ var rlp = sum / cnt;
+ sailors[i].rlp = rlp;
+ sailors[i].m = cnt;
+ } else {
+ sailors.splice(i, 1);
+ }
+ }
+
+ sailors.sort(function (a,b) {
+ if (a.m != b.m) return b.m - a.m;
+ return b.rlp - a.rlp;
+ });
+
+ for (var i = 0; i < sailors.length; i ++) {
+ sailors[i].rank = (i + 1);
+ }
+
+ resolve([sailors, rankNoResults]);
+ });
+}
+
async function updateSyncStatus() { // TODO
// var syncStatus = document.getElementById('syncstatus');
// var lastSync = await dbGetData('update_times', 'last_sync');
diff --git a/client/scripts/regatten.js.php b/client/scripts/regatten.js.php
index 326fef0..25fcc02 100644
--- a/client/scripts/regatten.js.php
+++ b/client/scripts/regatten.js.php
@@ -9,6 +9,8 @@
const QUERY_URL = '/api/';
const BOATCLASS = '';
const LINK_PRE = '/';
+const YOUTH_AGE = '';
+const YOUTH_GERMAN_NAME = '';
var randomId = function() { return '_' + Math.random().toString(36).substr(2, 9); }
diff --git a/client/styles/regatten.css b/client/styles/regatten.css
index 0815a55..efea685 100644
--- a/client/styles/regatten.css
+++ b/client/styles/regatten.css
@@ -43,6 +43,107 @@
text-align: right;
}
+/*** RANKING LIST ***/
+.ranking-list > div {
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+ border-bottom: 1px solid #dee2e6;
+ cursor: pointer;
+}
+
+.ranking-list > div:last-child {
+ border: 0;
+ padding-bottom: 0;
+}
+
+.ranking-list div {
+ white-space: nowrap;
+}
+
+.ranking-list > div > div > div {
+ display: inline-block;
+}
+
+.ranking-list > div > div:nth-child(1) > div:nth-child(1) {
+ width: 25%;
+}
+.ranking-list > div > div:nth-child(1) > div:nth-child(2) {
+ width: 50%;
+ text-align: right;
+}
+.ranking-list > div > div:nth-child(1) > div:nth-child(3) {
+ width: 25%;
+ text-align: right;
+}
+
+.ranking-list > div > div:nth-child(2) > div:nth-child(1) {
+ width: 75%;
+}
+.ranking-list > div > div:nth-child(2) > div:nth-child(2) {
+ width: 25%;
+ text-align: right;
+}
+
+/*** RANKING DETAIL LIST ***/
+.ranking-detail-list > div {
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+ border-bottom: 1px solid #dee2e6;
+ cursor: pointer;
+}
+
+.ranking-detail-list > div:last-child {
+ border: 0;
+ padding-bottom: 0;
+}
+
+.ranking-detail-list div {
+ white-space: nowrap;
+}
+
+.ranking-detail-list > div > div > div {
+ display: inline-block;
+}
+
+.ranking-detail-list > div > div:nth-child(2) > div:nth-child(1) {
+ width: 50%;
+}
+.ranking-detail-list > div > div:nth-child(2) > div:nth-child(2) {
+ width: 25%;
+ text-align: right;
+}
+.ranking-detail-list > div > div:nth-child(2) > div:nth-child(3) {
+ width: 25%;
+ text-align: right;
+}
+
+.ranking-detail-list > div > div:nth-child(3) {
+ border-bottom: 1px dashed #dee2e6;
+}
+.ranking-detail-list > div > div:nth-child(3) > div:nth-child(1) {
+ width: 50%;
+}
+.ranking-detail-list > div > div:nth-child(3) > div:nth-child(2) {
+ width: 50%;
+ text-align: right;
+}
+
+.ranking-detail-list > div > div:nth-child(4) > div:nth-child(1) {
+ width: 50%;
+}
+.ranking-detail-list > div > div:nth-child(4) > div:nth-child(2) {
+ width: 50%;
+ text-align: right;
+}
+
+.ranking-detail-list > div > div:nth-child(n+5) > div:nth-child(1) {
+ width: 75%;
+}
+.ranking-detail-list > div > div:nth-child(n+5) > div:nth-child(2) {
+ width: 25%;
+ text-align: right;
+}
+
/*** NORMAL LIST ***/
.normal-list > div {
padding-top: 1rem;
diff --git a/server/content/calc.php b/server/content/calc.php
new file mode 100644
index 0000000..650e2c4
--- /dev/null
+++ b/server/content/calc.php
@@ -0,0 +1,65 @@
+RLP Rechner";
+ $content .= '
Einfach Ranglistenpunkte berechnen
';
+
+ $sp['output'] .= $tpl->load('card', [$content]);
+
+ // Inputs
+ $content = $tpl->load('input', ['html-id' => 'input-rlf', 'placeholder' => 'Ranglistenfaktor (rlf)', 'type' => 'number']);
+ $content .= $tpl->load('input', ['html-id' => 'input-m', 'placeholder' => 'Multiplikator (m)', 'type' => 'number']);
+ $content .= $tpl->load('input', ['html-id' => 'input-fb', 'placeholder' => 'Gezeitete Boote (fb)', 'type' => 'number']);
+ $content .= $tpl->load('input', ['html-id' => 'input-pl', 'placeholder' => 'Platzierung (pl)', 'type' => 'number']);
+ $content .= $tpl->load('button', ['Hinzufügen', '#', 'html-id' => 'button-add']);
+
+ $sp['output'] .= $tpl->load('card', [$content]);
+
+ // Table
+ $thead = 'RLF m fb pl RLP ';
+ $content = $tpl->load('table', [$thead, 'html-id' => 'table-races']);
+ $content .= '
';
+
+ $sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-races']);
+
+ // Infos
+ $content = 'Hinweise zum Ausfüllen ';
+ $content .= 'Ranglistenfaktor (RLF) ';
+ $content .= 'Der Ranglistenfaktor ist ein von der KV vorgegebener Faktor zwischen 1,0 und 1,6 zur Gewichtung der Regatten. ';
+ $content .= 'Du findest ihn in der Regatten-Liste .';
+ $content .= '
';
+ $content .= 'Multiplikator (m) ';
+ $content .= 'Der Multiplikator gibt an, wie oft eine Regatta in die Wertung eingeht. ';
+ $content .= 'Er ist abhängig von den tatsächlich gesegelten Wettfahrten. Dabei gilt: ';
+ $content .= '1 Wettfahrt => m = 1 ';
+ $content .= '2 Wettfahrten => m = 2 ';
+ $content .= '3 Wettfahrten => m = 3 ';
+ $content .= '4 oder mehr Wettfahrten => m = 4 ';
+ $content .= 'Ist die Regatta für mehr als 2 Tage ausgeschrieben, gilt außerdem: ';
+ $content .= '6 oder mehr Wettfahrten => m = 5 ';
+ $content .= '
';
+ $content .= 'Gezeitete Boote (fb) ';
+ $content .= 'Die Anzahl der Boote, die in mindestens einer Wettfahrt ins Ziel gefahren sind.';
+ $content .= '
';
+ $content .= 'Platzierung (pl) ';
+ $content .= 'Deine Platzierung in den Endergebnissen';
+ $content .= '
';
+
+ $sp['output'] .= $tpl->load('card', [$content]);
+
+ $content = 'Berechnung ';
+ $content .= 'Die Ranglistenpunkte (RLP) für eine Regatta berechnen sich nach folgender Formel: ';
+ $content .= 'RLP = RLF * 100 * ((fb + 1 - pl) / fb) ';
+ $content .= 'Diese Ranglistenpunkte können je nach Multiplikator bis zu 5 mal in die Wertung eingehen. ';
+ $content .= 'Der Mittelwert der 9 besten Wertungen ergibt die Ranglistenpunkte.';
+ $content .= '
';
+
+ $sp['output'] .= $tpl->load('card', [$content]);
+
+ $sp['scripts'] .= $scripts->load('calc');
+
+?>
\ No newline at end of file
diff --git a/server/content/rank.php b/server/content/rank.php
new file mode 100644
index 0000000..2f7d543
--- /dev/null
+++ b/server/content/rank.php
@@ -0,0 +1,46 @@
+Ranglisten";
+
+ $options = 'Jahres-Rangliste ';
+ $options .= 'Jugend-Rangliste ';
+ $options .= '' . $_CLASS['youth-german-name'] . '-Rangliste ';
+ $options .= 'Benutzerdefiniert ';
+ $content .= $tpl->load('select', ['html-id' => 'select-type', 'placeholder' => 'Rangliste', 'options' => $options, 'css-class' => 'mt-3 mb-0']);
+ $content .= $tpl->load('select', ['html-id' => 'select-year', 'placeholder' => 'Jahr', 'css-class' => 'mt-3 mb-0']);
+ $content .= $tpl->load('input', ['html-id' => 'input-from', 'placeholder' => 'Von', 'type' => 'date', 'css-class' => 'mt-3']);
+ $content .= $tpl->load('input', ['html-id' => 'input-to', 'placeholder' => 'Bis', 'type' => 'date']);
+ $chbox = $tpl->load('checkbox', ['html-id' => 'input-jugend', 'placeholder' => 'Jugend']);
+ $content .= '' . $chbox . '
';
+ $chbox = $tpl->load('checkbox', ['html-id' => 'input-jugstrict', 'placeholder' => 'Streng']);
+ $content .= '' . $chbox . '
';
+ $content .= $tpl->load('button', ['Anzeigen', '#', 'html-id' => 'button-show']);
+
+ $sp['output'] .= $tpl->load('card', [$content]);
+
+ // No Results
+ $content = 'ACHTUNG ';
+ $content .= 'Zu folgenden Regatten wurden noch keine Ergebnisse hinterlegt:
';
+ $content .= '';
+
+ $sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-noresults', 'css-class' => 'bg-red2-dark']);
+
+ // Ranking
+ $content = $tpl->load('input', ['html-id' => 'input-search', 'placeholder' => 'Suche', 'type' => 'text']);
+ $content .= '
';
+
+ $sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-rank']);
+
+ // Menu
+ $items = '';
+ $items .= '
';
+ $sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-rank', 'title' => 'Ranglisten-Details', 'height' => 500]);
+
+ $sp['scripts'] .= $scripts->load('rank');
+
+?>
\ No newline at end of file
diff --git a/server/content/result.php b/server/content/result.php
new file mode 100644
index 0000000..8b63561
--- /dev/null
+++ b/server/content/result.php
@@ -0,0 +1,20 @@
+';
+ $content .= '
';
+
+ $sp['output'] .= $tpl->load('card', [$content]);
+
+ // Results
+ $content = '
';
+ $content .= $tpl->load('table', ['html-id' => 'table-results', 'css-class' => 'mb-0 text-nowrap']);
+
+ $sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-results']);
+
+ $sp['scripts'] .= $scripts->load('result');
+
+?>
\ No newline at end of file
diff --git a/server/scripts/calc.js b/server/scripts/calc.js
new file mode 100644
index 0000000..1912e6c
--- /dev/null
+++ b/server/scripts/calc.js
@@ -0,0 +1,92 @@
+var races = [];
+var firstCall = true;
+
+function reCalc() {
+ setTimeout(function(){
+ if (races.length > 0) {
+ $('#card-races').show();
+ $('#p-result').text('Berechne...');
+ var rlps = [];
+ var tbody = '';
+ for (var i = 0; i < races.length; i ++) {
+ tbody += '';
+ tbody += '' + races[i].rlf + ' ';
+ tbody += '' + races[i].m + ' ';
+ tbody += '' + races[i].fb + ' ';
+ tbody += '' + races[i].pl + ' ';
+ tbody += '' + races[i].rlp.toFixed(3) + ' ';
+ tbody += ' ';
+ tbody += ' ';
+ for (var j = 0; j < races[i].m; j ++) {
+ rlps.push(races[i].rlp);
+ }
+ }
+ $('#table-races').find('tbody').html(tbody);
+ rlps.sort(function (a,b) {
+ return b-a;
+ });
+ var sum = 0;
+ var cnt = Math.min(rlps.length, 9);
+ for (var i = 0; i < cnt; i ++) {
+ sum += rlps[i];
+ }
+ $('#p-result').html('' + (sum / cnt).toFixed(3) + ' Punkte aus ' + cnt + ' Wertungen.');
+ } else {
+ $('#card-races').hide();
+ }
+ }, 0);
+}
+
+function addRace() {
+ var rlf = parseFloat($('#input-rlf').val().replace(',', '.'));
+ var m = parseFloat($('#input-m').val());
+ var fb = parseFloat($('#input-fb').val());
+ var pl = parseFloat($('#input-pl').val().replace(',', '.'));
+
+ if (isNaN(rlf) || (rlf < 1) || (rlf > 1.6)) {
+ toastError('RLF ungültig');
+ return;
+ }
+ if (isNaN(m) || (m < 1) || (m > 5)) {
+ toastError('m ungültig');
+ return;
+ }
+ if (isNaN(fb) || (fb < 1)) {
+ toastError('fb ungültig');
+ return;
+ }
+ if (isNaN(pl) || (pl < 1) || (pl > (fb + 1))) {
+ toastError('pl ungültig');
+ return;
+ }
+
+ var race = {
+ rlf: rlf,
+ m: m,
+ fb: fb,
+ pl: pl,
+ rlp: (100 * rlf * ((fb + 1 - pl) / fb))
+ };
+
+ $('#input-rlf').val('');
+ $('#input-m').val('');
+ $('#input-fb').val('');
+ $('#input-pl').val('');
+
+ races.push(race);
+ reCalc();
+}
+
+function removeRace(id) {
+ if ((id >= 0) && (id < races.length)) races.splice(id, 1);
+ reCalc();
+}
+
+var siteScript = async function () {
+ if (firstCall) {
+ firstCall = false;
+ $('#button-add').click(addRace);
+ }
+ reCalc();
+ hideLoader();
+}
\ No newline at end of file
diff --git a/server/scripts/index.js b/server/scripts/index.js
index 48f95c6..9f27bbe 100644
--- a/server/scripts/index.js
+++ b/server/scripts/index.js
@@ -19,14 +19,23 @@ var siteScript = async function() {
if (watched.length > 0) {
var year = (new Date()).getFullYear();
$('#th-ranking').html('Rangliste ' + year);
- // TODO: get ranking
+ var ranking = (await dbGetRanking(parseDate('01.12.' + (year - 1)), parseDate('30.11.' + year), false, false))[0];
tbody = '';
for (i in watched) {
sailor = watched[i];
tbody += '' + sailor.name + ' ';
- // TODO: check if ranking and output
- //tbody += 'nicht in der Rangliste ';
- tbody += 'Ranglisten werden aktuell noch nicht unterstützt ';
+ var rank = null;
+ for (r in ranking) {
+ if (ranking[r].id == sailor.id) {
+ rank = ranking[r].rank;
+ break;
+ }
+ }
+ if (rank == null) {
+ tbody += 'nicht in der Rangliste ';
+ } else {
+ tbody += '' + rank + '. Platz';
+ }
tbody += ' ';
}
$('#table-favorites').find('tbody').html(tbody);
diff --git a/server/scripts/rank.js b/server/scripts/rank.js
new file mode 100644
index 0000000..decaffc
--- /dev/null
+++ b/server/scripts/rank.js
@@ -0,0 +1,335 @@
+function onDetailClicked(regatta) {
+ location.href = LINK_PRE + 'result?regatta=' + regatta;
+}
+
+async function onRankingClicked(id) {
+ var sailor = null;
+ for (var i in ranking) {
+ if (ranking[i].id == id) {
+ sailor = ranking[i];
+ break;
+ }
+ }
+ if (sailor == null) return;
+
+ $('#menu-rank').find('.menu-title').find('p').text(sailor.name);
+ if (lastRanking != null) {
+ var lastRank;
+ if (sailor.id in lastRanking) {
+ lastRank = lastRanking[sailor.id] + '.';
+ } else {
+ lastRank = 'nicht in der Rangliste';
+ }
+ $('#menu-item-text').text('Vorheriges Jahr: ' + lastRank);
+ $('#menu-item-text').show();
+ } else {
+ $('#menu-item-text').hide();
+ }
+
+ list = '';
+ for (var i in sailor.regattas) {
+ var entry = sailor.regattas[i];
+ var regatta = entry.regatta;
+ var boat = await dbGetData('boats', entry.boat);
+
+ var dateFrom = parseDate(regatta.date);
+ var dateTo = parseDate(regatta.date);
+ dateTo.setDate(dateTo.getDate() + Math.max(parseInt(regatta.length) - 1, 0));
+
+ list += '';
+
+ // ZEILE 1
+ list += '
' + regatta.name + '
';
+
+ // ZEILE 2
+ list += '
';
+
+ // DATE
+ list += '
' + formatDate('d.m.Y', dateFrom) + ' - ' + formatDate('d.m.Y', dateTo) + '
';
+
+ // m
+ list += '
m: ' + entry.m + '
';
+
+ // rlf
+ list += '
RLF: ' + parseFloat(regatta.rlf).toFixed(2) + '
';
+
+ list += '
';
+
+ // ZEILE 3
+ list += '
';
+
+ // Place
+ list += '
Platz ' + entry.place + ' / ' + entry.fb + '
';
+
+ // rlp
+ var color;
+ if (entry.used == 0) { color = 'color-red2-dark'; }
+ else if (entry.used == entry.m) { color = 'color-green2-dark'; }
+ else { color = 'color-yellow2-dark'; }
+ list += '
Punkte: ' + entry.used + ' x ' + parseFloat(entry.rlp).toFixed(2) + '
';
+
+ list += '
';
+
+ // ZEILE 4
+ list += '
';
+
+ // Sailnumber
+ list += '
' + boat.sailnumber + '
';
+
+ // Boatname
+ list += '
' + boat.name + '
';
+
+ list += '
';
+
+ // ZEILE 5...
+ var crew = entry.crew.split(',');
+ for (var c in crew) {
+ var cr = await dbGetData('sailors', crew[c]);
+ if (cr != null) {
+ list += '
';
+
+ // Name
+ list += '
' + cr.name + '
';
+
+ // Year
+ list += '
' + ((cr.year != null) ? ('(' + cr.year + ')') : '') + '
';
+
+ list += '
';
+ }
+ }
+
+ list += '
';
+ }
+ $('#div-details').html(list);
+
+ $('#menu-rank').showMenu();
+ $('#menu-rank').scrollTop(0);
+}
+
+function selectChange(callSiteScript = true) {
+ var type = $('#select-type').val();
+ var year = parseInt($('#select-year').val());
+ if (type == "user") {
+ $('#select-year').parent().hide();
+ $('#input-from').parent().show();
+ $('#input-to').parent().show();
+ $('#input-jugend').parent().parent().show();
+ $('#input-jugstrict').parent().parent().show();
+ $('#button-show').show();
+ } else {
+ $('#select-year').parent().show();
+ $('#input-from').parent().hide();
+ $('#input-to').parent().hide();
+ $('#input-jugend').parent().parent().hide();
+ $('#input-jugstrict').parent().parent().hide();
+ $('#button-show').hide();
+
+ var from, to, jugend, jugstrict;
+ switch (type) {
+ case 'year':
+ from = (year - 1) + '-12-01';
+ to = year + '-11-30';
+ jugend = jugstrict = false;
+ break;
+ case 'youth':
+ from = (year - 1) + '-12-01';
+ to = year + '-11-30';
+ jugend = jugstrict = true;
+ break;
+ case 'idjm':
+ // TODO
+ from = (year - 1) + '-12-01';
+ to = year + '-11-30';
+ jugend = true;
+ jugstrict = false;
+ break;
+ }
+
+ $('#input-from').val(from);
+ $('#input-to').val(to);
+ $('#input-jugend').prop('checked', jugend);
+ $('#input-jugstrict').prop('checked', jugstrict);
+
+ if (callSiteScript && (typeof siteScript === 'function'))
+ siteScript();
+ }
+}
+
+function initSelects() {
+ var type = findGetParameter('type');
+ var year = findGetParameter('year');
+ if (type === null) type = 'year';
+ if (year === null) year = new Date().getFullYear();
+
+ $('#select-type').val(type);
+
+ $('#select-year').html('' + year + ' ');
+ $('#select-year').val(year);
+
+ selectChange(false);
+}
+
+var firstCall = true;
+var rows = [];
+var ranking;
+var lastRanking;
+
+async function drawList () {
+ window.setTimeout(function () {
+ var list = '';
+ rows.forEach(function (entry) {
+ if (entry == null) {
+ list += 'Ende der Rangliste gemäß DSV-Ranglistenverordnung (min. m = 9 Wertungen)
';
+ } else if (search($('#input-search').val(), entry.keywords)) {
+ list += entry.content;
+ }
+ });
+ $('#div-rank').html(list);
+ }, 0);
+}
+
+var siteScript = async function() {
+ if (firstCall) {
+ firstCall = false;
+ initSelects();
+ $('#select-type').change(selectChange);
+ $('#select-year').change(selectChange);
+ $('#button-show').click(siteScript);
+ $('#input-search').on('input', drawList);
+ }
+
+ var minDate = parseDate($('#input-from').val());
+ var maxDate = parseDate($('#input-to').val());
+ var jugend = $('#input-jugend').prop('checked');
+ var jugstrict = $('#input-jugstrict').prop('checked');
+ var dbRanking = await dbGetRanking(minDate, maxDate, jugend, jugstrict);
+ ranking = dbRanking[0];
+
+ lastRanking = null;
+ if (($('#select-type').val() == 'year') || ($('#select-type').val() == 'youth')) {
+ lastRanking = {};
+ var lYear = parseInt($('#select-year').val()) - 1;
+ var lMinDate = parseDate((lYear - 1) + '-12-01');
+ var lMaxDate = parseDate(lYear + '-11-30');
+ var lDbRanking = (await dbGetRanking(lMinDate, lMaxDate, jugend, jugstrict))[0];
+ for (var i in lDbRanking) {
+ lastRanking[lDbRanking[i].id] = lDbRanking[i].rank;
+ }
+ }
+
+ var selectedYear = $('#select-year').val();
+
+ var years = await dbGetData('years');
+ years.sort(function (a, b) {
+ if (a['year'] > b['year']) return -1;
+ if (a['year'] < b['year']) return 1;
+ return 0;
+ });
+ var options = '';
+ for (id in years) {
+ var year = years[id]['year'];
+ options += '' + year + ' ';
+ }
+ $('#select-year').html(options);
+ $('#select-year').val(selectedYear);
+
+ if (dbRanking[1].length > 0) {
+ $('#card-noresults').show();
+ list = '';
+ for (id in dbRanking[1]) {
+ list += '';
+ list += dbRanking[1][id].name;
+ list += ' ';
+ }
+ $('#ul-noresults').html(list);
+ } else {
+ $('#card-noresults').hide();
+ }
+
+ var count = ranking.length;
+ if (count > 0) {
+ $('#input-search').parent().show();
+
+ var dsvEnd = false;
+
+ rows = [];
+
+ for (id in ranking) {
+ var entry = ranking[id];
+
+ for (var i in entry.regattas) {
+ entry.regattas[i].regatta = await dbGetData('regattas', entry.regattas[i].regatta);
+ }
+ entry.regattas = Object.values(entry.regattas);
+ entry.regattas.sort(function (a,b) {
+ return a.regatta.date.localeCompare(b.regatta.date);
+ });
+
+ var club = null;
+ if (entry['club'] != null)
+ club = await dbGetData('clubs', entry['club']);
+
+ var row = { keywords: [], content: '' };
+ row.keywords.push(entry['name']);
+ if (entry['year'] != null) row.keywords.push(entry['year']);
+ if (club != null) row.keywords.push(club['kurz'], club['name']);
+
+ if (!dsvEnd && (entry.m < 9)) {
+ rows.push(null);
+ dsvEnd = true;
+ }
+
+ row.content += '';
+
+ // ZEILE 1
+ row.content += '
';
+
+ // Rank
+ var icon = '';
+ if (lastRanking != null) {
+ if (entry.id in lastRanking) {
+ if (entry.rank < lastRanking[entry.id]) { icon = 'color-green2-dark fa-caret-up'; }
+ else if (entry.rank > lastRanking[entry.id]) { icon = 'color-red2-dark fa-caret-down'; }
+ else { icon = 'color-yellow2-dark fa-minus'; }
+ } else {
+ icon = 'color-green2-dark fa-caret-up';
+ }
+ icon = '
';
+ }
+ row.content += '
' + icon + '' + entry.rank + '.
';
+
+ // m
+ row.content += '
m = ' + entry.m + '
';
+
+ // rlp
+ row.content += '
' + entry.rlp.toFixed(3) + '
';
+
+ row.content += '
';
+
+ // ZEILE 2
+ row.content += '
';
+
+ // Name
+ row.content += '
' + entry.name + '
';
+
+ // Year
+ row.content += '
' + ((entry.year != null) ? ('(' + entry.year + ')') : '') + '
';
+
+ row.content += '
';
+
+ rows.push(row);
+ }
+
+ if (!dsvEnd) {
+ rows.push(null);
+ }
+
+ drawList();
+
+ } else {
+ $('#div-rank').html('Keine Ergebnisse gefunden!');
+ $('#input-search').parent().hide();
+ }
+
+ hideLoader();
+}
\ No newline at end of file
diff --git a/server/scripts/result.js b/server/scripts/result.js
new file mode 100644
index 0000000..4646356
--- /dev/null
+++ b/server/scripts/result.js
@@ -0,0 +1,77 @@
+var siteScript = async function() {
+ var regattaId = findGetParameter('regatta');
+ if (regattaId == null) {
+ $('#h1-title').text('Regatta nicht gefunden');
+ hideLoader();
+ return;
+ }
+ var regatta = await dbGetData('regattas', regattaId);
+ if (regatta == null) {
+ $('#h1-title').text('Regatta nicht gefunden');
+ hideLoader();
+ return;
+ }
+ var dateFrom = parseDate(regatta['date']);
+ var dateTo = parseDate(regatta['date']);
+ dateTo.setDate(dateTo.getDate() + Math.max(parseInt(regatta['length']) - 1, 0));
+
+ $('#h1-title').text(regatta.name);
+ $('#p-title').text(formatDate('d.m.Y', dateFrom) + ' - ' + formatDate('d.m.Y', dateTo));
+
+ var results = await dbGetResultCalculated(regatta);
+ if (results.length > 0) {
+ var m;
+ if (regatta.m > 0) {
+ m = regatta.m;
+ } else if (regatta.races <= 4) {
+ m = regatta.races;
+ } else {
+ if ((regatta.length > 2) && (regatta.races >= 6)) {
+ m = 5;
+ } else {
+ m = 4;
+ }
+ }
+ $('#p-info').text(regatta.races + ' Wettfahrten, ' + regatta.streicher + ' Streicher, m = ' + m);
+
+ $('#table-results').show();
+ var thead = '# Boot Crew ';
+ for (var i = 1; i <= regatta.races; i ++) thead += 'WF ' + i + ' ';
+ thead += 'Summe Netto # RLP ';
+ $('#table-results').find('thead').html(thead);
+
+ var tbody = '';
+ for (var r in results) {
+ var result = results[r];
+ var boat = await dbGetData('boats', result.boat);
+ var steuermann = (await dbGetData('sailors', result.steuermann)).name;
+ var cr = result.crew.split(',');
+ var crew = [];
+ for (c in cr) {
+ var s = await dbGetData('sailors', cr[c]);
+ if (s != null) crew.push(s.name);
+ }
+
+ tbody += '';
+ tbody += '' + result.place + '. ';
+ tbody += '' + boat.sailnumber + ' ' + boat.name + ' ';
+ tbody += '' + steuermann + ' ' + crew.join(' ') + ' ';
+ tbody += ' ';
+ for (var i = 0; i < regatta.races; i ++) {
+ tbody += '' + result.texts[i] + ' ';
+ }
+ tbody += ' ';
+ tbody += '' + result.brutto + ' ';
+ tbody += '' + result.netto + ' ';
+ tbody += '' + result.place + '. ';
+ tbody += '' + parseFloat(result.rlp).toFixed(2) + ' ';
+ tbody += ' ';
+ }
+ $('#table-results').find('tbody').html(tbody);
+ } else {
+ $('#p-info').text('Keine Ergebnisse gefunden.');
+ $('#table-results').hide();
+ }
+
+ hideLoader();
+}
\ No newline at end of file
diff --git a/server/templates/checkbox.html b/server/templates/checkbox.html
new file mode 100644
index 0000000..a6d4539
--- /dev/null
+++ b/server/templates/checkbox.html
@@ -0,0 +1,5 @@
+
+
+
+ $$placeholder;
+
\ No newline at end of file