342 Commits

Author SHA1 Message Date
Philip
15c9d589fe serializer 2024-03-05 20:06:38 +03:00
Philip
fa116c08c1 fix task 2024-03-05 13:47:36 +03:00
Philip
4f9129e718 sample 2024-02-28 14:10:20 +03:00
Philip
df45f3a704 not found 2024-02-25 13:41:26 +03:00
Philip
90ef093fca supscriptions 2024-02-24 19:54:57 +03:00
4331b26542 0.1.362 fix language bug redirect to main page 2024-02-22 18:54:15 +03:00
SDE
dd8a8ddd53 0.12.26 get_phone_valid_error change 2024-02-21 17:12:45 +03:00
SBD
abb0d488eb 14 2024-02-21 15:10:34 +03:00
SBD
be97b848d0 14 2024-02-21 14:56:25 +03:00
SBD
6bc112d689 13 2024-02-21 14:37:31 +03:00
SBD
dc534a0c51 12 2024-02-21 14:21:48 +03:00
SDE
e71ed05e6c 0.12.25 timezone in chat messages 2024-02-21 14:12:03 +03:00
SBD
2048ed6baf 11 2024-02-20 19:31:10 +03:00
SBD
c146bd6155 10 2024-02-20 18:57:17 +03:00
SBD
98665abf4d 9 2024-02-20 18:27:36 +03:00
SBD
9954140d3a 9 2024-02-20 17:43:08 +03:00
SBD
fafee63a64 7 2024-02-20 17:35:01 +03:00
c623d69767 0.1.361 comment red marker on mobile_header temp 2024-02-12 17:22:24 +03:00
670eb28bc0 0.1.360 add red marker on mobile_header temp 2024-02-12 17:17:21 +03:00
144ff286f6 0.1.359 add red marker on mobile_header temp 2024-02-12 17:12:44 +03:00
05f94de0b4 Merge remote-tracking branch 'origin/main' 2024-02-12 16:09:24 +03:00
c4650ce603 0.1.358 upd profile_button width 2024-02-12 16:09:13 +03:00
SDE
3971a8ee23 0.12.24 timezone in chat messages 2024-02-09 20:33:04 +03:00
SDE
a3ba6bc783 0.12.23 timezone in chat messages 2024-02-09 18:18:21 +03:00
SDE
b87df02714 0.12.22 timezone in chat messages 2024-02-09 18:01:11 +03:00
SDE
713695cf7d 0.12.21 timezone in chat messages 2024-02-09 17:00:28 +03:00
SDE
a25f30eda7 0.12.20 timezone in chat messages 2024-02-09 16:57:27 +03:00
SDE
eddb3a1858 0.12.19 timezone in chat messages 2024-02-09 15:12:10 +03:00
SDE
5a89200f1d Merge remote-tracking branch 'origin/main' 2024-02-08 14:51:27 +03:00
SDE
2f47a9e3db 0.12.18 registration mail to user 2024-02-08 14:51:19 +03:00
155b6272ec 0.1.357 upd mobile_styles.css for menu_profile 2024-02-08 14:20:50 +03:00
SDE
1479584bfc 0.12.17 change_avatar_confirm_ajax RequestDataTooBig 2024-02-05 23:02:11 +03:00
SDE
f86be5bd97 Merge remote-tracking branch 'origin/main' 2024-02-05 22:41:58 +03:00
SDE
c87a7095ad 0.12.16 change_avatar_confirm_ajax RequestDataTooBig 2024-02-05 22:41:50 +03:00
ac4df7a5f7 0.1.356 upd text_block 2024-02-05 14:34:15 +03:00
SDE
c48839ff8c 0.12.15 subscribe mailing 2024-02-02 18:50:51 +03:00
SDE
ea296e3f05 0.12.14 subscribe mailing 2024-02-02 18:15:51 +03:00
SDE
8124ed62fe 0.12.13 subscribe mailing 2024-02-02 18:08:28 +03:00
SDE
cc643d2641 0.12.12 subscribe mailing 2024-02-02 18:06:35 +03:00
SDE
6de42c5ba9 Merge remote-tracking branch 'origin/main' 2024-02-02 17:44:50 +03:00
SDE
36b7f4dee7 0.12.11 subscribe mailing 2024-02-02 17:44:43 +03:00
2328f09023 0.1.355 mailingSubscribeRequired functional UPD 2024-02-02 17:41:01 +03:00
60faeeace9 Merge remote-tracking branch 'origin/main' 2024-02-02 17:37:35 +03:00
abe53dd88b 0.1.354 mailingSubscribeRequired functional 2024-02-02 17:37:25 +03:00
SDE
c76a18c5ff Merge remote-tracking branch 'origin/main' 2024-02-02 15:51:45 +03:00
SDE
3725ce1882 0.12.10 routes order 2024-02-02 15:51:37 +03:00
6a69ff02b1 0.1.353 add font-display for lcp test 2024-02-02 15:04:30 +03:00
6ba41af305 0.1.352 small bug_fix 2024-02-02 12:50:59 +03:00
SDE
5815a08b55 0.12.9 subscribe mailing 2024-02-01 19:13:26 +03:00
SDE
7805161829 0.12.8 subscribe mailing 2024-02-01 19:07:48 +03:00
6fa31f3866 Merge remote-tracking branch 'origin/main' 2024-02-01 18:51:01 +03:00
0763faf224 0.1.351 upd footer 2024-02-01 18:50:28 +03:00
SDE
a3d3e12467 0.12.7 subscribe mailing 2024-02-01 18:43:16 +03:00
SDE
ab22a3ec88 0.12.6 subscribe mailing 2024-02-01 18:32:29 +03:00
SDE
9d0a059909 0.12.5 subscribe mailing 2024-02-01 18:24:02 +03:00
SDE
1011f112b2 0.12.4 subscribe mailing 2024-02-01 17:49:57 +03:00
SDE
d07ab2c71f Merge remote-tracking branch 'origin/main' 2024-02-01 17:46:55 +03:00
SDE
96bfef04a8 0.12.3 subscribe mailing 2024-02-01 17:46:44 +03:00
SBD
779dd7e93d 7 2024-02-01 15:06:05 +03:00
SBD
0abcb34829 7 2024-02-01 14:58:26 +03:00
SBD
33c028207a 6 2024-02-01 14:36:08 +03:00
SBD
64b3e40ed0 6 2024-02-01 14:14:35 +03:00
SBD
0023676b28 Merge remote-tracking branch 'origin/main' 2024-02-01 13:26:53 +03:00
SBD
b90039f21a 5 2024-02-01 13:26:42 +03:00
b5f24ebf2e 0.1.350 small upd for .css 2024-01-31 17:49:03 +03:00
SBD
f99a010e4a 5 2024-01-31 17:17:53 +03:00
SBD
a4944360a6 5 2024-01-31 17:13:15 +03:00
SBD
a2b5d81c98 5 2024-01-31 17:11:12 +03:00
SBD
13b7c2572d Merge remote-tracking branch 'origin/main' 2024-01-31 16:57:06 +03:00
SBD
47b12882ba 5 2024-01-31 16:56:57 +03:00
SDE
c008aa585b Merge remote-tracking branch 'origin/main' 2024-01-31 16:39:12 +03:00
SDE
406b5e8480 0.12.2 registration mail 2024-01-31 16:39:03 +03:00
SBD
584a196784 5 2024-01-31 15:20:50 +03:00
SBD
618f7751d1 5 2024-01-31 15:20:20 +03:00
SBD
faaea1129a 5 2024-01-31 15:11:39 +03:00
SBD
dd7afc28f7 5 2024-01-31 15:00:48 +03:00
SBD
9ecf5ce073 5 2024-01-31 14:55:04 +03:00
SBD
422373f00e 5 2024-01-31 14:46:18 +03:00
SBD
60636daeb8 Merge remote-tracking branch 'origin/main' 2024-01-31 14:40:19 +03:00
SBD
9d47f4c2bc 5 2024-01-31 14:40:11 +03:00
SDE
4d6dbddd28 Merge remote-tracking branch 'origin/main' 2024-01-31 14:37:49 +03:00
SDE
3f00ff39d2 0.12.1 fix form from and to place fields choices 2024-01-31 14:37:41 +03:00
SBD
bff6a81586 Merge remote-tracking branch 'origin/main' 2024-01-31 14:12:55 +03:00
SBD
9cb8036d3c 3 2024-01-31 14:12:44 +03:00
SDE
a43de1fa91 Merge remote-tracking branch 'origin/main' 2024-01-31 13:44:18 +03:00
SDE
93717bee2d 0.12.11 del mobile markers for response 2024-01-31 13:44:08 +03:00
SBD
8db1d6fdce 3 2024-01-31 13:41:47 +03:00
SBD
b41f8c7eca 3 2024-01-31 13:37:31 +03:00
SBD
c19405d32a Merge remote-tracking branch 'origin/main' 2024-01-31 13:24:02 +03:00
SBD
7b75c533a8 3 2024-01-31 13:23:50 +03:00
SDE
649dbab901 0.12.10 fix allauth google cancel 2024-01-26 19:02:17 +03:00
SDE
1a4498d19f 0.12.9 fix allauth google cancel 2024-01-26 19:00:47 +03:00
SDE
2786ef454d Merge remote-tracking branch 'origin/main' 2024-01-26 18:26:52 +03:00
SDE
961c0dd2a5 0.12.8 switch off push for static pages 2024-01-26 18:26:37 +03:00
SBD
0a0835d3a6 3 2024-01-26 18:20:25 +03:00
SBD
bc87d10d59 Merge remote-tracking branch 'origin/main' 2024-01-26 18:14:50 +03:00
SBD
792693848b 2 2024-01-26 18:14:41 +03:00
SDE
de229c5f78 0.12.7 chat fixes 2024-01-26 17:45:48 +03:00
SDE
03f9a836e6 0.12.6 chat fixes 2024-01-26 17:09:42 +03:00
SBD
91751574cc 1 2024-01-26 16:31:58 +03:00
d5453dada6 0.1.349 small upd 2024-01-26 14:37:50 +03:00
22adb18a39 Merge remote-tracking branch 'origin/main' 2024-01-26 13:59:36 +03:00
0a3c40dd5d 0.1.348 upd input_list for main page 2024-01-26 13:58:51 +03:00
SBD
b29825d62b correct titles 2024-01-26 13:29:05 +03:00
c9bda8aab2 Merge remote-tracking branch 'origin/main' 2024-01-26 13:06:30 +03:00
284a4b064a 0.1.347 update show_contact button behavior 2024-01-26 13:06:17 +03:00
SBD
6f20f53d75 ws changes 2024-01-26 12:47:46 +03:00
SDE
473a047af9 Merge remote-tracking branch 'origin/main' 2024-01-25 18:36:29 +03:00
SDE
481f9a881f 0.12.5 google auth fix 2024-01-25 18:36:15 +03:00
6ceedddbc1 0.1.346 add border for input_list. Change color and width for scroll-bar v2 2024-01-25 17:05:01 +03:00
bd9e0fad48 0.1.345 add border for input_list. Change color and width for scroll-bar 2024-01-25 16:50:36 +03:00
6b118d00b6 0.1.344 hide div with phone number 2024-01-25 15:39:15 +03:00
01e221196f 0.1.343 small bug fix with buttons style v.2 2024-01-25 14:57:26 +03:00
ccf016999b 0.1.342 small bug fix with buttons style 2024-01-25 14:51:49 +03:00
SBD
cb79e47796 Merge remote-tracking branch 'origin/main' 2024-01-23 18:05:57 +03:00
SBD
4076bd6065 ws changes 2024-01-23 18:05:45 +03:00
e54c258007 Merge remote-tracking branch 'origin/main' 2024-01-23 17:15:15 +03:00
c3b7401255 0.1.341 upd text for main page, customer/mover page. Add new png for main page 2024-01-23 17:15:04 +03:00
SDE
9af72d30f4 0.12.4 ws fix 2024-01-22 18:10:32 +03:00
SDE
dbe948ae5f Merge remote-tracking branch 'origin/main' 2024-01-22 18:09:04 +03:00
SDE
885d36a90c 0.12.3 ws fix 2024-01-22 18:08:55 +03:00
SBD
7acfbc0113 Merge remote-tracking branch 'origin/main' 2024-01-22 17:41:33 +03:00
SBD
43c5faf988 took wss 2024-01-22 17:41:17 +03:00
SDE
437142fba0 Merge remote-tracking branch 'origin/main' 2024-01-22 17:32:10 +03:00
SDE
acf7b702ee 0.12.2 ws fix 2024-01-22 17:32:03 +03:00
74ca1be884 Merge remote-tracking branch 'origin/main' 2024-01-19 13:18:30 +03:00
26b987d6ce 0.1.340 upd text and add href for customer button 2024-01-19 13:18:09 +03:00
SDE
3f7f1d88ed 0.12.1 addsense register 2024-01-18 20:13:52 +03:00
SDE
59225b1688 Merge remote-tracking branch 'origin/main' 2024-01-18 20:11:54 +03:00
SDE
108aee2c43 0.12.0 addsense register 2024-01-18 20:11:45 +03:00
9062ce32a1 Merge remote-tracking branch 'origin/main' 2024-01-18 14:09:46 +03:00
7c74a0f3fe 0.1.339 slice name/surname if it longer then 5 character 2024-01-18 14:08:48 +03:00
SDE
4fb3a12f47 0.11.22 push w link 2024-01-18 13:15:28 +03:00
SDE
59bc25f31c 0.11.21 push w link 2024-01-16 17:25:40 +03:00
SDE
87fbe7852c 0.11.20 push w link 2024-01-16 16:53:01 +03:00
SDE
793d283d97 0.11.19 Google Auth 2024-01-15 19:31:30 +03:00
SDE
651ae18345 0.11.18 Google Auth 2024-01-15 17:44:59 +03:00
SDE
67eb32968e 0.11.17 Google Auth 2024-01-15 17:43:18 +03:00
SDE
c6d41513c0 0.11.16 Google Auth 2024-01-15 17:27:48 +03:00
SDE
67ba698b60 0.11.15 Google Auth 2024-01-15 17:06:53 +03:00
SDE
15d1c00ac6 0.11.14 Google Auth 2024-01-15 16:56:18 +03:00
SDE
9e9a82ffc0 0.11.13 Google Auth 2024-01-15 16:51:38 +03:00
SDE
a0eb5210ab 0.11.12 Google Auth 2024-01-15 16:47:53 +03:00
SDE
3dacc0316e Merge remote-tracking branch 'origin/main' 2024-01-15 16:36:59 +03:00
SDE
e2c347c912 0.11.11 Google Auth 2024-01-15 16:36:51 +03:00
758f8b1f55 0.1.338 upd style for cards_item 2024-01-15 13:43:38 +03:00
SDE
b446a8f519 0.11.10 Google Auth 2024-01-13 21:24:58 +03:00
SDE
c8ba0dd770 0.11.9 Google Auth 2024-01-13 21:15:05 +03:00
SDE
f13a1329ca 0.11.8 Google Auth 2024-01-13 21:13:06 +03:00
SDE
4b3604098f 0.11.7 Google Auth 2024-01-13 21:12:04 +03:00
SDE
defbf6746f 0.11.6 Google Auth 2024-01-13 18:04:01 +03:00
SDE
bf3f26ec4f 0.11.5 Google Auth 2024-01-13 18:01:34 +03:00
SDE
76018333b0 0.11.4 Google Auth 2024-01-13 17:29:21 +03:00
SDE
e6e345b9fe 0.11.3 Google Auth 2024-01-13 17:27:32 +03:00
SDE
eafccabb66 0.11.2 Google Auth 2024-01-13 17:26:25 +03:00
SDE
f2e0628de1 0.11.1 Google Auth 2024-01-13 17:05:57 +03:00
SDE
2e1f3a10ab 0.11.0 Google Auth 2024-01-13 14:49:32 +03:00
bf18c96dbd 0.1.337 add google authorization button 2024-01-13 14:12:25 +03:00
23718a5f3f 0.1.336 upd cards_item for main page 2024-01-13 13:46:58 +03:00
c6a1d5bdcf Merge remote-tracking branch 'origin/main' 2024-01-12 17:42:00 +03:00
f75e94f706 0.1.335 upd cards_wrapper on main page 2024-01-12 17:41:48 +03:00
SBD
11c9bb6c23 took wss 2024-01-12 17:01:50 +03:00
SBD
b1ff9c47da Merge remote-tracking branch 'origin/main' 2024-01-12 16:49:47 +03:00
SBD
35c09dc70b check post csrf8 2024-01-12 16:49:38 +03:00
SDE
f0efae5987 0.10.7 fix 403 2024-01-12 16:44:51 +03:00
SDE
65120cd2d4 0.10.6 fix 403 2024-01-12 16:41:43 +03:00
SBD
231d062814 check post csrf7 2024-01-12 16:32:00 +03:00
SBD
615922a881 check post csrf6 2024-01-12 16:28:49 +03:00
SBD
61b2b824d5 check post csrf5 2024-01-12 16:21:11 +03:00
SBD
317445998a check post csrf4 2024-01-12 16:16:27 +03:00
SBD
4ad3813499 check post csrf3 2024-01-12 16:11:35 +03:00
SBD
9a88243323 Merge remote-tracking branch 'origin/main' 2024-01-12 15:58:42 +03:00
SBD
df0f32c71a check post csrf2 2024-01-12 15:58:34 +03:00
SDE
4ddd402442 0.10.5 fix 403 2024-01-12 15:55:09 +03:00
SBD
a05c4b3898 Merge remote-tracking branch 'origin/main' 2024-01-12 15:50:54 +03:00
SBD
a3ab0973c9 check post csrf1 2024-01-12 15:50:43 +03:00
SDE
0f801aa44b 0.10.4 monkey patching fix 403 2024-01-12 02:28:51 +03:00
SBD
7bc386bc44 Merge remote-tracking branch 'origin/main' 2024-01-11 19:37:48 +03:00
SBD
e148c60d70 add cookie 3 2024-01-11 19:37:39 +03:00
SDE
4667352ec4 0.10.3 fix websocet with ssl 2024-01-11 19:34:34 +03:00
SBD
e7cf694d88 add cookie 2 2024-01-11 19:31:14 +03:00
SBD
b2abb3046b add cookie 2024-01-11 19:10:30 +03:00
SDE
6c1011e59e 0.10.2 mail alert by new routes 2024-01-11 19:03:25 +03:00
ad909b98bf 0.1.334 save checked after reload in receive_msg_by_email 2024-01-11 15:27:14 +03:00
9d2e35246a 0.1.333 upd 404_page and create conditions for unfound routes 2024-01-11 15:14:45 +03:00
48dc573c0f 0.1.334 upd text for unfinded routes 2024-01-11 13:45:20 +03:00
SBD
e559660912 Merge remote-tracking branch 'origin/main' 2024-01-09 22:01:13 +03:00
SBD
aa3bec304a correct work curtain 2024-01-09 22:01:00 +03:00
c7bc22813f 0.1.333 upd 404_page and create conditions for unfound routes 2024-01-09 13:03:30 +03:00
SDE
46e73db10a 0.10.1 browser push messages 2024-01-08 15:08:46 +03:00
SDE
ad451c2ae0 0.10.0 browser push messages 2024-01-08 14:54:59 +03:00
SDE
0b5b557a35 0.9.0 404 prepare 2024-01-08 13:22:11 +03:00
SBD
fb9228c432 correct work curtain 2024-01-06 14:48:31 +03:00
SBD
fbcbe93042 correct work curtain 2024-01-06 14:37:34 +03:00
ca44deb077 0.0.332 upd text on main_page 2024-01-04 14:50:25 +03:00
61403bfac2 0.0.331 set white background-color for input_list 2024-01-03 13:20:25 +03:00
SBD
190efa4b74 mobile === false 2023-12-29 21:30:03 +05:00
SBD
ca06836b11 mobile === false 2023-12-29 21:06:08 +05:00
SBD
b31241872f mobile === false 2023-12-29 19:45:43 +05:00
SBD
f80e2844bf mobile === false 2023-12-29 12:49:13 +05:00
1dae86f0e7 0.0.330 add color for title in my_routes 2023-12-21 16:28:42 +03:00
0c146caeef 0.0.329 upd logic for from_to_country inputs in b_new_route 2023-12-20 14:18:31 +03:00
410733211b 0.0.328 fix bug in lalble b_new_route.html | upd style title for routes on main page | commented out the code in b_chats.html for i icon 2023-12-20 14:03:59 +03:00
14df8969c2 0.0.327 upd title on main page 2023-12-18 16:08:09 +03:00
SBD
4388414ac2 correct work icons right or left of the curtain 2023-12-17 08:42:50 +03:00
SBD
791ac8d436 correct work curtain at routes_find_routes 2023-12-17 08:39:47 +03:00
a3d6f498b1 0.0.326 upd change_profile 2023-12-15 16:56:14 +03:00
SDE
b8fdd61948 0.8.43 change profile validation 2023-12-15 16:12:34 +03:00
SDE
4437372d7c 0.8.42 change profile validation 2023-12-15 16:03:27 +03:00
SDE
f8d29d80b7 0.8.41 change profile validation 2023-12-15 15:56:51 +03:00
SDE
36fd9599af 0.8.40 change profile validation 2023-12-15 15:46:46 +03:00
65eccde487 0.0.326 upd change_profile 2023-12-15 15:44:23 +03:00
SDE
037b4cc562 0.8.39 change profile validation 2023-12-15 15:28:29 +03:00
SDE
9c971a6fa4 0.8.38 change profile validation 2023-12-15 15:11:35 +03:00
SBD
a3faa17754 Merge remote-tracking branch 'origin/main' 2023-12-13 17:59:25 +03:00
SBD
085f905125 correct work curtain at routes_find_routes 2023-12-13 17:57:00 +03:00
dc16ced786 0.0.325 hide scroll for mozilla 2023-12-12 17:06:05 +03:00
d5cba26098 0.0.324 2023-12-12 16:50:52 +03:00
001dd2cb87 0.0.323 2023-12-12 16:34:00 +03:00
16e860a29f 0.0.322 upd lable for b_new_route.html 2023-12-12 16:01:01 +03:00
SDE
6a5331d8eb 0.8.37 owner_type initial 2023-12-07 18:35:06 +03:00
aff0b0fe98 0.0.321 2023-12-07 16:54:57 +03:00
fd3612c370 0.0.320 2023-12-06 18:03:48 +03:00
d14a46d3d7 0.0.319 upd create_route, header_buttons alight 2023-12-06 15:51:55 +03:00
SBD
d7ace77de8 0.8.482 2023-12-05 22:17:49 +03:00
SBD
885e4722af 0.8.481 2023-12-05 21:11:36 +03:00
SBD
72ed6369d8 0.8.479 2023-12-05 20:24:07 +03:00
b23e440efd 0.0.318 work with datarangepicker.js 2023-12-05 20:16:44 +03:00
75ddb002fd Merge remote-tracking branch 'origin/main' 2023-12-05 18:52:58 +03:00
28a36335ce 0.0.317 locale for datarangepicker.js 2023-12-05 18:52:52 +03:00
SDE
fba225aa70 Merge remote-tracking branch 'origin/main' 2023-12-05 17:43:09 +03:00
SDE
af800ac84c 0.8.36 check dates when route create 2023-12-05 17:43:01 +03:00
87e90d7152 0.0.316 add new language flags 2023-12-05 16:58:32 +03:00
c25942a6ca 0.0.315 test with viewport 2023-12-05 15:24:46 +03:00
692419816f 0.0.314 test with viewport 2023-12-05 15:21:21 +03:00
3a109340fd 0.0.313 test with viewport 2023-12-05 14:59:44 +03:00
5925ecb975 0.0.312 test with viewport 2023-12-05 14:54:21 +03:00
325acd3580 0.0.311 add red color for changed input in from_to_addres_point 2023-12-05 14:38:25 +03:00
3ac85784a9 0.0.310 2023-12-05 13:48:41 +03:00
5c4e715970 Merge remote-tracking branch 'origin/main' 2023-12-05 13:39:38 +03:00
89b57feb4e 0.0.309 upd avatar for routes 2023-12-05 13:37:17 +03:00
SDE
fc194d3f85 0.8.35 order for city / country 2023-12-05 13:25:31 +03:00
SDE
12af0ea238 Merge remote-tracking branch 'origin/main' 2023-12-05 12:47:30 +03:00
SDE
6e758cf62e 0.8.34 fix route_search 2023-12-05 12:47:23 +03:00
f7783c070b Merge remote-tracking branch 'origin/main' 2023-12-05 12:45:26 +03:00
SBD
fb3cd30db4 0.8.478 2023-12-04 17:23:27 +03:00
ff949a8205 0.0.308 2023-12-03 21:02:13 +03:00
SBD
624653f581 Merge remote-tracking branch 'origin/main' 2023-12-03 20:57:56 +03:00
SBD
f3e5f02f07 0.8.477 2023-12-03 20:57:38 +03:00
d0792e9e84 Merge remote-tracking branch 'origin/main' 2023-12-03 20:56:38 +03:00
f752eb5d4a 0.0.307 clear errors for DT in create route. Change default select for main 2023-12-03 20:56:29 +03:00
SBD
f0861fde84 Merge remote-tracking branch 'origin/main' 2023-12-03 20:53:59 +03:00
SBD
4e7aa09c21 0.8.476 2023-12-03 20:53:48 +03:00
SDE
e68a0dc151 Merge remote-tracking branch 'origin/main' 2023-12-03 20:49:14 +03:00
SDE
fc37bea98a 0.8.33 tickets text 2023-12-03 20:49:07 +03:00
SBD
8a91e611ac Merge remote-tracking branch 'origin/main' 2023-12-03 20:43:24 +03:00
SBD
7208db6981 0.8.475 2023-12-03 20:43:13 +03:00
SDE
447a78cd3a 0.8.32 tickets text 2023-12-03 20:37:01 +03:00
SBD
95dff519b8 0.8.474 2023-12-03 20:36:20 +03:00
SBD
62aeebae95 0.8.473 2023-12-03 20:22:20 +03:00
SBD
c2e03728f8 0.8.472 2023-12-03 20:00:32 +03:00
SBD
a64fbab270 0.8.471 2023-12-03 19:59:15 +03:00
SBD
00ea16f631 0.8.470 2023-12-03 19:50:51 +03:00
SBD
e3aafcdfe9 0.8.469 2023-12-03 19:35:52 +03:00
SBD
421a3a2dab Merge remote-tracking branch 'origin/main' 2023-12-03 19:27:11 +03:00
SBD
61e4f7e450 0.8.468 2023-12-03 19:26:56 +03:00
SDE
3b52cab162 0.8.31 fix registration form 2023-12-03 19:07:49 +03:00
fe9be61772 Merge remote-tracking branch 'origin/main' 2023-12-03 18:59:00 +03:00
0818f880cc 0.0.306 upd registration error_msg 2023-12-03 18:58:54 +03:00
SBD
cca062efec Merge remote-tracking branch 'origin/main' 2023-12-03 18:33:34 +03:00
SBD
2eb7ac85d3 0.8.467 2023-12-03 18:33:23 +03:00
SDE
3469a3923c 0.8.30 fix registration form 2023-12-03 18:07:39 +03:00
SDE
20fb49b3e4 0.8.30 fix registration form 2023-12-03 17:47:29 +03:00
SDE
afe8feebc2 Merge remote-tracking branch 'origin/main' 2023-12-03 17:43:13 +03:00
SDE
ae6a68d85b 0.8.30 check password 2023-12-03 17:43:01 +03:00
SBD
d80c45acd5 0.8.466 2023-12-03 17:40:28 +03:00
3a9ac2c289 Merge remote-tracking branch 'origin/main' 2023-12-03 17:38:59 +03:00
2d68836724 0.0.305 set test_banners for news 2023-12-03 17:38:53 +03:00
SDE
0deb85b5a3 0.8.29 admin airport change city 2023-12-03 17:25:21 +03:00
SBD
7b38f6e3b3 Merge remote-tracking branch 'origin/main' 2023-12-03 17:21:23 +03:00
SBD
43f050f070 0.8.465 2023-12-03 17:21:12 +03:00
098b7c4fb5 Merge remote-tracking branch 'origin/main' 2023-12-03 17:15:32 +03:00
eae56199e0 0.0.304 rewrite news widget 2023-12-03 17:15:23 +03:00
SDE
71e8f0f465 Merge remote-tracking branch 'origin/main' 2023-12-03 17:12:49 +03:00
SBD
66d7183278 0.8.464 2023-12-03 17:12:35 +03:00
SDE
92b92f2d65 0.8.29 admin airport change city 2023-12-03 17:12:32 +03:00
SBD
d5ab7d82eb 0.8.463 2023-12-03 17:09:16 +03:00
SBD
1ebd9f9c0b Merge remote-tracking branch 'origin/main' 2023-12-03 16:53:30 +03:00
SBD
7fd2c60ddb 0.8.462 2023-12-03 16:53:23 +03:00
SDE
f068182557 0.8.28 switch off passanger in airport route 2023-12-03 16:37:24 +03:00
SBD
02945b0691 Merge remote-tracking branch 'origin/main' 2023-12-03 16:09:32 +03:00
SBD
21b959e6a3 0.8.461 2023-12-03 16:09:24 +03:00
SDE
747091c744 0.8.27 one article breadcrumbs 2023-12-03 15:39:52 +03:00
7b70052ff1 0.0.303 2023-12-03 15:26:08 +03:00
SBD
49fd26bc4c Merge remote-tracking branch 'origin/main' 2023-12-03 15:12:18 +03:00
SBD
77f365ef45 Merge remote-tracking branch 'origin/main' 2023-12-03 15:12:11 +03:00
SDE
6d34d46e38 0.8.26 one article breadcrumbs 2023-12-03 15:12:04 +03:00
SBD
970c2e0837 0.8.460 2023-12-03 15:11:33 +03:00
SDE
b87549d567 0.8.25 msgs admin list change 2023-12-03 15:06:47 +03:00
SBD
78abdb2fef 0.8.459 2023-12-03 14:46:34 +03:00
SBD
f73ebb08c9 Merge remote-tracking branch 'origin/main' 2023-12-03 14:39:16 +03:00
SBD
628e8eec09 0.8.458 2023-12-03 14:39:07 +03:00
66ddcaec5b Merge remote-tracking branch 'origin/main' 2023-12-03 14:38:29 +03:00
3901c82aae 0.0.302 clear ID of hide inputs in create/find routes 2023-12-03 14:38:23 +03:00
SBD
9f682b66a5 0.8.457 2023-12-03 14:24:15 +03:00
SBD
c74aff7b91 0.8.456 2023-12-03 13:52:49 +03:00
SBD
1be50b1277 Merge remote-tracking branch 'origin/main' 2023-12-03 13:34:01 +03:00
SDE
af00d1a54b 0.8.25 profile unredeaded messages 2023-12-03 13:32:21 +03:00
SBD
dd4ad82248 0.8.455 2023-12-03 13:18:49 +03:00
SBD
38c08cbced Merge remote-tracking branch 'origin/main' 2023-12-03 12:59:15 +03:00
SBD
ed2c74a280 0.8.454 2023-12-03 12:59:05 +03:00
SDE
90ab1bb6b4 Merge remote-tracking branch 'origin/main' 2023-12-03 12:55:22 +03:00
SDE
3e2220e5f2 0.8.24 articles main 3 elements 2023-12-03 12:55:10 +03:00
SBD
33e27620b1 0.8.453 2023-12-03 12:46:44 +03:00
SBD
fbdef2a1ec 0.8.452 2023-12-03 12:34:24 +03:00
SBD
1834639b50 0.8.451 2023-12-03 12:22:05 +03:00
f9606a3c88 0.0.301 initialization in com_of 2023-12-02 17:07:25 +03:00
SDE
c803d7abbb 0.8.23 fix png black bg 2023-12-02 16:26:53 +03:00
SDE
efd75817bc 0.8.22 admin options change 2023-12-02 16:09:56 +03:00
SDE
36fff15e2b 0.8.21 admin options change 2023-12-02 16:07:12 +03:00
SDE
7573bfb344 Merge remote-tracking branch 'origin/main' 2023-12-02 15:59:40 +03:00
SDE
0c33d638ba 0.8.21 fix problem ckeditor uploads images 2023-12-02 15:59:29 +03:00
SBD
7d3da34e22 0.8.450 2023-12-02 15:55:47 +03:00
SDE
0e2723a367 Merge remote-tracking branch 'origin/main' 2023-12-02 15:42:34 +03:00
SDE
b102c44031 0.8.20 fix problem ckeditor uploads images 2023-12-02 15:42:25 +03:00
SBD
4b480c35e5 Merge remote-tracking branch 'origin/main' 2023-12-02 15:32:00 +03:00
SBD
8e7bcd8fd8 0.8.449 2023-12-02 15:31:50 +03:00
SDE
c60c545031 0.8.19 enable for subscribe in admin 2023-12-02 15:12:23 +03:00
SDE
51d075f799 0.8.18 enable for subscribe in admin 2023-12-02 15:10:17 +03:00
SDE
db54ec1650 Merge remote-tracking branch 'origin/main' 2023-12-02 15:02:48 +03:00
SDE
14b362442f 0.8.18 change pillow version for ckeditor 2023-12-02 15:02:39 +03:00
SBD
fcfbeece87 0.8.448 2023-12-02 15:01:48 +03:00
SBD
aea501aedb 0.8.447 2023-12-02 14:58:16 +03:00
SBD
f1d175fe84 Merge remote-tracking branch 'origin/main' 2023-12-02 14:56:40 +03:00
SBD
0f432c4fd9 0.8.446 2023-12-02 14:56:30 +03:00
b53e19c439 0.0.301 initialization in com_of 2023-12-02 14:43:23 +03:00
SDE
bebd20abf0 Merge remote-tracking branch 'origin/main' 2023-12-02 14:06:05 +03:00
SDE
5dc2293212 0.8.17 admin switch off functional 2023-12-02 14:05:57 +03:00
37f480c01e Merge remote-tracking branch 'origin/main' 2023-12-02 14:05:19 +03:00
f16efa24b0 0.0.300 fix errors in console 2023-12-02 14:05:14 +03:00
SDE
e11d05eb02 Merge remote-tracking branch 'origin/main' 2023-12-02 13:55:34 +03:00
SDE
32cd45106d 0.8.16 admin switch off functional 2023-12-02 13:55:26 +03:00
125 changed files with 22360 additions and 923 deletions

