Compare commits

...

201 Commits

Author SHA1 Message Date
099fb6deb6 Merge branch 'hotfix/fix_login_loop' 2025-02-19 19:44:01 +01:00
f3e1620057 gitflow-hotfix-stash: fix_login_loop 2025-02-19 19:43:56 +01:00
b52eea79c2 Merge branch 'hotfix/debug_info_on_push_subscription' 2025-02-19 16:49:56 +01:00
8972d2d72a gitflow-hotfix-stash: debug_info_on_push_subscription 2025-02-19 16:49:51 +01:00
49ed27e58f Merge branch 'hotfix/menu-more-size' 2025-02-19 15:37:36 +01:00
9a5d90a703 fix menu-more-size 2025-02-19 15:37:28 +01:00
bceca97c98 Merge branch 'hotfix/expenditures_dark_mode' 2025-02-19 15:35:19 +01:00
52c6914d41 fix expenditures dark mode 2025-02-19 15:35:11 +01:00
0a323be5bf Merge branch 'release/v1.13' 2025-02-19 15:21:09 +01:00
2242cedfea release v1.13 2025-02-19 15:20:54 +01:00
69dcb13f50 Merge branch 'feature/expenditures' into develop 2025-02-19 15:18:40 +01:00
5dc88a78a2 expenditures: add: regatta_name got datalist 2025-02-19 15:18:08 +01:00
a221c86431 expenditures: Ausgleichen-Button 2025-02-19 15:05:19 +01:00
839f668b08 expenditures: added badge for open approvals 2025-02-19 14:49:21 +01:00
8f597051dd planning_edit: crew: fa-times
instead of fa-angle-right to show that by clicking the sailor will be removed
2025-02-19 14:31:45 +01:00
dd587f7603 added full expenditures functionality 2025-02-19 14:30:44 +01:00
0e501e8ba4 added table expenditures inkl sync 2025-02-18 14:02:06 +01:00
42e68e5511 changed main menu: planning <-> lists 2025-02-18 13:05:22 +01:00
2971fdd259 Merge branch 'hotfix/v1.12.1h9' 2025-02-17 13:28:49 +01:00
9360f0e943 Merge branch 'hotfix/v1.12.1h9' into develop 2025-02-17 13:28:49 +01:00
47718318ef gitflow-hotfix-stash: v1.12.1h9 2025-02-17 13:28:34 +01:00
bd4fc4c255 Merge branch 'hotfix/register_on_regatten_net' 2025-02-17 13:26:59 +01:00
1ab0e9185f Merge branch 'hotfix/register_on_regatten_net' into develop 2025-02-17 13:26:59 +01:00
027abe5364 gitflow-hotfix-stash: register_on_regatten_net 2025-02-17 13:26:08 +01:00
ostertun
29f83814ee Merge branch 'hotfix/new_follow2' 2024-02-18 13:19:12 +01:00
ostertun
deb23a5f7f Merge branch 'hotfix/new_follow2' into develop 2024-02-18 13:19:12 +01:00
ostertun
744be24410 gitflow-hotfix-stash: new_follow2 2024-02-18 13:19:04 +01:00
ostertun
633e39ce5d Merge branch 'hotfix/new_follow' 2024-02-18 13:14:12 +01:00
ostertun
bd2aafe67c Merge branch 'hotfix/new_follow' into develop 2024-02-18 13:14:12 +01:00
ostertun
2e6eb25e68 gitflow-hotfix-stash: new_follow 2024-02-18 13:13:55 +01:00
ostertun
dc2ead3a07 Merge branch 'hotfix/a53.2' 2023-11-27 09:21:05 +01:00
ostertun
ccc8731394 Merge branch 'hotfix/a53.2' into develop 2023-11-27 09:21:05 +01:00
ostertun
6b89acf422 gitflow-hotfix-stash: a53.2 2023-11-27 09:20:58 +01:00
ostertun
54ceae6ce0 Merge branch 'hotfix/a53' 2023-11-27 09:14:53 +01:00
ostertun
fe02f8707b Merge branch 'hotfix/a53' into develop 2023-11-27 09:14:52 +01:00
ostertun
a6f0c8e0f5 a53 2023-11-27 09:14:45 +01:00
ostertun
fe90438cb3 gitflow-hotfix-stash: a53 2023-11-27 09:14:19 +01:00
ostertun
8c4d2f00cd Merge branch 'temp' 2023-10-10 08:09:23 +02:00
ostertun
34ae418598 Merge branch 'hotfix/ranking_year2' into develop 2023-10-10 08:07:31 +02:00
ostertun
d59b384e1a gitflow-hotfix-stash: ranking_year2 2023-10-10 08:07:12 +02:00
ostertun
25df9995dd Merge branch 'hotfix/wfn_entrylist_link' 2023-09-04 14:26:03 +02:00
ostertun
12538aaa3f Merge branch 'hotfix/wfn_entrylist_link' into develop 2023-09-04 14:26:02 +02:00
ostertun
e087e137ff fix wfn_entrylist_link 2023-09-04 14:25:37 +02:00
ostertun
e5dc107a7d Merge branch 'hotfix/extServiceWfn' 2023-04-28 21:44:27 +02:00
ostertun
fefd3c8929 Merge branch 'hotfix/extServiceWfn' into develop 2023-04-28 21:44:26 +02:00
ostertun
dcc5428615 gitflow-hotfix-stash: extServiceWfn 2023-04-28 21:43:49 +02:00
ostertun
a37cf0ea46 Merge branch 'hotfix/api_move_regattenNet2' 2023-03-29 12:07:52 +02:00
ostertun
49f2923a97 Merge branch 'hotfix/api_move_regattenNet2' into develop 2023-03-29 12:07:52 +02:00
ostertun
b2c57839c4 file must be changed to change revision... 2023-03-29 12:07:42 +02:00
ostertun
eddf0f151b Merge branch 'hotfix/api_move_ranglistenNet' 2023-03-29 12:03:34 +02:00
ostertun
0dd83a47cb Merge branch 'hotfix/api_move_ranglistenNet' into develop 2023-03-29 12:03:34 +02:00
ostertun
3c07c67a1a api_move_ranglistenNet: change version to update cached files => config new loaded 2023-03-29 12:03:22 +02:00
ostertun
dd7d8731e8 remove tel num 2023-01-02 11:02:01 +01:00
ostertun
2caf6c4339 Merge branch 'release/v_1.12.1' 2022-08-03 12:32:53 +02:00
ostertun
866d3ab3c1 Merge branch 'release/v_1.12.1' into develop 2022-08-03 12:32:53 +02:00
ostertun
6b503eeae0 gitflow-release-stash: v_1.12.1 2022-08-03 12:32:38 +02:00
ostertun
a88c8356c2 crew ranking 2022-08-03 12:31:38 +02:00
ostertun
ba09698ece Merge branch 'release/v_1.11.9' 2022-06-27 11:35:34 +02:00
ostertun
ea3ac5f329 Merge branch 'release/v_1.11.9' into develop 2022-06-27 11:35:33 +02:00
ostertun
abe412d8ed gitflow-release-stash: v_1.11.9 2022-06-27 11:35:29 +02:00
ostertun
e25ca534ec show entry deadlines also when already registered 2022-06-27 11:35:07 +02:00
ostertun
4f01262eba Merge branch 'release/v_1.11.8' 2022-06-27 11:32:58 +02:00
ostertun
314792b09e Merge branch 'release/v_1.11.8' into develop 2022-06-27 11:32:57 +02:00
ostertun
a9464c382b gitflow-release-stash: v_1.11.8 2022-06-27 11:32:46 +02:00
ostertun
d204acd365 regattas: scroll to today button 2022-06-27 11:32:11 +02:00
ostertun
00dc405158 added regatta_facts incl links 2022-06-27 11:31:59 +02:00
ostertun
b87f557a62 Merge branch 'hotfix/rank_quali' 2022-04-27 14:14:03 +02:00
ostertun
689845d02a Merge branch 'hotfix/rank_quali' into develop 2022-04-27 14:14:03 +02:00
ostertun
ae8aed446b gitflow-hotfix-stash: rank_quali 2022-04-27 14:13:53 +02:00
ostertun
343d898afd Merge branch 'release/v_1.11.7' 2022-04-27 13:35:19 +02:00
ostertun
c88a512ff8 Merge branch 'release/v_1.11.7' into develop 2022-04-27 13:35:19 +02:00
ostertun
1fc7b8fe6d gitflow-release-stash: v_1.11.7 2022-04-27 13:35:06 +02:00
ostertun
2014303fae added special rank links 2022-04-27 13:34:26 +02:00
ostertun
7b6ad832a9 new ranking calculation (via ranking DB table) 2022-04-27 13:13:41 +02:00
ostertun
eaf0fd5a95 Merge branch 'hotfix/rank_fault_info' 2022-04-25 11:31:24 +02:00
ostertun
6c547d43c5 Merge branch 'hotfix/rank_fault_info' into develop 2022-04-25 11:31:24 +02:00
ostertun
e9e56b66ab gitflow-hotfix-stash: rank_fault_info 2022-04-25 11:31:12 +02:00
ostertun
143755a50f Merge branch 'release/v_1.11.6' 2022-04-21 14:08:02 +02:00
ostertun
8ba463c8fe Merge branch 'release/v_1.11.6' into develop 2022-04-21 14:08:01 +02:00
ostertun
13927fb769 v_1.11.6 boat in planning 2022-04-21 14:07:45 +02:00
ostertun
90075ceb4f planning: added boat 2022-04-21 14:06:10 +02:00
ostertun
526b338e41 small fixes to rank 2022-04-21 12:57:47 +02:00
ostertun
aa60df83db Merge branch 'hotfix/fix_error_report' 2021-09-03 12:59:44 +02:00
ostertun
58505a0f53 Merge branch 'hotfix/fix_error_report' into develop 2021-09-03 12:59:44 +02:00
ostertun
37c584e525 gitflow-hotfix-stash: fix_error_report 2021-09-03 12:59:33 +02:00
tostertun
1010e4ffdd Merge branch 'hotfix/wrong_result_sorting' 2021-08-31 16:53:47 +02:00
tostertun
c17c2b64cf Merge branch 'hotfix/wrong_result_sorting' into develop 2021-08-31 16:53:47 +02:00
tostertun
0658a44516 gitflow-hotfix-stash: wrong_result_sorting 2021-08-31 16:53:23 +02:00
ostertun
2f2d94bab4 Merge branch 'hotfix/deadline_expired_text' 2021-06-15 11:33:29 +02:00
ostertun
dd854b7df5 Merge branch 'hotfix/deadline_expired_text' into develop 2021-06-15 11:33:29 +02:00
ostertun
c91dc57736 gitflow-hotfix-stash: deadline_expired_text 2021-06-15 11:32:14 +02:00
ostertun
c8cef6ee95 Merge branch 'hotfix/state_NSC' 2021-06-13 23:24:05 +02:00
ostertun
3f7d7a40ec Merge branch 'hotfix/state_NSC' into develop 2021-06-13 23:24:05 +02:00
ostertun
19f561ffde gitflow-hotfix-stash: state_NSC 2021-06-13 23:23:25 +02:00
ostertun
84677ef4dd m2s listLink select class 2021-04-19 12:19:34 +02:00
ostertun
4dfa2d7bd5 Merge branch 'release/v_1.11.5' 2020-12-24 11:08:35 +01:00
ostertun
1e0052f629 Merge branch 'release/v_1.11.5' into develop 2020-12-24 11:08:34 +01:00
ostertun
c983a1702f Fix Altersklassen & no_regattas_on_index 2020-12-23 15:08:36 +01:00
ostertun
a1facbca85 Altersklassen 2020-12-22 18:44:05 +01:00
ostertun
fba8c8e958 v_1.11.5 Dark Mode 2020-12-21 12:01:59 +01:00
ostertun
8aa3e3ccb6 Merge branch 'hotfix/no_regattas_on_index' 2020-12-11 17:27:49 +01:00
ostertun
c319e568b6 Merge branch 'hotfix/no_regattas_on_index' into develop 2020-12-11 17:27:48 +01:00
ostertun
748176159d v_1.11.4h2 no_regattas_on_index 2020-12-11 17:27:44 +01:00
ostertun
053981175b Merge branch 'hotfix/notify_android_lost_subscription' 2020-12-09 13:53:37 +01:00
ostertun
7083b46831 Merge branch 'hotfix/notify_android_lost_subscription' into develop 2020-12-09 13:53:37 +01:00
ostertun
2c8c99b8f0 v_1.11.4h1 notify_android_lost_subscription 2020-12-09 13:53:17 +01:00
ostertun
07d01ae700 Merge branch 'release/V_1.11.4' 2020-12-07 16:48:32 +01:00
ostertun
7da31729e9 Merge branch 'release/V_1.11.4' into develop 2020-12-07 16:48:32 +01:00
ostertun
08ab714a54 Release v_1.11.4 2020-12-07 16:48:08 +01:00
ostertun
44c962b7b3 Show next year in regattas lists 2020-12-07 16:47:24 +01:00
ostertun
004280f3ea Merge branch 'hotfix/pushsubscription_onerror' 2020-11-19 13:20:41 +01:00
ostertun
63a8d174d7 Merge branch 'hotfix/pushsubscription_onerror' into develop 2020-11-19 13:20:41 +01:00
ostertun
13f496f0a6 gitflow-hotfix-stash: pushsubscription_onerror 2020-11-19 13:20:29 +01:00
ostertun
da553a8f8d Merge branch 'release/v_1.11.3' 2020-11-01 17:00:27 +01:00
ostertun
69ef983c07 Merge branch 'release/v_1.11.3' into develop 2020-11-01 17:00:26 +01:00
ostertun
32473901d6 Release v_1.11.3 2020-11-01 17:00:04 +01:00
ostertun
84320f3a67 Planning-edit: Show known sailors 2020-11-01 16:58:47 +01:00
ostertun
cd30ba1ce6 Menu close on back improved 2020-11-01 16:45:00 +01:00
ostertun
1fb619d4ec Planning: keep year 2020-11-01 16:38:06 +01:00
ostertun
0fd09c22a2 Link to entryList incl count 2020-10-29 14:52:36 +01:00
ostertun
12ed412226 Merge branch 'hotfix/error_report_button' 2020-10-22 14:54:24 +02:00
ostertun
7fd1c1c6e7 Merge branch 'hotfix/error_report_button' into develop 2020-10-22 14:54:23 +02:00
ostertun
4e85d3a993 gitflow-hotfix-stash: error_report_button 2020-10-22 14:54:18 +02:00
ostertun
5c22604896 Merge branch 'release/v_1.11.2' 2020-10-22 11:38:44 +02:00
ostertun
a2fe4c2637 Merge branch 'release/v_1.11.2' into develop 2020-10-22 11:38:43 +02:00
ostertun
4a65b48520 Release v_1.11.2 2020-10-22 11:38:28 +02:00
ostertun
4eb2970671 Special fields 2020-10-22 11:37:19 +02:00
ostertun
0298cefc8b Merge branch 'hotfix/error_reporting' 2020-10-22 01:17:11 +02:00
ostertun
e17f99d005 Merge branch 'hotfix/error_reporting' into develop 2020-10-22 01:17:11 +02:00
ostertun
15d7060354 gitflow-hotfix-stash: error_reporting 2020-10-22 01:10:37 +02:00
ostertun
d38de287dd Merge branch 'hotfix/ios_problems' 2020-10-21 16:27:02 +02:00
ostertun
1cb6de2402 Merge branch 'hotfix/ios_problems' into develop 2020-10-21 16:27:01 +02:00
ostertun
da2beac8d3 hotfix 2020-10-21 16:26:40 +02:00
ostertun
92a11bcfa5 gitflow-hotfix-stash: ios_problems 2020-10-21 16:26:02 +02:00
ostertun
2ddeac4ba4 sW: melde-erinnerungen only for regattas not registered 2020-10-16 13:45:02 +02:00
ostertun
fa4770e12a Merge branch 'hotfix/remote_logout' 2020-10-16 13:01:24 +02:00
ostertun
a845137873 Merge branch 'hotfix/remote_logout' into develop 2020-10-16 13:01:24 +02:00
ostertun
a6f2568753 gitflow-hotfix-stash: remote_logout 2020-10-16 13:01:06 +02:00
ostertun
6d0fdea0e8 Merge branch 'hotfix/add_planning_list_button' 2020-10-16 10:19:20 +02:00
ostertun
8bc0d9b15e Merge branch 'hotfix/add_planning_list_button' into develop 2020-10-16 10:19:20 +02:00
ostertun
1252c02d7c gitflow-hotfix-stash: add_planning_list_button 2020-10-16 10:19:05 +02:00
ostertun
f617fa7923 Merge branch 'release/v_1.11' 2020-10-15 19:41:34 +02:00
ostertun
3ff17a63e0 Merge branch 'release/v_1.11' into develop 2020-10-15 19:41:33 +02:00
ostertun
c66dc96598 Release v_1.11 2020-10-15 19:40:57 +02:00
ostertun
f5d059202e RA-#9 Signup 2020-10-15 19:39:47 +02:00
ostertun
5962e1cc90 RA-#29 Follow Sailors 2020-10-15 19:02:25 +02:00
ostertun
9f3019b4c5 Notification info banner 2020-10-15 15:19:04 +02:00
ostertun
326ba4a6bd Merge branch 'hotfix/fix_inputs_forcesync' 2020-10-15 14:04:06 +02:00
ostertun
4228ec739d Merge branch 'hotfix/fix_inputs_forcesync' into develop 2020-10-15 14:04:06 +02:00
ostertun
a38c48dab4 hotfix v_1.10.5h1 2020-10-15 14:03:55 +02:00
ostertun
da48e79a36 gitflow-hotfix-stash: fix_inputs_forcesync 2020-10-15 14:03:17 +02:00
ostertun
de5abcdfaf Merge branch 'release/v_1.10.5' 2020-10-14 14:18:03 +02:00
ostertun
6b1e35cc14 Merge branch 'release/v_1.10.5' into develop 2020-10-14 14:18:03 +02:00
ostertun
89e24f69b7 Release v_1.10.5 2020-10-14 14:17:40 +02:00
ostertun
554b810e85 Merge branch 'feature/RA-29-runtime-analysis' into develop 2020-10-14 14:16:39 +02:00
ostertun
fbd1eaaae8 Fix: hide loader on first visit 2020-10-14 13:44:34 +02:00
ostertun
ce42f87227 Cache if regatta has results 2020-10-14 13:37:47 +02:00
ostertun
e66f95ff50 Merge branch 'release/v_1.10.4' 2020-10-14 12:59:58 +02:00
ostertun
fcd791ed65 Merge branch 'release/v_1.10.4' into develop 2020-10-14 12:59:57 +02:00
ostertun
439679bbbe Release v_1.10.4 2020-10-14 12:59:35 +02:00
ostertun
9a8d6892f2 Merge branch 'feature/RA-29-runtime-analysis' into develop 2020-10-14 12:57:35 +02:00
ostertun
3b71f3d707 Better logging 2020-10-14 12:35:15 +02:00
ostertun
94c6a42106 RA-#29 remove unused code from scripts 2020-10-14 12:07:40 +02:00
ostertun
0c9eb9c013 RA-#27 back button on menu opened 2020-10-14 11:52:22 +02:00
ostertun
2034e8b659 RA-#24: dont show info after force resync 2020-10-14 11:24:36 +02:00
ostertun
e57bf4a426 RA-#25 Show loader after sync 2020-10-14 11:19:32 +02:00
ostertun
3c8289d11c index: Sort last regattas desc. 2020-10-14 11:08:27 +02:00
ostertun
63de725ebd Disable dark mode 2020-10-14 11:05:39 +02:00
ostertun
69efb93646 Merge branch 'hotfix/site_build_logging' 2020-10-11 17:01:23 +02:00
ostertun
6f302d6527 Merge branch 'hotfix/site_build_logging' into develop 2020-10-11 17:01:23 +02:00
ostertun
bfc2f84f0f Fix 2020-10-11 17:01:19 +02:00
ostertun
0660b2b6b3 Merge branch 'hotfix/site_build_logging' into develop 2020-10-11 16:57:55 +02:00
ostertun
3ee722f6c2 Merge branch 'hotfix/site_build_logging' 2020-10-11 16:57:17 +02:00
ostertun
0ce58aeacc Merge branch 'hotfix/site_build_logging' into develop 2020-10-11 16:57:17 +02:00
ostertun
28ba380cca gitflow-hotfix-stash: site_build_logging 2020-10-11 16:57:09 +02:00
ostertun
357449c1c6 Merge branch 'hotfix/update_subscription' 2020-10-09 12:59:35 +02:00
ostertun
e84eaa2562 Merge branch 'hotfix/update_subscription' into develop 2020-10-09 12:59:35 +02:00
ostertun
de70522850 gitflow-hotfix-stash: update_subscription 2020-10-09 12:59:20 +02:00
ostertun
cf5f71d14e Merge branch 'hotfix/hide_preloader_console_button' 2020-10-08 12:56:42 +02:00
ostertun
775a7bd27a Merge branch 'hotfix/hide_preloader_console_button' into develop 2020-10-08 12:56:41 +02:00
ostertun
34b47e40ab gitflow-hotfix-stash: hide_preloader_console_button 2020-10-08 12:56:19 +02:00
ostertun
32ea581437 Merge branch 'release/v_1.10.3' 2020-10-08 12:48:12 +02:00
ostertun
4106a177f8 Merge branch 'release/v_1.10.3' into develop 2020-10-08 12:48:11 +02:00
ostertun
16ccbca2af Release v_1.10.3 2020-10-08 12:47:53 +02:00
ostertun
3fd9beae1e Add last sync info 2020-10-06 00:21:23 +02:00
ostertun
01d0ae96f9 Fix no-db warning 2020-10-05 23:55:20 +02:00
ostertun
c211817f78 Added no-db warning 2020-10-05 23:52:09 +02:00
ostertun
9ff0b96837 Merge branch 'release/v_1.10.2' 2020-10-05 20:32:21 +02:00
ostertun
7a3413b339 Merge branch 'release/v_1.10.2' into develop 2020-10-05 20:32:21 +02:00
ostertun
72ff731694 Release v_1.10.2 2020-10-05 20:32:10 +02:00
ostertun
3959b208b5 Added go2url site 2020-10-05 20:19:57 +02:00
ostertun
7b500bf67d Merge branch 'release/v_1.10' 2020-10-05 17:45:03 +02:00
ostertun
5c8c9db1de Merge branch 'release/v_1.10' into develop 2020-10-05 17:45:02 +02:00
ostertun
fa526b11a8 Release v_1.10 2020-10-05 17:44:43 +02:00
ostertun
2dc2225263 Focus search input on show sailor selector 2020-10-05 17:38:00 +02:00
ostertun
fcf9dc9a20 Fixes 2020-10-05 17:35:10 +02:00
ostertun
203c2534eb Merge branch 'develop' into feature/RA-22-add-sites 2020-10-05 17:31:12 +02:00
ostertun
730dd9112f Add planning_edit 2020-10-05 17:19:24 +02:00
ostertun
54852f4383 Merge branch 'hotfix/regattas_range' into develop 2020-10-05 14:49:23 +02:00
ostertun
15cbe15651 Merge branch 'hotfix/fix_db_sync_log' into develop 2020-10-05 14:35:21 +02:00
ostertun
be98511957 Merge branch 'release/v_1.9' into develop 2020-10-05 13:59:22 +02:00
48 changed files with 4063 additions and 2054 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ server/config.php
api/config.php
.htaccess
!.keepfolder
.idea

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

