Compare commits
160 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dfa2d7bd5 | ||
|
|
c983a1702f | ||
|
|
a1facbca85 | ||
|
|
fba8c8e958 | ||
|
|
8aa3e3ccb6 | ||
|
|
c319e568b6 | ||
|
|
748176159d | ||
|
|
053981175b | ||
|
|
7083b46831 | ||
|
|
2c8c99b8f0 | ||
|
|
07d01ae700 | ||
|
|
7da31729e9 | ||
|
|
08ab714a54 | ||
|
|
44c962b7b3 | ||
|
|
004280f3ea | ||
|
|
63a8d174d7 | ||
|
|
13f496f0a6 | ||
|
|
da553a8f8d | ||
|
|
69ef983c07 | ||
|
|
32473901d6 | ||
|
|
84320f3a67 | ||
|
|
cd30ba1ce6 | ||
|
|
1fb619d4ec | ||
|
|
0fd09c22a2 | ||
|
|
12ed412226 | ||
|
|
7fd1c1c6e7 | ||
|
|
4e85d3a993 | ||
|
|
5c22604896 | ||
|
|
a2fe4c2637 | ||
|
|
4a65b48520 | ||
|
|
4eb2970671 | ||
|
|
0298cefc8b | ||
|
|
e17f99d005 | ||
|
|
15d7060354 | ||
|
|
d38de287dd | ||
|
|
1cb6de2402 | ||
|
|
da2beac8d3 | ||
|
|
92a11bcfa5 | ||
|
|
2ddeac4ba4 | ||
|
|
fa4770e12a | ||
|
|
a845137873 | ||
|
|
a6f2568753 | ||
|
|
6d0fdea0e8 | ||
|
|
8bc0d9b15e | ||
|
|
1252c02d7c | ||
|
|
f617fa7923 | ||
|
|
3ff17a63e0 | ||
|
|
c66dc96598 | ||
|
|
f5d059202e | ||
|
|
5962e1cc90 | ||
|
|
9f3019b4c5 | ||
|
|
326ba4a6bd | ||
|
|
4228ec739d | ||
|
|
a38c48dab4 | ||
|
|
da48e79a36 | ||
|
|
de5abcdfaf | ||
|
|
6b1e35cc14 | ||
|
|
89e24f69b7 | ||
|
|
554b810e85 | ||
|
|
fbd1eaaae8 | ||
|
|
ce42f87227 | ||
|
|
e66f95ff50 | ||
|
|
fcd791ed65 | ||
|
|
439679bbbe | ||
|
|
9a8d6892f2 | ||
|
|
3b71f3d707 | ||
|
|
94c6a42106 | ||
|
|
0c9eb9c013 | ||
|
|
2034e8b659 | ||
|
|
e57bf4a426 | ||
|
|
3c8289d11c | ||
|
|
63de725ebd | ||
|
|
69efb93646 | ||
|
|
6f302d6527 | ||
|
|
bfc2f84f0f | ||
|
|
0660b2b6b3 | ||
|
|
3ee722f6c2 | ||
|
|
0ce58aeacc | ||
|
|
28ba380cca | ||
|
|
357449c1c6 | ||
|
|
e84eaa2562 | ||
|
|
de70522850 | ||
|
|
cf5f71d14e | ||
|
|
775a7bd27a | ||
|
|
34b47e40ab | ||
|
|
32ea581437 | ||
|
|
4106a177f8 | ||
|
|
16ccbca2af | ||
|
|
3fd9beae1e | ||
|
|
01d0ae96f9 | ||
|
|
c211817f78 | ||
|
|
9ff0b96837 | ||
|
|
7a3413b339 | ||
|
|
72ff731694 | ||
|
|
3959b208b5 | ||
|
|
7b500bf67d | ||
|
|
5c8c9db1de | ||
|
|
fa526b11a8 | ||
|
|
2dc2225263 | ||
|
|
fcf9dc9a20 | ||
|
|
203c2534eb | ||
|
|
730dd9112f | ||
|
|
13ceef37d9 | ||
|
|
54852f4383 | ||
|
|
8808d12bf1 | ||
|
|
c6d5450b0e | ||
|
|
15cbe15651 | ||
|
|
cb8a1817ae | ||
|
|
acf51ea71c | ||
|
|
be98511957 | ||
|
|
65608cdd5a | ||
|
|
d0996fa0c3 | ||
|
|
c9a90eb77c | ||
|
|
754cb6f77d | ||
|
|
5e926f3e75 | ||
|
|
138071769c | ||
|
|
26d9d83ba2 | ||
|
|
eaa08ba301 | ||
|
|
760c05286e | ||
|
|
3f676141d7 | ||
|
|
ae9bf02c49 | ||
|
|
c2a482bba1 | ||
|
|
06266b788d | ||
|
|
3db5ae1723 | ||
|
|
a45af73c25 | ||
|
|
b784733b69 | ||
|
|
f30eac8aa5 | ||
|
|
99b624ff92 | ||
|
|
e74ffa9a70 | ||
|
|
cbb398988d | ||
|
|
856f6c1d66 | ||
|
|
2ea26408be | ||
|
|
fb1ca6d28e | ||
|
|
6a5d06325d | ||
|
|
72ac8df460 | ||
|
|
246231fd0e | ||
|
|
3e533f65fc | ||
|
|
2533c3d66a | ||
|
|
cacee5a54a | ||
|
|
274aa85cf7 | ||
|
|
4317e4fe87 | ||
|
|
b7dec825ca | ||
|
|
6ca6a79dc3 | ||
|
|
d1e5d753b4 | ||
|
|
7afacc3fff | ||
|
|
77ea57d643 | ||
|
|
a72c462483 | ||
|
|
b739e6cc4e | ||
|
|
eb47cdf016 | ||
|
|
12c1a614bb | ||
|
|
0fb1bb0462 | ||
|
|
1b1176b952 | ||
|
|
00c1c93b80 | ||
|
|
876776eb5b | ||
|
|
a92dc45bb7 | ||
|
|
2bf623733d | ||
|
|
60caf85daa | ||
|
|
eddcff9e39 | ||
|
|
967ad50755 | ||
|
|
a437d05647 |
20
.github/ISSUE_TEMPLATE/-de--feature-anfrage.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/-de--feature-anfrage.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: "[DE] Feature-Anfrage"
|
||||
about: Schlage eine Idee für dieses Projekt vor
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Bezieht sich Deine Feature-Anfrage auf ein Problem? Bitte beschreiben.**
|
||||
Eine klare und präzise Beschreibung des Problems. Z.B. Ich bin immer frustriert, wenn [...]
|
||||
|
||||
**Beschreibe die gewünschte Lösung**
|
||||
Eine klare und präzise Beschreibung dessen, was passieren soll.
|
||||
|
||||
**Beschreibe Alternativen, die Du in Betracht gezogen hast**
|
||||
Eine klare und präzise Beschreibung aller alternativen Lösungen oder Funktionen, die Du in Betracht gezogen hast.
|
||||
|
||||
**Zusätzlicher Kontext**
|
||||
Füge hier weitere Kontexte oder Screenshots zur Feature-Anfrage hinzu.
|
||||
38
.github/ISSUE_TEMPLATE/-de--fehlerbericht.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/-de--fehlerbericht.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: "[DE] Fehlerbericht"
|
||||
about: Erstelle einen Bericht, um uns zu helfen, die App zu verbessern
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Beschreibe den Fehler**
|
||||
Eine klare und präzise Beschreibung des Fehlers.
|
||||
|
||||
**Reproduzierung**
|
||||
Schritte zum Reproduzieren des Fehlers:
|
||||
1. Gehe zu '...'
|
||||
2. Klicke auf '....'
|
||||
3. Scrolle nach unten zu '....'
|
||||
4. Sieh den Fehler
|
||||
|
||||
**Erwartetes Verhalten**
|
||||
Eine klare und präzise Beschreibung dessen, was Du erwartet hattest.
|
||||
|
||||
**Screenshots**
|
||||
Füge gegebenenfalls Screenshots hinzu, um Dein Problem zu erklären.
|
||||
|
||||
**Desktop (bitte verfolständige die folgenden Informationen):**
|
||||
- Betriebssystem: [z.B. Windows 10]
|
||||
- Browser [z.B. chrome, safari]
|
||||
- Version [z.B. 2.14]
|
||||
|
||||
**Smartphone (bitte verfolständige die folgenden Informationen):**
|
||||
- Gerät: [z.B. iPhone 6]
|
||||
- Betriebssystem: [z.B. iOS 8.1]
|
||||
- Browser [z.B. stock browser, safari]
|
||||
- Version [z.B. 2.14]
|
||||
|
||||
**Zusätzlicher Kontext**
|
||||
Füge hier einen anderen Kontext zum Problem hinzu.
|
||||
38
.github/ISSUE_TEMPLATE/-en--bug-report.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/-en--bug-report.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: "[EN] Bug report"
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. Windows 10]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 2.14]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone 6]
|
||||
- OS: [e.g. iOS 8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 2.14]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/-en--feature-request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/-en--feature-request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: "[EN] Feature request"
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -12,7 +12,7 @@ RewriteRule ^(.*)server(.*)$ / [R=301,L,NC]
|
||||
### CONTENT LOADER
|
||||
|
||||
# Keep this subfolders untouched
|
||||
RewriteRule ^(api)($|/) - [L]
|
||||
#RewriteRule ^(api)($|/) - [L]
|
||||
|
||||
# Show site
|
||||
RewriteRule ^([^\.]*)$ index.php?request=$1 [QSA]
|
||||
11
README.md
Normal file
11
README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Regatten.net App
|
||||
|
||||
Willkommen im GitHub-Repository unserer neuen Regatten.net App.
|
||||
|
||||
Falls sich jemand dafür interessiert, ist hier der gesamte Quellcode unserer neuen App zu finden.
|
||||
Bitte beachtet, dass diese App einschließlich dem gesamten Quellcode exklusivem Urheberrecht unterliegt. Sie darf also nicht kopiert, verteilt oder verändert werden.
|
||||
Sollte Interesse an einer Anbindung an unser System bestehen, kontaktiere uns bitte einfach (https://regatten.net/contact)
|
||||
|
||||
Der Hauptzweck dieses Repository besteht jedoch darin, Feedback von Euch zu unserer neuen App zu bekommen.
|
||||
Selbstverständlich könnt Ihr uns auch weiterhin auf anderen Kanälen erreichen, doch für Problem-Meldungen und Verbesserungsvorschläge ist GitHub am besten geeignet.
|
||||
Wie Du Teil unseres BETA-Programmes wirst, die App installierst und Feedback gibst, erfährst Du in unserem [Wiki](https://github.com/ostertun/RegattenApp/wiki).
|
||||
@@ -1,8 +0,0 @@
|
||||
RewriteEngine on
|
||||
# root directory:
|
||||
RewriteBase /projects/RegattenApp/api/
|
||||
|
||||
|
||||
|
||||
# Show site
|
||||
RewriteRule ^(.*)$ index.php?request=$1 [QSA]
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
// DATABASE Credentials
|
||||
define('DB_USER', 'regattenwebsite');
|
||||
define('DB_PASS', 'RBpOv4YYtZKWIGcN');
|
||||
define('DB_HOST', 'localhost');
|
||||
define('DB_DATABASE', 'regattenwebsite');
|
||||
|
||||
define('DB_CHANGE_TIME', true);
|
||||
define('DB_USE_UTF8', true); // use utf-8 in DB requests
|
||||
|
||||
// DATABASE Table names
|
||||
define('DB_TABLE_USERS', 'users');
|
||||
define('DB_TABLE_LOGINS', 'logins');
|
||||
define('DB_TABLE_KEEPLOGGEDIN', 'keeploggedin');
|
||||
define('DB_TABLE_RESET', 'rstpw');
|
||||
|
||||
define('DB_TABLE_CLUBS', 'regatta_clubs');
|
||||
define('DB_TABLE_SUFFIX_BOATS', '_boats');
|
||||
define('DB_TABLE_SUFFIX_SAILORS', '_sailors');
|
||||
define('DB_TABLE_SUFFIX_PLANNING', '_planning');
|
||||
define('DB_TABLE_SUFFIX_REGATTAS', '_regattas');
|
||||
define('DB_TABLE_SUFFIX_RESULTS', '_results');
|
||||
define('DB_TABLE_TRIM_BOATS', 'trim_boats');
|
||||
define('DB_TABLE_TRIM_USERS', 'trim_users');
|
||||
define('DB_TABLE_TRIM_TRIMS', 'trim_trims');
|
||||
define('DB_TABLE_NEWS', 'news');
|
||||
define('DB_TABLE_UPDATETIMES', '_updatetimes');
|
||||
|
||||
// OUTGOING MAILS - Credentials for outgoing mails
|
||||
define('MAIL_SMTP_HOST', 'ssl://ostertun.net'); // SMTP Server address
|
||||
define('MAIL_SMTP_PORT', 465); // port to use
|
||||
define('MAIL_FROM_ADDRESS', 'no-reply@regatten.net'); // address to send mails from
|
||||
define('MAIL_USERNAME', MAIL_FROM_ADDRESS); // if true: username
|
||||
define('MAIL_PASSWORD', 'pVc05j_3'); // & password
|
||||
|
||||
?>
|
||||
157
api/database.php
157
api/database.php
@@ -1,157 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
Mysql Database Support
|
||||
----------------------
|
||||
|
||||
Required defines:
|
||||
- DB_HOST (STRING)
|
||||
- DB_USER (STRING)
|
||||
- DB_PASS (STRING)
|
||||
- DB_DATABASE (STRING)
|
||||
- DB_USE_UTF8 (BOOL)
|
||||
- DB_CHANGE_TIME (BOOL)
|
||||
|
||||
Required functions:
|
||||
- logE (in /_global/log.php)
|
||||
|
||||
*/
|
||||
|
||||
$mysqli = mysqli_connect(DB_HOST, DB_USER, DB_PASS);
|
||||
|
||||
if ($mysqli === false) {
|
||||
logE("database", "Could not connect to database\n" . mysqli_connect_error);
|
||||
die('Error: Could not connect to database');
|
||||
}
|
||||
|
||||
mysqli_select_db($mysqli, DB_DATABASE);
|
||||
if (DB_USE_UTF8) {
|
||||
mysqli_set_charset($mysqli, 'utf8');
|
||||
}
|
||||
|
||||
function db_get_data($mysqli, $table, $fields = '*', $where = false, $limit = false) {
|
||||
$rest = '';
|
||||
if ($where != false) {
|
||||
$rest .= ' WHERE ' . $where;
|
||||
}
|
||||
if ($limit != false) {
|
||||
$rest .= sprintf(' LIMIT %d', $limit);
|
||||
}
|
||||
$query = 'SELECT ' . $fields . ' FROM ' . mysqli_real_escape_string($mysqli, $table) . $rest . ';';
|
||||
$response = mysqli_query($mysqli, $query);
|
||||
|
||||
if ($response !== false) {
|
||||
$result = array();
|
||||
if ($response->num_rows > 0) {
|
||||
$i = 0;
|
||||
while ($row = $response->fetch_assoc()) {
|
||||
if (isset($row['id'])) {
|
||||
$id = $row['id'];
|
||||
} else {
|
||||
$id = $i;
|
||||
$i ++;
|
||||
}
|
||||
foreach ($row as $key => $value) {
|
||||
$result[$id][$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
} else {
|
||||
logE("database", "get_data\nInvalid request\n" . $query . "\n" . mysqli_error($mysqli));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function db_update_data($mysqli, $table, $data, $where, $limit = false) {
|
||||
$rest = '';
|
||||
if ($where != false) {
|
||||
$rest .= ' WHERE ' . $where;
|
||||
}
|
||||
if ($limit != false) {
|
||||
$rest .= sprintf(' LIMIT %d', $limit);
|
||||
}
|
||||
$set = '';
|
||||
$first = true;
|
||||
foreach ($data as $key => $value) {
|
||||
if ($first) {
|
||||
$first = false;
|
||||
} else {
|
||||
$set .= ', ';
|
||||
}
|
||||
if ($value === null) {
|
||||
$set .= '`' . mysqli_real_escape_string($mysqli, $key) . '`=NULL';
|
||||
} else {
|
||||
$set .= '`' . mysqli_real_escape_string($mysqli, $key) . '`="' . mysqli_real_escape_string($mysqli, $value) . '"';
|
||||
}
|
||||
}
|
||||
if (defined('DB_CHANGE_TIME')) $set .= ', `changed`=NOW()';
|
||||
$query = 'UPDATE ' . mysqli_real_escape_string($mysqli, $table) . ' SET ' . $set . $rest . ';';
|
||||
$response = mysqli_query($mysqli, $query);
|
||||
|
||||
if ($response === false) {
|
||||
logE("database", "update_data\nInvalid request\n" . $query . "\n" . mysqli_error($mysqli));
|
||||
} elseif (defined('DB_CHANGE_TIME')) {
|
||||
mysqli_query($mysqli, 'UPDATE `_updatetimes` SET `update`=NOW() WHERE `table`="' . mysqli_real_escape_string($mysqli, $table) . '";');
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
function db_insert_data($mysqli, $table, $data) {
|
||||
$fields = '';
|
||||
$values = '';
|
||||
$first = true;
|
||||
foreach ($data as $key => $value) {
|
||||
if ($first) {
|
||||
$first = false;
|
||||
} else {
|
||||
$fields .= ', ';
|
||||
$values .= ', ';
|
||||
}
|
||||
$fields .= '`' . mysqli_real_escape_string($mysqli, $key) . '`';
|
||||
if ($value === null) {
|
||||
$values .= 'NULL';
|
||||
} else {
|
||||
$values .= '"' . mysqli_real_escape_string($mysqli, $value) . '"';
|
||||
}
|
||||
}
|
||||
if (defined('DB_CHANGE_TIME')) {
|
||||
$fields .= ', `changed`';
|
||||
$values .= ', NOW()';
|
||||
}
|
||||
$query = 'INSERT INTO `' . mysqli_real_escape_string($mysqli, $table) . '` (' . $fields . ') VALUES (' . $values . ');';
|
||||
$response = mysqli_query($mysqli, $query);
|
||||
if ($response === false) {
|
||||
logE("database", "insert_data\nInvalid request\n" . $query . "\n" . mysqli_error($mysqli));
|
||||
} else {
|
||||
$response = mysqli_insert_id($mysqli);
|
||||
if (defined('DB_CHANGE_TIME')) {
|
||||
mysqli_query($mysqli, 'UPDATE `_updatetimes` SET `update`=NOW() WHERE `table`="' . mysqli_real_escape_string($mysqli, $table) . '";');
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
function db_delete_data($mysqli, $table, $where, $limit = false) {
|
||||
$rest = '';
|
||||
if ($where != false) {
|
||||
$rest .= ' WHERE ' . $where;
|
||||
}
|
||||
if ($limit != false) {
|
||||
$rest .= sprintf(' LIMIT %d', $limit);
|
||||
}
|
||||
$query = 'DELETE FROM `' . mysqli_real_escape_string($mysqli, $table) . '`' . $rest . ';';
|
||||
$response = mysqli_query($mysqli, $query);
|
||||
if ($response === false) {
|
||||
logE("database", "delete_data\nInvalid request\n" . $query . "\n" . mysqli_error($mysqli));
|
||||
} elseif (defined('DB_CHANGE_TIME')) {
|
||||
mysqli_query($mysqli, 'UPDATE `_updatetimes` SET `update`=NOW() WHERE `table`="' . mysqli_real_escape_string($mysqli, $table) . '";');
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,450 +0,0 @@
|
||||
<?php
|
||||
|
||||
function get_db_entry($mysqli, $table, $id = false, $order = false) {
|
||||
if ($id === false) {
|
||||
return db_get_data($mysqli, $table, '*', ($order !== false ? ('1=1 ORDER BY ' . $order) : false));
|
||||
} else {
|
||||
$result = db_get_data($mysqli, $table, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $id) . '"', 1);
|
||||
if (($result === false) or (count($result) != 1))
|
||||
return false;
|
||||
else
|
||||
return array_values($result)[0];
|
||||
}
|
||||
}
|
||||
|
||||
function get_club($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, DB_TABLE_CLUBS, $id, '`kurz` ASC');
|
||||
}
|
||||
|
||||
function get_boat($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, BOATCLASS . DB_TABLE_SUFFIX_BOATS, $id, '`sailnumber` ASC');
|
||||
}
|
||||
|
||||
function get_sailor($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, BOATCLASS . DB_TABLE_SUFFIX_SAILORS, $id, '`name` ASC');
|
||||
}
|
||||
|
||||
function get_planning($mysqli, $userId = false, $regattaId = false) {
|
||||
$where = '';
|
||||
$limit = false;
|
||||
if ($userId !== false) {
|
||||
$where .= '(`user`="' . mysqli_real_escape_string($mysqli, $userId) . '")';
|
||||
}
|
||||
if (($userId !== false) and ($regattaId !== false)) {
|
||||
$where .= ' AND ';
|
||||
$limit = 1;
|
||||
}
|
||||
if ($regattaId !== false) {
|
||||
$where .= '(`regatta`="' . mysqli_real_escape_string($mysqli, $regattaId) . '")';
|
||||
}
|
||||
if ($where == '') $where = false;
|
||||
if ($limit === false) {
|
||||
return db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', $where);
|
||||
} else {
|
||||
$result = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', $where, 1);
|
||||
if (($result === false) or (count($result) != 1))
|
||||
return false;
|
||||
else
|
||||
return array_values($result)[0];
|
||||
}
|
||||
}
|
||||
|
||||
function get_regatta($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, BOATCLASS . DB_TABLE_SUFFIX_REGATTAS, $id, '`date` ASC');
|
||||
}
|
||||
|
||||
function get_result($mysqli, $regattaId = false) {
|
||||
if ($regattaId === false) {
|
||||
return db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_RESULTS);
|
||||
} else {
|
||||
return db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_RESULTS, '*', '`regatta` = "' . mysqli_real_escape_string($mysqli, $regattaId) . '"');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function get_regattas_range($mysqli, $from, $to) {
|
||||
return db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_REGATTAS, '*', '(`date` >= "' . date('Y-m-d', $from) . '") AND (`date` <= "' . date('Y-m-d', $to) . '") ORDER BY `date`');
|
||||
}
|
||||
|
||||
function get_regatta_years($mysqli) {
|
||||
$query = 'SELECT DISTINCT(YEAR(`date`)) as year FROM ' . BOATCLASS . DB_TABLE_SUFFIX_REGATTAS . ' ORDER BY `date`;';
|
||||
$response = mysqli_query($mysqli, $query);
|
||||
|
||||
if ($response !== false) {
|
||||
$result = array();
|
||||
if ($response->num_rows > 0) {
|
||||
while ($row = $response->fetch_assoc()) {
|
||||
$result[] = $row['year'];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
} else {
|
||||
logE("functions", "get_data\nInvalid request\n" . $query . "\n" . mysqli_error($mysqli));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function get_result_calculated($mysqli, $regatta_id) {
|
||||
$regatta = get_regatta($mysqli, $regatta_id);
|
||||
if ($regatta === false) {
|
||||
return false;
|
||||
}
|
||||
$results = get_result($mysqli, $regatta_id);
|
||||
if ($results !== false) {
|
||||
|
||||
// *** Replace , with .
|
||||
foreach ($results as $key => $value) {
|
||||
for ($i = 1; $i <= $regatta['races']; $i ++) {
|
||||
$results[$key]['race' . $i] = str_replace(',', '.', $results[$key]['race' . $i]);
|
||||
}
|
||||
}
|
||||
|
||||
// *** Calculation ***
|
||||
$gemeldet = count($results);
|
||||
|
||||
$sortarray = array();
|
||||
foreach ($results as $key => $value) {
|
||||
$results[$key]['finished'] = false;
|
||||
$results[$key]['values'] = array();
|
||||
$results[$key]['values_all'] = array();
|
||||
$results[$key]['texts'] = array();
|
||||
$copy = array();
|
||||
for ($i = 1; $i <= $regatta['races']; $i ++) {
|
||||
if (is_numeric($value['race' . $i])) {
|
||||
$results[$key]['values'][$i] = $value['race' . $i];
|
||||
$results[$key]['texts'][$i] = $value['race' . $i];
|
||||
$copy[$i] = $value['race' . $i];
|
||||
$results[$key]['finished'] = true;
|
||||
} else {
|
||||
switch ($value['race' . $i]) {
|
||||
// Nicht gestartet
|
||||
case 'DNC': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Did not come
|
||||
case 'DNS': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Did not started
|
||||
// Startfehler
|
||||
case 'OCS': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // On course site
|
||||
// Muss v. Hand case 'ZFP': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Z-Flag penalty (20% nach 30.2)
|
||||
case 'UFD': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Uniform Flag Disqualified (disqu. nach 30.3)
|
||||
case 'BFD': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Black Flag Disqualified (disqu. nach 30.4)
|
||||
// Nicht durch Ziel gegangen
|
||||
case 'DNF': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Did not finish
|
||||
case 'RET': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Retired (Aufgegeben)
|
||||
case 'RAF': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Retired after finish
|
||||
// Disqualifizierun
|
||||
case 'DSQ': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Disqualified
|
||||
case 'DNE': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = -1; /*$results[$key]['finished'] = true;*/ break; // Disqualified, not excludable (disqu. kann nach 90.3(b) nicht gestrichen werden)
|
||||
case 'DGM': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = -2; /*$results[$key]['finished'] = true;*/ break; // Disqualification Gross Missconduct (kann nach 69.1(b)(2) nicht gestr. werden, grobes Fehlverhalten)
|
||||
// Wiedergutmachung
|
||||
// Muss v. Hand case 'RDG': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Redress given (Wiedergutmachung gewährt)
|
||||
// Strafen
|
||||
// Muss v. Hand case 'SCP': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Wertungsstrafe nach 44.3(a) (20%)
|
||||
// Muss v. Hand case 'DPI': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Punktstrafe nach Ermessen der Jury
|
||||
// Unbekannt
|
||||
default: $results[$key]['values'][$i] = 0; $copy[$i] = 0; break;
|
||||
}
|
||||
|
||||
if ($results[$key]['values'][$i] != 0) {
|
||||
$results[$key]['texts'][$i] = $value['race' . $i] . ' (' . $results[$key]['values'][$i] . ')';
|
||||
} else {
|
||||
$results[$key]['texts'][$i] = $value['race' . $i] . ' (Unknown - 0)';
|
||||
}
|
||||
}
|
||||
}
|
||||
$results[$key]['values_all'] = $results[$key]['values'];
|
||||
for ($s = 0; $s < $regatta['streicher']; $s ++) {
|
||||
$max = max($copy);
|
||||
for ($i = 1; $i <= $regatta['races']; $i ++) {
|
||||
if ($copy[$i] == $max) {
|
||||
$copy[$i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$brutto = $netto = 0;
|
||||
for ($i = 1; $i <= $regatta['races']; $i ++) {
|
||||
$brutto += $results[$key]['values_all'][$i];
|
||||
if ($copy[$i] == -1) { $results[$key]['values'][$i] = $gemeldet + 1; }
|
||||
elseif ($copy[$i] == -2) { $results[$key]['values'][$i] = $gemeldet + 1; }
|
||||
else { $results[$key]['values'][$i] = $copy[$i]; }
|
||||
if ($results[$key]['values'][$i] == 0) {
|
||||
$results[$key]['texts'][$i] = '[' . $results[$key]['texts'][$i] . ']';
|
||||
}
|
||||
$netto += $results[$key]['values'][$i];
|
||||
}
|
||||
$results[$key]['brutto'] = $brutto;
|
||||
$results[$key]['netto'] = $netto;
|
||||
|
||||
if ($results[$key]['finished']) {
|
||||
$sortarray[$key] = 0;
|
||||
} else {
|
||||
$sortarray[$key] = 1;
|
||||
}
|
||||
$sortarray[$key] /*.*/= sprintf("%08.2f", $netto);
|
||||
$temp = $results[$key]['values'];
|
||||
sort($temp);
|
||||
$i = 0;
|
||||
foreach ($temp as $val) {
|
||||
if ($i < $regatta['races']) {
|
||||
$sortarray[$key] .= sprintf("%07.2f", $val);
|
||||
}
|
||||
$i ++;
|
||||
}
|
||||
for ($i = $regatta['races']; $i > 0; $i --) {
|
||||
$sortarray[$key] .= sprintf("%07.2f", $results[$key]['values_all'][$i]);
|
||||
}
|
||||
$results[$key]['sortvalue'] = $sortarray[$key];
|
||||
}
|
||||
array_multisort($sortarray, $results);
|
||||
$i = 1;
|
||||
foreach ($results as $key => $value) {
|
||||
if (($i > 1) and ($sortarray[$key] == $sortarray[$lastkey])) {
|
||||
$results[$key]['place'] = $results[$lastkey]['place'];
|
||||
} else {
|
||||
$results[$key]['place'] = $i;
|
||||
}
|
||||
$i ++;
|
||||
$lastkey = $key;
|
||||
}
|
||||
unset ($sortarray);
|
||||
|
||||
return $results;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function update_result_cache($mysqli, $regatta_id) {
|
||||
$regatta = get_regatta($mysqli, $regatta_id);
|
||||
if ($regatta === false) return;
|
||||
$results = get_result_calculated($mysqli, $regatta['id']);
|
||||
if ($results === false) return;
|
||||
|
||||
// count finished boats
|
||||
$fb = 0;
|
||||
foreach ($results as $result) {
|
||||
if ($result['finished']) {
|
||||
$fb ++;
|
||||
}
|
||||
}
|
||||
|
||||
db_update_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_REGATTAS, ['finishedBoats' => $fb], '`id`="' . $regatta['id'] . '"', 1);
|
||||
|
||||
foreach ($results as $result) {
|
||||
if ($fb == 0) {
|
||||
$rlp = 0;
|
||||
} else {
|
||||
$rlp = 100 * $regatta['rlf'] * (($fb + 1 - $result['place']) / $fb);
|
||||
}
|
||||
db_update_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_RESULTS, ['place' => $result['place'], 'rlp' => $rlp], '`id`="' . $result['id'] . '"', 1);
|
||||
}
|
||||
}
|
||||
|
||||
function get_ranking($mysqli, $from, $to, $jugend = false, $jugstrict = false) {
|
||||
global $rankNoResults, $_CLASSES;
|
||||
$rankNoResults = array();
|
||||
|
||||
$sailors = get_sailor($mysqli);
|
||||
$regattas = get_regattas_range($mysqli, $from, $to);
|
||||
|
||||
if (($sailors !== false) and ($regattas !== false)) {
|
||||
foreach ($sailors as $key => $sailor) {
|
||||
$sailors[$key]['regattas'] = array();
|
||||
$sailors[$key]['tmp_rlp'] = array();
|
||||
}
|
||||
|
||||
foreach ($regattas as $regatta) {
|
||||
$date = strtotime($regatta['date']);
|
||||
|
||||
// regatta has to be min. 2 days to be ranking-regatta
|
||||
if ($regatta['length'] < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$results = get_result($mysqli, $regatta['id']);
|
||||
if ($results === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count($results) <= 0) {
|
||||
if (strtotime('+' . ($regatta['length']-1) . ' days', $date) <= time()) {
|
||||
if (!$regatta['canceled']) {
|
||||
$rankNoResults[] = $regatta;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// in one race there must be at least 10 boats started
|
||||
$ok = false;
|
||||
for ($i = 1; $i <= $regatta['races']; $i ++) {
|
||||
$temp = 0;
|
||||
foreach ($results as $result) {
|
||||
if (($result['race' . $i] != 'DNC') and ($result['race' . $i] != 'DNS')) {
|
||||
$temp ++;
|
||||
}
|
||||
}
|
||||
if ($temp >= 10) {
|
||||
$ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$ok) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fb = $regatta['finishedBoats'];
|
||||
|
||||
// add regatta to each sailor
|
||||
foreach ($results as $result) {
|
||||
if ($result['rlp'] == 0) {
|
||||
continue;
|
||||
}
|
||||
// check if crew is youth
|
||||
//if ($jugend) {
|
||||
// $crew = explode(',', $result['crew']);
|
||||
// $okay = true;
|
||||
// foreach ($crew as $sailor) {
|
||||
// if (($sailor == '') or !isset($sailors[$sailor])) continue;
|
||||
// $sailor = $sailors[$sailor];
|
||||
// if ((($sailor['year'] !== null) and ($sailor['year'] < (date('Y', $date) - $_CLASSES[BOATCLASS]['youth-age']))) or
|
||||
// (($sailor['year'] === null) and ($jugstrict))) {
|
||||
// $okay = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (!$okay) continue;
|
||||
//}
|
||||
// calc m
|
||||
if ($regatta['m'] > 0) {
|
||||
$m = $regatta['m'];
|
||||
} elseif ($regatta['races'] <= 4) {
|
||||
$m = $regatta['races'];
|
||||
} else {
|
||||
if (($regatta['length'] > 2) and ($regatta['races'] >= 6)) {
|
||||
$m = 5;
|
||||
} else {
|
||||
$m = 4;
|
||||
}
|
||||
}
|
||||
$rlp = $result['rlp'];
|
||||
$sailors[$result['steuermann']]['regattas'][$regatta['id']] = array(
|
||||
'regatta' => $regatta['id'],
|
||||
'boat' => $result['boat'],
|
||||
'crew' => $result['crew'],
|
||||
'place' => $result['place'],
|
||||
'fb' => $fb,
|
||||
'rlp' => $rlp,
|
||||
'used' => 0,
|
||||
'm' => $m
|
||||
);
|
||||
for ($i = 0; $i < $m; $i ++) {
|
||||
array_push($sailors[$result['steuermann']]['tmp_rlp'], array($regatta['id'], $rlp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($sailors as $key => $sailor) {
|
||||
if ($sailor['german'] == 0) {
|
||||
unset($sailors[$key]);
|
||||
} elseif ($jugend) {
|
||||
if ((($sailor['year'] !== null) and ($sailor['year'] < (date('Y', $to) - $_CLASSES[BOATCLASS]['youth-age']))) or
|
||||
(($sailor['year'] === null) and ($jugstrict))) {
|
||||
unset($sailors[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sortarray = array();
|
||||
|
||||
foreach ($sailors as $key => $sailor) {
|
||||
// sort rlps desc
|
||||
$sort = array();
|
||||
foreach ($sailor['tmp_rlp'] as $key2 => $value) {
|
||||
$sort[$key2] = $value[1];
|
||||
}
|
||||
array_multisort($sort, SORT_DESC, $sailors[$key]['tmp_rlp']);
|
||||
// calc mean. rlp
|
||||
$sum = 0;
|
||||
$cnt = 0;
|
||||
foreach ($sailors[$key]['tmp_rlp'] as $value) {
|
||||
$sum += $value[1];
|
||||
$sailors[$key]['regattas'][$value[0]]['used'] ++;
|
||||
$cnt ++;
|
||||
if ($cnt >= 9) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
unset($sailors[$key]['tmp_rlp']);
|
||||
if ($cnt > 0) {
|
||||
$rlp = $sum / $cnt;
|
||||
$sailors[$key]['rlp'] = $rlp;
|
||||
$sailors[$key]['m'] = $cnt;
|
||||
} else {
|
||||
unset($sailors[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($rlp == 0) {
|
||||
$sortarray[$key] = $cnt;
|
||||
} else {
|
||||
$sortarray[$key] = $cnt * 1000 + $rlp;
|
||||
}
|
||||
}
|
||||
array_multisort($sortarray, SORT_DESC, $sailors);
|
||||
unset($sortarray);
|
||||
|
||||
$i = 1;
|
||||
foreach ($sailors as $key => $sailor) {
|
||||
$sailors[$key]['rank'] = $i;
|
||||
$i ++;
|
||||
}
|
||||
|
||||
return $sailors;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function get_trim_boat($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, DB_TABLE_TRIM_BOATS, $id);
|
||||
}
|
||||
|
||||
function get_trim_boat_users($mysqli, $id) {
|
||||
$result = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`boat` = "' . mysqli_real_escape_string($mysqli, $id) . '"');
|
||||
if ($result === false)
|
||||
return false;
|
||||
else
|
||||
return $result;
|
||||
}
|
||||
|
||||
function get_trim_user_boats($mysqli, $id) {
|
||||
$boats = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`user` = "' . mysqli_real_escape_string($mysqli, $id) . '"');
|
||||
if ($boats === false) {
|
||||
return false;
|
||||
} else {
|
||||
$result = [];
|
||||
foreach ($boats as $value) {
|
||||
$result[$value['boat']] = get_trim_boat($mysqli, $value['boat']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
function trim_is_boat_user($mysqli, $user, $boat) {
|
||||
$res = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`user` = "' . mysqli_real_escape_string($mysqli, $user) . '" AND `boat` = "' . mysqli_real_escape_string($mysqli, $boat) . '"');
|
||||
return ($res !== false) and (count($res) == 1);
|
||||
}
|
||||
|
||||
function get_trim_trim($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, DB_TABLE_TRIM_TRIMS, $id);
|
||||
}
|
||||
|
||||
function get_trim_boat_trims($mysqli, $id) {
|
||||
$result = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`boat` = "' . mysqli_real_escape_string($mysqli, $id) . '"');
|
||||
if ($result === false) {
|
||||
return false;
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
466
api/index.php
466
api/index.php
@@ -1,466 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once(__DIR__ . '/../server/config.php');
|
||||
require_once(__DIR__ . '/config.php');
|
||||
require_once(__DIR__ . '/../server/log.php');
|
||||
require_once(__DIR__ . '/database.php');
|
||||
require_once(__DIR__ . '/login.php');
|
||||
require_once(__DIR__ . '/functions.php');
|
||||
|
||||
$request = false;
|
||||
if (isset($_GET['request'])) {
|
||||
$request = explode('/', $_GET['request']);
|
||||
}
|
||||
if ($request === false) {
|
||||
$request = array();
|
||||
}
|
||||
if (count($request) >= 1) {
|
||||
$action = array_shift($request);
|
||||
} else {
|
||||
$action = '';
|
||||
}
|
||||
|
||||
define('DONE_OKAY', 0);
|
||||
define('DONE_EMPTY', 1);
|
||||
define('DONE_DATABASE', 2);
|
||||
define('DONE_UNAUTHORIZED', 3);
|
||||
define('DONE_BAD_REQUEST', 4);
|
||||
define('DONE_CONFLICT', 5);
|
||||
define('DONE_SERVER_ERROR', 6);
|
||||
function done($donecode, $content = null) {
|
||||
switch ($donecode) {
|
||||
case DONE_OKAY:
|
||||
header('HTTP/1.0 200 OK');
|
||||
break;
|
||||
case DONE_EMPTY:
|
||||
header('HTTP/1.0 204 No Content');
|
||||
break;
|
||||
case DONE_DATABASE:
|
||||
header('HTTP/1.0 500 Internal Server Error');
|
||||
if ($content === null) {
|
||||
$content = array('error' => 'database error');
|
||||
}
|
||||
break;
|
||||
case DONE_UNAUTHORIZED:
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
if ($content === null) {
|
||||
$content = array('error' => 'unauthorized');
|
||||
}
|
||||
break;
|
||||
case DONE_BAD_REQUEST:
|
||||
header('HTTP/1.0 400 Bad Request');
|
||||
if ($content === null) {
|
||||
$content = array('error' => 'bad request');
|
||||
}
|
||||
break;
|
||||
case DONE_CONFLICT:
|
||||
header('HTTP/1.0 409 Conflict');
|
||||
break;
|
||||
case DONE_SERVER_ERROR:
|
||||
header('HTTP/1.0 500 Internal Server Error');
|
||||
break;
|
||||
default:
|
||||
header('HTTP/1.0 500 Internal Server Error');
|
||||
break;
|
||||
}
|
||||
header('Content-Type: application/json');
|
||||
if ($content !== null) {
|
||||
echo json_encode($content);
|
||||
} else {
|
||||
echo '{ }';
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['auth']['id'], $_REQUEST['auth']['hash'])) {
|
||||
$user_id = auth_check($mysqli, $_REQUEST['auth']['id'], $_REQUEST['auth']['hash']);
|
||||
} else {
|
||||
$user_id = false;
|
||||
}
|
||||
|
||||
function isLoggedIn() {
|
||||
global $user_id;
|
||||
return $user_id !== false;
|
||||
}
|
||||
|
||||
function checkLoggedIn() {
|
||||
if (!isLoggedIn()) done(DONE_UNAUTHORIZED, ['error' => 'permission denied']);
|
||||
}
|
||||
|
||||
function checkRequest($param) {
|
||||
if (!isset($_REQUEST[$param])) done(DONE_BAD_REQUEST, ['error' => 'missing parameter: ' . $param]);
|
||||
}
|
||||
|
||||
function replaceChanged($array) {
|
||||
return array_map(function ($entry) {
|
||||
unset($entry['changed']);
|
||||
return $entry;
|
||||
}, $array);
|
||||
}
|
||||
|
||||
$whereString = false;
|
||||
if (isset($_REQUEST['index'], $_REQUEST['value'])) {
|
||||
$whereString = '`' . mysqli_real_escape_string($mysqli, $_REQUEST['index']) . '`="' . mysqli_real_escape_string($mysqli, $_REQUEST['value']) . '"';
|
||||
}
|
||||
|
||||
function sendEntries($table) {
|
||||
global $mysqli, $whereString;
|
||||
$response = db_get_data($mysqli, $table, '*', $whereString);
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, $table, '*', '`changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
}
|
||||
|
||||
function sendEntry($table) {
|
||||
global $mysqli;
|
||||
checkRequest('id');
|
||||
$response = db_get_data($mysqli, $table, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
|
||||
case 'login':
|
||||
checkRequest('username');
|
||||
checkRequest('password');
|
||||
checkRequest('device');
|
||||
$auth = auth_login($mysqli, $_REQUEST['username'], $_REQUEST['password'], $_REQUEST['device']);
|
||||
if ($auth === false) done(DONE_UNAUTHORIZED);
|
||||
done(DONE_OKAY, $auth);
|
||||
break;
|
||||
|
||||
case 'logout':
|
||||
checkLoggedIn();
|
||||
auth_logout($mysqli, $_REQUEST['auth']['id']);
|
||||
done(DONE_OKAY);
|
||||
break;
|
||||
|
||||
case 'get_update_time':
|
||||
$times = array();
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_CLUBS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['clubs'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_BOATS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['boats'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_SAILORS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['sailors'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_REGATTAS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['regattas'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_RESULTS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['results'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_PLANNING . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['plannings'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_TRIM_BOATS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['trim_boats'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_TRIM_USERS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['trim_users'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_TRIM_TRIMS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['trim_trims'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_USERS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['users'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
done(DONE_OKAY, $times);
|
||||
break;
|
||||
|
||||
case 'get_clubs':
|
||||
sendEntries(DB_TABLE_CLUBS);
|
||||
break;
|
||||
|
||||
case 'get_club':
|
||||
sendEntry(DB_TABLE_CLUBS);
|
||||
break;
|
||||
|
||||
case 'get_boats':
|
||||
sendEntries(BOATCLASS . DB_TABLE_SUFFIX_BOATS);
|
||||
break;
|
||||
|
||||
case 'get_boat':
|
||||
sendEntry(BOATCLASS . DB_TABLE_SUFFIX_BOATS);
|
||||
break;
|
||||
|
||||
case 'get_sailors':
|
||||
sendEntries(BOATCLASS . DB_TABLE_SUFFIX_SAILORS);
|
||||
break;
|
||||
|
||||
case 'get_sailor':
|
||||
sendEntry(BOATCLASS . DB_TABLE_SUFFIX_SAILORS);
|
||||
break;
|
||||
|
||||
case 'get_years':
|
||||
$response = get_regatta_years($mysqli);
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
foreach ($response as $key => $value)
|
||||
$response[$key] = ['year' => $value];
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'get_regattas':
|
||||
sendEntries(BOATCLASS . DB_TABLE_SUFFIX_REGATTAS);
|
||||
break;
|
||||
|
||||
case 'get_regatta':
|
||||
sendEntry(BOATCLASS . DB_TABLE_SUFFIX_REGATTAS);
|
||||
break;
|
||||
|
||||
case 'get_results':
|
||||
sendEntries(BOATCLASS . DB_TABLE_SUFFIX_RESULTS);
|
||||
break;
|
||||
|
||||
case 'get_result':
|
||||
sendEntry(BOATCLASS . DB_TABLE_SUFFIX_RESULTS);
|
||||
break;
|
||||
|
||||
case 'get_plannings':
|
||||
$response = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', $whereString);
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', '`changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_map(function ($entry) {
|
||||
global $user_id;
|
||||
if (($user_id === false) or ($entry['user'] != $user_id)) {
|
||||
unset($entry['gemeldet'], $entry['bezahlt']);
|
||||
}
|
||||
return $entry;
|
||||
}, $response);
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
break;
|
||||
|
||||
case 'get_planning':
|
||||
checkRequest('id');
|
||||
$response = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
if (($user_id === false) or ($response['user'] != $user_id)) {
|
||||
unset($response['gemeldet'], $response['bezahlt']);
|
||||
}
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'get_trim_boats':
|
||||
checkLoggedIn();
|
||||
$users = db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'boat', '`user`="' . $user_id . '"');
|
||||
$boats = implode(',', array_column($users, 'boat'));
|
||||
if ($boats == '') {
|
||||
done(DONE_OKAY, array('data' => [], 'keys' => []));
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_BOATS, '*', '`id` IN (' . $boats . ')' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_BOATS, '*', '`id` IN (' . $boats . ') AND `changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
break;
|
||||
|
||||
case 'get_trim_boat':
|
||||
checkLoggedIn();
|
||||
checkRequest('id');
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_BOATS, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
if (count(db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'id', '`user`="' . $user_id . '" AND `boat`="' . $response['id'] . '"')) != 1)
|
||||
done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'get_trim_users':
|
||||
checkLoggedIn();
|
||||
$users = db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'boat', '`user`="' . $user_id . '"');
|
||||
$boats = implode(',', array_column($users, 'boat'));
|
||||
if ($boats == '') {
|
||||
done(DONE_OKAY, array('data' => [], 'keys' => []));
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`boat` IN (' . $boats . ')' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`boat` IN (' . $boats . ') AND `changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
break;
|
||||
|
||||
case 'get_trim_user':
|
||||
checkLoggedIn();
|
||||
checkRequest('id');
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
if (count(db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'id', '`user`="' . $user_id . '" AND `boat`="' . $response['boat'] . '"')) != 1)
|
||||
done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'get_trim_trims':
|
||||
checkLoggedIn();
|
||||
$users = db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'boat', '`user`="' . $user_id . '"');
|
||||
$boats = implode(',', array_column($users, 'boat'));
|
||||
if ($boats == '') {
|
||||
done(DONE_OKAY, array('data' => [], 'keys' => []));
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`boat` IN (' . $boats . ')' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`boat` IN (' . $boats . ') AND `changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
break;
|
||||
|
||||
case 'get_trim_trim':
|
||||
checkLoggedIn();
|
||||
checkRequest('id');
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
if (count(db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'id', '`user`="' . $user_id . '" AND `boat`="' . $response['boat'] . '"')) != 1)
|
||||
done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'get_users':
|
||||
$followFields = '';
|
||||
for ($i = 1; $i <= 5; $i ++) $followFields .= ',' . BOATCLASS . '_sailor' . $i . ' AS sailor' . $i;
|
||||
$response = db_get_data($mysqli, DB_TABLE_USERS, 'id,username,email' . $followFields, $whereString);
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, DB_TABLE_USERS, 'id,username,email' . $followFields, '`changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_map(function ($entry) {
|
||||
global $user_id;
|
||||
if ($entry['id'] != $user_id) {
|
||||
$entry = ['id' => $entry['id'], 'username' => $entry['username']];
|
||||
}
|
||||
return $entry;
|
||||
}, $response);
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
break;
|
||||
|
||||
case 'get_user':
|
||||
checkRequest('id');
|
||||
$followFields = '';
|
||||
for ($i = 1; $i <= 5; $i ++) $followFields .= ',' . BOATCLASS . '_sailor' . $i . ' AS sailor' . $i;
|
||||
$response = db_get_data($mysqli, DB_TABLE_USERS, 'id,username,email' . $followFields, '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
if ($response['id'] != $user_id) {
|
||||
$response = ['id' => $response['id'], 'username' => $response['username']];
|
||||
}
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'add_subscription':
|
||||
checkRequest('subscription');
|
||||
$data = [
|
||||
'auth' => PUSH_AUTH,
|
||||
'subscription' => $_REQUEST['subscription']
|
||||
];
|
||||
$ch = curl_init('https://push.ostertun.net/add_subscription');
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
if ($result == "OK")
|
||||
done(DONE_OKAY);
|
||||
else {
|
||||
logE('add_subscription', $result);
|
||||
done(DONE_SERVER_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'remove_subscription':
|
||||
checkRequest('subscription');
|
||||
$data = [
|
||||
'auth' => PUSH_AUTH,
|
||||
'subscription' => $_REQUEST['subscription']
|
||||
];
|
||||
$ch = curl_init('https://push.ostertun.net/remove_subscription');
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
if ($result == "OK")
|
||||
done(DONE_OKAY);
|
||||
else {
|
||||
logE('remove_subscription', $result);
|
||||
done(DONE_SERVER_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
done(DONE_BAD_REQUEST, ['error' => 'action invalid']);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
107
api/login.php
107
api/login.php
@@ -1,107 +0,0 @@
|
||||
<?php
|
||||
|
||||
function get_user($mysqli, $username = null) {
|
||||
if ($username === null) {
|
||||
return db_get_data($mysqli, DB_TABLE_USERS);
|
||||
} else {
|
||||
$user = db_get_data($mysqli, DB_TABLE_USERS, '*', '`username` = "' . mysqli_real_escape_string($mysqli, $username) . '"', 1);
|
||||
if (($user === false) or (count($user) != 1)) return false;
|
||||
return array_values($user)[0];
|
||||
}
|
||||
}
|
||||
|
||||
function get_user_by_id($mysqli, $user_id) {
|
||||
$res = db_get_data($mysqli, DB_TABLE_USERS, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $user_id) . '"', 1);
|
||||
if (($res !== false) and (count($res) == 1)) {
|
||||
return array_values($res)[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//function signup($mysqli, $username, $email, $password) {
|
||||
// if (($username == '') or ($email == '') or ($password == '')) {
|
||||
// return 1;
|
||||
// }
|
||||
// if (get_user($mysqli, $username) !== false) {
|
||||
// return 1;
|
||||
// }
|
||||
// $salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), true));
|
||||
// $hashpassword = hash('sha512', $password . $salt);
|
||||
//
|
||||
// $user = array();
|
||||
// $user['username'] = $username;
|
||||
// $user['email'] = $email;
|
||||
// $user['password'] = $hashpassword;
|
||||
// $user['salt'] = $salt;
|
||||
// if (db_insert_data($mysqli, DB_TABLE_USERS, $user) !== false) {
|
||||
// $values = array();
|
||||
// $values['USERNAME'] = $username;
|
||||
// $message = createMail('signup', STRING_SIGNUP_EMAIL_SUBJECT, $values);
|
||||
// smtp_send_mail(['Regatten.net', MAIL_FROM_ADDRESS], [[$username, $email]], [], [], STRING_SIGNUP_EMAIL_SUBJECT, $message, [['Content-Type', 'text/html; charset="UTF-8"']]);
|
||||
// // Analytics
|
||||
// matomo_event('Login', 'SignUp', $username);
|
||||
// return true;
|
||||
// } else {
|
||||
// return 2;
|
||||
// }
|
||||
//}
|
||||
|
||||
function get_perm($mysqli, $user_id) {
|
||||
if ($user_id !== false) {
|
||||
$result = get_user_by_id($mysqli, $user_id);
|
||||
if ($result !== false) {
|
||||
return $result[DB_FIELD_PERM];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ### NEW LOGIN ####################################
|
||||
|
||||
function auth_login($mysqli, $username, $password, $device) {
|
||||
$user = get_user($mysqli, $username);
|
||||
if ($user === false) {
|
||||
// User does not exist
|
||||
return false;
|
||||
}
|
||||
$hashpassword = hash('sha512', $password . $user['salt']);
|
||||
if ($hashpassword !== $user['password']) {
|
||||
// Password incorrect
|
||||
return false;
|
||||
}
|
||||
// All correct
|
||||
$auth = [];
|
||||
$auth['user'] = $user['id'];
|
||||
$auth['username'] = $user['username'];
|
||||
$auth['auth'] = str_replace('/', '-', str_replace('+', '_', base64_encode(openssl_random_pseudo_bytes(24))));
|
||||
$salt = base64_encode(openssl_random_pseudo_bytes(24));
|
||||
$hash = hash('sha512', $auth['auth'] . $salt);
|
||||
$data = [
|
||||
'user' => $user['id'],
|
||||
'salt' => $salt,
|
||||
'authhash' => $hash,
|
||||
'device' => $device
|
||||
];
|
||||
$auth['id'] = db_insert_data($mysqli, DB_TABLE_LOGINS, $data);
|
||||
return $auth;
|
||||
}
|
||||
|
||||
function auth_logout($mysqli, $id) {
|
||||
db_delete_data($mysqli, DB_TABLE_LOGINS, 'id = "' . mysqli_real_escape_string($mysqli, $id) . '"', 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
function auth_check($mysqli, $id, $hash) {
|
||||
$auth = db_get_data($mysqli, DB_TABLE_LOGINS, '*', 'id="' . mysqli_real_escape_string($mysqli, $id) . '"', 1);
|
||||
if (($auth === false) or (count($auth) != 1)) return false;
|
||||
$auth = array_values($auth)[0];
|
||||
$hash = hash('sha512', $hash . $auth['salt']);
|
||||
if ($hash != $auth['authhash']) return false;
|
||||
db_update_data($mysqli, DB_TABLE_LOGINS, ['id' => $auth['id']], 'id="' . $auth['id'] . '"', 1); // update changed field => last login
|
||||
return $auth['user'];
|
||||
}
|
||||
|
||||
?>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -38,6 +38,16 @@ function parseDate(string) {
|
||||
return date;
|
||||
}
|
||||
|
||||
function parseDbTimestamp(string) {
|
||||
var year = string.substr(0, 4);
|
||||
var month = string.substr(5, 2);
|
||||
var day = string.substr(8, 2);
|
||||
var hour = string.substr(11, 2);
|
||||
var minute = string.substr(14, 2);
|
||||
var second = string.substr(17, 2);
|
||||
return new Date(year, month - 1, day, hour, minute, second);
|
||||
}
|
||||
|
||||
function getToday() {
|
||||
var date = new Date();
|
||||
date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
||||
|
||||
1530
client/scripts/mobileconsole.js
Normal file
1530
client/scripts/mobileconsole.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -7,9 +7,11 @@
|
||||
|
||||
?>
|
||||
//Loading the Service Worker
|
||||
var swRegistration = null;
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function() {
|
||||
navigator.serviceWorker.register('<?php echo SERVER_ADDR; ?>/service-worker.js.php');
|
||||
window.addEventListener('load', async function() {
|
||||
swRegistration = await navigator.serviceWorker.register('<?php echo SERVER_ADDR; ?>/service-worker.js.php');
|
||||
if (typeof onServiceWorkerLoaded === 'function') onServiceWorkerLoaded();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,8 +20,6 @@ $(document).ready(function(){
|
||||
'use strict'
|
||||
|
||||
var pwaVersion = '<?php echo PWA_VERSION; ?>'; //must be identical to _manifest.json version. If not it will create update window loop
|
||||
var pwaCookie = true; // if set to false, the PWA prompt will appear even if the user selects "maybe later"
|
||||
var pwaNoCache = false; // always keep the cache clear to serve the freshest possible content
|
||||
|
||||
|
||||
$('[data-pwa-version]').data('pwa-version', pwaVersion);
|
||||
@@ -33,7 +33,7 @@ $(document).ready(function(){
|
||||
//Enabling dismiss button
|
||||
setTimeout(function(){
|
||||
$('.pwa-dismiss').on('click',function(){
|
||||
console.log('User Closed Add to Home / PWA Prompt')
|
||||
log('[pwa] User Closed Add to Home / PWA Prompt')
|
||||
createCookie('Sticky_pwa_rejected_install', true, 1);
|
||||
$('body').find('#menu-install-pwa-android, #menu-install-pwa-ios, .menu-hider').removeClass('menu-active');
|
||||
});
|
||||
@@ -50,34 +50,37 @@ $(document).ready(function(){
|
||||
|
||||
//Firing PWA prompts for specific versions and when not on home screen.
|
||||
if (isMobile.Android()) {
|
||||
console.log('Android Detected');
|
||||
log('[pwa] Android Detected');
|
||||
function showInstallPromotion(){
|
||||
if($('#menu-install-pwa-android, .add-to-home').length){
|
||||
console.log('Triggering PWA Menu for Android');
|
||||
log('[pwa] Triggering PWA Menu for Android');
|
||||
if (!readCookie('Sticky_pwa_rejected_install')) {
|
||||
setTimeout(function(){
|
||||
$('.add-to-home').addClass('add-to-home-visible add-to-home-android');
|
||||
$('#menu-install-pwa-android, .menu-hider').addClass('menu-active')
|
||||
},4500);
|
||||
},3000);
|
||||
}
|
||||
} else {
|
||||
console.log('The div #menu-install-pwa-android was not found. Please add this div to show the install window')
|
||||
}
|
||||
}
|
||||
let deferredPrompt;
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
e.preventDefault();
|
||||
deferredPrompt = e;
|
||||
showInstallPromotion();
|
||||
var welcomActive = $('#menu-welcome').hasClass('menu-active');
|
||||
if (welcomActive) {
|
||||
$('#menu-welcome-a-okay').click(showInstallPromotion);
|
||||
} else {
|
||||
showInstallPromotion();
|
||||
}
|
||||
});
|
||||
$('.pwa-install').on('click',function(e){
|
||||
deferredPrompt.prompt();
|
||||
deferredPrompt.userChoice
|
||||
.then((choiceResult) => {
|
||||
if (choiceResult.outcome === 'accepted') {
|
||||
console.log('User accepted the A2HS prompt');
|
||||
log('[pwa] User accepted the A2HS prompt');
|
||||
} else {
|
||||
console.log('User dismissed the A2HS prompt');
|
||||
log('[pwa] User dismissed the A2HS prompt');
|
||||
}
|
||||
deferredPrompt = null;
|
||||
});
|
||||
@@ -89,108 +92,32 @@ $(document).ready(function(){
|
||||
|
||||
if (isMobile.iOS()) {
|
||||
if(!isInWebAppiOS){
|
||||
console.log('iOS Detected');
|
||||
log('[pwa] iOS Detected');
|
||||
if($('#menu-install-pwa-ios, .add-to-home').length){
|
||||
if (!readCookie('Sticky_pwa_rejected_install')) {
|
||||
console.log('Triggering PWA / Add to Home Screen Menu for iOS');
|
||||
setTimeout(function(){
|
||||
$('.add-to-home').addClass('add-to-home-visible add-to-home-ios');
|
||||
$('#menu-install-pwa-ios, .menu-hider').addClass('menu-active');
|
||||
},4500);
|
||||
setTimeout(function(){
|
||||
function triggerPwaInstallIos() {
|
||||
log('[pwa] Triggering PWA / Add to Home Screen Menu for iOS');
|
||||
$('.add-to-home').addClass('add-to-home-visible add-to-home-ios');
|
||||
$('#menu-install-pwa-ios, .menu-hider').addClass('menu-active');
|
||||
}
|
||||
var welcomActive = $('#menu-welcome').hasClass('menu-active');
|
||||
if (welcomActive) {
|
||||
$('#menu-welcome-a-okay').click(triggerPwaInstallIos);
|
||||
} else {
|
||||
triggerPwaInstallIos();
|
||||
}
|
||||
},3000);
|
||||
};
|
||||
} else {
|
||||
console.log('The div #menu-install-pwa-ios was not found. Please add this div to show the install window')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Creating Update Modal
|
||||
function updateModal(){
|
||||
var body = $('body');
|
||||
var updateModal = $('#menu-update');
|
||||
var mt = new Date();
|
||||
var menuUpdate = mt.getHours() + ":" + mt.getMinutes() + ":" + mt.getSeconds();
|
||||
if(!updateModal.length){
|
||||
body.append('<div id="menu-update"></div>');
|
||||
setTimeout(function(){
|
||||
body.find('#menu-update').load('menu-update.html?ver='+menuUpdate);
|
||||
},250);
|
||||
}
|
||||
};
|
||||
//Update Version in 5 Seconds After New Version Detected
|
||||
function updateButton(){
|
||||
var counter = 3;
|
||||
var interval = setInterval(function() {
|
||||
counter--;
|
||||
console.log(counter);
|
||||
$('.page-update').html('Aktuallisierung in ... '+ counter + ' Sekunden');
|
||||
if (counter == 0) {
|
||||
clearInterval(interval);
|
||||
window.location.reload(true)
|
||||
}
|
||||
}, 1000);
|
||||
caches.delete('workbox-runtime').then(function() {
|
||||
console.log('Content Updated - Cache Removed!');
|
||||
});
|
||||
//localStorage.clear();
|
||||
sessionStorage.clear()
|
||||
caches.keys().then(cacheNames => {
|
||||
cacheNames.forEach(cacheName => {
|
||||
caches.delete(cacheName);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
//Check Version
|
||||
function check_version(){
|
||||
if($('link[data-pwa-version]').length){
|
||||
function versionCheck(){
|
||||
var dt = new Date();
|
||||
var maniTimeVersion = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds();
|
||||
var localVersionNumber = $('link[rel="manifest"]').data('pwa-version');
|
||||
var onlineVersionJSON = "<?php echo SERVER_ADDR; ?>/manifest.json.php?ver=" + maniTimeVersion;
|
||||
var onlineVersionNumber = "Connection Offline. Waiting to Reconect";
|
||||
$.getJSON(onlineVersionJSON, function(onlineData) {onlineVersionNumber = onlineData.version;});
|
||||
setTimeout(function(){
|
||||
//console.log(' Checking PWA Content for updates...\n PWA Server Version: ' + onlineVersionNumber + '\n' + ' PWA Cached Version: ' + localVersionNumber);
|
||||
if(onlineVersionNumber != localVersionNumber && onlineVersionNumber != "Connection Offline. Waiting to Reconect"){
|
||||
updateModal();
|
||||
console.log('New Version of Content Available. Refreshing. On Desktop Browsers a manual refresh maybe required.')
|
||||
setTimeout(function(){
|
||||
$('body').find('#menu-update').addClass('menu-active');
|
||||
$('.menu-hider').addClass('menu-active-no-click');
|
||||
updateButton();
|
||||
},500);
|
||||
}
|
||||
if(onlineVersionNumber == localVersionNumber){/*No update required. Versions Identical*/}
|
||||
if(onlineVersionNumber === "undefined"){/*Error Checking for Updates*/}
|
||||
if(onlineVersionNumber === "Finding Online Version..."){
|
||||
$('.reloadme').addClass('disabled');
|
||||
$('body').find('#menu-update').removeClass('menu-active');
|
||||
$('.menu-hider').removeClass('menu-active-no-click');
|
||||
}
|
||||
},3000);
|
||||
}
|
||||
//Checking for new version every 60 seconds
|
||||
setInterval(function(){versionCheck()}, 50000);
|
||||
//Initial Load Version Check in 10 Second After Load
|
||||
setTimeout(function(){versionCheck();}, 10000);
|
||||
}
|
||||
}
|
||||
|
||||
if(pwaCookie == false){
|
||||
eraseCookie('Sticky_pwa_rejected_install');
|
||||
}
|
||||
|
||||
//Reload To Clear Button
|
||||
$('body').on('click', '.page-update, .reloadme', function() {
|
||||
location.reload();
|
||||
});
|
||||
|
||||
//Check for Version Change if Online If not Kill the Function
|
||||
if (navigator.onLine) {check_version();} else {function check_version(){}}
|
||||
|
||||
//Adding Offline Alerts
|
||||
var offlineAlerts = $('.offline-message');
|
||||
|
||||
@@ -213,47 +140,19 @@ $(document).ready(function(){
|
||||
setTimeout(function(){$('.online-message').removeClass('online-message-active');},2000);
|
||||
}
|
||||
|
||||
$('.simulate-offline').on('click',function(){isOffline();})
|
||||
$('.simulate-online').on('click',function(){isOnline();})
|
||||
|
||||
//Disable links to other pages if offline.
|
||||
//Warning! Enabling offline for iOS can cause issues
|
||||
//To allow offline functionality delete the next 7 lines
|
||||
function returnFalse(){
|
||||
var detectHREF = $(this).attr('href');
|
||||
if(detectHREF.match(/.html/)){
|
||||
isOffline();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Check if Online / Offline
|
||||
function updateOnlineStatus(event) {
|
||||
var condition = navigator.onLine ? "online" : "offline";
|
||||
isOnline();
|
||||
console.log( 'Connection: Online');
|
||||
$("a").off( "click", returnFalse );
|
||||
log('[pwa] Connection: Online');
|
||||
}
|
||||
function updateOfflineStatus(event) {
|
||||
isOffline();
|
||||
$("a").on( "click", returnFalse );
|
||||
console.log( 'Connection: Offline');
|
||||
log('[pwa] Connection: Offline');
|
||||
}
|
||||
window.addEventListener('online', updateOnlineStatus);
|
||||
window.addEventListener('offline', updateOfflineStatus);
|
||||
|
||||
|
||||
if(pwaNoCache == true){
|
||||
caches.delete('workbox-runtime').then(function() {
|
||||
});
|
||||
localStorage.clear();
|
||||
sessionStorage.clear()
|
||||
caches.keys().then(cacheNames => {
|
||||
cacheNames.forEach(cacheName => {
|
||||
caches.delete(cacheName);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
@@ -3,14 +3,52 @@
|
||||
header('Content-Type: text/javascript');
|
||||
|
||||
require_once(__DIR__ . '/../../server/config.php');
|
||||
require_once(__DIR__ . '/../../server/version.php');
|
||||
|
||||
?>
|
||||
|
||||
const QUERY_URL = '<?php echo SERVER_ADDR; ?>/api/';
|
||||
const QUERY_URL = '<?php echo QUERY_URL; ?>';
|
||||
const BOATCLASS = '<?php echo BOATCLASS; ?>';
|
||||
const LINK_PRE = '<?php echo SERVER_ADDR; ?>/';
|
||||
const YOUTH_AGE = '<?php echo $_CLASS['youth-age']; ?>';
|
||||
const YOUTH_GERMAN_NAME = '<?php echo $_CLASS['youth-german-name']; ?>';
|
||||
const PUSH_SERVER_KEY = '<?php echo PUSH_SERVER_KEY; ?>';
|
||||
|
||||
var consoleOutput = [];
|
||||
|
||||
function onConsoleOutput(entry) {
|
||||
consoleOutput.push(entry);
|
||||
}
|
||||
|
||||
window.onerror = function(message, source, lineno, colno, errorError) {
|
||||
if (source.startsWith(LINK_PRE)) {
|
||||
source = source.substr(LINK_PRE.length);
|
||||
}
|
||||
var pos = source.indexOf('?');
|
||||
if (pos >= 0) {
|
||||
source = source.substr(0, pos);
|
||||
}
|
||||
consoleOutput.push({
|
||||
message: message,
|
||||
stack: {
|
||||
caller: '',
|
||||
file: source,
|
||||
line: lineno,
|
||||
col: colno
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function log() {
|
||||
var now = new Date();
|
||||
var hour = now.getHours().toString();
|
||||
var min = now.getMinutes().toString();
|
||||
var sec = now.getSeconds().toString();
|
||||
var millis = now.getMilliseconds().toString();
|
||||
hour = (hour.length < 2 ? '0' + hour : hour);
|
||||
min = (min.length < 2 ? '0' + min : min);
|
||||
sec = (sec.length < 2 ? '0' + sec : sec);
|
||||
while (millis.length < 3) millis = '0' + millis;
|
||||
console.log('[' + hour + ':' + min + ':' + sec + '.' + millis + ']', ...arguments);
|
||||
}
|
||||
|
||||
var randomId = function() { return '_' + Math.random().toString(36).substr(2, 9); }
|
||||
|
||||
@@ -117,12 +155,58 @@ function findGetParameter(parameterName) {
|
||||
return result;
|
||||
}
|
||||
|
||||
var signup = function() {
|
||||
log('[app] Signup');
|
||||
var username = $('#input-signup-username').val();
|
||||
var email = $('#input-signup-email').val();
|
||||
var password = $('#input-signup-password').val();
|
||||
if (username == '') { $('#input-signup-username').focus(); return; }
|
||||
if (email == '') { $('#input-signup-email').focus(); return; }
|
||||
if (password == '') { $('#input-signup-password').focus(); return; }
|
||||
log('[app] Signup: All fields okay');
|
||||
showLoader();
|
||||
$('#input-signup-username').val('').trigger('focusin').trigger('focusout');
|
||||
$('#input-signup-email').val('').trigger('focusin').trigger('focusout');
|
||||
$('#input-signup-password').val('').trigger('focusin').trigger('focusout');
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'signup',
|
||||
method: 'POST',
|
||||
data: {
|
||||
username: username,
|
||||
email: email,
|
||||
password: password
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
log('[app] Signup: error:', xhr.status, status);
|
||||
if (xhr.status == 409) {
|
||||
toastError('Benutzername bereits vergeben');
|
||||
$('#input-signup-email').val(email).trigger('focusin').trigger('focusout');
|
||||
} else if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um Dich anzumelden');
|
||||
$('#menu-signup').hideMenu();
|
||||
} else {
|
||||
log('[app] Signup: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
hideLoader();
|
||||
},
|
||||
success: function (data, status, xhr) {
|
||||
log('[app] Signup successful, logging in');
|
||||
$('#input-login-username').val(username);
|
||||
$('#input-login-password').val(password);
|
||||
login();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var login = function() {
|
||||
log('[app] Login');
|
||||
showLoader();
|
||||
var username = $('#input-login-username').val();
|
||||
var password = $('#input-login-password').val();
|
||||
$('#input-login-username').val('');
|
||||
$('#input-login-password').val('');
|
||||
$('#input-login-username').val('').trigger('focusin').trigger('focusout');
|
||||
$('#input-login-password').val('').trigger('focusin').trigger('focusout');
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'login',
|
||||
method: 'POST',
|
||||
@@ -132,20 +216,22 @@ var login = function() {
|
||||
device: navigator.userAgent
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
log('[app] Login: error:', xhr.status, status);
|
||||
if (xhr.status == 401) {
|
||||
toastError('Benutzername oder Passwort falsch');
|
||||
$('#input-login-username').val(username);
|
||||
$('#input-login-username').val(username).trigger('focusin').trigger('focusout');
|
||||
} else if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um Dich anzumelden');
|
||||
$('#menu-login').hideMenu();
|
||||
} else {
|
||||
console.log('Login: unbekannter Fehler', status, error);
|
||||
console.log(xhr);
|
||||
log('[app] Login: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
hideLoader();
|
||||
},
|
||||
success: function (data, status, xhr) {
|
||||
log('[app] Login successful');
|
||||
localStorage.setItem('auth_id', data.id);
|
||||
localStorage.setItem('auth_hash', data.auth);
|
||||
localStorage.setItem('auth_user', data.user);
|
||||
@@ -166,13 +252,14 @@ var logoutClearStorage = function() {
|
||||
}
|
||||
|
||||
var logout = function() {
|
||||
log('[app] Logout');
|
||||
showLoader();
|
||||
var auth = {
|
||||
id: localStorage.getItem('auth_id'),
|
||||
hash: localStorage.getItem('auth_hash')
|
||||
}
|
||||
if ((auth.id === null) || (auth.hash === null)) {
|
||||
console.log('Not logged in');
|
||||
log('[app] Not logged in');
|
||||
logoutClearStorage();
|
||||
return;
|
||||
}
|
||||
@@ -183,47 +270,300 @@ var logout = function() {
|
||||
auth: auth
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
log('[app] Logout: error:', xhr.status, status);
|
||||
if (xhr.status == 401) {
|
||||
console.log('Not logged in');
|
||||
log('[app] Not logged in');
|
||||
logoutClearStorage();
|
||||
} else if (xhr.status == 0) {
|
||||
console.log('Could not delete auth from server');
|
||||
log('[app] Could not delete auth from server');
|
||||
logoutClearStorage();
|
||||
} else {
|
||||
console.log('Logout: unbekannter Fehler', status, error);
|
||||
console.log(xhr);
|
||||
log('[app] Logout: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
hideLoader();
|
||||
}
|
||||
},
|
||||
success: function (data, status, xhr) {
|
||||
log('[app] Logout successful');
|
||||
logoutClearStorage();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function resetCache() {
|
||||
function deleteDb() {
|
||||
log('[app] Deleting DB');
|
||||
$('#menu-developer').hideMenu();
|
||||
if (canUseLocalDB) {
|
||||
showLoader();
|
||||
var request = window.indexedDB.deleteDatabase('regatten_app_db_' + BOATCLASS);
|
||||
request.onerror = function (event) {
|
||||
log('[app] Cannot delete DB: ', event.target.errorCode);
|
||||
toastError('Beim Löschen der Datenbank ist ein Fehler aufgetreten.<br>Bitte melde diesen Fehler. (Dev-Menu => Problem melden)', 5000);
|
||||
hideLoader();
|
||||
}
|
||||
request.onsuccess = function (event) {
|
||||
log('[app] DB deleted');
|
||||
toastInfo('Die Datenbank wurde gelöscht. Die Seite lädt in wenigen Sekunden neu und erstellt damit eine neue Datenbank.', 10000);
|
||||
hideLoader();
|
||||
setTimeout(function(){ location.reload(); }, 3000);
|
||||
}
|
||||
} else {
|
||||
log('[app] DB not supported');
|
||||
toastWarn('Dein Gerät unterstützt kein lokales Speichern der Daten. Alle Daten werden direkt vom Server gezogen.<br>Entsprechend kannst Du die Datenbank auch nicht zurücksetzen.', 10000);
|
||||
}
|
||||
}
|
||||
|
||||
function deleteCache() {
|
||||
log('[app] Deleting cache');
|
||||
$('#menu-developer').hideMenu();
|
||||
navigator.serviceWorker.getRegistrations().then(function (registrations) {
|
||||
for (let registration of registrations) {
|
||||
console.log('Unregister sW:', registration);
|
||||
log('[app] Unregister sW:', registration);
|
||||
registration.unregister();
|
||||
}
|
||||
});
|
||||
caches.keys().then((keyList) => {
|
||||
return Promise.all(keyList.map((key) => {
|
||||
console.log('Cache deleted:', key);
|
||||
log('[app] Cache deleted:', key);
|
||||
return caches.delete(key);
|
||||
}));
|
||||
});
|
||||
toastInfo('The serviceWorker and the cache were deleted. A new serviceWorker will be generated on the next refresh.');
|
||||
toastInfo('Der serviceWorker und alle Caches wurden gelöscht. Die Seite lädt in wenigen Sekunden neu und erstellt damit neue Caches.', 10000);
|
||||
setTimeout(function(){ location.reload(); }, 3000);
|
||||
}
|
||||
|
||||
var pushesPossible = false;
|
||||
|
||||
function urlB64ToUint8Array(base64String) {
|
||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||
const base64 = (base64String + padding)
|
||||
.replace(/\-/g, '+')
|
||||
.replace(/_/g, '/');
|
||||
|
||||
const rawData = window.atob(base64);
|
||||
const outputArray = new Uint8Array(rawData.length);
|
||||
|
||||
for (let i = 0; i < rawData.length; ++i) {
|
||||
outputArray[i] = rawData.charCodeAt(i);
|
||||
}
|
||||
return outputArray;
|
||||
}
|
||||
|
||||
function pushesSubscribe() {
|
||||
log('[app] Subscribing');
|
||||
const applicationServerKey = urlB64ToUint8Array(PUSH_SERVER_KEY);
|
||||
log('[app] Subscription app server key:', applicationServerKey);
|
||||
swRegistration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: applicationServerKey
|
||||
})
|
||||
.then(async function(subscription) {
|
||||
log('[app] Subscription:', subscription);
|
||||
if (await pushesUpdateServerSubscription(subscription, true)) {
|
||||
log('[app] Subscription: Sent to server, updating UI');
|
||||
dbSettingsSet('notify_endpoint_' + BOATCLASS, subscription.endpoint);
|
||||
updatePushSwitches();
|
||||
updatePushBadge();
|
||||
} else {
|
||||
$('#menu-pushes').hideMenu();
|
||||
log('[app] Failed to subscribe the user due to connection error');
|
||||
toastError('Da ist leider etwas schief gelaufen. Bitte stelle sicher, dass Du mit dem Internet verbunden bist und versuche es erneut.', 5000);
|
||||
pushesUnSubscribe(true);
|
||||
}
|
||||
hideLoader();
|
||||
})
|
||||
.catch(function(err) {
|
||||
$('#menu-pushes').hideMenu();
|
||||
log('[app] Failed to subscribe the user: ', err);
|
||||
toastError('Da ist leider etwas schief gelaufen. Bitte stelle sicher, dass Du mit dem Internet verbunden bist und versuche es erneut.', 5000);
|
||||
pushesUnSubscribe(true);
|
||||
});
|
||||
}
|
||||
|
||||
function pushesUnSubscribe(silent = false) {
|
||||
log('[app] Unsubscribing');
|
||||
swRegistration.pushManager.getSubscription()
|
||||
.then(async function(subscription) {
|
||||
log('[app] Subscription:', subscription);
|
||||
if (subscription) {
|
||||
if (await pushesUpdateServerSubscription(subscription, false)) {
|
||||
log('[app] Subscription: Removed from server');
|
||||
} else {
|
||||
log('[app] Failed to unsubscribe the user due to connection error');
|
||||
}
|
||||
log('[app] Removing subscription');
|
||||
subscription.unsubscribe();
|
||||
log('[app] Subscription: Updating UI');
|
||||
$('#menu-pushes').hideMenu();
|
||||
dbSettingsSet('notify_endpoint_' + BOATCLASS, false);
|
||||
updatePushBadge();
|
||||
hideLoader();
|
||||
if (!silent) toastOk('Du erhältst ab sofort keine Benachrichtigungen mehr von uns.');
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
log('[app] Error unsubscribing', error);
|
||||
$('#menu-pushes').hideMenu();
|
||||
if (!silent) toastError('Da ist leider etwas schief gelaufen. Bitte versuche es erneut oder wende Dich an unseren Support.', 5000);
|
||||
updatePushBadge();
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
function pushesUpdateServerSubscription(subscription, enabled) {
|
||||
return new Promise(function(resolve){
|
||||
log('[app] updateServer', enabled, subscription);
|
||||
$.ajax({
|
||||
url: QUERY_URL + (enabled ? 'add' : 'remove') + '_subscription',
|
||||
type: 'POST',
|
||||
data: { subscription: JSON.stringify(subscription) },
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
log('[app] Subscription sent to server');
|
||||
resolve(true);
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
log('[app] Error sending subscription to server');
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function initPushSettings() {
|
||||
var items = [
|
||||
['notify_channel_' + BOATCLASS + '_news', true],
|
||||
['notify_channel_' + BOATCLASS + '_regatta_changed_my', true],
|
||||
['notify_channel_' + BOATCLASS + '_regatta_changed_all', false],
|
||||
['notify_channel_' + BOATCLASS + '_result_ready_my', true],
|
||||
['notify_channel_' + BOATCLASS + '_result_ready_all', true],
|
||||
['notify_channel_' + BOATCLASS + '_meldeschluss', true]
|
||||
];
|
||||
for (var i in items) {
|
||||
var item = items[i];
|
||||
if ((await dbSettingsGet(item[0])) == null) dbSettingsSet(item[0], item[1]);
|
||||
}
|
||||
}
|
||||
|
||||
async function updatePushSwitches() {
|
||||
$('#switch-pushes-news').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_news'));
|
||||
$('#switch-pushes-regatta-changed-my').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_regatta_changed_my'));
|
||||
$('#switch-pushes-regatta-changed-all').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_regatta_changed_all'));
|
||||
$('#switch-pushes-result-ready-my').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_result_ready_my'));
|
||||
$('#switch-pushes-result-ready-all').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_result_ready_all'));
|
||||
$('#switch-pushes-meldeschluss').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_meldeschluss'));
|
||||
|
||||
if ($('#switch-pushes').prop('checked')) {
|
||||
$('#p-pushes-info').show();
|
||||
$('.a-switch-pushes-channel-all').show();
|
||||
$('.a-switch-pushes-channel-my').show();
|
||||
if (!isLoggedIn()) {
|
||||
$('.a-switch-pushes-channel-my').find('div').remove();
|
||||
$('.a-switch-pushes-channel-my').find('.badge').text('nicht angemeldet');
|
||||
}
|
||||
} else {
|
||||
$('#p-pushes-info').hide();
|
||||
$('.a-switch-pushes-channel-all').hide();
|
||||
$('.a-switch-pushes-channel-my').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function pushesSubscribeClicked() {
|
||||
showLoader();
|
||||
if ($('#switch-pushes').prop('checked')) {
|
||||
pushesSubscribe();
|
||||
} else {
|
||||
pushesUnSubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
function pushesChannelClicked() {
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_news', $('#switch-pushes-news').prop('checked'));
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_regatta_changed_my', $('#switch-pushes-regatta-changed-my').prop('checked'));
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_regatta_changed_all', $('#switch-pushes-regatta-changed-all').prop('checked'));
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_result_ready_my', $('#switch-pushes-result-ready-my').prop('checked'));
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_result_ready_all', $('#switch-pushes-result-ready-all').prop('checked'));
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_meldeschluss', $('#switch-pushes-meldeschluss').prop('checked'));
|
||||
}
|
||||
|
||||
function pushesOpenMenu() {
|
||||
$('#menu-settings').hideMenu();
|
||||
if (!pushesPossible) {
|
||||
toastWarn('Dein Browser unterstützt leider keine Benachrichtigungen.', 5000);
|
||||
return;
|
||||
}
|
||||
if (Notification.permission == 'denied') {
|
||||
toastWarn('Benachrichtigungen werden von Deinem Browser blockiert.', 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
swRegistration.pushManager.getSubscription().then(function(subscription) {
|
||||
var isSub = (subscription !== null);
|
||||
$('#switch-pushes').prop('checked', isSub);
|
||||
updatePushSwitches();
|
||||
$('#menu-pushes').showMenu();
|
||||
});
|
||||
}
|
||||
|
||||
function updatePushBadge() {
|
||||
if (typeof onUpdatePushBadge === 'function') onUpdatePushBadge();
|
||||
if (!pushesPossible) return;
|
||||
if (Notification.permission == 'denied') {
|
||||
$('#badge-pushes').removeClass('bg-green2-dark').addClass('bg-red2-dark').text('BLOCKED');
|
||||
return;
|
||||
}
|
||||
swRegistration.pushManager.getSubscription().then(async function(subscription) {
|
||||
var dbSub = await dbSettingsGet('notify_endpoint_' + BOATCLASS);
|
||||
var isSub = (subscription !== null);
|
||||
log('[app] DB Subscription:', dbSub);
|
||||
log('[app] Real Subscription:', subscription);
|
||||
if (isSub) {
|
||||
$('#badge-pushes').removeClass('bg-red2-dark').addClass('bg-green2-dark').text('AN');
|
||||
if (dbSub === null) dbSettingsSet('notify_endpoint_' + BOATCLASS, subscription.endpoint);
|
||||
else if (dbSub !== subscription.endpoint) {
|
||||
if (navigator.onLine) {
|
||||
log('[app] Updating subscription');
|
||||
pushesSubscribe();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$('#badge-pushes').removeClass('bg-green2-dark').addClass('bg-red2-dark').text('AUS');
|
||||
if (dbSub === null) dbSettingsSet('notify_endpoint_' + BOATCLASS, false);
|
||||
else if (dbSub !== false) {
|
||||
if (navigator.onLine) {
|
||||
log('[app] Re subscribe');
|
||||
pushesSubscribe();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function updateNewsBadge() {
|
||||
var newsRead = await dbSettingsGet('news_read_' + BOATCLASS);
|
||||
if (newsRead === null) dbSettingsSet('news_read_' + BOATCLASS, newsRead = new Date());
|
||||
var news = await dbGetData('news');
|
||||
var now = new Date();
|
||||
var sum = 0;
|
||||
for (var n in news) {
|
||||
var newsEntry = news[n];
|
||||
newsEntry.date = parseDbTimestamp(newsEntry.date);
|
||||
if (newsEntry.date > now) continue;
|
||||
if (newsEntry.date < newsRead) continue;
|
||||
sum ++;
|
||||
}
|
||||
updateBadge('more/news', sum);
|
||||
}
|
||||
|
||||
var initRegatten = function() {
|
||||
showLoader();
|
||||
|
||||
log('[app] Initializing DB...');
|
||||
|
||||
initDatabase();
|
||||
|
||||
log('[app] Loading app specific code...');
|
||||
|
||||
if (isLoggedIn()) {
|
||||
$('.show-loggedin').show();
|
||||
$('.show-notloggedin').hide();
|
||||
@@ -235,4 +575,115 @@ var initRegatten = function() {
|
||||
$('.show-loggedin').hide();
|
||||
$('.show-notloggedin').show();
|
||||
}
|
||||
|
||||
// Pushes
|
||||
$('#a-switch-pushes').click(pushesSubscribeClicked);
|
||||
$('.a-switch-pushes-channel-all').click(pushesChannelClicked);
|
||||
$('.a-switch-pushes-channel-my').click(pushesChannelClicked);
|
||||
}
|
||||
|
||||
var onServiceWorkerLoaded = function() {
|
||||
log('[app] sW loaded');
|
||||
if ((swRegistration !== null) && (swRegistration.pushManager) && canUseLocalDB) {
|
||||
pushesPossible = true;
|
||||
updatePushBadge();
|
||||
} else {
|
||||
$('#badge-pushes').removeClass('bg-green2-dark').addClass('bg-red2-dark').text('NOT SUPPORTED');
|
||||
}
|
||||
}
|
||||
|
||||
var onDatabaseLoaded = function() {
|
||||
log('[app] DB loaded');
|
||||
if (!canUseLocalDB && !$('#menu-welcome').hasClass('menu-active')) {
|
||||
function NoDbWarningOk() {
|
||||
createCookie('regatten_nodb_banner', true, 1);
|
||||
$('#menu-nodb-warning').hideMenu();
|
||||
}
|
||||
function showNoDbWarning() {
|
||||
if (!readCookie('regatten_nodb_banner')) {
|
||||
$('#menu-nodb-warning').showMenu();
|
||||
}
|
||||
}
|
||||
$('#menu-nodb-warning-okay').click(NoDbWarningOk);
|
||||
showNoDbWarning();
|
||||
}
|
||||
|
||||
onServiceWorkerLoaded();
|
||||
initPushSettings();
|
||||
|
||||
updateNewsBadge();
|
||||
}
|
||||
|
||||
var onAfterSync = function() {
|
||||
updateNewsBadge();
|
||||
}
|
||||
|
||||
function sendErrorReport() {
|
||||
alert('FEHLERBERICHT\nEs wird jetzt ein Fehlerbericht an die Entwickler geschickt.\nBitte stelle sicher, dass Du mit dem Internet verbunden bist und drücke dann auf OK.');
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'error_report',
|
||||
method: 'POST',
|
||||
data: {
|
||||
errors: consoleOutput,
|
||||
device: navigator.userAgent,
|
||||
version: '<?php echo PWA_VERSION; ?>'
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 0) {
|
||||
alert('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um den Fehlerbericht zu senden');
|
||||
} else {
|
||||
alert('Beim Senden ist ein unbekannter Fehler aufgetreten. Bitte versuche es noch einmal');
|
||||
}
|
||||
},
|
||||
success: function (data, status, xhr) {
|
||||
alert('Wir leiten Dich jetzt zum erstellten Fehlerbericht um, sodass Du ggf. weitere Informationen ergänzen kannst.');
|
||||
location.href = 'https://github.com/ostertun/RegattenApp/issues/' + data.issueNumber;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add console opener to preloader
|
||||
var addConsoleOpenerToPreloader = function() {
|
||||
addConsoleOpenerToPreloader = function(){};
|
||||
var preloader = document.getElementById('preloader');
|
||||
var button = document.createElement('a');
|
||||
button.id = 'button-show-console';
|
||||
button.href = '#';
|
||||
button.classList = 'btn rounded-s text-uppercase font-900 shadow-m m-3 bg-red2-dark bg-white';
|
||||
button.style.position = 'fixed';
|
||||
button.style.bottom = 0;
|
||||
button.style.left = 0;
|
||||
button.style.right = 0;
|
||||
button.innerHTML = 'Fehlerbericht senden';
|
||||
button.onclick = function(){
|
||||
sendErrorReport();
|
||||
return false;
|
||||
}
|
||||
preloader.appendChild(button);
|
||||
$(button).hide();
|
||||
}
|
||||
addConsoleOpenerToPreloader();
|
||||
|
||||
function m2s_getLink(type, eventId) {
|
||||
switch (type) {
|
||||
case 'entrylist':
|
||||
return 'https://manage2sail.com/de-DE/event/' + eventId + '#!/entries';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function ro_getLink(type, eventId) {
|
||||
switch (type) {
|
||||
case 'entrylist':
|
||||
return 'http://www.raceoffice.org/entrylist.php?eid=' + eventId;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function extServiceGetLink(serviceName, type, eventId = '') {
|
||||
switch (serviceName) {
|
||||
case 'm2s':
|
||||
return m2s_getLink(type, eventId);
|
||||
case 'ro':
|
||||
return ro_getLink(type, eventId);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -173,6 +173,13 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/*** BLOCKQUOTE ***/
|
||||
blockquote {
|
||||
border-left: 0.5em solid rgba(0, 0, 0, 0.125);
|
||||
font-style: italic;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
/*** BLINKING ICONS ***/
|
||||
@keyframes fa-blink {
|
||||
0% { opacity: 1; }
|
||||
|
||||
@@ -4254,7 +4254,7 @@ code {
|
||||
}
|
||||
|
||||
/*Contact Form*/
|
||||
.menu input[type="text"] {
|
||||
/*.menu input[type="text"] {
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
}
|
||||
@@ -4271,7 +4271,7 @@ code {
|
||||
.menu .form-field label {
|
||||
font-size: 12px;
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
}*/
|
||||
|
||||
.form-field span {
|
||||
position: absolute;
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
error_reporting(0); // disable error reporting in browser
|
||||
define('SEND_ERRORS', true); // send errors via log
|
||||
|
||||
define('BOATCLASS', 'pirat');
|
||||
|
||||
date_default_timezone_set('Europe/Berlin');
|
||||
define('SERVER_PATH', '/subfolder'); // path to root directory
|
||||
define('SERVER_ADDR', 'https://' . $_SERVER['SERVER_NAME'] . SERVER_PATH); // path to root directory
|
||||
define('QUERY_URL', 'http://' . $_SERVER['SERVER_NAME'] . '/api/' . BOATCLASS . '/'); // url to api backend
|
||||
define('LOGGING_APIKEY', 'xxx'); // Apikey for Logging API -> get from ostertun.net/logging
|
||||
|
||||
// PUSH SERVER
|
||||
define('PUSH_AUTH', 'xxxxxxx'); // auth string for push.ostertun.net
|
||||
define('PUSH_SERVERKEY', 'xxxxxxx'); // server key from push.ostertun.net
|
||||
// PUSH
|
||||
define('PUSH_SERVER_KEY', '');
|
||||
|
||||
define('BOATCLASS', 'pirat');
|
||||
|
||||
// BOAT CLASSES
|
||||
// BOAT CLASS
|
||||
$_CLASS = array(
|
||||
'name' => 'Pirat',
|
||||
'desc' => 'eine vom DSV geförderte Jugendmeisterschaftsklasse',
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
$items .= $tpl->load('menu/item-icon', ['Vereins-Website', '', 'html-id' => 'menu-item-clubwebsite', 'icon' => 'fa-globe', 'css-class' => 'border-0']);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-boat', 'title' => 'Boots-Details', 'height' => 200]);
|
||||
|
||||
$items = '<p class="mb-2 mt-1" style="line-height: 1.5em;">Bitte trage hier den Bootsnamen ein:</p>';
|
||||
$items .= $tpl->load('input', ['html-id' => 'input-editboatname', 'placeholder' => 'Bootsname', 'type' => 'text']);
|
||||
$items .= $tpl->load('button', ['Speichern', '#', 'html-id' => 'button-editboatname']);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-editboatname', 'height' => 240]);
|
||||
|
||||
$sp['scripts'] .= $scripts->load('pagination', ['pageChange', 'page', 'pageCount', 'pagination']);
|
||||
$sp['scripts'] .= $scripts->load('boats');
|
||||
|
||||
|
||||
@@ -1,19 +1,38 @@
|
||||
<?php
|
||||
|
||||
// TODO: Create site
|
||||
|
||||
$sp['title'] = 'Seite noch nicht unterstuuml;tzt - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['title'] = 'Kontakt - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['backbutton'] = true;
|
||||
$sp['activenav'] = 5;
|
||||
|
||||
$content = $tpl->load('error', ['404', 'Seite existiert noch nicht']);
|
||||
$content .= '<p>';
|
||||
$content .= 'Die gesuchte Seite ist leider noch nicht verfügbar.<br>';
|
||||
$content .= 'Wir arbeiten daran, sie schnellstmöglich zur Verfügung zu stellen.<br>';
|
||||
$content .= 'Wie wäre es mit der Homepage?';
|
||||
// TITLE
|
||||
$content = '<h1>Kontakt</h1>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content]);
|
||||
|
||||
// Info
|
||||
$content = '<p>';
|
||||
$content .= 'Du hast eine Frage? Du hast einen Fehler in unserer Software oder in den gespeicherten Daten gefunden? Du willst Regatten.net auch für Deine Bootsklasse nutzen?<br>';
|
||||
$content .= 'Egal was es ist, lass es uns wissen! Schreibe uns eine Mail an <a href="mailto:info@regatten.net">info@regatten.net</a> oder nutze einfach dieses Kontakt-Formular.<br>';
|
||||
$content .= 'Wir werden Deine Anfrage so schnell wie möglich bearbeiten.';
|
||||
$content .= '</p>';
|
||||
$content .= '<p>';
|
||||
$content .= 'Alternativ erreichst Du uns auch telefonisch unter <a href="tel:+4941039659768">+49 (0) 4103 965 976 8</a><br>';
|
||||
$content .= 'Mo-Fr: 7-20 Uhr<br>';
|
||||
$content .= 'Sa: 9-17 Uhr';
|
||||
$content .= '</p>';
|
||||
$content .= $tpl->load('button', ['Zur Startseite', LINK_PRE . 'index', 'css-class' => 'mb-3']);
|
||||
$content .= $tpl->load('button', ['Kontakt', LINK_PRE . 'contact']);
|
||||
|
||||
$sp['output'] = $tpl->load('card', [$content, 'css-class' => 'text-center pt-3']);
|
||||
$sp['output'] .= $tpl->load('card', [$content]);
|
||||
|
||||
// Formular
|
||||
$content = '<h2>Kontakt-Formular</h2>';
|
||||
$content .= $tpl->load('input', ['html-id' => 'input-name', 'placeholder' => 'Dein Name', 'type' => 'text']);
|
||||
$content .= $tpl->load('input', ['html-id' => 'input-email', 'placeholder' => 'Email-Adresse', 'type' => 'email']);
|
||||
$content .= $tpl->load('input', ['html-id' => 'input-subject', 'placeholder' => 'Betreff', 'type' => 'text']);
|
||||
$content .= $tpl->load('textarea', ['html-id' => 'input-message', 'placeholder' => 'Deine Nachricht']);
|
||||
$content .= $tpl->load('button', ['Senden', '#', 'html-id' => 'button-send']);
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content]);
|
||||
|
||||
$sp['scripts'] .= $scripts->load('contact');
|
||||
|
||||
?>
|
||||
13
server/content/go2url.php
Normal file
13
server/content/go2url.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
$sp['title'] = 'Umleitung - Regatten.net ' . $_CLASS['name'];
|
||||
|
||||
// Title
|
||||
$content = '<h1>Umleitung</h1>';
|
||||
$content .= '<p>Wir leiten Dich in Kürze zur gewünschten Website weiter</p>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-title']);
|
||||
|
||||
$sp['scripts'] .= $scripts->load('go2url');
|
||||
|
||||
?>
|
||||
@@ -11,8 +11,7 @@
|
||||
|
||||
// Favorites
|
||||
$content = '<h2>Deine Favoriten</h2>';
|
||||
$thead = '<tr><th>Segler</th><th id="th-ranking">Rangliste</th></tr>';
|
||||
$content .= $tpl->load('table', [$thead, 'html-id' => 'table-favorites', 'css-class' => 'mb-0 mt-3']);
|
||||
$content .= '<div id="div-favorites" class="normal-list mb-0"></div>';
|
||||
$content .= '<p id="p-favorites" class="mt-3">';
|
||||
$content .= 'Du folgst <b>keinen</b> Seglern.<br>';
|
||||
$content .= 'Um jemandem zu folgen, gehe zur <a href="' . LINK_PRE . 'sailors">Segler-Liste</a> und wähle bis zu fünf Segler aus.';
|
||||
@@ -38,6 +37,18 @@
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-notloggedin']);
|
||||
|
||||
// Notification Info
|
||||
$content = '<h2 class="color-white">Push-Benachrichtigungen</h2>';
|
||||
$content .= '<p class="mt-3 mb-3 color-white">';
|
||||
$content .= '<b>Bleibe immer auf dem Laufendem!</b><br>';
|
||||
$content .= 'Aktiviere einfach unsere Push-Benachrichtigungen und wir informieren Dich über alle Änderungen.<br>';
|
||||
$content .= 'Du bestimmst natürlich, welche Benachrichtigungen Du bekommen möchtest.';
|
||||
$content .= '</p>';
|
||||
$content .= $tpl->load('button', ['Jetzt aktivieren', '#', 'html-id' => 'button-notifications-activate', 'css-class' => 'bg-green2-dark']);
|
||||
$content .= '<p class="text-center mt-3"><a id="a-notifications-later" class="color-grey2-light text-uppercase font-900">Vielleicht später</a></p>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-notifications', 'css-class' => 'bg-blue2-dark']);
|
||||
|
||||
// Next
|
||||
$content = '<h2>Nächste Regatten</h2>';
|
||||
$content .= '<div id="div-next" class="regattas-list mb-0"></div>';
|
||||
@@ -69,8 +80,10 @@
|
||||
$sp['output'] .= $tpl->load('card', [$content]);
|
||||
|
||||
// Regattas Menu
|
||||
$items = '<p id="menu-item-yourplanning" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
|
||||
$items .= $tpl->load('menu/item-icon', ['Saison-Planungen', '', 'html-id' => 'menu-item-plannings', 'icon' => 'fa-calendar-alt']);
|
||||
$items = '<p id="menu-item-special" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
|
||||
$items .= '<p id="menu-item-yourplanning" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Saison-Planungen', '', 'html-id' => 'menu-item-plannings', 'icon' => 'fa-calendar-alt', 'badge-id' => 'badge-regatta-plannings']);
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Meldeliste', '', 'html-id' => 'menu-item-entrylist', 'icon' => 'fa-file-signature', 'badge-id' => 'badge-regatta-entrylist']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Ergebnisse', '', 'html-id' => 'menu-item-results', 'icon' => 'fa-poll']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Bericht', '', 'html-id' => 'menu-item-bericht', 'icon' => 'fa-book']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Informationen', '', 'html-id' => 'menu-item-info', 'icon' => 'fa-info']);
|
||||
@@ -79,6 +92,10 @@
|
||||
$items .= $tpl->load('menu/item-icon', ['Vereins-Website', '', 'html-id' => 'menu-item-clubwebsite', 'icon' => 'fa-globe']);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-regatta', 'title' => 'Regatta-Details', 'height' => 320]);
|
||||
|
||||
// Favorites Menu
|
||||
$items = $tpl->load('menu/item-icon', ['Nicht mehr folgen', '#', 'html-id' => 'menu-item-unfollow', 'icon' => 'fa-heart', 'css-class' => ' border-0']);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-favorite', 'title' => 'Favorit', 'height' => 200]);
|
||||
|
||||
$sp['scripts'] .= $scripts->load('onRegattaClicked');
|
||||
$sp['scripts'] .= $scripts->load('index');
|
||||
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
<?php
|
||||
|
||||
// TODO: Create site
|
||||
|
||||
$sp['title'] = 'Seite noch nicht unterstuuml;tzt - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['title'] = 'News - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['backbutton'] = true;
|
||||
$sp['activenav'] = 5;
|
||||
|
||||
$content = $tpl->load('error', ['404', 'Seite existiert noch nicht']);
|
||||
$content .= '<p>';
|
||||
$content .= 'Die gesuchte Seite ist leider noch nicht verfügbar.<br>';
|
||||
$content .= 'Wir arbeiten daran, sie schnellstmöglich zur Verfügung zu stellen.<br>';
|
||||
$content .= 'Wie wäre es mit der Homepage?';
|
||||
$content .= '</p>';
|
||||
$content .= $tpl->load('button', ['Zur Startseite', LINK_PRE . 'index', 'css-class' => 'mb-3']);
|
||||
$content .= $tpl->load('button', ['Kontakt', LINK_PRE . 'contact']);
|
||||
// Title
|
||||
$content = "<h1>Neuigkeiten</h1>";
|
||||
$content .= '<p>Aktuelles der letzten zwölf Monate</p>';
|
||||
|
||||
$sp['output'] = $tpl->load('card', [$content, 'css-class' => 'text-center pt-3']);
|
||||
$sp['output'] .= $tpl->load('card', [$content]);
|
||||
|
||||
$sp['output'] .= '<div id="news-entries"></div>';
|
||||
|
||||
// Pagination
|
||||
$sp['output'] .= $tpl->load('pagination', ['html-id' => 'pagination']);
|
||||
|
||||
// Menu
|
||||
$sp['menus'] .= $tpl->load('menu/modal', ['html-id' => 'menu-news', 'title' => 'Details']);
|
||||
|
||||
$sp['scripts'] .= $scripts->load('pagination', ['pageChange', 'page', 'pageCount', 'pagination']);
|
||||
$cardTemplate = $tpl->load('card', ['%CONTENT%', 'html-id' => '%ID%', 'css-class' => 'card-news']);
|
||||
$cardTemplate = str_replace("\n", '', $cardTemplate);
|
||||
$cardTemplate = str_replace("\r", '', $cardTemplate);
|
||||
$sp['scripts'] .= "<script>const cardTemplate = '" . $cardTemplate . "';</script>";
|
||||
$sp['scripts'] .= $scripts->load('news');
|
||||
|
||||
?>
|
||||
@@ -1,19 +1,51 @@
|
||||
<?php
|
||||
|
||||
// TODO: Create site
|
||||
$sp['title'] = 'Saison-Planung - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['backbutton'] = 'index';
|
||||
$sp['activenav'] = 5;
|
||||
|
||||
$sp['title'] = 'Seite noch nicht unterstuuml;tzt - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['backbutton'] = true;
|
||||
// Title
|
||||
$content = '<h1>Saison-Planung</h1>';
|
||||
$content .= $tpl->load('button', ['<i class="fas fa-list"></i> Saison-Planungen anderer', 'html-id' => 'a-list-plannings', 'css-class' => 'mt-2 mb-2']);
|
||||
$content .= '<p class="mb-1"><b>Hinweis:</b> Diese Seite kannst nur Du sehen.<br>Wenn Du Deine Saison-Planung teilen möchtest, <a id="a-share-planning">klicke hier</a></p>';
|
||||
$content .= $tpl->load('button', ['<i class="fas fa-edit"></i> bearbeiten', 'html-id' => 'a-edit-planning']);
|
||||
$content .= $tpl->load('select', ['html-id' => 'select-year', 'placeholder' => 'Jahr', 'css-class' => 'mt-3 mb-0']);
|
||||
|
||||
$content = $tpl->load('error', ['404', 'Seite existiert noch nicht']);
|
||||
$content .= '<p>';
|
||||
$content .= 'Die gesuchte Seite ist leider noch nicht verfügbar.<br>';
|
||||
$content .= 'Wir arbeiten daran, sie schnellstmöglich zur Verfügung zu stellen.<br>';
|
||||
$content .= 'Wie wäre es mit der Homepage?';
|
||||
$content .= '</p>';
|
||||
$content .= $tpl->load('button', ['Zur Startseite', LINK_PRE . 'index', 'css-class' => 'mb-3']);
|
||||
$content .= $tpl->load('button', ['Kontakt', LINK_PRE . 'contact']);
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-loggedin']);
|
||||
|
||||
$sp['output'] = $tpl->load('card', [$content, 'css-class' => 'text-center pt-3']);
|
||||
// Not loggedin
|
||||
$content = '<h1>Saison-Planung</h1>';
|
||||
$content .= '<p>Um Deine Saison-Planung zu sehen, musst Du angemeldet sein.<br><a href="#" data-menu="menu-login">Melde Dich hier an</a> oder <a href="#" data-menu="menu-signup">registriere Dich jetzt kostenlos</a>.</p>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-notloggedin']);
|
||||
|
||||
// Regattas
|
||||
$content = '<p id="p-count" class="mb-0"></p>';
|
||||
$content .= $tpl->load('input', ['html-id' => 'input-search', 'placeholder' => 'Suche', 'type' => 'text', 'css-class' => 'mt-2']);
|
||||
$content .= '<div id="div-regattas" class="regattas-list mb-0"></div>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-regattas', 'css-class' => 'show-loggedin']);
|
||||
|
||||
// Menu
|
||||
$items = '<p id="menu-item-special" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
|
||||
$items .= '<p id="menu-item-yourplanning" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
|
||||
$items .= $tpl->load('menu/item-icon', ['Status bearbeiten', '#', 'html-id' => 'menu-item-status', 'icon' => 'fa-edit']);
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Saison-Planungen', '', 'html-id' => 'menu-item-plannings', 'icon' => 'fa-calendar-alt', 'badge-id' => 'badge-regatta-plannings']);
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Meldeliste', '', 'html-id' => 'menu-item-entrylist', 'icon' => 'fa-file-signature', 'badge-id' => 'badge-regatta-entrylist']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Ergebnisse', '', 'html-id' => 'menu-item-results', 'icon' => 'fa-poll']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Bericht', '', 'html-id' => 'menu-item-bericht', 'icon' => 'fa-book']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Informationen', '', 'html-id' => 'menu-item-info', 'icon' => 'fa-info']);
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Meldung', '', 'html-id' => 'menu-item-meldung', 'icon' => 'fa-file-signature', 'badge-id' => 'badge-regatta-meldung']);
|
||||
$items .= $tpl->load('menu/item-icon', ['offizielle Ergebnisse', '', 'html-id' => 'menu-item-oresults', 'icon' => 'fa-poll']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Vereins-Website', '', 'html-id' => 'menu-item-clubwebsite', 'icon' => 'fa-globe']);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-regatta', 'title' => 'Regatta-Details', 'height' => 320]);
|
||||
|
||||
// Menu Edit status
|
||||
$items = $tpl->load('menu/item-switch', ['Gemeldet', 'html-id' => 'switch-status-gemeldet', 'icon' => 'fa-file-signature']);
|
||||
$items .= $tpl->load('menu/item-switch', ['Bezahlt', 'html-id' => 'switch-status-bezahlt', 'icon' => 'fa-euro-sign', 'css-class' => 'border-0']);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-status', 'title' => 'Status bearbeiten', 'height' => 220]);
|
||||
|
||||
$sp['scripts'] .= $scripts->load('onRegattaClicked');
|
||||
$sp['scripts'] .= $scripts->load('planning');
|
||||
|
||||
?>
|
||||
@@ -1,19 +1,31 @@
|
||||
<?php
|
||||
|
||||
// TODO: Create site
|
||||
|
||||
$sp['title'] = 'Seite noch nicht unterstuuml;tzt - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['title'] = 'Saison-Planung bearbeiten - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['backbutton'] = true;
|
||||
$sp['activenav'] = 5;
|
||||
|
||||
$content = $tpl->load('error', ['404', 'Seite existiert noch nicht']);
|
||||
$content .= '<p>';
|
||||
$content .= 'Die gesuchte Seite ist leider noch nicht verfügbar.<br>';
|
||||
$content .= 'Wir arbeiten daran, sie schnellstmöglich zur Verfügung zu stellen.<br>';
|
||||
$content .= 'Wie wäre es mit der Homepage?';
|
||||
$content .= '</p>';
|
||||
$content .= $tpl->load('button', ['Zur Startseite', LINK_PRE . 'index', 'css-class' => 'mb-3']);
|
||||
$content .= $tpl->load('button', ['Kontakt', LINK_PRE . 'contact']);
|
||||
// Title, Inputs
|
||||
$content = "<h1>Saison-Planung bearbeiten</h1>";
|
||||
$content .= $tpl->load('select', ['html-id' => 'select-year', 'placeholder' => 'Jahr', 'css-class' => 'mt-3 mb-0']);
|
||||
|
||||
$sp['output'] = $tpl->load('card', [$content, 'css-class' => 'text-center pt-3']);
|
||||
$sp['output'] .= $tpl->load('card', [$content]);
|
||||
|
||||
// Regattas
|
||||
$content = '<p id="p-count" class="mb-0"></p>';
|
||||
$content .= $tpl->load('input', ['html-id' => 'input-search', 'placeholder' => 'Suche', 'type' => 'text', 'css-class' => 'mt-2']);
|
||||
$content .= '<div id="div-regattas" class="ranking-detail-list mb-0"></div>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-regattas']);
|
||||
|
||||
// Menu
|
||||
$items = $tpl->load('menu/item-switch', ['In die Saison-Planung aufnehmen', 'html-id' => 'switch-planning-include', 'icon' => 'fa-check']);
|
||||
$items .= $tpl->load('menu/item-simple', ['', '#', 'html-id' => 'item-steuermann']);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-edit', 'title' => 'Regatta bearbeiten', 'height' => 320]);
|
||||
|
||||
// Select sailor
|
||||
$items = $tpl->load('input', ['html-id' => 'input-edit-search', 'placeholder' => 'Suche', 'type' => 'text']);
|
||||
$sp['menus'] .= $tpl->load('menu/modal', [$items, 'html-id' => 'menu-sailor', 'height' => 500, 'width' => 350]);
|
||||
|
||||
$sp['scripts'] .= $scripts->load('planning_edit');
|
||||
|
||||
?>
|
||||
@@ -1,19 +1,27 @@
|
||||
<?php
|
||||
|
||||
// TODO: Create site
|
||||
|
||||
$sp['title'] = 'Seite noch nicht unterstuuml;tzt - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['title'] = 'Saison-Planungen - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['backbutton'] = true;
|
||||
$sp['activenav'] = 5;
|
||||
|
||||
$content = $tpl->load('error', ['404', 'Seite existiert noch nicht']);
|
||||
$content .= '<p>';
|
||||
$content .= 'Die gesuchte Seite ist leider noch nicht verfügbar.<br>';
|
||||
$content .= 'Wir arbeiten daran, sie schnellstmöglich zur Verfügung zu stellen.<br>';
|
||||
$content .= 'Wie wäre es mit der Homepage?';
|
||||
$content .= '</p>';
|
||||
$content .= $tpl->load('button', ['Zur Startseite', LINK_PRE . 'index', 'css-class' => 'mb-3']);
|
||||
$content .= $tpl->load('button', ['Kontakt', LINK_PRE . 'contact']);
|
||||
// Title
|
||||
$content = '<h1>Saison-Planungen</h1>';
|
||||
$content .= $tpl->load('select', ['html-id' => 'select-year', 'placeholder' => 'Jahr', 'css-class' => 'mt-3 mb-0']);
|
||||
|
||||
$sp['output'] = $tpl->load('card', [$content, 'css-class' => 'text-center pt-3']);
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-loggedin']);
|
||||
|
||||
// Not loggedin
|
||||
$content = '<h1>Saison-Planungen</h1>';
|
||||
$content .= '<p>Um die Saison-Planungen anderer zu sehen, musst Du angemeldet sein.<br><a href="#" data-menu="menu-login">Melde Dich hier an</a> oder <a href="#" data-menu="menu-signup">registriere Dich jetzt kostenlos</a>.</p>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-notloggedin']);
|
||||
|
||||
// Regattas
|
||||
$content = $tpl->load('input', ['html-id' => 'input-search', 'placeholder' => 'Suche', 'type' => 'text']);
|
||||
$content .= '<div id="div-users" class="normal-list mb-0"></div>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-regattas', 'css-class' => 'show-loggedin']);
|
||||
|
||||
$sp['scripts'] .= $scripts->load('planning_list');
|
||||
|
||||
?>
|
||||
@@ -1,19 +1,38 @@
|
||||
<?php
|
||||
|
||||
// TODO: Create site
|
||||
|
||||
$sp['title'] = 'Seite noch nicht unterstuuml;tzt - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['title'] = 'Saison-Planung - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['backbutton'] = true;
|
||||
$sp['activenav'] = 5;
|
||||
|
||||
$content = $tpl->load('error', ['404', 'Seite existiert noch nicht']);
|
||||
$content .= '<p>';
|
||||
$content .= 'Die gesuchte Seite ist leider noch nicht verfügbar.<br>';
|
||||
$content .= 'Wir arbeiten daran, sie schnellstmöglich zur Verfügung zu stellen.<br>';
|
||||
$content .= 'Wie wäre es mit der Homepage?';
|
||||
$content .= '</p>';
|
||||
$content .= $tpl->load('button', ['Zur Startseite', LINK_PRE . 'index', 'css-class' => 'mb-3']);
|
||||
$content .= $tpl->load('button', ['Kontakt', LINK_PRE . 'contact']);
|
||||
// Title
|
||||
$content = '<h1>Saison-Planung</h1>';
|
||||
$content .= '<p id="p-username" class="mb-1"></p>';
|
||||
$content .= $tpl->load('button', ['<i class="fas fa-share-alt"></i> Teilen', '#', 'html-id' => 'button-share']);
|
||||
$content .= $tpl->load('select', ['html-id' => 'select-year', 'placeholder' => 'Jahr', 'css-class' => 'mt-3 mb-0']);
|
||||
|
||||
$sp['output'] = $tpl->load('card', [$content, 'css-class' => 'text-center pt-3']);
|
||||
$sp['output'] .= $tpl->load('card', [$content]);
|
||||
|
||||
// Regattas
|
||||
$content = '<p id="p-count" class="mb-0"></p>';
|
||||
$content .= $tpl->load('input', ['html-id' => 'input-search', 'placeholder' => 'Suche', 'type' => 'text', 'css-class' => 'mt-2']);
|
||||
$content .= '<div id="div-regattas" class="ranking-detail-list mb-0"></div>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-regattas']);
|
||||
|
||||
// Menu
|
||||
$items = '<p id="menu-item-special" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
|
||||
$items .= '<p id="menu-item-yourplanning" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Saison-Planungen', '', 'html-id' => 'menu-item-plannings', 'icon' => 'fa-calendar-alt', 'badge-id' => 'badge-regatta-plannings']);
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Meldeliste', '', 'html-id' => 'menu-item-entrylist', 'icon' => 'fa-file-signature', 'badge-id' => 'badge-regatta-entrylist']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Ergebnisse', '', 'html-id' => 'menu-item-results', 'icon' => 'fa-poll']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Bericht', '', 'html-id' => 'menu-item-bericht', 'icon' => 'fa-book']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Informationen', '', 'html-id' => 'menu-item-info', 'icon' => 'fa-info']);
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Meldung', '', 'html-id' => 'menu-item-meldung', 'icon' => 'fa-file-signature', 'badge-id' => 'badge-regatta-meldung']);
|
||||
$items .= $tpl->load('menu/item-icon', ['offizielle Ergebnisse', '', 'html-id' => 'menu-item-oresults', 'icon' => 'fa-poll']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Vereins-Website', '', 'html-id' => 'menu-item-clubwebsite', 'icon' => 'fa-globe']);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-regatta', 'title' => 'Regatta-Details', 'height' => 320]);
|
||||
|
||||
$sp['scripts'] .= $scripts->load('onRegattaClicked');
|
||||
$sp['scripts'] .= $scripts->load('planning_view');
|
||||
|
||||
?>
|
||||
@@ -21,9 +21,13 @@
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-regattas']);
|
||||
|
||||
$sp['output'] .= $tpl->load('card', ['<p></p>', 'html-id' => 'card-special']);
|
||||
|
||||
// Menu
|
||||
$items = '<p id="menu-item-yourplanning" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
|
||||
$items .= $tpl->load('menu/item-icon', ['Saison-Planungen', '', 'html-id' => 'menu-item-plannings', 'icon' => 'fa-calendar-alt']);
|
||||
$items = '<p id="menu-item-special" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
|
||||
$items .= '<p id="menu-item-yourplanning" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Saison-Planungen', '', 'html-id' => 'menu-item-plannings', 'icon' => 'fa-calendar-alt', 'badge-id' => 'badge-regatta-plannings']);
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Meldeliste', '', 'html-id' => 'menu-item-entrylist', 'icon' => 'fa-file-signature', 'badge-id' => 'badge-regatta-entrylist']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Ergebnisse', '', 'html-id' => 'menu-item-results', 'icon' => 'fa-poll']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Bericht', '', 'html-id' => 'menu-item-bericht', 'icon' => 'fa-book']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Informationen', '', 'html-id' => 'menu-item-info', 'icon' => 'fa-info']);
|
||||
|
||||
@@ -31,9 +31,16 @@
|
||||
$sp['output'] .= $tpl->load('pagination', ['html-id' => 'pagination']);
|
||||
|
||||
// Menu
|
||||
$items = $tpl->load('menu/item-icon', ['', '#', 'html-id' => 'menu-item-year', 'icon' => 'fa-edit']);
|
||||
$items = $tpl->load('menu/item-switch', ['Favorit', 'html-id' => 'menu-item-follow', 'icon' => 'fa-heart']);
|
||||
$items .= $tpl->load('menu/item-icon-badge', ['Favorit', '#', 'html-id' => 'menu-item-follow-disabled', 'icon' => 'fa-heart', 'badge-value' => 'MAX REACHED']);
|
||||
$items .= $tpl->load('menu/item-icon', ['', '#', 'html-id' => 'menu-item-year', 'icon' => 'fa-edit']);
|
||||
$items .= $tpl->load('menu/item-icon', ['Vereins-Website', '', 'html-id' => 'menu-item-clubwebsite', 'icon' => 'fa-globe', 'css-class' => 'border-0']);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-sailor', 'title' => 'Segler-Details', 'height' => 200]);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-sailor', 'title' => 'Segler-Details', 'height' => 260]);
|
||||
|
||||
$items = '<p class="mb-2 mt-1" style="line-height: 1.5em;">Bitte trage hier den Jahrgang ein:</p>';
|
||||
$items .= $tpl->load('input', ['html-id' => 'input-edityear', 'placeholder' => 'Jahrgang', 'type' => 'number']);
|
||||
$items .= $tpl->load('button', ['Speichern', '#', 'html-id' => 'button-edityear']);
|
||||
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-edityear', 'height' => 240]);
|
||||
|
||||
$sp['scripts'] .= $scripts->load('pagination', ['pageChange', 'page', 'pageCount', 'pagination']);
|
||||
$sp['scripts'] .= $scripts->load('sailors');
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
<div id="menu-share" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="345" data-menu-effect="menu-over">
|
||||
<div class="menu-title mt-n1"><h1>Share the Love</h1><p class="color-highlight">Just Tap the Social Icon. We'll add the Link</p><a href="#" class="close-menu"><i class="fa fa-times"></i></a></div>
|
||||
<div class="menu-title mt-n1"><h1>Seite Teilen</h1><p class="color-highlight">Teile diese Seite mit Deinen Freunden!</p><a href="#" class="close-menu"><i class="fa fa-times"></i></a></div>
|
||||
<div class="content mb-0">
|
||||
<div class="divider mb-0"></div>
|
||||
<div class="list-group list-custom-small list-icon-0">
|
||||
<a href="#" class="shareToFacebook">
|
||||
<a href="#" class="shareToFacebook" target="_blank">
|
||||
<i class="font-18 fab fa-facebook color-facebook"></i>
|
||||
<span class="font-13">Facebook</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" class="shareToTwitter">
|
||||
<a href="#" class="shareToTwitter" target="_blank">
|
||||
<i class="font-18 fab fa-twitter-square color-twitter"></i>
|
||||
<span class="font-13">Twitter</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" class="shareToLinkedIn">
|
||||
<a href="#" class="shareToLinkedIn" target="_blank">
|
||||
<i class="font-18 fab fa-linkedin color-linkedin"></i>
|
||||
<span class="font-13">LinkedIn</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" class="shareToWhatsApp">
|
||||
<a href="#" class="shareToWhatsApp" target="_blank">
|
||||
<i class="font-18 fab fa-whatsapp-square color-whatsapp"></i>
|
||||
<span class="font-13">WhatsApp</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" class="shareToMail border-0">
|
||||
<a href="#" class="shareToMail border-0" target="_blank">
|
||||
<i class="font-18 fa fa-envelope-square color-mail"></i>
|
||||
<span class="font-13">Email</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
@@ -92,7 +92,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="menu-settings" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="270">
|
||||
<div id="menu-settings" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="310">
|
||||
<div class="menu-title"><h1>Einstellungen</h1><p class="color-highlight"> </p><a href="#" class="close-menu"><i class="fa fa-times"></i></a></div>
|
||||
<div class="divider divider-margins mb-n2"></div>
|
||||
<div class="content">
|
||||
@@ -110,7 +110,7 @@
|
||||
<span>Login</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" data-menu="menu-signup" class="show-notloggedin border-0">
|
||||
<a href="#" data-menu="menu-signup" class="show-notloggedin">
|
||||
<i class="fa font-14 fa-user-plus rounded-s bg-highlight color-white"></i>
|
||||
<span>Registrieren</span>
|
||||
<span class="badge bg-red2-dark color-white">FREE</span>
|
||||
@@ -120,45 +120,135 @@
|
||||
<span>Account</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" onclick="logout();" class="show-loggedin border-0">
|
||||
<a href="#" onclick="logout();" class="show-loggedin">
|
||||
<i class="fa font-14 fa-sign-out-alt rounded-s bg-highlight color-white"></i>
|
||||
<span>Logout</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" onclick="pushesOpenMenu()" class="border-0">
|
||||
<i class="fa font-14 fa-bell rounded-s bg-highlight color-white"></i>
|
||||
<span>Benachrichtigungen</span>
|
||||
<span id="badge-pushes" class="badge color-white"></span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="menu-developer" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="310">
|
||||
<div id="menu-pushes" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="500">
|
||||
<div class="menu-title"><h1>Benachrichtigungen</h1><p class="color-highlight">Bleibe immer auf dem aktuellen Stand</p><a href="#" class="close-menu"><i class="fa fa-times"></i></a></div>
|
||||
<div class="divider divider-margins mb-n2"></div>
|
||||
<div class="content">
|
||||
<div class="list-group list-custom-small">
|
||||
<a id="a-switch-pushes" href="#" data-trigger-switch="switch-pushes" class="pb-2">
|
||||
<i class="fa font-14 fa-bell rounded-s bg-highlight color-white"></i>
|
||||
<span>Benachrichtigungen aktivieren</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes">
|
||||
<label class="custom-control-label" for="switch-pushes"></label>
|
||||
</div>
|
||||
</a>
|
||||
<div class="divider"></div>
|
||||
<p style="line-height: 1.5em;" id="p-pushes-info">
|
||||
Wähle hier, über was Du informiert werden möchtest.<br>
|
||||
(meine) bezieht sich auf die Regatten, die in Deiner Saison-Planung sind,<br>
|
||||
(alle) informiert Dich über alle Regatten
|
||||
</p>
|
||||
<a href="#" data-trigger-switch="switch-pushes-news" class="pb-2 a-switch-pushes-channel-all">
|
||||
<i class="fa font-14 fa-newspaper rounded-s bg-highlight color-white"></i>
|
||||
<span>Neuigkeiten</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-news">
|
||||
<label class="custom-control-label" for="switch-pushes-news"></label>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" data-trigger-switch="switch-pushes-regatta-changed-my" class="pb-2 a-switch-pushes-channel-my">
|
||||
<i class="fa font-14 fa-calendar-check rounded-s bg-highlight color-white"></i>
|
||||
<span>Regatta verschoben (meine)</span>
|
||||
<span class="badge bg-red2-dark color-white"></span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-regatta-changed-my">
|
||||
<label class="custom-control-label" for="switch-pushes-regatta-changed-my"></label>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" data-trigger-switch="switch-pushes-regatta-changed-all" class="pb-2 a-switch-pushes-channel-all">
|
||||
<i class="fa font-14 fa-calendar-check rounded-s bg-highlight color-white"></i>
|
||||
<span>Regatta verschoben (alle)</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-regatta-changed-all">
|
||||
<label class="custom-control-label" for="switch-pushes-regatta-changed-all"></label>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" data-trigger-switch="switch-pushes-result-ready-my" class="pb-2 a-switch-pushes-channel-my">
|
||||
<i class="fa font-14 fa-poll rounded-s bg-highlight color-white"></i>
|
||||
<span>Ergebnisse verfügbar (meine)</span>
|
||||
<span class="badge bg-red2-dark color-white"></span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-result-ready-my">
|
||||
<label class="custom-control-label" for="switch-pushes-result-ready-my"></label>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" data-trigger-switch="switch-pushes-result-ready-all" class="pb-2 a-switch-pushes-channel-all">
|
||||
<i class="fa font-14 fa-poll rounded-s bg-highlight color-white"></i>
|
||||
<span>Ergebnisse verfügbar (alle)</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-result-ready-all">
|
||||
<label class="custom-control-label" for="switch-pushes-result-ready-all"></label>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" data-trigger-switch="switch-pushes-meldeschluss" class="pb-2 a-switch-pushes-channel-my">
|
||||
<i class="fa font-14 fa-file-signature rounded-s bg-highlight color-white"></i>
|
||||
<span>Melde-Erinnerungen</span>
|
||||
<span class="badge bg-red2-dark color-white"></span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-meldeschluss">
|
||||
<label class="custom-control-label" for="switch-pushes-meldeschluss"></label>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="menu-developer" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="400">
|
||||
<div class="menu-title"><h1>Entwickler-Optionen</h1><p class="color-highlight">Version <?php echo PWA_VERSION; ?></p><a href="#" class="close-menu"><i class="fa fa-times"></i></a></div>
|
||||
<div class="divider divider-margins mb-n2"></div>
|
||||
<div class="content">
|
||||
<div class="list-group list-custom-small">
|
||||
<a href="https://info.ostertun.net/regatten/beta">
|
||||
<a href="https://github.com/ostertun/RegattenApp/wiki">
|
||||
<i class="fa font-14 fa-info rounded-s bg-highlight color-white"></i>
|
||||
<span>Infos zur BETA</span>
|
||||
<span>App-Wiki</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="javascript:resetDb(false);">
|
||||
<a href="javascript:deleteDb();">
|
||||
<i class="fa font-14 fa-database rounded-s bg-highlight color-white"></i>
|
||||
<span>Reset Database</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="javascript:resetCache();">
|
||||
<a href="javascript:deleteCache();">
|
||||
<i class="fa font-14 fa-trash-alt rounded-s bg-highlight color-white"></i>
|
||||
<span>Reset Cache</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="https://report.regatten.net/" class="border-0">
|
||||
<a href="https://github.com/ostertun/RegattenApp/issues/new">
|
||||
<i class="fa font-14 fa-bug rounded-s bg-highlight color-white"></i>
|
||||
<span>Problem melden</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" onclick="sendErrorReport(); return false;" class="menu-close">
|
||||
<i class="fa font-14 fa-bug rounded-s bg-highlight color-white"></i>
|
||||
<span>Fehlerbericht senden</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" onclick="mobileConsole.displayConsole(); return false;" class="border-0 menu-close">
|
||||
<i class="fa font-14 fa-terminal rounded-s bg-highlight color-white"></i>
|
||||
<span>Console anzeigen</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="menu-login" class="menu menu-box-top menu-box-detached rounded-m" data-menu-height="270">
|
||||
<div id="menu-login" class="menu menu-box-top menu-box-detached rounded-m" data-menu-height="320">
|
||||
<div class="content bottom-0">
|
||||
<h1 class="text-center mt-5 font-900">Login</h1>
|
||||
<div class="input-style input-style-2 has-icon input-required">
|
||||
@@ -172,18 +262,29 @@
|
||||
<input id="input-login-password" class="form-control" type="password" placeholder="Passwort" />
|
||||
</div>
|
||||
<a class="btn btn-m mt-2 mb-2 btn-full bg-green2-dark text-uppercase font-900" href="#" onclick="login();">Login</a>
|
||||
<p class="text-center mt-3"><a class="text-uppercase font-900" href="https://regatten.net/reset">Benutzername oder Passwort vergessen</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="menu-signup" class="menu menu-box-modal menu-box-detached rounded-m" data-menu-height="300">
|
||||
<div id="menu-signup" class="menu menu-box-top menu-box-detached rounded-m" data-menu-height="340">
|
||||
<div class="content bottom-0">
|
||||
<h1 class="text-center mt-5 font-900">Registrieren</h1>
|
||||
<p class="text-center">
|
||||
Momentan kannst Du Dich leider nicht in der App registrieren.<br>
|
||||
Das ist aber kein Problem, registriere Dich einfach kostenlos auf unserer Website!
|
||||
</p>
|
||||
<a href="https://regatten.net/de/signup" class="btn btn-center-xl btn-m shadow-xl rounded-s bg-highlight font-900 text-center">Registrieren</a>
|
||||
<p class="text-center font-10 bottom-0">Du kannst Dich danach in dieser App anmelden.</p>
|
||||
<div class="input-style input-style-2 has-icon input-required">
|
||||
<i class="input-icon fa fa-user color-theme"></i>
|
||||
<span class="color-highlight">Benutzername</span>
|
||||
<input id="input-signup-username" class="form-control" type="name" placeholder="Benutzername" />
|
||||
</div>
|
||||
<div class="input-style input-style-2 has-icon input-required">
|
||||
<i class="input-icon fa fa-envelope color-theme"></i>
|
||||
<span class="color-highlight">Email</span>
|
||||
<input id="input-signup-email" class="form-control" type="email" placeholder="Email" />
|
||||
</div>
|
||||
<div class="input-style input-style-2 has-icon input-required">
|
||||
<i class="input-icon fa fa-lock color-theme"></i>
|
||||
<span class="color-highlight">Passwort</span>
|
||||
<input id="input-signup-password" class="form-control" type="password" placeholder="Passwort" />
|
||||
</div>
|
||||
<a class="btn btn-m mt-2 mb-2 btn-full bg-green2-dark text-uppercase font-900" href="#" onclick="signup();">Registrieren</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -197,7 +298,7 @@
|
||||
Vielen Dank für Deine Unterstützung!
|
||||
</p>
|
||||
<p>
|
||||
Mehr Informationen findest <a href="https://info.ostertun.net/regatten/beta">hier</a>.
|
||||
Mehr Informationen findest Du <a href="https://info.ostertun.net/regatten/beta">hier</a>.
|
||||
</p>
|
||||
<p>
|
||||
Mit der Nutzung dieser App erklärst Du Dich außerdem damit einverstanden, dass wir Cookies einsetzen.
|
||||
@@ -206,14 +307,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="menu-update">
|
||||
<div id="menu-nodb-warning" class="menu menu-box-bottom menu-box-detached rounded-m" data-height="500">
|
||||
<div class="menu-title"><h1>Warnung</h1><p class="color-highlight">Datenbank nicht unterstützt</p><a href="#" class="close-menu"><i class="fa fa-times"></i></a></div>
|
||||
<div class="divider divider-margins mb-n2"></div>
|
||||
<div class="content bottom-0">
|
||||
<p class="text-center mt-5"><i class="fa fa-sync-alt fa-7x color-highlight fa-spin"></i></p>
|
||||
<h1 class="text-center mt-5 font-900">Update Verfügbar</h1>
|
||||
<p class="text-center">
|
||||
Eine neue Version unserer App ist verfügbar. Keine Sorge, Du musst nichts machen. Wir aktuallisieren den Inhalt in wenigen Sekunden.
|
||||
<p>
|
||||
Das Speichern der benötigten Daten wird von Deinem Gerät nicht unterstützt.<br>
|
||||
Da deshalb die Daten jedesmal direkt vom Server geladen werden müssen, kannst Du die App nicht offline nutzen.<br>
|
||||
Das Nachladen kann außerdem gerade bei großen Datenmengen (wie Ranglisten) sehr lange dauern.
|
||||
Wir empfehlen Dir daher, auf diesem Gerät unsere normale Website zu benutzen. Diese ist auch für Mobil-Geräte optimiert.
|
||||
</p>
|
||||
<a href="#" class="page-update btn btn-center-xl btn-m shadow-xl rounded-s bg-highlight font-900 text-center">Update</a>
|
||||
<p class="text-center font-10 bottom-0">Die App wird neu laden und das Update ist abgeschlossen.</p>
|
||||
<a class="btn btn-m mt-2 btn-full bg-highlight text-uppercase font-900" href="https://regatten.net/">Zur Website</a>
|
||||
<a id="menu-nodb-warning-okay" class="btn btn-m mt-2 mb-3 btn-full bg-highlight text-uppercase font-900" href="#">Nicht erneut anzeigen</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2,6 +2,7 @@
|
||||
<html lang="de">
|
||||
|
||||
<head>
|
||||
<script type="text/javascript" src="<?php echo SERVER_ADDR; ?>/client/scripts/mobileconsole.js"></script>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
@@ -26,7 +27,8 @@
|
||||
<?php include(__DIR__ . '/headerfooter.php'); ?>
|
||||
|
||||
<!--start of page content, add your stuff here-->
|
||||
<div class="page-content header-clear-medium">
|
||||
<div class="page-content header-clear">
|
||||
<div id="syncstatus" class="text-right mr-2 mb-1">Zuletzt aktualisiert: nie</div>
|
||||
<?php echo $sp['output']; ?>
|
||||
</div>
|
||||
<!--end of page content, off canvas elements here-->
|
||||
|
||||
@@ -5,18 +5,64 @@ var page = 1;
|
||||
var pageCount = 0;
|
||||
const showCount = 25;
|
||||
|
||||
async function onEditBoatnameClick() {
|
||||
var id = $('#button-editboatname').attr('data-boat-id');
|
||||
var name = $('#input-editboatname').val();
|
||||
if (name != '') {
|
||||
showLoader();
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'add_boatname',
|
||||
method: 'POST',
|
||||
data: {
|
||||
boat: id,
|
||||
name: name
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um den Bootsnamen zu bearbeiten');
|
||||
} else {
|
||||
log('EditBoatname: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
hideLoader();
|
||||
},
|
||||
success: function (data, status, xhr) {
|
||||
if ('status' in data) {
|
||||
if (data.status == 'added') {
|
||||
toastOk('Bootsnamen erfolgreich hinzugefügt');
|
||||
sync();
|
||||
} else {
|
||||
toastInfo('Wir prüfen Deine Anfrage und korrigieren den Bootsnamen schnellstmöglich', 5000);
|
||||
}
|
||||
} else {
|
||||
toastOk('Erfolgreich');
|
||||
}
|
||||
hideLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
$('#menu-editboatname').hideMenu();
|
||||
}
|
||||
|
||||
async function onListClicked(id) {
|
||||
var boat = await dbGetData('boats', id);
|
||||
|
||||
$('#menu-boat').find('.menu-title').find('p').text(boat.sailnumber);
|
||||
|
||||
// Edit Boatname
|
||||
// TODO: create menu for edit boatname
|
||||
$('#button-editboatname').attr('data-boat-id', boat.id);
|
||||
$('#menu-editboatname').find('.menu-title').find('p').text(boat.sailnumber);
|
||||
if (boat['name'] == '') {
|
||||
$('#menu-item-boatname').find('span').text('Bootsnamen hinzufügen');
|
||||
$('#menu-editboatname').find('.menu-title').find('h1').text('Bootsnamen hinzufügen');
|
||||
$('#input-editboatname').val('');
|
||||
} else {
|
||||
$('#menu-item-boatname').find('span').text('Bootsnamen bearbeiten');
|
||||
$('#menu-editboatname').find('.menu-title').find('h1').text('Bootsnamen bearbeiten');
|
||||
$('#input-editboatname').val(boat.name);
|
||||
}
|
||||
$('#input-editboatname').trigger('focusin').trigger('focusout');
|
||||
|
||||
// club website
|
||||
var clubwebsite = '';
|
||||
@@ -86,6 +132,8 @@ var siteScript = async function() {
|
||||
firstCall = false;
|
||||
initPagination();
|
||||
$('#input-search').on('input', reSearch);
|
||||
$('#menu-item-boatname').click(function(){ $('#menu-boat').hideMenu(); $('#menu-editboatname').showMenu(); });
|
||||
$('#button-editboatname').click(onEditBoatnameClick);
|
||||
}
|
||||
|
||||
var results = await dbGetData('boats');
|
||||
|
||||
@@ -68,10 +68,10 @@ function addRace() {
|
||||
rlp: (100 * rlf * ((fb + 1 - pl) / fb))
|
||||
};
|
||||
|
||||
$('#input-rlf').val('');
|
||||
$('#input-m').val('');
|
||||
$('#input-fb').val('');
|
||||
$('#input-pl').val('');
|
||||
$('#input-rlf').val('').trigger('focusin').trigger('focusout');
|
||||
$('#input-m').val('').trigger('focusin').trigger('focusout');
|
||||
$('#input-fb').val('').trigger('focusin').trigger('focusout');
|
||||
$('#input-pl').val('').trigger('focusin').trigger('focusout');
|
||||
|
||||
races.push(race);
|
||||
reCalc();
|
||||
|
||||
49
server/scripts/contact.js
Normal file
49
server/scripts/contact.js
Normal file
@@ -0,0 +1,49 @@
|
||||
function sendMessage() {
|
||||
var name = $('#input-name').val();
|
||||
var email = $('#input-email').val();
|
||||
var subject = $('#input-subject').val();
|
||||
var message = $('#input-message').val();
|
||||
|
||||
if ((name == '') || (email == '') || (subject == '') || (message == '')) {
|
||||
toastError('Bitte fülle alle Felder aus!');
|
||||
return;
|
||||
}
|
||||
|
||||
showLoader();
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'contact',
|
||||
method: 'POST',
|
||||
data: {
|
||||
name: name,
|
||||
email: email,
|
||||
subject: subject,
|
||||
message: message
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um eine Nachricht zu versenden');
|
||||
} else {
|
||||
log('Contact: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
hideLoader();
|
||||
},
|
||||
success: function (data, status, xhr) {
|
||||
toastOk('Nachricht erfolgreich versandt!');
|
||||
$('#input-subject').val('').trigger('focusin').trigger('focusout');
|
||||
$('#input-message').val('').trigger('focusin').trigger('focusout');
|
||||
hideLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var siteScript = async function () {
|
||||
if (isLoggedIn()) {
|
||||
var user = await dbGetData('users', USER_ID);
|
||||
$('#input-name').val(user.username).trigger('focusin').trigger('focusout');
|
||||
$('#input-email').val(user.email).trigger('focusin').trigger('focusout');
|
||||
}
|
||||
$('#button-send').click(sendMessage);
|
||||
hideLoader();
|
||||
}
|
||||
12
server/scripts/go2url.js
Normal file
12
server/scripts/go2url.js
Normal file
@@ -0,0 +1,12 @@
|
||||
var siteScript = function() {
|
||||
hideLoader();
|
||||
setTimeout(function() {
|
||||
var url = findGetParameter('url');
|
||||
if (url === null) {
|
||||
$('#card-title').find('p').html('Wir konnten Dich leider nicht umleiten.<br><a href="' + LINK_PRE + 'index">Hier kommst Du zurück zur Startseite</a>');
|
||||
} else {
|
||||
showLoader();
|
||||
location.href = url;
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
@@ -1,8 +1,84 @@
|
||||
var firstCall = true;
|
||||
var today;
|
||||
var onUpdatePushBadge;
|
||||
|
||||
var onUnfollowClicked = async function() {
|
||||
var id = $('#menu-item-unfollow').attr('data-sailor-id');
|
||||
showLoader();
|
||||
$('#menu-favorite').hideMenu();
|
||||
var auth = {
|
||||
id: localStorage.getItem('auth_id'),
|
||||
hash: localStorage.getItem('auth_hash')
|
||||
}
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'sailor_unfollow',
|
||||
method: 'POST',
|
||||
data: {
|
||||
auth: auth,
|
||||
sailor: id
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um Deine Favoriten zu bearbeiten.');
|
||||
} else {
|
||||
log('Unfollow: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
hideLoader();
|
||||
},
|
||||
success: async function (data, status, xhr) {
|
||||
await sync();
|
||||
toastOk('Erfolgreich');
|
||||
hideLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var onFavoriteClicked = async function(id) {
|
||||
var sailor = await dbGetData('sailors', id);
|
||||
|
||||
$('#menu-favorite').find('.menu-title').find('p').text(sailor.name);
|
||||
|
||||
$('#menu-item-unfollow').attr('data-sailor-id', sailor.id);
|
||||
|
||||
$('#menu-favorite').showMenu();
|
||||
}
|
||||
|
||||
var siteScript = async function() {
|
||||
today = getToday();
|
||||
|
||||
if (firstCall) {
|
||||
firstCall = false;
|
||||
$('#button-notifications-activate').click(function(){
|
||||
pushesOpenMenu();
|
||||
});
|
||||
$('#a-notifications-later').click(function(){
|
||||
createCookie('regatten_app_' + BOATCLASS + '_rejected_push', true, 1);
|
||||
$('#card-notifications').hide();
|
||||
});
|
||||
if (readCookie('regatten_app_' + BOATCLASS + '_rejected_push')) {
|
||||
$('#card-notifications').hide();
|
||||
} else {
|
||||
onUpdatePushBadge = function () {
|
||||
if (!pushesPossible || (Notification.permission == 'denied')) {
|
||||
$('#card-notifications').hide();
|
||||
} else {
|
||||
swRegistration.pushManager.getSubscription().then(function(subscription) {
|
||||
var isSub = (subscription !== null);
|
||||
if (isSub) {
|
||||
$('#card-notifications').hide();
|
||||
} else {
|
||||
$('#card-notifications').show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
onUpdatePushBadge();
|
||||
}
|
||||
$('#menu-item-unfollow').click(onUnfollowClicked);
|
||||
}
|
||||
|
||||
if (isLoggedIn()) {
|
||||
$('#card-notloggedin').hide();
|
||||
|
||||
@@ -18,31 +94,41 @@ var siteScript = async function() {
|
||||
}
|
||||
if (watched.length > 0) {
|
||||
var year = (new Date()).getFullYear();
|
||||
$('#th-ranking').html('Rangliste ' + year);
|
||||
var ranking = (await dbGetRanking(parseDate('01.12.' + (year - 1)), parseDate('30.11.' + year), false, false))[0];
|
||||
tbody = '';
|
||||
var list = '';
|
||||
for (i in watched) {
|
||||
sailor = watched[i];
|
||||
tbody += '<tr><td>' + sailor.name + '</td><td>';
|
||||
var club = null;
|
||||
if (sailor.club != null)
|
||||
club = await dbGetData('clubs', sailor.club);
|
||||
var rank = null;
|
||||
for (r in ranking) {
|
||||
if (ranking[r].id == sailor.id) {
|
||||
rank = ranking[r].rank;
|
||||
rank = ranking[r];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list += '<div onclick="onFavoriteClicked(' + sailor.id + ');">';
|
||||
list += '<div>';
|
||||
// Name
|
||||
list += '<div><b>' + sailor.name + '</b></div>';
|
||||
list += '</div><div>';
|
||||
if (rank == null) {
|
||||
tbody += '<i>nicht in der Rangliste</i>';
|
||||
list += '<div>Nicht in der Rangliste</div>';
|
||||
} else {
|
||||
tbody += '<b>' + rank + '.</b> Platz';
|
||||
// Rank
|
||||
list += '<div>Platz <b>' + rank.rank + '</b></div>';
|
||||
// rlp
|
||||
list += '<div>' + rank.rlp.toFixed(3) + ' Punkte</div>';
|
||||
}
|
||||
tbody += '</td></tr>';
|
||||
list += '</div></div>';
|
||||
}
|
||||
$('#table-favorites').find('tbody').html(tbody);
|
||||
$('#div-favorites').html(list);
|
||||
$('#p-favorites').hide();
|
||||
$('#table-favorites').show();
|
||||
$('#div-favorites').show();
|
||||
} else {
|
||||
$('#table-favorites').hide();
|
||||
$('#div-favorites').hide();
|
||||
$('#p-favorites').show();
|
||||
}
|
||||
$('#card-favorites').show();
|
||||
@@ -50,7 +136,7 @@ var siteScript = async function() {
|
||||
// Your next
|
||||
var planningsDB = await dbGetDataIndex('plannings', 'user', user.id);
|
||||
var minDate = getToday();
|
||||
minDate.setDate(minDate.getDate() - 1);
|
||||
minDate.setDate(minDate.getDate());
|
||||
var maxDate = getToday();
|
||||
maxDate.setDate(maxDate.getDate() + 28);
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
@@ -59,7 +145,7 @@ var siteScript = async function() {
|
||||
var planning = planningsDB[i];
|
||||
for (j in regattas) {
|
||||
var regatta = regattas[j];
|
||||
if (regatta.id == planning.regatta) {
|
||||
if ((regatta.id == planning.regatta) && (regatta.length > 0)) {
|
||||
planning.regatta = regatta;
|
||||
plannings.push(planning);
|
||||
}
|
||||
@@ -76,8 +162,6 @@ var siteScript = async function() {
|
||||
var planning = plannings[i];
|
||||
var regatta = planning.regatta;
|
||||
|
||||
if (regatta['length'] < 1) continue;
|
||||
|
||||
var club = null;
|
||||
if (regatta['club'] != null)
|
||||
club = await dbGetData('clubs', regatta['club']);
|
||||
@@ -102,6 +186,26 @@ var siteScript = async function() {
|
||||
list += '<div>' + ((club != null) ? club['kurz'] : '') + '</div>';
|
||||
|
||||
// Special
|
||||
if (regatta.special.substr(0, 1) == '#') {
|
||||
regatta.special = '* ' + regatta.special.substr(1);
|
||||
}
|
||||
// replace placeholders
|
||||
var pos;
|
||||
while ((pos = regatta.special.indexOf('$')) >= 0) {
|
||||
var pos2 = regatta.special.indexOf('$', pos + 1);
|
||||
if (pos2 < 0) break;
|
||||
var key = regatta.special.substring(pos + 1, pos2);
|
||||
|
||||
var value = '';
|
||||
// age class
|
||||
if ((key.substr(0, 1) == 'U') && (!isNaN(value = parseInt(key.substr(1))))) {
|
||||
value = 'U-' + value;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
regatta.special = regatta.special.replace('$' + key + '$', value);
|
||||
}
|
||||
list += '<div>' + regatta['special'] + '</div>';
|
||||
|
||||
// Icons
|
||||
@@ -120,8 +224,10 @@ var siteScript = async function() {
|
||||
ms = parseDate(regatta['meldungSchluss']);
|
||||
}
|
||||
var diff = Math.round((ms - today) / 86400000);
|
||||
if ((ms >= today) && (diff < 7)) {
|
||||
if (ms < today) {
|
||||
color = ' color-red2-dark';
|
||||
} else if (diff < 7) {
|
||||
color = ' color-yellow2-dark';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,17 +270,23 @@ var siteScript = async function() {
|
||||
|
||||
// Next
|
||||
var minDate = getToday();
|
||||
minDate.setDate(minDate.getDate() - 1);
|
||||
minDate.setDate(minDate.getDate());
|
||||
var maxDate = getToday();
|
||||
maxDate.setDate(maxDate.getDate() + 14);
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
i = 0;
|
||||
while (i < regattas.length) {
|
||||
if (regattas[i].length < 1) {
|
||||
regattas.splice(i, 1);
|
||||
} else {
|
||||
i ++;
|
||||
}
|
||||
}
|
||||
if (regattas.length > 0) {
|
||||
list = '';
|
||||
for (i in regattas) {
|
||||
var regatta = regattas[i];
|
||||
|
||||
if (regatta['length'] < 1) continue;
|
||||
|
||||
var club = null;
|
||||
if (regatta['club'] != null)
|
||||
club = await dbGetData('clubs', regatta['club']);
|
||||
@@ -199,6 +311,26 @@ var siteScript = async function() {
|
||||
list += '<div>' + ((club != null) ? club['kurz'] : '') + '</div>';
|
||||
|
||||
// Special
|
||||
if (regatta.special.substr(0, 1) == '#') {
|
||||
regatta.special = '* ' + regatta.special.substr(1);
|
||||
}
|
||||
// replace placeholders
|
||||
var pos;
|
||||
while ((pos = regatta.special.indexOf('$')) >= 0) {
|
||||
var pos2 = regatta.special.indexOf('$', pos + 1);
|
||||
if (pos2 < 0) break;
|
||||
var key = regatta.special.substring(pos + 1, pos2);
|
||||
|
||||
var value = '';
|
||||
// age class
|
||||
if ((key.substr(0, 1) == 'U') && (!isNaN(value = parseInt(key.substr(1))))) {
|
||||
value = 'U-' + value;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
regatta.special = regatta.special.replace('$' + key + '$', value);
|
||||
}
|
||||
list += '<div>' + regatta['special'] + '</div>';
|
||||
|
||||
// Icons
|
||||
@@ -227,8 +359,10 @@ var siteScript = async function() {
|
||||
ms = parseDate(regatta['meldungSchluss']);
|
||||
}
|
||||
var diff = Math.round((ms - today) / 86400000);
|
||||
if ((ms >= today) && (diff < 7)) {
|
||||
if (ms < today) {
|
||||
color = ' color-red2-dark';
|
||||
} else if (diff < 7) {
|
||||
color = ' color-yellow2-dark';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,19 +403,22 @@ var siteScript = async function() {
|
||||
var maxDate = getToday();
|
||||
maxDate.setDate(maxDate.getDate() - 1);
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
var regattaResults = [];
|
||||
for (id in regattas) {
|
||||
var entry = regattas[id];
|
||||
var results = await dbGetDataIndex('results', 'regatta', entry['id']);
|
||||
regattaResults[entry['id']] = (results.length > 0);
|
||||
i = 0;
|
||||
while (i < regattas.length) {
|
||||
if (regattas[i].length < 1) {
|
||||
regattas.splice(i, 1);
|
||||
} else {
|
||||
i ++;
|
||||
}
|
||||
}
|
||||
regattas.sort(function(a,b){
|
||||
return b.date.localeCompare(a.date);
|
||||
});
|
||||
if (regattas.length > 0) {
|
||||
list = '';
|
||||
for (i in regattas) {
|
||||
var regatta = regattas[i];
|
||||
|
||||
if (regatta['length'] < 1) continue;
|
||||
|
||||
var club = null;
|
||||
if (regatta['club'] != null)
|
||||
club = await dbGetData('clubs', regatta['club']);
|
||||
@@ -306,6 +443,26 @@ var siteScript = async function() {
|
||||
list += '<div>' + ((club != null) ? club['kurz'] : '') + '</div>';
|
||||
|
||||
// Special
|
||||
if (regatta.special.substr(0, 1) == '#') {
|
||||
regatta.special = '* ' + regatta.special.substr(1);
|
||||
}
|
||||
// replace placeholders
|
||||
var pos;
|
||||
while ((pos = regatta.special.indexOf('$')) >= 0) {
|
||||
var pos2 = regatta.special.indexOf('$', pos + 1);
|
||||
if (pos2 < 0) break;
|
||||
var key = regatta.special.substring(pos + 1, pos2);
|
||||
|
||||
var value = '';
|
||||
// age class
|
||||
if ((key.substr(0, 1) == 'U') && (!isNaN(value = parseInt(key.substr(1))))) {
|
||||
value = 'U-' + value;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
regatta.special = regatta.special.replace('$' + key + '$', value);
|
||||
}
|
||||
list += '<div>' + regatta['special'] + '</div>';
|
||||
|
||||
// Icons
|
||||
@@ -316,7 +473,7 @@ var siteScript = async function() {
|
||||
icons.push('<i class="fas fa-book"></i>');
|
||||
if (regatta['canceled'] == '1') {
|
||||
icons.push('<i class="fas fa-times color-red2-dark"></i>');
|
||||
} else if (regattaResults[regatta['id']]) {
|
||||
} else if (regatta['results'] == '1') {
|
||||
icons.push('<i class="fas fa-poll"></i>');
|
||||
}
|
||||
list += '<div class="color-green2-dark">' + icons.join(' ') + '</div>';
|
||||
|
||||
88
server/scripts/news.js
Normal file
88
server/scripts/news.js
Normal file
@@ -0,0 +1,88 @@
|
||||
var firstCall = true;
|
||||
var rows = [];
|
||||
var page = 1;
|
||||
var pageCount = 0;
|
||||
const showCount = 10;
|
||||
|
||||
async function onNewsClicked(id) {
|
||||
var newsEntry = await dbGetData('news', id);
|
||||
if (newsEntry == null) return;
|
||||
|
||||
$('#menu-news').css('height', '80%');
|
||||
$('#menu-news').css('width', '90%');
|
||||
$('#menu-news').find('.menu-title').find('p').text(newsEntry.title);
|
||||
$('#menu-news').find('.content').addClass('pb-3');
|
||||
$('#menu-news').find('.content').html(newsEntry.html);
|
||||
|
||||
$('#menu-news').showMenu();
|
||||
}
|
||||
|
||||
function pageChange() {
|
||||
$('h1')[0].scrollIntoView({ behavior: "smooth" });
|
||||
drawList();
|
||||
}
|
||||
|
||||
function addCard(newsEntry) {
|
||||
var badge = '';
|
||||
if (newsEntry.unread) {
|
||||
badge += '<span class="badge bg-highlight color-white p-1">NEW</span> ';
|
||||
}
|
||||
var content = '<h2>' + badge + newsEntry.title + '</h2>';
|
||||
content += '<p class="mb-2"><i>' + formatDate('d.m.Y', newsEntry.date) + '</i></p>';
|
||||
content += '<p class="mb-0">' + newsEntry.description.replace('\n', '<br>') + '</p>';
|
||||
if (newsEntry.html != '') {
|
||||
content += '<a class="btn btn-full rounded-s text-uppercase font-900 shadow-m bg-highlight mt-3" href="#" onclick="onNewsClicked(' + newsEntry.id + '); return false;">Mehr lesen</a>';
|
||||
}
|
||||
|
||||
$('#news-entries').append(cardTemplate.replace('%ID%', 'card-news-' + newsEntry.id).replace('%CONTENT%', content));
|
||||
}
|
||||
|
||||
async function drawList() {
|
||||
$('.card-news').remove();
|
||||
if (rows.length > 0) {
|
||||
var offset = (page - 1) * showCount;
|
||||
var count = (page == pageCount ? (rows.length % showCount) : showCount);
|
||||
if (count == 0) count = showCount;
|
||||
|
||||
for (i = 0; i < count; i ++) {
|
||||
addCard(rows[i + offset]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var siteScript = async function() {
|
||||
if (firstCall) {
|
||||
firstCall = false;
|
||||
initPagination();
|
||||
}
|
||||
rows = [];
|
||||
var news = await dbGetData('news');
|
||||
news.sort(function (a,b) {
|
||||
return b.date.localeCompare(a.date);
|
||||
});
|
||||
var newsRead = await dbSettingsGet('news_read_' + BOATCLASS);
|
||||
var now = new Date();
|
||||
var lastYear = new Date();
|
||||
lastYear.setFullYear(lastYear.getFullYear() - 1);
|
||||
for (var n in news) {
|
||||
var newsEntry = news[n];
|
||||
newsEntry.date = parseDbTimestamp(newsEntry.date);
|
||||
if (newsEntry.date > now) continue;
|
||||
if (newsEntry.date < lastYear) break;
|
||||
newsEntry.unread = (newsEntry.date > newsRead);
|
||||
rows.push(newsEntry);
|
||||
}
|
||||
pageCount = Math.ceil(rows.length / showCount);
|
||||
if ((page < 1) || (page > pageCount)) {
|
||||
if (page < 1) {
|
||||
page = 1;
|
||||
} else {
|
||||
page = pageCount;
|
||||
}
|
||||
}
|
||||
drawPagination();
|
||||
drawList();
|
||||
dbSettingsSet('news_read_' + BOATCLASS, now);
|
||||
updateNewsBadge();
|
||||
hideLoader();
|
||||
}
|
||||
@@ -6,6 +6,43 @@ async function onRegattaClicked(id) {
|
||||
var dateTo = parseDate(regatta['date']);
|
||||
dateTo.setDate(dateTo.getDate() + Math.max(parseInt(regatta['length']) - 1, 0));
|
||||
|
||||
var text = [];
|
||||
var specialFields = await dbGetClassProp('special-fields');
|
||||
if (specialFields === null) specialFields = {};
|
||||
if (regatta.special.substr(0, 1) == '#') {
|
||||
regatta.special = regatta.special.substr(1);
|
||||
if (typeof specialFields[regatta.special] !== 'undefined') {
|
||||
text.push(specialFields[regatta.special]);
|
||||
}
|
||||
}
|
||||
var pos;
|
||||
while ((pos = regatta.special.indexOf('$')) >= 0) {
|
||||
var pos2 = regatta.special.indexOf('$', pos + 1);
|
||||
if (pos2 < 0) break;
|
||||
var key = regatta.special.substring(pos + 1, pos2);
|
||||
|
||||
// age class
|
||||
if ((key.substr(0, 1) == 'U') && (!isNaN(value = parseInt(key.substr(1))))) {
|
||||
var year = parseDate(regatta.date).getFullYear();
|
||||
year = year - value + 1;
|
||||
text.push('Jahrgänge ' + year + ' und jünger');
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
regatta.special = regatta.special.replace('$' + key + '$', '');
|
||||
}
|
||||
if (text.length > 0) {
|
||||
text.sort();
|
||||
for (i in text) {
|
||||
text[i] = $('<div />').text(text[i]).html();
|
||||
}
|
||||
$('#menu-item-special').html(text.join('<br>'));
|
||||
$('#menu-item-special').show();
|
||||
} else {
|
||||
$('#menu-item-special').hide();
|
||||
}
|
||||
|
||||
var plannings = await dbGetDataIndex('plannings', 'regatta', regatta['id']);
|
||||
var planning = null;
|
||||
if (isLoggedIn()) {
|
||||
@@ -32,22 +69,52 @@ async function onRegattaClicked(id) {
|
||||
crew.push(sailor.name);
|
||||
}
|
||||
}
|
||||
var status = '';
|
||||
if (planning.gemeldet == '1') status = 'gemeldet';
|
||||
if (planning.bezahlt == '1') {
|
||||
if (status != '') status += ' und ';
|
||||
status += 'bezahlt';
|
||||
}
|
||||
if (status != '') crew.push('<font style="font-style:italic;">' + status + '</font>');
|
||||
$('#menu-item-yourplanning').html(crew.join('<br>'));
|
||||
} else {
|
||||
$('#menu-item-yourplanning').hide();
|
||||
}
|
||||
|
||||
// Planning: Edit Status
|
||||
if ((planning != null) && (typeof planningEditStatus === 'function')) {
|
||||
$('#menu-item-status').show();
|
||||
$('#menu-item-status').attr('onclick', 'planningEditStatus(' + regatta['id'] + ')');
|
||||
} else {
|
||||
$('#menu-item-status').hide();
|
||||
}
|
||||
|
||||
// Planning
|
||||
if ((plannings.length > 0) && (dateTo >= today)) {
|
||||
$('#menu-item-plannings').show();
|
||||
$('#badge-regatta-plannings').text(plannings.length);
|
||||
$('#menu-item-plannings').attr('href', LINK_PRE + 'regatta_plan?regatta=' + regatta['id']);
|
||||
$('#menu-item-plannings').show();
|
||||
} else {
|
||||
$('#menu-item-plannings').hide();
|
||||
}
|
||||
|
||||
// Entrylist
|
||||
var extServiceData;
|
||||
try {
|
||||
extServiceData = JSON.parse(regatta.extServiceData);
|
||||
} catch {
|
||||
extServiceData = {};
|
||||
}
|
||||
if ((regatta.extService !== null) && ('entryCount' in extServiceData)) {
|
||||
$('#badge-regatta-entrylist').text(extServiceData.entryCount);
|
||||
$('#menu-item-entrylist').attr('href', extServiceGetLink(regatta.extService, 'entrylist', extServiceData.eventId)); // TODO
|
||||
$('#menu-item-entrylist').show();
|
||||
} else {
|
||||
$('#menu-item-entrylist').hide();
|
||||
}
|
||||
|
||||
// Results
|
||||
var results = await dbGetDataIndex('results', 'regatta', regatta['id']);
|
||||
if (results.length > 0) {
|
||||
if (regatta['results'] == '1') {
|
||||
$('#menu-item-results').show();
|
||||
$('#menu-item-results').attr('href', LINK_PRE + 'result?regatta=' + regatta['id']);
|
||||
} else {
|
||||
|
||||
334
server/scripts/planning.js
Normal file
334
server/scripts/planning.js
Normal file
@@ -0,0 +1,334 @@
|
||||
async function planningSwitchChanged() {
|
||||
showLoader();
|
||||
var id = $('#switch-status-gemeldet').data('regatta');
|
||||
var gemeldet = $('#switch-status-gemeldet').prop('checked');
|
||||
var bezahlt = $('#switch-status-bezahlt').prop('checked');
|
||||
var auth = {
|
||||
id: localStorage.getItem('auth_id'),
|
||||
hash: localStorage.getItem('auth_hash')
|
||||
}
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'planning_set_state',
|
||||
method: 'POST',
|
||||
data: {
|
||||
auth: auth,
|
||||
regatta: id,
|
||||
gemeldet: gemeldet,
|
||||
bezahlt: bezahlt
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 401) {
|
||||
log('authentification failed');
|
||||
toastError('Authentifizierung fehlgeschlagen. Versuche es erneut.');
|
||||
} else if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um den Status zu ändern');
|
||||
} else {
|
||||
log('Login: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
$('#menu-status').hideMenu();
|
||||
hideLoader();
|
||||
},
|
||||
success: function (data, status, xhr) {
|
||||
sync();
|
||||
hideLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function planningEditStatus(id) {
|
||||
$('#menu-regatta').hideMenu();
|
||||
|
||||
var regatta = await dbGetData('regattas', id);
|
||||
|
||||
$('#menu-status').find('.menu-title').find('p').text(regatta.name);
|
||||
|
||||
var plannings = await dbGetDataIndex('plannings', 'regatta', regatta['id']);
|
||||
var planning = null;
|
||||
if (isLoggedIn()) {
|
||||
for (i in plannings) {
|
||||
if (plannings[i]['user'] == USER_ID) {
|
||||
planning = plannings[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (planning !== null) {
|
||||
$('#switch-status-gemeldet').data('regatta', id);
|
||||
$('#switch-status-gemeldet').prop('checked', planning.gemeldet == '1');
|
||||
$('#switch-status-bezahlt').prop('checked', planning.bezahlt == '1');
|
||||
$('#menu-status').showMenu();
|
||||
}
|
||||
}
|
||||
|
||||
function selectChange() {
|
||||
var val = $('#select-year').val();
|
||||
|
||||
if (typeof siteScript === 'function') {
|
||||
history.replaceState(null, '', '?year=' + val);
|
||||
showLoader();
|
||||
siteScript();
|
||||
}
|
||||
}
|
||||
|
||||
function initYear() {
|
||||
return new Promise(async function (resolve) {
|
||||
var year = findGetParameter('year');
|
||||
if (year === null) year = await dbGetCurrentYear();
|
||||
|
||||
$('#select-year').html('<option value="' + year + '">' + year + '</option>');
|
||||
$('#select-year').val(year);
|
||||
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
var firstCall = true;
|
||||
var rows = [];
|
||||
var today;
|
||||
|
||||
async function drawList () {
|
||||
window.setTimeout(function () {
|
||||
var list = '';
|
||||
rows.forEach(function (entry) {
|
||||
if (entry == null) {
|
||||
list += '<div><div align="center" class="color-highlight"><b>Heute ist der ' + formatDate('d.m.Y', today) + '</b></div></div>';
|
||||
} else if (search($('#input-search').val(), entry.keywords)) {
|
||||
list += entry.content;
|
||||
}
|
||||
});
|
||||
$('#div-regattas').html(list);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
var siteScript = async function() {
|
||||
if (!isLoggedIn()) {
|
||||
hideLoader();
|
||||
return;
|
||||
}
|
||||
|
||||
if (firstCall) {
|
||||
firstCall = false;
|
||||
await initYear();
|
||||
$('#select-year').change(selectChange);
|
||||
$('#input-search').on('input', drawList);
|
||||
$('#switch-status-gemeldet').parent().parent().click(planningSwitchChanged);
|
||||
$('#switch-status-bezahlt').parent().parent().click(planningSwitchChanged);
|
||||
}
|
||||
|
||||
var selectedYear = $('#select-year').val();
|
||||
|
||||
$('#a-share-planning').attr('href', LINK_PRE + 'planning_view?user=' + USER_ID + '&year=' + selectedYear);
|
||||
$('#a-edit-planning').attr('href', LINK_PRE + 'planning_edit?year=' + selectedYear);
|
||||
$('#a-list-plannings').attr('href', LINK_PRE + 'planning_list?year=' + selectedYear);
|
||||
|
||||
today = getToday();
|
||||
|
||||
var minDate = parseDate(selectedYear + '-01-01');
|
||||
var maxDate = parseDate(selectedYear + '-12-31');
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
var plannings = await dbGetDataIndex('plannings', 'user', USER_ID);
|
||||
for (var i = regattas.length - 1; i >= 0; i --) {
|
||||
var entry = regattas[i];
|
||||
var okay = false;
|
||||
for (p in plannings) {
|
||||
if (plannings[p].regatta == entry.id) {
|
||||
regattas[i].planning = plannings[p];
|
||||
okay = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!okay) {
|
||||
regattas.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
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 += '<option value="' + year + '">' + year + '</option>';
|
||||
}
|
||||
$('#select-year').html(options);
|
||||
$('#select-year').val(selectedYear);
|
||||
|
||||
var count = regattas.length;
|
||||
if (count > 0) {
|
||||
if (count == 1) {
|
||||
$('#p-count').html('Es wurde 1 Regatta gefunden!');
|
||||
} else {
|
||||
$('#p-count').html('Es wurden ' + count + ' Regatten gefunden!');
|
||||
}
|
||||
$('#div-regattas').show();
|
||||
$('#input-search').parent().show();
|
||||
|
||||
var heute = false;
|
||||
|
||||
rows = [];
|
||||
|
||||
for (id in regattas) {
|
||||
var entry = regattas[id];
|
||||
var club = null;
|
||||
if (entry['club'] != null)
|
||||
club = await dbGetData('clubs', entry['club']);
|
||||
if (entry.planning.steuermann !== null) {
|
||||
entry.planning.steuermann = (await dbGetData('sailors', entry.planning.steuermann)).name;
|
||||
}
|
||||
var crewString = entry.planning.crew.split(',');
|
||||
entry.planning.crew = [];
|
||||
for (c in crewString) {
|
||||
var sailor = await dbGetData('sailors', crewString[c]);
|
||||
if (sailor !== null) {
|
||||
entry.planning.crew.push(sailor.name);
|
||||
}
|
||||
}
|
||||
|
||||
var dateFrom = entry['dateFrom'];
|
||||
var dateTo = entry['dateTo'];
|
||||
|
||||
var row = { keywords: [], content: '' };
|
||||
row.keywords.push(entry['name']);
|
||||
if (entry['number'] != null) row.keywords.push(entry['number']);
|
||||
if (club != null) row.keywords.push(club['kurz'], club['name']);
|
||||
if (entry.planning.steuermann != null) row.keywords.push(entry.planning.steuermann);
|
||||
for (c in entry.planning.crew) row.keywords.push(entry.planning.crew[c]);
|
||||
|
||||
if (!heute && (today <= dateFrom)) {
|
||||
rows.push(null);
|
||||
heute = true;
|
||||
}
|
||||
|
||||
row.content += '<div onclick="onRegattaClicked(' + entry['id'] + ');">';
|
||||
|
||||
// ZEILE 1
|
||||
// Name
|
||||
row.content += '<div><b>' + (entry['canceled'] == 1 ? '<s>' : '') + entry['name'] + (entry['canceled'] == 1 ? '</s>' : '') + '</b></div>';
|
||||
|
||||
// ZEILE 2
|
||||
row.content += '<div>';
|
||||
|
||||
// Number
|
||||
row.content += '<div>' + ((entry['number'] != null) ? ('# ' + entry['number']) : '') + '</div>';
|
||||
|
||||
// Club
|
||||
row.content += '<div>' + ((club != null) ? club['kurz'] : '') + '</div>';
|
||||
|
||||
// Special
|
||||
if (entry.special.substr(0, 1) == '#') {
|
||||
entry.special = '* ' + entry.special.substr(1);
|
||||
}
|
||||
// replace placeholders
|
||||
var pos;
|
||||
while ((pos = entry.special.indexOf('$')) >= 0) {
|
||||
var pos2 = entry.special.indexOf('$', pos + 1);
|
||||
if (pos2 < 0) break;
|
||||
var key = entry.special.substring(pos + 1, pos2);
|
||||
|
||||
var value = '';
|
||||
// age class
|
||||
if ((key.substr(0, 1) == 'U') && (!isNaN(value = parseInt(key.substr(1))))) {
|
||||
value = 'U-' + value;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
entry.special = entry.special.replace('$' + key + '$', value);
|
||||
}
|
||||
row.content += '<div>' + entry['special'] + '</div>';
|
||||
|
||||
// Icons
|
||||
var icons = [];
|
||||
if ((entry['meldung'] != '') && (dateTo >= today) && (entry['meldungOffen'] == '1') && (entry.planning.gemeldet != '1')) {
|
||||
var color = '';
|
||||
var planning = null;
|
||||
if (isLoggedIn()) {
|
||||
var plannings = await dbGetDataIndex('plannings', 'regatta', entry['id']);
|
||||
for (id in plannings) {
|
||||
if (plannings[id]['user'] == USER_ID) {
|
||||
planning = plannings[id];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entry['meldungSchluss'] != null) {
|
||||
if ((planning == null) || (planning['gemeldet'] == '0')) {
|
||||
var ms = 0;
|
||||
if (entry['meldungEarly'] != null) {
|
||||
ms = parseDate(entry['meldungEarly']);
|
||||
}
|
||||
if (ms < today) {
|
||||
ms = parseDate(entry['meldungSchluss']);
|
||||
}
|
||||
var diff = Math.round((ms - today) / 86400000);
|
||||
if (ms < today) {
|
||||
color = ' color-red2-dark';
|
||||
} else if (diff < 7) {
|
||||
color = ' color-yellow2-dark';
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((planning != null) && (planning['gemeldet'] == '0')) {
|
||||
color += ' fa-blink';
|
||||
}
|
||||
icons.push('<i class="fas fa-file-signature' + color + '"></i>');
|
||||
}
|
||||
if (entry['bericht'] != '')
|
||||
icons.push('<i class="fas fa-book"></i>');
|
||||
if (entry['canceled'] == '1') {
|
||||
icons.push('<i class="fas fa-times color-red2-dark"></i>');
|
||||
} else if (entry['results'] == '1') {
|
||||
icons.push('<i class="fas fa-poll"></i>');
|
||||
}
|
||||
if (entry.planning.gemeldet == '1') {
|
||||
icons.push('<i class="fas fa-file-signature color-highlight"></i>');
|
||||
}
|
||||
if (entry.planning.bezahlt == '1') {
|
||||
icons.push('<i class="fas fa-euro-sign color-highlight"></i>');
|
||||
}
|
||||
row.content += '<div class="color-green2-dark">' + icons.join(' ') + '</div>';
|
||||
|
||||
row.content += '</div>';
|
||||
|
||||
// ZEILE 3
|
||||
row.content += '<div>';
|
||||
|
||||
// Date
|
||||
if (entry['length'] < 1) {
|
||||
if (formatDate('d.m', dateFrom) == '01.01') {
|
||||
row.content += '<div><font class="color-red2-dark">Datum noch unklar</font></div>';
|
||||
} else {
|
||||
row.content += '<div>' + formatDate("d.m.Y", dateFrom) + ' - <font class="color-red2-dark">Datum nicht final</font></div>';
|
||||
}
|
||||
} else {
|
||||
row.content += '<div>' + formatDate("d.m.Y", dateFrom) + ' - ' + formatDate("d.m.Y", dateTo) + '</div>';
|
||||
}
|
||||
|
||||
// RLF
|
||||
row.content += '<div>' + parseFloat(entry['rlf']).toFixed(2) + '</div>';
|
||||
|
||||
row.content += '</div></div>';
|
||||
|
||||
rows.push(row);
|
||||
}
|
||||
|
||||
if (!heute) {
|
||||
rows.push(null);
|
||||
}
|
||||
|
||||
drawList();
|
||||
|
||||
} else {
|
||||
$('#p-count').html('Du hast noch keine Regatten in Deiner Saison-Planung!');
|
||||
$('#div-regattas').hide();
|
||||
$('#input-search').parent().hide();
|
||||
}
|
||||
|
||||
hideLoader();
|
||||
}
|
||||
522
server/scripts/planning_edit.js
Normal file
522
server/scripts/planning_edit.js
Normal file
@@ -0,0 +1,522 @@
|
||||
async function planningSwitchChanged() {
|
||||
showLoader();
|
||||
var id = $('#switch-planning-include').data('regatta');
|
||||
var include = $('#switch-planning-include').prop('checked');
|
||||
var auth = {
|
||||
id: localStorage.getItem('auth_id'),
|
||||
hash: localStorage.getItem('auth_hash')
|
||||
}
|
||||
if (include) {
|
||||
// add to planning
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'planning_add',
|
||||
method: 'POST',
|
||||
data: {
|
||||
auth: auth,
|
||||
regatta: id
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 401) {
|
||||
log('authentification failed');
|
||||
toastError('Authentifizierung fehlgeschlagen. Versuche es erneut.');
|
||||
} else if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um die Änderungen zu speichern');
|
||||
} else {
|
||||
log('planning_add: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
$('#menu-edit').hideMenu();
|
||||
hideLoader();
|
||||
},
|
||||
success: async function (data, status, xhr) {
|
||||
await sync();
|
||||
planningEdit(id);
|
||||
hideLoader();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// remove from planning
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'planning_remove',
|
||||
method: 'POST',
|
||||
data: {
|
||||
auth: auth,
|
||||
regatta: id
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 401) {
|
||||
log('authentification failed');
|
||||
toastError('Authentifizierung fehlgeschlagen. Versuche es erneut.');
|
||||
} else if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um die Änderungen zu speichern');
|
||||
} else {
|
||||
log('planning_remove: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
$('#menu-edit').hideMenu();
|
||||
hideLoader();
|
||||
},
|
||||
success: async function (data, status, xhr) {
|
||||
await sync();
|
||||
planningEdit(id);
|
||||
hideLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var sailorIsSteuermann;
|
||||
var sailors = [];
|
||||
var knownIds = [];
|
||||
var known = [];
|
||||
|
||||
async function sailorSelected(sid) {
|
||||
$('#menu-sailor').hideMenu();
|
||||
showLoader();
|
||||
var rid = $('#switch-planning-include').data('regatta');
|
||||
var action = (sailorIsSteuermann ? 'planning_set_steuermann' : 'planning_add_crew');
|
||||
// add sailor
|
||||
var auth = {
|
||||
id: localStorage.getItem('auth_id'),
|
||||
hash: localStorage.getItem('auth_hash')
|
||||
}
|
||||
$.ajax({
|
||||
url: QUERY_URL + action,
|
||||
method: 'POST',
|
||||
data: {
|
||||
auth: auth,
|
||||
regatta: rid,
|
||||
sailor: sid
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 401) {
|
||||
log('authentification failed');
|
||||
toastError('Authentifizierung fehlgeschlagen. Versuche es erneut.');
|
||||
} else if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um die Änderungen zu speichern');
|
||||
} else {
|
||||
log(action + ': unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
hideLoader();
|
||||
},
|
||||
success: async function (data, status, xhr) {
|
||||
await sync();
|
||||
if ((sid === null) || (sid in knownIds)) {
|
||||
planningEdit(rid);
|
||||
hideLoader();
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function sailorsSearch() {
|
||||
$('.item-sailor-search').remove();
|
||||
if (sailorIsSteuermann) {
|
||||
var item = '<a class="item-sailor-search" onclick="sailorSelected(null)">';
|
||||
item += '<span style="font-style:italic;">noch unklar</span>';
|
||||
item += '<i class="fa fa-angle-right"></i>';
|
||||
item += '</a>';
|
||||
$('#menu-sailor').find('.content').find('.list-group').append(item);
|
||||
}
|
||||
if ($('#input-edit-search').val().length == 0) {
|
||||
known.forEach(function (entry) {
|
||||
$('#menu-sailor').find('.content').find('.list-group').append(entry);
|
||||
});
|
||||
}
|
||||
if ($('#input-edit-search').val().length >= 3) {
|
||||
sailors.forEach(function (entry) {
|
||||
if (search($('#input-edit-search').val(), entry.keywords)) {
|
||||
$('#menu-sailor').find('.content').find('.list-group').append(entry.content);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var item = '<p class="item-sailor-search">Zum Suchen mindestens 3 Zeichen eingeben</p>';
|
||||
$('#menu-sailor').find('.content').find('.list-group').append(item);
|
||||
}
|
||||
}
|
||||
|
||||
async function initSailors() {
|
||||
sailors = [];
|
||||
known = [];
|
||||
var plannings = await dbGetDataIndex('plannings', 'user', USER_ID);
|
||||
knownIds = {};
|
||||
for (var p in plannings) {
|
||||
p = plannings[p];
|
||||
if (p.steuermann !== null) knownIds[p.steuermann] = true;
|
||||
var crew = p.crew.split(',');
|
||||
for (var c in crew) {
|
||||
c = crew[c];
|
||||
if (c != '') knownIds[c] = true;
|
||||
}
|
||||
}
|
||||
var dbSailors = await dbGetData('sailors');
|
||||
dbSailors.sort(function(a,b){
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
for (var s in dbSailors) {
|
||||
var item = '<a class="item-sailor-search" onclick="sailorSelected(' + dbSailors[s].id + ')">';
|
||||
item += '<span>' + dbSailors[s].name + '</span>';
|
||||
item += '<i class="fa fa-angle-right"></i>';
|
||||
item += '</a>';
|
||||
sailors.push({
|
||||
keywords: [dbSailors[s].name],
|
||||
content: item
|
||||
});
|
||||
if (dbSailors[s].id in knownIds) known.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
async function planningChangeCrew(sid = null) {
|
||||
if (sid !== null) {
|
||||
showLoader();
|
||||
var rid = $('#switch-planning-include').data('regatta');
|
||||
// remove sailor
|
||||
var auth = {
|
||||
id: localStorage.getItem('auth_id'),
|
||||
hash: localStorage.getItem('auth_hash')
|
||||
}
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'planning_remove_crew',
|
||||
method: 'POST',
|
||||
data: {
|
||||
auth: auth,
|
||||
regatta: rid,
|
||||
sailor: sid
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 401) {
|
||||
log('authentification failed');
|
||||
toastError('Authentifizierung fehlgeschlagen. Versuche es erneut.');
|
||||
} else if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um die Änderungen zu speichern');
|
||||
} else {
|
||||
log('planning_remove_crew: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
$('#menu-edit').hideMenu();
|
||||
hideLoader();
|
||||
},
|
||||
success: async function (data, status, xhr) {
|
||||
await sync();
|
||||
planningEdit(rid);
|
||||
hideLoader();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
sailorIsSteuermann = false;
|
||||
$('#input-edit-search').val('').trigger('focusin').trigger('focusout');
|
||||
sailorsSearch();
|
||||
$('#menu-edit').hideMenu();
|
||||
$('#menu-sailor').find('.menu-title').find('h1').text('Crew hinzufügen');
|
||||
$('#menu-sailor').showMenu();
|
||||
$('#input-edit-search').focus();
|
||||
}
|
||||
}
|
||||
|
||||
async function planningChangeSteuermann() {
|
||||
sailorIsSteuermann = true;
|
||||
$('#input-edit-search').val('').trigger('focusin').trigger('focusout');
|
||||
sailorsSearch();
|
||||
$('#menu-edit').hideMenu();
|
||||
$('#menu-sailor').find('.menu-title').find('h1').text('Steuermann/-frau bearbeiten');
|
||||
$('#menu-sailor').showMenu();
|
||||
$('#input-edit-search').focus();
|
||||
}
|
||||
|
||||
async function planningEdit(id) {
|
||||
var regatta = await dbGetData('regattas', id);
|
||||
|
||||
$('#menu-edit').find('.menu-title').find('p').text(regatta.name);
|
||||
|
||||
var plannings = await dbGetDataIndex('plannings', 'regatta', regatta['id']);
|
||||
var planning = null;
|
||||
if (isLoggedIn()) {
|
||||
for (i in plannings) {
|
||||
if (plannings[i]['user'] == USER_ID) {
|
||||
planning = plannings[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('#switch-planning-include').data('regatta', id);
|
||||
if (planning !== null) {
|
||||
$('#switch-planning-include').prop('checked', true);
|
||||
$('#item-steuermann').show();
|
||||
if (planning.steuermann !== null) {
|
||||
$('#item-steuermann').find('span').text('Am Steuer: ' + (await dbGetData('sailors', planning.steuermann)).name);
|
||||
} else {
|
||||
$('#item-steuermann').find('span').html('Am Steuer: <font style="font-style:italic;">noch unklar</font>');
|
||||
}
|
||||
$('.item-crew').remove();
|
||||
var crew = planning.crew.split(',');
|
||||
for (c in crew) {
|
||||
var sailor = await dbGetData('sailors', crew[c]);
|
||||
if (sailor !== null) {
|
||||
var item = '<a class="item-crew" onclick="planningChangeCrew(' + sailor.id + ')">';
|
||||
item += '<span>' + sailor.name + '</span>';
|
||||
item += '<i class="fa fa-angle-right"></i>';
|
||||
item += '</a>';
|
||||
$('#menu-edit').find('.content').find('.list-group').append(item);
|
||||
}
|
||||
}
|
||||
var item = '<a class="item-crew" onclick="planningChangeCrew()">';
|
||||
item += '<span style="font-style:italic;">Weiteren Segler hinzufügen</span>';
|
||||
item += '<i class="fa fa-angle-right"></i>';
|
||||
item += '</a>';
|
||||
$('#menu-edit').find('.content').find('.list-group').append(item);
|
||||
} else {
|
||||
$('#switch-planning-include').prop('checked', false);
|
||||
$('#item-steuermann').hide();
|
||||
$('.item-crew').remove();
|
||||
}
|
||||
$('#menu-edit').showMenu();
|
||||
}
|
||||
|
||||
function selectChange() {
|
||||
var val = $('#select-year').val();
|
||||
|
||||
if (typeof siteScript === 'function') {
|
||||
history.replaceState(null, '', '?year=' + val);
|
||||
showLoader();
|
||||
siteScript();
|
||||
}
|
||||
}
|
||||
|
||||
function initYear() {
|
||||
return new Promise(async function (resolve) {
|
||||
var year = findGetParameter('year');
|
||||
if (year === null) year = await dbGetCurrentYear();
|
||||
|
||||
$('#select-year').html('<option value="' + year + '">' + year + '</option>');
|
||||
$('#select-year').val(year);
|
||||
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
var firstCall = true;
|
||||
var rows = [];
|
||||
var today;
|
||||
|
||||
async function drawList () {
|
||||
window.setTimeout(function () {
|
||||
var list = '';
|
||||
rows.forEach(function (entry) {
|
||||
if (entry == null) {
|
||||
list += '<div><div align="center" class="color-highlight"><b>Heute ist der ' + formatDate('d.m.Y', today) + '</b></div></div>';
|
||||
} else if (search($('#input-search').val(), entry.keywords)) {
|
||||
list += entry.content;
|
||||
}
|
||||
});
|
||||
$('#div-regattas').html(list);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
var siteScript = async function() {
|
||||
if (!isLoggedIn()) {
|
||||
location.href = LINK_PRE + 'planning';
|
||||
return;
|
||||
}
|
||||
|
||||
if (firstCall) {
|
||||
firstCall = false;
|
||||
await initYear();
|
||||
$('#select-year').change(selectChange);
|
||||
$('#input-search').on('input', drawList);
|
||||
$('#switch-planning-include').parent().parent().click(planningSwitchChanged);
|
||||
$('#item-steuermann').click(planningChangeSteuermann);
|
||||
$('#input-edit-search').on('input', sailorsSearch);
|
||||
initSailors();
|
||||
}
|
||||
|
||||
today = getToday();
|
||||
|
||||
var selectedYear = $('#select-year').val();
|
||||
var minDate = parseDate(selectedYear + '-01-01');
|
||||
var maxDate = parseDate(selectedYear + '-12-31');
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
var plannings = await dbGetDataIndex('plannings', 'user', USER_ID);
|
||||
for (var i = regattas.length - 1; i >= 0; i --) {
|
||||
var entry = regattas[i];
|
||||
var okay = false;
|
||||
for (p in plannings) {
|
||||
if (plannings[p].regatta == entry.id) {
|
||||
regattas[i].planning = plannings[p];
|
||||
okay = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!okay) {
|
||||
regattas[i].planning = null;
|
||||
}
|
||||
}
|
||||
|
||||
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 += '<option value="' + year + '">' + year + '</option>';
|
||||
}
|
||||
$('#select-year').html(options);
|
||||
$('#select-year').val(selectedYear);
|
||||
|
||||
var count = regattas.length;
|
||||
if (count > 0) {
|
||||
if (count == 1) {
|
||||
$('#p-count').html('Es wurde 1 Regatta gefunden!');
|
||||
} else {
|
||||
$('#p-count').html('Es wurden ' + count + ' Regatten gefunden!');
|
||||
}
|
||||
$('#div-regattas').show();
|
||||
$('#input-search').parent().show();
|
||||
|
||||
var heute = false;
|
||||
|
||||
rows = [];
|
||||
|
||||
for (id in regattas) {
|
||||
var entry = regattas[id];
|
||||
var club = null;
|
||||
if (entry['club'] != null)
|
||||
club = await dbGetData('clubs', entry['club']);
|
||||
if (entry.planning !== null) {
|
||||
if (entry.planning.steuermann !== null) {
|
||||
entry.planning.steuermann = (await dbGetData('sailors', entry.planning.steuermann)).name;
|
||||
}
|
||||
var crewString = entry.planning.crew.split(',');
|
||||
entry.planning.crew = [];
|
||||
for (c in crewString) {
|
||||
var sailor = await dbGetData('sailors', crewString[c]);
|
||||
if (sailor !== null) {
|
||||
entry.planning.crew.push(sailor.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var dateFrom = entry['dateFrom'];
|
||||
var dateTo = entry['dateTo'];
|
||||
|
||||
var row = { keywords: [], content: '' };
|
||||
row.keywords.push(entry['name']);
|
||||
if (entry['number'] != null) row.keywords.push(entry['number']);
|
||||
if (club != null) row.keywords.push(club['kurz'], club['name']);
|
||||
|
||||
if (!heute && (today <= dateFrom)) {
|
||||
rows.push(null);
|
||||
heute = true;
|
||||
}
|
||||
|
||||
if (entry.planning !== null) {
|
||||
row.content += '<div onclick="planningEdit(' + entry['id'] + ');">';
|
||||
} else {
|
||||
row.content += '<div onclick="planningEdit(' + entry['id'] + ');" style="opacity:0.5;">';
|
||||
}
|
||||
|
||||
// ZEILE 1
|
||||
// Name
|
||||
row.content += '<div><b>' + (entry['canceled'] == 1 ? '<s>' : '') + entry['name'] + (entry['canceled'] == 1 ? '</s>' : '') + '</b></div>';
|
||||
|
||||
// ZEILE 2
|
||||
row.content += '<div>';
|
||||
|
||||
// Number
|
||||
row.content += '<div>' + ((entry['number'] != null) ? ('# ' + entry['number']) : '') + '</div>';
|
||||
|
||||
// Special
|
||||
if (entry.special.substr(0, 1) == '#') {
|
||||
entry.special = '* ' + entry.special.substr(1);
|
||||
}
|
||||
// replace placeholders
|
||||
var pos;
|
||||
while ((pos = entry.special.indexOf('$')) >= 0) {
|
||||
var pos2 = entry.special.indexOf('$', pos + 1);
|
||||
if (pos2 < 0) break;
|
||||
var key = entry.special.substring(pos + 1, pos2);
|
||||
|
||||
var value = '';
|
||||
// age class
|
||||
if ((key.substr(0, 1) == 'U') && (!isNaN(value = parseInt(key.substr(1))))) {
|
||||
value = 'U-' + value;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
entry.special = entry.special.replace('$' + key + '$', value);
|
||||
}
|
||||
row.content += '<div>' + entry['special'] + '</div>';
|
||||
|
||||
// Club
|
||||
row.content += '<div>' + ((club != null) ? club['kurz'] : '') + '</div>';
|
||||
|
||||
row.content += '</div>';
|
||||
|
||||
// ZEILE 3
|
||||
row.content += '<div>';
|
||||
|
||||
// Date
|
||||
if (entry['length'] < 1) {
|
||||
if (formatDate('d.m', dateFrom) == '01.01') {
|
||||
row.content += '<div><font class="color-red2-dark">Datum noch unklar</font></div>';
|
||||
} else {
|
||||
row.content += '<div>' + formatDate("d.m.Y", dateFrom) + ' - <font class="color-red2-dark">Datum nicht final</font></div>';
|
||||
}
|
||||
} else {
|
||||
row.content += '<div>' + formatDate("d.m.Y", dateFrom) + ' - ' + formatDate("d.m.Y", dateTo) + '</div>';
|
||||
}
|
||||
|
||||
// RLF
|
||||
row.content += '<div>' + parseFloat(entry['rlf']).toFixed(2) + '</div>';
|
||||
|
||||
row.content += '</div>';
|
||||
|
||||
if (entry.planning !== null) {
|
||||
// ZEILE 4
|
||||
row.content += '<div></div>';
|
||||
|
||||
// ZEILE 5
|
||||
row.content += '<div>';
|
||||
row.content += '<div>' + (entry.planning.steuermann !== null ? entry.planning.steuermann : 'noch unklar') + '</div>';
|
||||
row.content += '</div>';
|
||||
|
||||
// ZEILE 6...
|
||||
for (var i in entry.planning.crew) {
|
||||
row.content += '<div>';
|
||||
row.content += '<div>' + entry.planning.crew[i] + '</div>';
|
||||
row.content += '</div>';
|
||||
}
|
||||
} else {
|
||||
row.content += '<div>Du planst nicht, hierhin zu fahren</div>';
|
||||
}
|
||||
|
||||
row.content += '</div>';
|
||||
|
||||
rows.push(row);
|
||||
}
|
||||
|
||||
if (!heute) {
|
||||
rows.push(null);
|
||||
}
|
||||
|
||||
drawList();
|
||||
|
||||
} else {
|
||||
$('#p-count').html('Keine Regatten gefunden!');
|
||||
$('#div-regattas').hide();
|
||||
$('#input-search').parent().hide();
|
||||
}
|
||||
|
||||
hideLoader();
|
||||
}
|
||||
151
server/scripts/planning_list.js
Normal file
151
server/scripts/planning_list.js
Normal file
@@ -0,0 +1,151 @@
|
||||
async function onUserClicked(id) {
|
||||
var user = await dbGetData('users', id);
|
||||
if (user !== null) {
|
||||
location.href = LINK_PRE + 'planning_view?user=' + user.id + '&year=' + $('#select-year').val();
|
||||
}
|
||||
}
|
||||
|
||||
function selectChange() {
|
||||
var val = $('#select-year').val();
|
||||
|
||||
if (typeof siteScript === 'function') {
|
||||
history.replaceState(null, '', '?year=' + val);
|
||||
showLoader();
|
||||
siteScript();
|
||||
}
|
||||
}
|
||||
|
||||
function initYear() {
|
||||
return new Promise(async function (resolve) {
|
||||
var year = findGetParameter('year');
|
||||
if (year === null) year = await dbGetCurrentYear();
|
||||
|
||||
$('#select-year').html('<option value="' + year + '">' + year + '</option>');
|
||||
$('#select-year').val(year);
|
||||
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
var firstCall = true;
|
||||
var rows = [];
|
||||
var today;
|
||||
|
||||
async function drawList () {
|
||||
window.setTimeout(function () {
|
||||
var list = '';
|
||||
rows.forEach(function (entry) {
|
||||
if (search($('#input-search').val(), entry.keywords)) {
|
||||
list += entry.content;
|
||||
}
|
||||
});
|
||||
$('#div-users').html(list);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
var siteScript = async function() {
|
||||
if (!isLoggedIn()) {
|
||||
hideLoader();
|
||||
return;
|
||||
}
|
||||
|
||||
if (firstCall) {
|
||||
firstCall = false;
|
||||
await initYear();
|
||||
$('#select-year').change(selectChange);
|
||||
$('#input-search').on('input', drawList);
|
||||
}
|
||||
|
||||
var selectedYear = $('#select-year').val();
|
||||
var minDate = parseDate(selectedYear + '-01-01');
|
||||
var maxDate = parseDate(selectedYear + '-12-31');
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
var plannings = {};
|
||||
for (var i in regattas) {
|
||||
var entry = regattas[i];
|
||||
var planning = await dbGetDataIndex('plannings', 'regatta', entry.id);
|
||||
for (p in planning) {
|
||||
if (!(planning[p].user in plannings)) {
|
||||
plannings[planning[p].user] = {
|
||||
user: await dbGetData('users', planning[p].user),
|
||||
regattas: [],
|
||||
sailors: {}
|
||||
};
|
||||
}
|
||||
plannings[planning[p].user].regattas.push(entry);
|
||||
var sailor = null;
|
||||
if (planning[p].steuermann !== null) sailor = await dbGetData('sailors', planning[p].steuermann);
|
||||
if (sailor !== null) {
|
||||
if (!(sailor.id in plannings[planning[p].user].sailors)) plannings[planning[p].user].sailors[sailor.id] = sailor.name;
|
||||
}
|
||||
var crew = planning[p].crew.split(',');
|
||||
for (i in crew) {
|
||||
sailor = await dbGetData('sailors', crew[i]);
|
||||
if (sailor !== null) {
|
||||
if (!(sailor.id in plannings[planning[p].user].sailors)) plannings[planning[p].user].sailors[sailor.id] = sailor.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
plannings = Object.values(plannings);
|
||||
plannings.sort(function(a,b){
|
||||
return a.user.username.localeCompare(b.user.username);
|
||||
});
|
||||
|
||||
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 += '<option value="' + year + '">' + year + '</option>';
|
||||
}
|
||||
$('#select-year').html(options);
|
||||
$('#select-year').val(selectedYear);
|
||||
|
||||
var count = plannings.length;
|
||||
if (count > 0) {
|
||||
$('#input-search').parent().show();
|
||||
|
||||
rows = [];
|
||||
|
||||
for (id in plannings) {
|
||||
var entry = plannings[id];
|
||||
|
||||
var row = { keywords: [], content: '' };
|
||||
row.keywords.push(entry.user.username);
|
||||
for (i in entry.sailors) {
|
||||
row.keywords.push(entry.sailors[i]);
|
||||
}
|
||||
|
||||
row.content += '<div onclick="onUserClicked(' + entry.user.id + ');">';
|
||||
|
||||
// ZEILE 1
|
||||
row.content += '<div></div>';
|
||||
|
||||
// ZEILE 2
|
||||
row.content += '<div>';
|
||||
|
||||
// Name
|
||||
row.content += '<div>' + entry.user.username + '</div>';
|
||||
|
||||
// Count of regattas
|
||||
row.content += '<div>' + entry.regattas.length + ' Regatten</div>';
|
||||
|
||||
row.content += '</div></div>';
|
||||
|
||||
rows.push(row);
|
||||
}
|
||||
|
||||
drawList();
|
||||
|
||||
} else {
|
||||
$('#div-users').html('Es hat noch niemand eine Saison-Planung erstellt');
|
||||
$('#input-search').parent().hide();
|
||||
}
|
||||
|
||||
hideLoader();
|
||||
}
|
||||
246
server/scripts/planning_view.js
Normal file
246
server/scripts/planning_view.js
Normal file
@@ -0,0 +1,246 @@
|
||||
var userid;
|
||||
|
||||
function selectChange() {
|
||||
var val = $('#select-year').val();
|
||||
|
||||
if (typeof siteScript === 'function') {
|
||||
history.replaceState(null, '', '?user=' + userid + '&year=' + val);
|
||||
showLoader();
|
||||
siteScript();
|
||||
}
|
||||
}
|
||||
|
||||
function initYear() {
|
||||
return new Promise(async function (resolve) {
|
||||
var year = findGetParameter('year');
|
||||
if (year === null) year = await dbGetCurrentYear();
|
||||
|
||||
$('#select-year').html('<option value="' + year + '">' + year + '</option>');
|
||||
$('#select-year').val(year);
|
||||
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
var firstCall = true;
|
||||
var rows = [];
|
||||
var today;
|
||||
|
||||
async function drawList () {
|
||||
window.setTimeout(function () {
|
||||
var list = '';
|
||||
rows.forEach(function (entry) {
|
||||
if (entry == null) {
|
||||
list += '<div><div align="center" class="color-highlight"><b>Heute ist der ' + formatDate('d.m.Y', today) + '</b></div></div>';
|
||||
} else if (search($('#input-search').val(), entry.keywords)) {
|
||||
list += entry.content;
|
||||
}
|
||||
});
|
||||
$('#div-regattas').html(list);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
var siteScript = async function() {
|
||||
userid = findGetParameter('user');
|
||||
var user = null;
|
||||
if (userid !== null) {
|
||||
user = await dbGetData('users', userid);
|
||||
}
|
||||
if (user === null) {
|
||||
location.href = LINK_PRE + 'planning_list';
|
||||
return;
|
||||
}
|
||||
|
||||
$('#p-username').text(user.username);
|
||||
|
||||
if (isLoggedIn() && (userid == USER_ID)) {
|
||||
$('#button-share').show();
|
||||
$('#button-share').click(function(){
|
||||
$('#menu-share').showMenu();
|
||||
});
|
||||
} else {
|
||||
$('#button-share').hide();
|
||||
}
|
||||
|
||||
if (firstCall) {
|
||||
firstCall = false;
|
||||
await initYear();
|
||||
$('#select-year').change(selectChange);
|
||||
$('#input-search').on('input', drawList);
|
||||
}
|
||||
|
||||
today = getToday();
|
||||
|
||||
var selectedYear = $('#select-year').val();
|
||||
var minDate = parseDate(selectedYear + '-01-01');
|
||||
var maxDate = parseDate(selectedYear + '-12-31');
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
var plannings = await dbGetDataIndex('plannings', 'user', user.id);
|
||||
for (var i = regattas.length - 1; i >= 0; i --) {
|
||||
var entry = regattas[i];
|
||||
var okay = false;
|
||||
for (p in plannings) {
|
||||
if (plannings[p].regatta == entry.id) {
|
||||
regattas[i].planning = plannings[p];
|
||||
okay = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!okay) {
|
||||
regattas.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
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 += '<option value="' + year + '">' + year + '</option>';
|
||||
}
|
||||
$('#select-year').html(options);
|
||||
$('#select-year').val(selectedYear);
|
||||
|
||||
var count = regattas.length;
|
||||
if (count > 0) {
|
||||
if (count == 1) {
|
||||
$('#p-count').html('Es wurde 1 Regatta gefunden!');
|
||||
} else {
|
||||
$('#p-count').html('Es wurden ' + count + ' Regatten gefunden!');
|
||||
}
|
||||
$('#div-regattas').show();
|
||||
$('#input-search').parent().show();
|
||||
|
||||
var heute = false;
|
||||
|
||||
rows = [];
|
||||
|
||||
for (id in regattas) {
|
||||
var entry = regattas[id];
|
||||
var club = null;
|
||||
if (entry['club'] != null)
|
||||
club = await dbGetData('clubs', entry['club']);
|
||||
if (entry.planning.steuermann !== null) {
|
||||
entry.planning.steuermann = (await dbGetData('sailors', entry.planning.steuermann)).name;
|
||||
}
|
||||
var crewString = entry.planning.crew.split(',');
|
||||
entry.planning.crew = [];
|
||||
for (c in crewString) {
|
||||
var sailor = await dbGetData('sailors', crewString[c]);
|
||||
if (sailor !== null) {
|
||||
entry.planning.crew.push(sailor.name);
|
||||
}
|
||||
}
|
||||
|
||||
var dateFrom = entry['dateFrom'];
|
||||
var dateTo = entry['dateTo'];
|
||||
|
||||
var row = { keywords: [], content: '' };
|
||||
row.keywords.push(entry['name']);
|
||||
if (entry['number'] != null) row.keywords.push(entry['number']);
|
||||
if (club != null) row.keywords.push(club['kurz'], club['name']);
|
||||
if (entry.planning.steuermann != null) row.keywords.push(entry.planning.steuermann);
|
||||
for (c in entry.planning.crew) row.keywords.push(entry.planning.crew[c]);
|
||||
|
||||
if (!heute && (today <= dateFrom)) {
|
||||
rows.push(null);
|
||||
heute = true;
|
||||
}
|
||||
|
||||
row.content += '<div onclick="onRegattaClicked(' + entry['id'] + ');">';
|
||||
|
||||
// ZEILE 1
|
||||
// Name
|
||||
row.content += '<div><b>' + (entry['canceled'] == 1 ? '<s>' : '') + entry['name'] + (entry['canceled'] == 1 ? '</s>' : '') + '</b></div>';
|
||||
|
||||
// ZEILE 2
|
||||
row.content += '<div>';
|
||||
|
||||
// Number
|
||||
row.content += '<div>' + ((entry['number'] != null) ? ('# ' + entry['number']) : '') + '</div>';
|
||||
|
||||
// Special
|
||||
if (entry.special.substr(0, 1) == '#') {
|
||||
entry.special = '* ' + entry.special.substr(1);
|
||||
}
|
||||
// replace placeholders
|
||||
var pos;
|
||||
while ((pos = entry.special.indexOf('$')) >= 0) {
|
||||
var pos2 = entry.special.indexOf('$', pos + 1);
|
||||
if (pos2 < 0) break;
|
||||
var key = entry.special.substring(pos + 1, pos2);
|
||||
|
||||
var value = '';
|
||||
// age class
|
||||
if ((key.substr(0, 1) == 'U') && (!isNaN(value = parseInt(key.substr(1))))) {
|
||||
value = 'U-' + value;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
entry.special = entry.special.replace('$' + key + '$', value);
|
||||
}
|
||||
row.content += '<div>' + entry['special'] + '</div>';
|
||||
|
||||
// Club
|
||||
row.content += '<div>' + ((club != null) ? club['kurz'] : '') + '</div>';
|
||||
|
||||
row.content += '</div>';
|
||||
|
||||
// ZEILE 3
|
||||
row.content += '<div>';
|
||||
|
||||
// Date
|
||||
if (entry['length'] < 1) {
|
||||
if (formatDate('d.m', dateFrom) == '01.01') {
|
||||
row.content += '<div><font class="color-red2-dark">Datum noch unklar</font></div>';
|
||||
} else {
|
||||
row.content += '<div>' + formatDate("d.m.Y", dateFrom) + ' - <font class="color-red2-dark">Datum nicht final</font></div>';
|
||||
}
|
||||
} else {
|
||||
row.content += '<div>' + formatDate("d.m.Y", dateFrom) + ' - ' + formatDate("d.m.Y", dateTo) + '</div>';
|
||||
}
|
||||
|
||||
// RLF
|
||||
row.content += '<div>' + parseFloat(entry['rlf']).toFixed(2) + '</div>';
|
||||
|
||||
row.content += '</div>';
|
||||
|
||||
// ZEILE 4
|
||||
row.content += '<div></div>';
|
||||
|
||||
// ZEILE 5
|
||||
row.content += '<div>';
|
||||
row.content += '<div>' + (entry.planning.steuermann !== null ? entry.planning.steuermann : 'noch unklar') + '</div>';
|
||||
row.content += '</div>';
|
||||
|
||||
// ZEILE 6...
|
||||
for (var i in entry.planning.crew) {
|
||||
row.content += '<div>';
|
||||
row.content += '<div>' + entry.planning.crew[i] + '</div>';
|
||||
row.content += '</div>';
|
||||
}
|
||||
|
||||
row.content += '</div>';
|
||||
|
||||
rows.push(row);
|
||||
}
|
||||
|
||||
if (!heute) {
|
||||
rows.push(null);
|
||||
}
|
||||
|
||||
drawList();
|
||||
|
||||
} else {
|
||||
$('#p-count').html(user.username + ' hat noch keine Regatten in seiner/ihrer Saison-Planung!');
|
||||
$('#div-regattas').hide();
|
||||
$('#input-search').parent().hide();
|
||||
}
|
||||
|
||||
hideLoader();
|
||||
}
|
||||
@@ -111,8 +111,8 @@ async function selectChange(callSiteScript = true) {
|
||||
var year = parseInt($('#select-year').val());
|
||||
if (type == "user") {
|
||||
$('#select-year').parent().hide();
|
||||
$('#input-from').parent().show();
|
||||
$('#input-to').parent().show();
|
||||
$('#input-from').trigger('focusin').trigger('focusout').parent().show();
|
||||
$('#input-to').trigger('focusin').trigger('focusout').parent().show();
|
||||
$('#input-jugend').parent().parent().show();
|
||||
$('#input-jugstrict').parent().parent().show();
|
||||
$('#button-show').show();
|
||||
@@ -137,6 +137,7 @@ async function selectChange(callSiteScript = true) {
|
||||
jugend = jugstrict = true;
|
||||
break;
|
||||
case 'idjm':
|
||||
var youthGermanName = await dbGetClassProp('youth-german-name');
|
||||
var beginn = null;
|
||||
var regattas = await dbGetData('regattas');
|
||||
regattas.sort(function(a,b){ return b.date.localeCompare(a.date); });
|
||||
@@ -146,7 +147,7 @@ async function selectChange(callSiteScript = true) {
|
||||
if ((date < parseDate('01.01.' + year)) || (date > parseDate('31.12.' + year))) {
|
||||
continue;
|
||||
}
|
||||
if (regatta.name.indexOf(YOUTH_GERMAN_NAME) >= 0) {
|
||||
if (regatta.name.indexOf(youthGermanName) >= 0) {
|
||||
beginn = ((regatta.meldungSchluss != null) ? parseDate(regatta.meldungSchluss) : date);
|
||||
break;
|
||||
}
|
||||
@@ -162,7 +163,7 @@ async function selectChange(callSiteScript = true) {
|
||||
jugend = true;
|
||||
jugstrict = false;
|
||||
} else {
|
||||
$('#div-rank').html('Keine ' + YOUTH_GERMAN_NAME + ' gefunden!');
|
||||
$('#div-rank').html('Keine ' + youthGermanName + ' gefunden!');
|
||||
$('#input-search').parent().hide();
|
||||
return;
|
||||
}
|
||||
@@ -174,8 +175,22 @@ async function selectChange(callSiteScript = true) {
|
||||
$('#input-jugend').prop('checked', jugend);
|
||||
$('#input-jugstrict').prop('checked', jugstrict);
|
||||
|
||||
if (callSiteScript && (typeof siteScript === 'function'))
|
||||
if (callSiteScript && (typeof siteScript === 'function')) {
|
||||
history.replaceState(null, '', '?type=' + type + '&year=' + year);
|
||||
showLoader();
|
||||
siteScript();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buttonShowPressed() {
|
||||
if (typeof siteScript === 'function') {
|
||||
var chboxes = '';
|
||||
if ($('#input-jugend').prop('checked')) chboxes += '&jugend=on'
|
||||
if ($('#input-jugstrict').prop('checked')) chboxes += '&jugstrict=on'
|
||||
history.replaceState(null, '', '?type=user&from=' + $('#input-from').val() + "&to=" + $('#input-to').val() + chboxes)
|
||||
showLoader();
|
||||
siteScript();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +205,19 @@ function initSelects() {
|
||||
$('#select-year').html('<option value="' + year + '">' + year + '</option>');
|
||||
$('#select-year').val(year);
|
||||
|
||||
if (type == "user") {
|
||||
var from = findGetParameter('from');
|
||||
var to = findGetParameter('to');
|
||||
if (from === null) from = formatDate('Y-m-d')
|
||||
if (to === null) to = formatDate('Y-m-d')
|
||||
$('#input-from').val(from).trigger('focusin').trigger('focusout');
|
||||
$('#input-to').val(to).trigger('focusin').trigger('focusout');
|
||||
var jugend = findGetParameter('jugend');
|
||||
var jugstrict = findGetParameter('jugstrict');
|
||||
$('#input-jugend').prop('checked', jugend !== null);
|
||||
$('#input-jugstrict').prop('checked', jugstrict !== null);
|
||||
}
|
||||
|
||||
selectChange(false);
|
||||
}
|
||||
|
||||
@@ -218,7 +246,7 @@ var siteScript = async function() {
|
||||
initSelects();
|
||||
$('#select-type').change(selectChange);
|
||||
$('#select-year').change(selectChange);
|
||||
$('#button-show').click(siteScript);
|
||||
$('#button-show').click(buttonShowPressed);
|
||||
$('#input-search').on('input', drawList);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ var siteScript = async function() {
|
||||
tbody += '<td>' + (await dbGetData('users', planning.user)).username + '</td>';
|
||||
|
||||
if (planning.steuermann != null) {
|
||||
tbody += '<td>' + (await dbGetData('users', planning.user)).username + '</td>';
|
||||
tbody += '<td>' + (await dbGetData('sailors', planning.steuermann)).name + '</td>';
|
||||
} else {
|
||||
tbody += '<td>(noch unklar)</td>';
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
function selectChange(callSiteScript = true) {
|
||||
var val = $('#select-year').val();
|
||||
if (val == "user") {
|
||||
$('#input-from').parent().show();
|
||||
$('#input-to').parent().show();
|
||||
$('#input-from').trigger('focusin').trigger('focusout').parent().show();
|
||||
$('#input-to').trigger('focusin').trigger('focusout').parent().show();
|
||||
$('#button-show').show();
|
||||
} else {
|
||||
$('#input-from').parent().hide();
|
||||
@@ -12,19 +12,43 @@ function selectChange(callSiteScript = true) {
|
||||
$('#input-from').val(val + '-01-01');
|
||||
$('#input-to').val(val + '-12-31');
|
||||
|
||||
if (callSiteScript && (typeof siteScript === 'function'))
|
||||
if (callSiteScript && (typeof siteScript === 'function')) {
|
||||
history.replaceState(null, '', '?year=' + val);
|
||||
showLoader();
|
||||
siteScript();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buttonShowPressed() {
|
||||
if (typeof siteScript === 'function') {
|
||||
history.replaceState(null, '', '?year=user&from=' + $('#input-from').val() + "&to=" + $('#input-to').val());
|
||||
showLoader();
|
||||
siteScript();
|
||||
}
|
||||
}
|
||||
|
||||
function initYear() {
|
||||
var year = findGetParameter('year');
|
||||
if (year === null) year = new Date().getFullYear();
|
||||
return new Promise(async function (resolve) {
|
||||
var year = findGetParameter('year');
|
||||
if (year === null) year = await dbGetCurrentYear();
|
||||
|
||||
$('#select-year').html('<option value="' + year + '">' + year + '</option>');
|
||||
$('#select-year').val(year);
|
||||
$('#select-year').html('<option value="' + year + '">' + year + '</option>');
|
||||
$('#select-year').val(year);
|
||||
|
||||
selectChange(false);
|
||||
if (year == "user") {
|
||||
var from = findGetParameter('from');
|
||||
var to = findGetParameter('to');
|
||||
if (from === null) from = formatDate('Y-m-d')
|
||||
if (to === null) to = formatDate('Y-m-d')
|
||||
$('#input-from').val(from).trigger('focusin').trigger('focusout');
|
||||
$('#input-to').val(to).trigger('focusin').trigger('focusout');
|
||||
}
|
||||
|
||||
selectChange(false);
|
||||
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
var firstCall = true;
|
||||
@@ -48,9 +72,9 @@ async function drawList () {
|
||||
var siteScript = async function() {
|
||||
if (firstCall) {
|
||||
firstCall = false;
|
||||
initYear();
|
||||
await initYear();
|
||||
$('#select-year').change(selectChange);
|
||||
$('#button-show').click(siteScript);
|
||||
$('#button-show').click(buttonShowPressed);
|
||||
$('#input-search').on('input', drawList);
|
||||
}
|
||||
|
||||
@@ -59,12 +83,6 @@ var siteScript = async function() {
|
||||
var minDate = parseDate($('#input-from').val());
|
||||
var maxDate = parseDate($('#input-to').val());
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
var regattaResults = [];
|
||||
for (id in regattas) {
|
||||
var entry = regattas[id];
|
||||
var results = await dbGetDataIndex('results', 'regatta', entry['id']);
|
||||
regattaResults[entry['id']] = (results.length > 0);
|
||||
}
|
||||
|
||||
var selectedYear = $('#select-year').val();
|
||||
|
||||
@@ -95,6 +113,9 @@ var siteScript = async function() {
|
||||
var heute = false;
|
||||
|
||||
rows = [];
|
||||
var specialFields = await dbGetClassProp('special-fields');
|
||||
if (specialFields === null) specialFields = {};
|
||||
var specialShown = {};
|
||||
|
||||
for (id in regattas) {
|
||||
var entry = regattas[id];
|
||||
@@ -132,7 +153,37 @@ var siteScript = async function() {
|
||||
row.content += '<div>' + ((club != null) ? club['kurz'] : '') + '</div>';
|
||||
|
||||
// Special
|
||||
row.content += '<div>' + entry['special'] + '</div>';
|
||||
if (entry.special.substr(0, 1) == '#') {
|
||||
entry.special = entry.special.substr(1);
|
||||
if (typeof specialFields[entry.special] !== 'undefined') {
|
||||
specialShown[entry.special] = specialFields[entry.special];
|
||||
entry.special = '* ' + entry.special;
|
||||
} else {
|
||||
entry.special = 'ERROR';
|
||||
}
|
||||
}
|
||||
// replace placeholders
|
||||
var pos;
|
||||
while ((pos = entry.special.indexOf('$')) >= 0) {
|
||||
var pos2 = entry.special.indexOf('$', pos + 1);
|
||||
if (pos2 < 0) break;
|
||||
var key = entry.special.substring(pos + 1, pos2);
|
||||
|
||||
var value = '';
|
||||
// age class
|
||||
if ((key.substr(0, 1) == 'U') && (!isNaN(value = parseInt(key.substr(1))))) {
|
||||
var year = parseDate(entry.date).getFullYear();
|
||||
year = year - value + 1;
|
||||
var text = 'Jahrgänge ' + year + ' und jünger';
|
||||
value = 'U-' + value;
|
||||
specialShown[value] = text;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
entry.special = entry.special.replace('$' + key + '$', value);
|
||||
}
|
||||
row.content += '<div>' + entry.special + '</div>';
|
||||
|
||||
// Icons
|
||||
var icons = [];
|
||||
@@ -160,8 +211,10 @@ var siteScript = async function() {
|
||||
ms = parseDate(entry['meldungSchluss']);
|
||||
}
|
||||
var diff = Math.round((ms - today) / 86400000);
|
||||
if ((ms >= today) && (diff < 7)) {
|
||||
if (ms < today) {
|
||||
color = ' color-red2-dark';
|
||||
} else if (diff < 7) {
|
||||
color = ' color-yellow2-dark';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,7 +227,7 @@ var siteScript = async function() {
|
||||
icons.push('<i class="fas fa-book"></i>');
|
||||
if (entry['canceled'] == '1') {
|
||||
icons.push('<i class="fas fa-times color-red2-dark"></i>');
|
||||
} else if (regattaResults[entry['id']]) {
|
||||
} else if (entry['results'] == '1') {
|
||||
icons.push('<i class="fas fa-poll"></i>');
|
||||
}
|
||||
row.content += '<div class="color-green2-dark">' + icons.join(' ') + '</div>';
|
||||
@@ -207,12 +260,27 @@ var siteScript = async function() {
|
||||
rows.push(null);
|
||||
}
|
||||
|
||||
var specialKeys = Object.keys(specialShown);
|
||||
if (specialKeys.length > 0) {
|
||||
specialKeys.sort();
|
||||
var specialText = '';
|
||||
for (i in specialKeys) {
|
||||
var key = specialKeys[i];
|
||||
specialText += '* ' + key + ': ' + specialShown[key] + '<br>';
|
||||
}
|
||||
$('#card-special').find('p').html(specialText);
|
||||
$('#card-special').show();
|
||||
} else {
|
||||
$('#card-special').hide();
|
||||
}
|
||||
|
||||
drawList();
|
||||
|
||||
} else {
|
||||
$('#p-count').html('Keine Regatten gefunden!');
|
||||
$('#div-regattas').hide();
|
||||
$('#input-search').parent().hide();
|
||||
$('#card-special').hide();
|
||||
}
|
||||
|
||||
hideLoader();
|
||||
|
||||
@@ -4,19 +4,119 @@ var displayed = [];
|
||||
var page = 1;
|
||||
var pageCount = 0;
|
||||
const showCount = 25;
|
||||
var followedSailors = [];
|
||||
|
||||
async function onFollowChange() {
|
||||
var id = $('#menu-item-follow').attr('data-sailor-id');
|
||||
showLoader();
|
||||
$('#menu-sailor').hideMenu();
|
||||
var auth = {
|
||||
id: localStorage.getItem('auth_id'),
|
||||
hash: localStorage.getItem('auth_hash')
|
||||
}
|
||||
$.ajax({
|
||||
url: QUERY_URL + ($('#menu-item-follow').prop('checked') ? 'sailor_follow' : 'sailor_unfollow'),
|
||||
method: 'POST',
|
||||
data: {
|
||||
auth: auth,
|
||||
sailor: id
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um Deine Favoriten zu bearbeiten.');
|
||||
} else {
|
||||
log('Un/Follow: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
hideLoader();
|
||||
},
|
||||
success: async function (data, status, xhr) {
|
||||
await sync();
|
||||
toastOk('Erfolgreich');
|
||||
hideLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function onEditYearClick() {
|
||||
var id = $('#button-edityear').attr('data-sailor-id');
|
||||
var year = $('#input-edityear').val();
|
||||
if (year != '') {
|
||||
showLoader();
|
||||
$.ajax({
|
||||
url: QUERY_URL + 'add_year',
|
||||
method: 'POST',
|
||||
data: {
|
||||
sailor: id,
|
||||
year: year
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
if (xhr.status == 0) {
|
||||
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um den Jahrgang zu bearbeiten');
|
||||
} else {
|
||||
log('EditYear: unbekannter Fehler', status, error);
|
||||
log(xhr);
|
||||
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
|
||||
}
|
||||
hideLoader();
|
||||
},
|
||||
success: function (data, status, xhr) {
|
||||
if ('status' in data) {
|
||||
if (data.status == 'added') {
|
||||
toastOk('Jahrgang erfolgreich hinzugefügt');
|
||||
sync();
|
||||
} else {
|
||||
toastInfo('Wir prüfen Deine Anfrage und korrigieren den Jahrgang schnellstmöglich', 5000);
|
||||
}
|
||||
} else {
|
||||
toastOk('Erfolgreich');
|
||||
}
|
||||
hideLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
$('#menu-edityear').hideMenu();
|
||||
}
|
||||
|
||||
async function onListClicked(id) {
|
||||
var sailor = await dbGetData('sailors', id);
|
||||
|
||||
$('#menu-sailor').find('.menu-title').find('p').text(sailor.name);
|
||||
|
||||
// Follow
|
||||
if (isLoggedIn()) {
|
||||
var found = false;
|
||||
for (var i in followedSailors) {
|
||||
if (followedSailors[i].id == sailor.id) found = true;
|
||||
}
|
||||
if (found || (followedSailors.length < 5)) {
|
||||
$('#menu-item-follow').attr('data-sailor-id', sailor.id);
|
||||
$('#menu-item-follow').prop('checked', found);
|
||||
$('#menu-item-follow').parent().parent().show();
|
||||
$('#menu-item-follow-disabled').hide();
|
||||
} else {
|
||||
$('#menu-item-follow').parent().parent().hide();
|
||||
$('#menu-item-follow-disabled').show();
|
||||
}
|
||||
} else {
|
||||
$('#menu-item-follow').parent().parent().hide();
|
||||
$('#menu-item-follow-disabled').hide();
|
||||
}
|
||||
|
||||
// Edit Year
|
||||
// TODO: create menu for edit year
|
||||
$('#button-edityear').attr('data-sailor-id', sailor.id);
|
||||
$('#menu-edityear').find('.menu-title').find('p').text(sailor.name);
|
||||
if (sailor['year'] == null) {
|
||||
$('#menu-item-year').find('span').text('Jahrgang hinzufügen');
|
||||
$('#menu-edityear').find('.menu-title').find('h1').text('Jahrgang hinzufügen');
|
||||
$('#input-edityear').val('');
|
||||
} else {
|
||||
$('#menu-item-year').find('span').text('Jahrgang bearbeiten');
|
||||
$('#menu-edityear').find('.menu-title').find('h1').text('Jahrgang bearbeiten');
|
||||
$('#input-edityear').val(sailor.year);
|
||||
}
|
||||
$('#input-edityear').trigger('focusin').trigger('focusout');
|
||||
|
||||
// club website
|
||||
var clubwebsite = '';
|
||||
@@ -86,6 +186,21 @@ var siteScript = async function() {
|
||||
firstCall = false;
|
||||
initPagination();
|
||||
$('#input-search').on('input', reSearch);
|
||||
$('#menu-item-year').click(function(){ $('#menu-sailor').hideMenu(); $('#menu-edityear').showMenu(); });
|
||||
$('#button-edityear').click(onEditYearClick);
|
||||
$('#menu-item-follow').parent().parent().click(onFollowChange);
|
||||
$('#menu-item-follow-disabled').click(function(){ $('#menu-sailor').hideMenu(); toastInfo('Du kannst maximal 5 Seglern folgen. Entferne erst einen Segler aus Deinen Favoriten, bevor Du andere aufnimmst.', 5000); });
|
||||
}
|
||||
|
||||
if (isLoggedIn()) {
|
||||
var user = await dbGetData('users', USER_ID);
|
||||
followedSailors = [];
|
||||
for (var i = 1; i <= 5; i ++) {
|
||||
sailor_id = user['sailor' + i];
|
||||
if (sailor_id != null) {
|
||||
followedSailors.push(await dbGetData('sailors', sailor_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var results = await dbGetData('sailors');
|
||||
|
||||
8
server/templates/menu/item-switch.html
Normal file
8
server/templates/menu/item-switch.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<a href="#" data-trigger-switch="$$html-id;" class="pb-2 $$css-class;">
|
||||
<i class="fa font-14 $$icon; rounded-s bg-highlight color-white"></i>
|
||||
<span>$$0;</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="$$html-id;">
|
||||
<label class="custom-control-label" for="$$html-id;"></label>
|
||||
</div>
|
||||
</a>
|
||||
@@ -1,4 +1,4 @@
|
||||
<nav id="$$html-id;">
|
||||
<nav id="$$html-id;" class="$$css-class;">
|
||||
<ul class="pagination justify-content-center">
|
||||
<li id="$$html-id;-1" class="page-item"><a onclick="onPaginationClick(this)" class="page-link color-black bg-theme rounded-xs shadow-x1 border-0" style="cursor: pointer;">1</a></li>
|
||||
<li id="$$html-id;-2" class="page-item"><a onclick="onPaginationClick(this)" class="page-link color-black bg-theme rounded-xs shadow-x1 border-0" style="cursor: pointer;">2</a></li>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="input-style input-style-2 input-required $$css-class;">
|
||||
<span class="color-highlight">$$placeholder;</span>
|
||||
<textarea id="$$html-id;" class="form-control" placeholder="$$placeholder;">$$value;</textarea>
|
||||
<textarea id="$$html-id;" class="form-control pt-3 pb-3" placeholder="$$placeholder;" style="height: 10em; line-height: 1.5em;">$$value;</textarea>
|
||||
</div>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
|
||||
define('PWA_VERSION', '1.4');
|
||||
define('PWA_VERSION', '1.11.5');
|
||||
|
||||
?>
|
||||
@@ -56,15 +56,19 @@ workbox.precaching.precacheAndRoute([
|
||||
'/manifest.json.php',
|
||||
];
|
||||
$dirsToCache = [
|
||||
'/client',
|
||||
'/client/app',
|
||||
'/client/fonts/css',
|
||||
'/client/fonts/webfonts',
|
||||
'/client/images',
|
||||
'/client/scripts',
|
||||
'/client/styles',
|
||||
];
|
||||
|
||||
function addDir($path) {
|
||||
global $filesToCache;
|
||||
if ($dir = opendir(__DIR__ . $path)) {
|
||||
while (($file = readdir($dir)) !== false) {
|
||||
if ($file == '.') continue;
|
||||
if ($file == '..') continue;
|
||||
if (substr($file, 0, 1) == '.') continue;
|
||||
if (is_dir(__DIR__ . $path . '/' . $file)) {
|
||||
addDir($path . '/' . $file);
|
||||
} else {
|
||||
@@ -105,3 +109,217 @@ workbox.routing.registerRoute(
|
||||
|
||||
//Learn more about Service Workers and Configurations
|
||||
//https://developers.google.com/web/tools/workbox/
|
||||
|
||||
|
||||
// DB
|
||||
|
||||
function openDb() {
|
||||
return new Promise(function(resolve) {
|
||||
if (indexedDB) {
|
||||
var request = indexedDB.open('regatten_app_db_<?php echo BOATCLASS; ?>');
|
||||
request.onerror = function (e) {
|
||||
console.log('[sW] Cannot open DB:', e.targer.errorCode);
|
||||
resolve(null);
|
||||
};
|
||||
request.onupgradeneeded = function (e) {
|
||||
console.log('[sW] DB does not exist');
|
||||
e.target.transaction.abort();
|
||||
resolve(null);
|
||||
};
|
||||
request.onsuccess = function (e) {
|
||||
console.log('[sW] DB loaded');
|
||||
var db = e.target.result;
|
||||
db.onerror = function (e) {
|
||||
console.log('[sW] DB Error:', e);
|
||||
};
|
||||
resolve(db);
|
||||
}
|
||||
} else {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function dbSettingsGet(key) {
|
||||
return new Promise(async function(resolve) {
|
||||
var db = await openDb();
|
||||
if (db !== null) {
|
||||
var request = db.transaction('settings').objectStore('settings').get(key);
|
||||
request.onsuccess = function (event) {
|
||||
db.close();
|
||||
console.log('[sW] DB closed');
|
||||
resolve(typeof request.result != 'undefined' ? request.result.value : null);
|
||||
}
|
||||
} else {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function dbSettingsSet(key, value) {
|
||||
var db = await openDb();
|
||||
if (db != null) {
|
||||
var os = db.transaction('settings', 'readwrite').objectStore('settings');
|
||||
var request = os.put({ key: key, value: value});
|
||||
request.onerror = function (event) {
|
||||
console.log('[sW] Error while saving data to DB:', e);
|
||||
db.close();
|
||||
console.log('[sW] DB closed');
|
||||
}
|
||||
request.onsuccess = function (event) {
|
||||
db.close();
|
||||
console.log('[sW] DB closed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// PUSHES
|
||||
|
||||
function getEntry(data, index, defaultValue) {
|
||||
return ((typeof data[index] !== "undefined") ? data[index] : defaultValue);
|
||||
}
|
||||
|
||||
function isMyRegatta(id, suffix = '') {
|
||||
return new Promise(async function (resolve) {
|
||||
var regattas = await dbSettingsGet('myregattas_<?php echo BOATCLASS; ?>' + suffix);
|
||||
if (regattas == null) resolve(false);
|
||||
else resolve(regattas.includes(id.toString()));
|
||||
});
|
||||
}
|
||||
|
||||
self.addEventListener('push', async function(event) {
|
||||
console.log('[sW] Push received:', event.data.text());
|
||||
|
||||
var data;
|
||||
try {
|
||||
data = JSON.parse(event.data.text());
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
data = undefined;
|
||||
}
|
||||
|
||||
if (typeof data.type !== "undefined") {
|
||||
switch (data.type) {
|
||||
case 'notification':
|
||||
if (typeof data.title === "undefined") break;
|
||||
if (typeof data.body === "undefined") break;
|
||||
if (typeof data.channel === "undefined") break;
|
||||
|
||||
// check channel
|
||||
var okay = false;
|
||||
switch (data.channel) {
|
||||
case 'news':
|
||||
if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_news')) okay = true;
|
||||
break;
|
||||
case 'regatta_changed':
|
||||
if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_regatta_changed_all')) okay = true;
|
||||
else if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_regatta_changed_my')) {
|
||||
if (await isMyRegatta(getEntry(data, 'id', ''))) okay = true;
|
||||
}
|
||||
break;
|
||||
case 'result_ready':
|
||||
if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_result_ready_all')) okay = true;
|
||||
else if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_result_ready_my')) {
|
||||
if (await isMyRegatta(getEntry(data, 'id', ''))) okay = true;
|
||||
}
|
||||
break;
|
||||
case 'meldeschluss':
|
||||
if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_meldeschluss')) {
|
||||
if (await isMyRegatta(getEntry(data, 'id', ''), '_meldung_off')) okay = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log('[sW] Unknown channel:', data.channel);
|
||||
break;
|
||||
}
|
||||
if (!okay) {
|
||||
console.log('[sW] Notification channel not subscribed');
|
||||
return;
|
||||
}
|
||||
|
||||
const options = {
|
||||
data: data,
|
||||
body: data.body,
|
||||
icon: getEntry(data, 'icon', '<?php echo SERVER_ADDR; ?>/client/app/icons/icon-512x512.png'),
|
||||
badge: '<?php echo SERVER_ADDR; ?>/client/app/icons/badge-128x128.png',
|
||||
vibrate: [500,100,500]
|
||||
};
|
||||
if ((image = getEntry(data, 'image', null)) !== null) {
|
||||
options.image = image;
|
||||
}
|
||||
|
||||
// Force refresh on next app open
|
||||
var db = await openDb();
|
||||
if (db != null) {
|
||||
var os = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
var request = os.put({ table: 'last_sync', time: 1 });
|
||||
request.onerror = function (event) {
|
||||
console.log('[sW] Error while saving data to DB:', e);
|
||||
db.close();
|
||||
console.log('[sW] DB closed');
|
||||
}
|
||||
request.onsuccess = function (event) {
|
||||
db.close();
|
||||
console.log('[sW] DB closed');
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[sW] Showing notification');
|
||||
self.registration.showNotification(data.title, options);
|
||||
break;
|
||||
|
||||
case 'forcesync':
|
||||
// Force refresh on next app open
|
||||
var db = await openDb();
|
||||
if (db != null) {
|
||||
var os = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
var request = os.put({ table: 'last_sync', time: 1 });
|
||||
request.onerror = function (event) {
|
||||
console.log('[sW] Error while saving data to DB:', e);
|
||||
db.close();
|
||||
console.log('[sW] DB closed');
|
||||
}
|
||||
request.onsuccess = function (event) {
|
||||
console.log('[sW] Data successfully saved');
|
||||
db.close();
|
||||
console.log('[sW] DB closed');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log('[sW] Push type unknown:', data.type);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
console.log('[sW] No push type given!');
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener('notificationclick', function(event) {
|
||||
var data = event.notification.data;
|
||||
|
||||
event.notification.close();
|
||||
|
||||
var url = '<?php echo SERVER_ADDR; ?>' + getEntry(data, 'url', '');
|
||||
|
||||
event.waitUntil(
|
||||
clients.openWindow(url)
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('pushsubscriptionchange', function(event) {
|
||||
var formData = new URLSearchParams();
|
||||
formData.append('old', JSON.stringify(event.oldSubscription));
|
||||
formData.append('new', JSON.stringify(event.newSubscription));
|
||||
event.waitUntil(
|
||||
fetch('<?php echo QUERY_URL; ?>update_subscription', {
|
||||
method: 'POST',
|
||||
cache: 'no-cache',
|
||||
body: formData
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user