1
.gitignore vendored
View File

@@ -414,4 +414,5 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
celerybeat-schedule.db

View File

@@ -28,20 +28,23 @@ def get_flat_pages_links_Dict(site):
def get_article_breadcrumbs(request, art):
# print('get_article_breadcrumbs')
articles_add_count = 1
articles_add_count = 3
# half_count = articlesCountInBlock / 2
arts_top = ArticleModel.objects.filter(enable=True, createDT__gt=art.createDT).order_by(
'createDT')[:articles_add_count]
arts_down = ArticleModel.objects.filter(enable=True, createDT__lt=art.createDT).order_by(
'-createDT')[:articles_add_count]
# arts_top = ArticleModel.objects.filter(enable=True, createDT__gt=art.createDT).order_by(
# 'createDT')[:articles_add_count]
# arts_down = ArticleModel.objects.filter(enable=True, createDT__lt=art.createDT).order_by(
# '-createDT')[:articles_add_count]
# if len(artListDown)<half_count:
# art_List = ArticleModel.objects.filter(enable=True, article_DT__gte=art.article_DT).order_by(
# 'article_DT')[:art.articlesCountInBlock-len(artListDown)]
breadcrumbs_arts = ArticleModel.objects.exclude(id=art.id).order_by('?')[:3]
Dict = {
'arts_top': arts_top,
'arts_down': arts_down
'breadcrumbs_arts': breadcrumbs_arts
# 'arts_top': arts_top,
# 'arts_down': arts_down
}
return Dict

View File