View File

@@ -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()));

View File

@@ -1155,6 +1155,8 @@ var mobileConsole = (function () {
if (!msgContainer.innerHTML) { return; }
leftContainer.appendChild(msgContainer);
var errorReportEntry = { message: arguments[1].newMessage };
if (detailTable || stackTable) {
setCSS(msgContainer, {cursor : 'pointer'});
leftContainer.appendChild(detailTable || stackTable);
@@ -1164,8 +1166,18 @@ var mobileConsole = (function () {
//populate right side
if (stackTrace && typeof stackTrace[stackTrace.length - 1] !== 'undefined') {
rightContainer.appendChild(setCSS(getLink(stackTrace[0].url, stackTrace[0].linkText), {color: '#808080'}));
errorReportEntry.stack = { caller: stackTrace[0].caller, file: stackTrace[0].url, line: stackTrace[0].line, col: stackTrace[0].col };
if ((typeof LINK_PRE !== 'undefined') && (errorReportEntry.stack.file.startsWith(LINK_PRE))) {
errorReportEntry.stack.file = errorReportEntry.stack.file.substr(LINK_PRE.length);
}
var pos = errorReportEntry.stack.file.indexOf('?');
if (pos >= 0) {
errorReportEntry.stack.file = errorReportEntry.stack.file.substr(0, pos);
}
}
if (typeof onConsoleOutput === 'function') onConsoleOutput(errorReportEntry);
//add to line
lineContainer.appendChild(leftContainer);
lineContainer.appendChild(rightContainer);

View File

@@ -20,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);
@@ -35,7 +33,7 @@ $(document).ready(function(){
//Enabling dismiss button
setTimeout(function(){
$('.pwa-dismiss').on('click',function(){
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');
});
@@ -52,10 +50,10 @@ $(document).ready(function(){
//Firing PWA prompts for specific versions and when not on home screen.
if (isMobile.Android()) {
log('Android Detected');
log('[pwa] Android Detected');
function showInstallPromotion(){
if($('#menu-install-pwa-android, .add-to-home').length){
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');
@@ -80,9 +78,9 @@ $(document).ready(function(){
deferredPrompt.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
log('User accepted the A2HS prompt');
log('[pwa] User accepted the A2HS prompt');
} else {
log('User dismissed the A2HS prompt');
log('[pwa] User dismissed the A2HS prompt');
}
deferredPrompt = null;
});
@@ -94,114 +92,32 @@ $(document).ready(function(){
if (isMobile.iOS()) {
if(!isInWebAppiOS){
log('iOS Detected');
log('[pwa] iOS Detected');
if($('#menu-install-pwa-ios, .add-to-home').length){
if (!readCookie('Sticky_pwa_rejected_install')) {
function triggerPwaInstallIos() {
log('Triggering PWA / Add to Home Screen Menu for iOS');
setTimeout(function(){
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');
},3000);
}
var welcomActive = $('#menu-welcome').hasClass('menu-active');
if (welcomActive) {
$('#menu-welcome-a-okay').click(triggerPwaInstallIos);
} else {
triggerPwaInstallIos();
}
}
var welcomActive = $('#menu-welcome').hasClass('menu-active');
if (welcomActive) {
$('#menu-welcome-a-okay').click(triggerPwaInstallIos);
} else {
triggerPwaInstallIos();
}
},3000);
};
}
}
}
//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--;
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() {
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();
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');
@@ -224,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();
log( 'Connection: Online');
$("a").off( "click", returnFalse );
log('[pwa] Connection: Online');
}
function updateOfflineStatus(event) {
isOffline();
$("a").on( "click", returnFalse );
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);
});
});
}
});

View File

@@ -3,16 +3,42 @@
header('Content-Type: text/javascript');
require_once(__DIR__ . '/../../server/config.php');
require_once(__DIR__ . '/../../server/version.php');
// QUERY_URL changed in config.php (this is to update this file on client devices)
?>
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();
@@ -36,7 +62,11 @@ var badges = {
news: {
id: 'badge-more-news',
cnt: 0
}
},
expenditures: {
id: 'badge-more-expenditures',
cnt: 0
}
}
}
};
@@ -132,6 +162,7 @@ function findGetParameter(parameterName) {
}
var login = function() {
log('[app] Login');
showLoader();
var username = $('#input-login-username').val();
var password = $('#input-login-password').val();
@@ -146,6 +177,7 @@ 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).trigger('focusin').trigger('focusout');
@@ -153,13 +185,14 @@ var login = function() {
toastError('Du bist momentan offline.<br>Stelle eine Internetverbindung her, um Dich anzumelden');
$('#menu-login').hideMenu();
} else {
log('Login: unbekannter Fehler', status, error);
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);
@@ -180,13 +213,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)) {
log('Not logged in');
log('[app] Not logged in');
logoutClearStorage();
return;
}
@@ -197,57 +231,62 @@ var logout = function() {
auth: auth
},
error: function (xhr, status, error) {
log('[app] Logout: error:', xhr.status, status);
if (xhr.status == 401) {
log('Not logged in');
log('[app] Not logged in');
logoutClearStorage();
} else if (xhr.status == 0) {
log('Could not delete auth from server');
log('[app] Could not delete auth from server');
logoutClearStorage();
} else {
log('Logout: unbekannter Fehler', status, error);
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 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('Cannot delete DB: ', event.target.errorCode);
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('DB deleted');
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) {
log('Unregister sW:', registration);
log('[app] Unregister sW:', registration);
registration.unregister();
}
});
caches.keys().then((keyList) => {
return Promise.all(keyList.map((key) => {
log('Cache deleted:', key);
log('[app] Cache deleted:', key);
return caches.delete(key);
}));
});
@@ -273,38 +312,59 @@ function urlB64ToUint8Array(base64String) {
}
function pushesSubscribe() {
log('Subscribing');
log('[app] Subscribing');
const applicationServerKey = urlB64ToUint8Array(PUSH_SERVER_KEY);
log('[app] Subscription app server key:', applicationServerKey);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(function(subscription) {
pushesUpdateServerSubscription(subscription, true);
updatePushSwitches();
updatePushBadge();
.then(async function(subscription) {
log('[app] Subscription:', JSON.stringify(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) {
log('Failed to subscribe the user: ', 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('Unsubscribing');
log('[app] Unsubscribing');
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
.then(async function(subscription) {
log('[app] Subscription:', JSON.stringify(subscription));
if (subscription) {
pushesUpdateServerSubscription(subscription, false);
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('Error unsubscribing', 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();
@@ -313,20 +373,21 @@ function pushesUnSubscribe(silent = false) {
}
function pushesUpdateServerSubscription(subscription, enabled) {
log('updateServer', enabled, subscription);
$.ajax({
url: QUERY_URL + (enabled ? 'add' : 'remove') + '_subscription',
type: 'POST',
data: { subscription: JSON.stringify(subscription) },
success: function (data, textStatus, jqXHR) {
if (!enabled) {
toastOk('Du erhältst ab sofort keine Benachrichtigungen mehr von uns.');
return new Promise(function(resolve){
log('[app] updateServer', enabled, JSON.stringify(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);
}
hideLoader();
},
error: function (jqXHR, textStatus, errorThrown) {
throw 'Cannot update server subscription';
}
});
});
}
@@ -406,17 +467,35 @@ function pushesOpenMenu() {
}
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(function(subscription) {
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:', JSON.stringify(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();
}
}
}
});
}
@@ -429,7 +508,7 @@ async function updateNewsBadge() {
var sum = 0;
for (var n in news) {
var newsEntry = news[n];
newsEntry.date = new Date(Date.parse(newsEntry.date));
newsEntry.date = parseDbTimestamp(newsEntry.date);
if (newsEntry.date > now) continue;
if (newsEntry.date < newsRead) continue;
sum ++;
@@ -437,11 +516,33 @@ async function updateNewsBadge() {
updateBadge('more/news', sum);
}
async function updateExpendituresBadge() {
let allExps = await dbGetData('expenditures');
let sum = 0;
for (let i in allExps) {
let exp = allExps[i];
if (exp.approved == 0) {
if (exp.direction < 0 && exp.canceled == 0) sum++;
if (exp.direction > 0 && exp.canceled == 1) sum++;
}
}
updateBadge('more/expenditures', sum);
}
function updateBadges() {
updateNewsBadge();
updateExpendituresBadge();
}
var initRegatten = function() {
showLoader();
log('[app] Initializing DB...');
initDatabase();
log('[app] Loading app specific code...');
if (isLoggedIn()) {
$('.show-loggedin').show();
$('.show-notloggedin').hide();
@@ -461,7 +562,8 @@ var initRegatten = function() {
}
var onServiceWorkerLoaded = function() {
if ((swRegistration !== null) && canUseLocalDB) {
log('[app] sW loaded');
if ((swRegistration !== null) && (swRegistration.pushManager) && canUseLocalDB) {
pushesPossible = true;
updatePushBadge();
} else {
@@ -470,14 +572,53 @@ var onServiceWorkerLoaded = function() {
}
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();
updateBadges();
}
var onAfterSync = function() {
updateNewsBadge();
updateBadges();
}
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: JSON.stringify(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
@@ -485,19 +626,52 @@ 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 btn-full rounded-s text-uppercase font-900 shadow-m bg-highlight m-3';
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 = 'Show Console';
button.innerHTML = 'Fehlerbericht senden';
button.onclick = function(){
mobileConsole.displayConsole();
sendErrorReport();
return false;
}
setTimeout(function(){
preloader.appendChild(button);
}, 5000);
preloader.appendChild(button);
$(button).hide();
}
addConsoleOpenerToPreloader();
function m2s_getLink(type, eventId, classId) {
switch (type) {
case 'entrylist':
return 'https://manage2sail.com/de-DE/event/' + eventId + '#!/entries?classId=' + classId;
}
return '';
}
function ro_getLink(type, eventId, classId) {
switch (type) {
case 'entrylist':
return 'http://www.raceoffice.org/entrylist.php?eid=' + eventId;
}
return '';
}
function wfn_getLink(type, eventId, classId) {
switch (type) {
case 'entrylist':
return 'https://wettfahrten.net/event/' + eventId + '/entrylist?class=' + classId;
}
return '';
}
function extServiceGetLink(serviceName, type, eventId = '', classId = '') {
switch (serviceName) {
case 'm2s':
return m2s_getLink(type, eventId, classId);
case 'ro':
return ro_getLink(type, eventId, classId);
case 'wfn':
return wfn_getLink(type, eventId, classId);
}
return '';
}

View File

@@ -144,6 +144,72 @@
text-align: right;
}
/*** EXPENDITURES LIST ***/
.expenditures-list.display-border > div {
border-bottom: 1px solid #dee2e6;
}
.expenditures-list > div {
padding-top: 1rem;
padding-bottom: 1rem;
cursor: pointer;
}
.expenditures-list > div:last-child {
border: 0;
padding-bottom: 0;
}
.expenditures-list div {
white-space: nowrap;
}
.expenditures-list > div > div > div {
display: inline-block;
}
.expenditures-list > div > div:nth-child(1) > div:nth-child(1) {
width: calc(75% - 1.5em);
}
.expenditures-list > div > div:nth-child(1) > div:nth-child(2) {
width: 25%;
text-align: right;
}
.expenditures-list > div > div:nth-child(1) > div:nth-child(3) {
width: 1.5em;
text-align: right;
}
.expenditures-list > div > div:nth-child(2) > div:nth-child(1) {
width: 6em;
}
.expenditures-list > div > div:nth-child(2) > div:nth-child(2) {
width: calc(70% - 6em);
overflow-x: visible;
}
.expenditures-list > div > div:nth-child(2) > div:nth-child(3) {
width: 30%;
text-align: right;
}
.expenditures-list > div.sum {
padding: 0;
}
.expenditures-list > div.sum > div:nth-child(1) {
background: #dee2e6;
height: 1px;
display: flex;
justify-content: center;
}
.expenditures-list > div.sum > div:nth-child(1) > div:nth-child(1) {
background: #fff;
width: initial;
margin-top: -1em;
padding: 0 .5em;
}
.theme-dark .expenditures-list > div.sum > div:nth-child(1) > div:nth-child(1) {
background-color: #0f1117;
}
/*** NORMAL LIST ***/
.normal-list > div {
padding-top: 1rem;

View File

@@ -2,7 +2,7 @@
$sp['title'] = 'Boote - Regatten.net ' . $_CLASS['name'];
$sp['backbutton'] = 'index';
$sp['activenav'] = 4;
$sp['activenav'] = 5;
// Title
$content = "<h1>Boote</h1>";

View File

@@ -2,7 +2,7 @@
$sp['title'] = 'Vereine - Regatten.net ' . $_CLASS['name'];
$sp['backbutton'] = 'index';
$sp['activenav'] = 4;
$sp['activenav'] = 5;
// Title
$content = "<h1>Vereine</h1>";

View File

@@ -15,11 +15,11 @@
$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&ouml;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 .= '<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>';
$sp['output'] .= $tpl->load('card', [$content]);

View File

@@ -0,0 +1,80 @@
<?php
$sp['title'] = 'Ausgaben-Verwaltung - Regatten.net ' . $_CLASS['name'];
$sp['backbutton'] = 'expenditures';
$sp['activenav'] = 5;
// Title
$content = "<h1>Ausgaben-Verwaltung</h1>";
$content .= '<p id="p-username" class="mb-1"></p>';
$content .= $tpl->load('button', ['<i class="fas fa-plus"></i>&ensp;Neue Ausgabe', '#', 'html-id' => 'button-add', 'css-class' => 'mt-3 mb-2']);
$content .= $tpl->load('button', ['<i class="fas fa-plus"></i>&ensp;Neuer Geldtransfer', '#', 'html-id' => 'button-add-transfer', 'css-class' => 'mt-3 mb-0']);
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-loggedin']);
// Not loggedin
$content = '<h1>Ausgaben-Verwaltung</h1>';
$content .= '<p>Um die Ausgaben-Verwaltung nutzen zu können, musst Du angemeldet sein.<br><a href="#" data-menu="menu-login">Melde Dich hier an</a> oder <a href="https://regatten.net/#signup">registriere Dich jetzt kostenlos</a>.</p>';
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-notloggedin']);
// List
$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-list" class="expenditures-list mb-0"></div>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-list', 'css-class' => 'show-loggedin']);
// Pagination
$sp['output'] .= $tpl->load('pagination', ['html-id' => 'pagination', 'css-class' => 'show-loggedin']);
// Legend
$content = '<p>';
$content .= '<i class="fas fa-check"></i>&ensp;genehmigt<br>';
$content .= '<i class="fas fa-times"></i>&ensp;storniert<br>';
$content .= '<i class="fas fa-hourglass-half"></i>&ensp;wartet auf Zustimmung von <span class="span-username"></span><br>';
$content .= '<i class="fas fa-exclamation"></i>&ensp;wartet auf Deine Zustimmung';
$content .= '</p>';
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-loggedin']);
// Menu
$items = $tpl->load('menu/item-icon', ['Akzeptieren', '#', 'html-id' => 'menu-item-approve', 'icon' => 'fa-check']);
$items .= $tpl->load('menu/item-icon', ['Ablehnen', '#', 'html-id' => 'menu-item-decline', 'icon' => 'fa-times']);
$items .= $tpl->load('menu/item-icon', ['Stornieren', '#', 'html-id' => 'menu-item-cancel', 'icon' => 'fa-times']);
$sp['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-expenditure', 'title' => 'Ausgabe', 'height' => 200]);
// Menu Add
$items = $tpl->load('menu/item-simple', ['bezahlt von: ', '#', 'html-id' => 'item-add-user-from']);
$items .= $tpl->load('input', ['html-id' => 'input-add-date', 'placeholder' => 'Datum des Transfers', 'type' => 'date', 'css-class' => 'mt-3']);
$items .= $tpl->load('input', ['html-id' => 'input-add-amount', 'placeholder' => 'Betrag in Euro', 'type' => 'number" min="0.01" step="0.01']);
$options = '<option value="entryfee">Meldegeld</option>';
$options .= '<option value="camping">Camping</option>';
$options .= '<option value="food">Essen</option>';
$options .= '<option value="other">andere</option>';
$items .= $tpl->load('select', ['html-id' => 'select-add-purpose', 'placeholder' => 'Verwendung', 'options' => $options]);
$items .= $tpl->load('input', ['html-id' => 'input-add-regatta-name', 'placeholder' => 'Name der Regatta (optional)', 'type' => 'text']);
$items .= $tpl->load('input', ['html-id' => 'input-add-purpose-text', 'placeholder' => 'Verwendungszweck (optional)', 'type' => 'text']);
$items .= '<p style="line-height: normal; margin-bottom: 0;">Für wen wurde das Geld ausgegeben? (z.B. Du und Dein Segelpartner)<br>Hinweis: Der angegebene Betrag wird durch die Personen geteilt, die Du hier auswählst.</p>';
$items .= $tpl->load('menu/item-simple', ['<span style="font-style:italic;">Weiteren Benutzer hinzuf&uuml;gen</span>', '#', 'html-id' => 'item-add-user-to']);
$items .= $tpl->load('button', ['Speichern', '#', 'html-id' => 'button-add-save', 'css-class' => 'mb-3']);
$sp['menus'] .= $tpl->load('menu/modal', [$items, 'html-id' => 'menu-add', 'title' => 'Neue Ausgabe', 'height' => '90vh', 'width' => '90vw']);
// Menu Add Transfer
$items = $tpl->load('menu/item-switch', ['Geld bekommen', 'html-id' => 'switch-add-transfer-received', 'icon' => 'fa-arrow-left']);
$items .= $tpl->load('menu/item-simple', ['von: <font style="font-style:italic;">bitte auswählen</font>', '#', 'html-id' => 'item-add-transfer-user']);
$items .= $tpl->load('input', ['html-id' => 'input-add-transfer-date', 'placeholder' => 'Datum des Transfers', 'type' => 'date', 'css-class' => 'mt-3']);
$items .= $tpl->load('input', ['html-id' => 'input-add-transfer-amount', 'placeholder' => 'Betrag in Euro', 'type' => 'number" min="0.01" step="0.01']);
$items .= $tpl->load('input', ['html-id' => 'input-add-transfer-purpose-text', 'placeholder' => 'Verwendungszweck (optional)', 'type' => 'text']);
$items .= $tpl->load('button', ['Speichern', '#', 'html-id' => 'button-add-transfer-save']);
$sp['menus'] .= $tpl->load('menu/modal', [$items, 'html-id' => 'menu-add-transfer', 'title' => 'Neuer Geldtransfer', 'height' => 470, 'width' => '90vw']);
// Select user
$items = $tpl->load('input', ['html-id' => 'input-user-search', 'placeholder' => 'Suche...', 'type' => 'text']);
$sp['menus'] .= $tpl->load('menu/modal', [$items, 'html-id' => 'menu-select-user', 'title' => 'Benutzer auswählen', 'height' => 500, 'width' => '90vw']);
$sp['scripts'] .= $scripts->load('pagination', ['pageChange', 'page', 'pageCount', 'pagination']);
$sp['scripts'] .= $scripts->load('expenditures-add');
$sp['scripts'] .= $scripts->load('expenditures-user');
?>

View File

@@ -0,0 +1,63 @@
<?php
$sp['title'] = 'Ausgaben-Verwaltung - Regatten.net ' . $_CLASS['name'];
$sp['backbutton'] = 'index';
$sp['activenav'] = 5;
// Title
$content = "<h1>Ausgaben-Verwaltung</h1>";
$content .= $tpl->load('button', ['<i class="fas fa-plus"></i>&ensp;Neue Ausgabe', '#', 'html-id' => 'button-add', 'css-class' => 'mt-3 mb-2']);
$content .= $tpl->load('button', ['<i class="fas fa-plus"></i>&ensp;Neuer Geldtransfer', '#', 'html-id' => 'button-add-transfer', 'css-class' => 'mt-3 mb-0']);
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-loggedin']);
// Not loggedin
$content = '<h1>Ausgaben-Verwaltung</h1>';
$content .= '<p>Um die Ausgaben-Verwaltung nutzen zu können, musst Du angemeldet sein.<br><a href="#" data-menu="menu-login">Melde Dich hier an</a> oder <a href="https://regatten.net/#signup">registriere Dich jetzt kostenlos</a>.</p>';
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-notloggedin']);
// List
$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-list" class="normal-list mb-0"></div>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-list', 'css-class' => 'show-loggedin']);
// Pagination
$sp['output'] .= $tpl->load('pagination', ['html-id' => 'pagination', 'css-class' => 'show-loggedin']);
// Menu Add
$items = $tpl->load('menu/item-simple', ['bezahlt von: ', '#', 'html-id' => 'item-add-user-from']);
$items .= $tpl->load('input', ['html-id' => 'input-add-date', 'placeholder' => 'Datum des Transfers', 'type' => 'date', 'css-class' => 'mt-3']);
$items .= $tpl->load('input', ['html-id' => 'input-add-amount', 'placeholder' => 'Betrag in Euro', 'type' => 'number" min="0.01" step="0.01']);
$options = '<option value="entryfee">Meldegeld</option>';
$options .= '<option value="camping">Camping</option>';
$options .= '<option value="food">Essen</option>';
$options .= '<option value="other">andere</option>';
$items .= $tpl->load('select', ['html-id' => 'select-add-purpose', 'placeholder' => 'Verwendung', 'options' => $options]);
$items .= $tpl->load('input', ['html-id' => 'input-add-regatta-name', 'placeholder' => 'Name der Regatta (optional)', 'type' => 'text']);
$items .= $tpl->load('input', ['html-id' => 'input-add-purpose-text', 'placeholder' => 'Verwendungszweck (optional)', 'type' => 'text']);
$items .= '<p style="line-height: normal; margin-bottom: 0;">Für wen wurde das Geld ausgegeben? (z.B. Du und Dein Segelpartner)<br>Hinweis: Der angegebene Betrag wird durch die Personen geteilt, die Du hier auswählst.</p>';
$items .= $tpl->load('menu/item-simple', ['<span style="font-style:italic;">Weiteren Benutzer hinzuf&uuml;gen</span>', '#', 'html-id' => 'item-add-user-to']);
$items .= $tpl->load('button', ['Speichern', '#', 'html-id' => 'button-add-save', 'css-class' => 'mb-3']);
$sp['menus'] .= $tpl->load('menu/modal', [$items, 'html-id' => 'menu-add', 'title' => 'Neue Ausgabe', 'height' => '90vh', 'width' => '90vw']);
// Menu Add Transfer
$items = $tpl->load('menu/item-switch', ['Geld bekommen', 'html-id' => 'switch-add-transfer-received', 'icon' => 'fa-arrow-left']);
$items .= $tpl->load('menu/item-simple', ['von: <font style="font-style:italic;">bitte auswählen</font>', '#', 'html-id' => 'item-add-transfer-user']);
$items .= $tpl->load('input', ['html-id' => 'input-add-transfer-date', 'placeholder' => 'Datum des Transfers', 'type' => 'date', 'css-class' => 'mt-3']);
$items .= $tpl->load('input', ['html-id' => 'input-add-transfer-amount', 'placeholder' => 'Betrag in Euro', 'type' => 'number" min="0.01" step="0.01']);
$items .= $tpl->load('input', ['html-id' => 'input-add-transfer-purpose-text', 'placeholder' => 'Verwendungszweck (optional)', 'type' => 'text']);
$items .= $tpl->load('button', ['Speichern', '#', 'html-id' => 'button-add-transfer-save']);
$sp['menus'] .= $tpl->load('menu/modal', [$items, 'html-id' => 'menu-add-transfer', 'title' => 'Neuer Geldtransfer', 'height' => 470, 'width' => '90vw']);
// Select user
$items = $tpl->load('input', ['html-id' => 'input-user-search', 'placeholder' => 'Suche...', 'type' => 'text']);
$sp['menus'] .= $tpl->load('menu/modal', [$items, 'html-id' => 'menu-select-user', 'title' => 'Benutzer auswählen', 'height' => 500, 'width' => '90vw']);
$sp['scripts'] .= $scripts->load('pagination', ['pageChange', 'page', 'pageCount', 'pagination']);
$sp['scripts'] .= $scripts->load('expenditures-add');
$sp['scripts'] .= $scripts->load('expenditures');
?>

13
server/content/go2url.php Normal file
View 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&uuml;rze zur gew&uuml;nschten Website weiter</p>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-title']);
$sp['scripts'] .= $scripts->load('go2url');
?>

View File

@@ -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&auml;hle bis zu f&uuml;nf Segler aus.';
@@ -33,11 +32,23 @@
$content = '<h2>Nicht angemeldet</h2>';
$content .= '<p class="mt-3">';
$content .= 'Um alle Funktionen dieser Seite nutzen zu k&ouml;nnen, <a href="#" data-menu="menu-login">logge Dich bitte ein</a>.<br>';
$content .= 'Solltest Du noch kein Benutzerkonto haben, kannst Du Dich kostenlos <a href="#" data-menu="menu-signup">registrieren</a>.';
$content .= 'Solltest Du noch kein Benutzerkonto haben, kannst Du Dich kostenlos <a href="https://regatten.net/#signup">registrieren</a>.';
$content .= '</p>';
$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 &uuml;ber alle &Auml;nderungen.<br>';
$content .= 'Du bestimmst nat&uuml;rlich, welche Benachrichtigungen Du bekommen m&ouml;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&auml;ter</a></p>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-notifications', 'css-class' => 'bg-blue2-dark']);
// Next
$content = '<h2>N&auml;chste Regatten</h2>';
$content .= '<div id="div-next" class="regattas-list mb-0"></div>';
@@ -61,23 +72,30 @@
$content .= '<p>Du willst alle Regatta-Termine in deinem Kalender, aber nicht alles abtippen?<br>Kein Problem! Abonniere einfach unseren ics-Kalender.</p>';
$content .= '<p><b>Nur die Regatten, zu denen Du gehst?</b><br>Auch kein Problem! ';
$content .= '<font class="show-loggedin">Erstelle einfach eine <a href="' . LINK_PRE . 'planning">Saison-Planung</a> und abonniere Deinen persönlichen Kalender.</font>';
$content .= '<font class="show-notloggedin"><a href="#" data-menu="menu-signup">Registriere Dich einfach kostenlos</a>, erstelle eine Saison-Planung und wir erstellen Dir einen pers&ouml;nlichen Kalender.</font>';
$content .= '<font class="show-notloggedin"><a href="https://regatten.net/#signup">Registriere Dich einfach kostenlos</a>, erstelle eine Saison-Planung und wir erstellen Dir einen pers&ouml;nlichen Kalender.</font>';
$content .= '</p>';
$content .= $tpl->load('button', ['<i class="fas fa-calendar-alt"></i> Regatta-Kalender', 'https://regatten.net/client/calendar/' . BOATCLASS . '/everything.ics', 'css-class' => 'mb-2']);
$content .= $tpl->load('button', ['<i class="fas fa-calendar-alt"></i> Kalender f&uuml;r <font class="replace-username"></font>', 'https://regatten.net/client/calendar/' . BOATCLASS . '/user_%USERID%.ics', 'css-class' => 'show-loggedin replace-userid-href']);
$content .= $tpl->load('button', ['<i class="fas fa-calendar-alt"></i> Regatta-Kalender', 'https://ranglisten.net/client/calendar/' . BOATCLASS . '/everything.ics', 'css-class' => 'mb-2']);
$content .= $tpl->load('button', ['<i class="fas fa-calendar-alt"></i> Kalender f&uuml;r <font class="replace-username"></font>', 'https://ranglisten.net/client/calendar/' . BOATCLASS . '/user_%USERID%.ics', 'css-class' => 'show-loggedin replace-userid-href']);
$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', ['Fakten', '', 'html-id' => 'menu-item-facts', 'icon' => 'fa-list']);
$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['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-regatta', 'title' => 'Regatta-Details', 'height' => 400]);
// 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');

View File

@@ -2,19 +2,20 @@
$sp['title'] = 'Saison-Planung - Regatten.net ' . $_CLASS['name'];
$sp['backbutton'] = 'index';
$sp['activenav'] = 5;
$sp['activenav'] = 4;
// Title
$content = '<h1>Saison-Planung</h1>';
$content .= $tpl->load('button', ['<i class="fas fa-list"></i>&ensp;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>&ensp;bearbeiten', LINK_PRE . 'planning_edit']);
$content .= $tpl->load('button', ['<i class="fas fa-edit"></i>&ensp;bearbeiten', 'html-id' => 'a-edit-planning']);
$content .= $tpl->load('select', ['html-id' => 'select-year', 'placeholder' => 'Jahr', 'css-class' => 'mt-3 mb-0']);
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-loggedin']);
// 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>';
$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="https://regatten.net/#signup">registriere Dich jetzt kostenlos</a>.</p>';
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-notloggedin']);
@@ -26,16 +27,19 @@
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-regattas', 'css-class' => 'show-loggedin']);
// Menu
$items = '<p id="menu-item-yourplanning" class="mb-2 mt-1" style="line-height: 1.5em;"></p>';
$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', ['Saison-Planungen', '', 'html-id' => 'menu-item-plannings', 'icon' => 'fa-calendar-alt']);
$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', ['Fakten', '', 'html-id' => 'menu-item-facts', 'icon' => 'fa-list']);
$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['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-regatta', 'title' => 'Regatta-Details', 'height' => 400]);
// Menu Edit status
$items = $tpl->load('menu/item-switch', ['Gemeldet', 'html-id' => 'switch-status-gemeldet', 'icon' => 'fa-file-signature']);

View File

@@ -1,21 +1,36 @@
<?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'] = 4;
$content = $tpl->load('error', ['404', 'Seite existiert noch nicht']);
$content .= '<p>';
$content .= 'Du kannst die Saison-Planung momentan leider noch nicht in der App bearbeiten.<br>';
$content .= 'Bis diese Funktion implementiert wurde, erstelle Deine Saison-Planung bitte auf <a target="_blank" href="https://regatten.net/' . BOATCLASS . '/planning_edit">unserer Website</a>.<br>';
$content .= 'Deine Saison-Planung wird dann automatisch synchronisiert und ist dann auch in dieser App verf&uuml;gbar.<br>';
$content .= 'Wir arbeiten daran, dass Du Deine Saison-Planung bald auch in der App bearbeiten kannst.<br>';
$content .= '</p>';
$content .= $tpl->load('button', ['Zur Website', 'https://regatten.net/' . BOATCLASS, 'css-class' => 'mb-3']);
$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-boat']);
$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' => 400]);
// Select boat
$items = $tpl->load('input', ['html-id' => 'input-edit-boat-search', 'placeholder' => 'Suche', 'type' => 'text']);
$sp['menus'] .= $tpl->load('menu/modal', [$items, 'html-id' => 'menu-boat', 'height' => 500, 'width' => 350]);
// 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');
?>

View File

@@ -1,8 +1,8 @@
<?php
$sp['title'] = 'Saison-Planungen - Regatten.net ' . $_CLASS['name'];
$sp['backbutton'] = 'planning';
$sp['activenav'] = 5;
$sp['backbutton'] = true;
$sp['activenav'] = 4;
// Title
$content = '<h1>Saison-Planungen</h1>';
@@ -12,7 +12,7 @@
// 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>';
$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="https://regatten.net/#signup">registriere Dich jetzt kostenlos</a>.</p>';
$sp['output'] .= $tpl->load('card', [$content, 'css-class' => 'show-notloggedin']);

View File

@@ -1,8 +1,8 @@
<?php
$sp['title'] = 'Saison-Planung - Regatten.net ' . $_CLASS['name'];
$sp['backbutton'] = 'planning_list';
$sp['activenav'] = 5;
$sp['backbutton'] = true;
$sp['activenav'] = 4;
// Title
$content = '<h1>Saison-Planung</h1>';
@@ -20,15 +20,18 @@
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-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', ['Fakten', '', 'html-id' => 'menu-item-facts', 'icon' => 'fa-list']);
$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['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-regatta', 'title' => 'Regatta-Details', 'height' => 400]);
$sp['scripts'] .= $scripts->load('onRegattaClicked');
$sp['scripts'] .= $scripts->load('planning_view');

View File

@@ -7,22 +7,22 @@
// Title, Inputs
$content = "<h1>Ranglisten</h1>";
$options = '<option value="year">Jahres-Rangliste</option>';
$options .= '<option value="youth">Jugend-Rangliste</option>';
$options .= '<option value="idjm">' . $_CLASS['youth-german-name'] . '-Rangliste</option>';
$options .= '<option value="user">Benutzerdefiniert</option>';
$content .= $tpl->load('select', ['html-id' => 'select-type', 'placeholder' => 'Rangliste', 'options' => $options, 'css-class' => 'mt-3 mb-0']);
$content .= $tpl->load('select', ['html-id' => 'select-year', 'placeholder' => 'Jahr', 'css-class' => 'mt-3 mb-0']);
$content .= $tpl->load('select', ['html-id' => 'select-type', 'placeholder' => 'Rangliste', 'css-class' => 'mt-3 mb-0']);
$content .= $tpl->load('input', ['html-id' => 'input-from', 'placeholder' => 'Von', 'type' => 'date', 'css-class' => 'mt-3']);
$content .= $tpl->load('input', ['html-id' => 'input-to', 'placeholder' => 'Bis', 'type' => 'date']);
$chbox = $tpl->load('checkbox', ['html-id' => 'input-jugend', 'placeholder' => 'Jugend']);
$content .= '<div class="mb-3" style="display:inline-block; width:50%;">' . $chbox . '</div>';
$chbox = $tpl->load('checkbox', ['html-id' => 'input-jugstrict', 'placeholder' => 'Streng']);
$content .= '<div class="mb-3" style="display:inline-block; width:50%;">' . $chbox . '</div>';
$content .= $tpl->load('button', ['Anzeigen', '#', 'html-id' => 'button-show']);
$content .= $tpl->load('input', ['html-id' => 'input-altm', 'placeholder' => 'alt. m', 'type' => 'number']);
$content .= $tpl->load('input', ['html-id' => 'input-maxage', 'placeholder' => 'max. Alter (leer = nicht prüfen)', 'type' => 'number']);
$content .= $tpl->load('checkbox', ['html-id' => 'input-agestrict', 'placeholder' => 'unb. Jahrgänge ausschließen']);
$content .= $tpl->load('checkbox', ['html-id' => 'input-agecrew', 'placeholder' => 'Crew auch prüfen']);
$content .= $tpl->load('select', ['html-id' => 'select-personmode', 'placeholder' => 'nach', 'css-class' => 'mt-3 mb-0']);
$content .= $tpl->load('button', ['Anzeigen', '#', 'html-id' => 'button-show', 'css-class' => 'mt-3']);
$sp['output'] .= $tpl->load('card', [$content]);
// Sepcial ranks
$sp['output'] .= $tpl->load('card', ['', 'html-id' => 'card-special-ranks']);
// No Results
$content = '<h2 class="color-white">ACHTUNG</h2>';
$content .= '<p class="color-white">Zu folgenden Regatten wurden noch keine Ergebnisse hinterlegt:</p>';

View File

@@ -0,0 +1,49 @@
<?php
$sp['title'] = 'Fakten - Regatten.net ' . $_CLASS['name'];
$sp['backbutton'] = true;
$sp['activenav'] = 2;
// Title, Inputs
$content = '<h1 id="h1-title"></h1>';
$content .= '<p id="p-title"></p>';
$sp['output'] .= $tpl->load('card', [$content]);
// NO FACTS INFO
$content = '<p>Es sind keine Fakten zu dieser Veranstaltung hinterlegt. Bitte lies die Ausschreibung.</p>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-nofactsinfo']);
// Meldegeld
$content = '<h2>Meldegeld</h2>';
$content .= '<p></p>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-entryfee']);
// Wettfahrten
$content = '<h2>Wettfahrten</h2>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-races']);
// Zeitplan
$content = '<h2>Zeitplan</h2>';
$content .= $tpl->load('table', ['css-class' => 'mb-0 text-nowrap']);
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-times']);
// Camping
$content = '<h2>Camping</h2>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-camping']);
// Verpflegung
$content = '<h2>Verpflegung</h2>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-food']);
// Weitere Infos
$content = '<h2>Weitere Informationen</h2><p></p>';
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-text']);
// Disclaimer
$content = '<p><i>Alle Angaben ohne Gewähr. Änderungen vorbehalten. Am Ende gilt, was in der Ausschreibung / Segelanweisung steht!</i></p>';
$sp['output'] .= $tpl->load('card', [$content]);
$sp['scripts'] .= $scripts->load('regatta_facts');
?>