@@ -39,10 +39,11 @@ class Admin_ProfileInline(admin.StackedInline):
(None, {
'classes': ['wide'],
'fields': (
('account_type',),
# ('account_type',),
('enable',),
('phone',),
('country', 'city'),
('mailing_on', ),
('authMailCode',),
('birthdate'),
'comment', 'creator'
@@ -71,6 +72,10 @@ class Admin_ProfileInline(admin.StackedInline):
class Admin_User(UserAdmin):
def mailing_on(self, obj):
return obj.user_profile.mailing_on
mailing_on.boolean = True
fieldsets = (
(None, {
'classes': ['wide'],
@@ -91,61 +96,63 @@ class Admin_User(UserAdmin):
save_on_top = True
list_display = ['id', 'last_name', 'first_name', 'email', 'is_staff',
list_display = ['id', 'last_name', 'first_name', 'mailing_on', 'email', 'is_staff',
'is_active']
list_editable = ['is_staff', 'is_active']
list_display_links = ['first_name', 'last_name', 'email']
search_fields = ['first_name', 'last_name', 'email']
list_filter = ['user_profile__mailing_on', 'is_staff', 'is_active']
inlines = (Admin_ProfileInline,)
# actions = ['del_all_temp_users', ]
ordering = ['is_staff', 'last_name', 'first_name']
ordering = ['is_staff', '-id', 'last_name', 'first_name']
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, Admin_User)
class Admin_UserProfile(Admin_BaseIconModel):
fieldsets = (
(None, {
'classes': ['wide'],
'fields': (
'user', 'enable',
('account_type',),
('phone',),
('country', 'city'),
('authMailCode',),
('birthdate'),
'creator'
)
}),
('1С', {
'classes': ['wide'],
'fields': (
('name',),
)
}),
)
save_on_top = True
list_display = [
'id', 'user', 'enable', 'birthdate', 'modifiedDT', 'createDT'
]
list_editable = ['enable', 'birthdate']
list_display_links = ['id', ] # 'user__last_name', 'user__first_name']
search_fields = [
'id', 'user__last_name', 'user__first_name', 'user__email',
]
list_filter = ['enable', 'account_type']
# filter_horizontal = ['connected_mailings']
# raw_id_fields = ("favourites",)
verbose_name_plural = _(u'Профиль пользователя')
admin.site.register(UserProfile, Admin_UserProfile)
# class Admin_UserProfile(Admin_BaseIconModel):
#
# fieldsets = (
# (None, {
# 'classes': ['wide'],
# 'fields': (
# 'user', 'enable',
# ('account_type',),
# ('phone',),
# ('country', 'city'),
# ('authMailCode',),
# ('birthdate'),
# 'creator'
# )
# }),
# ('1С', {
# 'classes': ['wide'],
# 'fields': (
# ('name',),
# )
# }),
# )
#
# save_on_top = True
#
# list_display = [
# 'id', 'user', 'enable', 'birthdate', 'modifiedDT', 'createDT'
# ]
# list_editable = ['enable', 'birthdate']
# list_display_links = ['id', ] # 'user__last_name', 'user__first_name']
# search_fields = [
# 'id', 'user__last_name', 'user__first_name', 'user__email',
# ]
#
# list_filter = ['enable', 'account_type']
#
# # filter_horizontal = ['connected_mailings']
# # raw_id_fields = ("favourites",)
# verbose_name_plural = _(u'Профиль пользователя')
#
#
# admin.site.register(UserProfile, Admin_UserProfile)

View File

@@ -29,22 +29,61 @@ class RegistrationForm(forms.Form):
tel = forms.CharField()
agreement = forms.BooleanField(initial=False, required=True)
def __init__(self, *args, **kwargs):
required_password = True
required_agreement = True
required_email = True
create_new_account = True
if 'not_required_password' in kwargs.keys() and kwargs['not_required_password']:
required_password = False
del kwargs['not_required_password']
if 'not_required_agreement' in kwargs.keys() and kwargs['not_required_agreement']:
required_agreement = False
del kwargs['not_required_agreement']
if 'not_required_email' in kwargs.keys() and kwargs['not_required_email']:
required_email = False
del kwargs['not_required_email']
if 'create_new_account' in kwargs.keys() and not kwargs['create_new_account']:
create_new_account = False
del kwargs['create_new_account']
super(RegistrationForm, self).__init__(*args, **kwargs)
self.fields['password'].required = required_password
self.fields['confirm_password'].required = required_password
self.fields['agreement'].required = required_agreement
self.fields['email'].required = required_email
self.create_new_account = create_new_account
def clean(self):
pass
# cleaned_data = super().clean()
# for item in self.changed_data:
# if item in self.data:
#
#
# cc_myself = cleaned_data.get("cc_myself")
# subject = cleaned_data.get("subject")
#
# if cc_myself and subject:
# # Only do something if both fields are valid so far.
# if "help" not in subject:
# raise ValidationError(
# "Did not send for 'help' in the subject despite " "CC'ing yourself."
# )
cleaned_data = super().clean()
# i = 0
# names = list(cleaned_data.keys())
# while i < len(names):
# if not cleaned_data[names[i]]:
# if self.fields[names[i]].required:
# self.add_error(names[i], _('Обязательное поле'))
# i += 1
if 'tel' in cleaned_data and 'tel' in cleaned_data:
from BaseModels.validators.form_field_validators import get_phone_valid_error
error = get_phone_valid_error(cleaned_data["tel"])
if error:
self.add_error('tel', error)
if cleaned_data and 'confirm_password' in cleaned_data and 'password' in cleaned_data:
if cleaned_data['confirm_password'] != cleaned_data['password']:
self.add_error("password", _('Пароль и подтверждение пароля не совпадают'))
self.add_error("confirm_password", _('Пароль и подтверждение пароля не совпадают'))
if self.create_new_account and cleaned_data and 'email' in cleaned_data:
users = User.objects.filter(email=cleaned_data['email'])
if users:
self.add_error('email', _("Пользователь с указанным email уже существует"))

View File

@@ -1,8 +1,25 @@
from django.template.loader import render_to_string
def get_user_timezone_Dict(user, request=None):
tz = None
if request:
tz = request.COOKIES.get("user_tz")
if not tz and user.is_authenticated:
tz = user.user_profile.get_timezone()
if not tz:
from django.conf import settings
tz = settings.TIME_ZONE
return {'user_tz': tz}
def get_dashboard_page_content_html(request):
from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user
Dict = {
'unanswered_msgs_count': get_unanswered_msgs_count_for_user(request.user)
}
html = render_to_string('blocks/profile/b_profile_first_page.html', Dict, request=request)
@@ -15,10 +32,10 @@ def get_profile_page_content_html(request, page_name, data):
return get_chat_page_content_html(request, data)
elif page_name == 'create_route_for_customer':
from RoutesApp.funcs import get_profile_new_route_page_html
return get_profile_new_route_page_html(request, {})
return get_profile_new_route_page_html(request, {'owner_type': 'customer'})
elif page_name == 'create_route_for_mover':
from RoutesApp.funcs import get_profile_new_route_page_html
return get_profile_new_route_page_html(request, {})
return get_profile_new_route_page_html(request, {'owner_type': 'mover'})
elif page_name == 'my_routes':
from RoutesApp.funcs import get_profile_my_routes_page_content_html
return get_profile_my_routes_page_content_html(request)
@@ -73,5 +90,7 @@ def get_profile_support_page_content_html(request, data=None):
}
tpl_name = 'blocks/profile/b_support_tickets.html'
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string(tpl_name, Dict, request=request)
return html

View File

@@ -28,6 +28,8 @@ urlpatterns = [
path('change_profile_confirm/', change_profile_confirm_ajax, name='change_profile_confirm_ajax'),
path('change_avatar_confirm/', change_avatar_confirm_ajax, name='change_avatar_confirm_ajax'),
path('send_message/', send_message_ajax, name='send_message_ajax')
path('send_message/', send_message_ajax, name='send_message_ajax'),
path('mailing_subscribe/', mailing_subscribe_ajax, name='mailing_subscribe_ajax')
]

View File

@@ -17,6 +17,7 @@ import json
from django.core.files import File
import base64
from django.core.validators import validate_email
from django.urls import reverse
# @login_required(login_url='/profile/login/')
@@ -31,6 +32,49 @@ from django.core.validators import validate_email
# return JsonResponse({'html': html}, status=200)
def mailing_subscribe_ajax(request):
if request.method != 'POST':
raise Http404
try:
email = request.POST['email']
user = None
if request.user and request.user.is_authenticated:
user = request.user
user.user_profile.mailing_on = True
user.user_profile.save(update_fields=['mailing_on'])
return JsonResponse({
'status': 'sended',
'del_form': True,
'html': _('Подписка на рассылку для адреса ') + user.email + _(' одобрена')
})
if not user:
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
user = None
if user:
redirect_url = f"{reverse('login_profile')}?mailingSubscribeRequired=true"
else:
redirect_url = f"{reverse('registration_page')}?mailingSubscribeRequired=true"
return JsonResponse({
'status': 'sended',
'redirect_url': redirect_url,
'email': email
})
except Exception as e:
return JsonResponse({
'status': 'error',
'html': str(e)
}, status=400)
def send_message_ajax(request):
if request.method != 'POST':
@@ -126,7 +170,7 @@ def send_message_ajax(request):
return JsonResponse({'html': html}, status=400)
Dict = {
'logo': f'{request.scheme}://{sets["domain"]}/static/img/svg/LogoMobile.svg',
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
'project_name': sets['project_name'],
'message_title': subject,
'message_text': f'<p><b>{_("ДАННЫЕ ЗАПРОСА")}</b></p>'
@@ -188,6 +232,7 @@ def chats_ajax(request):
'receivers': receivers,
# 'messages': cur_chat_msgs
}
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string('blocks/profile/b_chats.html', Dict, request=request)
return JsonResponse({'html': html}, status=200)
@@ -205,6 +250,7 @@ def support_tickets_ajax(request):
@login_required(login_url='/profile/login/')
def change_avatar_confirm_ajax(request):
from django.core.files.base import ContentFile
from django.core.exceptions import RequestDataTooBig
if request.method != 'POST':
raise Http404
@@ -217,11 +263,15 @@ def change_avatar_confirm_ajax(request):
file = ContentFile(content)
request.user.user_profile.avatar.save(file_data['file_name'], file)
request.user.user_profile.save(update_fields=['avatar'])
except RequestDataTooBig:
msg = _('Слишком большой размер файла. Размер файла не должен быть больше 3МБ')
print(msg)
return JsonResponse({'error': msg}, status=400)
except Exception as e:
msg = f'change_avatar_confirm_ajax Error = {str(e)}'
print(msg)
JsonResponse({'error': msg})
return JsonResponse({'error': msg}, status=400)
return JsonResponse({'url': request.user.user_profile.avatar.url})
@@ -236,7 +286,19 @@ def change_profile_confirm_ajax(request):
data = json.loads(request.body)
from .forms import RegistrationForm
form = RegistrationForm(data)
kwargs = {
'not_required_password': True,
'not_required_agreement': True,
'not_required_email': True,
'create_new_account': False,
}
form = RegistrationForm(data, **kwargs)
if not form.is_valid():
form.initial = data
Dict = {'profileForm': form}
html = render_to_string('blocks/profile/b_profile.html', Dict, request=request)
return JsonResponse({'html': html}, status=400)
data_for_save = {}
users = User.objects.filter(id=request.user.id)
@@ -349,6 +411,9 @@ def login_ajax(request):
user = authenticate(username=form.data['username'], password=form.data['password'])
if user is not None:
auth.login(request, user)
if 'mailingSubscribeRequired' in data and data['mailingSubscribeRequired'] == 'true':
user.user_profile.mailing_on = True
user.user_profile.save(update_fields=['mailing_on'])
else:
errors_Dict = {
'errors': {
@@ -378,6 +443,42 @@ def login_ajax(request):
return JsonResponse({'html': html}, status=400)
def send_registration_mail(data_Dict, user):
try:
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
subject = _('Добро пожаловать в Trip With Bonus!')
Dict = {
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
'project_name': sets['project_name'],
'message_title': subject,
}
Dict.update(data_Dict)
html = render_to_string('mail/m_registration.html', Dict)
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
mail_sets = get_mail_send_options()
to = [user.email, 'web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
return res
except Exception as e:
print(f'send_registration_mail Error = {str(e)}')
return None
def registration_ajax(request):
if request.method != 'POST':
raise Http404
@@ -393,17 +494,20 @@ def registration_ajax(request):
html = render_to_string('forms/f_registration.html', Dict, request=request)
return JsonResponse({'html': html}, status=400)
users = User.objects.filter(email=form.data['email'])
if users:
form.errors['email'] = _("Пользователь с указанным email уже существует")
Dict = {'form': form}
html = render_to_string('forms/f_registration.html', Dict, request=request)
return JsonResponse({'html': html}, status=400)
# users = User.objects.filter(email=form.data['email'])
# if users:
# form.errors['email'] = _("Пользователь с указанным email уже существует")
# Dict = {'form': form}
# html = render_to_string('forms/f_registration.html', Dict, request=request)
# return JsonResponse({'html': html}, status=400)
user = User.objects.create_user(username=form.data['email'], email=form.data['email'], password=form.data['password'])
# user = auth.authenticate(username=new_user_Dict['name'], password=new_user_Dict['pass'])
if user:
auth.login(request, user)
auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
if 'mailingSubscribeRequired' in data and data['mailingSubscribeRequired'] == 'true':
user.user_profile.mailing_on = True
user.last_name = form.data['lastname']
user.first_name = form.data['firstname']
@@ -411,6 +515,12 @@ def registration_ajax(request):
user.user_profile.phone = form.data['tel']
user.user_profile.save()
mail_Dict = {
'user': user,
'pass': form.data['password']
}
res = send_registration_mail(mail_Dict, user)
res_Dict = {
'redirect_url': reverse('profile_page', args=['dashboard'])
}

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2024-02-01 17:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('AuthApp', '0004_alter_userprofile_account_type'),
]
operations = [
migrations.AddField(
model_name='userprofile',
name='mailing_on',
field=models.BooleanField(default=False, verbose_name='Рассылка'),
),
]

View File

@@ -51,6 +51,14 @@ class UserProfile(BaseModel):
on_delete=models.SET_NULL
)
mailing_on = models.BooleanField(default=False, verbose_name=_('Рассылка'))
def get_timezone(self):
tz = None
if 'user_timezone' in self.json_data:
tz = self.json_data['user_timezone']
return tz
def save_user_alerts_to_session(self, request):
for_save_to_session = self.get_node_by_name('for_save_to_session')
if for_save_to_session:
@@ -74,8 +82,23 @@ class UserProfile(BaseModel):
def create_user_profile(sender, instance, created, **kwargs):
user_profile = None
if created:
UserProfile.objects.create(user=instance)
user_profile = UserProfile.objects.create(user=instance)
# if user_profile and not user_profile.avatar:
# from allauth.socialaccount.models import SocialAccount
# # try:
# social_accounts = SocialAccount.objects.filter(user=instance)
# if social_accounts:
# for social_account in social_accounts:
# if 'picture' in social_account.account.extra_data and social_account.account.extra_data['picture']:
# with open(social_account.account.extra_data['picture'], 'rb') as fd:
# user_profile.avatar.save(f'avatar_{instance.id}.jpeg', fd.read(), True)
#
# # except Exception as e:
# # msg = f'post_save create_user_profile Error = {str(e)}'
# # print(msg)
post_save.connect(create_user_profile, sender=User, dispatch_uid='post_save_connect')
@@ -85,6 +108,7 @@ def preSaveUser(sender, instance, **kwargs):
if not instance.email:
instance.email = str(instance.username).lower()
try:
instance.user_profile.modifiedDT = datetime.now()
except:

View File

@@ -21,6 +21,8 @@ urlpatterns = [
path('login/', login_View, name='login_profile'),
path('logout/', logout_View, name='logout_profile'),
path('account/signup/', login_View, name="custom_singup" ),
# ajax ----------------
# url(r'^login$', user_login_View_ajax, name='user_login_View_ajax'),

View File

@@ -19,6 +19,11 @@ def registration_View(request):
Dict = {}
if request.GET and 'mailingSubscribeRequired' in request.GET and request.GET['mailingSubscribeRequired'] == 'true':
request.session['mailingSubscribeRequired'] = 'true'
# if request.p
t = loader.get_template('pages/profile/p_registration.html')
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -44,6 +49,11 @@ def profile_page_View(request, page_name, id=None):
'page_type': 'profile'
}
if request.session and 'mailingSubscribeRequired' in request.session and request.session['mailingSubscribeRequired'] == 'true':
request.user.user_profile.mailing_on = True
request.user.user_profile.save(update_fields=['mailing_on'])
del request.session['mailingSubscribeRequired']
title = f"{_('Личный кабинет пользователя')} {request.user.first_name} {request.user.last_name}"
Dict.update({
@@ -54,10 +64,10 @@ def profile_page_View(request, page_name, id=None):
}
})
if request.GET and 'mobile' in request.GET and request.GET['mobile'] == 'true':
Dict.update({
'mobile': True
})
# if request.GET and 'mobile' in request.GET and request.GET['mobile'] == 'true':
# Dict.update({
# 'mobile': True
# })
t = loader.get_template('pages/profile/p_user_profile.html')
return get_inter_http_respose(t, Dict, request)
@@ -117,7 +127,14 @@ def logout_View(request):
def login_View(request):
Dict = {}
from allauth.socialaccount.models import SocialApp
auth_google_allow = SocialApp.objects.filter(provider='google')
Dict = {
'auth_google_allow': auth_google_allow
}
if request.GET and 'mailingSubscribeRequired' in request.GET and request.GET['mailingSubscribeRequired'] == 'true':
request.session['mailingSubscribeRequired'] = 'true'
t = loader.get_template('pages/profile/p_login.html')
return get_inter_http_respose(t, Dict, request)

View File

@@ -0,0 +1,70 @@
import os
from io import BytesIO
from django.conf import settings
from django.utils.functional import cached_property
from PIL import Image
from ckeditor_uploader import utils
THUMBNAIL_SIZE = getattr(settings, "CKEDITOR_THUMBNAIL_SIZE", (75, 75))
class PillowBackend:
def __init__(self, storage_engine, file_object):
self.file_object = file_object
self.storage_engine = storage_engine
@cached_property
def is_image(self):
try:
Image.open(
BytesIO(self.file_object.read())
).verify() # verify closes the file
return True
except OSError:
return False
finally:
self.file_object.seek(0)
def _compress_image(self, image):
quality = getattr(settings, "CKEDITOR_IMAGE_QUALITY", 75)
image = image.resize(image.size, Image.ANTIALIAS).convert("RGB")
image_tmp = BytesIO()
image.save(image_tmp, format="JPEG", quality=quality, optimize=True)
return image_tmp
def save_as(self, filepath):
if not self.is_image:
saved_path = self.storage_engine.save(filepath, self.file_object)
return saved_path
image = Image.open(self.file_object)
should_compress = getattr(settings, "CKEDITOR_FORCE_JPEG_COMPRESSION", False)
is_animated = hasattr(image, "is_animated") and image.is_animated
if should_compress and not is_animated:
file_object = self._compress_image(image)
filepath = f"{os.path.splitext(filepath)[0]}.jpg"
saved_path = self.storage_engine.save(filepath, file_object)
else:
file_object = self.file_object
saved_path = self.storage_engine.save(filepath, self.file_object)
if not is_animated:
self.create_thumbnail(file_object, saved_path)
return saved_path
def create_thumbnail(self, file_object, file_path):
thumbnail_filename = utils.get_thumb_filename(file_path)
thumbnail_io = BytesIO()
# File object after saving e.g. to S3 can be closed.
try:
image = Image.open(file_object).convert("RGBA")
except ValueError:
file_object = self.storage_engine.open(file_path)
image = Image.open(file_object).convert("RGBA")
image.thumbnail(THUMBNAIL_SIZE, Image.ANTIALIAS)
image.save(thumbnail_io, format="PNG", optimize=True)
return self.storage_engine.save(thumbnail_filename, thumbnail_io)

View File

@@ -112,6 +112,20 @@ class BaseModelViewPage(BaseModel):
class Meta:
abstract = True
def get_title(self):
if self.seo_title:
return self.seo_title
elif self.title:
return self.title
else:
return self.name
def get_description(self):
if self.seo_description:
return self.seo_description
else:
return self.description
def get_FAQ_items(self):
return self.FAQ_items.filter(enable=True).order_by('order')

View File

@@ -253,7 +253,7 @@ def techSendMail_for_specified_email_list(sets, html_content, email_list, title=
except Exception as e:
msg = 'techSendMail_for_specified_email_list error={0}'.format(str(e))
techSendMail(msg)
techSendMail(sets, msg)
print(msg)
return 'Fail'
@@ -266,19 +266,22 @@ def techSendMail(sets, html_content, title=None, add_emails=None):
# return msg
print('techSendMail')
project_name = ''
if 'project_name' in sets:
project_name = sets['project_name']
try:
# subject = u'truEnergy Data техническое оповещение'
from_email = 'support@truenergy.by'
from_email = sets['sender_email']
to = ['web@syncsystems.net']
if add_emails:
to.extend(add_emails)
text_content = 'Technical message from truEnergy.'
text_content = f'Technical message from {project_name}'
if title:
subject = title
else:
subject = u'truEnergy Data техническое оповещение'
subject = f'{project_name} - техническое оповещение'
res = admin_send_mail_by_SMTPlib(sets, subject, from_email, to, html_content)

View File

@@ -1,11 +1,23 @@
from django.utils.translation import gettext as _
from django.utils.safestring import mark_safe
def get_phone_valid_error(val):
allow_chars = '01234567890()+ -'
error_msg = mark_safe(_('Некорректные символы в номере, введите номер в международном формате с кодом страны'))
if not val:
return None
if len(val) < 10:
return error_msg
if '+' in val and val[0] != '+':
return error_msg
i = 0
while i < len(val):
if val[i] not in allow_chars:
return _('Некорректные символы в номере телефона, пример корректного ввода +7 925 8600100')
return error_msg
i += 1

View File

@@ -1,6 +1,11 @@
from sets.admin import *
from .models import *
from django.contrib import admin
from django import forms
from django.forms import widgets
class Admin_MsgGroup(Admin_BaseModel):
list_display = [
@@ -11,8 +16,33 @@ class Admin_MsgGroup(Admin_BaseModel):
admin.site.register(MsgGroup,Admin_MsgGroup)
class Admin_Message(Admin_BaseModel):
def cut_group_text(self, obj):
if obj.group:
return obj.group.name[:10]
return '-'
cut_group_text.allow_tags = True
cut_group_text.short_description = 'ticket'
def cut_text(self, obj):
if obj.text:
if len(obj.text) > 20:
return f'{obj.text[:20]}...'
else:
return obj.text
return '-'
cut_text.allow_tags = True
cut_text.short_description = 'сообщение'
search_fields = ['group__name', 'text', 'name', 'id']
list_filter = ['status']
list_display = [
'id', 'msg_type', 'group', 'status', 'sender', 'receiver', 'text',
'id',
# 'msg_type',
'cut_group_text', 'status', 'sender', 'receiver', 'cut_text',
'name',
'order', 'modifiedDT', 'createDT'
]

View File

@@ -1,3 +1,5 @@
import copy
from .models import *
from django.db.models import Q, Value as V, Count, OuterRef, Subquery
from django.http import HttpResponse, Http404, JsonResponse
@@ -11,6 +13,13 @@ from django.urls import reverse
import json
from datetime import datetime, time
from django.conf import settings
from AuthApp.funcs import get_user_timezone_Dict
def get_unanswered_msgs_count_for_user(user):
msgs = Message.objects.filter(receiver=user, status='sended', group=None)
return msgs.count()
def get_update_chat_Dict(data):
@@ -45,11 +54,22 @@ def get_update_chat_Dict(data):
receiver = User.objects.get(id=data['receiver'])
if data['sender'] == data['cur_user']:
context_Dict.update({'user': sender})
user = copy.copy(sender)
cur_receiver = copy.copy(receiver)
else:
context_Dict.update({'user': receiver})
user = copy.copy(receiver)
cur_receiver = copy.copy(sender)
# context_Dict.update({'user': receiver})
context_Dict.update({'cur_receiver': receiver})
# context_Dict.update({'cur_receiver': receiver})
context_Dict.update({
'cur_receiver': cur_receiver,
'user': user,
})
context_Dict.update(get_user_timezone_Dict(user))
if sender == receiver:
print('!')
required_beep = data['required_beep']
@@ -92,7 +112,7 @@ def get_update_chat_Dict(data):
context_Dict.update({
'messages': msgs,
'MEDIA_URL': settings.MEDIA_URL
'MEDIA_URL': settings.MEDIA_URL,
})
html = render_to_string(tpl_name, context_Dict)
if required_full_support_chat_html:
@@ -268,6 +288,7 @@ def send_msg(data):
def get_chat_page_content_html(request, receiver_id=None):
from AuthApp.models import User
from AuthApp.funcs import get_user_timezone_Dict
msgs = []
try:
@@ -287,6 +308,7 @@ def get_chat_page_content_html(request, receiver_id=None):
'receivers': receivers,
'page': 'chat',
}
Dict.update(get_user_timezone_Dict(request.user, request=request))
tpl_name = 'blocks/profile/b_chats.html'
html = render_to_string(tpl_name, Dict, request=request)

View File

@@ -53,6 +53,7 @@ def show_chat_w_user_ajax(request):
data = json.loads(request.body)
Dict = get_chat_page_content_Dict(request, data['user_id'])
Dict.update(get_user_timezone_Dict(request.user, request=request))
tpl_name = 'blocks/profile/b_chats.html'
@@ -99,7 +100,7 @@ def update_chat_ajax2(request):
receiver = User.objects.get(id=data['receiver'])
context_Dict.update({'cur_receiver': receiver})
context_Dict.update(get_user_timezone_Dict(request.user, request=request))
if not ticket:
@@ -123,6 +124,7 @@ def update_chat_ajax2(request):
# формируем правую панель
context_Dict.update({'receivers': receivers})
users_list_html = render_to_string(
'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request)
res_Dict.update({
@@ -190,6 +192,7 @@ def update_chat_ajax(request):
receiver = User.objects.get(id=data['receiver'])
context_Dict.update({'cur_receiver': receiver})
context_Dict.update(get_user_timezone_Dict(request.user, request=request))
if ticket:
@@ -201,6 +204,8 @@ def update_chat_ajax(request):
context_Dict.update({'messages': msgs})
context_Dict = get_ticketsDict_for_staff(request.user)
context_Dict.update(get_user_timezone_Dict(request.user))
tickets_list_html = render_to_string(
'blocks/profile/b_list_of_tickets_support_chat.html', context_Dict, request=request)
res_Dict.update({
@@ -220,6 +225,8 @@ def update_chat_ajax(request):
required_beep = True
context_Dict.update({'receivers': receivers})
context_Dict.update(get_user_timezone_Dict(request.user))
users_list_html = render_to_string(
'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request)
res_Dict.update({
@@ -404,12 +411,14 @@ def support_show_chat_by_ticket_ajax(request):
'cur_receiver': cur_receiver,
'new_msg_allow': new_msg_allow,
'staff': request.user.is_staff,
'mobile': data['mobile']
# 'mobile': data['mobile']
}
Dict.update(get_ticketsDict_for_staff(request.user))
tpl_name = 'blocks/profile/b_support_chat.html'
Dict.update(get_user_timezone_Dict(request.user))
tpl_name = 'blocks/profile/b_support_chat.html'
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string(tpl_name, Dict, request=request)
return JsonResponse({'html': html}, status=200)
@@ -429,6 +438,9 @@ def support_create_ticket_form_ajax(request):
Dict = {
'form': TicketForm()
}
Dict.update(get_user_timezone_Dict(request.user))
tpl_name = 'blocks/profile/b_create_ticket.html'
html = render_to_string(tpl_name, Dict, request=request)
@@ -450,6 +462,8 @@ def create_ticket_ajax(request):
if not form.is_valid():
form.initial = form.cleaned_data
Dict = {'form': form}
Dict.update(get_user_timezone_Dict(request.user))
html = render_to_string('blocks/profile/b_create_ticket.html', Dict, request=request)
return JsonResponse({'html': html}, status=400)
@@ -490,6 +504,8 @@ def create_ticket_ajax(request):
'messages': msgs_for_ticket
}
Dict.update(get_user_timezone_Dict(request.user))
html = render_to_string('blocks/profile/b_support_chat.html', Dict, request=request)
res_Dict = {
@@ -500,9 +516,11 @@ def create_ticket_ajax(request):
except Exception as e:
msg = f'{_("ошибка в запросе")} = {str(e)}'
errors_Dict = {
'errors': {
'all__': f'{_("ошибка в запросе")} = {str(e)}'
'all__': msg
}
}
Dict = {'form': errors_Dict}

View File

@@ -38,6 +38,18 @@ class MsgGroup(BaseModel):
manager = models.ForeignKey(User, verbose_name=_('Менеджер'), related_name='rel_msgGroups_for_manager',
on_delete=models.SET_NULL, null=True)
def get_last_msg_txt(self):
msg = self.rel_messages_for_group.all().order_by('-createDT').first()
if not msg:
return self.text
if msg.text:
return msg.text
elif msg.files:
return msg.files[0]['file_name']
return self.name
class Meta:
verbose_name = _('Тикет')
verbose_name_plural = _('Тикеты')

View File

@@ -41,6 +41,10 @@ def get_filesize(size):
@register.simple_tag
def get_msg_side(cur_user, ticket, msg):
if msg:
# if msg.sender == cur_user:
# return 'left'
# else:
# return 'right'
if msg.sender == cur_user:
return 'right'
else:

View File

@@ -52,33 +52,33 @@ class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
admin.site.register(StaticPage,Admin_StaticPage)
class Admin_Block(Admin_Trans_BaseModel):
pass
# def get_fieldsets(self, request, obj=None):
# fieldsets = super(type(self), self).get_fieldsets(request, obj)
# if not request.user.is_superuser and obj.name and obj.name in ('About US', 'machines', 'works'):
# fieldsets[0][1]['fields'].pop(0)
# fieldsets.insert(
# 1, (_('Контент'), {
# 'classes': ['wide'],
# 'fields': (
# 'title', 'description', 'text',
# 'picture',
# )
#
# })
# )
# return fieldsets
#
# def has_delete_permission(self, request, obj=None):
# if request.user.is_superuser:
# return True
#
# if obj.name in ('About US', 'machines', 'works'):
# return False
admin.site.register(Block,Admin_Block)
# class Admin_Block(Admin_Trans_BaseModel):
# pass
#
# # def get_fieldsets(self, request, obj=None):
# # fieldsets = super(type(self), self).get_fieldsets(request, obj)
# # if not request.user.is_superuser and obj.name and obj.name in ('About US', 'machines', 'works'):
# # fieldsets[0][1]['fields'].pop(0)
# # fieldsets.insert(
# # 1, (_('Контент'), {
# # 'classes': ['wide'],
# # 'fields': (
# # 'title', 'description', 'text',
# # 'picture',
# # )
# #
# # })
# # )
# # return fieldsets
# #
# # def has_delete_permission(self, request, obj=None):
# # if request.user.is_superuser:
# # return True
# #
# # if obj.name in ('About US', 'machines', 'works'):
# # return False
#
# admin.site.register(Block,Admin_Block)
class Admin_Option(Admin_Trans_BaseModel):
@@ -105,7 +105,7 @@ class Admin_Option(Admin_Trans_BaseModel):
}),
]
list_display = ['image_thumb', 'opt_type', 'name', 'prefix', 'value']
list_display = ['image_thumb', 'opt_type', 'name', 'value', 'prefix']
list_editable = ['value', 'prefix']
list_filter = ['opt_type']

View File

@@ -0,0 +1,51 @@
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.account.utils import user_field
from django.conf import settings
from allauth.account.adapter import DefaultAccountAdapter
import requests
from django.core.files import File
from django.core.files.temp import NamedTemporaryFile
class MyAccountAdapter(DefaultAccountAdapter):
def get_login_redirect_url(self, request):
path = super(MyAccountAdapter, self).get_login_redirect_url(request)
try:
user = request.user
user_profile = user.user_profile
if user_profile and not user_profile.avatar:
social_accounts = user.socialaccount_set.all()
if social_accounts:
for social_account in social_accounts:
if 'picture' in social_account.extra_data and social_account.extra_data['picture']:
r = requests.get(social_account.extra_data['picture'])
img_temp = NamedTemporaryFile()
img_temp.write(r.content)
img_temp.flush()
user_profile.avatar.save(f'avatar_{user.id}.jpeg', File(img_temp), True)
break
except Exception as e:
msg = f'post_save create_user_profile Error = {str(e)}'
print(msg)
return path
# class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
# def populate_user(self, request, sociallogin, data):
# from AuthApp.models import UserProfile
#
# user = super().populate_user(request, sociallogin, data)
# try:
# picture = sociallogin.account.extra_data['picture']
# user_profile = UserProfile.objects.get_or_create(user=user)
# with open(picture, 'rb') as fd:
# user_profile.avatar.save(f'user_{user.id}_avatar.jpeg', fd.read(), True)
# # user_field(user, "profile_photo", picture)
# except Exception as e:
# msg = f'CustomSocialAccountAdapter populate_user Error = {str(e)}'
# print(msg)
#
# return user

View File

@@ -1,14 +1,45 @@
from django.http import HttpResponse, Http404, FileResponse
from django.conf import settings
def get_inter_Dict(user):
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(user)
return {'user_subscribe': user_subscribe}
Dict = {
'user_subscribe': user_subscribe,
'prod': True
}
if settings.WS_ADDRESS == 'localhost:8000':
Dict.update({'prod': False})
from PushMessages.views import get_key_Dict
Dict.update(get_key_Dict())
return Dict
def get_inter_http_respose(template_obj, context_Dict, request):
context_Dict.update(get_inter_Dict(request.user))
from PushMessages.views import send_push
if request and 'page' in context_Dict:
text = None
title = None
if context_Dict['page'] == dict:
if 'title' in context_Dict['page']:
title = context_Dict['page']['title']
if 'description' in context_Dict['page']:
text = context_Dict['page']['description']
else:
title = getattr(context_Dict['page'], 'title', None)
text = getattr(context_Dict['page'], 'description', None)
# if text and title and not request.user.is_anonymous:
# send_push(user=request.user, title=title, text=text)
return HttpResponse(template_obj.render(context_Dict, request))

View File

@@ -10,8 +10,25 @@ def get_options_by_opt_types(opt_types, only_vals=False):
opts = Option.objects.filter(**kwargs)
if opts and only_vals:
opts = opts.values('opt_type', 'value')
opts = {item['opt_type']: item['value'] for item in opts}
res = {}
opts = opts.values('opt_type', 'value', 'prefix')
for item in opts:
if item['opt_type'] == 'domain':
try:
from django.contrib.sites.models import Site
current_site = Site.objects.get_current()
res.update({item['opt_type']: current_site.domain})
continue
except Exception as e:
print(str(e))
if item['prefix']:
res.update({item['opt_type']: f"{item['prefix']}{item['value']}"})
else:
res.update({item['opt_type']: f"{item['value']}"})
return res
return opts
def get_first_option_value_by_opt_type(opt_type):
@@ -22,6 +39,6 @@ def get_first_option_value_by_opt_type(opt_type):
return None
def get_mail_send_options():
opt_types = ['mail_server_url', 'mail_server_smtp_port', 'sender_mail_login', 'sender_mail_password', 'sender_email']
opt_types = ['mail_server_url', 'mail_server_smtp_port', 'sender_mail_login', 'sender_mail_password', 'sender_email', 'project_name']
return get_options_by_opt_types(opt_types, only_vals=True)

View File

@@ -6,33 +6,72 @@ from django.contrib.auth.decorators import login_required
from .models import *
from django.conf import settings
from .funcs import get_inter_http_respose
from django.http.response import JsonResponse, HttpResponse
from django.views.decorators.http import require_GET, require_POST
from django.shortcuts import get_object_or_404
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt
from webpush import send_user_notification
import json
def test_code(request):
from RoutesApp.funcs import get_city_by_type_transport_and_address_point
from RoutesApp.models import Route
from ReferenceDataApp.models import Airport, City
routes = Route.objects.all()
# import allauth
# from allauth.socialaccount.models import SocialApp
# apps = SocialApp.objects.all()
# apps.delete()
for route in routes:
print(route.id)
required_save = False
if not route.from_city:
route.from_city = get_city_by_type_transport_and_address_point(route.type_transport, route.from_address_point)
required_save = True
from RoutesApp.search_matches import search_matches
search_matches()
if not route.to_city:
route.to_city = get_city_by_type_transport_and_address_point(route.type_transport,
route.to_address_point)
required_save = True
# try:
# # body = request.body
# # data = json.loads(body)
# # if 'head' not in data or 'body' not in data or 'id' not in data:
# # return JsonResponse(status=400, data={"message": "Invalid data format"})
# # user_id = data['id']
# user = request.user
# payload = {'head': '123', 'body': 'qwerty'}
# send_user_notification(user=user, payload=payload, ttl=1000)
# return JsonResponse(status=200, data={"message": "Web push successful"})
# except TypeError:
# return JsonResponse(status=500, data={"message": "An error occurred"})
if required_save:
route.save()
# routes = Route.objects.all()
#
# for route in routes:
# print(route.id)
# required_save = False
# if not route.from_city:
# route.from_city = get_city_by_type_transport_and_address_point(route.type_transport, route.from_address_point)
# required_save = True
#
# if not route.to_city:
# route.to_city = get_city_by_type_transport_and_address_point(route.type_transport,
# route.to_address_point)
# required_save = True
#
# if required_save:
# route.save()
return HttpResponse('finished')
def Page404(request, exeption=None):
Dict = {}
t = loader.get_template('404.html')
try:
res = get_inter_http_respose(t, Dict, request)
return HttpResponse(res, status=404)
except Exception as e:
return HttpResponse(str(e))
@@ -48,7 +87,7 @@ def MainPage(request):
page = StaticPage.objects.get(url='main')
from ArticlesApp.models import ArticleModel
arts = ArticleModel.objects.filter(enable=True).order_by('-createDT')[:4]
arts = ArticleModel.objects.filter(enable=True).order_by('-createDT')[:3]
Dict = {
'page': page,
@@ -58,6 +97,8 @@ def MainPage(request):
'owner_type': 'mover'
}
breadcrumbs_Dict = {
}
Dict.update({'breadcrumbs': breadcrumbs_Dict})

0
PushMessages/__init__.py Normal file
View File

3
PushMessages/admin.py Normal file
View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
PushMessages/apps.py Normal file
View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class PushmessagesConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'PushMessages'

View File

3
PushMessages/models.py Normal file
View File

@@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

3
PushMessages/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

16
PushMessages/urls.py Normal file
View File

@@ -0,0 +1,16 @@
# coding=utf-8
from django.urls import path, include
# from AuthApp.js_views import *
# from AuthApp.import_funcs import *
from .views import *
from django.contrib.auth import views
from RoutesApp.js_views import new_route_view_ajax
from django.views.generic import TemplateView
urlpatterns = [
path('send_push', send_push),
path('webpush/', include('webpush.urls')),
path('sw.js', TemplateView.as_view(template_name='sw.js', content_type='application/x-javascript')),
]

49
PushMessages/views.py Normal file
View File

@@ -0,0 +1,49 @@
from django.http.response import JsonResponse, HttpResponse
from django.views.decorators.http import require_GET, require_POST
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt
from webpush import send_user_notification
import json
from django.shortcuts import render, get_object_or_404
from django.conf import settings
from django.utils.translation import gettext as _
def get_key_Dict():
webpush_settings = getattr(settings, 'WEBPUSH_SETTINGS', {})
vapid_key = webpush_settings.get('VAPID_PUBLIC_KEY')
Dict = {
'vapid_key': vapid_key
}
return Dict
def send_push(user, title, text, url=None, button_name=None, img=None):
try:
# body = request.body
# data = json.loads(body)
#
# if 'head' not in data or 'body' not in data or 'id' not in data:
# return JsonResponse(status=400, data={"message": "Invalid data format"})
#
# user_id = data['id']
# user = get_object_or_404(User, pk=user_id)
Dict = {
'head': title,
'body': text,
}
if url:
Dict['url'] = url
if button_name:
Dict['button_name'] = button_name
else:
Dict['button_name'] = _('Перейти'),
if img:
Dict['img'] = img
# payload = {'head': data['head'], 'body': data['body']}
send_user_notification(user=user, payload=Dict, ttl=1000)
return JsonResponse(status=200, data={"message": "Web push successful"})
except TypeError:
return JsonResponse(status=500, data={"message": "An error occurred"})

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
celery -A TWB.celery:app worker -l info
celery -A TWB.celery:app beat -l info

View File

@@ -55,7 +55,7 @@ def get_address_point_ajax(request):
else:
item['city_name'] = item['name']
item['country_name'] = item['country__name']
item['fullname'] = f'{item["country_name"]} / {item["city_name"]}'
item['fullname'] = f'{item["city_name"]} / {item["country_name"]}'
html = f"{html}{render_to_string('widgets/w_ac_input_address_point.html', item)}"
i += 1

View File

@@ -4,7 +4,7 @@ from django.contrib import admin
class Admin_Route(Admin_Trans_BaseModel):
list_display = [
'id', 'owner_type', 'type_transport', 'cargo_type',
'id', 'owner_type', 'receive_msg_by_email', 'type_transport', 'cargo_type',
'departure_DT', 'from_city', 'from_place',
'arrival_DT', 'to_city', 'to_place', 'owner',
'order', 'modifiedDT', 'createDT'
@@ -14,5 +14,6 @@ class Admin_Route(Admin_Trans_BaseModel):
list_filter = ['owner_type', 'type_transport', 'cargo_type', 'from_place', 'arrival_DT', 'modifiedDT', 'createDT']
search_fields = ['owner__first_name', 'owner__last_name']
raw_id_fields = ['from_city', 'to_city']
admin.site.register(Route,Admin_Route)

View File

@@ -6,6 +6,47 @@ from django.core.exceptions import ValidationError
from .models import *
def routeForm_assign_choices_by_type_transport(form, type_transport):
if type_transport == 'avia':
transfer_location_choices = (
('airport', _('В аэропорту')),
('city', _('По городу')),
('other', _('По договоренности'))
)
cargo_type_choices = (
('cargo', _('Груз')),
('parcel', _('Бандероль')),
('package', _('Посылка')),
('letter', _('Письмо\Документ'))
)
else:
transfer_location_choices = (
('city', _('По городу')),
('other', _('По договоренности'))
)
cargo_type_choices = (
('passenger', _('Пассажир')),
('cargo', _('Груз')),
('parcel', _('Бандероль')),
('package', _('Посылка')),
('letter', _('Письмо\Документ'))
)
form.fields['from_place'].choices = transfer_location_choices
form.fields['to_place'].choices = transfer_location_choices
form.fields['cargo_type'].choices = cargo_type_choices
form.base_fields['from_place'].choices = transfer_location_choices
form.base_fields['to_place'].choices = transfer_location_choices
form.base_fields['cargo_type'].choices = cargo_type_choices
return form
class RouteForm(forms.ModelForm):
from_address_point_txt = forms.CharField(required=True)
to_address_point_txt = forms.CharField(required=True)
@@ -24,6 +65,22 @@ class RouteForm(forms.ModelForm):
try:
if 'phone' in cleaned_data and 'phone' in cleaned_data:
from BaseModels.validators.form_field_validators import get_phone_valid_error
error = get_phone_valid_error(cleaned_data["phone"])
if error:
self.add_error('phone', error)
if 'extra_phone' in cleaned_data and 'extra_phone' in cleaned_data:
from BaseModels.validators.form_field_validators import get_phone_valid_error
error = get_phone_valid_error(cleaned_data["extra_phone"])
if error:
self.add_error('extra_phone', error)
if 'departure_DT' in cleaned_data and 'arrival_DT' in cleaned_data and cleaned_data['arrival_DT'] < cleaned_data['departure_DT']:
self.add_error('arrival_DT', _('Указана неверная дата прибытия'))
if 'from_place' in self.data and self.data['from_place'] not in [item[0] for item in self.fields['from_place'].choices]:
cleaned_data['from_place'] = self.fields['from_place'].choices[0][0]
if 'from_place' in self.errors and self.errors['from_place'].data[0].code == 'invalid_choice':

View File

@@ -7,12 +7,19 @@ from datetime import datetime
elements_on_page = 25
def get_profile_new_route_page_html(request, data):
form = RouteForm()
Dict = {
'form': form
}
try:
errors_off = True
@@ -27,59 +34,71 @@ def get_profile_new_route_page_html(request, data):
if 'to_address_point_txt' in data:
del data['to_address_point_txt']
# if data['type_transport'] == 'avia':
# transfer_location_choices = (
# ('airport', _('В аэропорту')),
# ('city', _('По городу')),
# ('other', _('По договоренности'))
# )
#
# cargo_type_choices = (
# ('cargo', _('Груз')),
# ('parcel', _('Бандероль')),
# ('package', _('Посылка')),
# ('letter', _('Письмо\Документ'))
# )
#
#
# else:
# transfer_location_choices = (
# ('city', _('По городу')),
# ('other', _('По договоренности'))
# )
#
# cargo_type_choices = (
# ('passenger', _('Пассажир')),
# ('cargo', _('Груз')),
# ('parcel', _('Бандероль')),
# ('package', _('Посылка')),
# ('letter', _('Письмо\Документ'))
# )
form = RouteForm(data)
if not form.is_valid():
pass
form = RouteForm(initial=form.cleaned_data)
if 'type_transport' in data:
if data['type_transport'] == 'avia':
transfer_location_choices = (
('airport', _('В аэропорту')),
('city', _('По городу')),
('other', _('По договоренности'))
)
form = routeForm_assign_choices_by_type_transport(form, data['type_transport'])
cargo_type_choices = (
('passenger', _('Пассажир')),
('cargo', _('Груз')),
('parcel', _('Бандероль')),
('package', _('Посылка')),
('letter', _('Письмо\Документ'))
)
else:
transfer_location_choices = (
('city', _('По городу')),
('other', _('По договоренности'))
)
cargo_type_choices = (
('cargo', _('Груз')),
('parcel', _('Бандероль')),
('package', _('Посылка')),
('letter', _('Письмо\Документ'))
)
form = RouteForm(data)
if not form.is_valid():
pass
form = RouteForm(initial=form.cleaned_data)
form.fields['from_place'].choices = transfer_location_choices
form.fields['to_place'].choices = transfer_location_choices
form.fields['cargo_type'].choices = cargo_type_choices
form.base_fields['from_place'].choices = transfer_location_choices
form.base_fields['to_place'].choices = transfer_location_choices
form.base_fields['cargo_type'].choices = cargo_type_choices
# form.fields['from_place'].choices = transfer_location_choices
# form.fields['to_place'].choices = transfer_location_choices
# form.fields['cargo_type'].choices = cargo_type_choices
#
# form.base_fields['from_place'].choices = transfer_location_choices
# form.base_fields['to_place'].choices = transfer_location_choices
# form.base_fields['cargo_type'].choices = cargo_type_choices
# form = CreateRouteForm(initial=data)
# if not form.is_valid():
# pass
if 'owner_type' in data:
form.initial['owner_type'] = data['owner_type']
if request.user and request.user.is_authenticated and request.user.user_profile and request.user.user_profile.phone:
form.initial.update({'phone': request.user.user_profile.phone})
Dict = {
'form': form,
'errors_off': errors_off
}
if 'owner_type' in data:
Dict.update({'owner_type': data['owner_type']})
# print(form)
except Exception as e:
# form.errors.append({'__all__': f'Ошибка: {str(e)}'})
@@ -141,18 +160,31 @@ def get_routes_Dict(user=None, data=None):
res_Dict = {}
if data:
type_transport = None
if 'type_transport' in data and data['type_transport']:
items_list = data['type_transport'].split(',')
kwargs.update({f'type_transport__in': items_list})
if len(items_list) == 1:
type_transport = items_list[0]
for key, val in data.items():
if val:
if key == 'weight':
weight_list = val.split(';')
if weight_list[0]:
kwargs.update({f'{key}__gte': int(weight_list[0])})
if weight_list[1]:
kwargs.update({f'{key}__lte': int(weight_list[1])})
if len(weight_list) > 1:
if weight_list[0]:
kwargs.update({f'{key}__gte': int(weight_list[0])})
if weight_list[1]:
kwargs.update({f'{key}__lte': int(weight_list[1])})
else:
kwargs.update({f'{key}__lte': int(weight_list[0])})
if key == 'type_transport':
items_list = val.split(',')
kwargs.update({f'{key}__in': items_list})
# if key == 'type_transport':
# items_list = val.split(',')
# kwargs.update({f'{key}__in': items_list})
if key in (
@@ -172,19 +204,18 @@ def get_routes_Dict(user=None, data=None):
kwargs.update({key: val})
if key == 'from_address_point':
kwargs.update({f'from_city__id': val})
city = get_city_by_type_transport_and_address_point(type_transport, val)
kwargs.update({f'from_city': city})
res_Dict.update({
'from_address_point_txt': get_country_n_city_str_by_type_transport_and_address_point(
'road', val
)
'from_address_point_txt': city.get_country_n_city_str()
})
if key == 'to_address_point':
kwargs.update({f'to_city__id': val})
city = get_city_by_type_transport_and_address_point(type_transport, val)
kwargs.update({f'to_city': city})
res_Dict.update({
'to_address_point_txt': get_country_n_city_str_by_type_transport_and_address_point(
'road', val
)
'to_address_point_txt': city.get_country_n_city_str()
})
if key == 'from_el':
@@ -192,7 +223,7 @@ def get_routes_Dict(user=None, data=None):
if key == 'to_el':
to_el = int(val)
routes = Route.objects.filter(**kwargs).order_by('departure_DT', 'arrival_DT', '-modifiedDT')
routes = Route.objects.filter(**kwargs).order_by('-departure_DT', '-arrival_DT', '-modifiedDT')
routes_count = routes.count()
if from_el and to_el:

View File

@@ -67,6 +67,8 @@ def edit_route_ajax(request):
route = Route.objects.get(id=data['route_id'])
form = RouteForm(instance=route)
form = routeForm_assign_choices_by_type_transport(form, route.type_transport)
route_address_points_Dict = route.get_address_points()
form.initial.update({
'from_address_point_txt': route_address_points_Dict['from_address_point_txt'],
@@ -230,7 +232,7 @@ def create_or_change_route_ajax(request, route_id=None):
return JsonResponse({'html': html}, status=400)
obj = form.save(commit=False)
if 'owner_type' in data:
if 'owner_type' in data and data['owner_type']:
obj.owner_type = data['owner_type']
if obj.from_address_point:

View File

View File

@@ -0,0 +1,36 @@
from django.core.management.base import BaseCommand
from datetime import datetime
from BaseModels.mailSender import techSendMail
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
class Command(BaseCommand):
def handle(self, *args, **options):
mail_sets = get_mail_send_options()
log = ''
log_begin_DT = datetime.now()
msg = str(log_begin_DT)
print('-------------')
print(msg)
try:
from ...search_matches import search_matches
msg = search_matches()
if msg:
print(msg)
except Exception as e:
msg = f'every_1hour_start search_matches fail = {str(e)}'
print(msg)
techSendMail(mail_sets, msg, title='every_1hour_start search_matches')
if msg:
techSendMail(mail_sets, str(msg), title='every_1hour_start get_competitors_prices')
print(f'- processing time = {str(datetime.now() - log_begin_DT)} -')

View File

@@ -0,0 +1,13 @@
from django.core.management.base import BaseCommand
from datetime import datetime
class Command(BaseCommand):
def handle(self, *args, **options):
# from B2BApp.funcs import assign_contracts_for_orders_by_tmp_data
# log = assign_contracts_for_orders_by_tmp_data()
from GeneralApp.views import test_code
test_code(None)
self.stdout.write(u'fix_code end')

View File

@@ -111,8 +111,8 @@ class Route(BaseModel):
to_address_point_Dict = to_address_point_objs.values(
'id', 'name', 'country__name')[0]
from_address_point_txt = f'{from_address_point_Dict["country__name"]} / {from_address_point_Dict["name"]}'
to_address_point_txt = f'{to_address_point_Dict["country__name"]} / {to_address_point_Dict["name"]}'
from_address_point_txt = f'{from_address_point_Dict["name"]} / {from_address_point_Dict["country__name"]}'
to_address_point_txt = f'{to_address_point_Dict["name"]} / {to_address_point_Dict["country__name"]}'
return {
'from_address_point_obj': from_address_point_objs[0],

145
RoutesApp/search_matches.py Normal file
View File

@@ -0,0 +1,145 @@
from .models import *
from datetime import datetime, timedelta
from django.utils.translation import gettext as _
from django.template.loader import render_to_string
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
from BaseModels.mailSender import admin_send_mail_by_SMTPlib, techSendMail
def get_Dict_for_send_msgs(kwargs, search_owner_type):
print('get_Dict_for_send_msgs')
Dict = {
'search_owner_type': search_owner_type
}
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
Dict.update(sets)
Dict.update({'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg', })
find_routes_page_url = f'{sets["domain"]}/routes/route_search_results/?'
kwargs_list = [f'{key}={value}' for key, value in kwargs.items()]
kwargs_list.append(f'owner_type={search_owner_type}')
find_routes_page_url += f'{"&".join(kwargs_list)}'
Dict.update({'find_routes_page_url': find_routes_page_url})
return Dict
def send_push_message_for_found_matches_routes(route, data_Dict):
print(f'send_push_message_for_found_matches_routes to route id = {route.id}')
if not route.owner.is_authenticated:
return None
from PushMessages.views import send_push
title = 'Мы нашли исполнителя по Вашему объявлению!'
text = 'Для просмотра результата нажмите на кнопку ниже'
send_push(route.owner, title, text, url=data_Dict['find_routes_page_url'], button_name=_('Перейти к найденному'))
return None
def send_mail_found_matches_routes(route, data_Dict):
print(f'send_mail_found_matches_routes to route id = {route.id}')
Dict = {
'route': route,
}
Dict.update(data_Dict)
html = render_to_string('mail/m_found_matched_routes.html', Dict)
mail_sets = get_mail_send_options()
to = [route.owner.email, 'web@syncsystems.net']
subject = _('Мы нашли исполнителя по Вашему объявлению!')
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
return res
def search_matches(for_routes=None):
print('search_matches')
log = ''
try:
if not for_routes:
for_routes = Route.objects.filter(
createDT__gte=datetime.now() - timedelta(hours=1),
receive_msg_by_email=True
)
check_fields = [
'type_transport', 'departure_DT', 'arrival_DT', 'from_address_point', 'to_address_point',
'from_place', 'to_place', 'cargo_type', 'weight'
]
if for_routes:
msg = f'last hour create routes count = {for_routes.count()}'
else:
msg = f'last hour not create routes'
print(msg)
for route in for_routes:
kwargs = {}
params = {}
for field_name in check_fields:
field_val = getattr(route, field_name, None)
if field_val:
if type(field_val) == datetime:
params.update({f"{field_name}": f'{field_val.strftime("%d.%m.%Y")} - {field_val.strftime("%d.%m.%Y")}'})
kwargs.update({f"{field_name}__date": field_val.date()})
elif field_name == 'weight':
# print(field_name)
params.update({f"{field_name}": field_val})
if route.owner_type == 'mover':
kwargs.update({f"{field_name}__lte": field_val})
else:
kwargs.update({f"{field_name}__gte": field_val})
else:
kwargs.update({field_name: field_val})
params.update({field_name: field_val})
found_routes = Route.objects.exclude(
id=route.id,
).exclude(
owner=route.owner
).exclude(
owner_type=route.owner_type
).filter(
**kwargs
# ).count(
)
if found_routes:
msg = f'found routes for send messages = {found_routes.count()}'
data_Dict = get_Dict_for_send_msgs(params, found_routes[0].owner_type)
msg = send_push_message_for_found_matches_routes(route, data_Dict)
if msg:
log += msg
msg = send_mail_found_matches_routes(route, data_Dict)
if msg:
log += msg
except Exception as e:
msg = f'<br>\n! search_matches Error = {str(e)}'
print(msg)
log += msg
mail_sets = get_mail_send_options()
techSendMail(mail_sets, log, title='search_matches fail')
return log

View File

@@ -6,7 +6,7 @@ class Admin_Subscribe(Admin_Trans_BaseModel):
fieldsets = (
(None, {
'classes': ['wide'],
'fields': ('name',
'fields': ('name', 'enable',
('price'),
'options',
'period_name', 'period',
@@ -18,12 +18,13 @@ class Admin_Subscribe(Admin_Trans_BaseModel):
list_display = [
'id',
'name', 'price',
'name', 'enable', 'price',
'period_name', 'period',
'order', 'modifiedDT', 'createDT'
]
list_display_links = ['id']
list_editable = ['enable']
list_filter = ['modifiedDT', 'createDT']
search_fields = ['name', 'period_name']
@@ -37,16 +38,18 @@ class Admin_SubscribeOption(Admin_Trans_BaseModel):
(None, {
'classes': ['wide'],
'fields': ('name',
'order'
'order',
'enable'
)
}),
)
list_display = [
'id',
'id', 'enable',
'name',
'order', 'modifiedDT', 'createDT'
]
list_editable = ['enable']
list_display_links = ['id']

View File

@@ -0,0 +1,7 @@
from rest_framework import serializers
class SubscribersSerializer(serializers.Serializer):
email = serializers.EmailField(error_messages={'invalid': 'Invalid email'})
email_notification = serializers.BooleanField()
auto_subscribe = serializers.BooleanField()

9
SubscribesApp/urls.py Normal file
View File

@@ -0,0 +1,9 @@
from django.urls import path
from SubscribesApp.views import SubscribersView
urlpatterns = [
path('auto-subscribe/', SubscribersView.as_view(), name='auto_subscribe'),
]

View File

@@ -1,3 +1,43 @@
from django.shortcuts import render
from django.contrib.auth.models import User
from django.http import JsonResponse
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
# Create your views here.
from SubscribesApp.models import SubscribeForUser
from SubscribesApp.serializers import SubscribersSerializer
class SubscribersView(APIView):
# permission_classes = [IsAuthenticated]
def post(self, request):
serializer = SubscribersSerializer(data=request.data)
if serializer.is_valid():
validated_data = serializer.validated_data
email = validated_data['email']
email_notification = validated_data['email_notification']
auto_subscribe = validated_data['auto_subscribe']
user = User.objects.filter(email=email)
if user:
subscribe_for_user = SubscribeForUser.objects.filter(user_id=user[0].id)
if email_notification:
subscribe_for_user.update(receive_finish_subscribe_msg=True)
else:
subscribe_for_user.update(receive_finish_subscribe_msg=False)
if auto_subscribe:
subscribe_for_user.update(auto_continue=True)
else:
subscribe_for_user.update(auto_continue=False)
return JsonResponse({"message": "Subscriptions updated successfully"}, status=status.HTTP_200_OK)
else:
return JsonResponse({"message": "User not found"}, status=status.HTTP_404_NOT_FOUND)
else:
return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

View File

@@ -22,11 +22,14 @@ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TWB.settings')
application = ProtocolTypeRouter({
'http': get_asgi_application(),
"websocket": QueryAuthMiddleware(
URLRouter(
websocket_urlpatterns
)
),
"websocket":
# AllowedHostsOriginValidator(
QueryAuthMiddleware(
URLRouter(
websocket_urlpatterns
)
# )
),
# 'websocket': AuthMiddlewareStack(
# URLRouter(
# websocket_urlpatterns

27
TWB/celery.py Executable file
View File

@@ -0,0 +1,27 @@
from __future__ import absolute_import
import os
from celery import Celery
from celery.schedules import crontab
from django.conf import settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "TWB.settings")
app = Celery('bo', include=['TWB.tasks'])
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
app.conf.beat_schedule = {
'update-currency-rates': {
'task': 'TWB.tasks.check_auto_subscribe',
'schedule': crontab(minute=0, hour='*/1'),
},
'subscription_expiration_check': {
'task': 'TWB.tasks.subscription_expiration_check',
'schedule': crontab(hour=0, minute=0),
# 'schedule': crontab(minute='*', hour='*'),
},
}
app.conf.broker_url = settings.CELERY_BROKER_URL

View File

@@ -11,10 +11,13 @@ https://docs.djangoproject.com/en/4.2/ref/settings/
"""
from pathlib import Path
from decouple import config
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
CSRF_TRUSTED_ORIGINS = ['https://tripwb.com']
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
@@ -28,6 +31,50 @@ DEBUG = True
ALLOWED_HOSTS = ["*"]
WEBPUSH_SETTINGS = {
"VAPID_PUBLIC_KEY": "BKS8byh3MucwCF2h06JY9oey1s1RYII09j-j3ehI3qTYhs965UHv0qNPl-jFjQBbIJCvjVXm9RW6t_oJJK8yMOk",
"VAPID_PRIVATE_KEY": "f5NMgOntBtRqsyeKwEzloK-051ggMnZGF_GFimERY0w",
"VAPID_ADMIN_EMAIL": "admin@tripwb.com"
}
SOCIALACCOUNT_LOGIN_ON_GET=True
ACCOUNT_DEFAULT_HTTP_PROTOCOL='https'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_VERIFICATION = 'optional'
LOGIN_REDIRECT_URL = '/profile/page/dashboard/'
LOGIN_URL = '/profile/login/'
LOGOUT_REDIRECT_URL = '/profile/login/'
ACCOUNT_SIGNUP_REDIRECT_URL = '/profile/page/dashboard/'
ACCOUNT_LOGOUT_ON_GET = True
# SOCIALACCOUNT_ADAPTER = 'GeneralApp.allauth_funcs.MyAccountAdapter'
ACCOUNT_ADAPTER = 'GeneralApp.allauth_funcs.MyAccountAdapter'
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
]
SOCIALACCOUNT_PROVIDERS = {
'google': {
'SCOPE': [
'profile',
'email',
],
'AUTH_PARAMS': {
'access_type': 'online',
},
}
}
# NOTIFICATION_KEY = 'BJLyGzmo8sLI3Qkc6pN2cz11frCXiJdewvgve7Yps-_fM1lY1LSnTQfQxYtAgQ_26nAji_rgeYC1DkLiTwxw0Mo'
# SESSION_COOKIE_HTTPONLY = False
# Application definition
@@ -46,17 +93,27 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'django.contrib.humanize',
'django.contrib.sites',
'colorfield',
'ckeditor',
'ckeditor_uploader',
'webpush',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.google',
'GeneralApp',
'AuthApp',
'RoutesApp',
'ReferenceDataApp',
'ArticlesApp',
'SubscribesApp',
'PushMessages',
]
MIDDLEWARE = [
@@ -69,8 +126,14 @@ MIDDLEWARE = [
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'AuthApp.middleware.ResponseInterceptionMiddleware',
'TWB.tz_middelware.TimezoneMiddleware',
# 'tz_detect.middleware.TimezoneMiddleware',
"allauth.account.middleware.AccountMiddleware",
]
SITE_ID = 1
ROOT_URLCONF = 'TWB.urls'
TEMPLATES = [
@@ -109,11 +172,8 @@ CHANNEL_LAYERS = {
}
POSTGRES_DB = config('POSTGRES_DB')
POSTGRES_USER = config('POSTGRES_USER')
# Database
@@ -122,8 +182,8 @@ CHANNEL_LAYERS = {
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'twbDB',
'USER': 'test_user',
'NAME': POSTGRES_DB,
'USER': POSTGRES_USER,
'PASSWORD': 'test_db_pass',
'HOST': '127.0.0.1',
'PORT': '5432',
@@ -209,6 +269,7 @@ django.conf.locale.LANG_INFO = LANG_INFO
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DATA_UPLOAD_MAX_MEMORY_SIZE = 4145728
CKEDITOR_BASEPATH = "/static/ckeditor/ckeditor/"
CKEDITOR_UPLOAD_PATH = "uploads/"
@@ -216,7 +277,9 @@ CKEDITOR_RESTRICT_BY_DATE = False
CKEDITOR_RESTRICT_BY_USER = True
CKEDITOR_BROWSE_SHOW_DIRS = True
CKEDITOR_IMAGE_BACKEND = "pillow"
# CKEDITOR_IMAGE_BACKEND = 'ckeditor_uploader.backends.PillowBackend'
# CKEDITOR_IMAGE_BACKEND = 'pillow'
CKEDITOR_IMAGE_BACKEND = "BaseModels.PIL.pillow_backend.PillowBackend"
# CKEDITOR_BROWSE_SHOW_DIRS = True
@@ -231,6 +294,10 @@ CKEDITOR_CONFIGS = {
'toolbar': 'Custom',
'forcePasteAsPlainText': True,
'allowedContent': True,
'filebrowserImageThumbWidth': 300,
'filebrowserImageThumbHeight': 300,
'filebrowserUploadUrl': '/ckeditor/upload/',
# 'disallowedContent': 'img{width,height};img[width,height]',
# 'extraPlugins': 'image2',
@@ -266,6 +333,16 @@ CKEDITOR_CONFIGS = {
}
}
CELERY_BROKER_URL = config('CELERY_BROKER_URL')
CELERY_RESULT_BACKEND = config('CELERY_RESULT_BACKEND')
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = config('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD')
# CKEDITOR_OPTIONS = {
# 'height': 291,

40
TWB/tasks.py Normal file
View File

@@ -0,0 +1,40 @@
from datetime import datetime, timedelta, timezone
from SubscribesApp.models import SubscribeForUser
from TWB import settings
from TWB.celery import app
from django.core.mail import send_mail
@app.task
def check_auto_subscribe():
current_time = datetime.now()
subscribes = SubscribeForUser.objects.filter(auto_continue=True)
if subscribes:
for subscribe in subscribes:
if subscribe.paid_period_to_DT and subscribe.paid_period_to_DT <= current_time + timedelta(hours=1):
user_email = subscribe.user.email
subject = 'Подписка продлена!'
message = 'Ваша подписка успешно продлена!'
send_mail(subject, message, settings.EMAIL_HOST_USER, [user_email], fail_silently=False)
else:
print('Нету подписок')
@app.task
def subscription_expiration_check():
current_time = datetime.now()
subscribes = SubscribeForUser.objects.filter(paid_period_to_DT__gte=current_time)
if subscribes:
for subscribe in subscribes:
expiration_date = subscribe.paid_period_to_DT
remaining_days = (expiration_date - current_time).days
if remaining_days <= 7:
message = f'Ваша подписка заканчивается через {remaining_days} дня. Пожалуйста, продлите её.'
user_email = subscribe.user.email
subject = 'Подписка истекает!'
send_mail(subject, message, settings.EMAIL_HOST_USER, [user_email], fail_silently=False)
else:
print('Нету подписок')

22
TWB/tz_middelware.py Normal file
View File

@@ -0,0 +1,22 @@
import zoneinfo
from django.utils import timezone
from django.shortcuts import render
class TimezoneMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
tz = request.COOKIES.get("user_tz")
if tz:
if request.user.is_authenticated:
if not 'user_timezone' in request.user.user_profile.json_data or request.user.user_profile.json_data['user_timezone'] != tz:
request.user.user_profile.json_data['user_timezone'] = tz
request.user.user_profile.save(update_fields=['json_data'])
msg = f'user={str(request.user.id)} tz={str(tz)}'
print(msg)
timezone.activate(zoneinfo.ZoneInfo(tz))
else:
timezone.activate(zoneinfo.ZoneInfo("UTC"))
return self.get_response(request)

View File

@@ -1,18 +1,30 @@
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from GeneralApp.views import Page404
from AuthApp.views import login_View
handler404 = Page404
urlpatterns = [
# path('admin/', admin.site.urls),
path('ckeditor/', include('ckeditor_uploader.urls')),
path('i18n/', include('django.conf.urls.i18n')),
# path('tz_detect/', include('tz_detect.urls')),
path('accounts/signup/', login_View, name='signup'),
path('accounts/login/cancelled/', login_View),
path('accounts/', include('allauth.urls')),
path('accounts/', include('allauth.socialaccount.urls')),
path('messages/', include('ChatServiceApp.urls')),
path('user_account/', include('AuthApp.js_urls')),
path('routes/', include('RoutesApp.js_urls')),
path('subscribes/', include('SubscribesApp.js_urls')),
@@ -22,6 +34,12 @@ urlpatterns = [
path('reference_data/', include('ReferenceDataApp.js_urls')),
path('', include('ArticlesApp.js_urls')),
path('test_404', Page404, name='page_404'),
path('', include('PushMessages.urls')),
path('', include('SubscribesApp.urls')),
]
from django.conf.urls.i18n import i18n_patterns

8
env.sample Normal file
View File

@@ -0,0 +1,8 @@
EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=
POSTGRES_DB=
POSTGRES_USER=
CELERY_BROKER_URL=
CELERY_RESULT_BACKEND=

View File

@@ -580,9 +580,9 @@ msgstr ""
#: .\templates\blocks\static_pages_blocks\b_partners.html:18
msgid ""
"Вы можете разместить объявление о перевозке посылки и перевозчики со всего "
"мира откликнуться на ваше объявление или воспользовавшись поиском на сайте "
"мира откликнутся на ваше объявление или воспользовавшись поиском на сайте "
"найти перевозчика, который будет готов взять Вашу посылку и доставить в "
"указанное место авто- или авива транспортом."
"указанное место наземным или авиатранспортом."
msgstr ""
#: .\templates\blocks\static_pages_blocks\b_about_service.html:22

View File

@@ -2,7 +2,6 @@ Django==4.2.2
django-ckeditor==6.5.1
psycopg2-binary==2.9.6
requests
Pillow
django-modeltranslation==0.18.10
overpass
geopy
@@ -10,4 +9,9 @@ channels==4.0.0
daphne==4.0.0
channels-redis==4.1.0
django-colorfield
django-webpush==0.3.5
django-allauth==0.60.0
pytz==2024.1
celery==5.3.6
djangorestframework==3.14.0
python-decouple==3.8

View File

@@ -18,11 +18,21 @@
@media (max-width: 1199px){
.dropbtn{
margin-right: 20px;
margin-right: unset;
}
.header_logo, .header_btn_mover{
margin-right: 20px;
}
.dropbtn_lang{
padding: 2px 0.5px;
border-radius: 12px;
}
#ru_lang,#en_lang{
padding: unset;
}
#customer_service{
margin-right: 10px;
@@ -61,41 +71,41 @@
left: 33%;
}
.cards_item_1,
.cards_item_2,
.cards_item_3,
.cards_item_4
{
width: 46%;
height: 180px;
background-size:60%;
}
/* .cards_item_1,*/
/*.cards_item_2,*/
/*.cards_item_3,*/
/*.cards_item_4*/
/*{*/
/* width: 46%;*/
/* height: 180px;*/
/* background-size:60%;*/
/*}*/
.card_title_1{
font-size: 34px;
font-style: normal;
font-weight: 700;
line-height: 42px;
margin: 22px 0 0 10px;
text-shadow: 1px 1px 0px #272424;
}
.card_title_2{
font-size: 17px;
font-style: normal;
font-weight: 600;
line-height: 26px;
margin: 10px 0 0 10px;
text-shadow: 1px 1px 0px #272424;
}
.card_title_3{
margin: 10px 0 0 10px;
width: 95%;
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 20px;
text-shadow: 1px 1px 0px #272424;
}
/* .card_title_1{*/
/* font-size: 34px;*/
/* font-style: normal;*/
/* font-weight: 700;*/
/* line-height: 42px;*/
/* margin: 22px 0 0 10px;*/
/* text-shadow: 1px 1px 0px #272424;*/
/*}*/
/*.card_title_2{*/
/* font-size: 17px;*/
/* font-style: normal;*/
/* font-weight: 600;*/
/* line-height: 26px;*/
/* margin: 10px 0 0 10px;*/
/* text-shadow: 1px 1px 0px #272424;*/
/*}*/
/*.card_title_3{*/
/* margin: 10px 0 0 10px;*/
/* width: 95%;*/
/* font-size: 12px;*/
/* font-style: normal;*/
/* font-weight: 400;*/
/* line-height: 20px;*/
/* text-shadow: 1px 1px 0px #272424;*/
/*}*/
.sf_1_column {
padding-left: 25px;
padding-right: 90px;
@@ -106,12 +116,102 @@
}
@media (max-width: 1180px){
.input_list.find_route{
left: unset;
width: 70%;
}
.handler_curtain_left{
display: block;
}
.handler_curtain_left.close{
left: 0;
top: 293px;
position: fixed;
height: 127px;
width: 32px;
background: #FF613A;
border-radius: 0 10px 10px 0;
z-index: 101;
transition: 200ms;
}
.container_content_handler_curtain_left{
display: flex;
rotate: 90deg;
justify-content: space-between;
height: 32px;
width: 87px;
position: relative;
left: -49px;
top: 47px;
padding: 0 20px;
}
.handler_curtain_left.open{
left: 320px;
top: 293px;
position: fixed;
height: 127px;
width: 32px;
background: #FFFFFF;
border-radius: 0 10px 10px 0;
z-index: 101;
transition: 200ms;
}
.handler_curtain_left.open .container_content_handler_curtain_left{
rotate: 270deg;
}
.cards_item_1,
.cards_item_2,
.cards_item_3,
.cards_item_4{
height: 322px;
width: 65%;
float: unset;
margin: 15px auto;
}
.filter_img{
width: 15px;
display: block;
position: relative;
bottom: 0;
transform: rotate(270deg) translate(0, 0);
filter: brightness(0) saturate(100%) invert(100%) sepia(0%) saturate(0%) hue-rotate(296deg) brightness(106%) contrast(101%);
/*transition: 200ms;*/
}
.handler_curtain_left.open .filter_img{
transform: translate(0, 0);
filter: brightness(0) saturate(100%) invert(53%) sepia(48%) saturate(4340%) hue-rotate(337deg) brightness(102%) contrast(102%);
/*transition: 200ms;*/
}
.arrows_handler_curtain_left{
width: 7px;
rotate: -90deg;
filter: unset;
/*transition: 200ms;*/
}
.handler_curtain_left.open .arrows_handler_curtain_left{
filter: brightness(0) saturate(100%) invert(53%) sepia(48%) saturate(4340%) hue-rotate(337deg) brightness(102%) contrast(102%);
transition: 200ms;
}
.wrapper_name_art{
font-size: 29px;
line-height: 33px;
}
.header_buttons{
display: none;
}
.confirm_profile_btn{
width: 95%;
}
.not_found_routes>img{
display: none;
@@ -283,8 +383,9 @@
}
.button_profile_header_mobile{
display: inline-block ;
margin-left: 5px;
}
.header-first>div {
.header_logo_mobile {
margin-right: 37px;
}
.line_f_header{
@@ -335,10 +436,11 @@
margin-top: unset;
}
button#more_button{
#more_button, #send_parcel_button{
width: 50%;
/*margin-top: 40px;*/
}
#title_static{
font-size: 33px;
line-height: 42px;
@@ -494,6 +596,7 @@
section.register>form{
display: block;
width: unset;
margin-right: 10px;
}
.inputs{
@@ -639,7 +742,7 @@
top: 0;
}
.cut_width_f_curtain.n_profile.left{
position: fixed;
position: sticky;
/*min-width: 1280px;*/
}
@@ -867,10 +970,10 @@
.left-part-block-enter-message{
width: 70%;
width: calc(70% - 74px);
}
.right-part-block-enter-message{
width: 30%;
width: 74px;
}
.container-message_support_chat{
width: 70%;
@@ -935,9 +1038,9 @@
.wrapper_advertisement{
padding: unset;
}
.advertisement_block_news{
height: 80px;
}
/*.advertisement_block_news{*/
/* height: 80px;*/
/*}*/
.three_pinned_news{
margin: unset;
}
@@ -1030,7 +1133,7 @@
.cargo_type_trans{
display: block;
margin-bottom: 15px;
float: unset;
/*float: unset;*/
}
.from-to-country-container-carrier{
@@ -1358,7 +1461,9 @@
.header_logo, .header_btn_mover{
margin-right: 26px;
}
.cookie_block{
width: 100%;
}
.menu_buttons.curtain.left.close.chat{
width: 265px;
}
@@ -1400,11 +1505,69 @@
width: 490px;
margin: 0 auto 30px;
}
.news_item_pagination{
width: 490px;
}
.pag_news_img{
width: unset;
}
.news_item_pagination.odd .pag_news_img, .news_item_pagination.odd .pag_news_item_text{
float: unset;
}
.news_item_pagination.even .pag_news_img, .news_item_pagination.even .pag_news_item_text{
float: unset;
}
.pag_news_item_text{
width: unset;
}
}
@media (max-width: 850px){
.cards_item_1,
.cards_item_2,
.cards_item_3,
.cards_item_4{
width: 70%;
height: unset;
float: unset;
margin: 15px auto;
}
.cards_item_img, .cards_item_text{
float: unset;
width: unset;
}
.cards_item_1>.cards_item_img>img,
.cards_item_2>.cards_item_img>img,
.cards_item_3>.cards_item_img>img,
.cards_item_4>.cards_item_img>img{
float: unset;
aspect-ratio: 4/3;
object-fit: cover;
width: 100%;
border-radius: 10px;
}
.cards_item_text{
padding-bottom: 20px;
}
.card_title_1{
margin: 25px 0 0 20px;
}
.read_more_about_subscribe{
padding: 0 14px;
height: 30px;
@@ -1471,6 +1634,25 @@
}
@media (max-width: 800px) {
.marker_messages_mobile{
position: absolute;
top: 0;
right: 0;
border-radius: 100%;
background: #ff0000;
height: 14px;
width: 15px;
}
.marker_messages_mobile.hide{
display: none;
}
.marker_messages_mobile.show{
display: block;
}
}
@media (max-width: 828px){
/*.to_address_point_txt.find_route {*/
/*width: 54.6%;*/
@@ -1531,6 +1713,17 @@
}
@media (max-width: 699px){
.block-chat.support {
/*height: calc(100vh - 190px);*/
/*1. 100svh 2. 45px - header 3. name_ticket 4. just padding */
height: calc(100svh - 45px - 40px - 50px);
}
.block-chat{
/*height: calc(88vh - 50px);*/
/*1. 100svh 2. 45px - header 3. just padding */
height: calc(100svh - 45px - 50px);
}
.block_overlay.show{
display: block;
}
@@ -1573,6 +1766,28 @@
background: #FFF;
}
.menu_buttons.right.open .menu_profile{
padding-top: unset;
}
.menu_profile>div{
height: 30px;
margin-top: 3px;
margin-bottom: 8px;
}
#customer>.text_btn_profile, #mover>.text_btn_profile{
top: 8px;
}
/*.text_btn_profile{*/
/* top: 14px;*/
/*}*/
.menu_profile > .subscribe_type_txt{
margin-bottom: 12px;
padding-top: 12px;
}
.menu_profile>div>img.svg{
margin-top: 4px;
}
.info_profile{
width: 100%;
}
@@ -1631,10 +1846,16 @@
}
@media (max-width: 575px){
.phones_carrier{
display: block;
}
.news_item_pagination{
width: 100%;
}
.previous_next_news>.news_item_static{
margin: unset;
margin-bottom: 40px;
@@ -1682,24 +1903,47 @@
width: 100%;
margin-top: 20px;
}
button#more_button{
#more_button{
width: 100%;
margin-top: 40px;
}
#send_parcel_button{
width: 100%;
margin-top: 40px;
}
.news_block_main{
justify-content: center;
}
.cards_item_1,
.cards_item_2,
.cards_item_3,
.cards_item_4
{
width: 100%;
height: 180px;
background-size:60%;
/*.cards_item_1,*/
/*.cards_item_2,*/
/*.cards_item_3,*/
/*.cards_item_4*/
/*{*/
/* width: 100%;*/
/* height: 180px;*/
/* background-size:60%;*/
/*}*/
.card_title_1{
font-size: 34px;
font-style: normal;
font-weight: 700;
line-height: 42px;
}
.card_title_2{
font-size: 18px;
font-style: normal;
font-weight: 600;
line-height: 26px;
}
.card_title_3{
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 20px;
}
.cards_wrapper{
@@ -1764,9 +2008,7 @@
height: 30px;
}
.header_buttons{
display: none;
}
/*.to_address_point_txt.find_route {*/
/* width: 48.4%;*/
/*}*/
@@ -1777,7 +2019,7 @@
.container_inp_w_abr {
width: 99%;
width: 100%;
}
.another_subscribe{
@@ -1791,6 +2033,10 @@
@media (max-width: 440px){
.card_title_3{
margin: 20px 5px 0 20px;
}
.f-r{
text-align: left;
}
@@ -1858,6 +2104,13 @@
}
@media (max-width: 360px){
#customer>.text_btn_profile, #mover>.text_btn_profile{
width: 53%;
}
.loader_chat_f_sw_chats.show {
display: block;
height: 100px;
@@ -1866,6 +2119,76 @@
top: 35%;
left: 34%;
}
.menu_buttons.left.open.filters {
width: calc(100vw - 35px);
background: #FFFFFF;
border-radius: 10px;
height: 100vh;
left: 19px;
padding: 13px;
/* position: fixed; */
float: left;
text-align: left;
position: absolute;
top: 0;
transition: 0ms;
scrollbar-width: none;
box-sizing: border-box;
}
.menu_buttons.right.open {
right: 0;
transition: 200ms;
position: fixed;
display: block;
padding-top: 10px;
top: 35px;
background: #ffffff;
width: calc(100vw - 35px);
}
.menu_profile>div {
width: 80%;
}
.menu_buttons.close .btns_f_curtain {
transition: 200ms;
transform: rotate(270deg);
filter: brightness(0) saturate(100%) invert(100%) sepia(2%) saturate(0%) hue-rotate(162deg) brightness(104%) contrast(103%);
/* padding-right: 2px; */
padding-right: 0;
bottom: -2px;
position: relative;
}
.menu_buttons.left.open {
left: 0;
transition: 200ms;
position: fixed;
float: unset;
padding-top: 10px;
height: 100vh;
max-height: 100vh;
width: calc(100vw - 35px);
}
.menu_buttons.left.open.first.filters .btns_f_curtain {
transition: 200ms;
transform: rotate(270deg);
filter: brightness(0) saturate(100%) invert(100%) sepia(2%) saturate(0%) hue-rotate(162deg) brightness(104%) contrast(103%);
padding-left: 10px;
position: relative;
top: 7px;
}
.menu_profile {
width: 100%;
text-align: -webkit-center;
}
.menu_buttons.right.open .handler_menu {
background: #FFFFFF;
color: #000000;
right: calc(100vw - 83px);
}
.menu_buttons.left.open .handler_menu {
background: #FFFFFF;
color: #000000;
left: calc(100vw - 83px);
}
.tab-btn-1{
padding: unset;
}

View File

@@ -58,6 +58,8 @@
width: 100%;
/*background: rgba(39, 53, 62, 0.7);*/
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
-moz-backdrop-filter: blur(6px);
z-index: 100;
position: fixed;
top: 0;
@@ -221,6 +223,7 @@
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
float: left;
height: 20px;
}
.message-sprt-inf{
@@ -447,6 +450,7 @@
box-shadow: -1px 4px 10px 0 rgba(198, 199, 203, 0.20), 0 -1px 10px 0 rgba(198, 199, 203, 0.20);
float: right;
position: relative;
overflow: hidden;
}
.block_loader_chat{
@@ -481,7 +485,8 @@
}
.bottom_part_of_chats{
height: calc(100% - 39px);
height: 100%;
padding-bottom: 39px;
position: relative;
}
@@ -492,6 +497,8 @@
width: calc(100% - 40px);
height: 60px;
padding: 10px 20px;
position: absolute;
top: 0;
}
.header-chat-left-part{
@@ -535,14 +542,15 @@
}
.container-messages{
height: calc(100% - 175px);
height: calc(100% - 224px);
width: 100%;
/* transform: rotate(180deg); */
overflow-y: auto;
/* transform: scaleY(-1); */
display: flex;
flex-direction: column-reverse;
padding-top: 70px;
padding-bottom: 63px;
margin-top: 100px;
}
@@ -559,7 +567,7 @@
border: 1px solid #E6E6E6;
padding: 0 20px 0 20px;
position: absolute;
bottom: 43px;
bottom: 0;
}
.footer-chat.hide{
@@ -567,12 +575,12 @@
}
.left-part-block-enter-message{
width: 80%;
width: calc(80% - 74px);
float: left;
}
.right-part-block-enter-message{
width: 20%;
width: 74px;
float: right;
padding-top: 11px;
text-align: right;
@@ -1025,7 +1033,7 @@
.from_address_point_txt.find_route.first.w_100{
width: calc(100% - 35px);
border-right: 1px solid #E6E6E6;
border-right: 2px solid #E6E6E6;
}
.from_address_point_txt.post_route.first.w_100{
@@ -1071,15 +1079,20 @@
.input_list.find_route{
width: 100%;
/* display: block; */
border-radius: 0 10px;
top: 61px;
z-index: 12;
width: 90%;
/*display: block;*/
border-radius: 0 0 10px 10px;
top: 62px;
left: 9px;
z-index: 10000;
}
.input_list.find_route.show{
display: block;
border: 2px solid #E6E6E6;
border-top: hidden;
}
.container_inp_w_abr{
@@ -1199,9 +1212,9 @@
margin: 0;
}
.cont-el-form-search-carrier.last > label{
opacity: 0;
}
/*.cont-el-form-search-carrier.last > label{*/
/* opacity: 0;*/
/*}*/
.block-filters-find-route {
@@ -1230,8 +1243,8 @@
}
.not_found_routes{
width: 98%;
height: 250px;
width: 96%;
min-height: 250px;
background: #FFFFFF;
box-shadow: -1px 4px 10px 0 rgba(198, 199, 203, 0.20), 0 -1px 10px 0 rgba(198, 199, 203, 0.20);
position: relative;
@@ -1484,6 +1497,17 @@
width: 100%;
}
a.open_inf_carrier{
display: block;
width: 88%;
}
.show_contact_wrapper {
text-align: center;
}
.open_inf_carrier:hover{
background: #FF613A;
color: #FFFFFF;
@@ -1534,7 +1558,13 @@
font-weight: 500;
font-size: 20px;
color: #272424;
padding-bottom: 10px;
margin-bottom: 10px;
/*border: 2px solid #FF613A;*/
border-radius: 10px;
padding: 7px;
text-align: center;
}
.name_carrier{
@@ -2101,7 +2131,7 @@
.button_profile_header{
height: 50px;
width: 150px;
width: 155px;
background: #FF613A;
color: #FFF;
/* Heading 5 */
@@ -2241,6 +2271,10 @@
border-radius: 10px;
}
.input_f_profile.grey{
background: #F8F8F8;
}
.status_f_profile{
width: calc(100% - 120px);
padding-left: 10px;
@@ -2329,11 +2363,11 @@
/*p_main news*/
.news_description{
/*background: linear-gradient(45deg, #040404 33%, #c5c5c5 66%, #ffffff);*/
/*-webkit-background-clip: text;*/
/*-webkit-text-fill-color: transparent;*/
font-size: 16px;
font-weight: 400;
background: linear-gradient(180deg, #040404 46%, #ffffff 72%, #ffffff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.menu_buttons.right.close{
@@ -2389,6 +2423,27 @@
height: 695px;
}
.menu_buttons.left::-webkit-scrollbar-track{
background-color: #F6F6F6;
display: none;
}
.menu_buttons.left::-webkit-scrollbar-thumb{
background-color: #989898;
border-radius: 3px;
width: 3px;
display: none;
}
.menu_buttons.left::-webkit-scrollbar{
background-color:#FF613A;
width: 4px;
display: none;
}
.menu_buttons{
/*background: #FFFFFF;*/
/*height: 100vh;*/
@@ -2523,6 +2578,7 @@
position: absolute;
top: 293px;
transition: 0ms;
scrollbar-width: none;
}
@@ -2629,7 +2685,7 @@
.menu_buttons.left.open.first.filters .text_f_curtain > img{
transition: 200ms;
transform: rotate(270deg);
transform: rotate(270deg) translate(0, 0);
filter: brightness(0) saturate(100%) invert(100%) sepia(2%) saturate(0%) hue-rotate(162deg) brightness(104%) contrast(103%);
position: relative;
}
@@ -2647,6 +2703,7 @@
height: calc(100vh - 95px);
max-height: 697px;
background: #F8F8F8;
scrollbar-width: none;
}
.menu_profile.background{
@@ -2744,6 +2801,9 @@
.container_descript_one_news{
width: 100%;
overflow-wrap: break-word;
background: linear-gradient(180deg, #040404 46%, #ffffff 72%, #ffffff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.container_name_one_news{
@@ -2839,9 +2899,70 @@
}
.text_in_btn_a_anchor{
padding-top: 20px;
padding-top: 17px;
}
.anchor{
scroll-margin-top: 60px;
}
.anchor.about_service{
scroll-margin-top: 150px;
}
/*login page*/
.error_f_login{
color: #f00;
margin-bottom: 20px;
display: block;
}
/*b_profile_first_page*/
.title_b_first_page{
margin-top: 70px;
}
/* handler_curtain changed*/
.handler_curtain_left{
display: none;
}
/*cookie*/
.cookie_block{
background: #000000;
width: 951px;
position: fixed;
bottom: 5px;
z-index: 100000000000000;
box-sizing: border-box;
display: none;
}
.cookie_block.show{
display: block;
}
.txt_cookie{
color: #FFFFFF;
font-size: 14px;
}
.a_cookie{
color: #FFFFFF;
font-size: 14px;
}
.container_content_cookie_block{
display: flex;
justify-content: space-between;
padding: 15px;
}
.cookie_btn{
background: none;
border: 2px solid white;
color: #FFFFFF;
height: 25px;
width: 95px;
cursor: pointer;
}

View File

@@ -23,24 +23,28 @@
src: url("/static/fonts/inter/Inter-Regular.ttf") format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face{
font-family: 'Inter';
src: url("/static/fonts/inter/Inter-Medium.ttf") format('truetype') ;
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face{
font-family: 'Inter';
src: url("/static/fonts/inter/Inter-SemiBold.ttf") format('truetype') ;
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face{
font-family: 'Inter';
src: url("/static/fonts/inter/Inter-Bold.ttf") format('truetype') ;
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* Links */
@@ -136,8 +140,15 @@ legend {
}
html, body{
height: 100%;
/*height: 100%;*/
scroll-behavior: smooth;
/*boris changed height*/
height: 100vh;
height: -webkit-fill-available;
height: fill-available;
max-height: fill-available;
max-height: -webkit-fill-available;
/* end*/
}
.wrapper_content {
@@ -145,6 +156,7 @@ html, body{
max-width: 1280px;
position: relative;
min-height: 695px;
max-height: 100%;
}
.wrapper_content.m_h_0{
@@ -222,6 +234,8 @@ body {
margin: 0;
padding: 0;
background: #F8F8F8;
/*mix-blend-mode: multiply;*/
/*пока убрал надо чтобы fire протестил на iphone*/
}
header {
@@ -257,11 +271,15 @@ section.register>h1 {
border-radius: 10px;
border: 1px solid black;
}
.footer_input_wrap.hide{
display: none;
}
.footer_input_wrap {
display: flex;
color: #FF613A;
}
.footer_input::placeholder {
color: rgba(39, 36, 36, 0.60);
font-size: 16px;
@@ -536,6 +554,21 @@ header .header-first {
font-size: 16px;
border: none;
}
#changes_saved_txt{
display: none;
}
#changes_saved_txt.show{
display: block;
}
#save_changes_txt.hide{
display: none;
}
#mover_title_color{
background: #e0bff0;
}
#customer_title_color{
background: #f5d813;
}
.dropdown {
position: relative;
@@ -556,6 +589,7 @@ header .header-first {
height: 390px;
box-shadow: -1px 4px 10px 0px rgba(198, 199, 203, 0.20), 0px -1px 10px 0px rgba(198, 199, 203, 0.20);
z-index: 1;
top: 30px;
}
.dropdown-content.show{
display:block;
@@ -634,8 +668,26 @@ header .header-second {
.button_profile_header_mobile{
display: none;
cursor: pointer;
vertical-align: middle;
}
.route_contact_avatar{
object-fit: cover;
height: 40px;
width: 40px;
border-radius: 10px;
aspect-ratio: 4/3;
}
.from_address_point_txt.red_text{
color: #ff0000;
}
.to_address_point_txt.red_text{
color: #ff0000;
}
.header-second-item,
.cont_header_btn_profile,
@@ -670,8 +722,9 @@ span.btn_profile_name {
/*Language select*/
.dropbtn_lang {
padding: 7px 0 7px 0;
padding: 8px 6.5px;
cursor: pointer;
border-radius: 23px;
}
/* The container <div> - needed to position the dropdown content */
@@ -690,9 +743,9 @@ span.btn_profile_name {
.dropbtn_lang
{
background: url('/static/img/png/ru.png') no-repeat left center;
padding-left: 25px;
width: 40px;
/*background: url('/static/img/svg/ru.svg') no-repeat left center;*/
/*padding-left: 25px;*/
/*width: 40px;*/
color: transparent;
}
@@ -708,16 +761,19 @@ span.btn_profile_name {
#ru_lang
{
background: url('/static/img/png/ru.png') no-repeat left center;
background: url('/static/img/svg/ru.svg') no-repeat center;
color: transparent;
padding: 10px;
padding: 6px;
margin: 5px 0;
border-radius: 5px;
}
#en_lang
{
background: url('/static/img/png/en.png') no-repeat left center;
background: url('/static/img/svg/gb.svg') no-repeat center;
color: transparent;
padding: 10px;
padding: 6px;
border-radius: 5px;
}
/* Links inside the dropdown */
@@ -732,6 +788,20 @@ span.btn_profile_name {
display: block;
}
#create_route{
border-radius: 10px;
color: #FFFFFF;
background: #FF613A;
/*height: 60px;*/
font-size: 18px;
font-weight: 500;
width: 80%;
margin-top: 10px;
display: inline-block;
padding: 15px 0px;
}
/* Change color of dropdown links on hover */
.dropdown-content-lang a:hover {background-color: #f1f1f1}
@@ -742,8 +812,9 @@ span.btn_profile_name {
/*END Language select*/
.header-second>div>img{
#support_img{
margin-right: 5px;
margin-left: 40px;
}
#customer_service{
margin-right: 35px;
@@ -820,13 +891,15 @@ section.register>form {
}
.agree {
display: flex;
/*display: flex;*/
margin-bottom: 40px;
align-items: end;
display: inline-block;
}
.agree>.checkbox{
width: 50px;
display: inline-block;
}
.agree_text {
@@ -836,6 +909,8 @@ section.register>form {
font-style: normal;
font-weight: 400;
line-height: 20px;
display: inline-block;
width: 90%;
}
.button_register>button {
@@ -1327,6 +1402,13 @@ h2.title_new_route{
.prof_second_line>a {
color: #FF613A;
cursor: pointer;
}
#id_email{
cursor: unset;
}
#error_arrival_DT.hide, #error_departure_DT.hide{
display: none;
}
.prof_third_line>a {
@@ -1369,14 +1451,14 @@ h2.title_new_route{
width: 100%;
}
.errorlist{
position: absolute;
/*position: absolute;*/
}
.errorlist>li{
color:red;
margin-left: 12px;
font-size: 14px;
font-size: 12px;
}
span.errorlist{
color: red;
@@ -1390,6 +1472,7 @@ span.errorlist{
/*create new route*/
select#id_type_transport{
cursor: pointer;
display: block;
height: 60px;
width: 47%;
@@ -1583,6 +1666,10 @@ div.departure_arrival>div>input{
}
#hide_owner_type{
display: none;
}
/*end create new route*/
@@ -1648,12 +1735,32 @@ div.departure_arrival>div>input{
max-height: 200px;
width: 100%;
position: absolute;
background-color: #F8F8F8;
background-color: #FFFFFF;
overflow: scroll;
overflow-x:hidden;
}
/*.input_list::-webkit-scrollbar {*/
/* width: 5px;*/
/* height: 20px;*/
/* background-color: #FF613A;*/
/*}*/
.input_list::-webkit-scrollbar {
width: 10px;
}
.input_list::-webkit-scrollbar-thumb {
background-color: #FF613A;
border-radius: 20px;
border: 3px solid white;
}
.input_list.post_route{
padding-top: 20px;
max-width: 390px;
@@ -1669,6 +1776,12 @@ div.departure_arrival>div>input{
.input_list .hide{
display: none;
}
span.hide, .error_to_address_point.hide, #id_cargo_lable.hide, #error_id_phone.hide{
display: none;
}
#agreement_check.hide{
display: none;
}
@@ -1894,6 +2007,7 @@ button#edit_route {
position: absolute;
height: -webkit-fill-available;
width: -webkit-fill-available;
width: -moz-available;
}
#error_footer{
@@ -1902,6 +2016,14 @@ button#edit_route {
margin-left: 5px;
}
.pag_news_img>img{
object-fit: cover;
width: 100%;
border-radius: 10px;
aspect-ratio: 4 / 3;
max-height: 300px;
}
#error_footer.hide{
display: none;
}
@@ -1983,12 +2105,33 @@ button.cancel_remove.show, button.confirm_remove.show{
/*Static_pages*/
.not_found_wrap{
padding-top: 20px;
}
.not_found_text{
text-align: center;
font-style: normal;
font-weight: 700;
line-height: 52px;
margin-bottom: 20px;
}
.not_found_title{
font-size: 60px;
}
.not_found_sub_title{
font-size: 26px;
}
#title_static{
text-align: center;
font-size: 44px;
font-style: normal;
font-weight: 700;
line-height: 52px;
margin-bottom: 20px;
}
@@ -2029,9 +2172,9 @@ span#sub_title_static{
}
button#more_button{
#more_button, #send_parcel_button{
display: inline-block;
height: 60px;
/*height: 60px;*/
width: 20%;
background: #FF613A;
color: #FFF;
@@ -2049,6 +2192,11 @@ button#more_button{
}
#send_parcel_button{
height: 60px;
}
.top_block_static{
position: relative;
width: 90%;
@@ -2253,7 +2401,7 @@ figure{
.bottom_block_static>#box2 {
/* Положение верхнего левого изображения */
top: 16%;
top: 0%;
left: -2%;
transform: scale(-1, 1);
@@ -2271,7 +2419,7 @@ figure{
.bottom_block_static>#box4 {
/* Положение верхнего правого изображения */
top: 18%;
top: 9%;
right: -1%;
}
@@ -2544,18 +2692,40 @@ button#send_feedback_form:active{
}
.cards_wrapper{
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
/*display: flex;*/
/*flex-direction: row;*/
/*flex-wrap: wrap;*/
/*justify-content: center;*/
display: inline-block;
}
.cards_item_1, .cards_item_3{
float: left;
}
.cards_item_2, .cards_item_4{
float: right;
}
.cards_item_1>.cards_item_img>img,
.cards_item_2>.cards_item_img>img,
.cards_item_3>.cards_item_img>img,
.cards_item_4>.cards_item_img>img{
float: right;
}
#reg_or_text{
margin: 10px;
}
.cards_item_2>.cards_item_text>div, .cards_item_3>.cards_item_text>div{
color: #1d1e20;
}
.cards_item_1{
width: 48%;
height: 322px;
border-radius: 10px;
background: url(/static/img/png/cards_item_1.png) #1d1e20 50%;
/*background: url(/static/img/png/cards_item_1.png) #1d1e20 50%;*/
background: #1d1e20 50%;
background-repeat: no-repeat;
background-position: right;
@@ -2564,13 +2734,7 @@ button#send_feedback_form:active{
margin: 10px;
}
.cards_item_1_left,
.cards_item_2_left,
.cards_item_3_left,
.cards_item_4_left{
width: 55%;
float: left;
}
@@ -2585,10 +2749,9 @@ button#send_feedback_form:active{
}
.cards_item_2{
width: 48%;
height: 322px;
border-radius: 10px;
background: url(/static/img/png/cards_item_2.png) white 50%;
border-radius: 10px;
/*background: url(/static/img/png/cards_item_2.png) white 50%;*/
background: white 50%;
background-repeat: no-repeat;
background-position: right;
@@ -2598,13 +2761,23 @@ button#send_feedback_form:active{
}
.cards_item_2>div,
.cards_item_3>div{
color: black;
text-shadow: none;
text-shadow: 1px 1px 0px #ffffff;
.cards_item_text {
float: left;
width: 50%;
}
.cards_item_img {
float: right;
width: 50%;
}
/*.cards_item_2>div,*/
/*.cards_item_3>div{*/
/* color: black;*/
/* text-shadow: none;*/
/* text-shadow: 1px 1px 0px #ffffff;*/
/*}*/
.cards_item_2_right{
float: right;
border-radius: 10px;
@@ -2630,10 +2803,9 @@ button#send_feedback_form:active{
.cards_item_3{
width: 48%;
height: 322px;
border-radius: 10px;
background: url(/static/img/png/cards_item_3.png) white 50%;
/*background: url(/static/img/png/cards_item_3.png) white 50%;*/
background: white 50%;
background-repeat: no-repeat;
background-position: right;
box-shadow: -1px 4px 10px 0px rgba(198, 199, 203, 0.20), 0px -1px 10px 0px rgba(198, 199, 203, 0.20);
@@ -2653,10 +2825,9 @@ button#send_feedback_form:active{
.cards_item_4{
width: 48%;
height: 322px;
border-radius: 10px;
background: url(/static/img/png/cards_item_4.png), #111217 50%;
/*background: url(/static/img/png/cards_item_4.png), #111217 50%;*/
background: #111217 50%;
background-repeat: no-repeat;
background-position: right;
@@ -2665,6 +2836,16 @@ button#send_feedback_form:active{
margin: 10px;
}
.cards_item_1,
.cards_item_2,
.cards_item_3,
.cards_item_4{
height: 322px;
width: 48%;
}
.cards_item_4_right{
float: right;
border-radius: 10px;
@@ -2681,7 +2862,7 @@ button#send_feedback_form:active{
font-style: normal;
font-weight: 700;
line-height: 52px; /* 118.182% */
margin: 104px 0 0 20px;
margin: 67px 0 0 20px;
}
.card_title_2{
color: #FFF;
@@ -2698,7 +2879,7 @@ button#send_feedback_form:active{
font-weight: 400;
line-height: 22px;
margin: 20px 0 0 20px;
width: 50%;
}
/*faq_main_page*/
@@ -2887,13 +3068,17 @@ details[open] summary ~ *{
/*END_user_articles*/
/*news articles all*/
.advertisement_block_news{
height: 200px;
text-align: center;
border-radius: 10px;
background: #FFF;
box-shadow: -1px 4px 10px 0px rgba(198, 199, 203, 0.20), 0px -1px 10px 0px rgba(198, 199, 203, 0.20);
/*text-align: center;*/
/*background: #FFF;*/
/*box-shadow: -1px 4px 10px 0px rgba(198, 199, 203, 0.20), 0px -1px 10px 0px rgba(198, 199, 203, 0.20);*/
margin-bottom: 40px;
}
.advertisement_content>img{
width: 100%;
border-radius: 10px;
box-shadow: -1px 4px 10px 0px rgba(198, 199, 203, 0.20), 0px -1px 10px 0px rgba(198, 199, 203, 0.20);
}
.wrapper_advertisement {
/*padding-top: 140px;*/
@@ -2944,6 +3129,7 @@ details[open] summary ~ *{
font-style: normal;
font-weight: 600;
line-height: 20px;
margin-bottom: 20px;
}
.self_news_header{
font-size: 24px;
@@ -2953,7 +3139,7 @@ details[open] summary ~ *{
margin-bottom: 40px;
}
.self_news_description{
margin-bottom: 40px;
margin-bottom: 20px;
}
.self_news_text>p+img{
@@ -2969,6 +3155,7 @@ details[open] summary ~ *{
float: right;
width: 40%;
margin-left: 20px;
margin-bottom: 20px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

7
static/img/svg/gb.svg Normal file
View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-gb" viewBox="0 0 512 512">
<path fill="#012169" d="M0 0h512v512H0z"/>
<path fill="#FFF" d="M512 0v64L322 256l190 187v69h-67L254 324 68 512H0v-68l186-187L0 74V0h62l192 188L440 0z"/>
<path fill="#C8102E" d="M184 324l11 34L42 512H0v-3l184-185zm124-12l54 8 150 147v45L308 312zM512 0L320 196l-4-44L466 0h46zM0 1l193 189-59-8L0 49V1z"/>
<path fill="#FFF" d="M176 0v512h160V0H176zM0 176v160h512V176H0z"/>
<path fill="#C8102E" d="M0 208v96h512v-96H0zM208 0v512h96V0h-96z"/>
</svg>

After

Width:  |  Height:  |  Size: 541 B

7
static/img/svg/ru.svg Normal file
View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-ru" viewBox="0 0 512 512">
<g fill-rule="evenodd" stroke-width="1pt">
<path fill="#fff" d="M0 0h512v512H0z"/>
<path fill="#0039a6" d="M0 170.7h512V512H0z"/>
<path fill="#d52b1e" d="M0 341.3h512V512H0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -3,6 +3,8 @@ function SendLoginForm(el){
event.preventDefault()
let form = el.form;
let formData = new FormData(form);
let msr = sessionStorage.getItem('mailingSubscribeRequired')
formData.set('mailingSubscribeRequired',msr)
@@ -18,7 +20,10 @@ function SendLoginForm(el){
data: formData,
success: function(data){
location.href = '/profile/page/dashboard/'
location.href = `/profile/page/dashboard/`
window.sessionStorage.removeItem('mailingSubscribeRequired')
window.sessionStorage.removeItem('email')

View File

@@ -1,13 +1,16 @@
function update_count_unread_messages (data) {
let list_unrd = document.querySelectorAll(".unredmessages_value_text")
let list_unrd_parent = document.querySelectorAll(".icon_unread_messages")
let i = 0
for (i;i < list_unrd.length;i++){
if (!list_unrd_parent[i].classList.contains("showed")){
list_unrd_parent[i].classList.toggle("showed")
let selected_btn = document.querySelector(".selected")
if (selected_btn.dataset['ajaxUrl'] !== 'chats'){
let list_unrd = document.querySelectorAll(".unredmessages_value_text")
let list_unrd_parent = document.querySelectorAll(".icon_unread_messages")
let i = 0
for (i;i < list_unrd.length;i++){
if (!list_unrd_parent[i].classList.contains("showed")){
list_unrd_parent[i].classList.toggle("showed")
}
list_unrd[i].innerHTML = data.unread_msgs_count.toString()
}
list_unrd[i].innerHTML = data.unread_msgs_count.toString()
}
}

View File

@@ -19,7 +19,7 @@ function update_chat_html (data,msg_cont) {
function update_list_w_users (data,old_item_tab_user,el_tab) {
let list_of_users = document.querySelector(".block-list-of-users")
let list_of_users = document.querySelector(".container_block_list_of_users")
if (list_of_users) {
if (data.users_list_html){

View File

@@ -1,16 +1,20 @@
function sendMessageSocket (data) {
if (chatSocket.readyState !== 1 && chatSocket.readyState !== 0){
init_ws()
}
loader_show_message(data)
chatSocket.send(JSON.stringify(data));
if (!data.ticket_id){
let el_tab = document.querySelector(".tab_user_messanger.select")
if (el_tab !== null){
el_tab.querySelector(".last-message-messenger-user-tab").innerHTML = data['text']
if (chatSocket && chatSocket.readyState !== 0) {
if (chatSocket.readyState !== 1 && chatSocket.readyState !== 0){
init_ws()
}
loader_show_message(data)
chatSocket.send(JSON.stringify(data));
if (!data.ticket_id){
let el_tab = document.querySelector(".tab_user_messanger.select")
if (el_tab !== null){
el_tab.querySelector(".last-message-messenger-user-tab").innerHTML = data['text']
}
}
} else {
alert('Websoket connection failed')
}
}
@@ -35,6 +39,16 @@ function wsReceiveData (e) {
console.log(data)
} else if (data.type === "update_chat") {
let msg_cont = document.querySelector(".container-messages")
if (getInfoAboutUser('screen_width') < 800){
if (!window.location.href.includes("chat") && !window.location.href.includes("support")){
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('hide')){
marker_new_messages.classList.add('show')
marker_new_messages.classList.remove('hide')
}
setCokie(365,'twb_new_messages',true)
}
}
update_chat_html(data,msg_cont)
// document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'end',inline:'end'});
@@ -55,6 +69,8 @@ function wsReceiveData (e) {
if (user_id) {
if (ticket_maneger.toString() !== user_id) {
clear_messenger()
} else {
}
}
else {
@@ -93,14 +109,25 @@ function wsReceiveData (e) {
}
// }
// if
update_list_w_users(data,old_item_tab_user,el_tab)
if (window.location.href.includes("chat")){
update_list_w_users(data,old_item_tab_user,el_tab)
}
} else if (data.type === "update_support_chat"){
update_support_chat_func(data,msg_cont)
}
if (data.unread_msgs_count > 0){
if (getInfoAboutUser('screen_width') < 800){
if (!window.location.href.includes("chat") && !window.location.href.includes("support")){
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('hide')){
marker_new_messages.classList.add('show')
marker_new_messages.classList.remove('hide')
}
setCokie(365,'twb_new_messages',true)
}
}
update_count_unread_messages(data)
}
if (data.required_beep === true) {

View File

@@ -4,6 +4,9 @@
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
!function(t,e) {
if ("function" == typeof define && define.amd) define(["moment", "jquery"], function (t, a) {
@@ -47,19 +50,26 @@
this.buttonClasses = "btn btn-sm",
this.applyButtonClasses = "btn-primary",
this.cancelButtonClasses = "btn-default",
this.locale = {
direction: "ltr",
// format: t.localeData().longDateFormat("L"),
format: "DD.MM.YYYY",
separator: " - ",
applyLabel: "Apply",
cancelLabel: "Cancel",
weekLabel: "W",
customRangeLabel: "Custom Range",
daysOfWeek: t.weekdaysMin(),
monthNames: t.monthsShort(),
firstDay: t.localeData().firstDayOfWeek()
}, this.callback = function () {
this.locale = i.locale,
this.locale.daysOfWeek = t.weekdaysMin(),
this.locale.monthNames = t.monthsShort(),
this.locale.firstDay = t.localeData().firstDayOfWeek(),
// this.locale = {
// direction: "ltr",
// // format: t.localeData().longDateFormat("L"),
// format: "DD.MM.YYYY",
// separator: " - ",
// applyLabel: "Принять",
// cancelLabel: "Отменить",
// weekLabel: "Н",
// customRangeLabel: "Custom Range",
// daysOfWeek: t.weekdaysMin(),
// monthNames: t.monthsShort(),
// firstDay: t.localeData().firstDayOfWeek()
// }
this.callback = function () {
}, this.isShowing = !1, this.leftCalendar = {}, this.rightCalendar = {}, "object" == typeof i && null !== i || (i = {}), "string" == typeof (i = e.extend(this.element.data(), i)).template || i.template instanceof e || (i.template = '<div class="daterangepicker"><div class="ranges"></div><div class="drp-calendar left"><div class="calendar-table"></div><div class="calendar-time"></div></div><div class="drp-calendar right"><div class="calendar-table"></div><div class="calendar-time"></div></div><div class="drp-buttons"><span class="drp-selected"></span><button class="cancelBtn" type="button"></button><button class="applyBtn" disabled="disabled" type="button"></button> </div></div>'), this.parentEl = i.parentEl && e(i.parentEl).length ? e(i.parentEl) : e(this.parentEl), this.container = e(i.template).appendTo(this.parentEl), "object" == typeof i.locale && ("string" == typeof i.locale.direction && (this.locale.direction = i.locale.direction), "string" == typeof i.locale.format && (this.locale.format = i.locale.format), "string" == typeof i.locale.separator && (this.locale.separator = i.locale.separator), "object" == typeof i.locale.daysOfWeek && (this.locale.daysOfWeek = i.locale.daysOfWeek.slice()), "object" == typeof i.locale.monthNames && (this.locale.monthNames = i.locale.monthNames.slice()), "number" == typeof i.locale.firstDay && (this.locale.firstDay = i.locale.firstDay), "string" == typeof i.locale.applyLabel && (this.locale.applyLabel = i.locale.applyLabel), "string" == typeof i.locale.cancelLabel && (this.locale.cancelLabel = i.locale.cancelLabel), "string" == typeof i.locale.weekLabel && (this.locale.weekLabel = i.locale.weekLabel), "string" == typeof i.locale.customRangeLabel)) {
(p = document.createElement("textarea")).innerHTML = i.locale.customRangeLabel;
var n = p.value;

View File

@@ -1,6 +1,6 @@
timeout_range_slider = null
function filters_func_find_route_main (el,owner_type=null,win_loc_replace=null,weight=null){
function filters_func_find_route_main (el, owner_type=null, win_loc_replace=null, weight=null){
console.log("asd")
@@ -11,9 +11,9 @@ function filters_func_find_route_main (el,owner_type=null,win_loc_replace=null,w
let list = forloop_func_form(data_d,"get",get_url)
data_d = list[0]
get_url = list[1]
// if (owner_type !== null) {
// data_d['owner_type'] = owner_type
// }
if (owner_type !== null) {
data_d['owner_type'] = owner_type
}
// get_url = get_url + `owner_type=${owner_type}`
window.location.href = `${win_loc_replace}?${get_url}`
@@ -31,10 +31,10 @@ function filters_func_find_route_main (el,owner_type=null,win_loc_replace=null,w
let list = forloop_func_form(data_d,"get",get_url)
data_d = list[0]
get_url = list[1]
// if (owner_type !== null) {
// data_d['owner_type'] = owner_type
// get_url = get_url + `owner_type=${owner_type}`
// }
if (owner_type !== null) {
data_d['owner_type'] = owner_type
// get_url = get_url + `owner_type=${owner_type}`
}
if (weight){
@@ -58,6 +58,7 @@ function ajax_for_filter (data_d,get_url){
document.querySelector(".container_loader_filters_routes").classList.toggle("show")
}
$.ajax({
// headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
url: '/routes/find_routes/',
type: "POST",

View File

@@ -82,4 +82,11 @@ function focusOnInput (el) {
let parent = el.offsetParent
let input = parent.querySelector('.find_route')
input.focus()
}
function checkLetterOrNumber (el){
let txt = el.value
if (isNaN(txt)){
el.value = txt.slice(0, -1);
}
}

View File

@@ -1,31 +1,139 @@
// $(document).ready(function (){
// middleWareJS()
// })
$(document).ready(function (){
hide_or_show_new_messages_marker()
checkStateCookie()
})
// window.onfocus = function () {
// getSocketState()
// }
window.onload = function (){
changeTopStrMobile()
middleWareJS()
openOrCloseCurtainSupportChat()
openOverlayOrClose()
goToChatIfChat()
// let body = document.querySelector("body")
// const viewPortH = body.getBoundingClientRect().height;
// const windowH = window.innerHeight;
// const browserUiBarsH = viewPortH - windowH;
// body.style.height = `calc(100vh - ${browserUiBarsH}px)`;
// let height = window.innerHeight
// document.querySelector('body').style.maxHeight = height + 'px'
// document.querySelector('body').style.height = height + 'px'
if (window.location.href.includes('profile') && !window.location.href.includes('login') && !window.location.href.includes('registration')){
let user_type = getInfoAboutUser()
if (user_type === 'mobile') {
open_curtain_w_btn_profile()
} else {
if (!window.location.href.includes('profile')){
open_curtain_w_btn_profile()
}
}
if (window.location.href.includes("profile")){
setStandartSettingsToBlockOverlay()
}
// if (window.location.href.includes("profile")){
// selectTabProfileIfHisNotSelected(url)
// }
let chats = document.querySelector(`[data-ajax-url='chats']`)
if (chats){
deleteMarkerMessages()
}
}
}
function hide_or_show_new_messages_marker () {
if (getInfoAboutUser('screen_width') < 800){
if (window.location.href.includes("chat") || window.location.href.includes("support")){
setCokie(365,'twb_new_messages','false')
}
}
}
//
function goToChatIfChat () {
if (document.querySelector('.block-chat')){
let scroll_el = document.querySelector('.block-chat')
if (document.querySelector(".name_ticket")){
scroll_el = document.querySelector(".name_ticket")
}
let top = scroll_el.offsetTop
window.scrollTo({top:top})
document.addEventListener('focusout', function(e,scroll_el) {
window.scrollTo(scroll_el, 0)
});
}
}
function middleWareJS(){
let footer = document.querySelector("footer")
let body = document.querySelector("body")
let type = getInfoAboutUser()
if (type !== 'mobile'){
if (document.querySelector(".menu_buttons.curtain.left") || window.location.href.includes('support') || window.location.href.includes('chat')){
footer.style.display = "none"
body.style.overflow = "hidden"
// if (type !== 'mobile'){
if (document.querySelector(".menu_buttons.curtain.left") || window.location.href.includes('support') || window.location.href.includes('chat')){
footer.style.display = "none"
body.style.overflow = "hidden"
} else {
footer.style.display = ""
body.style.overflow = ""
}
// }/
}
function changeTopStrMobile (){
let body = document.querySelector("body")
// if (!window.location.href.includes("mobile")){
// if (!window.location.href.includes("mobile") && !window.location.href.includes("route_search_results")){
// window.location.href = window.location.href + `?mobile=${getInfoAboutUser() === 'mobile'}`
// }
body.style.opacity = ''
body.style.transition = '500ms'
// } else {
body.style.display = ''
body.style.transition = '500ms'
// }
}
function openOrCloseCurtainSupportChat (){
if (window.location.href.includes("support")){
let type_screen = getInfoAboutUser()
let chat_block = document.querySelector(".block-chat")
let name_ticket = document.querySelector(".name_ticket")
let str = 'menu_buttons curtain left'
if (type_screen === 'mobile'){
if (!chat_block){
str = `${str} open`
} else {
str = `${str} close`
}
} else {
footer.style.display = ""
body.style.overflow = ""
str = `${str} open`
}
if (name_ticket){
str = `${str} margin`
}
document.querySelector(".menu_buttons").class = str
}
}
function openOverlayOrClose () {
if (window.location.href.includes("profile") && !window.location.href.includes("login") && !window.location.href.includes("registration")){
let overlay = document.querySelector('.block_overlay')
if (screen.width < 700){
if (!overlay.classList.contains("show")){
overlay.classList.add("show")
overlay.classList.remove("hidden")
}
}
}
}
function getTypeOfData (data) {
@@ -34,41 +142,58 @@ function getTypeOfData (data) {
}
function getInfoAboutUser (){
function getInfoAboutUser (screen_width){
let user_type = ''
if (screen.width <= 700){
user_type = 'mobile'
} else if (screen.width > 1024) {
} else if (screen.width > 1180) {
user_type = 'desctop'
} else if (screen.width > 700 && screen.width < 1024) {
} else if (screen.width > 700 && screen.width <= 1180) {
user_type = 'laptop'
}
return user_type
if (screen_width){
return screen.width
} else {
return user_type
}
}
document.addEventListener('DOMContentLoaded', function() {
let img = document.getElementById('dropbtn_lang')
if (window.location.href.indexOf("ru") > -1){
img.style.background = "url('/static/img/png/ru.png')"
img.style.background = "url('/static/img/svg/ru.svg')"
img.style.backgroundRepeat = "no-repeat"
img.style.backgroundPosition = "left center"
img.style.backgroundPosition = "center"
// img.style.backgroundSize = '50%'
}else if(window.location.href.indexOf("en") > -1){
img.style.background = "url('/static/img/png/en.png')"
img.style.background = "url('/static/img/svg/gb.svg')"
img.style.backgroundRepeat = "no-repeat"
img.style.backgroundPosition = "left center"
img.style.backgroundPosition = "center"
// img.style.backgroundSize = '50%'
}
let login_email = document.getElementById('login_email_input')
let registration_email = document.getElementById('registration_email_input')
if(login_email){
login_email.value = sessionStorage.getItem('email')
}else if(registration_email){
registration_email.value = sessionStorage.getItem('email')
}
});
window.addEventListener('scroll', () => {
// let headerBG = document.getElementById('header_bg')
//
// headerBG.style.backgroundColor = 'rgb(248 248 248 / 90%)'
// headerBG.style.padding = '20px 40px'
// headerBG.style.paddingBottom = 'padding: 10px 40px 10px 40px'
// headerBG.style.paddingRight = 'padding: 10px 40px 10px 40px'
// headerBG.style.paddingLeft = 'padding: 10px 40px 10px 40px'
})
// window.addEventListener('scroll', () => {
// // let headerBG = document.getElementById('header_bg')
// //
// // headerBG.style.backgroundColor = 'rgb(248 248 248 / 90%)'
// // headerBG.style.padding = '20px 40px'
// // headerBG.style.paddingBottom = 'padding: 10px 40px 10px 40px'
// // headerBG.style.paddingRight = 'padding: 10px 40px 10px 40px'
// // headerBG.style.paddingLeft = 'padding: 10px 40px 10px 40px'
// })
// Действия при изменении URL
@@ -98,3 +223,50 @@ function scroll_ev (event,el){
}
}
function checkStateCookie () {
if (!window.document.cookie.includes("allow_cookie=true")){
document.querySelector(".cookie_block").classList.add("show")
}
if (window.document.cookie.includes("twb_new_messages=true")){
if (getInfoAboutUser('screen_width') < 800) {
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('hide')) {
marker_new_messages.classList.remove('hide')
marker_new_messages.classList.add('show')
}
}
} else if (window.document.cookie.includes("twb_new_messages=false")){
if (getInfoAboutUser('screen_width') < 800) {
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('show')) {
marker_new_messages.classList.add('hide')
marker_new_messages.classList.remove('show')
}
}
}
}
function getCsrfCookie () {
let str = window.document.cookie
str = str.split('; ');
let obj_cookie = {}
for (let i = 0;i < str.length;i++){
let cur = str[i].split('=');
obj_cookie[cur[0]] = cur[1]
}
let csrf = obj_cookie['csrftoken']
return csrf
}
function setCokie (days,name,val) {
let date = new Date();
// let days = 182;
date.setTime(+ date + (days * 86400000));
window.document.cookie = `${name}=${val}` + "; expires=" + date.toGMTString() + "; path=/";
document.querySelector(".cookie_block").classList.remove("show")
// return value;
}
function getInCookieTime (time) {
return time * 24 * 60 * 60
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,91 @@
const registerSw = async () => {
if ('serviceWorker' in navigator) {
const reg = await navigator.serviceWorker.register('/sw.js');
initialiseState(reg)
} else {
showNotAllowed("You can't send push notifications ☹️😢")
}
};
const initialiseState = (reg) => {
if (!reg.showNotification) {
showNotAllowed('Showing notifications isn\'t supported ☹️😢');
return
}
if (Notification.permission === 'denied') {
showNotAllowed('You prevented us from showing notifications ☹️🤔');
return
}
if (!'PushManager' in window) {
showNotAllowed("Push isn't allowed in your browser 🤔");
return
}
subscribe(reg);
}
const showNotAllowed = (message) => {
const button = document.querySelector('form>button');
button.innerHTML = `${message}`;
button.setAttribute('disabled', 'true');
};
function urlB64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
const outputData = outputArray.map((output, index) => rawData.charCodeAt(index));
return outputData;
}
const subscribe = async (reg) => {
const subscription = await reg.pushManager.getSubscription();
if (subscription) {
sendSubData(subscription);
return;
}
const vapidMeta = document.querySelector('meta[name="vapid-key"]');
const key = vapidMeta.content;
const options = {
userVisibleOnly: true,
// if key exists, create applicationServerKey property
...(key && {applicationServerKey: urlB64ToUint8Array(key)})
};
const sub = await reg.pushManager.subscribe(options);
sendSubData(sub)
};
const sendSubData = async (subscription) => {
const browser = navigator.userAgent.match(/(firefox|msie|chrome|safari|trident)/ig)[0].toLowerCase();
const data = {
status_type: 'subscribe',
subscription: subscription.toJSON(),
browser: browser,
user_agent: browser,
};
const res = await fetch('/webpush/save_information', {
method: 'POST',
body: JSON.stringify(data),
headers: {
'content-type': 'application/json',
},
credentials: "include"
});
handleResponse(res);
};
const handleResponse = (res) => {
console.log(res.status);
};
registerSw();

View File

@@ -43,6 +43,52 @@
// });
// }
// });
locale_ru = new Object({
direction: "ltr",
// format: t.localeData().longDateFormat("L"),
format: "DD.MM.YYYY",
separator: " - ",
applyLabel: "Принять",
cancelLabel: "Отменить",
weekLabel: "Н",
customRangeLabel: "Custom Range",
});
locale_en = new Object({
direction: "ltr",
// format: t.localeData().longDateFormat("L"),
format: "DD.MM.YYYY",
separator: " - ",
applyLabel: "Apply",
cancelLabel: "Cancel",
weekLabel: "W",
customRangeLabel: "Custom Range",
});
function changeLangForDateTimePicker() {
if (document.documentElement.lang === 'ru'){
locale_lang = locale_ru;
lang = 'ru';
} else {
locale_lang = locale_en;
lang ='en';
}
moment.locale(lang);
return locale_lang
}
function init_arrival_DT (date=null,single=true,hour=true){
let minDate = null
if (date){
@@ -58,6 +104,9 @@ function init_arrival_DT (date=null,single=true,hour=true){
}
let place_1 = document.querySelector("#id_arrival_DT")
if (place_1) {
$(place_1).daterangepicker({
"autoapply": true,
"linkedCalendars": false,
@@ -65,6 +114,7 @@ function init_arrival_DT (date=null,single=true,hour=true){
"timePicker":hour,
"timePicker24Hour":true,
"minDate":minDate,
"locale": changeLangForDateTimePicker(),
},
function (start, end, label) {
@@ -77,6 +127,7 @@ function init_arrival_DT (date=null,single=true,hour=true){
}
});
$(`${place_1.id} .drp-calendar.right`).hide();
$(`${place_1.id} .drp-calendar.left`).addClass('single');
@@ -108,6 +159,7 @@ function init_departure_DT (){
"singleDatePicker":true,
"timePicker":true,
"timePicker24Hour":true,
"locale": changeLangForDateTimePicker(),
},
function(start, end, label) {
// $('#displayRegervation').text('Registration date is: ' + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD'));
@@ -142,6 +194,7 @@ $(function () {
$(place_1).daterangepicker({
"autoapply": true,
"linkedCalendars": false,
"locale": changeLangForDateTimePicker(),
},
function (start, end, label) {
@@ -174,6 +227,7 @@ $(function() {
$(place_1).daterangepicker({
"autoapply": true,
"linkedCalendars": false,
"locale": changeLangForDateTimePicker(),
onl_param
},
function(start, end, label) {

View File

@@ -2,6 +2,8 @@ function SendRegistrationForm(el){
event.preventDefault()
let form = el.form;
let formData = new FormData(form);
let msr = sessionStorage.getItem('mailingSubscribeRequired')
formData.set('mailingSubscribeRequired',msr)
$.ajax({
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
@@ -15,7 +17,9 @@ function SendRegistrationForm(el){
data: formData,
success: function(data){
location.href = '/profile/page/dashboard/'
location.href = `/profile/page/dashboard/`
window.sessionStorage.removeItem('mailingSubscribeRequired')
window.sessionStorage.removeItem('email')
},
error: function (data, exception){
document.querySelector(".register").innerHTML = data.responseJSON.html

View File

@@ -255,6 +255,7 @@ function loader_place_ins_boris (el,type=null){
let cur_loader_place = el.nextElementSibling
if (type){
cur_loader_place.innerHTML = ""
changeWidthEL(el)
} else {
if (loader_place){
@@ -313,9 +314,6 @@ function searchTown(el){
success: function(data){
el.style.background = 'white url("/static/img/png/icon-arrow.svg") no-repeat calc(100% - 15px) center';
loader_place_ins_boris(el,"el")
if (document.querySelector(".container_form_search_carrier")){
document.querySelector(".container_form_search_carrier").style.zIndex = '10000000000'
}
@@ -329,7 +327,7 @@ function searchTown(el){
}
});
}, 1500);
}, 500);
}
}
@@ -350,13 +348,14 @@ function selectItemAddrPoint(id, name, ctrl_name,){
tap_txt_cont.setAttribute('title',name)
let tap_cont = document.querySelector("#id_" + ctrl_name.slice(0, -4));
tap_cont.value = id;
if (tap_txt_cont.classList.contains('red_text')){
tap_txt_cont.classList.remove('red_text')
}
if (!window.location.href.includes("profile")){
changeWidthEL(tap_txt_cont)
}
input_list.classList.remove('show');
if (document.querySelector(".container_form_search_carrier")){
document.querySelector(".container_form_search_carrier").style.zIndex = 'unset'
}
}
@@ -402,14 +401,29 @@ function onblurInputField(event,el){
if(!parent_event || parent_event[0] !== search_list){
search_list.classList.remove('show')
if (document.querySelector(".container_form_search_carrier")){
document.querySelector(".container_form_search_carrier").style.zIndex = '10000000000'
}
}
// }
}
function clearID(el) {
el.select();
if(el.value !== "" && el.id === 'id_from_address_point_txt' ){
document.getElementById('id_from_address_point').value = ''
el.value = ''
// el.classList.add('red_text')
} else if(el.value !== "" && el.id === 'id_to_address_point_txt'){
document.getElementById('id_to_address_point').value = ''
el.value = ''
// el.classList.add('red_text')
}
}
// function hideErrorMsg(el) {
// let hide_element = document.querySelector()
@@ -472,58 +486,62 @@ function sendRoute(el, routeID = null){
el.disabled = true
let list_of_elements_form = document.querySelectorAll(".el_form_b_new_route");
let checked_cargo_type = document.querySelectorAll('.cargo_check');
// let list_of_elements_form = document.querySelectorAll(".el_form_b_new_route");
// let checked_cargo_type = document.querySelectorAll('.cargo_check');
//
// let obj_w_el_form = {}
//
//
// for (let n = 0;n < checked_cargo_type.length; n++){
// let checked_cargo = checked_cargo_type[n]
// if(checked_cargo.checked === true){
// let name_cargo = checked_cargo.name
// let value_cargo = checked_cargo_type[n].value
// obj_w_el_form[name_cargo] = value_cargo
//
//
// }
// }
//
//
//
//
// for (let i = 0; i < list_of_elements_form.length ;i++) {
// // let id_el = list_of_elements_form[i].id
// // if (id_el){
// // if (id_el === "")
// // }
//
//
//
// let name_attr = list_of_elements_form[i].attributes["name"]
// if (name_attr) {
// let name_el = name_attr.value
// let value_el = list_of_elements_form[i].value
// obj_w_el_form[name_el] = value_el
// }
// }
//
//
//
// let selected_owner_type = document.querySelectorAll("#customer, #mover")
//
// selected_owner_type.forEach(function(item) {
// if (item.classList.contains('selected')) {
// let { id, innerText } = item
// obj_w_el_form['owner_type'] = id
// }
// });
//
// if (selected_owner_type[0].classList.contains('selected')){
//
// }else{}
let owner_type_value = document.getElementById('hide_owner_type').value
let obj_w_el_form = {}
for (let n = 0;n < checked_cargo_type.length; n++){
let checked_cargo = checked_cargo_type[n]
if(checked_cargo.checked === true){
let name_cargo = checked_cargo.name
let value_cargo = checked_cargo_type[n].value
obj_w_el_form[name_cargo] = value_cargo
}
}
for (let i = 0; i < list_of_elements_form.length ;i++) {
// let id_el = list_of_elements_form[i].id
// if (id_el){
// if (id_el === "")
// }
let name_attr = list_of_elements_form[i].attributes["name"]
if (name_attr) {
let name_el = name_attr.value
let value_el = list_of_elements_form[i].value
obj_w_el_form[name_el] = value_el
}
}
let selected_owner_type = document.querySelectorAll("#customer, #mover")
selected_owner_type.forEach(function(item) {
if (item.classList.contains('selected')) {
let { id, innerText } = item
obj_w_el_form['owner_type'] = id
}
});
if (selected_owner_type[0].classList.contains('selected')){
}else{}
let form = el.form
let formData = new FormData(form);
let owner_type = owner_type_value
formData.set('owner_type', owner_type)
let url = '/routes/create_or_change_route/'
if (routeID !== null){
@@ -539,7 +557,8 @@ function sendRoute(el, routeID = null){
processData: false,
contentType: false,
// enctype: 'json',
data: JSON.stringify(obj_w_el_form),
// data: JSON.stringify(obj_w_el_form),
data: formData,
success: function(data){
let data_route_id = data.route_id
@@ -561,6 +580,8 @@ function sendRoute(el, routeID = null){
// document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'nearest',inline:'nearest'});
@@ -588,12 +609,20 @@ function sendRoute(el, routeID = null){
function validate(el) {
if (el.checked) {
console.log('cheked', el.id);
} else {
console.log("You didn't check it! Let me check it for you.", el.id);
}
// function validate(el) {
// if (el.checked) {
// console.log('cheked', el.id);
// } else {
// console.log("You didn't check it! Let me check it for you.", el.id);
// }
// }
function setIcon(el) {
if(el.id === 'id_departure_DT' ){
document.getElementById('id_departure_DT').style.background = 'url("/static/img/svg/IconCalendar.svg") white 98% no-repeat';
}
}
@@ -602,9 +631,22 @@ function validate(el) {
//cleaning route inputs after selection changes
function OnSelectionChange(el) {
event.preventDefault()
let form = el.form;
// if (customer.classList.contains('selected')) {
// owner_type = form.dataset['customer']
// } else if (mover.classList.contains('selected')) {
// owner_type = form.dataset['customer']
// }
let owner_type_value = document.getElementById('hide_owner_type').value
let formData = new FormData(form);
let owner_type = owner_type_value
formData.set('owner_type', owner_type)
// formData.set('owner_type', owner_type)
// let data = {};
// data['csrfmiddlewaretoken'] = $('input[name="csrfmiddlewaretoken"]')[0].value;
@@ -755,6 +797,11 @@ function editRoute(id) {
if(data.html){
let changeTextButton = document.getElementById('registration')
changeTextButton.innerText = 'Сохранить изменения'
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
});
}
init_departure_DT()
@@ -812,11 +859,11 @@ function checkDate() {
// alert("End date cannot be less than Start date.");
dateArrival.value = ""
let arrivalDiv = document.getElementById('arrival_div')
let errorMessage = document.createElement('span');
errorMessage.textContent = "Дата прибытия, не может быть установлена раньше даты отправки"
errorMessage.classList.add('errorlist')
arrivalDiv.appendChild(errorMessage);
// let arrivalDiv = document.getElementById('arrival_div')
// let errorMessage = document.createElement('span');
// // errorMessage.textContent = "Дата прибытия, не может быть установлена раньше даты отправки"
// errorMessage.classList.add('errorlist')
// arrivalDiv.appendChild(errorMessage);
}
else if (DateEnd > DateStart){
let arrivalDiv = document.getElementById('arrival_div');
@@ -941,35 +988,150 @@ function RequestCommercialOffer (el){
}
function subscribeNewsletter (el){
el.style.background = '#FF613A url("/static/img/svg/loader_white.svg") no-repeat center';
el.style.contentVisibility = 'hidden';
event.preventDefault()
let disable_btn_f = document.getElementById('footer_input_button');
disable_btn_f.setAttribute('disabled', true);
let form = el.form;
let formData = new FormData(form);
let form_name = form.dataset['name']
formData.set('form_name',form_name)
$.ajax({
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
url: '/user_account/mailing_subscribe/',
type: "POST",
// async: true,
cache: false,
processData: false,
contentType: false,
// enctype: 'json',
data: formData,
success: function(data){
// el.style.background = '#FF613A';
el.removeAttribute('style')
if(data.status === 'sended' && data.del_form === true){
document.querySelector('.footer_input_wrap').innerHTML = data.html;
} else if(data.redirect_url){
window.sessionStorage.setItem('email', data.email)
window.sessionStorage.setItem('mailingSubscribeRequired','true')
window.location.replace(data.redirect_url)
}
if(el.id !== 'footer_input_button'){
let insert_text = document.querySelector(".clear_form")
if(insert_text){
$(data.html).insertBefore(insert_text)
}
let insert_text_2 = document.querySelector(".commercial_offer")
if(insert_text_2){
$(data.html).insertBefore(insert_text_2)
}
} else {
let disable_btn_f = document.getElementById('footer_input_button');
if(disable_btn_f){
disable_btn_f.removeAttribute('disabled');
}
let clear_footer_form = document.getElementById('clear_input');
clear_footer_form.reset();
let hide_error_msg = document.getElementById('error_footer').classList.add('hide')
}
},
error: function (data, exception){
// document.querySelector(".login").innerHTML = data.responseJSON.html
if(el.id !== 'footer_input_button'){
let feedback_form = document.querySelector('.feedback_form')
if(feedback_form){
feedback_form.innerHTML = data.responseJSON.html;
// let incorrect_block = document.querySelectorAll('.inputs_l')
}
let commercial_offer = document.querySelector('.commercial_offer')
if(commercial_offer){
commercial_offer.innerHTML = data.responseJSON.html;
}
} else {
let footer_form = document.querySelector('.insert_form').innerHTML = data.responseJSON.html;
// $(data.responseJSON.html).insertBefore(footer_form)
}
// document.querySelector(".info_profile").innerHTML = data.html;
}
});
}
function hideErrors(el) {
let error_feeedback_text = document.getElementById('error_feedback_text')
let error_feeedback = el.nextElementSibling
let counter_text = document.querySelector('.counter-text')
let footer_button = document.getElementById('footer_input_button')
let error_footer = document.getElementById('error_footer')
if(error_feeedback === counter_text ){
error_feeedback_text.classList.add('hide')
} else if(error_feeedback === footer_button ){
error_footer.classList.add('hide')
}
else {
error_feeedback.classList.add('hide')
}
let error_feeedback_text = document.getElementById('error_feedback_text')
let error_feeedback = el.nextElementSibling
let counter_text = document.querySelector('.counter-text')
let footer_button = document.getElementById('footer_input_button')
let error_footer = document.getElementById('error_footer')
let agree_error = document.getElementById('reg_agree_error')
let error_departure_DT = document.getElementById('error_departure_DT')
let error_arrival_DT = document.getElementById('error_arrival_DT')
let error_from_address_point = document.getElementById('error_from_address_point')
let error_to_address_point = document.getElementById('error_to_address_point')
let error_cargo_type = document.getElementById('error_cargo_type')
let error_id_phone = document.getElementById('error_id_phone')
if(error_feeedback === counter_text && error_feeedback !== null && error_feeedback_text !== null ){
error_feeedback_text.classList.add('hide')
} else if(error_feeedback === footer_button && error_footer !== null ){
error_footer.classList.add('hide')
} else if(el.id === 'agreement_check'){
agree_error.classList.add('hide')
} else if(el.id === 'id_arrival_DT' && error_arrival_DT !== null){
error_arrival_DT.classList.add('hide')
}else if(el.id === 'id_departure_DT' && error_departure_DT !== null){
error_departure_DT.classList.add('hide')
} else if(el.id === 'id_from_address_point_txt' && error_from_address_point !== null ){
error_from_address_point.classList.add('hide')
}else if(el.id === 'id_to_address_point_txt' && error_to_address_point !== null ){
error_to_address_point.classList.add('hide')
} else if(el.id === 'id_cargo_lable' && error_cargo_type !== null){
error_cargo_type.classList.add('hide')
} else if(el.id === 'id_phone' && error_id_phone !==null){
error_id_phone.classList.add('hide')
}
// if(el.nextElementSibling === errorFeeedback){
// errorFeeedback.classList.add('hide')
// }
else if(error_feeedback !== null) {
error_feeedback.classList.add('hide')
}
}

View File

@@ -9,7 +9,6 @@ profile_tabs_f_static_map = new Map([
['dashboard','dashboard']
])
function select_tab_profile (el,url,owner_type=null) {
let data = {}
let confirm_url = `/user_account/${url}/`
@@ -26,6 +25,7 @@ function select_tab_profile (el,url,owner_type=null) {
document.querySelector(".info_profile").innerHTML = '<img src="/static/img/svg/loader.svg" style="height: 30px;position: absolute;top: 47%;left: 45%;"/>'
}
$.ajax({
// headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
url: confirm_url,
type: "POST",
@@ -36,6 +36,7 @@ function select_tab_profile (el,url,owner_type=null) {
// enctype: 'json',
data: JSON.stringify(data),
success: function(data){
let scroll_top = window.scrollY
document.querySelector(".info_profile").innerHTML = data.html;
let list_div = document.querySelectorAll('.menu_profile div');
list_div.forEach(el=>{ el.classList.remove('selected'); });
@@ -45,22 +46,26 @@ function select_tab_profile (el,url,owner_type=null) {
let confirm_url_f_lang_ru = ''
let confirm_url_f_lang_en = ''
if (owner_type){
window.history.pushState(null, null, `/${document.documentElement.lang}/profile/page/${profile_tabs_f_static_map.get(`${url}_${owner_type}`)}/?mobile=${getInfoAboutUser() === 'mobile'}`)
confirm_url_f_lang_ru = `/ru/profile/page/${profile_tabs_f_static_map.get(`${url}_${owner_type}`)}/?mobile=${getInfoAboutUser() === 'mobile'}`
confirm_url_f_lang_en = `/en/profile/page/${profile_tabs_f_static_map.get(`${url}_${owner_type}`)}/?mobile=${getInfoAboutUser() === 'mobile'}`
window.history.pushState(null, null, `/${document.documentElement.lang}/profile/page/${profile_tabs_f_static_map.get(`${url}_${owner_type}`)}`)
confirm_url_f_lang_ru = `/ru/profile/page/${profile_tabs_f_static_map.get(`${url}_${owner_type}`)}/`
confirm_url_f_lang_en = `/en/profile/page/${profile_tabs_f_static_map.get(`${url}_${owner_type}`)}/`
} else {
window.history.pushState(null, null, `/${document.documentElement.lang}/profile/page/${profile_tabs_f_static_map.get(url)}/?mobile=${getInfoAboutUser() === 'mobile'}`)
confirm_url_f_lang_ru = `/ru/profile/page/${profile_tabs_f_static_map.get(url)}/?mobile=${getInfoAboutUser() === 'mobile'}`
confirm_url_f_lang_en = `/en/profile/page/${profile_tabs_f_static_map.get(url)}/?mobile=${getInfoAboutUser() === 'mobile'}`
window.history.pushState(null, null, `/${document.documentElement.lang}/profile/page/${profile_tabs_f_static_map.get(url)}/`)
confirm_url_f_lang_ru = `/ru/profile/page/${profile_tabs_f_static_map.get(url)}/`
confirm_url_f_lang_en = `/en/profile/page/${profile_tabs_f_static_map.get(url)}/`
}
document.querySelector("#ru_lang").href = confirm_url_f_lang_ru
document.querySelector("#en_lang").href = confirm_url_f_lang_en
let header = document.querySelector("header")
header.scrollIntoView({
behavior: "smooth",
block: "end",
inline: "nearest"
})
// let header = document.querySelector("header")
// header.scrollIntoView({
// behavior: "smooth",
// block: "end",
// inline:'nearest'
// })
window.scrollTo({
top: 0,
behavior: "smooth",
});
middleWareJS()
let user_type = getInfoAboutUser()
if (user_type === 'mobile') {
@@ -75,6 +80,22 @@ function select_tab_profile (el,url,owner_type=null) {
setStandartSettingsToBlockOverlay()
}
if (window.location.href.includes("profile")){
selectTabProfileIfHisNotSelected(url)
}
deleteMarkerMessages(el)
checkStatesAfterTransitionToAnotherTabProfile()
goToChatIfChat()
if (window.location.href.includes("chat") || window.location.href.includes("support")) {
if (getInfoAboutUser('screen_width') < 800) {
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('show')) {
marker_new_messages.classList.remove('show')
marker_new_messages.classList.add('hide')
}
}
}
setCokie(365,'twb_new_messages','false')
},
error: function (data){
console.log(data)
@@ -82,16 +103,54 @@ function select_tab_profile (el,url,owner_type=null) {
}
});
}
function checkStatesAfterTransitionToAnotherTabProfile () {
// check which page if profile - do
if (window.location.href.includes('profile')){
// if curtain open we need to close, so we'il see content without curtain
if (document.querySelector(".menu_buttons.curtain.right.open")){
open_curtain_w_btn_profile()
}
// if overlay open we need to close, so we'il see content without overlay
if (document.querySelector('.block_overlay.show')){
setStandartSettingsToBlockOverlay()
}
// if page === chat - do or if page === support
if (window.location.href.includes("page/chat/") || window.location.href.includes("page/support/")){
// if curtain with contacts or curtain with clients close we need to open it,
// but if user === not admin, and user in page support we didn't need to do anything
if (document.querySelector(".menu_buttons.curtain.left.close")){
open_curtain_w_contacts()
}
}
}
}
function deleteMarkerMessages (el) {
let marker = document.querySelectorAll(".icon_unread_messages")
if (marker.length > 0) {
marker[0].classList.remove("showed")
if (marker[1]) {
marker[1].classList.remove("showed")
}
}
}
function selectTabProfileIfHisNotSelected (url) {
if (url !== 'new_route_view') {
let el_f_select = document.querySelector(`[data-ajax-url=${url}]`)
el_f_select.classList.add('selected')
}
}
function clickONTHEAPROfileBTN (el) {
let parent = el.parentNode
let el_f_click = parent.querySelector(".text_btn_profile")
let el_f_click = el.querySelector(".text_btn_profile")
el_f_click.click()
}
function changeHrefCl (el) {
let dataset = el.dataset
let old_href = dataset['href']
let new_href = old_href + `?mobile=${getInfoAboutUser() === 'mobile'}`
let new_href = old_href
el.setAttribute('href',new_href)
}
@@ -342,25 +401,26 @@ async function attachFilemeassge (el,id_ticket=null,sender=null,receiver=null,ch
function change_profile_confirm (el){
event.preventDefault()
let form = el.form
let changed_elements = {}
for (let i = 0;i < form.length;i++){
let cur_el = form[i]
if (cur_el.localName !== 'button'){
let new_val = cur_el.value
let dataset = cur_el.dataset
let old_val = ''
if (dataset){
old_val = dataset['initialValue']
}
// if (old_val){
if (old_val === new_val){
//
} else {
changed_elements[cur_el.name] = cur_el.value
}
}
// }
}
let formData = new FormData(form);
// let changed_elements = {}
// for (let i = 0;i < form.length;i++){
// let cur_el = form[i]
// if (cur_el.localName !== 'button'){
// let new_val = cur_el.value
// let dataset = cur_el.dataset
// let old_val = ''
// if (dataset){
// old_val = dataset['initialValue']
// }
// // if (old_val){
// if (old_val === new_val){
// //
// } else {
// changed_elements[cur_el.name] = cur_el.value
// }
// }
// // }
// }
$.ajax({
@@ -372,16 +432,23 @@ function change_profile_confirm (el){
processData: false,
contentType: false,
// enctype: 'json',
data: JSON.stringify(changed_elements),
// data: JSON.stringify(changed_elements),
data: formData,
success: function(data){
middleWareJS()
document.querySelector(".info_profile").innerHTML = data.html;
document.getElementById('save_changes_txt').classList.add('hide')
document.getElementById('changes_saved_txt').classList.add('show')
},
error: function (data){
document.querySelector(".avatar_user_profile").innerHTML = data.responseJSON.html;
// document.querySelector(".avatar_user_profile").innerHTML = data.responseJSON.html;
document.querySelector(".info_profile").innerHTML = data.responseJSON.html;
}
});
@@ -412,8 +479,8 @@ async function upload_photo_f_profile (el,files) {
},
error: function (data){
document.querySelector(".avatar_user_profile").innerHTML = data.responseJSON.html;
alert(data.responseJSON.error);
el.value = ''
}
});
// }
@@ -477,9 +544,9 @@ function selectedUserMessenger (ticket_id=null,user_id=null,el){
url = 'show_chat_w_user/'
}
let user_type = getInfoAboutUser()
if (user_type === 'mobile' || user_type === 'laptop') {
open_curtain_w_contacts()
}
// if (user_type === 'mobile' || user_type === 'laptop') {
// open_curtain_w_contacts()
// }
data['mobile'] = getInfoAboutUser() === 'mobile' || getInfoAboutUser() === 'laptop'
$.ajax({
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
@@ -499,8 +566,27 @@ function selectedUserMessenger (ticket_id=null,user_id=null,el){
// let left_curtain = document.querySelector('.curtain.left')
document.querySelector(".info_profile").innerHTML = data.html;
document.querySelector(".enter-message-inp").focus()
goToChatIfChat()
// document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'center',inline: 'start'});
document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'end',inline:'end'});
if (document.querySelector(".menu_buttons.curtain.left.open")){
let top = document.querySelector(".tab_user_messanger.select").offsetTop
document.querySelector(".menu_buttons.curtain.left.open").scrollTo({top:top})
}
// second time beacause we need to close curtain
// if (user_type === 'mobile' || user_type === 'laptop') {
// open_curtain_w_contacts()
// }
// document.querySelector(".handler_curtain_left").classList.toggle("open")
// document.querySelector(".handler_curtain_left").classList.toggle("close")
// if (getInfoAboutUser() === 'mobile' || getInfoAboutUser() === 'laptop'){
// window.scrollTo({
// top: 0,
// left: 0
// // behavior: "smooth",
// });
// }
// if (window.location.host.includes('support') && user_type !== 'mobile' && user_type !== 'laptop'){
// let menu = document.querySelector(".menu_buttons.curtain.left")
// let container_user_messenger = document.querySelector(".container-messenger")
@@ -511,8 +597,8 @@ function selectedUserMessenger (ticket_id=null,user_id=null,el){
// }
// check state
checkStateAfterChooseContact()
},
error: function (data){
@@ -524,6 +610,17 @@ function selectedUserMessenger (ticket_id=null,user_id=null,el){
}
function checkStateAfterChooseContact () {
if (document.querySelector('.menu_buttons.curtain.left.open')){
open_curtain_w_contacts()
}
if (document.querySelector('.block_overlay.show')){
setStandartSettingsToBlockOverlay()
}
}
function sendMessage(id_ticket=null,sender,receiver,files=null){
// import {sendMessageSocket} from "./chat_sockets";
if (!files){
@@ -695,6 +792,7 @@ function open_curtain_w_btn_profile () {
last_open_curtain = curtain
set_curtain_z_index(curtain)
close_first_curt(curtain)
checkStateCurtain(curtain)
// delete_margin_in_mobile()
} else if (!window.location.href.includes("profile")){
curtain.classList.toggle("open")
@@ -706,15 +804,38 @@ function open_curtain_w_btn_profile () {
last_open_curtain = curtain
set_curtain_z_index(curtain)
close_first_curt(curtain)
// delete_margin_in_mobile()
}
}
function checkStateCurtain (curtain) {
if (curtain.classList.contains("open")){
if (!document.querySelector(".block_overlay.show")){
document.querySelector(".block_overlay").classList.add("show")
document.querySelector(".block_overlay").classList.remove("hidden")
}
if (!curtain.parentNode.classList.contains("open")) {
curtain.parentNode.classList.add("open")
curtain.parentNode.classList.remove("close")
}
}
}
function open_curtain_w_contacts () {
let curtain = document.querySelector('.menu_buttons.left')
let btn_handler_left_curtain = document.querySelector(".handler_curtain_left")
let user_type = getInfoAboutUser()
if (user_type === 'mobile' || user_type === 'laptop' && window.location.href.includes("profile")) {
if (user_type === 'mobile' && window.location.href.includes("profile") || user_type === 'laptop' && window.location.href.includes("profile")) {
open_overlay(curtain)
if (!curtain.parentNode.classList.contains('open') && !curtain.parentNode.classList.contains('close')){
curtain.parentNode.classList.add("open")
} else if (curtain.parentNode.classList.contains('open') || curtain.parentNode.classList.contains('close')) {
curtain.parentNode.classList.toggle("open")
curtain.parentNode.classList.toggle("close")
}
btn_handler_left_curtain.classList.toggle("open")
btn_handler_left_curtain.classList.toggle("close")
curtain.classList.toggle('open')
curtain.classList.toggle('close')
if (curtain.classList.contains('first')) {
@@ -728,6 +849,14 @@ function open_curtain_w_contacts () {
close_first_curt(curtain)
// delete_margin_in_mobile()
} else if (!window.location.href.includes("profile")){
if (!curtain.parentNode.classList.contains('open') && !curtain.parentNode.classList.contains('close')){
curtain.parentNode.classList.add("open")
} else if (curtain.parentNode.classList.contains('open') || curtain.parentNode.classList.contains('close')) {
curtain.parentNode.classList.toggle("open")
curtain.parentNode.classList.toggle("close")
}
btn_handler_left_curtain.classList.toggle("open")
btn_handler_left_curtain.classList.toggle("close")
open_overlay(curtain)
curtain.classList.toggle('open')
curtain.classList.toggle('close')
@@ -740,6 +869,7 @@ function open_curtain_w_contacts () {
set_curtain_z_index(curtain)
last_open_curtain = curtain
close_first_curt(curtain)
checkStateCurtain(curtain)
// delete_margin_in_mobile()
}
}
@@ -794,7 +924,13 @@ function close_first_curt (curtain) {
if (cur_el !== curtain){
cur_el.classList.toggle('open')
cur_el.classList.toggle('close')
if (cur_el.classList.contains('left')){
document.querySelector(".handler_curtain_left").classList.toggle("open")
document.querySelector(".handler_curtain_left").classList.toggle("close")
}
if (window.location.href.includes("route_search_results")){
scroll_ev(event,window)
}
}
i++
})
@@ -809,9 +945,17 @@ function set_curtain_z_index (curtain) {
curtains.forEach(function (){
let cur_el = curtains[i]
if (cur_el === curtain){
if (!cur_el.querySelector(".handler_menu") && cur_el.classList.contains("left")){
let switcher = document.querySelector(".handler_curtain_left")
switcher.style.zIndex = 101
}
cur_el.style.zIndex = 101
cur_el.parentNode.style.zIndex = 101
} else {
if (!cur_el.querySelector(".handler_menu") && cur_el.classList.contains("left")){
let switcher = document.querySelector(".handler_curtain_left")
switcher.style.zIndex = 99
}
cur_el.style.zIndex = 99
cur_el.parentNode.style.zIndex = 99
}
@@ -821,7 +965,14 @@ function set_curtain_z_index (curtain) {
}
function close_open_curtain () {
if (getInfoAboutUser() === 'mobile' || !window.location.href.includes("profile")){
if (getInfoAboutUser() === 'mobile' || getInfoAboutUser() === 'laptop' || !window.location.href.includes("profile")){
let btn_handler_left_curtain = document.querySelector(".handler_curtain_left")
if (last_open_curtain){
if (last_open_curtain.classList.contains("left")) {
btn_handler_left_curtain.classList.toggle("open")
btn_handler_left_curtain.classList.toggle("close")
}
}
let curtains = document.querySelectorAll('.curtain.open')
if (curtains.length >= 2) {
if (last_open_curtain) {
@@ -868,13 +1019,13 @@ function setStandartSettingsToBlockOverlay () {
block_overlay.classList.add("hidden")
}
// function show_header_list () {
// let el = document.querySelector(".menu_profile_btn")
// if (el) {
// el.classList.toggle("show")
// closeCurtain()
// }
// }
function show_header_list () {
let el = document.querySelector(".menu_profile_btn")
if (el) {
el.classList.toggle("show")
// closeCurtain()
}
}
// function closeCurtain (left,right) {
// if (left){
@@ -883,7 +1034,7 @@ function setStandartSettingsToBlockOverlay () {
// } else if (right){
// let right = document.querySelector(".curtain.right")
// open_curtain(null,right,null,'close')
// } else {
// } else {`
// let curtain = getOpenCurtain()
// if (curtain) {
// open_curtain(null, null, null, 'close')

27
templates/404.html Normal file
View File

@@ -0,0 +1,27 @@
{% extends "tb_base.html" %}
{% load i18n %}
{% block content %}
<div class="not_found_wrap">
<div class="not_found_text">
<div
class="not_found_title">
404
</div>
<div class="not_found_sub_title">
{% translate "Страница не найдена" %}
</div>
</div>
<div class="button_container">
<a
class="a_btn_standart"
href="{% url 'main' %}">
{% translate "Вернуться на главную" %}
</a>
</div>
</div>
{% endblock %}

View File

@@ -10,9 +10,38 @@
<div class="not_found_routes show">
<div class="text-align-center fw-700 font-large c-txt-b2 m-a w-80 m-t-8p">
{% blocktranslate %}
Упс... <span class="orange-text">Ничего не найдено</span>, попробуйте
изменить параметры поиска
Упс... <span class="orange-text">Ничего не найдено</span>, попробуйте
изменить параметры поиска <span class="orange-text"> или создайте своё собственное объявление </span>
{% endblocktranslate %}
{% if user.is_authenticated %}
<a
id="create_route"
{% if owner_type == "mover" %}
href="{% url 'profile_page' 'create_route_for_customer' %}"
{% elif owner_type == "customer" %}
href="{% url 'profile_page' 'create_route_for_mover' %}"
{% endif %}
>
{% translate "Создать объявление" %}
</a>
{% endif %}
{% if not user.is_authenticated %}
<a
id="create_route"
href="{% url "login_profile" %}"
>
{% translate " Войти и Создать объявление" %}
</a>
{% endif %}
</div>
<img class="boxes_not_fond_routes left" src="{% static "/img/boxes_for_not_found_routes/b_1.svg" %}">
<img class="boxes_not_fond_routes right" src="{% static "/img/boxes_for_not_found_routes/b_2.svg" %}">

View File

@@ -6,11 +6,12 @@
<div class="first-column">
<div class="footer_logo"><img class="svg" src="/static/img/svg/LogoWhite.svg"></div>
<div>
<div class="footer_text_sub">{% trans "Подпишись и будь в курсе всех событий, а также получай подарки и бонусы от Trip With Bonus" %}</div>
<div class="insert_form">
{% include "forms/f_one_field_form.html" %}
</div>
{% if not user.user_profile.mailing_on %}
<div class="footer_text_sub">{% trans "Подпишись и будь в курсе всех событий, а также получай подарки и бонусы от Trip With Bonus" %}</div>
<div class="insert_form">
{% include "forms/f_one_field_form.html" %}
</div>
{% endif %}
</div>
@@ -46,9 +47,9 @@
<div class="four-column">
<div class="footer_text_inform">{% trans "Свяжитесь с нами:" %}</div>
<div class="footer_text_contact">
<div>
<a href="tel:+77777777777">+ 7 (777) 777-77-77</a>
</div>
{# <div>#}
{# <a href="tel:+77777777777">+ 7 (777) 777-77-77</a>#}
{# </div>#}
<div>
<a href="mailto:sales@tripwb.com">sales@tripwb.com</a>
</div>

View File

@@ -6,10 +6,13 @@
<div class="wrapper_header_content">
<div class="header-first">
<div class="header_logo">
<a href="/"><img class="svg" src="/static/img/svg/Logo.svg"></a>
<a href="{% url 'main' %}">
<img class="svg" src="/static/img/svg/Logo.svg">
</a>
</div>
<div class="header_logo_mobile">
<a href="/"><img class="svg" src="/static/img/svg/LogoMobile.svg"></a>
{# <a href="/"><img class="svg" src="/static/img/svg/LogoMobile.svg"></a>#}
<a href="{% url 'main' %}"><img class="svg" src="/static/img/svg/LogoMobile.svg"></a>
</div>
<div class="dropdown">
@@ -20,8 +23,8 @@
>
<a href="/">{% trans "Главная" %}</a>
<a href="{% url 'static_page' 'for_movers' %}">{% trans "Для отправителя" %}</a>
<a href="{% url 'static_page' 'for_customers' %}">{% trans "Для перевозчика" %}</a>
<a href="{% url 'static_page' 'for_customers' %}">{% trans "Для отправителя" %}</a>
<a href="{% url 'static_page' 'for_movers' %}">{% trans "Для перевозчика" %}</a>
<a href="{% url "static_page" "about_service" %}">{% trans "" %}О Trip With Bonus</a>
<a href="{% url 'static_page' 'contacts' %}">{% trans "Контакты" %}</a>
<a href="{% url 'static_page' 'advertisement' %}">{% trans "Реклама" %}</a>
@@ -52,7 +55,7 @@
</div>
</div>
<div class="header-second-item">
<img class="svg" src="/static/img/svg/Helpdesk_%20Icon.svg">
<img id="support_img" class="svg" src="/static/img/svg/Helpdesk_%20Icon.svg">
</div>
<div class="header-second-item">
<a id="customer_service" href="{% url 'static_page' 'customer_service' %}">{% trans "Служба поддержки" %}</a>
@@ -66,17 +69,22 @@
{# <div class="button_profile_header" onclick="open_curtain(null,'right')" data-user-id="{{ user.id }}">#}
<span class="btn_profile_name">
{{ user.first_name }} {{ user.last_name }}
{{ user.first_name|truncatechars:6}} {{ user.last_name|truncatechars:5 }}
</span>
<span id="placeholder1"></span>
<div class="icon_unread_messages" style="padding-top: 2px;padding-right: 13px;">
<div class="icon_unread_messages" style="position:relative;top: 4px;padding-right: 13px;">
<div class="cost-messages-in-user-tab-messenger" style="background: #FFFFFF;">
<span class="unredmessages_value_text" style="padding-top: 2px;padding-left: 0; color: #000000;"></span>
<span class="unredmessages_value_text" style="padding-top: 2px;padding-left: 0;position: relative;top: -8px;color: #FF613A;"></span>
</div>
</div>
</div>
<div class="button_profile_header_mobile" onclick="open_curtain_w_btn_profile()">
<div class="marker_messages_mobile hide"></div>
<img src="/static/img/svg/userMobile.svg" alt="">
{# <div class="icon_unread_messages" style="position:absolute;right: 5px;top: 0;">#}
{# <div class="cost-messages-in-user-tab-messenger" style="background: #ff0000;">#}
{# </div>#}
{# </div>#}
</div>
{# <div class="menu_profile_btn">#}
{# {% if user_subscribe %}<div class="subscribe_type_txt"><span class="f-l">Подписка:</span> <span class="f-r">{{ user_subscribe.subscribe.name }}</span><div class="clear_both"></div></div>{% endif %}#}
@@ -110,6 +118,7 @@
<div class="button_profile_header_mobile" onclick="show_header_list()">
<div class="marker_messages_mobile hide"></div>
<img src="/static/img/svg/userMobile.svg" alt="">
</div>

View File

@@ -9,7 +9,7 @@
{%trans "Написать сообщение" as t_chats %}
{%trans "Тех. поддержка" as t_support %}
{%trans "Моя подписка" as t_subscribe %}
{%trans "Мой профиль" as t_change_profile %}
{%trans "Изменить профиль" as t_change_profile %}
{%trans "Выход" as t_logout %}
<div class="menu_profile {% if not page_type == 'profile' %}background{% endif %}">
@@ -116,7 +116,7 @@
{# {% if page_name == 'change_profile' %}#}
{# class="selected"#}
{# {% endif %}>#}
{# <img class="svg" src="/static/img/svg/User.svg">#}
{# <img class="svg" src="/static/img/svg/user_icon_standart.png">#}
{# <a href="{% url "profile_page" "change_profile" %}">Мой профиль</a>#}
{# </div>#}
{# <div>#}

View File

@@ -7,11 +7,18 @@
<div class="container_block_list_of_users">
{% include 'blocks/profile/b_list_of_users_messenger.html' %}
</div>
<div class="handler_menu close" onclick="open_curtain_w_contacts()">
<img class="btns_f_curtain close left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">
<div class="text_f_curtain left"><img style='width: 25px;display: block;position: relative;bottom: 0;transform: rotate(270deg);' src='{% static "/img/svg/users-solid.svg" %}'></div>
<img class="btns_f_curtain close right" src="{% static 'img/svg/arrow_f_curtain.svg' %}">
<div class="clear_both"></div>
{# <div class="handler_menu close" onclick="open_curtain_w_contacts()">#}
{# <img class="btns_f_curtain close left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
{# <div class="text_f_curtain left"><img style='width: 25px;display: block;position: relative;bottom: 0;transform: rotate(270deg);' src='{% static "/img/svg/users-solid.svg" %}'></div>#}
{# <img class="btns_f_curtain close right" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
{# <div class="clear_both"></div>#}
{# </div>#}
</div>
<div class="handler_curtain_left {% if not cur_receiver %}open{% else %}close{% endif %}" onclick="open_curtain_w_contacts()">
<div class="container_content_handler_curtain_left">
<img class="arrows_handler_curtain_left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">
<img class="filter_img" src='{% static "/img/svg/users-solid.svg" %}'>
<img class="arrows_handler_curtain_left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">
</div>
</div>
{#<div class="title-profile-cont">#}
@@ -60,16 +67,18 @@
<div class="container-header-chat">
<div class="header-chat-left-part">
<img class="chat-avatar" {% if cur_receiver.user_profile.avatar %}src="{{ cur_receiver.user_profile.avatar.url }}"{% else %}src="{% static "img/svg/User.svg" %}"{% endif %}>
<img class="chat-avatar" {% if cur_receiver.user_profile.avatar %}src="{{ cur_receiver.user_profile.avatar.url }}"{% else %}src="{% static "img/svg/user_icon_standart.png" %}"{% endif %}>
{# <span class="chat-username">{{ ticket.manager.last_name }} {{ ticket.manager.first_name }}</span>#}
<span class="chat-username">{{ cur_receiver.last_name }} {{ cur_receiver.first_name }}</span>
</div>
<div class="header-chat-right-part">
<img class="header-icons-right-part-padding" src="{% static "img/svg/phone.svg" %}">
<img class="header-icons-right-part-padding" src="{% static "img/svg/info.svg" %}">
<a href="tel:{{ cur_receiver.user_profile.phone }}">
<img class="header-icons-right-part-padding" src="{% static "img/svg/phone.svg" %}">
</a>
{# <img class="header-icons-right-part-padding" src="{% static "img/svg/info.svg" %}">#}
</div>
</div>
<div class="bottom_part_of_chats">
{# <div class="bottom_part_of_chats">#}
<div class="container-messages" data-user-id="{{ user.id }}" data-cur-receiver="{{ cur_receiver.id }}" data-ticket-id="null" >
{% include "blocks/profile/b_messages_container.html" %}
</div>
@@ -88,7 +97,7 @@
{# <button class="send-message" onclick="send_ws_msg('message')"></button>#}
</div>
</div>
</div>
{# </div>#}
</div>
{% endif %}

View File

@@ -6,7 +6,7 @@
{%trans "Тема запроса" as p_create_ticket %}
<form class="form-create-ticket" name="create-ticket">
{% if errors.all__ %}<div class="errors_all" style="margin-bottom: 12px;width: 100%;font-size: 16px;">{{ errors.all__ }}</div>{% endif %}
{% if form.errors.all__ %}<div class="errors_all" style="margin-bottom: 12px;width: 100%;font-size: 16px;">{{ form.errors.all__ }}</div>{% endif %}
{% csrf_token %}
<div class="container-input-form-create-ticket">

View File

@@ -1,5 +1,5 @@
{% load static %}
{% load tz %}
{#{% include "widgets/w_file.html" %}#}
{% if not messages and ticket %}
@@ -8,7 +8,9 @@
{% for msg in messages %}
{% include "widgets/w_message.html" %}
{% if forloop.first %}
<span style="display: none" class="date_n_time_last_message" data-modifiedDT="{{ msg.modifiedDT|date:"d.m.Y H:i:s:u" }}"></span>
{% timezone user_tz %}
<span style="display: none" class="date_n_time_last_message" data-modifiedDT="{{ msg.modifiedDT|date:"d.m.Y H:i:s:u" }}"></span>
{% endtimezone %}
{% endif %}
{% endfor %}
{% endif %}

View File

@@ -32,7 +32,7 @@
{# </div>#}
{# <label for="id_type_transport">{% translate "Выберите способ перевозки" %}</label>#}
<select
onchange="OnSelectionChange(this)"
name="type_transport"
@@ -56,11 +56,32 @@
{% endif %}
</div>
{# <input id="hide_owner_type" type="hidden" value="{{ form.initial.owner_type }}">#}
<input
id="hide_owner_type"
type="hidden"
{% if form.initial.owner_type %}
value="{{ form.initial.owner_type }}"
{% elif form.data.owner_type %}
value="{{ form.data.owner_type }}"
{% endif %}
>
{% if form.initial and form.initial.type_transport and form.initial.type_transport != '' %}
<hr>
<div class="departure_arrival">
<div class="wrap_left">
<label for="id_departure_DT">{{ form.fields.departure_DT.label }}</label>
<label for="id_departure_DT">
{% if form.initial.owner_type == 'mover' and form.initial.type_transport == 'road' or form.data.owner_type == 'mover' and form.initial.type_transport == 'road' %}
{% translate "Дата и время выезда" %}
{% elif form.initial.owner_type == 'mover' and form.initial.type_transport == 'avia' or form.data.owner_type == 'mover' and form.initial.type_transport == 'avia' %}
{% translate "Дата и время вылета" %}
{% elif form.initial.owner_type == 'customer' or form.data.owner_type == 'customer' %}
{% translate "Дата и время отправки" %}
{% endif %}
</label>
{# <input#}
@@ -75,16 +96,33 @@
{# {% if form.initial.departure_DT %}value="{{ form.initial.departure_DT.date|date:"Y-m-d" }}T{{ form.initial.departure_DT.time|date:"H:i" }}"{% endif %}#}
{# />#}
{# boris change input #}
<input class="el_form_b_new_route" onchange="checkDate()" type="text" id="id_departure_DT" name="departure_DT" placeholder="{% translate "Выберите дату и время" %}" {% if form.initial.departure_DT %} value="{{ form.initial.departure_DT|date:"y.m.d H:m" }}"{% endif %}/>
<input
class="el_form_b_new_route"
{# onchange="checkDate()"#}
{# onclick="setIcon(this)"#}
onmouseup="hideErrors(this)"
type="text"
id="id_departure_DT"
name="departure_DT"
placeholder="{% translate "Выберите дату и время" %}" {% if form.initial.departure_DT %}
value="{{ form.initial.departure_DT|date:"d.m.Y H:m" }}"{% endif %}/>
<div id="displayRegervation"></div>
{% if not errors_off and form.errors and form.errors.departure_DT %}
<span>{{ form.errors.departure_DT }}</span>
<span id="error_departure_DT">{{ form.errors.departure_DT }}</span>
{% endif %}
</div>
<div id="arrival_div">
<label for="id_arrival_DT">{{ form.fields.arrival_DT.label }}</label>
<label for="id_arrival_DT">
{% if form.initial.owner_type == 'mover' or form.data.owner_type == 'mover'%}
{% translate "Дата и время прибытия" %}
{% elif form.initial.owner_type == 'customer' or form.data.owner_type == 'customer' %}
{% translate "Дата и время доставки посылки" %}
{% endif %}
</label>
{# <input#}
{# type="datetime-local"#}
{# min= {% now "Y-m-d" %}T{% now "H:i" %}#}
@@ -96,12 +134,20 @@
{# {% if form.initial.arrival_DT %}value="{{ form.initial.arrival_DT.date|date:"Y-m-d" }}T{{ form.initial.arrival_DT.time|date:"H:i" }}"{% endif %}#}
{# />#}
{# boris change input #}
<input class="el_form_b_new_route" onchange="checkDate()" type="text" id="id_arrival_DT" name="arrival_DT" placeholder="{% translate "Выберите дату и время" %}" {% if form.initial.arrival_DT %} value="{{ form.initial.arrival_DT|date:"y.m.d H:m" }}"{% endif %}/>
<input
class="el_form_b_new_route"
onchange="checkDate()"
onmouseup="hideErrors(this)"
type="text"
id="id_arrival_DT"
name="arrival_DT"
placeholder="{% translate "Выберите дату и время" %}" {% if form.initial.arrival_DT %}
value="{{ form.initial.arrival_DT|date:"d.m.Y H:m" }}"{% endif %}/>
<div id="displayRegervation"></div>
{# end #}
{% if not errors_off and form.errors and form.errors.arrival_DT %}
<span>{{ form.errors.arrival_DT }}</span>
<span id="error_arrival_DT">{{ form.errors.arrival_DT }}</span>
{% endif %}
</div>
<div class="clear_both"></div>
@@ -109,7 +155,15 @@
<hr>
<div class="from_to_country">
<div class="from_country_container">
<label for="id_from_address_point_txt">{{ form.fields.from_address_point.label }}</label>
<label for="id_from_address_point_txt">
{% if form.initial.owner_type == 'mover' and form.initial.type_transport == 'avia' or form.data.owner_type == 'mover' and form.initial.type_transport == 'avia' %}
{% translate "Пункт вылета" %}
{% elif form.initial.owner_type == 'mover' and form.initial.type_transport == 'road' or form.data.owner_type == 'mover' and form.initial.type_transport == 'road' %}
{% translate "Пункт выезда" %}
{% elif form.initial.owner_type == 'customer' or form.data.owner_type == 'customer' %}
{% translate "Пункт отправки" %}
{% endif %}
</label>
<input
type="number"
name="from_address_point"
@@ -122,15 +176,16 @@
oninput="searchTown(this)"
onclick="showSearchList(this)"
onblur="onblurInputField(event, this)"
onFocus="this.select()"
onfocus="clearID(this)"
onkeydown = "hideErrors(this)"
autocomplete="off"
type="text"
minlength="3"
name="from_address_point_txt"
class="from_address_point_txt post_route el_form_b_new_route"
{% if form.fields.from_address_point.required %} required{% endif %}
id="id_from_address_point_txt"
placeholder="{% translate "Выберите страну и город" %}"
{% if form.initial.from_address_point_txt %}value="{{ form.initial.from_address_point_txt }}"{% endif %}
/>
<datalist id="from_address_point">
@@ -141,11 +196,19 @@
</div>
{% if not errors_off and form.errors and form.errors.from_address_point %}
<span>{{ form.errors.from_address_point}}</span>
<span id="error_from_address_point">{{ form.errors.from_address_point}}</span>
{% endif %}
</div>
<div class="wrap_right">
<label for="id_to_address_point_txt">{{ form.fields.to_address_point.label }}</label>
<label for="id_to_address_point_txt">
{% if form.initial.owner_type == 'mover' and form.initial.type_transport == 'avia' or form.data.owner_type == 'mover' and form.initial.type_transport == 'avia' %}
{% translate "Пункт прилета" %}
{% elif form.initial.owner_type == 'mover' and form.initial.type_transport == 'road' or form.data.owner_type == 'mover' and form.initial.type_transport == 'road' %}
{% translate "Пункт приезда" %}
{% elif form.initial.owner_type == 'customer' or form.data.owner_type == 'customer'%}
{% translate "Пункт прибытия" %}
{% endif %}
</label>
<input
type="number"
name="to_address_point"
@@ -158,14 +221,15 @@
oninput="searchTown(this)"
onclick="showSearchList(this)"
onblur="onblurInputField(event, this)"
onFocus="this.select()"
onkeydown = "hideErrors(this)"
onfocus="clearID(this)"
autocomplete="off"
type="text"
name="to_address_point_txt"
{% if form.fields.to_address_point.required %} required{% endif %}
id="id_to_address_point_txt"
class="to_address_point_txt post_route el_form_b_new_route"
placeholder="{% translate "Выберите страну и город" %}"
{% if form.initial.to_address_point_txt %}value="{{ form.initial.to_address_point_txt}}"{% endif %}
/>
@@ -173,7 +237,7 @@
</div>
{% if not errors_off and form.errors and form.errors.to_address_point %}
<span>{{ form.errors.to_address_point }}</span>
<span id="error_to_address_point">{{ form.errors.to_address_point }}</span>
{% endif %}
</div>
<div class="clear_both"></div>
@@ -189,7 +253,13 @@
{# </div>#}
<div class="from_to_place">
<div class="wrap_left">
<label for="id_from_place">{{ form.fields.from_place.label }}</label>
<label for="id_from_place">
{% if form.initial.owner_type == 'mover' or form.data.owner_type == 'mover' %}
{% translate "Откуда можете забрать?" %}
{% elif form.initial.owner_type == 'customer' or form.data.owner_type == 'customer' %}
{% translate "Откуда нужно забрать посылку?" %}
{% endif %}
</label>
<select
class="custom_select el_form_b_new_route"
name="from_place"
@@ -208,7 +278,13 @@
{% endif %}
</div>
<div class="wrap_right">
<label for="id_to_place">{{ form.fields.to_place.label }}</label>
<label for="id_to_place">
{% if form.initial.owner_type == 'mover' or form.data.owner_type == 'mover' %}
{% translate "Куда можете доставить?" %}
{% elif form.initial.owner_type == 'customer' or form.data.owner_type == 'customer' %}
{% translate "Куда нужно доставить посылку?" %}
{% endif %}
</label>
<select
name="to_place"
id="id_to_place"
@@ -231,7 +307,12 @@
<hr>
<div>
<label>{{ form.fields.cargo_type.label }}</label>
<label>{% if form.initial.owner_type == 'mover' or form.data.owner_type == 'mover' %}
{% translate "Могу перевезти:" %}
{% elif form.initial.owner_type == 'customer' or form.data.owner_type == 'customer' %}
{% translate "Что нужно перевезти?" %}
{% endif %}
</label>
</div>
@@ -246,6 +327,7 @@
class="custom-checkbox cargo_check"
type="radio"
name="cargo_type"
id="id_cargo_type_{{ forloop.counter }}"
{% if form.fields.cargo_type.required %} required{% endif %}
value="{{ item.0 }}"
@@ -255,7 +337,8 @@
/>
<label
onmousedown="hideErrors(this)"
id="id_cargo_lable"
for="id_cargo_type_{{ forloop.counter }}" >
<span>{{ item.1 }}</span>
</label>
@@ -264,7 +347,7 @@
{% if not errors_off and form.errors and form.errors.cargo_type %}
<span>{{ form.errors.cargo_type }}</span>
<span id="error_cargo_type">{{ form.errors.cargo_type }}</span>
{% endif %}
</div>
@@ -314,6 +397,7 @@
<input
type="phone"
name="phone"
onkeydown="hideErrors(this)"
autocomplete="off"
maxlength="13"
minlength="11"
@@ -325,7 +409,7 @@
/>
{% if not errors_off and form.errors and form.errors.phone %}
<span>{{ form.errors.phone }}</span>
<span id="error_id_phone">{{ form.errors.phone|safe }}</span>
{% endif %}
</div>
@@ -355,7 +439,13 @@
<div>
<input type="checkbox" name="receive_msg_by_email" class="custom-checkbox" id="id_receive_msg_by_email">
<input type="checkbox"
name="receive_msg_by_email"
class="custom-checkbox"
{% if form.initial.receive_msg_by_email == True %}
checked="checked"
{% endif %}
id="id_receive_msg_by_email">
<label for="id_receive_msg_by_email">
<div class="receive_msg_by_email">{{ form.fields.receive_msg_by_email.label }}</div>

View File

@@ -6,7 +6,7 @@
<div class="upload_photo_container">
<img class="avatar_user_profile" {% if user.user_profile.avatar %}
src="{{ user.user_profile.avatar.url }}"
{% else %}src="{% static "img/svg/User.svg" %}"{% endif %} >
{% else %}src="{% static "img/svg/user_icon_standart.png" %}"{% endif %} >
<input type="file" onchange="upload_photo_f_profile(this)" class="btn_f_upload_photo" id="id_btn_f_upload_photo">
<label class="upload_photo_label" for="id_btn_f_upload_photo">{% translate "Загрузить фото" %}</label>
</div>
@@ -35,13 +35,13 @@
{% if profileForm.errors.lastname %}<div class="error_form_profile">{{ profileForm.errors.lastname }}</div>{% endif %}
</div>
<div class="container_el_form_profile">
<label class="label_f_profile" for="id_tel">{% if profileForm.fields.tel.required %}<span class="orange-text">*</span>{% endif %}{% translate "Номер телефона" %} </label>
<label class="label_f_profile" for="id_tel">{% translate "Номер телефона" %} </label>
<input class="input_f_profile" type="text" id="id_tel" name="tel" {% if profileForm.initial.tel %}value="{{ profileForm.initial.tel }}" {% endif %} {% if profileForm.initial.tel %}data-initial-value="{{ profileForm.initial.tel }}"{% else %}data-initial-value=""{% endif %}>
{% if profileForm.errors.tel %}<div class="error_form_profile">{{ profileForm.errors.tel }}</div>{% endif %}
{% if profileForm.errors.tel %}<div class="error_form_profile">{{ profileForm.errors.tel|safe }}</div>{% endif %}
</div>
<div class="container_el_form_profile">
<label class="label_f_profile" for="id_email">{% if profileForm.fields.email.required %}<span class="orange-text">*</span>{% endif %} E-mail</label>
<input class="input_f_profile" type="text" id="id_email" name="email" {% if profileForm.initial.email %}value="{{ profileForm.initial.email }}" {% endif %} {% if profileForm.initial.email %}data-initial-value="{{ profileForm.initial.email }}"{% else %}data-initial-value=""{% endif %}>
<label class="label_f_profile" for="id_email">E-mail</label>
<input class="input_f_profile grey" type="text" id="id_email" name="email" readonly {% if profileForm.initial.email %}value="{{ profileForm.initial.email }}" {% endif %} {% if profileForm.initial.email %}data-initial-value="{{ profileForm.initial.email }}"{% else %}data-initial-value=""{% endif %}>
{% if profileForm.errors.email %}<div class="error_form_profile">{{ profileForm.errors.email }}</div>{% endif %}
</div>
<div class="container_el_form_profile">
@@ -58,14 +58,23 @@
<div class="line_f_form_profile"></div>
<div class="container_el_form_profile">
<label class="label_f_profile" for="id_password">{% if profileForm.fields.password.required %}<span class="orange-text">*</span>{% endif %}{% translate "Новый пароль" %} </label>
<label class="label_f_profile" for="id_password">{% translate "Новый пароль" %} </label>
<input class="input_f_profile" type="text" id="id_password" name="password" {% if profileForm.initial.password %}value="{{ profileForm.initial.password }}" {% endif %} {% if profileForm.initial.password %}data-initial-value="{{ profileForm.initial.password }}"{% else %}data-initial-value=""{% endif %}>
</div>
<div class="container_el_form_profile">
<label class="label_f_profile" for="id_confirm_password">{% if profileForm.fields.confirm_password.required %}<span class="orange-text">*</span>{% endif %}{% translate "Подтвердить пароль" %} </label>
<label class="label_f_profile" for="id_confirm_password">{% translate "Подтвердить пароль" %} </label>
<input class="input_f_profile" type="text" id="id_confirm_password" name="confirm_password" {% if profileForm.initial.confirm_password %}value="{{ profileForm.initial.confirm_password }}" {% endif %} {% if profileForm.initial.confirm_password %}data-initial-value="{{ profileForm.initial.confirm_password }}"{% else %}data-initial-value=""{% endif %}>
</div>
<button class="confirm_profile_btn" onclick="change_profile_confirm(this)">{% translate "Сохарнить" %}</button>
<button class="confirm_profile_btn" onclick="change_profile_confirm(this)">
<p id="save_changes_txt">
{% translate "Сохарнить" %}
</p>
<p id="changes_saved_txt">
{% translate "Изменения сохранены" %}
</p>
</button>
</div>
</form>

View File

@@ -1,15 +1,15 @@
{% load static %}
{% load i18n %}
<h1>{% translate "Добро пожаловать:" %} <span class="user_first_name">{{ user.first_name }} {{ user.last_name }}</span> <span class="user_username" >({{ user.username }})</span></h1>
<h1 class="title_b_first_page">{% translate "Добро пожаловать:" %} <span class="user_first_name">{{ user.first_name }} {{ user.last_name }}</span> <span class="user_username" >({{ user.username }})</span></h1>
<div class="profile_prof"><img class="avatar_user_profile" {% if user.user_profile.avatar %}
src="{{ user.user_profile.avatar.url }}"
{% else %}src="{% static "img/svg/User.svg" %}"{% endif %} alt="">
{% else %}src="{% static "img/svg/user_icon_standart.png" %}"{% endif %} alt="">
<div>
{# <div class="avatar_block">#}
{# <img class="avatar_user_profile" {% if user.user_profile.avatar %}#}
{# src="{{ user.user_profile.avatar.url }}"#}
{# {% else %}src="{% static "img/svg/User.svg" %}"{% endif %} >#}
{# {% else %}src="{% static "img/svg/user_icon_standart.png" %}"{% endif %} >#}
{# </div>#}
{# <div>{% translate "Статус:" %} {{ user.user_profile.get_account_type_display }}</div>#}
{# <div>#}
@@ -21,5 +21,8 @@
</div>
{# <div class="advice_text">{% translate "Если хотите отправить посылку - зарегистрируйтесь, как отправитель" %}</div>#}
<div class="prof_first_line">{% translate "Если у Вас возникнут вопросы Вы можете связаться с нами:" %} <a href="mailto:support@twb.com">support@twb.com</a></div>
{# <div class="prof_second_line">{% translate "У Вас" %} <a href="#">{% translate "три " %}</a>{% translate "новых сообщения." %} <a href="#">{% translate "Посмотреть" %}</a></div>#}
<div class="prof_second_line">
{% blocktrans %}У Вас {{ unanswered_msgs_count }} новых сообщений{% endblocktrans %}
<a onclick="select_tab_profile(this,'chats'{% if owner_type %},'{{ owner_type }}'{% endif %})"onclick="clickONTHEAPROfileBTN(this)">{% translate "Посмотреть" %}</a>
</div>
{# <div class="prof_third_line">{% translate "Хотите получать уведомление о появлении посылок?" %} <a href="#">{% translate "Заполните форму" %}</a></div>#}

View File

@@ -1,9 +1,9 @@
{% load static %}
{% load i18n %}
<div class="title-profile-cont">
{% translate "Подписка" %}
</div>
{#<div class="title-profile-cont">#}
{# {% translate "Подписка" %}#}
{#</div>#}
<div>

View File

@@ -13,15 +13,32 @@
{# <h1>Техническая поддержка</h1>#}
{# </div>#}
{% if user.is_staff or staff %}
<div class="menu_buttons curtain left {% if mobile %}{% if not ticket %}open{% else %}close{% endif %}{% else %}open{% endif %}{% if name.ticket %}margin{% endif %}" data-name="<img style='width: 25px;display: block;position: relative;bottom: 0;' src='{% static "/img/svg/users-solid.svg" %}'>">
<div class="menu_buttons curtain left
{% if mobile %}
{% if not ticket %}open
{% else %}close
{% endif %}
{% else %}
open
{% endif %}
{% if name.ticket %}margin{% endif %}"
data-name="<img style='width: 25px;display: block;position: relative;bottom: 0;' src='{% static "/img/svg/users-solid.svg" %}'>"
>
<div class="container_block_list_of_users">
{% include 'blocks/profile/b_list_of_tickets_support_chat.html' %}
</div>
<div class="handler_menu close" onclick="open_curtain_w_contacts()">
<img class="btns_f_curtain close left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">
<div class="text_f_curtain left"><img style='width: 25px;display: block;position: relative;bottom: 0;transform: rotate(270deg);' src='{% static "/img/svg/users-solid.svg" %}'></div>
<img class="btns_f_curtain close right" src="{% static 'img/svg/arrow_f_curtain.svg' %}">
<div class="clear_both"></div>
{# <div class="handler_menu close" onclick="open_curtain_w_contacts()">#}
{# <img class="btns_f_curtain close left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
{# <div class="text_f_curtain left"><img style='width: 25px;display: block;position: relative;bottom: 0;transform: rotate(270deg);' src='{% static "/img/svg/users-solid.svg" %}'></div>#}
{# <img class="btns_f_curtain close right" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
{# <div class="clear_both"></div>#}
{# </div>#}
</div>
<div class="handler_curtain_left {% if mobile %}{% if not ticket %}open{% else %}close{% endif %}{% else %}open{% endif %}{% if name.ticket %}margin{% endif %}" onclick="open_curtain_w_contacts()">
<div class="container_content_handler_curtain_left">
<img class="arrows_handler_curtain_left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">
<img class="filter_img" src='{% static "/img/svg/users-solid.svg" %}'>
<img class="arrows_handler_curtain_left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">
</div>
</div>
{% endif %}
@@ -39,7 +56,7 @@
{% if user.is_staff or ticket.manager %}
<div class="container-header-chat">
<div class="header-chat-left-part">
<img class="chat-avatar" {% if cur_receiver.user_profile.avatar %}src="{{ cur_receiver.user_profile.avatar.url }}"{% else %}src="{% static "img/svg/User.svg" %}"{% endif %}>
<img class="chat-avatar" {% if cur_receiver.user_profile.avatar %}src="{{ cur_receiver.user_profile.avatar.url }}"{% else %}src="{% static "img/svg/user_icon_standart.png" %}"{% endif %}>
<span class="chat-username">{{ cur_receiver.last_name }} {{ cur_receiver.first_name }}</span>
</div>
<div class="header-chat-right-part">
@@ -62,13 +79,13 @@
{# {% endfor %}#}
{# {% endif %}#}
{# </div>#}
<div class="bottom_part_of_chats">
{# <div class="bottom_part_of_chats">#}
<div class="container-messages" data-user-id="{{ user.id }}" data-cur-receiver="{{ cur_receiver.id }}" data-ticket-id='{{ ticket.id }}'>
{% include "blocks/profile/b_messages_container.html" %}
</div>
<div class="footer-chat{% if not new_msg_allow %} hide{% endif %}">
<div class="footer-chat{% if not new_msg_allow %} hide{% endif %}">
<div class="left-part-block-enter-message">
<input class="enter-message-inp" onfocus="check_new_messages_timeout()" onkeypress="sendMessageEnter(event,{{ ticket.id }},{{ user.id }},{{ cur_receiver.id }})" placeholder="{{ p_send_msg }}">
@@ -79,16 +96,17 @@
{# </div>#}
<div class="right-part-block-enter-message">
{# <button class="attach-file-btn-message" onclick="attachFilemeassge(event,this,null,{{ user.id }},{{ cur_receiver.id }})"></button>#}
<input style="display: none;" type="file" onchange="attachFilemeassge(event,this,{{ ticket.id }},{{ user.id }},{{ cur_receiver.id }})" id="id_choce_file" multiple>
<input style="display: none;" type="file" onchange="attachFilemeassge(this,{{ ticket.id }},{{ user.id }},{{ cur_receiver.id }})" id="id_choce_file" multiple>
<label for="id_choce_file" class="attach-file-btn-message"></label>
<button class="send-message" onclick="sendMessage({{ ticket.id }},{{ user.id }},{{ cur_receiver.id }})"></button>
<img src="{% static "/img/svg/loader.svg" %}" class="loader_show_message">
{# <button class="send-message" onclick="send_ws_msg('message')"></button>#}
</div>
</div>
</div>
{# </div>#}
</div>
<div class="clear_both"></div>
{% endif %}
</div>

View File

@@ -6,9 +6,9 @@
<div>
<div class="title-profile-cont">
<h1>{% translate "Техническая поддержка" %}</h1>
</div>
{# <div class="title-profile-cont">#}
{# <h1>{% translate "Техническая поддержка" %}</h1>#}
{# </div>#}
<div class="insert-tech-place">
<div class="container-sprt-inf">
<div class="container-support-btn">

View File

@@ -6,7 +6,7 @@
<div class="button_container">
<button
onclick="document.location='{% url 'profile_page' 'create_route_for_customer' %}'"
id="more_button">{% translate "Отправить посылку" %}</button>
id="send_parcel_button">{% translate "Отправить посылку" %}</button>
<a class="btn_a_anchor" href="#scroll_to_wrapper" id="how_it_work_b">
<div class="text_in_btn_a_anchor">{% translate "Как это работает?" %}</div>
</a>
@@ -17,11 +17,11 @@
<div class="mid_block_static">
<div id="title_static">{% translate "О сервисе Trip With Bonus" %}</div>
<div class="text_wrapper anchor" id="scroll_to_wrapper">
<div class="text_wrapper anchor about_service" id="scroll_to_wrapper">
<span>{% translate "Trip With Bonus- это сервис, который соединяет отправителя посылки и перевозчика." %}</span>
<span>{% translate "Trip With Bonus это сервис, который соединяет отправителя посылки и перевозчика." %}</span>
<span>{% translate "Вы можете разместить объявление о перевозке посылки и перевозчики со всего мира откликнуться на ваше объявление или воспользовавшись поиском на сайте найти перевозчика, который будет готов взять Вашу посылку и доставить в указанное место авто- или авива транспортом." %}</span>
<span>{% translate "Вы можете разместить объявление о перевозке посылки и перевозчики со всего мира откликнутся на ваше объявление или воспользовавшись поиском на сайте найти перевозчика, который будет готов взять Вашу посылку и доставить в указанное место наземным или авиатранспортом." %}</span>
<span>{% translate "Если же Вы часто путешествуете или в разъездах, Вы можете самостоятельно перевозить посылки и при этом получать бонусы и благодарности." %}</span>
@@ -49,7 +49,7 @@
<div class="button_container">
<button
onclick="document.location = '/ru/page/partners/'"
id="more_button">{% translate "Читать подробнее" %}</button>
id="send_parcel_button">{% translate "Читать подробнее" %}</button>
</div>

View File

@@ -16,14 +16,16 @@
<div class="button_container">
{% if page.url == 'for_customers' %}
<button
onclick="document.location='{% url 'profile_page' 'create_route_for_customer' %}'"
id="more_button">{% translate "Отправить посылку" %}</button>
id="send_parcel_button">{% translate "Отправить посылку" %}
</button>
{% endif %}
{% if page.url == 'for_movers' %}
<button
onclick="document.location='{% url 'profile_page' 'create_route_for_mover' %}'"
id="more_button">{% translate "Перевезти посылку" %}</button>
id="send_parcel_button">{% translate "Перевезти посылку" %}</button>
{% endif %}
<a class="btn_a_anchor" href="#anchor_how_it_work" id="how_it_work_b">
@@ -42,7 +44,7 @@
<span>{% translate "Trip With Bonus- это сервис, который соединяет отправителя посылки и перевозчика." %}</span>
<span>{% translate "Вы можете разместить объявление о перевозке посылки и перевозчики со всего мира откликнуться на ваше объявление или воспользовавшись поиском на сайте найти перевозчика, который будет готов взять Вашу посылку и доставить в указанное место авто- или авива транспортом." %}</span>
<span>{% translate "Вы можете разместить объявление о перевозке посылки и перевозчики со всего мира откликнутся на ваше объявление или воспользовавшись поиском на сайте найти перевозчика, который будет готов взять Вашу посылку и доставить в указанное место наземным или авиатранспортом." %}</span>
<span>{% translate "Если же Вы часто путешествуете или в разъездах, Вы можете самостоятельно перевозить посылки и при этом получать бонусы и благодарности." %}</span>
@@ -68,7 +70,7 @@
<h3 >{% translate "Найдите перевозчика" %}</h3>
{% endif %}
{% if page.url == 'for_movers' %}
<h3>{% translate "Разместите объявление" %}</h3>
<h3>{% translate "Найдите отправителя" %}</h3>
{% endif %}
{% if page.url == 'for_customers' %}
@@ -76,7 +78,7 @@
{% endif %}
{% if page.url == 'for_movers' %}
<span>{% translate "Укажите откуда, куда хотите перевезти посылку, а также Вашу дату отправки и прибытия. При желании Вы можете указать дополнительные параметры: тип, вес, вид перевозки и т.д" %}</span>
<span>{% translate "Зайдите на сайт Trip With Bonus и в форме вверху страницы, заполните данные для поиска отправителя посылки." %}</span>
{% endif %}
</div>
@@ -85,14 +87,20 @@
<div class="benefit_img_item">
<img src="/static/img/svg/Contact_carrier.svg" alt="">
<h3>{% translate "Свяжитесь с перевозчиком" %}</h3>
{% if page.url == 'for_customers' %}
<span>{% translate "Откройте контакты на сайте и договоритесь о месте встречи и условиях перевозки" %}</span>
<h3>{% translate "Свяжитесь с перевозчиком" %}</h3>
{% endif %}
{% if page.url == 'for_movers' %}
<span>{% translate "В отобразившемся списке выберите подходящего отправителя и посылку, откройте контакты и свяжитесь удобным способом. Если не нашли подходящего отправителя с посылкой, разместите объявление о возможности перевезти посылку и отправители Вас сами найдут" %}</span>
<h3>{% translate "Свяжитесь с отправителем" %}</h3>
{% endif %}
{% if page.url == 'for_customers' %}
<span>{% translate "Откройте контакты на сайте и договоритесь о месте встречи и условиях перевозки. В случае, если Вы не нашли объявления о перевозчиках по Вашему запросу, Вы можете разместить свое объявление воспользовавшись формой в личном кабинете." %}</span>
{% endif %}
{% if page.url == 'for_movers' %}
<span>{% translate "Откройте контакты на сайте и договоритесь о месте встречи и условиях перевозки. В случае, если Вы не нашли объявления об отправителях по Вашему запросу, Вы можете разместить свое объявление воспользовавшись формой в личном кабинете." %}</span>
{% endif %}
</div>
@@ -101,13 +109,21 @@
<div class="benefit_img_item">
<img src="/static/img/svg/Pass_package.svg" alt="">
<h3>{% translate "Передайте посылку" %}</h3>
{% if page.url == 'for_customers' %}
<h3>{% translate "Передайте посылку" %}</h3>
{% endif %}
{% if page.url == 'for_movers' %}
<h3>{% translate "Принимайте посылку" %}</h3>
{% endif %}
{% if page.url == 'for_customers' %}
<span>{% translate "Встречайтесь, знакомьтесь и передавайте посылку" %}</span>
{% endif %}
{% if page.url == 'for_movers' %}
<span>{% translate "Обсудите с отправителем все условия: время, место и прочие детали. Готово! Доставьте посылку из пункта А в пункт Б и получите благодарность отправителя!" %}</span>
<span>{% translate "Встречайтесь, знакомьтесь и принимайте посылку" %}</span>
{% endif %}
</div>
</div>
@@ -117,14 +133,21 @@
<div class="button_container">
{% if page.url == 'for_customers' %}
<button
onclick="document.location='{% url 'profile_page' 'create_route_for_customer' %}'"
id="more_button">{% translate "Отправить посылку" %}</button>
<div class="button_container">
<a class="a_btn_standart"
href="{% url 'profile_page' 'create_route_for_customer' %}"
id="more_button">{% translate "Отправить посылку" %}
</a>
</div>
{% endif %}
{% if page.url == 'for_movers' %}
<button
onclick="document.location='{% url 'profile_page' 'create_route_for_mover' %}'"
id="more_button">{% translate "Перевезти посылку" %}</button>
<div class="button_container">
<a class="a_btn_standart"
href="{% url 'profile_page' 'create_route_for_mover' %}"
id="more_button">{% translate "Перевезти посылку" %}
</a>
</div>
{% endif %}
</div>
<div class="subscribes_container">
@@ -180,7 +203,7 @@
onclick="document.location='{% url 'profile_page' 'my_subscribe' %}'"
>
<button id="more_button">{% translate "Получить" %}</button>
<button id=send_parcel_button>{% translate "Получить" %}</button>
</div>
<img id="box1" src="/static/img/png/Box5.png" alt="">

Some files were not shown because too many files have changed in this diff Show More