View File

@@ -12,7 +12,7 @@
// Plannings
$content = '<p id="p-info" class="mb-0"></p>';
$thead = '<tr><th>Benutzer</th><th>Steuermann/-frau</th><th>Crew</th></tr>';
$thead = '<tr><th>Benutzer</th><th>Boot</th><th>Steuermann/-frau</th><th>Crew</th></tr>';
$content .= $tpl->load('table', [$thead, 'html-id' => 'table-plannings', 'css-class' => 'mb-0 text-nowrap']);
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-plannings']);
@@ -21,7 +21,7 @@
$content = '<p>Du planst, hier hinzufahren, aber stehst nicht auf dieser Liste?<br>';
$content .= 'Das kannst Du &auml;ndern! ';
$content .= '<font class="show-loggedin">Erstelle einfach <a href="' . LINK_PRE . 'planning">hier</a> Deine eigene Saison-Planung.</font>';
$content .= '<font class="show-notloggedin"><a href="#" data-menu="menu-login">Melde Dich an</a> oder <a href="#" data-menu="menu-signup">registriere Dich kostenlos</a> und erstelle Deine eigene Saison-Planung.</font>';
$content .= '<font class="show-notloggedin"><a href="#" data-menu="menu-login">Melde Dich an</a> oder <a href="https://regatten.net/#signup">registriere Dich kostenlos</a> und erstelle Deine eigene Saison-Planung.</font>';
$content .= '</p>';
$sp['output'] .= $tpl->load('card', [$content]);

View File

@@ -14,6 +14,11 @@
$sp['output'] .= $tpl->load('card', [$content]);
// To today
$content = $tpl->load('button', ['<i class="fas fa-arrow-down"></i>&emsp;Heute&emsp;<i class="fas fa-arrow-down"></i>', '#', 'html-id' => 'button-totoday']);
$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']);
@@ -21,16 +26,21 @@
$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', ['Fakten', '', 'html-id' => 'menu-item-facts', 'icon' => 'fa-list']);
$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['menus'] .= $tpl->load('menu/bottom', [$items, 'html-id' => 'menu-regatta', 'title' => 'Regatta-Details', 'height' => 400]);
$sp['scripts'] .= $scripts->load('onRegattaClicked');
$sp['scripts'] .= $scripts->load('regattas');

View File

@@ -2,7 +2,7 @@
$sp['title'] = 'Segler - Regatten.net ' . $_CLASS['name'];
$sp['backbutton'] = 'index';
$sp['activenav'] = 4;
$sp['activenav'] = 5;
// Title
$content = "<h1>Segler</h1>";
@@ -31,9 +31,11 @@
$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']);

View File

@@ -15,6 +15,6 @@
<a href="<?php echo LINK_PRE; ?>index"<?php if ($sp['activenav'] == 1) echo ' class="active-nav"'; ?>><i class="fa fa-home"></i><span>Start</span></a>
<a href="<?php echo LINK_PRE; ?>regattas"<?php if ($sp['activenav'] == 2) echo ' class="active-nav"'; ?>><i class="fa fa-flag-checkered"></i><span>Regatten</span></a>
<a href="<?php echo LINK_PRE; ?>rank"<?php if ($sp['activenav'] == 3) echo ' class="active-nav"'; ?>><i class="fa fa-trophy"></i><span>Ranglisten</span></a>
<a href="#" data-menu="menu-lists"<?php if ($sp['activenav'] == 4) echo ' class="active-nav"'; ?>><i class="fa fa-list"></i><span>Listen</span></a>
<a href="<?php echo LINK_PRE; ?>planning"<?php if ($sp['activenav'] == 4) echo ' class="active-nav"'; ?>><i class="fa fa-calendar-alt"></i><span>Planung</span></a>
<a href="#" data-menu="menu-more"<?php if ($sp['activenav'] == 5) echo ' class="active-nav"'; ?>><i class="fa fa-ellipsis-h"></i><span>Mehr</span><em id="badge-footer-more" class="badge bg-highlight"></em></a>
</div>

View File

@@ -1,5 +1,5 @@
<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">
@@ -57,7 +57,7 @@
</div>
</div>
<div id="menu-more" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="360" >
<div id="menu-more" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="410" >
<div class="menu-title"><h1>Mehr</h1><p class="color-highlight">&nbsp;</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">
@@ -68,11 +68,12 @@
<span id="badge-more-news" class="badge bg-highlight color-white"></span>
<i class="fa fa-angle-right"></i>
</a>
<a href="<?php echo LINK_PRE; ?>planning">
<i class="fa font-14 fa-calendar-alt rounded-s bg-highlight color-white"></i>
<span>Saison-Planung</span>
<i class="fa fa-angle-right"></i>
</a>
<a href="<?php echo LINK_PRE; ?>expenditures" class="show-loggedin">
<i class="fa font-14 fa-money-bill-wave rounded-s bg-highlight color-white"></i>
<span>Ausgaben-Verwaltung</span>
<span id="badge-more-expenditures" class="badge bg-highlight color-white"></span>
<i class="fa fa-angle-right"></i>
</a>
<a href="<?php echo LINK_PRE; ?>trim_list">
<i class="fa font-14 fa-book rounded-s bg-highlight color-white"></i>
<span>Trimm-B&uuml;cher</span>
@@ -83,6 +84,11 @@
<span>RLP-Rechner</span>
<i class="fa fa-angle-right"></i>
</a>
<a href="#" data-menu="menu-lists">
<i class="fa font-14 fa-list rounded-s bg-highlight color-white"></i>
<span>Listen</span>
<i class="fa fa-angle-right"></i>
</a>
<a href="<?php echo LINK_PRE; ?>contact" class="border-0">
<i class="fa font-14 fa-phone rounded-s bg-highlight color-white"></i>
<span>Kontakt</span>
@@ -110,7 +116,7 @@
<span>Login</span>
<i class="fa fa-angle-right"></i>
</a>
<a href="#" data-menu="menu-signup" class="show-notloggedin">
<a href="https://regatten.net/#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>
@@ -209,7 +215,7 @@
</div>
</div>
<div id="menu-developer" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="360">
<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">
@@ -229,11 +235,16 @@
<span>Reset Cache</span>
<i class="fa fa-angle-right"></i>
</a>
<a href="https://github.com/ostertun/RegattenApp/issues">
<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>
@@ -243,7 +254,7 @@
</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">
@@ -257,18 +268,7 @@
<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>
</div>
</div>
<div id="menu-signup" class="menu menu-box-modal menu-box-detached rounded-m" data-menu-height="300">
<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>
<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>
@@ -284,21 +284,21 @@
<p>
Mehr Informationen findest Du <a href="https://info.ostertun.net/regatten/beta">hier</a>.
</p>
<p>
Mit der Nutzung dieser App erkl&auml;rst Du Dich au&szlig;erdem damit einverstanden, dass wir Cookies einsetzen.
</p>
<a id="menu-welcome-a-okay" class="btn btn-m mt-2 mb-3 btn-full bg-green2-dark text-uppercase font-900" href="#">Alles klar</a>
</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&uuml;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&uuml;gbar. Keine Sorge, Du musst nichts machen. Wir aktuallisieren den Inhalt in wenigen Sekunden.
<p>
Das Speichern der ben&ouml;tigten Daten wird von Deinem Ger&auml;t nicht unterst&uuml;tzt.<br>
Da deshalb die Daten jedesmal direkt vom Server geladen werden m&uuml;ssen, kannst Du die App nicht offline nutzen.<br>
Das Nachladen kann au&szlig;erdem gerade bei gro&szlig;en Datenmengen (wie Ranglisten) sehr lange dauern.
Wir empfehlen Dir daher, auf diesem Ger&auml;t unsere normale Website zu benutzen. Diese ist auch f&uuml;r Mobil-Ger&auml;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://ranglisten.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>

View File

@@ -27,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-->

View File

@@ -0,0 +1,338 @@
let users = [];
let known = [];
let userSelectedCallback = null;
let excludeUsers = {};
function userSelected(id) {
if (typeof userSelectedCallback === 'function') {
userSelectedCallback(id);
}
}
async function usersSearch() {
$('.item-user-search').remove();
if ($('#input-user-search').val().length == 0) {
known.forEach(function (entry) {
if (!(entry.id in excludeUsers)) {
$('#menu-select-user').find('.content').find('.list-group').append(entry.content);
}
});
}
if ($('#input-user-search').val().length >= 3) {
let cnt = 0;
users.forEach(function (entry) {
if (!(entry.id in excludeUsers) && search($('#input-user-search').val(), entry.keywords)) {
$('#menu-select-user').find('.content').find('.list-group').append(entry.content);
cnt++;
}
});
if (cnt == 0) {
let item = '<p class="item-user-search">Keine Benutzer gefunden.</p>';
$('#menu-select-user').find('.content').find('.list-group').append(item);
}
} else {
let item = '<p class="item-user-search">Zum Suchen mindestens 3 Zeichen eingeben</p>';
$('#menu-select-user').find('.content').find('.list-group').append(item);
}
}
function addRemoveToUser(userid) {
$('.item-user-to[data-userid=' + userid + ']').remove();
}
async function expendituresInitModals() {
$('#button-add-save').click(function () {
showLoader();
const jqUserFrom = $('#item-add-user-from');
const userFrom = jqUserFrom.data('userid');
const jqDate = $('#input-add-date');
const purposeDate = jqDate.val();
if (purposeDate == '') {
hideLoader();
toastError('Es wurde kein Datum ausgewählt!');
jqDate.focus();
return;
}
const jqAmount = $('#input-add-amount');
const amount = jqAmount.val();
if (amount == '') {
hideLoader();
toastError('Es wurde kein Betrag ausgewählt!');
jqAmount.focus();
return;
}
const purpose = $('#select-add-purpose').val();
const regattaName = $('#input-add-regatta-name').val();
const purposeText = $('#input-add-purpose-text').val();
let usersTo = [];
$('.item-user-to[data-userid]').each(function (index) {
usersTo.push($(this).data('userid'));
});
let auth = {
id: localStorage.getItem('auth_id'),
hash: localStorage.getItem('auth_hash')
}
$.ajax({
url: QUERY_URL + 'expenditures_add',
method: 'POST',
data: {
auth: auth,
user_from: userFrom,
date: purposeDate,
amount: Math.round(parseFloat(amount) * 100),
purpose: purpose,
regatta_name: regattaName,
purpose_text: purposeText,
users_to: usersTo
},
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 Ausgabe zu speichern');
} else {
log('expenditures_add: 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();
updateExpendituresBadge();
$('#menu-add').hideMenu();
hideLoader();
toastOk('Ausgabe gespeichert. Betrag wurde durch ' + data.count + ' Personen geteilt.');
}
});
});
$('#item-add-user-from').click(async function () {
excludeUsers = {};
$('#input-user-search').val('').trigger('focusin').trigger('focusout');
usersSearch();
userSelectedCallback = async function (userid) {
$('#item-add-user-from').data('userid', userid).find('span').html('bezahlt von: ' + (await dbGetData('users', userid)).username);
$('#menu-select-user').hideMenu();
$('#menu-add').showMenu();
}
$('#menu-add').hideMenu();
$('#menu-select-user').showMenu();
$('#input-user-search').focus();
});
$('#item-add-user-to').click(async function () {
excludeUsers = {};
$('.item-user-to[data-userid]').each(function (index) {
excludeUsers[$(this).data('userid')] = true;
});
$('#input-user-search').val('').trigger('focusin').trigger('focusout');
usersSearch();
userSelectedCallback = async function (userid) {
let item = '<a class="item-user-to" data-userid="' + userid + '" onclick="addRemoveToUser(' + userid + ')">';
item += '<span>' + (await dbGetData('users', userid)).username + '</span>';
item += '<i class="fa fa-times"></i>';
item += '</a>';
$('#item-add-user-to').before(item);
$('#menu-select-user').hideMenu();
$('#menu-add').showMenu();
}
$('#menu-add').hideMenu();
$('#menu-select-user').showMenu();
$('#input-user-search').focus();
});
$('#button-add-transfer-save').click(function () {
showLoader();
const jqUser = $('#item-add-transfer-user');
const selectedUser = jqUser.data('userid');
if (selectedUser == 0) {
hideLoader();
toastError('Es wurde keine Person ausgewählt!');
return;
}
const jqDate = $('#input-add-transfer-date');
const selectedDate = jqDate.val();
if (selectedDate == '') {
hideLoader();
toastError('Es wurde kein Datum ausgewählt!');
jqDate.focus();
return;
}
const jqAmount = $('#input-add-transfer-amount');
const selectedAmount = jqAmount.val();
if (selectedAmount == '') {
hideLoader();
toastError('Es wurde kein Betrag ausgewählt!');
jqAmount.focus();
return;
}
const jqPurposeText = $('#input-add-transfer-purpose-text');
const selectedPurposeText = jqPurposeText.val();
const jqSwitch = $('#switch-add-transfer-received');
const direction = jqSwitch.prop('checked');
let auth = {
id: localStorage.getItem('auth_id'),
hash: localStorage.getItem('auth_hash')
}
$.ajax({
url: QUERY_URL + 'expenditures_add_transfer',
method: 'POST',
data: {
auth: auth,
direction: direction ? 1 : -1,
userid: selectedUser,
date: selectedDate,
amount: Math.round(parseFloat(selectedAmount) * 100),
purpose_text: selectedPurposeText
},
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 Geldtransfer zu speichern');
} else {
log('expenditures_add_transfer: 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();
updateExpendituresBadge();
$('#menu-add-transfer').hideMenu();
hideLoader();
toastOk(direction ? 'Geldtransfer gespeichert. ' + (await dbGetData('users', selectedUser)).username + ' muss dies noch bestätigen' : 'Geldtransfer wurde gespeichert');
}
});
});
$('#switch-add-transfer-received').parent().parent().click(async function () {
const jqSwitch = $('#switch-add-transfer-received');
const jqUser = $('#item-add-transfer-user');
const direction = jqSwitch.prop('checked');
jqSwitch.parent().prev().text(direction ? 'Geld gegeben' : 'Geld bekommen').prev().removeClass('fa-arrow-' + (direction ? 'left' : 'right')).addClass('fa-arrow-' + (direction ? 'right' : 'left'));
const selectedUser = jqUser.data('userid');
if (selectedUser == 0) {
jqUser.find('span').html((direction ? 'an: ' : 'von: ') + '<font style="font-style:italic;">bitte auswählen</font>');
} else {
jqUser.find('span').text((direction ? 'an: ' : 'von: ') + (await dbGetData('users', selectedUser)).username);
}
});
$('#item-add-transfer-user').click(async function () {
excludeUsers = {};
excludeUsers[USER_ID] = true;
$('#input-user-search').val('').trigger('focusin').trigger('focusout');
usersSearch();
userSelectedCallback = async function (userid) {
const direction = $('#switch-add-transfer-received').prop('checked');
$('#item-add-transfer-user').data('userid', userid).find('span').html((direction ? 'an: ' : 'von: ') + (await dbGetData('users', userid)).username);
$('#menu-select-user').hideMenu();
$('#menu-add-transfer').showMenu();
}
$('#menu-add-transfer').hideMenu();
$('#menu-select-user').showMenu();
$('#input-user-search').focus();
});
$('#input-user-search').on('input', usersSearch);
users = [];
known = [];
let itemMe = '<a class="item-user-search" onclick="userSelected(' + USER_ID + ')">';
itemMe += '<span>ICH (' + USER_NAME + ')</span>';
itemMe += '<i class="fa fa-angle-right"></i>';
itemMe += '</a>';
known.push({id: USER_ID, content: itemMe});
let knownIds = {};
let allExps = await dbGetData('expenditures');
let expUsers = {};
for (let i in allExps) {
let exp = allExps[i];
let eUId = exp.user;
if (!(eUId in expUsers)) {
expUsers[eUId] = {
userId: eUId,
username: (await dbGetData('users', eUId)).username,
cnt: 0
};
}
expUsers[eUId].cnt++;
}
expUsers = Object.values(expUsers);
expUsers.sort(function (a, b) {
return a.username.localeCompare(b.username);
});
for (let i in expUsers) {
knownIds[expUsers[i].userId] = true;
}
const dbUsers = await dbGetData('users');
dbUsers.sort(function (a, b) {
return a.username.localeCompare(b.username);
});
for (let i in dbUsers) {
let item = '<a class="item-user-search" onclick="userSelected(' + dbUsers[i].id + ')">';
item += '<span>' + dbUsers[i].username + '</span>';
item += '<i class="fa fa-angle-right"></i>';
item += '</a>';
users.push({
keywords: [dbUsers[i].username],
id: dbUsers[i].id,
content: item
});
if (dbUsers[i].id in knownIds) known.push({id: dbUsers[i].id, content: item});
}
$('#input-add-regatta-name').attr('list', 'list-regattas');
let listRegattas = $('<datalist id="list-regattas">').appendTo('body');
let plannings = await dbGetDataIndex('plannings', 'user', USER_ID);
let regattas = [];
for (let i in plannings) {
let regatta = await dbGetData('regattas', plannings[i].regatta);
regatta.year = formatDate('Y', parseDate(regatta.date));
regattas.push(regatta);
}
regattas.sort(function (a, b) {
if (a.year != b.year) return b.year - a.year;
return a.name.localeCompare(b.name);
});
for (let i in regattas) {
$('<option>').attr('value', regattas[i].name).appendTo(listRegattas);
}
}
async function expendituresShowAdd(defaultUser = 0) {
$('#item-add-user-from').data('userid', USER_ID).find('span').html('bezahlt von: ' + USER_NAME);
$('#input-add-date').val(formatDate('Y-m-d')).trigger('focusin');
$('#input-add-amount').val('');
$('#select-add-purpose').val('entryfee');
$('#input-add-regatta-name').val('');
$('#input-add-purpose-text').val('');
$('.item-user-to').remove();
let item = '<a class="item-user-to" data-userid="' + USER_ID + '" onclick="addRemoveToUser(' + USER_ID + ')">';
item += '<span>' + USER_NAME + '</span>';
item += '<i class="fa fa-times"></i>';
item += '</a>';
$('#item-add-user-to').before(item);
if (defaultUser > 0) {
item = '<a class="item-user-to" data-userid="' + defaultUser + '" onclick="addRemoveToUser(' + defaultUser + ')">';
item += '<span>' + (await dbGetData('users', defaultUser)).username + '</span>';
item += '<i class="fa fa-times"></i>';
item += '</a>';
$('#item-add-user-to').before(item);
}
$('#menu-add').showMenu();
}
async function expendituresShowAddTransfer(defaultUser = 0, defaultDirection = true, defaultAmount = '') {
$('#switch-add-transfer-received').prop('checked', defaultDirection).parent().prev().text(defaultDirection ? 'Geld gegeben' : 'Geld bekommen').prev().removeClass(defaultDirection ? 'fa-arrow-left' : 'fa-arrow-right').addClass(defaultDirection ? 'fa-arrow-right' : 'fa-arrow-left');
if (defaultUser == 0) {
$('#item-add-transfer-user').data('userid', 0).find('span').html((defaultDirection ? 'an: ' : 'von: ') + '<font style="font-style:italic;">bitte auswählen</font>');
} else {
$('#item-add-transfer-user').data('userid', defaultUser).find('span').html((defaultDirection ? 'an: ' : 'von: ') + (await dbGetData('users', defaultUser)).username);
}
$('#input-add-transfer-date').val(formatDate('Y-m-d')).trigger('focusin');
$('#input-add-transfer-amount').val(defaultAmount).trigger('focusin').trigger('focusout');
$('#input-add-transfer-purpose-text').val('');
$('#menu-add-transfer').showMenu();
}

View File

@@ -0,0 +1,326 @@
let firstCall = true;
let rows = [];
let displayed = [];
let page = 1;
let pageCount = 0;
const showCount = 25;
let sumsDisplayed = true;
function createPurpose(exp) {
let purpose = '';
let extraText = ': ';
switch (exp.purpose) {
case 'transfer': purpose = 'Geldtransfer'; break;
case 'entryfee': purpose = 'Meldegeld'; break;
case 'camping': purpose = 'Camping'; break;
case 'food': purpose = 'Essen'; break;
case 'other': extraText = ''; break;
}
if (exp.purpose_text != '') {
purpose += extraText + exp.purpose_text;
}
return purpose;
}
async function onListClicked(id) {
let exp = await dbGetData('expenditures', id);
console.log(exp);
$('#menu-expenditure').find('.menu-title').find('p').text(createPurpose(exp) + ' (' + (exp.direction * exp.amount / 100).toFixed(2) + ' €)');
if (exp.approved == 0 && (exp.direction < 0) == (exp.canceled == 0)) {
$('#menu-item-approve').show();
$('#menu-item-approve').attr('onclick', 'expenditureAction("approve", ' + exp['id'] + ', "' + (exp.canceled == 1 ? 'Stornierung' : 'Ausgabe') + ' genehmigt")');
$('#menu-item-approve').text(exp.canceled == 1 ? 'Storno akzeptieren' : 'Akzeptieren');
$('#menu-item-decline').show();
$('#menu-item-decline').attr('onclick', 'expenditureAction("decline", ' + exp['id'] + ', "Ausgabe ' + (exp.canceled == 1 ? 'erneut angefragt' : 'abgelehnt') + '")');
$('#menu-item-decline').text(exp.canceled == 1 ? 'Erneut anfragen' : 'Ablehnen');
} else {
$('#menu-item-approve').hide();
$('#menu-item-decline').hide();
}
if (exp.canceled == 0 && (exp.approved == 1 || exp.direction > 0)) {
$('#menu-item-cancel').show();
$('#menu-item-cancel').attr('onclick', 'expenditureAction("cancel", ' + exp['id'] + ', "' + (exp.direction > 0 ? 'Ausgabe storniert' : 'Stornierung beantragt') + '")');
} else {
$('#menu-item-cancel').hide();
}
$('#menu-expenditure').showMenu();
$('#menu-expenditure').scrollTop(0);
}
function expenditureAction(action, expId, successStr) {
$('#menu-expenditure').hideMenu();
showLoader();
let auth = {
id: localStorage.getItem('auth_id'),
hash: localStorage.getItem('auth_hash')
}
$.ajax({
url: QUERY_URL + 'expenditure_' + action,
method: 'POST',
data: {
auth: auth,
expenditure: expId
},
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 Ausgabe zu stornieren.');
} else {
log('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();
updateExpendituresBadge();
hideLoader();
toastOk(successStr);
}
});
}
function pageChange() {
$('#p-count')[0].scrollIntoView({ behavior: "smooth" });
drawList();
}
async function drawList() {
window.setTimeout(function () {
let list = '';
if (displayed.length > 0) {
let offset = (page - 1) * (sumsDisplayed ? showCount * 2 : showCount);
let count = (page == pageCount ? (displayed.length - offset) : (sumsDisplayed ? showCount * 2 + 1 : showCount));
for (i = 0; i < count; i ++) {
list += displayed[i + offset];
}
} else {
list = '<div><div>Keine Ergebnisse, die der Suche entsprechen</div></div>';
}
$('#div-list').html(list);
}, 0);
}
async function reSearch() {
window.setTimeout(function () {
displayed = [];
rows.forEach(function (entry) {
if (search($('#input-search').val(), entry.keywords)) {
displayed.push(entry.content);
}
});
sumsDisplayed = displayed.length == rows.length;
$('#div-list').toggleClass('display-border', !sumsDisplayed);
pageCount = Math.ceil((displayed.length - (sumsDisplayed ? 1 : 0)) / (sumsDisplayed ? showCount * 2 : showCount));
if ((page < 1) || (page > pageCount)) {
if (page < 1) {
page = 1;
} else {
page = pageCount;
}
}
drawPagination();
drawList();
}, 0);
}
function cancelCause(cancel_cause) {
switch (cancel_cause) {
case 'not approved':
return 'nicht genehmigt';
case 'canceled':
return 'storniert';
}
return 'unbekannter Grund';
}
let siteScript = async function() {
if (!isLoggedIn()) {
hideLoader();
return;
}
userid = findGetParameter('user');
let user = null;
if (userid !== null) {
user = await dbGetData('users', userid);
}
if (user === null) {
location.href = LINK_PRE + 'expenditures';
return;
}
$('#p-username').text(user.username);
$('.span-username').text(user.username);
if (firstCall) {
firstCall = false;
initPagination();
$('#input-search').on('input', reSearch);
$('#button-add').click((e) => expendituresShowAdd(userid));
$('#button-add-transfer').click((e) => expendituresShowAddTransfer(userid));
expendituresInitModals();
}
let exps = await dbGetDataIndex('expenditures', 'user', user.id);
exps.sort(function (a, b) {
return a.created - b.created;
});
let sum = 0;
for (i in exps) {
let exp = exps[i];
if (exp.canceled == 0) {
sum += exp.direction * exp.amount;
}
exps[i].sum = sum;
exps[i].purpose_html = createPurpose(exp);
exps[i].purpose_date = formatDate("d.m.Y", parseDate(exp.purpose_date));
}
let sumText = '';
let sumButton = '';
if (sum == 0) {
sumText = 'Du und ' + user.username + ' seid quitt.';
} else if (sum > 0) {
sumText = user.username + ' schuldet Dir noch ' + (sum / 100).toFixed(2) + ' €.';
sumButton = '&emsp;<a href="#" onclick="expendituresShowAddTransfer(' + user.id + ', false, ' + (sum/100) + '); return false;">Ausgleichen</a>';
} else {
sumText = 'Du schuldest ' + user.username + ' noch ' + (-sum / 100).toFixed(2) + ' €.';
sumButton = '&emsp;<a href="#" onclick="expendituresShowAddTransfer(' + user.id + ', true, ' + (-sum/100) + '); return false;">Ausgleichen</a>';
}
results = exps.reverse();
// TODO: open approvals
let count = results.length;
if (count > 0) {
$('#p-count').text(sumText);
$('#p-count').html($('#p-count').html() + sumButton);
$('#div-list').show();
$('#input-search').parent().show();
rows = [];
for (id in results) {
let entry = results[id];
let rowSum = { keywords: [], content: '' };
rowSum.content += '<div class="sum">';
// ZEILE SUM
rowSum.content += '<div>';
// sum
rowSum.content += '<div>';
if (entry.sum < 0) rowSum.content += '<font style="color:red;">';
rowSum.content += (entry.sum / 100).toFixed(2);
if (entry.sum < 0) rowSum.content += '</font>';
rowSum.content += ' €</div>';
rowSum.content += '</div></div>';
rows.push(rowSum);
let row = { keywords: [], content: '' };
row.keywords.push((entry.amount / 100).toFixed(2));
row.keywords.push(entry.purpose_html);
row.keywords.push(entry.purpose_date);
row.keywords.push(entry.regatta_name);
row.content += '<div onclick="onListClicked(' + entry.id + ');" style="';
if (entry.canceled == 1) {
row.content += 'opacity:0.5;';
}
if (entry.approved == 0) {
row.content += 'font-style:italic;';
}
row.content += '">';
// ZEILE 1
row.content += '<div>';
// purpose
row.content += '<div' + ((entry.canceled == 1) ? ' style="text-decoration: line-through;"' : '') + '>' + entry.purpose_html + '</div>';
// amount
row.content += '<div>';
if (entry.canceled == 1) row.content += '(';
if (entry.direction < 0) row.content += '<font style="color:red;">';
row.content += (entry.direction * entry.amount / 100).toFixed(2);
if (entry.direction < 0) row.content += '</font>';
if (entry.canceled == 1) row.content += ')';
row.content += ' €</div>';
// icons
if (entry.approved == 1) {
if (entry.canceled == 1) {
row.content += '<div><i class="fas fa-times"></i></div>';
} else {
row.content += '<div><i class="fas fa-check"></i></div>';
}
} else if ((entry.direction < 0) == (entry.canceled == 1)) {
row.content += '<div><i class="fas fa-hourglass-half"></i></div>';
} else {
row.content += '<div><i class="fas fa-exclamation fa-blink"></i></div>';
}
row.content += '</div>';
// ZEILE 2
row.content += '<div>';
// date
row.content += '<div>' + entry.purpose_date + '</div>';
// regatta
row.content += '<div>' + entry.regatta_name + '</div>';
// cancel_cause
row.content += '<div>' + (entry.canceled == 1 ? cancelCause(entry.cancel_cause) : '') + '</div>';
row.content += '</div></div>';
rows.push(row);
}
let rowSum = { keywords: [], content: '' };
rowSum.content += '<div class="sum">';
// ZEILE SUM
rowSum.content += '<div>';
// sum
rowSum.content += '<div>';
rowSum.content += (0).toFixed(2);
rowSum.content += ' €</div>';
rowSum.content += '</div></div>';
rows.push(rowSum);
reSearch();
} else {
$('#p-count').html('Keine Ausgaben gefunden!');
$('#div-list').hide();
$('#input-search').parent().hide();
}
hideLoader();
}

View File

@@ -0,0 +1,149 @@
var firstCall = true;
var rows = [];
var displayed = [];
var page = 1;
var pageCount = 0;
const showCount = 25;
async function onListClicked(id) {
window.location = LINK_PRE + 'expenditures-user?user=' + id;
}
function pageChange() {
$('#p-count')[0].scrollIntoView({ behavior: "smooth" });
drawList();
}
async function drawList() {
window.setTimeout(function () {
var list = '';
if (displayed.length > 0) {
var offset = (page - 1) * showCount;
var count = (page == pageCount ? (displayed.length % showCount) : showCount);
if (count == 0) count = showCount;
for (i = 0; i < count; i ++) {
list += displayed[i + offset];
}
} else {
list = '<div><div>Keine Ergebnisse, die der Suche entsprechen</div></div>';
}
$('#div-list').html(list);
}, 0);
}
async function reSearch() {
window.setTimeout(function () {
displayed = [];
rows.forEach(function (entry) {
if (search($('#input-search').val(), entry.keywords)) {
displayed.push(entry.content);
}
});
pageCount = Math.ceil(displayed.length / showCount);
if ((page < 1) || (page > pageCount)) {
if (page < 1) {
page = 1;
} else {
page = pageCount;
}
}
drawPagination();
drawList();
}, 0);
}
var siteScript = async function() {
if (!isLoggedIn()) {
hideLoader();
return;
}
if (firstCall) {
firstCall = false;
initPagination();
$('#input-search').on('input', reSearch);
$('#button-add').click((e) => expendituresShowAdd());
$('#button-add-transfer').click((e) => expendituresShowAddTransfer());
expendituresInitModals();
}
let allExps = await dbGetData('expenditures');
let expUsers = {};
for (let i in allExps) {
let exp = allExps[i];
let eUId = exp.user;
if (!(eUId in expUsers)) {
expUsers[eUId] = {
userId: eUId,
username: (await dbGetData('users', eUId)).username,
balance: 0,
openApprovals: 0,
cnt: 0
};
}
if (exp.canceled == 0) {
expUsers[eUId].balance += exp.direction * parseInt(exp.amount);
}
if (exp.approved == 0) {
if (exp.direction < 0 && exp.canceled == 0) expUsers[eUId].openApprovals++;
if (exp.direction > 0 && exp.canceled == 1) expUsers[eUId].openApprovals++;
}
expUsers[eUId].cnt++;
}
let results = Object.values(expUsers);
let count = results.length;
if (count > 0) {
$('#p-count').hide();
$('#div-list').show();
$('#input-search').parent().show();
results.sort(function (a, b) {
return b.cnt - a.cnt;
});
rows = [];
for (id in results) {
var entry = results[id];
var row = { keywords: [], content: '' };
row.keywords.push(entry.username);
row.content += '<div onclick="onListClicked(' + entry.userId + ');">';
// ZEILE 1
// Username
row.content += '<div><b>' + entry.username + '</b></div>';
// ZEILE 2
row.content += '<div>';
// open approvals
row.content += '<div>' + ((entry.openApprovals > 0) ? (entry.openApprovals + ' offene Genehmigung' + (entry.openApprovals > 1 ? 'en' : '')) : '') + '</div>';
// balance
row.content += '<div>';
if (entry.balance < 0) row.content += '<font style="color:red;">';
row.content += (entry.balance / 100).toFixed(2);
if (entry.balance < 0) row.content += '</font>';
row.content += ' €</div>';
row.content += '</div></div>';
rows.push(row);
}
reSearch();
} else {
$('#p-count').show().html('Keine Ausgaben gefunden!');
$('#div-list').hide();
$('#input-search').parent().hide();
}
hideLoader();
}

12
server/scripts/go2url.js Normal file
View 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&uuml;ck zur Startseite</a>');
} else {
showLoader();
location.href = url;
}
}, 2000);
}

View File

@@ -1,48 +1,132 @@
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();
var user = await dbGetData('users', localStorage.getItem('auth_user'));
// Favorites
var follows = await dbGetData('follows');
var watched = [];
for (var i = 1; i <= 5; i ++) {
sailor_id = user['sailor' + i];
if (sailor_id != null) {
watched.push(await dbGetData('sailors', sailor_id));
}
for (var i in follows) {
watched.push(await dbGetData('sailors', follows[i].sailor));
}
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();
@@ -59,7 +143,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 +160,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 +184,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
@@ -170,13 +272,19 @@ var siteScript = async function() {
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']);
@@ -201,6 +309,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
@@ -273,19 +401,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']);
@@ -310,6 +441,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
@@ -320,7 +471,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('&ensp;') + '</div>';

View File

@@ -66,7 +66,7 @@ var siteScript = async function() {
lastYear.setFullYear(lastYear.getFullYear() - 1);
for (var n in news) {
var newsEntry = news[n];
newsEntry.date = new Date(Date.parse(newsEntry.date));
newsEntry.date = parseDbTimestamp(newsEntry.date);
if (newsEntry.date > now) continue;
if (newsEntry.date < lastYear) break;
newsEntry.unread = (newsEntry.date > newsRead);

View File

@@ -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()) {
@@ -20,11 +57,18 @@ async function onRegattaClicked(id) {
// Your Planning
if (planning != null) {
$('#menu-item-yourplanning').show();
var boat = null;
if (planning.boat != null) {
boat = (await dbGetData('boats', planning.boat)).sailnumber;
}
var steuermann = null;
if (planning.steuermann != null) {
steuermann = (await dbGetData('sailors', planning.steuermann)).name;
}
var crew = [steuermann == null ? '[noch unklar]' : steuermann];
var crew = [
boat == null ? '[Boot unklar]' : boat,
steuermann == null ? '[St.mann unklar]' : steuermann
];
crewA = planning.crew.split(',');
for (i in crewA) {
var sailor = await dbGetData('sailors', crewA[i]);
@@ -54,15 +98,30 @@ async function onRegattaClicked(id) {
// 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, extServiceData.classId)); // 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 {
@@ -78,6 +137,14 @@ async function onRegattaClicked(id) {
$('#menu-item-bericht').hide();
}
// Fakten
if ('facts' in regatta && regatta['facts'] != null) {
$('#menu-item-facts').show();
$('#menu-item-facts').attr('href', LINK_PRE + 'regatta_facts?regatta=' + regatta['id']);
} else {
$('#menu-item-facts').hide();
}
// Info
if (regatta['info'] != '') {
$('#menu-item-info').show();
@@ -92,10 +159,10 @@ async function onRegattaClicked(id) {
$('#menu-item-meldung').show();
$('#menu-item-meldung').attr('href', regatta['meldung']);
$('#menu-item-meldung').attr('target', '_blank');
if ((planning != null) && (planning['gemeldet'] == '1')) {
/*if ((planning != null) && (planning['gemeldet'] == '1')) {
$('#badge-regatta-meldung').text('schon gemeldet');
$('#badge-regatta-meldung').addClass('bg-green2-dark').removeClass('bg-highlight bg-red2-dark bg-yellow2-dark');
} else if (regatta['meldungOffen'] == '0') {
} else*/ if (regatta['meldungOffen'] == '0') {
$('#badge-regatta-meldung').text('geschlossen');
$('#badge-regatta-meldung').addClass('bg-highlight').removeClass('bg-green2-dark bg-red2-dark bg-yellow2-dark');
} else if (regatta['meldungSchluss'] != null) {
@@ -135,7 +202,7 @@ async function onRegattaClicked(id) {
$('#badge-regatta-meldung').addClass('bg-highlight').removeClass('bg-green2-dark bg-red2-dark bg-yellow2-dark');
}
} else {
$('#badge-regatta-meldung').text('Meldeschluss abgelaufen');
$('#badge-regatta-meldung').text('Meldeschluss abgelaufen, Nachmeldung möglich');
$('#badge-regatta-meldung').addClass('bg-highlight').removeClass('bg-green2-dark bg-red2-dark bg-yellow2-dark');
}
} else {

View File

@@ -18,13 +18,13 @@ async function planningSwitchChanged() {
},
error: function (xhr, status, error) {
if (xhr.status == 401) {
console.log('authentification failed');
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 &auml;ndern');
} else {
console.log('Login: unbekannter Fehler', status, error);
console.log(xhr);
log('Login: unbekannter Fehler', status, error);
log(xhr);
toastError('Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal', 5000);
}
$('#menu-status').hideMenu();
@@ -35,8 +35,6 @@ async function planningSwitchChanged() {
hideLoader();
}
});
console.log(id, gemeldet, bezahlt);
hideLoader();
}
async function planningEditStatus(id) {
@@ -70,16 +68,21 @@ function selectChange() {
if (typeof siteScript === 'function') {
history.replaceState(null, '', '?year=' + 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);
resolve();
});
}
var firstCall = true;
@@ -108,18 +111,21 @@ var siteScript = async function() {
if (firstCall) {
firstCall = false;
initYear();
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);
}
$('#a-share-planning').attr('href', LINK_PRE + 'planning_view?user=' + USER_ID);
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 selectedYear = $('#select-year').val();
var minDate = parseDate(selectedYear + '-01-01');
var maxDate = parseDate(selectedYear + '-12-31');
var regattas = await dbGetRegattasRange(minDate, maxDate);
@@ -138,12 +144,6 @@ var siteScript = async function() {
regattas.splice(i, 1);
}
}
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 years = await dbGetData('years');
years.sort(function (a, b) {
@@ -178,6 +178,9 @@ var siteScript = async function() {
var club = null;
if (entry['club'] != null)
club = await dbGetData('clubs', entry['club']);
if (entry.planning.boat !== null) {
entry.planning.boat = (await dbGetData('boats', entry.planning.boat)).sailnumber;
}
if (entry.planning.steuermann !== null) {
entry.planning.steuermann = (await dbGetData('sailors', entry.planning.steuermann)).name;
}
@@ -197,6 +200,7 @@ var siteScript = async function() {
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.boat != null) row.keywords.push(entry.planning.boat);
if (entry.planning.steuermann != null) row.keywords.push(entry.planning.steuermann);
for (c in entry.planning.crew) row.keywords.push(entry.planning.crew[c]);
@@ -221,6 +225,26 @@ var siteScript = async function() {
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
@@ -263,7 +287,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>');
}
if (entry.planning.gemeldet == '1') {

View File

@@ -0,0 +1,638 @@
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 &Auml;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 &Auml;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 &Auml;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 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 &Auml;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();
}
var boats = [];
var boatKnownIds = [];
var boatKnown = [];
async function boatSelected(bid) {
$('#menu-boat').hideMenu();
showLoader();
var rid = $('#switch-planning-include').data('regatta');
var action = 'planning_set_boat';
// add boat
var auth = {
id: localStorage.getItem('auth_id'),
hash: localStorage.getItem('auth_hash')
}
$.ajax({
url: QUERY_URL + action,
method: 'POST',
data: {
auth: auth,
regatta: rid,
boat: bid
},
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 &Auml;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 ((bid === null) || (bid in boatKnownIds)) {
planningEdit(rid);
hideLoader();
} else {
location.reload();
}
}
});
}
async function boatsSearch() {
$('.item-boat-search').remove();
var item = '<a class="item-boat-search" onclick="boatSelected(null)">';
item += '<span style="font-style:italic;">noch unklar</span>';
item += '<i class="fa fa-angle-right"></i>';
item += '</a>';
$('#menu-boat').find('.content').find('.list-group').append(item);
if ($('#input-edit-boat-search').val().length == 0) {
boatKnown.forEach(function (entry) {
$('#menu-boat').find('.content').find('.list-group').append(entry);
});
}
if ($('#input-edit-boat-search').val().length >= 3) {
boats.forEach(function (entry) {
if (search($('#input-edit-boat-search').val(), entry.keywords)) {
$('#menu-boat').find('.content').find('.list-group').append(entry.content);
}
});
} else {
var item = '<p class="item-boat-search">Zum Suchen mindestens 3 Zeichen eingeben</p>';
$('#menu-boat').find('.content').find('.list-group').append(item);
}
}
async function planningChangeBoat() {
$('#input-edit-boat-search').val('').trigger('focusin').trigger('focusout');
boatsSearch();
$('#menu-edit').hideMenu();
$('#menu-boat').find('.menu-title').find('h1').text('Boot bearbeiten');
$('#menu-boat').showMenu();
$('#input-edit-boat-search').focus();
}
async function initBoatsSailors() {
boats = [];
sailors = [];
boatKnown = [];
known = [];
var plannings = await dbGetDataIndex('plannings', 'user', USER_ID);
boatKnownIds = {};
knownIds = {};
for (var p in plannings) {
p = plannings[p];
if (p.boat !== null) boatKnownIds[p.boat] = true;
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 dbBoats = await dbGetData('boats');
dbBoats.sort(function(a,b){
return a.sailnumber.localeCompare(b.sailnumber);
});
for (var b in dbBoats) {
var item = '<a class="item-boat-search" onclick="boatSelected(' + dbBoats[b].id + ')">';
item += '<span>' + dbBoats[b].sailnumber + ' - ' + dbBoats[b].name + '</span>';
item += '<i class="fa fa-angle-right"></i>';
item += '</a>';
boats.push({
keywords: [dbBoats[b].sailnumber, dbBoats[b].name],
content: item
});
if (dbBoats[b].id in boatKnownIds) boatKnown.push(item);
}
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 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-boat').show();
$('#item-steuermann').show();
if (planning.boat !== null) {
$('#item-boat').find('span').text('Boot: ' + (await dbGetData('boats', planning.boat)).sailnumber);
} else {
$('#item-boat').find('span').html('Boot: <font style="font-style:italic;">noch unklar</font>');
}
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-times"></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&uuml;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-boat').hide();
$('#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-boat').click(planningChangeBoat);
$('#item-steuermann').click(planningChangeSteuermann);
$('#input-edit-search').on('input', sailorsSearch);
$('#input-edit-boat-search').on('input', boatsSearch);
initBoatsSailors();
}
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.boat !== null) {
entry.planning.boat = (await dbGetData('boats', entry.planning.boat)).sailnumber;
}
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.boat !== null ? entry.planning.boat : '<i>Boot unklar</i>') + '</div>';
row.content += '</div>';
// ZEILE 6
row.content += '<div>';
row.content += '<div>' + (entry.planning.steuermann !== null ? entry.planning.steuermann : '<i>St.mann unklar</i>') + '</div>';
row.content += '</div>';
// ZEILE 7...
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();
}

View File

@@ -1,7 +1,7 @@
async function onUserClicked(id) {
var user = await dbGetData('users', id);
if (user !== null) {
location.href = LINK_PRE + 'planning_view?user=' + user.id;
location.href = LINK_PRE + 'planning_view?user=' + user.id + '&year=' + $('#select-year').val();
}
}
@@ -10,16 +10,21 @@ function selectChange() {
if (typeof siteScript === 'function') {
history.replaceState(null, '', '?year=' + 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);
resolve();
});
}
var firstCall = true;
@@ -46,7 +51,7 @@ var siteScript = async function() {
if (firstCall) {
firstCall = false;
initYear();
await initYear();
$('#select-year').change(selectChange);
$('#input-search').on('input', drawList);
}

View File

@@ -1,18 +1,25 @@
var userid;
function selectChange() {
var val = $('#select-year').val();
if (typeof siteScript === 'function') {
history.replaceState(null, '', '?year=' + val);
history.replaceState(null, '', '?user=' + userid + '&year=' + 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);
resolve();
});
}
var firstCall = true;
@@ -34,7 +41,7 @@ async function drawList () {
}
var siteScript = async function() {
var userid = findGetParameter('user');
userid = findGetParameter('user');
var user = null;
if (userid !== null) {
user = await dbGetData('users', userid);
@@ -57,7 +64,7 @@ var siteScript = async function() {
if (firstCall) {
firstCall = false;
initYear();
await initYear();
$('#select-year').change(selectChange);
$('#input-search').on('input', drawList);
}
@@ -83,12 +90,6 @@ var siteScript = async function() {
regattas.splice(i, 1);
}
}
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 years = await dbGetData('years');
years.sort(function (a, b) {
@@ -123,6 +124,9 @@ var siteScript = async function() {
var club = null;
if (entry['club'] != null)
club = await dbGetData('clubs', entry['club']);
if (entry.planning.boat !== null) {
entry.planning.boat = (await dbGetData('boats', entry.planning.boat)).sailnumber;
}
if (entry.planning.steuermann !== null) {
entry.planning.steuermann = (await dbGetData('sailors', entry.planning.steuermann)).name;
}
@@ -142,6 +146,7 @@ var siteScript = async function() {
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.boat != null) row.keywords.push(entry.planning.boat);
if (entry.planning.steuermann != null) row.keywords.push(entry.planning.steuermann);
for (c in entry.planning.crew) row.keywords.push(entry.planning.crew[c]);
@@ -163,6 +168,26 @@ var siteScript = async function() {
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
@@ -194,10 +219,15 @@ var siteScript = async function() {
// ZEILE 5
row.content += '<div>';
row.content += '<div>' + entry.planning.steuermann + '</div>';
row.content += '<div>' + (entry.planning.boat !== null ? entry.planning.boat : '<i>Boot unklar</i>') + '</div>';
row.content += '</div>';
// ZEILE 6...
// ZEILE 6
row.content += '<div>';
row.content += '<div>' + (entry.planning.steuermann !== null ? entry.planning.steuermann : '<i>St.mann unklar</i>') + '</div>';
row.content += '</div>';
// ZEILE 7...
for (var i in entry.planning.crew) {
row.content += '<div>';
row.content += '<div>' + entry.planning.crew[i] + '</div>';
@@ -205,72 +235,7 @@ var siteScript = async function() {
}
row.content += '</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
row.content += '<div>' + entry['special'] + '</div>';
// Icons
var icons = [];
if (entry['info'] != '')
icons.push('<i class="fas fa-info"></i>');
if ((entry['meldung'] != '') && (dateTo >= today) && (entry['meldungOffen'] == '1')) {
var color = '';
if (entry['meldungSchluss'] != null) {
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';
}
}
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 (regattaResults[entry['id']]) {
icons.push('<i class="fas fa-poll"></i>');
}
row.content += '<div class="color-green2-dark">' + icons.join('&ensp;') + '</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);
}

View File

@@ -83,6 +83,7 @@ async function onRankingClicked(id) {
// ZEILE 5...
var crew = entry.crew.split(',');
crew.unshift(entry.helm);
for (var c in crew) {
var cr = await dbGetData('sailors', crew[c]);
if (cr != null) {
@@ -106,116 +107,227 @@ async function onRankingClicked(id) {
$('#menu-rank').scrollTop(0);
}
async function selectChange(callSiteScript = true) {
var type = $('#select-type').val();
var year = parseInt($('#select-year').val());
if (type == "user") {
$('#select-year').parent().hide();
$('#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();
} else {
$('#select-year').parent().show();
$('#input-from').parent().hide();
$('#input-to').parent().hide();
$('#input-jugend').parent().parent().hide();
$('#input-jugstrict').parent().parent().hide();
$('#button-show').hide();
var rankings;
var from, to, jugend, jugstrict;
switch (type) {
case 'year':
from = (year - 1) + '-12-01';
to = year + '-11-30';
jugend = jugstrict = false;
break;
case 'youth':
from = (year - 1) + '-12-01';
to = year + '-11-30';
jugend = jugstrict = true;
break;
case 'idjm':
var beginn = null;
var regattas = await dbGetData('regattas');
regattas.sort(function(a,b){ return b.date.localeCompare(a.date); });
for (var r in regattas) {
var regatta = regattas[r];
var date = parseDate(regatta.date);
if ((date < parseDate('01.01.' + year)) || (date > parseDate('31.12.' + year))) {
continue;
function selectChange(callSiteScript = true) {
return new Promise(async function (resolve) {
var year = $('#select-year').val();
if (year == "user") {
$('#select-type').parent().hide();
$('#input-from').trigger('focusin').trigger('focusout').parent().show();
$('#input-to').trigger('focusin').trigger('focusout').parent().show();
$('#input-altm').trigger('focusin').trigger('focusout').parent().show();
$('#input-maxage').trigger('focusin').trigger('focusout').parent().show();
$('#input-agestrict').parent().show();
$('#input-agecrew').parent().show();
$('#button-show').show();
$('#card-special-ranks').hide();
} else {
year = parseInt(year);
var type = $('#select-type').val();
console.log('[rank] selected', year, type);
$('#select-type').parent().show();
$('#input-from').parent().hide();
$('#input-to').parent().hide();
$('#input-altm').parent().hide();
$('#input-maxage').parent().hide();
$('#input-agestrict').parent().hide();
$('#input-agecrew').parent().hide();
$('#button-show').hide();
$('#card-special-ranks').hide(); // first hide, show only when there are special ranks
var rankingsShow = {};
var options = '';
for (var i in rankings) {
if (rankings[i].year_from !== null && rankings[i].year_from > year) continue;
if (rankings[i].year_to !== null && rankings[i].year_to < year) continue;
var alias = rankings[i].alias;
options += '<option value="' + alias + '">' + rankings[i].name + '</option>';
rankingsShow[alias] = rankings[i];
}
$('#select-type').html(options);
if (!(type in rankingsShow)) {
console.log('[rank] selected type', type, 'not found for year', year, '. Using `year`');
type = 'year';
}
$('#select-type').val(type).trigger('focusin').trigger('focusout');
// special ranks
getJSON(QUERY_URL + 'get_special_rankings', function (code, data) {
if (code == 200) {
var specialRanks = [];
for (var i in data.data) {
var sr = data.data[i];
if (sr.to < (year + '-01-01')) continue;
if (sr.to > (year + '-12-31')) continue;
specialRanks.push(sr);
}
if (regatta.name.indexOf(YOUTH_GERMAN_NAME) >= 0) {
beginn = ((regatta.meldungSchluss != null) ? parseDate(regatta.meldungSchluss) : date);
break;
if (specialRanks.length > 0) {
var btns = '';
for (var i in specialRanks) {
var sr = specialRanks[i];
var link = 'https://ranglisten.net/frame.php?class=' + BOATCLASS + '&site=special_rank&rank_id=' + sr.id;
var name = sr.title;
var cssclass = i > 0 ? ' mt-3' : '';
btns += '<a class="btn btn-full rounded-s text-uppercase font-900 shadow-m bg-highlight' + cssclass + '" href="' + link + '">' + name + '</a>';
}
$('#card-special-ranks').find('.content').html(btns);
$('#card-special-ranks').show();
}
}
if (beginn != null) {
from = new Date(beginn);
from.setFullYear(from.getFullYear() - 1);
from.setDate(from.getDate() - 13);
from = formatDate('Y-m-d', from);
to = new Date(beginn);
to.setDate(to.getDate() - 14);
to = formatDate('Y-m-d', to);
jugend = true;
jugstrict = false;
} else {
$('#div-rank').html('Keine ' + YOUTH_GERMAN_NAME + ' gefunden!');
$('#input-search').parent().hide();
return;
log("[rank] special_ranks: Something went wrong (HTTP " + code + ")");
}
break;
}
});
$('#input-from').val(from);
$('#input-to').val(to);
$('#input-jugend').prop('checked', jugend);
$('#input-jugstrict').prop('checked', jugstrict);
var from, to, altm, maxage, agestrict, agecrew;
altm = 9; maxage = false; agestrict = false; agecrew = false;
var r = rankingsShow[type];
console.log('[rank] type', type, '=>', r);
if (r.max_age !== null) {
maxage = r.max_age;
agestrict = r.age_strict == 1;
agecrew = r.age_crew == 1;
}
if (r.alt_m !== null) {
altm = r.alt_m;
}
switch (r.type) {
case 'year':
from = (year - 1) + '-12-01';
to = year + '-11-30';
break;
case 'year2':
from = year + '-01-01';
to = year + '-12-31';
break;
case 'quali':
// TODO: auslagern in function getRegattaBegin
var beginn = null;
var regattas = await dbGetData('regattas');
regattas.sort(function(a,b){ return b.date.localeCompare(a.date); });
for (var ri in regattas) {
var regatta = regattas[ri];
var date = parseDate(regatta.date);
if ((date < parseDate('01.01.' + year)) || (date > parseDate('31.12.' + year))) {
continue;
}
if (regatta.name.toLowerCase().indexOf(r.quali_search.toLowerCase()) >= 0) {
console.log('FOUND', regatta);
beginn = ((regatta.meldungSchluss != null) ? parseDate(regatta.meldungSchluss) : date);
break;
}
}
// END OF TODO
if (beginn !== null) {
from = new Date(beginn);
from.setFullYear(from.getFullYear() - 1);
from.setDate(from.getDate() - 13);
from = formatDate('Y-m-d', from);
to = new Date(beginn);
to.setDate(to.getDate() - 14);
to = formatDate('Y-m-d', to);
} else {
console.log('[rank] no regatta found');
from = year + '-12-31'; // reverse => no regattas will be found => no ranking
to = year + '-01-01';
break; // TODO: bessere Fehlermeldung - keine Regatta gefunden
}
break;
default: // TODO: bessere Fehlermeldung - tritt nur bei Fehlkonfiguration in DB auf
from = (year - 1) + '-12-01';
to = year + '-11-30';
break;
}
if (callSiteScript && (typeof siteScript === 'function')) {
history.replaceState(null, '', '?type=' + type + '&year=' + year)
siteScript();
var personMode = $('#select-personmode').val();
console.log('[rank] setting', from, to, altm, maxage, agestrict, agecrew);
$('#input-from').val(from);
$('#input-to').val(to);
$('#input-altm').val(altm);
$('#input-maxage').val(maxage == false ? '' : maxage);
$('#input-agestrict').prop('checked', agestrict);
$('#input-agecrew').prop('checked', agecrew);
if (callSiteScript && (typeof siteScript === 'function')) {
history.replaceState(null, '', '?year=' + year + '&type=' + type + '&pm=' + personMode);
showLoader();
siteScript();
}
}
}
resolve();
});
}
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)
var additional = '';
if ($('#input-maxage').val() != '') additional += '&maxage=' + $('#input-maxage').val();
if ($('#input-agestrict').prop('checked')) additional += '&agestrict=on';
if ($('#input-agecrew').prop('checked')) additional += '&agecrew=on';
history.replaceState(null, '', '?year=user&from=' + $('#input-from').val() + "&to=" + $('#input-to').val() + "&altm=" + $('#input-altm').val() + "&pm=" + $('#select-personmode').val() + additional)
showLoader();
siteScript();
}
}
function initSelects() {
var type = findGetParameter('type');
var year = findGetParameter('year');
if (type === null) type = 'year';
if (year === null) year = new Date().getFullYear();
return new Promise(async function(resolve) {
var year = findGetParameter('year');
var type = findGetParameter('type');
var personMode = parseInt(findGetParameter('pm'));
if (year === null) year = new Date().getFullYear();
if (type === null) type = 'year';
if (isNaN(personMode) || personMode < 0 || personMode > 2) personMode = 0;
$('#select-type').val(type);
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 yearFound = year == 'user';
var options = '<option value="user">Benutzerdefiniert</option>';
for (id in years) {
var y = years[id]['year'];
options += '<option value="' + y + '">' + y + '</option>';
if (year == y) yearFound = true;
}
$('#select-year').html(options);
$('#select-year').val(yearFound ? year : years[0]);
$('#select-year').html('<option value="' + year + '">' + year + '</option>');
$('#select-year').val(year);
$('#select-type').html('<option value="' + type + '">' + type + '</option>');
$('#select-type').val(type);
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);
}
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');
var altm = findGetParameter('altm');
if (altm === null) altm = 9;
$('#input-altm').val(altm).trigger('focusin').trigger('focusout');
var maxage = findGetParameter('maxage');
if (maxage === null) maxage = '';
$('#input-maxage').val(maxage).trigger('focusin').trigger('focusout');
var agestrict = findGetParameter('agestrict');
var agecrew = findGetParameter('agecrew');
$('#input-agestrict').prop('checked', agestrict !== null);
$('#input-agecrew').prop('checked', agecrew !== null);
}
selectChange(false);
options = '<option value="0">Steuerleuten</option>';
options += '<option value="1">Vorschotern</option>';
options += '<option value="2">allen Seglern</option>';
$('#select-personmode').html(options);
$('#select-personmode').val(personMode);
await selectChange(false);
resolve();
});
}
var firstCall = true;
@@ -228,7 +340,12 @@ async function drawList () {
var list = '';
rows.forEach(function (entry) {
if (entry == null) {
list += '<div><div align="center" class="color-highlight" style="white-space:normal;"><b>Ende der Rangliste gem&auml;&szlig; DSV-Ranglistenverordnung (min. m = 9 Wertungen)</b></div></div>';
var altm = $('#input-altm').val(); if (altm == '') altm = 9; else altm = parseInt(altm);
if (altm == 9) {
list += '<div><div align="center" class="color-highlight" style="white-space:normal;"><b>Ende der Rangliste gem&auml;&szlig; DSV-Ranglistenverordnung (min. m = 9 Wertungen)</b></div></div>';
} else {
list += '<div><div align="center" class="color-highlight" style="white-space:normal;"><b>Ende der Rangliste (min. m = ' + altm + ' Wertungen)</b></div></div>';
}
} else if (search($('#input-search').val(), entry.keywords)) {
list += entry.content;
}
@@ -240,27 +357,43 @@ async function drawList () {
var siteScript = async function() {
if (firstCall) {
firstCall = false;
initSelects();
$('#select-type').change(selectChange);
rankings = await dbGetData('rankings');
await initSelects();
$('#select-year').change(selectChange);
$('#select-type').change(selectChange);
$('#select-personmode').change(selectChange);
$('#button-show').click(buttonShowPressed);
$('#input-search').on('input', drawList);
}
var minDate = parseDate($('#input-from').val());
var maxDate = parseDate($('#input-to').val());
var jugend = $('#input-jugend').prop('checked');
var jugstrict = $('#input-jugstrict').prop('checked');
var dbRanking = await dbGetRanking(minDate, maxDate, jugend, jugstrict);
var altm = $('#input-altm').val(); if (altm == '') altm = 9; else altm = parseInt(altm);
var maxage = $('#input-maxage').val(); if (maxage == '') maxage = false; else maxage = parseInt(maxage);
var agestrict = $('#input-agestrict').prop('checked');
var agecrew = $('#input-agecrew').prop('checked');
var personMode = $('#select-personmode').val();
console.log('[rank] rank params:', minDate, maxDate, altm, maxage, agestrict, agecrew, personMode);
var dbRanking = await dbGetRanking(minDate, maxDate, maxage, agestrict, altm, agecrew, personMode);
ranking = dbRanking[0];
lastRanking = null;
lastRanking = null; // TODO: also for quali ranks
if (($('#select-type').val() == 'year') || ($('#select-type').val() == 'youth')) {
lastRanking = {};
var lYear = parseInt($('#select-year').val()) - 1;
var lMinDate = parseDate((lYear - 1) + '-12-01');
var lMaxDate = parseDate(lYear + '-11-30');
var lDbRanking = (await dbGetRanking(lMinDate, lMaxDate, jugend, jugstrict))[0];
var lDbRanking = (await dbGetRanking(lMinDate, lMaxDate, maxage, agestrict, altm, agecrew, personMode))[0];
for (var i in lDbRanking) {
lastRanking[lDbRanking[i].id] = lDbRanking[i].rank;
}
}
if ($('#select-type').val() == 'year2') {
lastRanking = {};
var lYear = parseInt($('#select-year').val()) - 1;
var lMinDate = parseDate(lYear + '-01-01');
var lMaxDate = parseDate(lYear + '-12-31');
var lDbRanking = (await dbGetRanking(lMinDate, lMaxDate, maxage, agestrict, altm, agecrew, personMode))[0];
for (var i in lDbRanking) {
lastRanking[lDbRanking[i].id] = lDbRanking[i].rank;
}
@@ -268,20 +401,6 @@ var siteScript = async function() {
var selectedYear = $('#select-year').val();
var years = await dbGetData('years');
years.sort(function (a, b) {
if (a['year'] > b['year']) return -1;
if (a['year'] < b['year']) return 1;
return 0;
});
var options = '';
for (id in years) {
var year = years[id]['year'];
options += '<option value="' + year + '">' + year + '</option>';
}
$('#select-year').html(options);
$('#select-year').val(selectedYear);
if (dbRanking[1].length > 0) {
$('#card-noresults').show();
list = '';
@@ -323,7 +442,7 @@ var siteScript = async function() {
if (entry['year'] != null) row.keywords.push(entry['year']);
if (club != null) row.keywords.push(club['kurz'], club['name']);
if (!dsvEnd && (entry.m < 9)) {
if (!dsvEnd && (entry.m < altm)) {
rows.push(null);
dsvEnd = true;
}

View File

@@ -0,0 +1,258 @@
var siteScript = async function() {
$('#card-nofactsinfo').hide();
$('#card-entryfee').hide();
$('#card-races').hide();
$('#card-races').find('p').remove();
$('#card-races').find('table').remove();
$('#card-times').hide();
$('#card-camping').hide();
$('#card-food').hide();
$('#card-text').hide();
var regattaId = findGetParameter('regatta');
if (regattaId == null) {
$('#h1-title').text('Regatta nicht gefunden');
hideLoader();
return;
}
var regatta = await dbGetData('regattas', regattaId);
if (regatta == null) {
$('#h1-title').text('Regatta nicht gefunden');
hideLoader();
return;
}
var dateFrom = parseDate(regatta['date']);
var dateTo = parseDate(regatta['date']);
dateTo.setDate(dateTo.getDate() + Math.max(parseInt(regatta['length']) - 1, 0));
$('#h1-title').text(regatta.name);
if (regatta.length < 1) {
if (formatDate('d.m', dateFrom) == '01.01') {
$('#p-title').html('<font class="color-red2-dark">Datum noch unklar</font>');
} else {
$('#p-title').html(formatDate('d.m.Y', dateFrom) + ' - <font class="color-red2-dark">Datum nicht final</font>');
}
} else {
$('#p-title').html(formatDate('d.m.Y', dateFrom) + ' - ' + formatDate('d.m.Y', dateTo));
}
if (regatta.facts != null) {
var facts = JSON.parse(regatta.facts);
// Meldegeld
if ('entry' in facts && 'price' in facts.entry) {
$('#card-entryfee').show();
var content = 'Meldegeld: <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.entry.price)) + '</b>';
if ('early' in facts.entry) {
content += '<br />vergünstigt: <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.entry.early)) + '</b> (bis ' + formatDate('d.m.Y', parseDate(regatta.meldungEarly)) + ')';
}
if ('late' in facts.entry) {
content += '<br />nach Meldeschluss (' + formatDate('d.m.Y', parseDate(regatta.meldungSchluss)) + '): <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.entry.late)) + '</b>';
}
$('#card-entryfee').find('p').html(content);
}
// Wettfahrten / Anzahl
if ('races' in facts && 'cnt' in facts.races) {
$('#card-races').show();
$('#card-races').find('.content').append('<p>Anzahl Wettfahrten: <b>' + facts.races.cnt + '</b></p>');
if ('days' in facts.races) {
var table = $('<table class="table table-striped table-bordered text-nowrap">');
var tbody = $('<tbody>');
for (var day in facts.races.days) {
var cnt = facts.races.days[day];
day = formatDate('D, j.', parseDate(day));
tbody.append('<tr><td>' + day + '</td><td><b>' + cnt + '</b></td></tr>')
}
table.append(tbody);
$('#card-races').find('.content').append(table);
}
}
// Wettfahrten / Racetimes
if ('racetimes' in facts) {
$('#card-races').show();
var table = $('<table class="table table-striped table-bordered mb-0 text-nowrap">');
var tbody = $('<tbody>');
if ('sollzeit' in facts.racetimes) {
tbody.append('<tr><td>Sollzeit</td><td>' + facts.racetimes.sollzeit + ' min</td></tr>');
}
if ('zeitlimit' in facts.racetimes) {
tbody.append('<tr><td>Zeitlimit</td><td>' + facts.racetimes.zeitlimit + ' min</td></tr>');
}
if ('zielzeitfenster' in facts.racetimes) {
tbody.append('<tr><td>Zielzeitfenster</td><td>' + facts.racetimes.zielzeitfenster + ' min</td></tr>');
}
table.append(tbody);
$('#card-races').find('.content').append(table);
}
// Zeitplan
if ('times' in facts) {
$('#card-times').show();
var tbody = $('#card-times').find('table').find('tbody');
tbody.html('');
if ('checkin' in facts.times) {
tbody.append('<tr><td colspan="2" style="text-align: center; font-weight: bold;">Registrierung</td></tr>');
for (var day in facts.times.checkin) {
var times = facts.times.checkin[day];
day = formatDate('D, j.', parseDate(day));
var content = '';
if ('from' in times && 'to' in times) content = times.from + ' bis ' + times.to; // TODO:
else if ('from' in times) content = 'ab ' + times.from;
else if ('to' in times) content = 'bis ' + times.to;
tbody.append('<tr><td>' + day + '</td><td>' + content + '</td></tr>')
}
}
if ('measurements' in facts.times) {
tbody.append('<tr><td colspan="2" style="text-align: center; font-weight: bold;">Vermessung</td></tr>');
for (var day in facts.times.measurements) {
var times = facts.times.measurements[day];
day = formatDate('D, j.', parseDate(day));
var content = '';
if ('from' in times && 'to' in times) content = times.from + ' bis ' + times.to; // TODO:
else if ('from' in times) content = 'ab ' + times.from;
else if ('to' in times) content = 'bis ' + times.to;
tbody.append('<tr><td>' + day + '</td><td>' + content + '</td></tr>')
}
}
if ('helmmeeting' in facts.times) {
tbody.append('<tr><td colspan="2" style="text-align: center; font-weight: bold;">Steuerleutebesprechung</td></tr>');
for (var day in facts.times.helmmeeting) {
var time = facts.times.helmmeeting[day];
day = formatDate('D, j.', parseDate(day));
tbody.append('<tr><td>' + day + '</td><td>' + time + '</td></tr>')
}
}
if ('firststart' in facts.times) {
tbody.append('<tr><td colspan="2" style="text-align: center; font-weight: bold;">Erster Start</td></tr>');
for (var day in facts.times.firststart) {
var time = facts.times.firststart[day];
day = formatDate('D, j.', parseDate(day));
tbody.append('<tr><td>' + day + '</td><td>' + time + '</td></tr>')
}
}
if ('laststart' in facts.times) {
tbody.append('<tr><td colspan="2" style="text-align: center; font-weight: bold;">Letzter Start</td></tr>');
for (var day in facts.times.laststart) {
var time = facts.times.laststart[day];
day = formatDate('D, j.', parseDate(day));
tbody.append('<tr><td>' + day + '</td><td>' + time + '</td></tr>')
}
}
}
// Camping
if ('camping' in facts) {
$('#card-camping').show();
$('#card-camping').find('p').remove();
if ('tent' in facts.camping) {
var content = '';
if ('price' in facts.camping.tent && facts.camping.tent.price > 0) {
content += 'Zelten möglich für <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.camping.tent.price)) + '</b>';
}
else if ('pricepernight' in facts.camping.tent) {
content += 'Zelten möglich für <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.camping.tent.pricepernight)) + ' pro Nacht</b>';
}
else {
content += 'Zelten möglich und im Preis enthalten';
}
if ('electricity' in facts.camping.tent) {
content += '<br />';
if (facts.camping.tent.electricity > 0) {
content += 'Strom: <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.camping.tent.electricity)) + '</b>';
}
else {
content += 'Strom inklusive';
}
}
$('#card-camping').find('.content').append('<p>' + content + '</p>');
}
if ('van' in facts.camping) {
var content = '';
if ('price' in facts.camping.van && facts.camping.van.price > 0) {
content += 'Wohnwagen/-mobil möglich für <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.camping.van.price)) + '</b>';
}
else if ('pricepernight' in facts.camping.van) {
content += 'Wohnwagen/-mobil möglich für <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.camping.van.pricepernight)) + ' pro Nacht</b>';
}
else {
content += 'Wohnwagen/-mobil möglich und im Preis enthalten';
}
if ('electricity' in facts.camping.van) {
content += '<br />';
if (facts.camping.van.electricity > 0) {
content += 'Strom: <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.camping.van.electricity)) + '</b>';
}
else {
content += 'Strom inklusive';
}
}
$('#card-camping').find('.content').append('<p>' + content + '</p>');
}
if ('beds' in facts.camping) {
var content = '';
if ('price' in facts.camping.beds && facts.camping.beds.price > 0) {
content += 'Betten im Clubhaus vorhanden für <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.camping.beds.price)) + '</b>';
}
else if ('pricepernight' in facts.camping.beds) {
content += 'Betten im Clubhaus vorhanden für <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(facts.camping.beds.pricepernight)) + ' pro Nacht</b>';
}
else {
content += 'Betten im Clubhaus vorhanden und im Preis enthalten';
}
$('#card-camping').find('.content').append('<p>' + content + '</p>');
}
if ('text' in facts.camping) {
var p = $('<p>');
p.text(facts.camping.text);
p.html(p.html().replace(/\n/g, '<br />'));
$('#card-camping').find('.content').append(p);
}
}
// Verpflegung
if ('food' in facts) {
$('#card-food').show();
$('#card-food').find('p').remove();
for (var day in facts.food) {
var food = facts.food[day];
if (day == 'text') {
var p = $('<p>');
p.text(food);
p.html(p.html().replace(/\n/g, '<br />'));
$('#card-food').find('.content').append(p);
}
else {
day = formatDate('D, j.', parseDate(day));
var content = '';
if ('breakfast' in food) {
content += 'Frühstück am ' + day;
if (food.breakfast > 0) content += ' für <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(food.breakfast)) + '</b><br />';
else content += ' inklusive<br />';
}
if ('dinner' in food) {
content += 'Abendessen';
if ('dinnerdesc' in food) content += ' (' + food.dinnerdesc + ')';
content += ' am ' + day;
if (food.dinner > 0) content += ' für <b>' + (new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(food.dinner)) + '</b><br />';
else content += ' inklusive<br />';
}
$('#card-food').find('.content').append('<p>' + content + '</p>');
}
}
}
// Weitere Informationen
if ('text' in facts) {
$('#card-text').show();
var p = $('#card-text').find('p');
p.text(facts.text);
p.html(p.html().replace(/\n/g, '<br />'));
}
} else {
$('#card-nofactsinfo').show();
}
hideLoader();
}

View File

@@ -38,6 +38,12 @@ var siteScript = async function() {
tbody += '<td>' + (await dbGetData('users', planning.user)).username + '</td>';
if (planning.boat != null) {
tbody += '<td>' + (await dbGetData('boats', planning.boat)).sailnumber + '</td>';
} else {
tbody += '<td>(noch unklar)</td>';
}
if (planning.steuermann != null) {
tbody += '<td>' + (await dbGetData('sailors', planning.steuermann)).name + '</td>';
} else {

View File

@@ -1,3 +1,10 @@
Element.prototype.documentOffsetTop = function() {
return this.offsetTop + (this.offsetParent ? this.offsetParent.documentOffsetTop() : 0);
};
function scrollToToday() {
window.scrollTo({ top: document.getElementById('div-today').documentOffsetTop() - (window.innerHeight / 2), behavior: 'smooth' });
}
function selectChange(callSiteScript = true) {
var val = $('#select-year').val();
if (val == "user") {
@@ -14,6 +21,7 @@ function selectChange(callSiteScript = true) {
if (callSiteScript && (typeof siteScript === 'function')) {
history.replaceState(null, '', '?year=' + val);
showLoader();
siteScript();
}
}
@@ -21,28 +29,33 @@ function selectChange(callSiteScript = true) {
function buttonShowPressed() {
if (typeof siteScript === 'function') {
history.replaceState(null, '', '?year=user&from=' + $('#input-from').val() + "&to=" + $('#input-to').val())
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);
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');
}
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);
selectChange(false);
resolve();
});
}
var firstCall = true;
@@ -54,7 +67,7 @@ async function drawList () {
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>';
list += '<div><div id="div-today" 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;
}
@@ -66,10 +79,11 @@ async function drawList () {
var siteScript = async function() {
if (firstCall) {
firstCall = false;
initYear();
await initYear();
$('#select-year').change(selectChange);
$('#button-show').click(buttonShowPressed);
$('#input-search').on('input', drawList);
$('#button-totoday').click(scrollToToday);
}
today = getToday();
@@ -77,12 +91,9 @@ 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);
}
if (minDate <= today && maxDate >= today) $('#button-totoday').parent().parent().show();
else $('#button-totoday').parent().parent().hide();
var selectedYear = $('#select-year').val();
@@ -113,6 +124,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];
@@ -150,7 +164,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 = [];
@@ -194,7 +238,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('&ensp;') + '</div>';
@@ -227,12 +271,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();

View File

@@ -4,6 +4,40 @@ 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');
@@ -50,6 +84,26 @@ async function onListClicked(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
$('#button-edityear').attr('data-sailor-id', sailor.id);
$('#menu-edityear').find('.menu-title').find('p').text(sailor.name);
@@ -134,6 +188,17 @@ var siteScript = async function() {
$('#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);
var follows = await dbGetData('follows');
followedSailors = [];
for (var i in follows) {
followedSailors.push(await dbGetData('sailors', follows[i].sailor));
}
}
var results = await dbGetData('sailors');

View File

@@ -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>

View File

@@ -1,5 +1,5 @@
<?php
define('PWA_VERSION', '1.9.2');
define('PWA_VERSION', '1.13h4');
?>

View File

@@ -182,9 +182,9 @@ function getEntry(data, index, defaultValue) {
return ((typeof data[index] !== "undefined") ? data[index] : defaultValue);
}
function isMyRegatta(id) {
function isMyRegatta(id, suffix = '') {
return new Promise(async function (resolve) {
var regattas = await dbSettingsGet('myregattas_<?php echo BOATCLASS; ?>');
var regattas = await dbSettingsGet('myregattas_<?php echo BOATCLASS; ?>' + suffix);
if (regattas == null) resolve(false);
else resolve(regattas.includes(id.toString()));
});
@@ -228,15 +228,15 @@ self.addEventListener('push', async function(event) {
break;
case 'meldeschluss':
if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_meldeschluss')) {
if (await isMyRegatta(getEntry(data, 'id', ''))) okay = true;
if (await isMyRegatta(getEntry(data, 'id', ''), '_meldung_off')) okay = true;
}
break;
default:
console.log('Unknown channel:', data.channel);
console.log('[sW] Unknown channel:', data.channel);
break;
}
if (!okay) {
console.log('Notification channel not subscribed');
console.log('[sW] Notification channel not subscribed');
return;
}
@@ -255,7 +255,7 @@ self.addEventListener('push', async function(event) {
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: 0 });
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();
@@ -267,7 +267,7 @@ self.addEventListener('push', async function(event) {
}
}
console.log('Showing notification');
console.log('[sW] Showing notification');
self.registration.showNotification(data.title, options);
break;
@@ -276,7 +276,7 @@ self.addEventListener('push', async function(event) {
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: 0 });
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();
@@ -310,3 +310,16 @@ self.addEventListener('notificationclick', function(event) {
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
})
);
});