251 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
110 changed files with 21753 additions and 671 deletions

1
.gitignore vendored
View File

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

View File

@@ -43,6 +43,7 @@ class Admin_ProfileInline(admin.StackedInline):
('enable',), ('enable',),
('phone',), ('phone',),
('country', 'city'), ('country', 'city'),
('mailing_on', ),
('authMailCode',), ('authMailCode',),
('birthdate'), ('birthdate'),
'comment', 'creator' 'comment', 'creator'
@@ -71,6 +72,10 @@ class Admin_ProfileInline(admin.StackedInline):
class Admin_User(UserAdmin): class Admin_User(UserAdmin):
def mailing_on(self, obj):
return obj.user_profile.mailing_on
mailing_on.boolean = True
fieldsets = ( fieldsets = (
(None, { (None, {
'classes': ['wide'], 'classes': ['wide'],
@@ -91,16 +96,18 @@ class Admin_User(UserAdmin):
save_on_top = True 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'] 'is_active']
list_editable = ['is_staff', 'is_active'] list_editable = ['is_staff', 'is_active']
list_display_links = ['first_name', 'last_name', 'email'] list_display_links = ['first_name', 'last_name', 'email']
search_fields = ['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,) inlines = (Admin_ProfileInline,)
# actions = ['del_all_temp_users', ] # actions = ['del_all_temp_users', ]
ordering = ['is_staff', 'last_name', 'first_name'] ordering = ['is_staff', '-id', 'last_name', 'first_name']
# Re-register UserAdmin # Re-register UserAdmin
admin.site.unregister(User) admin.site.unregister(User)

View File

@@ -29,22 +29,57 @@ class RegistrationForm(forms.Form):
tel = forms.CharField() tel = forms.CharField()
agreement = forms.BooleanField(initial=False, required=True) 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): def clean(self):
cleaned_data = super().clean() cleaned_data = super().clean()
i = 0 # i = 0
names = list(cleaned_data.keys()) # names = list(cleaned_data.keys())
while i < len(names): # while i < len(names):
if not cleaned_data[names[i]]: # if not cleaned_data[names[i]]:
if self.fields[names[i]].required: # if self.fields[names[i]].required:
self.add_error(names[i], _('Обязательное поле')) # self.add_error(names[i], _('Обязательное поле'))
i += 1 # 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 and 'confirm_password' in cleaned_data and 'password' in cleaned_data:
if cleaned_data['confirm_password'] != cleaned_data['password']: if cleaned_data['confirm_password'] != cleaned_data['password']:
self.add_error("password", _('Пароль и подтверждение пароля не совпадают')) self.add_error("password", _('Пароль и подтверждение пароля не совпадают'))
self.add_error("confirm_password", _('Пароль и подтверждение пароля не совпадают')) self.add_error("confirm_password", _('Пароль и подтверждение пароля не совпадают'))
if cleaned_data and 'email' in cleaned_data: if self.create_new_account and cleaned_data and 'email' in cleaned_data:
users = User.objects.filter(email=cleaned_data['email']) users = User.objects.filter(email=cleaned_data['email'])
if users: if users:
self.add_error('email', _("Пользователь с указанным email уже существует")) self.add_error('email', _("Пользователь с указанным email уже существует"))

View File

@@ -1,5 +1,19 @@
from django.template.loader import render_to_string 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): def get_dashboard_page_content_html(request):
from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user
@@ -18,10 +32,10 @@ def get_profile_page_content_html(request, page_name, data):
return get_chat_page_content_html(request, data) return get_chat_page_content_html(request, data)
elif page_name == 'create_route_for_customer': elif page_name == 'create_route_for_customer':
from RoutesApp.funcs import get_profile_new_route_page_html 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': elif page_name == 'create_route_for_mover':
from RoutesApp.funcs import get_profile_new_route_page_html 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': elif page_name == 'my_routes':
from RoutesApp.funcs import get_profile_my_routes_page_content_html from RoutesApp.funcs import get_profile_my_routes_page_content_html
return get_profile_my_routes_page_content_html(request) return get_profile_my_routes_page_content_html(request)
@@ -76,5 +90,7 @@ def get_profile_support_page_content_html(request, data=None):
} }
tpl_name = 'blocks/profile/b_support_tickets.html' 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) html = render_to_string(tpl_name, Dict, request=request)
return html return html

View File

@@ -28,6 +28,8 @@ urlpatterns = [
path('change_profile_confirm/', change_profile_confirm_ajax, name='change_profile_confirm_ajax'), 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('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 from django.core.files import File
import base64 import base64
from django.core.validators import validate_email from django.core.validators import validate_email
from django.urls import reverse
# @login_required(login_url='/profile/login/') # @login_required(login_url='/profile/login/')
@@ -31,6 +32,49 @@ from django.core.validators import validate_email
# return JsonResponse({'html': html}, status=200) # 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): def send_message_ajax(request):
if request.method != 'POST': if request.method != 'POST':
@@ -126,7 +170,7 @@ def send_message_ajax(request):
return JsonResponse({'html': html}, status=400) return JsonResponse({'html': html}, status=400)
Dict = { 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'], 'project_name': sets['project_name'],
'message_title': subject, 'message_title': subject,
'message_text': f'<p><b>{_("ДАННЫЕ ЗАПРОСА")}</b></p>' 'message_text': f'<p><b>{_("ДАННЫЕ ЗАПРОСА")}</b></p>'
@@ -188,6 +232,7 @@ def chats_ajax(request):
'receivers': receivers, 'receivers': receivers,
# 'messages': cur_chat_msgs # '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) html = render_to_string('blocks/profile/b_chats.html', Dict, request=request)
return JsonResponse({'html': html}, status=200) return JsonResponse({'html': html}, status=200)
@@ -205,6 +250,7 @@ def support_tickets_ajax(request):
@login_required(login_url='/profile/login/') @login_required(login_url='/profile/login/')
def change_avatar_confirm_ajax(request): def change_avatar_confirm_ajax(request):
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.exceptions import RequestDataTooBig
if request.method != 'POST': if request.method != 'POST':
raise Http404 raise Http404
@@ -217,11 +263,15 @@ def change_avatar_confirm_ajax(request):
file = ContentFile(content) file = ContentFile(content)
request.user.user_profile.avatar.save(file_data['file_name'], file) request.user.user_profile.avatar.save(file_data['file_name'], file)
request.user.user_profile.save(update_fields=['avatar']) request.user.user_profile.save(update_fields=['avatar'])
except RequestDataTooBig:
msg = _('Слишком большой размер файла. Размер файла не должен быть больше 3МБ')
print(msg)
return JsonResponse({'error': msg}, status=400)
except Exception as e: except Exception as e:
msg = f'change_avatar_confirm_ajax Error = {str(e)}' msg = f'change_avatar_confirm_ajax Error = {str(e)}'
print(msg) print(msg)
JsonResponse({'error': msg}) return JsonResponse({'error': msg}, status=400)
return JsonResponse({'url': request.user.user_profile.avatar.url}) return JsonResponse({'url': request.user.user_profile.avatar.url})
@@ -236,7 +286,19 @@ def change_profile_confirm_ajax(request):
data = json.loads(request.body) data = json.loads(request.body)
from .forms import RegistrationForm 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 = {} data_for_save = {}
users = User.objects.filter(id=request.user.id) 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']) user = authenticate(username=form.data['username'], password=form.data['password'])
if user is not None: if user is not None:
auth.login(request, user) 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: else:
errors_Dict = { errors_Dict = {
'errors': { 'errors': {
@@ -378,6 +443,42 @@ def login_ajax(request):
return JsonResponse({'html': html}, status=400) 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): def registration_ajax(request):
if request.method != 'POST': if request.method != 'POST':
raise Http404 raise Http404
@@ -403,7 +504,10 @@ def registration_ajax(request):
user = User.objects.create_user(username=form.data['email'], email=form.data['email'], password=form.data['password']) 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']) # user = auth.authenticate(username=new_user_Dict['name'], password=new_user_Dict['pass'])
if user: 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.last_name = form.data['lastname']
user.first_name = form.data['firstname'] user.first_name = form.data['firstname']
@@ -411,6 +515,12 @@ def registration_ajax(request):
user.user_profile.phone = form.data['tel'] user.user_profile.phone = form.data['tel']
user.user_profile.save() user.user_profile.save()
mail_Dict = {
'user': user,
'pass': form.data['password']
}
res = send_registration_mail(mail_Dict, user)
res_Dict = { res_Dict = {
'redirect_url': reverse('profile_page', args=['dashboard']) '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 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): def save_user_alerts_to_session(self, request):
for_save_to_session = self.get_node_by_name('for_save_to_session') for_save_to_session = self.get_node_by_name('for_save_to_session')
if for_save_to_session: if for_save_to_session:
@@ -74,8 +82,23 @@ class UserProfile(BaseModel):
def create_user_profile(sender, instance, created, **kwargs): def create_user_profile(sender, instance, created, **kwargs):
user_profile = None
if created: 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') 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: if not instance.email:
instance.email = str(instance.username).lower() instance.email = str(instance.username).lower()
try: try:
instance.user_profile.modifiedDT = datetime.now() instance.user_profile.modifiedDT = datetime.now()
except: except:

View File

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

View File

@@ -19,6 +19,11 @@ def registration_View(request):
Dict = {} 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') t = loader.get_template('pages/profile/p_registration.html')
return get_inter_http_respose(t, Dict, request) return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request)) # return HttpResponse(t.render(Dict, request))
@@ -44,6 +49,11 @@ def profile_page_View(request, page_name, id=None):
'page_type': 'profile' '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}" title = f"{_('Личный кабинет пользователя')} {request.user.first_name} {request.user.last_name}"
Dict.update({ 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': # if request.GET and 'mobile' in request.GET and request.GET['mobile'] == 'true':
Dict.update({ # Dict.update({
'mobile': True # 'mobile': True
}) # })
t = loader.get_template('pages/profile/p_user_profile.html') t = loader.get_template('pages/profile/p_user_profile.html')
return get_inter_http_respose(t, Dict, request) return get_inter_http_respose(t, Dict, request)
@@ -117,7 +127,14 @@ def logout_View(request):
def login_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') t = loader.get_template('pages/profile/p_login.html')
return get_inter_http_respose(t, Dict, request) return get_inter_http_respose(t, Dict, request)

View File

@@ -112,6 +112,20 @@ class BaseModelViewPage(BaseModel):
class Meta: class Meta:
abstract = True 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): def get_FAQ_items(self):
return self.FAQ_items.filter(enable=True).order_by('order') 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: except Exception as e:
msg = 'techSendMail_for_specified_email_list error={0}'.format(str(e)) msg = 'techSendMail_for_specified_email_list error={0}'.format(str(e))
techSendMail(msg) techSendMail(sets, msg)
print(msg) print(msg)
return 'Fail' return 'Fail'
@@ -266,19 +266,22 @@ def techSendMail(sets, html_content, title=None, add_emails=None):
# return msg # return msg
print('techSendMail') print('techSendMail')
project_name = ''
if 'project_name' in sets:
project_name = sets['project_name']
try: try:
# subject = u'truEnergy Data техническое оповещение' # subject = u'truEnergy Data техническое оповещение'
from_email = 'support@truenergy.by' from_email = sets['sender_email']
to = ['web@syncsystems.net'] to = ['web@syncsystems.net']
if add_emails: if add_emails:
to.extend(add_emails) to.extend(add_emails)
text_content = 'Technical message from truEnergy.' text_content = f'Technical message from {project_name}'
if title: if title:
subject = title subject = title
else: else:
subject = u'truEnergy Data техническое оповещение' subject = f'{project_name} - техническое оповещение'
res = admin_send_mail_by_SMTPlib(sets, subject, from_email, to, html_content) 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.translation import gettext as _
from django.utils.safestring import mark_safe
def get_phone_valid_error(val): def get_phone_valid_error(val):
allow_chars = '01234567890()+ -' 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 i = 0
while i < len(val): while i < len(val):
if val[i] not in allow_chars: if val[i] not in allow_chars:
return _('Некорректные символы в номере телефона, пример корректного ввода +7 925 8600100') return error_msg
i += 1 i += 1

View File

@@ -1,3 +1,5 @@
import copy
from .models import * from .models import *
from django.db.models import Q, Value as V, Count, OuterRef, Subquery from django.db.models import Q, Value as V, Count, OuterRef, Subquery
from django.http import HttpResponse, Http404, JsonResponse from django.http import HttpResponse, Http404, JsonResponse
@@ -11,7 +13,7 @@ from django.urls import reverse
import json import json
from datetime import datetime, time from datetime import datetime, time
from django.conf import settings from django.conf import settings
from AuthApp.funcs import get_user_timezone_Dict
def get_unanswered_msgs_count_for_user(user): def get_unanswered_msgs_count_for_user(user):
@@ -52,11 +54,22 @@ def get_update_chat_Dict(data):
receiver = User.objects.get(id=data['receiver']) receiver = User.objects.get(id=data['receiver'])
if data['sender'] == data['cur_user']: if data['sender'] == data['cur_user']:
context_Dict.update({'user': sender}) user = copy.copy(sender)
cur_receiver = copy.copy(receiver)
else: 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'] required_beep = data['required_beep']
@@ -99,7 +112,7 @@ def get_update_chat_Dict(data):
context_Dict.update({ context_Dict.update({
'messages': msgs, 'messages': msgs,
'MEDIA_URL': settings.MEDIA_URL 'MEDIA_URL': settings.MEDIA_URL,
}) })
html = render_to_string(tpl_name, context_Dict) html = render_to_string(tpl_name, context_Dict)
if required_full_support_chat_html: if required_full_support_chat_html:
@@ -275,6 +288,7 @@ def send_msg(data):
def get_chat_page_content_html(request, receiver_id=None): def get_chat_page_content_html(request, receiver_id=None):
from AuthApp.models import User from AuthApp.models import User
from AuthApp.funcs import get_user_timezone_Dict
msgs = [] msgs = []
try: try:
@@ -294,6 +308,7 @@ def get_chat_page_content_html(request, receiver_id=None):
'receivers': receivers, 'receivers': receivers,
'page': 'chat', 'page': 'chat',
} }
Dict.update(get_user_timezone_Dict(request.user, request=request))
tpl_name = 'blocks/profile/b_chats.html' tpl_name = 'blocks/profile/b_chats.html'
html = render_to_string(tpl_name, Dict, request=request) 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) data = json.loads(request.body)
Dict = get_chat_page_content_Dict(request, data['user_id']) 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' tpl_name = 'blocks/profile/b_chats.html'
@@ -99,7 +100,7 @@ def update_chat_ajax2(request):
receiver = User.objects.get(id=data['receiver']) receiver = User.objects.get(id=data['receiver'])
context_Dict.update({'cur_receiver': receiver}) context_Dict.update({'cur_receiver': receiver})
context_Dict.update(get_user_timezone_Dict(request.user, request=request))
if not ticket: if not ticket:
@@ -123,6 +124,7 @@ def update_chat_ajax2(request):
# формируем правую панель # формируем правую панель
context_Dict.update({'receivers': receivers}) context_Dict.update({'receivers': receivers})
users_list_html = render_to_string( users_list_html = render_to_string(
'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request) 'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request)
res_Dict.update({ res_Dict.update({
@@ -190,6 +192,7 @@ def update_chat_ajax(request):
receiver = User.objects.get(id=data['receiver']) receiver = User.objects.get(id=data['receiver'])
context_Dict.update({'cur_receiver': receiver}) context_Dict.update({'cur_receiver': receiver})
context_Dict.update(get_user_timezone_Dict(request.user, request=request))
if ticket: if ticket:
@@ -201,6 +204,8 @@ def update_chat_ajax(request):
context_Dict.update({'messages': msgs}) context_Dict.update({'messages': msgs})
context_Dict = get_ticketsDict_for_staff(request.user) context_Dict = get_ticketsDict_for_staff(request.user)
context_Dict.update(get_user_timezone_Dict(request.user))
tickets_list_html = render_to_string( tickets_list_html = render_to_string(
'blocks/profile/b_list_of_tickets_support_chat.html', context_Dict, request=request) 'blocks/profile/b_list_of_tickets_support_chat.html', context_Dict, request=request)
res_Dict.update({ res_Dict.update({
@@ -220,6 +225,8 @@ def update_chat_ajax(request):
required_beep = True required_beep = True
context_Dict.update({'receivers': receivers}) context_Dict.update({'receivers': receivers})
context_Dict.update(get_user_timezone_Dict(request.user))
users_list_html = render_to_string( users_list_html = render_to_string(
'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request) 'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request)
res_Dict.update({ res_Dict.update({
@@ -404,12 +411,14 @@ def support_show_chat_by_ticket_ajax(request):
'cur_receiver': cur_receiver, 'cur_receiver': cur_receiver,
'new_msg_allow': new_msg_allow, 'new_msg_allow': new_msg_allow,
'staff': request.user.is_staff, 'staff': request.user.is_staff,
'mobile': data['mobile'] # 'mobile': data['mobile']
} }
Dict.update(get_ticketsDict_for_staff(request.user)) 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) html = render_to_string(tpl_name, Dict, request=request)
return JsonResponse({'html': html}, status=200) return JsonResponse({'html': html}, status=200)
@@ -429,6 +438,9 @@ def support_create_ticket_form_ajax(request):
Dict = { Dict = {
'form': TicketForm() 'form': TicketForm()
} }
Dict.update(get_user_timezone_Dict(request.user))
tpl_name = 'blocks/profile/b_create_ticket.html' tpl_name = 'blocks/profile/b_create_ticket.html'
html = render_to_string(tpl_name, Dict, request=request) html = render_to_string(tpl_name, Dict, request=request)
@@ -450,6 +462,8 @@ def create_ticket_ajax(request):
if not form.is_valid(): if not form.is_valid():
form.initial = form.cleaned_data form.initial = form.cleaned_data
Dict = {'form': form} Dict = {'form': form}
Dict.update(get_user_timezone_Dict(request.user))
html = render_to_string('blocks/profile/b_create_ticket.html', Dict, request=request) html = render_to_string('blocks/profile/b_create_ticket.html', Dict, request=request)
return JsonResponse({'html': html}, status=400) return JsonResponse({'html': html}, status=400)
@@ -490,6 +504,8 @@ def create_ticket_ajax(request):
'messages': msgs_for_ticket '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) html = render_to_string('blocks/profile/b_support_chat.html', Dict, request=request)
res_Dict = { res_Dict = {
@@ -500,9 +516,11 @@ def create_ticket_ajax(request):
except Exception as e: except Exception as e:
msg = f'{_("ошибка в запросе")} = {str(e)}'
errors_Dict = { errors_Dict = {
'errors': { 'errors': {
'all__': f'{_("ошибка в запросе")} = {str(e)}' 'all__': msg
} }
} }
Dict = {'form': errors_Dict} Dict = {'form': errors_Dict}

View File

@@ -46,7 +46,7 @@ class MsgGroup(BaseModel):
if msg.text: if msg.text:
return msg.text return msg.text
elif msg.files: elif msg.files:
return msg.files[0].file_name return msg.files[0]['file_name']
return self.name return self.name

View File

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

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.http import HttpResponse, Http404, FileResponse
from django.conf import settings
def get_inter_Dict(user): def get_inter_Dict(user):
from SubscribesApp.funcs import get_cur_user_subscribe from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(user) 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): def get_inter_http_respose(template_obj, context_Dict, request):
context_Dict.update(get_inter_Dict(request.user)) 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)) 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) opts = Option.objects.filter(**kwargs)
if opts and only_vals: if opts and only_vals:
opts = opts.values('opt_type', 'value') res = {}
opts = {item['opt_type']: item['value'] for item in opts} 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 return opts
def get_first_option_value_by_opt_type(opt_type): 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 return None
def get_mail_send_options(): 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) 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 .models import *
from django.conf import settings from django.conf import settings
from .funcs import get_inter_http_respose 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): def test_code(request):
from RoutesApp.funcs import get_city_by_type_transport_and_address_point from RoutesApp.funcs import get_city_by_type_transport_and_address_point
from RoutesApp.models import Route from RoutesApp.models import Route
from ReferenceDataApp.models import Airport, City 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: from RoutesApp.search_matches import search_matches
print(route.id) search_matches()
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: # try:
route.to_city = get_city_by_type_transport_and_address_point(route.type_transport, # # body = request.body
route.to_address_point) # # data = json.loads(body)
required_save = True # # 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: # routes = Route.objects.all()
route.save() #
# 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') 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))
@@ -58,6 +97,8 @@ def MainPage(request):
'owner_type': 'mover' 'owner_type': 'mover'
} }
breadcrumbs_Dict = { breadcrumbs_Dict = {
} }
Dict.update({'breadcrumbs': 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: else:
item['city_name'] = item['name'] item['city_name'] = item['name']
item['country_name'] = item['country__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)}" html = f"{html}{render_to_string('widgets/w_ac_input_address_point.html', item)}"
i += 1 i += 1

View File

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

View File

@@ -6,6 +6,47 @@ from django.core.exceptions import ValidationError
from .models import * 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): class RouteForm(forms.ModelForm):
from_address_point_txt = forms.CharField(required=True) from_address_point_txt = forms.CharField(required=True)
to_address_point_txt = forms.CharField(required=True) to_address_point_txt = forms.CharField(required=True)
@@ -24,6 +65,22 @@ class RouteForm(forms.ModelForm):
try: 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]: 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] 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': 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 elements_on_page = 25
def get_profile_new_route_page_html(request, data): def get_profile_new_route_page_html(request, data):
form = RouteForm() form = RouteForm()
Dict = { Dict = {
'form': form 'form': form
} }
try: try:
errors_off = True errors_off = True
@@ -27,59 +34,71 @@ def get_profile_new_route_page_html(request, data):
if 'to_address_point_txt' in data: if 'to_address_point_txt' in data:
del data['to_address_point_txt'] 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 'type_transport' in data:
if data['type_transport'] == 'avia': form = routeForm_assign_choices_by_type_transport(form, data['type_transport'])
transfer_location_choices = (
('airport', _('В аэропорту')),
('city', _('По городу')),
('other', _('По договоренности'))
)
cargo_type_choices = ( # form.fields['from_place'].choices = transfer_location_choices
('cargo', _('Груз')), # form.fields['to_place'].choices = transfer_location_choices
('parcel', _('Бандероль')), # form.fields['cargo_type'].choices = cargo_type_choices
('package', _('Посылка')), #
('letter', _('Письмо\Документ')) # 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
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)
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) # form = CreateRouteForm(initial=data)
# if not form.is_valid(): # if not form.is_valid():
# pass # 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 = { Dict = {
'form': form, 'form': form,
'errors_off': errors_off 'errors_off': errors_off
} }
if 'owner_type' in data:
Dict.update({'owner_type': data['owner_type']})
# print(form) # print(form)
except Exception as e: except Exception as e:
# form.errors.append({'__all__': f'Ошибка: {str(e)}'}) # form.errors.append({'__all__': f'Ошибка: {str(e)}'})
@@ -141,18 +160,31 @@ def get_routes_Dict(user=None, data=None):
res_Dict = {} res_Dict = {}
if data: 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(): for key, val in data.items():
if val: if val:
if key == 'weight': if key == 'weight':
weight_list = val.split(';') weight_list = val.split(';')
if weight_list[0]: if len(weight_list) > 1:
kwargs.update({f'{key}__gte': int(weight_list[0])}) if weight_list[0]:
if weight_list[1]: kwargs.update({f'{key}__gte': int(weight_list[0])})
kwargs.update({f'{key}__lte': int(weight_list[1])}) 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': # if key == 'type_transport':
items_list = val.split(',') # items_list = val.split(',')
kwargs.update({f'{key}__in': items_list}) # kwargs.update({f'{key}__in': items_list})
if key in ( if key in (
@@ -172,19 +204,18 @@ def get_routes_Dict(user=None, data=None):
kwargs.update({key: val}) kwargs.update({key: val})
if key == 'from_address_point': 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({ res_Dict.update({
'from_address_point_txt': get_country_n_city_str_by_type_transport_and_address_point( 'from_address_point_txt': city.get_country_n_city_str()
'road', val
)
}) })
if key == 'to_address_point': 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({ res_Dict.update({
'to_address_point_txt': get_country_n_city_str_by_type_transport_and_address_point( 'to_address_point_txt': city.get_country_n_city_str()
'road', val
)
}) })
if key == 'from_el': if key == 'from_el':
@@ -192,7 +223,7 @@ def get_routes_Dict(user=None, data=None):
if key == 'to_el': if key == 'to_el':
to_el = int(val) 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() routes_count = routes.count()
if from_el and to_el: 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']) route = Route.objects.get(id=data['route_id'])
form = RouteForm(instance=route) form = RouteForm(instance=route)
form = routeForm_assign_choices_by_type_transport(form, route.type_transport)
route_address_points_Dict = route.get_address_points() route_address_points_Dict = route.get_address_points()
form.initial.update({ form.initial.update({
'from_address_point_txt': route_address_points_Dict['from_address_point_txt'], '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) return JsonResponse({'html': html}, status=400)
obj = form.save(commit=False) 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'] obj.owner_type = data['owner_type']
if obj.from_address_point: 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( to_address_point_Dict = to_address_point_objs.values(
'id', 'name', 'country__name')[0] 'id', 'name', 'country__name')[0]
from_address_point_txt = f'{from_address_point_Dict["country__name"]} / {from_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["country__name"]} / {to_address_point_Dict["name"]}' to_address_point_txt = f'{to_address_point_Dict["name"]} / {to_address_point_Dict["country__name"]}'
return { return {
'from_address_point_obj': from_address_point_objs[0], '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

@@ -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({ application = ProtocolTypeRouter({
'http': get_asgi_application(), 'http': get_asgi_application(),
"websocket": QueryAuthMiddleware( "websocket":
URLRouter( # AllowedHostsOriginValidator(
websocket_urlpatterns QueryAuthMiddleware(
) URLRouter(
), websocket_urlpatterns
)
# )
),
# 'websocket': AuthMiddlewareStack( # 'websocket': AuthMiddlewareStack(
# URLRouter( # URLRouter(
# websocket_urlpatterns # 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 pathlib import Path
from decouple import config
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent 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 # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
@@ -28,6 +31,50 @@ DEBUG = True
ALLOWED_HOSTS = ["*"] 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 # SESSION_COOKIE_HTTPONLY = False
# Application definition # Application definition
@@ -46,17 +93,27 @@ INSTALLED_APPS = [
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django.contrib.humanize', 'django.contrib.humanize',
'django.contrib.sites',
'colorfield', 'colorfield',
'ckeditor', 'ckeditor',
'ckeditor_uploader', 'ckeditor_uploader',
'webpush',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.google',
'GeneralApp', 'GeneralApp',
'AuthApp', 'AuthApp',
'RoutesApp', 'RoutesApp',
'ReferenceDataApp', 'ReferenceDataApp',
'ArticlesApp', 'ArticlesApp',
'SubscribesApp', 'SubscribesApp',
'PushMessages',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@@ -69,8 +126,14 @@ MIDDLEWARE = [
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'AuthApp.middleware.ResponseInterceptionMiddleware', 'AuthApp.middleware.ResponseInterceptionMiddleware',
'TWB.tz_middelware.TimezoneMiddleware',
# 'tz_detect.middleware.TimezoneMiddleware',
"allauth.account.middleware.AccountMiddleware",
] ]
SITE_ID = 1
ROOT_URLCONF = 'TWB.urls' ROOT_URLCONF = 'TWB.urls'
TEMPLATES = [ TEMPLATES = [
@@ -109,11 +172,8 @@ CHANNEL_LAYERS = {
} }
POSTGRES_DB = config('POSTGRES_DB')
POSTGRES_USER = config('POSTGRES_USER')
# Database # Database
@@ -122,8 +182,8 @@ CHANNEL_LAYERS = {
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'twbDB', 'NAME': POSTGRES_DB,
'USER': 'test_user', 'USER': POSTGRES_USER,
'PASSWORD': 'test_db_pass', 'PASSWORD': 'test_db_pass',
'HOST': '127.0.0.1', 'HOST': '127.0.0.1',
'PORT': '5432', 'PORT': '5432',
@@ -209,6 +269,7 @@ django.conf.locale.LANG_INFO = LANG_INFO
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DATA_UPLOAD_MAX_MEMORY_SIZE = 4145728
CKEDITOR_BASEPATH = "/static/ckeditor/ckeditor/" CKEDITOR_BASEPATH = "/static/ckeditor/ckeditor/"
CKEDITOR_UPLOAD_PATH = "uploads/" CKEDITOR_UPLOAD_PATH = "uploads/"
@@ -272,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 = { # CKEDITOR_OPTIONS = {
# 'height': 291, # '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.contrib import admin
from django.urls import path, include from django.urls import path, include
from django.conf.urls.static import static from django.conf.urls.static import static
from django.conf import settings from django.conf import settings
from GeneralApp.views import Page404
from AuthApp.views import login_View
handler404 = Page404
urlpatterns = [ urlpatterns = [
# path('admin/', admin.site.urls),
path('ckeditor/', include('ckeditor_uploader.urls')), path('ckeditor/', include('ckeditor_uploader.urls')),
path('i18n/', include('django.conf.urls.i18n')), 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('messages/', include('ChatServiceApp.urls')),
path('user_account/', include('AuthApp.js_urls')), path('user_account/', include('AuthApp.js_urls')),
path('routes/', include('RoutesApp.js_urls')), path('routes/', include('RoutesApp.js_urls')),
path('subscribes/', include('SubscribesApp.js_urls')), path('subscribes/', include('SubscribesApp.js_urls')),
@@ -22,6 +34,12 @@ urlpatterns = [
path('reference_data/', include('ReferenceDataApp.js_urls')), path('reference_data/', include('ReferenceDataApp.js_urls')),
path('', include('ArticlesApp.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 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 #: .\templates\blocks\static_pages_blocks\b_partners.html:18
msgid "" msgid ""
"Вы можете разместить объявление о перевозке посылки и перевозчики со всего " "Вы можете разместить объявление о перевозке посылки и перевозчики со всего "
"мира откликнуться на ваше объявление или воспользовавшись поиском на сайте " "мира откликнутся на ваше объявление или воспользовавшись поиском на сайте "
"найти перевозчика, который будет готов взять Вашу посылку и доставить в " "найти перевозчика, который будет готов взять Вашу посылку и доставить в "
"указанное место авто- или авива транспортом." "указанное место наземным или авиатранспортом."
msgstr "" msgstr ""
#: .\templates\blocks\static_pages_blocks\b_about_service.html:22 #: .\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 django-ckeditor==6.5.1
psycopg2-binary==2.9.6 psycopg2-binary==2.9.6
requests requests
Pillow==9.5.0
django-modeltranslation==0.18.10 django-modeltranslation==0.18.10
overpass overpass
geopy geopy
@@ -10,4 +9,9 @@ channels==4.0.0
daphne==4.0.0 daphne==4.0.0
channels-redis==4.1.0 channels-redis==4.1.0
django-colorfield 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){ @media (max-width: 1199px){
.dropbtn{ .dropbtn{
margin-right: 20px; margin-right: unset;
} }
.header_logo, .header_btn_mover{ .header_logo, .header_btn_mover{
margin-right: 20px; margin-right: 20px;
} }
.dropbtn_lang{
padding: 2px 0.5px;
border-radius: 12px;
}
#ru_lang,#en_lang{
padding: unset;
}
#customer_service{ #customer_service{
margin-right: 10px; margin-right: 10px;
@@ -61,41 +71,41 @@
left: 33%; left: 33%;
} }
.cards_item_1, /* .cards_item_1,*/
.cards_item_2, /*.cards_item_2,*/
.cards_item_3, /*.cards_item_3,*/
.cards_item_4 /*.cards_item_4*/
{ /*{*/
width: 46%; /* width: 46%;*/
height: 180px; /* height: 180px;*/
background-size:60%; /* background-size:60%;*/
} /*}*/
.card_title_1{ /* .card_title_1{*/
font-size: 34px; /* font-size: 34px;*/
font-style: normal; /* font-style: normal;*/
font-weight: 700; /* font-weight: 700;*/
line-height: 42px; /* line-height: 42px;*/
margin: 22px 0 0 10px; /* margin: 22px 0 0 10px;*/
text-shadow: 1px 1px 0px #272424; /* text-shadow: 1px 1px 0px #272424;*/
} /*}*/
.card_title_2{ /*.card_title_2{*/
font-size: 17px; /* font-size: 17px;*/
font-style: normal; /* font-style: normal;*/
font-weight: 600; /* font-weight: 600;*/
line-height: 26px; /* line-height: 26px;*/
margin: 10px 0 0 10px; /* margin: 10px 0 0 10px;*/
text-shadow: 1px 1px 0px #272424; /* text-shadow: 1px 1px 0px #272424;*/
} /*}*/
.card_title_3{ /*.card_title_3{*/
margin: 10px 0 0 10px; /* margin: 10px 0 0 10px;*/
width: 95%; /* width: 95%;*/
font-size: 12px; /* font-size: 12px;*/
font-style: normal; /* font-style: normal;*/
font-weight: 400; /* font-weight: 400;*/
line-height: 20px; /* line-height: 20px;*/
text-shadow: 1px 1px 0px #272424; /* text-shadow: 1px 1px 0px #272424;*/
} /*}*/
.sf_1_column { .sf_1_column {
padding-left: 25px; padding-left: 25px;
padding-right: 90px; padding-right: 90px;
@@ -106,12 +116,102 @@
} }
@media (max-width: 1180px){ @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{ .wrapper_name_art{
font-size: 29px; font-size: 29px;
line-height: 33px; line-height: 33px;
} }
.header_buttons{
display: none;
}
.confirm_profile_btn{
width: 95%;
}
.not_found_routes>img{ .not_found_routes>img{
display: none; display: none;
@@ -283,8 +383,9 @@
} }
.button_profile_header_mobile{ .button_profile_header_mobile{
display: inline-block ; display: inline-block ;
margin-left: 5px;
} }
.header-first>div { .header_logo_mobile {
margin-right: 37px; margin-right: 37px;
} }
.line_f_header{ .line_f_header{
@@ -335,10 +436,11 @@
margin-top: unset; margin-top: unset;
} }
button#more_button{ #more_button, #send_parcel_button{
width: 50%; width: 50%;
/*margin-top: 40px;*/
} }
#title_static{ #title_static{
font-size: 33px; font-size: 33px;
line-height: 42px; line-height: 42px;
@@ -494,6 +596,7 @@
section.register>form{ section.register>form{
display: block; display: block;
width: unset; width: unset;
margin-right: 10px;
} }
.inputs{ .inputs{
@@ -639,7 +742,7 @@
top: 0; top: 0;
} }
.cut_width_f_curtain.n_profile.left{ .cut_width_f_curtain.n_profile.left{
position: fixed; position: sticky;
/*min-width: 1280px;*/ /*min-width: 1280px;*/
} }
@@ -867,10 +970,10 @@
.left-part-block-enter-message{ .left-part-block-enter-message{
width: 70%; width: calc(70% - 74px);
} }
.right-part-block-enter-message{ .right-part-block-enter-message{
width: 30%; width: 74px;
} }
.container-message_support_chat{ .container-message_support_chat{
width: 70%; width: 70%;
@@ -1030,7 +1133,7 @@
.cargo_type_trans{ .cargo_type_trans{
display: block; display: block;
margin-bottom: 15px; margin-bottom: 15px;
float: unset; /*float: unset;*/
} }
.from-to-country-container-carrier{ .from-to-country-container-carrier{
@@ -1358,7 +1461,9 @@
.header_logo, .header_btn_mover{ .header_logo, .header_btn_mover{
margin-right: 26px; margin-right: 26px;
} }
.cookie_block{
width: 100%;
}
.menu_buttons.curtain.left.close.chat{ .menu_buttons.curtain.left.close.chat{
width: 265px; width: 265px;
} }
@@ -1424,6 +1529,45 @@
.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{ .read_more_about_subscribe{
padding: 0 14px; padding: 0 14px;
height: 30px; height: 30px;
@@ -1490,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){ @media (max-width: 828px){
/*.to_address_point_txt.find_route {*/ /*.to_address_point_txt.find_route {*/
/*width: 54.6%;*/ /*width: 54.6%;*/
@@ -1550,6 +1713,17 @@
} }
@media (max-width: 699px){ @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{ .block_overlay.show{
display: block; display: block;
} }
@@ -1592,6 +1766,28 @@
background: #FFF; 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{ .info_profile{
width: 100%; width: 100%;
} }
@@ -1650,6 +1846,8 @@
} }
@media (max-width: 575px){ @media (max-width: 575px){
.phones_carrier{ .phones_carrier{
display: block; display: block;
} }
@@ -1705,24 +1903,47 @@
width: 100%; width: 100%;
margin-top: 20px; margin-top: 20px;
} }
button#more_button{ #more_button{
width: 100%; width: 100%;
margin-top: 40px; margin-top: 40px;
} }
#send_parcel_button{
width: 100%;
margin-top: 40px;
}
.news_block_main{ .news_block_main{
justify-content: center; justify-content: center;
} }
.cards_item_1, /*.cards_item_1,*/
.cards_item_2, /*.cards_item_2,*/
.cards_item_3, /*.cards_item_3,*/
.cards_item_4 /*.cards_item_4*/
{ /*{*/
width: 100%; /* width: 100%;*/
height: 180px; /* height: 180px;*/
background-size:60%; /* 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{ .cards_wrapper{
@@ -1787,9 +2008,7 @@
height: 30px; height: 30px;
} }
.header_buttons{
display: none;
}
/*.to_address_point_txt.find_route {*/ /*.to_address_point_txt.find_route {*/
/* width: 48.4%;*/ /* width: 48.4%;*/
/*}*/ /*}*/
@@ -1800,7 +2019,7 @@
.container_inp_w_abr { .container_inp_w_abr {
width: 99%; width: 100%;
} }
.another_subscribe{ .another_subscribe{
@@ -1814,6 +2033,10 @@
@media (max-width: 440px){ @media (max-width: 440px){
.card_title_3{
margin: 20px 5px 0 20px;
}
.f-r{ .f-r{
text-align: left; text-align: left;
} }
@@ -1881,6 +2104,13 @@
} }
@media (max-width: 360px){ @media (max-width: 360px){
#customer>.text_btn_profile, #mover>.text_btn_profile{
width: 53%;
}
.loader_chat_f_sw_chats.show { .loader_chat_f_sw_chats.show {
display: block; display: block;
height: 100px; height: 100px;
@@ -1889,6 +2119,76 @@
top: 35%; top: 35%;
left: 34%; 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{ .tab-btn-1{
padding: unset; padding: unset;
} }

View File

@@ -58,6 +58,8 @@
width: 100%; width: 100%;
/*background: rgba(39, 53, 62, 0.7);*/ /*background: rgba(39, 53, 62, 0.7);*/
backdrop-filter: blur(6px); backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
-moz-backdrop-filter: blur(6px);
z-index: 100; z-index: 100;
position: fixed; position: fixed;
top: 0; top: 0;
@@ -448,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); box-shadow: -1px 4px 10px 0 rgba(198, 199, 203, 0.20), 0 -1px 10px 0 rgba(198, 199, 203, 0.20);
float: right; float: right;
position: relative; position: relative;
overflow: hidden;
} }
.block_loader_chat{ .block_loader_chat{
@@ -482,7 +485,8 @@
} }
.bottom_part_of_chats{ .bottom_part_of_chats{
height: calc(100% - 39px); height: 100%;
padding-bottom: 39px;
position: relative; position: relative;
} }
@@ -493,6 +497,8 @@
width: calc(100% - 40px); width: calc(100% - 40px);
height: 60px; height: 60px;
padding: 10px 20px; padding: 10px 20px;
position: absolute;
top: 0;
} }
.header-chat-left-part{ .header-chat-left-part{
@@ -536,14 +542,15 @@
} }
.container-messages{ .container-messages{
height: calc(100% - 175px); height: calc(100% - 224px);
width: 100%; width: 100%;
/* transform: rotate(180deg); */ /* transform: rotate(180deg); */
overflow-y: auto; overflow-y: auto;
/* transform: scaleY(-1); */ /* transform: scaleY(-1); */
display: flex; display: flex;
flex-direction: column-reverse; flex-direction: column-reverse;
padding-top: 70px; padding-bottom: 63px;
margin-top: 100px;
} }
@@ -560,7 +567,7 @@
border: 1px solid #E6E6E6; border: 1px solid #E6E6E6;
padding: 0 20px 0 20px; padding: 0 20px 0 20px;
position: absolute; position: absolute;
bottom: 43px; bottom: 0;
} }
.footer-chat.hide{ .footer-chat.hide{
@@ -568,12 +575,12 @@
} }
.left-part-block-enter-message{ .left-part-block-enter-message{
width: 80%; width: calc(80% - 74px);
float: left; float: left;
} }
.right-part-block-enter-message{ .right-part-block-enter-message{
width: 20%; width: 74px;
float: right; float: right;
padding-top: 11px; padding-top: 11px;
text-align: right; text-align: right;
@@ -1026,7 +1033,7 @@
.from_address_point_txt.find_route.first.w_100{ .from_address_point_txt.find_route.first.w_100{
width: calc(100% - 35px); width: calc(100% - 35px);
border-right: 1px solid #E6E6E6; border-right: 2px solid #E6E6E6;
} }
.from_address_point_txt.post_route.first.w_100{ .from_address_point_txt.post_route.first.w_100{
@@ -1072,15 +1079,20 @@
.input_list.find_route{ .input_list.find_route{
width: 100%; width: 90%;
/* display: block; */ /*display: block;*/
border-radius: 0 10px; border-radius: 0 0 10px 10px;
top: 61px; top: 62px;
z-index: 12; left: 9px;
z-index: 10000;
} }
.input_list.find_route.show{ .input_list.find_route.show{
display: block; display: block;
border: 2px solid #E6E6E6;
border-top: hidden;
} }
.container_inp_w_abr{ .container_inp_w_abr{
@@ -1200,9 +1212,9 @@
margin: 0; margin: 0;
} }
.cont-el-form-search-carrier.last > label{ /*.cont-el-form-search-carrier.last > label{*/
opacity: 0; /* opacity: 0;*/
} /*}*/
.block-filters-find-route { .block-filters-find-route {
@@ -1231,8 +1243,8 @@
} }
.not_found_routes{ .not_found_routes{
width: 98%; width: 96%;
height: 250px; min-height: 250px;
background: #FFFFFF; background: #FFFFFF;
box-shadow: -1px 4px 10px 0 rgba(198, 199, 203, 0.20), 0 -1px 10px 0 rgba(198, 199, 203, 0.20); box-shadow: -1px 4px 10px 0 rgba(198, 199, 203, 0.20), 0 -1px 10px 0 rgba(198, 199, 203, 0.20);
position: relative; position: relative;
@@ -1485,6 +1497,17 @@
width: 100%; width: 100%;
} }
a.open_inf_carrier{
display: block;
width: 88%;
}
.show_contact_wrapper {
text-align: center;
}
.open_inf_carrier:hover{ .open_inf_carrier:hover{
background: #FF613A; background: #FF613A;
color: #FFFFFF; color: #FFFFFF;
@@ -1535,7 +1558,13 @@
font-weight: 500; font-weight: 500;
font-size: 20px; font-size: 20px;
color: #272424; color: #272424;
padding-bottom: 10px;
margin-bottom: 10px;
/*border: 2px solid #FF613A;*/
border-radius: 10px;
padding: 7px;
text-align: center;
} }
.name_carrier{ .name_carrier{
@@ -2102,7 +2131,7 @@
.button_profile_header{ .button_profile_header{
height: 50px; height: 50px;
width: 150px; width: 155px;
background: #FF613A; background: #FF613A;
color: #FFF; color: #FFF;
/* Heading 5 */ /* Heading 5 */
@@ -2549,6 +2578,7 @@
position: absolute; position: absolute;
top: 293px; top: 293px;
transition: 0ms; transition: 0ms;
scrollbar-width: none;
} }
@@ -2655,7 +2685,7 @@
.menu_buttons.left.open.first.filters .text_f_curtain > img{ .menu_buttons.left.open.first.filters .text_f_curtain > img{
transition: 200ms; 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%); filter: brightness(0) saturate(100%) invert(100%) sepia(2%) saturate(0%) hue-rotate(162deg) brightness(104%) contrast(103%);
position: relative; position: relative;
} }
@@ -2673,6 +2703,7 @@
height: calc(100vh - 95px); height: calc(100vh - 95px);
max-height: 697px; max-height: 697px;
background: #F8F8F8; background: #F8F8F8;
scrollbar-width: none;
} }
.menu_profile.background{ .menu_profile.background{
@@ -2868,7 +2899,7 @@
} }
.text_in_btn_a_anchor{ .text_in_btn_a_anchor{
padding-top: 20px; padding-top: 17px;
} }
.anchor{ .anchor{
@@ -2888,4 +2919,50 @@
.title_b_first_page{ .title_b_first_page{
margin-top: 70px; 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'); src: url("/static/fonts/inter/Inter-Regular.ttf") format('truetype');
font-weight: 400; font-weight: 400;
font-style: normal; font-style: normal;
font-display: swap;
} }
@font-face{ @font-face{
font-family: 'Inter'; font-family: 'Inter';
src: url("/static/fonts/inter/Inter-Medium.ttf") format('truetype') ; src: url("/static/fonts/inter/Inter-Medium.ttf") format('truetype') ;
font-weight: 500; font-weight: 500;
font-style: normal; font-style: normal;
font-display: swap;
} }
@font-face{ @font-face{
font-family: 'Inter'; font-family: 'Inter';
src: url("/static/fonts/inter/Inter-SemiBold.ttf") format('truetype') ; src: url("/static/fonts/inter/Inter-SemiBold.ttf") format('truetype') ;
font-weight: 600; font-weight: 600;
font-style: normal; font-style: normal;
font-display: swap;
} }
@font-face{ @font-face{
font-family: 'Inter'; font-family: 'Inter';
src: url("/static/fonts/inter/Inter-Bold.ttf") format('truetype') ; src: url("/static/fonts/inter/Inter-Bold.ttf") format('truetype') ;
font-weight: 700; font-weight: 700;
font-style: normal; font-style: normal;
font-display: swap;
} }
/* Links */ /* Links */
@@ -136,8 +140,15 @@ legend {
} }
html, body{ html, body{
height: 100%; /*height: 100%;*/
scroll-behavior: smooth; 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 { .wrapper_content {
@@ -223,6 +234,8 @@ body {
margin: 0; margin: 0;
padding: 0; padding: 0;
background: #F8F8F8; background: #F8F8F8;
/*mix-blend-mode: multiply;*/
/*пока убрал надо чтобы fire протестил на iphone*/
} }
header { header {
@@ -258,11 +271,15 @@ section.register>h1 {
border-radius: 10px; border-radius: 10px;
border: 1px solid black; border: 1px solid black;
} }
.footer_input_wrap.hide{
display: none;
}
.footer_input_wrap { .footer_input_wrap {
display: flex; display: flex;
color: #FF613A;
} }
.footer_input::placeholder { .footer_input::placeholder {
color: rgba(39, 36, 36, 0.60); color: rgba(39, 36, 36, 0.60);
font-size: 16px; font-size: 16px;
@@ -537,6 +554,21 @@ header .header-first {
font-size: 16px; font-size: 16px;
border: none; 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 { .dropdown {
position: relative; position: relative;
@@ -557,6 +589,7 @@ header .header-first {
height: 390px; height: 390px;
box-shadow: -1px 4px 10px 0px rgba(198, 199, 203, 0.20), 0px -1px 10px 0px rgba(198, 199, 203, 0.20); 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; z-index: 1;
top: 30px;
} }
.dropdown-content.show{ .dropdown-content.show{
display:block; display:block;
@@ -635,8 +668,26 @@ header .header-second {
.button_profile_header_mobile{ .button_profile_header_mobile{
display: none; 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, .header-second-item,
.cont_header_btn_profile, .cont_header_btn_profile,
@@ -671,8 +722,9 @@ span.btn_profile_name {
/*Language select*/ /*Language select*/
.dropbtn_lang { .dropbtn_lang {
padding: 7px 0 7px 0; padding: 8px 6.5px;
cursor: pointer; cursor: pointer;
border-radius: 23px;
} }
/* The container <div> - needed to position the dropdown content */ /* The container <div> - needed to position the dropdown content */
@@ -691,9 +743,9 @@ span.btn_profile_name {
.dropbtn_lang .dropbtn_lang
{ {
background: url('/static/img/png/ru.png') no-repeat left center; /*background: url('/static/img/svg/ru.svg') no-repeat left center;*/
padding-left: 25px; /*padding-left: 25px;*/
width: 40px; /*width: 40px;*/
color: transparent; color: transparent;
} }
@@ -709,16 +761,19 @@ span.btn_profile_name {
#ru_lang #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; color: transparent;
padding: 10px; padding: 6px;
margin: 5px 0;
border-radius: 5px;
} }
#en_lang #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; color: transparent;
padding: 10px; padding: 6px;
border-radius: 5px;
} }
/* Links inside the dropdown */ /* Links inside the dropdown */
@@ -733,6 +788,20 @@ span.btn_profile_name {
display: block; 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 */ /* Change color of dropdown links on hover */
.dropdown-content-lang a:hover {background-color: #f1f1f1} .dropdown-content-lang a:hover {background-color: #f1f1f1}
@@ -743,8 +812,9 @@ span.btn_profile_name {
/*END Language select*/ /*END Language select*/
.header-second>div>img{ #support_img{
margin-right: 5px; margin-right: 5px;
margin-left: 40px;
} }
#customer_service{ #customer_service{
margin-right: 35px; margin-right: 35px;
@@ -1332,6 +1402,13 @@ h2.title_new_route{
.prof_second_line>a { .prof_second_line>a {
color: #FF613A; color: #FF613A;
cursor: pointer;
}
#id_email{
cursor: unset;
}
#error_arrival_DT.hide, #error_departure_DT.hide{
display: none;
} }
.prof_third_line>a { .prof_third_line>a {
@@ -1395,6 +1472,7 @@ span.errorlist{
/*create new route*/ /*create new route*/
select#id_type_transport{ select#id_type_transport{
cursor: pointer;
display: block; display: block;
height: 60px; height: 60px;
width: 47%; width: 47%;
@@ -1588,6 +1666,10 @@ div.departure_arrival>div>input{
} }
#hide_owner_type{
display: none;
}
/*end create new route*/ /*end create new route*/
@@ -1653,12 +1735,32 @@ div.departure_arrival>div>input{
max-height: 200px; max-height: 200px;
width: 100%; width: 100%;
position: absolute; position: absolute;
background-color: #F8F8F8; background-color: #FFFFFF;
overflow: scroll; overflow: scroll;
overflow-x:hidden; 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{ .input_list.post_route{
padding-top: 20px; padding-top: 20px;
max-width: 390px; max-width: 390px;
@@ -1674,7 +1776,7 @@ div.departure_arrival>div>input{
.input_list .hide{ .input_list .hide{
display: none; display: none;
} }
span.hide{ span.hide, .error_to_address_point.hide, #id_cargo_lable.hide, #error_id_phone.hide{
display: none; display: none;
} }
#agreement_check.hide{ #agreement_check.hide{
@@ -2003,6 +2105,26 @@ button.cancel_remove.show, button.confirm_remove.show{
/*Static_pages*/ /*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{ #title_static{
text-align: center; text-align: center;
font-size: 44px; font-size: 44px;
@@ -2050,9 +2172,9 @@ span#sub_title_static{
} }
button#more_button{ #more_button, #send_parcel_button{
display: inline-block; display: inline-block;
height: 60px; /*height: 60px;*/
width: 20%; width: 20%;
background: #FF613A; background: #FF613A;
color: #FFF; color: #FFF;
@@ -2070,6 +2192,11 @@ button#more_button{
} }
#send_parcel_button{
height: 60px;
}
.top_block_static{ .top_block_static{
position: relative; position: relative;
width: 90%; width: 90%;
@@ -2274,7 +2401,7 @@ figure{
.bottom_block_static>#box2 { .bottom_block_static>#box2 {
/* Положение верхнего левого изображения */ /* Положение верхнего левого изображения */
top: 16%; top: 0%;
left: -2%; left: -2%;
transform: scale(-1, 1); transform: scale(-1, 1);
@@ -2292,7 +2419,7 @@ figure{
.bottom_block_static>#box4 { .bottom_block_static>#box4 {
/* Положение верхнего правого изображения */ /* Положение верхнего правого изображения */
top: 18%; top: 9%;
right: -1%; right: -1%;
} }
@@ -2565,18 +2692,40 @@ button#send_feedback_form:active{
} }
.cards_wrapper{ .cards_wrapper{
display: flex; /*display: flex;*/
flex-direction: row; /*flex-direction: row;*/
flex-wrap: wrap; /*flex-wrap: wrap;*/
justify-content: center; /*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{ .cards_item_1{
width: 48%;
height: 322px;
border-radius: 10px; 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-repeat: no-repeat;
background-position: right; background-position: right;
@@ -2585,13 +2734,7 @@ button#send_feedback_form:active{
margin: 10px; margin: 10px;
} }
.cards_item_1_left,
.cards_item_2_left,
.cards_item_3_left,
.cards_item_4_left{
width: 55%;
float: left;
}
@@ -2606,10 +2749,9 @@ button#send_feedback_form:active{
} }
.cards_item_2{ .cards_item_2{
width: 48%; border-radius: 10px;
height: 322px; /*background: url(/static/img/png/cards_item_2.png) white 50%;*/
border-radius: 10px; background: white 50%;
background: url(/static/img/png/cards_item_2.png) white 50%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: right; background-position: right;
@@ -2619,13 +2761,23 @@ button#send_feedback_form:active{
} }
.cards_item_2>div, .cards_item_text {
.cards_item_3>div{ float: left;
color: black; width: 50%;
text-shadow: none;
text-shadow: 1px 1px 0px #ffffff;
} }
.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{ .cards_item_2_right{
float: right; float: right;
border-radius: 10px; border-radius: 10px;
@@ -2651,10 +2803,9 @@ button#send_feedback_form:active{
.cards_item_3{ .cards_item_3{
width: 48%;
height: 322px;
border-radius: 10px; 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-repeat: no-repeat;
background-position: right; 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); box-shadow: -1px 4px 10px 0px rgba(198, 199, 203, 0.20), 0px -1px 10px 0px rgba(198, 199, 203, 0.20);
@@ -2674,10 +2825,9 @@ button#send_feedback_form:active{
.cards_item_4{ .cards_item_4{
width: 48%;
height: 322px;
border-radius: 10px; 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-repeat: no-repeat;
background-position: right; background-position: right;
@@ -2686,6 +2836,16 @@ button#send_feedback_form:active{
margin: 10px; margin: 10px;
} }
.cards_item_1,
.cards_item_2,
.cards_item_3,
.cards_item_4{
height: 322px;
width: 48%;
}
.cards_item_4_right{ .cards_item_4_right{
float: right; float: right;
border-radius: 10px; border-radius: 10px;
@@ -2702,7 +2862,7 @@ button#send_feedback_form:active{
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
line-height: 52px; /* 118.182% */ line-height: 52px; /* 118.182% */
margin: 104px 0 0 20px; margin: 67px 0 0 20px;
} }
.card_title_2{ .card_title_2{
color: #FFF; color: #FFF;
@@ -2719,7 +2879,7 @@ button#send_feedback_form:active{
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;
margin: 20px 0 0 20px; margin: 20px 0 0 20px;
width: 50%;
} }
/*faq_main_page*/ /*faq_main_page*/

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

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

View File

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

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) { 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 (list_of_users) {
if (data.users_list_html){ if (data.users_list_html){

View File

@@ -1,16 +1,20 @@
function sendMessageSocket (data) { function sendMessageSocket (data) {
if (chatSocket.readyState !== 1 && chatSocket.readyState !== 0){ if (chatSocket && chatSocket.readyState !== 0) {
init_ws() 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']
} }
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) console.log(data)
} else if (data.type === "update_chat") { } else if (data.type === "update_chat") {
let msg_cont = document.querySelector(".container-messages") 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) update_chat_html(data,msg_cont)
// document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'end',inline:'end'}); // document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'end',inline:'end'});
@@ -55,6 +69,8 @@ function wsReceiveData (e) {
if (user_id) { if (user_id) {
if (ticket_maneger.toString() !== user_id) { if (ticket_maneger.toString() !== user_id) {
clear_messenger() clear_messenger()
} else {
} }
} }
else { else {
@@ -93,14 +109,25 @@ function wsReceiveData (e) {
} }
// } // }
// if // if
if (window.location.href.includes("chat")){
update_list_w_users(data,old_item_tab_user,el_tab) update_list_w_users(data,old_item_tab_user,el_tab)
}
} else if (data.type === "update_support_chat"){ } else if (data.type === "update_support_chat"){
update_support_chat_func(data,msg_cont) update_support_chat_func(data,msg_cont)
} }
if (data.unread_msgs_count > 0){ 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) update_count_unread_messages(data)
} }
if (data.required_beep === true) { 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 * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/ */
!function(t,e) { !function(t,e) {
if ("function" == typeof define && define.amd) define(["moment", "jquery"], function (t, a) { if ("function" == typeof define && define.amd) define(["moment", "jquery"], function (t, a) {
@@ -47,19 +50,26 @@
this.buttonClasses = "btn btn-sm", this.buttonClasses = "btn btn-sm",
this.applyButtonClasses = "btn-primary", this.applyButtonClasses = "btn-primary",
this.cancelButtonClasses = "btn-default", this.cancelButtonClasses = "btn-default",
this.locale = {
direction: "ltr", this.locale = i.locale,
// format: t.localeData().longDateFormat("L"), this.locale.daysOfWeek = t.weekdaysMin(),
format: "DD.MM.YYYY", this.locale.monthNames = t.monthsShort(),
separator: " - ", this.locale.firstDay = t.localeData().firstDayOfWeek(),
applyLabel: "Apply",
cancelLabel: "Cancel", // this.locale = {
weekLabel: "W", // direction: "ltr",
customRangeLabel: "Custom Range", // // format: t.localeData().longDateFormat("L"),
daysOfWeek: t.weekdaysMin(), // format: "DD.MM.YYYY",
monthNames: t.monthsShort(), // separator: " - ",
firstDay: t.localeData().firstDayOfWeek() // applyLabel: "Принять",
}, this.callback = function () { // 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)) { }, 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; (p = document.createElement("textarea")).innerHTML = i.locale.customRangeLabel;
var n = p.value; var n = p.value;

View File

@@ -1,6 +1,6 @@
timeout_range_slider = null 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") 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) let list = forloop_func_form(data_d,"get",get_url)
data_d = list[0] data_d = list[0]
get_url = list[1] get_url = list[1]
// if (owner_type !== null) { if (owner_type !== null) {
// data_d['owner_type'] = owner_type data_d['owner_type'] = owner_type
// } }
// get_url = get_url + `owner_type=${owner_type}` // get_url = get_url + `owner_type=${owner_type}`
window.location.href = `${win_loc_replace}?${get_url}` 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) let list = forloop_func_form(data_d,"get",get_url)
data_d = list[0] data_d = list[0]
get_url = list[1] get_url = list[1]
// if (owner_type !== null) { if (owner_type !== null) {
// data_d['owner_type'] = owner_type data_d['owner_type'] = owner_type
// get_url = get_url + `owner_type=${owner_type}` // get_url = get_url + `owner_type=${owner_type}`
// } }
if (weight){ if (weight){
@@ -58,6 +58,7 @@ function ajax_for_filter (data_d,get_url){
document.querySelector(".container_loader_filters_routes").classList.toggle("show") document.querySelector(".container_loader_filters_routes").classList.toggle("show")
} }
$.ajax({ $.ajax({
// headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() }, headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
url: '/routes/find_routes/', url: '/routes/find_routes/',
type: "POST", type: "POST",

View File

@@ -1,31 +1,139 @@
// $(document).ready(function (){ $(document).ready(function (){
// middleWareJS() hide_or_show_new_messages_marker()
// }) checkStateCookie()
})
// window.onfocus = function () { // window.onfocus = function () {
// getSocketState() // getSocketState()
// } // }
window.onload = function (){ window.onload = function (){
changeTopStrMobile()
middleWareJS() 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(){ function middleWareJS(){
let footer = document.querySelector("footer") let footer = document.querySelector("footer")
let body = document.querySelector("body") let body = document.querySelector("body")
let type = getInfoAboutUser() let type = getInfoAboutUser()
if (type !== 'mobile'){ // if (type !== 'mobile'){
if (document.querySelector(".menu_buttons.curtain.left") || window.location.href.includes('support') || window.location.href.includes('chat')){ if (document.querySelector(".menu_buttons.curtain.left") || window.location.href.includes('support') || window.location.href.includes('chat')){
footer.style.display = "none" footer.style.display = "none"
body.style.overflow = "hidden" 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 { } else {
footer.style.display = "" str = `${str} open`
body.style.overflow = "" }
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) { function getTypeOfData (data) {
@@ -34,41 +142,58 @@ function getTypeOfData (data) {
} }
function getInfoAboutUser (){ function getInfoAboutUser (screen_width){
let user_type = '' let user_type = ''
if (screen.width <= 700){ if (screen.width <= 700){
user_type = 'mobile' user_type = 'mobile'
} else if (screen.width > 1024) { } else if (screen.width > 1180) {
user_type = 'desctop' user_type = 'desctop'
} else if (screen.width > 700 && screen.width < 1024) { } else if (screen.width > 700 && screen.width <= 1180) {
user_type = 'laptop' user_type = 'laptop'
} }
return user_type if (screen_width){
return screen.width
} else {
return user_type
}
} }
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
let img = document.getElementById('dropbtn_lang') let img = document.getElementById('dropbtn_lang')
if (window.location.href.indexOf("ru") > -1){ 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.backgroundRepeat = "no-repeat"
img.style.backgroundPosition = "left center" img.style.backgroundPosition = "center"
// img.style.backgroundSize = '50%'
}else if(window.location.href.indexOf("en") > -1){ }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.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', () => { // window.addEventListener('scroll', () => {
// let headerBG = document.getElementById('header_bg') // // let headerBG = document.getElementById('header_bg')
// // //
// headerBG.style.backgroundColor = 'rgb(248 248 248 / 90%)' // // headerBG.style.backgroundColor = 'rgb(248 248 248 / 90%)'
// headerBG.style.padding = '20px 40px' // // headerBG.style.padding = '20px 40px'
// headerBG.style.paddingBottom = 'padding: 10px 40px 10px 40px' // // headerBG.style.paddingBottom = 'padding: 10px 40px 10px 40px'
// headerBG.style.paddingRight = 'padding: 10px 40px 10px 40px' // // headerBG.style.paddingRight = 'padding: 10px 40px 10px 40px'
// headerBG.style.paddingLeft = 'padding: 10px 40px 10px 40px' // // headerBG.style.paddingLeft = 'padding: 10px 40px 10px 40px'
}) // })
// Действия при изменении URL // Действия при изменении 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){ function init_arrival_DT (date=null,single=true,hour=true){
let minDate = null let minDate = null
if (date){ if (date){
@@ -58,6 +104,9 @@ function init_arrival_DT (date=null,single=true,hour=true){
} }
let place_1 = document.querySelector("#id_arrival_DT") let place_1 = document.querySelector("#id_arrival_DT")
if (place_1) { if (place_1) {
$(place_1).daterangepicker({ $(place_1).daterangepicker({
"autoapply": true, "autoapply": true,
"linkedCalendars": false, "linkedCalendars": false,
@@ -65,6 +114,7 @@ function init_arrival_DT (date=null,single=true,hour=true){
"timePicker":hour, "timePicker":hour,
"timePicker24Hour":true, "timePicker24Hour":true,
"minDate":minDate, "minDate":minDate,
"locale": changeLangForDateTimePicker(),
}, },
function (start, end, label) { 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.right`).hide();
$(`${place_1.id} .drp-calendar.left`).addClass('single'); $(`${place_1.id} .drp-calendar.left`).addClass('single');
@@ -108,6 +159,7 @@ function init_departure_DT (){
"singleDatePicker":true, "singleDatePicker":true,
"timePicker":true, "timePicker":true,
"timePicker24Hour":true, "timePicker24Hour":true,
"locale": changeLangForDateTimePicker(),
}, },
function(start, end, label) { function(start, end, label) {
// $('#displayRegervation').text('Registration date is: ' + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD')); // $('#displayRegervation').text('Registration date is: ' + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD'));
@@ -142,6 +194,7 @@ $(function () {
$(place_1).daterangepicker({ $(place_1).daterangepicker({
"autoapply": true, "autoapply": true,
"linkedCalendars": false, "linkedCalendars": false,
"locale": changeLangForDateTimePicker(),
}, },
function (start, end, label) { function (start, end, label) {
@@ -174,6 +227,7 @@ $(function() {
$(place_1).daterangepicker({ $(place_1).daterangepicker({
"autoapply": true, "autoapply": true,
"linkedCalendars": false, "linkedCalendars": false,
"locale": changeLangForDateTimePicker(),
onl_param onl_param
}, },
function(start, end, label) { function(start, end, label) {

View File

@@ -2,6 +2,8 @@ function SendRegistrationForm(el){
event.preventDefault() event.preventDefault()
let form = el.form; let form = el.form;
let formData = new FormData(form); let formData = new FormData(form);
let msr = sessionStorage.getItem('mailingSubscribeRequired')
formData.set('mailingSubscribeRequired',msr)
$.ajax({ $.ajax({
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() }, headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
@@ -15,7 +17,9 @@ function SendRegistrationForm(el){
data: formData, data: formData,
success: function(data){ 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){ error: function (data, exception){
document.querySelector(".register").innerHTML = data.responseJSON.html document.querySelector(".register").innerHTML = data.responseJSON.html

View File

@@ -314,9 +314,6 @@ function searchTown(el){
success: function(data){ success: function(data){
el.style.background = 'white url("/static/img/png/icon-arrow.svg") no-repeat calc(100% - 15px) center'; el.style.background = 'white url("/static/img/png/icon-arrow.svg") no-repeat calc(100% - 15px) center';
loader_place_ins_boris(el,"el") loader_place_ins_boris(el,"el")
if (document.querySelector(".container_form_search_carrier")){
document.querySelector(".container_form_search_carrier").style.zIndex = '10000000000'
}
@@ -351,13 +348,14 @@ function selectItemAddrPoint(id, name, ctrl_name,){
tap_txt_cont.setAttribute('title',name) tap_txt_cont.setAttribute('title',name)
let tap_cont = document.querySelector("#id_" + ctrl_name.slice(0, -4)); let tap_cont = document.querySelector("#id_" + ctrl_name.slice(0, -4));
tap_cont.value = id; 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")){ if (!window.location.href.includes("profile")){
changeWidthEL(tap_txt_cont) changeWidthEL(tap_txt_cont)
} }
input_list.classList.remove('show'); input_list.classList.remove('show');
if (document.querySelector(".container_form_search_carrier")){
document.querySelector(".container_form_search_carrier").style.zIndex = 'unset'
}
} }
@@ -403,25 +401,27 @@ function onblurInputField(event,el){
if(!parent_event || parent_event[0] !== search_list){ if(!parent_event || parent_event[0] !== search_list){
search_list.classList.remove('show') search_list.classList.remove('show')
if (document.querySelector(".container_form_search_carrier")){
document.querySelector(".container_form_search_carrier").style.zIndex = '10000000000'
}
} }
// } // }
} }
function clearID(el) { function clearID(el) {
el.select(); el.select();
if(el.id === 'id_from_address_point_txt'){ if(el.value !== "" && el.id === 'id_from_address_point_txt' ){
document.getElementById('id_from_address_point').value = '' document.getElementById('id_from_address_point').value = ''
} else if(el.id === 'id_to_address_point_txt'){ 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 = '' document.getElementById('id_to_address_point').value = ''
el.value = ''
// el.classList.add('red_text')
} }
} }
@@ -486,58 +486,62 @@ function sendRoute(el, routeID = null){
el.disabled = true el.disabled = true
let list_of_elements_form = document.querySelectorAll(".el_form_b_new_route"); // let list_of_elements_form = document.querySelectorAll(".el_form_b_new_route");
let checked_cargo_type = document.querySelectorAll('.cargo_check'); // 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 form = el.form
let formData = new FormData(form);
let obj_w_el_form = {} let owner_type = owner_type_value
formData.set('owner_type', owner_type)
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 url = '/routes/create_or_change_route/' let url = '/routes/create_or_change_route/'
if (routeID !== null){ if (routeID !== null){
@@ -553,7 +557,8 @@ function sendRoute(el, routeID = null){
processData: false, processData: false,
contentType: false, contentType: false,
// enctype: 'json', // enctype: 'json',
data: JSON.stringify(obj_w_el_form), // data: JSON.stringify(obj_w_el_form),
data: formData,
success: function(data){ success: function(data){
let data_route_id = data.route_id let data_route_id = data.route_id
@@ -575,6 +580,8 @@ function sendRoute(el, routeID = null){
// document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'nearest',inline:'nearest'}); // document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'nearest',inline:'nearest'});
@@ -602,12 +609,20 @@ function sendRoute(el, routeID = null){
function validate(el) { // function validate(el) {
if (el.checked) { // if (el.checked) {
console.log('cheked', el.id); // console.log('cheked', el.id);
} else { // } else {
console.log("You didn't check it! Let me check it for you.", el.id); // 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';
}
} }
@@ -616,9 +631,22 @@ function validate(el) {
//cleaning route inputs after selection changes //cleaning route inputs after selection changes
function OnSelectionChange(el) { function OnSelectionChange(el) {
event.preventDefault() event.preventDefault()
let form = el.form; 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 formData = new FormData(form);
let owner_type = owner_type_value
formData.set('owner_type', owner_type)
// formData.set('owner_type', owner_type)
// let data = {}; // let data = {};
// data['csrfmiddlewaretoken'] = $('input[name="csrfmiddlewaretoken"]')[0].value; // data['csrfmiddlewaretoken'] = $('input[name="csrfmiddlewaretoken"]')[0].value;
@@ -769,6 +797,11 @@ function editRoute(id) {
if(data.html){ if(data.html){
let changeTextButton = document.getElementById('registration') let changeTextButton = document.getElementById('registration')
changeTextButton.innerText = 'Сохранить изменения' changeTextButton.innerText = 'Сохранить изменения'
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
});
} }
init_departure_DT() init_departure_DT()
@@ -826,11 +859,11 @@ function checkDate() {
// alert("End date cannot be less than Start date."); // alert("End date cannot be less than Start date.");
dateArrival.value = "" dateArrival.value = ""
let arrivalDiv = document.getElementById('arrival_div') // let arrivalDiv = document.getElementById('arrival_div')
let errorMessage = document.createElement('span'); // let errorMessage = document.createElement('span');
errorMessage.textContent = "Дата прибытия, не может быть установлена раньше даты отправки" // // errorMessage.textContent = "Дата прибытия, не может быть установлена раньше даты отправки"
errorMessage.classList.add('errorlist') // errorMessage.classList.add('errorlist')
arrivalDiv.appendChild(errorMessage); // arrivalDiv.appendChild(errorMessage);
} }
else if (DateEnd > DateStart){ else if (DateEnd > DateStart){
let arrivalDiv = document.getElementById('arrival_div'); let arrivalDiv = document.getElementById('arrival_div');
@@ -955,36 +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) { function hideErrors(el) {
let error_feeedback_text = document.getElementById('error_feedback_text') let error_feeedback_text = document.getElementById('error_feedback_text')
let error_feeedback = el.nextElementSibling let error_feeedback = el.nextElementSibling
let counter_text = document.querySelector('.counter-text') let counter_text = document.querySelector('.counter-text')
let footer_button = document.getElementById('footer_input_button') let footer_button = document.getElementById('footer_input_button')
let error_footer = document.getElementById('error_footer') let error_footer = document.getElementById('error_footer')
let agree_error = document.getElementById('reg_agree_error') 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')
if(error_feeedback === counter_text && error_feeedback !== null && error_feeedback_text !== null ){ let error_from_address_point = document.getElementById('error_from_address_point')
error_feeedback_text.classList.add('hide') let error_to_address_point = document.getElementById('error_to_address_point')
} else if(error_feeedback === footer_button && error_footer !== null ){ let error_cargo_type = document.getElementById('error_cargo_type')
error_footer.classList.add('hide') let error_id_phone = document.getElementById('error_id_phone')
} else if(error_feeedback !== null) {
error_feeedback.classList.add('hide')
} else if(el.id === 'agreement_check'){
agree_error.classList.add('hide')
}
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){ else if(error_feeedback !== null) {
// errorFeeedback.classList.add('hide') error_feeedback.classList.add('hide')
// } }
} }

View File

@@ -25,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%;"/>' document.querySelector(".info_profile").innerHTML = '<img src="/static/img/svg/loader.svg" style="height: 30px;position: absolute;top: 47%;left: 45%;"/>'
} }
$.ajax({ $.ajax({
// headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() }, headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
url: confirm_url, url: confirm_url,
type: "POST", type: "POST",
@@ -45,13 +46,13 @@ function select_tab_profile (el,url,owner_type=null) {
let confirm_url_f_lang_ru = '' let confirm_url_f_lang_ru = ''
let confirm_url_f_lang_en = '' let confirm_url_f_lang_en = ''
if (owner_type){ 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'}`) 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}`)}/?mobile=${getInfoAboutUser() === 'mobile'}` 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}`)}/?mobile=${getInfoAboutUser() === 'mobile'}` confirm_url_f_lang_en = `/en/profile/page/${profile_tabs_f_static_map.get(`${url}_${owner_type}`)}/`
} else { } else {
window.history.pushState(null, null, `/${document.documentElement.lang}/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)}/?mobile=${getInfoAboutUser() === 'mobile'}` 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)}/?mobile=${getInfoAboutUser() === 'mobile'}` 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("#ru_lang").href = confirm_url_f_lang_ru
document.querySelector("#en_lang").href = confirm_url_f_lang_en document.querySelector("#en_lang").href = confirm_url_f_lang_en
@@ -83,6 +84,18 @@ function select_tab_profile (el,url,owner_type=null) {
selectTabProfileIfHisNotSelected(url) selectTabProfileIfHisNotSelected(url)
} }
deleteMarkerMessages(el) 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){ error: function (data){
console.log(data) console.log(data)
@@ -91,16 +104,37 @@ function select_tab_profile (el,url,owner_type=null) {
}); });
} }
function deleteMarkerMessages (el) { function checkStatesAfterTransitionToAnotherTabProfile () {
let marker = el.querySelectorAll(".icon_unread_messages") // check which page if profile - do
if (marker.length > 0){ if (window.location.href.includes('profile')){
marker[0].classList.remove("showed") // if curtain open we need to close, so we'il see content without curtain
if (marker[1]){ if (document.querySelector(".menu_buttons.curtain.right.open")){
marker[1].classList.remove("showed") 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) { function selectTabProfileIfHisNotSelected (url) {
if (url !== 'new_route_view') { if (url !== 'new_route_view') {
let el_f_select = document.querySelector(`[data-ajax-url=${url}]`) let el_f_select = document.querySelector(`[data-ajax-url=${url}]`)
@@ -116,7 +150,7 @@ function clickONTHEAPROfileBTN (el) {
function changeHrefCl (el) { function changeHrefCl (el) {
let dataset = el.dataset let dataset = el.dataset
let old_href = dataset['href'] let old_href = dataset['href']
let new_href = old_href + `?mobile=${getInfoAboutUser() === 'mobile'}` let new_href = old_href
el.setAttribute('href',new_href) el.setAttribute('href',new_href)
} }
@@ -367,25 +401,26 @@ async function attachFilemeassge (el,id_ticket=null,sender=null,receiver=null,ch
function change_profile_confirm (el){ function change_profile_confirm (el){
event.preventDefault() event.preventDefault()
let form = el.form let form = el.form
let changed_elements = {} let formData = new FormData(form);
for (let i = 0;i < form.length;i++){ // let changed_elements = {}
let cur_el = form[i] // for (let i = 0;i < form.length;i++){
if (cur_el.localName !== 'button'){ // let cur_el = form[i]
let new_val = cur_el.value // if (cur_el.localName !== 'button'){
let dataset = cur_el.dataset // let new_val = cur_el.value
let old_val = '' // let dataset = cur_el.dataset
if (dataset){ // let old_val = ''
old_val = dataset['initialValue'] // if (dataset){
} // old_val = dataset['initialValue']
// if (old_val){ // }
if (old_val === new_val){ // // if (old_val){
// // if (old_val === new_val){
} else { // //
changed_elements[cur_el.name] = cur_el.value // } else {
} // changed_elements[cur_el.name] = cur_el.value
} // }
// } // }
} // // }
// }
$.ajax({ $.ajax({
@@ -397,16 +432,23 @@ function change_profile_confirm (el){
processData: false, processData: false,
contentType: false, contentType: false,
// enctype: 'json', // enctype: 'json',
data: JSON.stringify(changed_elements), // data: JSON.stringify(changed_elements),
data: formData,
success: function(data){ success: function(data){
middleWareJS() middleWareJS()
document.querySelector(".info_profile").innerHTML = data.html; 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){ 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;
} }
}); });
@@ -437,8 +479,8 @@ async function upload_photo_f_profile (el,files) {
}, },
error: function (data){ error: function (data){
document.querySelector(".avatar_user_profile").innerHTML = data.responseJSON.html; alert(data.responseJSON.error);
el.value = ''
} }
}); });
// } // }
@@ -502,9 +544,9 @@ function selectedUserMessenger (ticket_id=null,user_id=null,el){
url = 'show_chat_w_user/' url = 'show_chat_w_user/'
} }
let user_type = getInfoAboutUser() let user_type = getInfoAboutUser()
if (user_type === 'mobile' || user_type === 'laptop') { // if (user_type === 'mobile' || user_type === 'laptop') {
open_curtain_w_contacts() // open_curtain_w_contacts()
} // }
data['mobile'] = getInfoAboutUser() === 'mobile' || getInfoAboutUser() === 'laptop' data['mobile'] = getInfoAboutUser() === 'mobile' || getInfoAboutUser() === 'laptop'
$.ajax({ $.ajax({
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() }, headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
@@ -524,8 +566,27 @@ function selectedUserMessenger (ticket_id=null,user_id=null,el){
// let left_curtain = document.querySelector('.curtain.left') // let left_curtain = document.querySelector('.curtain.left')
document.querySelector(".info_profile").innerHTML = data.html; document.querySelector(".info_profile").innerHTML = data.html;
document.querySelector(".enter-message-inp").focus() 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'){ // if (window.location.host.includes('support') && user_type !== 'mobile' && user_type !== 'laptop'){
// let menu = document.querySelector(".menu_buttons.curtain.left") // let menu = document.querySelector(".menu_buttons.curtain.left")
// let container_user_messenger = document.querySelector(".container-messenger") // let container_user_messenger = document.querySelector(".container-messenger")
@@ -536,8 +597,8 @@ function selectedUserMessenger (ticket_id=null,user_id=null,el){
// } // }
// check state
checkStateAfterChooseContact()
}, },
error: function (data){ error: function (data){
@@ -549,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){ function sendMessage(id_ticket=null,sender,receiver,files=null){
// import {sendMessageSocket} from "./chat_sockets"; // import {sendMessageSocket} from "./chat_sockets";
if (!files){ if (!files){
@@ -720,6 +792,7 @@ function open_curtain_w_btn_profile () {
last_open_curtain = curtain last_open_curtain = curtain
set_curtain_z_index(curtain) set_curtain_z_index(curtain)
close_first_curt(curtain) close_first_curt(curtain)
checkStateCurtain(curtain)
// delete_margin_in_mobile() // delete_margin_in_mobile()
} else if (!window.location.href.includes("profile")){ } else if (!window.location.href.includes("profile")){
curtain.classList.toggle("open") curtain.classList.toggle("open")
@@ -731,15 +804,38 @@ function open_curtain_w_btn_profile () {
last_open_curtain = curtain last_open_curtain = curtain
set_curtain_z_index(curtain) set_curtain_z_index(curtain)
close_first_curt(curtain) close_first_curt(curtain)
// delete_margin_in_mobile() // 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 () { function open_curtain_w_contacts () {
let curtain = document.querySelector('.menu_buttons.left') let curtain = document.querySelector('.menu_buttons.left')
let btn_handler_left_curtain = document.querySelector(".handler_curtain_left")
let user_type = getInfoAboutUser() 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) 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('open')
curtain.classList.toggle('close') curtain.classList.toggle('close')
if (curtain.classList.contains('first')) { if (curtain.classList.contains('first')) {
@@ -753,6 +849,14 @@ function open_curtain_w_contacts () {
close_first_curt(curtain) close_first_curt(curtain)
// delete_margin_in_mobile() // delete_margin_in_mobile()
} else if (!window.location.href.includes("profile")){ } 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) open_overlay(curtain)
curtain.classList.toggle('open') curtain.classList.toggle('open')
curtain.classList.toggle('close') curtain.classList.toggle('close')
@@ -765,6 +869,7 @@ function open_curtain_w_contacts () {
set_curtain_z_index(curtain) set_curtain_z_index(curtain)
last_open_curtain = curtain last_open_curtain = curtain
close_first_curt(curtain) close_first_curt(curtain)
checkStateCurtain(curtain)
// delete_margin_in_mobile() // delete_margin_in_mobile()
} }
} }
@@ -819,7 +924,13 @@ function close_first_curt (curtain) {
if (cur_el !== curtain){ if (cur_el !== curtain){
cur_el.classList.toggle('open') cur_el.classList.toggle('open')
cur_el.classList.toggle('close') 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++ i++
}) })
@@ -834,9 +945,17 @@ function set_curtain_z_index (curtain) {
curtains.forEach(function (){ curtains.forEach(function (){
let cur_el = curtains[i] let cur_el = curtains[i]
if (cur_el === curtain){ 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.style.zIndex = 101
cur_el.parentNode.style.zIndex = 101 cur_el.parentNode.style.zIndex = 101
} else { } 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.style.zIndex = 99
cur_el.parentNode.style.zIndex = 99 cur_el.parentNode.style.zIndex = 99
} }
@@ -846,7 +965,14 @@ function set_curtain_z_index (curtain) {
} }
function close_open_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') let curtains = document.querySelectorAll('.curtain.open')
if (curtains.length >= 2) { if (curtains.length >= 2) {
if (last_open_curtain) { if (last_open_curtain) {
@@ -908,7 +1034,7 @@ function show_header_list () {
// } else if (right){ // } else if (right){
// let right = document.querySelector(".curtain.right") // let right = document.querySelector(".curtain.right")
// open_curtain(null,right,null,'close') // open_curtain(null,right,null,'close')
// } else { // } else {`
// let curtain = getOpenCurtain() // let curtain = getOpenCurtain()
// if (curtain) { // if (curtain) {
// open_curtain(null, null, null, 'close') // 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="not_found_routes show">
<div class="text-align-center fw-700 font-large c-txt-b2 m-a w-80 m-t-8p"> <div class="text-align-center fw-700 font-large c-txt-b2 m-a w-80 m-t-8p">
{% blocktranslate %} {% blocktranslate %}
Упс... <span class="orange-text">Ничего не найдено</span>, попробуйте Упс... <span class="orange-text">Ничего не найдено</span>, попробуйте
изменить параметры поиска изменить параметры поиска <span class="orange-text"> или создайте своё собственное объявление </span>
{% endblocktranslate %} {% 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> </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 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" %}"> <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="first-column">
<div class="footer_logo"><img class="svg" src="/static/img/svg/LogoWhite.svg"></div> <div class="footer_logo"><img class="svg" src="/static/img/svg/LogoWhite.svg"></div>
<div> <div>
<div class="footer_text_sub">{% trans "Подпишись и будь в курсе всех событий, а также получай подарки и бонусы от Trip With Bonus" %}</div> {% if not user.user_profile.mailing_on %}
<div class="insert_form"> <div class="footer_text_sub">{% trans "Подпишись и будь в курсе всех событий, а также получай подарки и бонусы от Trip With Bonus" %}</div>
{% include "forms/f_one_field_form.html" %} <div class="insert_form">
</div> {% include "forms/f_one_field_form.html" %}
</div>
{% endif %}
</div> </div>
@@ -46,9 +47,9 @@
<div class="four-column"> <div class="four-column">
<div class="footer_text_inform">{% trans "Свяжитесь с нами:" %}</div> <div class="footer_text_inform">{% trans "Свяжитесь с нами:" %}</div>
<div class="footer_text_contact"> <div class="footer_text_contact">
<div> {# <div>#}
<a href="tel:+77777777777">+ 7 (777) 777-77-77</a> {# <a href="tel:+77777777777">+ 7 (777) 777-77-77</a>#}
</div> {# </div>#}
<div> <div>
<a href="mailto:sales@tripwb.com">sales@tripwb.com</a> <a href="mailto:sales@tripwb.com">sales@tripwb.com</a>
</div> </div>

View File

@@ -6,10 +6,13 @@
<div class="wrapper_header_content"> <div class="wrapper_header_content">
<div class="header-first"> <div class="header-first">
<div class="header_logo"> <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>
<div class="header_logo_mobile"> <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>
<div class="dropdown"> <div class="dropdown">
@@ -20,8 +23,8 @@
> >
<a href="/">{% trans "Главная" %}</a> <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" "about_service" %}">{% trans "" %}О Trip With Bonus</a>
<a href="{% url 'static_page' 'contacts' %}">{% trans "Контакты" %}</a> <a href="{% url 'static_page' 'contacts' %}">{% trans "Контакты" %}</a>
<a href="{% url 'static_page' 'advertisement' %}">{% trans "Реклама" %}</a> <a href="{% url 'static_page' 'advertisement' %}">{% trans "Реклама" %}</a>
@@ -52,7 +55,7 @@
</div> </div>
</div> </div>
<div class="header-second-item"> <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>
<div class="header-second-item"> <div class="header-second-item">
<a id="customer_service" href="{% url 'static_page' 'customer_service' %}">{% trans "Служба поддержки" %}</a> <a id="customer_service" href="{% url 'static_page' 'customer_service' %}">{% trans "Служба поддержки" %}</a>
@@ -66,7 +69,7 @@
{# <div class="button_profile_header" onclick="open_curtain(null,'right')" data-user-id="{{ user.id }}">#} {# <div class="button_profile_header" onclick="open_curtain(null,'right')" data-user-id="{{ user.id }}">#}
<span class="btn_profile_name"> <span class="btn_profile_name">
{{ user.first_name }} {{ user.last_name }} {{ user.first_name|truncatechars:6}} {{ user.last_name|truncatechars:5 }}
</span> </span>
<span id="placeholder1"></span> <span id="placeholder1"></span>
<div class="icon_unread_messages" style="position:relative;top: 4px;padding-right: 13px;"> <div class="icon_unread_messages" style="position:relative;top: 4px;padding-right: 13px;">
@@ -76,7 +79,12 @@
</div> </div>
</div> </div>
<div class="button_profile_header_mobile" onclick="open_curtain_w_btn_profile()"> <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=""> <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>
{# <div class="menu_profile_btn">#} {# <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 %}#} {# {% 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="button_profile_header_mobile" onclick="show_header_list()">
<div class="marker_messages_mobile hide"></div>
<img src="/static/img/svg/userMobile.svg" alt=""> <img src="/static/img/svg/userMobile.svg" alt="">
</div> </div>

View File

@@ -9,7 +9,7 @@
{%trans "Написать сообщение" as t_chats %} {%trans "Написать сообщение" as t_chats %}
{%trans "Тех. поддержка" as t_support %} {%trans "Тех. поддержка" as t_support %}
{%trans "Моя подписка" as t_subscribe %} {%trans "Моя подписка" as t_subscribe %}
{%trans "Мой профиль" as t_change_profile %} {%trans "Изменить профиль" as t_change_profile %}
{%trans "Выход" as t_logout %} {%trans "Выход" as t_logout %}
<div class="menu_profile {% if not page_type == 'profile' %}background{% endif %}"> <div class="menu_profile {% if not page_type == 'profile' %}background{% endif %}">

View File

@@ -7,11 +7,18 @@
<div class="container_block_list_of_users"> <div class="container_block_list_of_users">
{% include 'blocks/profile/b_list_of_users_messenger.html' %} {% include 'blocks/profile/b_list_of_users_messenger.html' %}
</div> </div>
<div class="handler_menu close" onclick="open_curtain_w_contacts()"> {# <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' %}"> {# <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> {# <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' %}"> {# <img class="btns_f_curtain close right" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
<div class="clear_both"></div> {# <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> </div>
{#<div class="title-profile-cont">#} {#<div class="title-profile-cont">#}
@@ -65,11 +72,13 @@
<span class="chat-username">{{ cur_receiver.last_name }} {{ cur_receiver.first_name }}</span> <span class="chat-username">{{ cur_receiver.last_name }} {{ cur_receiver.first_name }}</span>
</div> </div>
<div class="header-chat-right-part"> <div class="header-chat-right-part">
<img class="header-icons-right-part-padding" src="{% static "img/svg/phone.svg" %}"> <a href="tel:{{ cur_receiver.user_profile.phone }}">
<img class="header-icons-right-part-padding" src="{% static "img/svg/info.svg" %}"> <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> </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" > <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" %} {% include "blocks/profile/b_messages_container.html" %}
</div> </div>
@@ -88,7 +97,7 @@
{# <button class="send-message" onclick="send_ws_msg('message')"></button>#} {# <button class="send-message" onclick="send_ws_msg('message')"></button>#}
</div> </div>
</div> </div>
</div> {# </div>#}
</div> </div>
{% endif %} {% endif %}

View File

@@ -6,7 +6,7 @@
{%trans "Тема запроса" as p_create_ticket %} {%trans "Тема запроса" as p_create_ticket %}
<form class="form-create-ticket" name="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 %} {% csrf_token %}
<div class="container-input-form-create-ticket"> <div class="container-input-form-create-ticket">

View File

@@ -1,5 +1,5 @@
{% load static %} {% load static %}
{% load tz %}
{#{% include "widgets/w_file.html" %}#} {#{% include "widgets/w_file.html" %}#}
{% if not messages and ticket %} {% if not messages and ticket %}
@@ -8,7 +8,9 @@
{% for msg in messages %} {% for msg in messages %}
{% include "widgets/w_message.html" %} {% include "widgets/w_message.html" %}
{% if forloop.first %} {% 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 %} {% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}

View File

@@ -32,7 +32,7 @@
{# </div>#} {# </div>#}
{# <label for="id_type_transport">{% translate "Выберите способ перевозки" %}</label>#}
<select <select
onchange="OnSelectionChange(this)" onchange="OnSelectionChange(this)"
name="type_transport" name="type_transport"
@@ -56,11 +56,32 @@
{% endif %} {% endif %}
</div> </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 != '' %} {% if form.initial and form.initial.type_transport and form.initial.type_transport != '' %}
<hr> <hr>
<div class="departure_arrival"> <div class="departure_arrival">
<div class="wrap_left"> <div class="wrap_left">
<label for="id_departure_DT">{% if form.initial.type_transport == 'road' %}Дата и время выезда{% elif form.initial.type_transport == 'avia' %}Дата и время вылета{% endif %}</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#} {# <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 %}#} {# {% 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 #} {# 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> <div id="displayRegervation"></div>
{% if not errors_off and form.errors and form.errors.departure_DT %} {% 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 %} {% endif %}
</div> </div>
<div id="arrival_div"> <div id="arrival_div">
<label for="id_arrival_DT">Дата и время прибытия</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#} {# <input#}
{# type="datetime-local"#} {# type="datetime-local"#}
{# min= {% now "Y-m-d" %}T{% now "H:i" %}#} {# 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 %}#} {# {% 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 #} {# 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> <div id="displayRegervation"></div>
{# end #} {# end #}
{% if not errors_off and form.errors and form.errors.arrival_DT %} {% 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 %} {% endif %}
</div> </div>
<div class="clear_both"></div> <div class="clear_both"></div>
@@ -109,7 +155,15 @@
<hr> <hr>
<div class="from_to_country"> <div class="from_to_country">
<div class="from_country_container"> <div class="from_country_container">
<label for="id_from_address_point_txt">{% if form.initial.type_transport == 'avia' %}Пункт вылета{% elif form.initial.type_transport == 'road' %}Пункт выезда{% endif %}</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 <input
type="number" type="number"
name="from_address_point" name="from_address_point"
@@ -123,10 +177,10 @@
onclick="showSearchList(this)" onclick="showSearchList(this)"
onblur="onblurInputField(event, this)" onblur="onblurInputField(event, this)"
onfocus="clearID(this)" onfocus="clearID(this)"
onkeydown = "hideErrors(this)"
autocomplete="off" autocomplete="off"
type="text" type="text"
minlength="3" minlength="3"
name="from_address_point_txt" name="from_address_point_txt"
class="from_address_point_txt post_route el_form_b_new_route" class="from_address_point_txt post_route el_form_b_new_route"
{% if form.fields.from_address_point.required %} required{% endif %} {% if form.fields.from_address_point.required %} required{% endif %}
@@ -142,11 +196,19 @@
</div> </div>
{% if not errors_off and form.errors and form.errors.from_address_point %} {% 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 %} {% endif %}
</div> </div>
<div class="wrap_right"> <div class="wrap_right">
<label for="id_to_address_point_txt">{% if form.initial.type_transport == 'avia' %}Пункт прилета{% elif form.initial.type_transport == 'road' %}Пункт приезда{% endif %}</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 <input
type="number" type="number"
name="to_address_point" name="to_address_point"
@@ -159,7 +221,7 @@
oninput="searchTown(this)" oninput="searchTown(this)"
onclick="showSearchList(this)" onclick="showSearchList(this)"
onblur="onblurInputField(event, this)" onblur="onblurInputField(event, this)"
onkeydown = "hideErrors(this)"
onfocus="clearID(this)" onfocus="clearID(this)"
autocomplete="off" autocomplete="off"
type="text" type="text"
@@ -175,7 +237,7 @@
</div> </div>
{% if not errors_off and form.errors and form.errors.to_address_point %} {% 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 %} {% endif %}
</div> </div>
<div class="clear_both"></div> <div class="clear_both"></div>
@@ -191,7 +253,13 @@
{# </div>#} {# </div>#}
<div class="from_to_place"> <div class="from_to_place">
<div class="wrap_left"> <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 <select
class="custom_select el_form_b_new_route" class="custom_select el_form_b_new_route"
name="from_place" name="from_place"
@@ -210,7 +278,13 @@
{% endif %} {% endif %}
</div> </div>
<div class="wrap_right"> <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 <select
name="to_place" name="to_place"
id="id_to_place" id="id_to_place"
@@ -233,7 +307,12 @@
<hr> <hr>
<div> <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> </div>
@@ -248,6 +327,7 @@
class="custom-checkbox cargo_check" class="custom-checkbox cargo_check"
type="radio" type="radio"
name="cargo_type" name="cargo_type"
id="id_cargo_type_{{ forloop.counter }}" id="id_cargo_type_{{ forloop.counter }}"
{% if form.fields.cargo_type.required %} required{% endif %} {% if form.fields.cargo_type.required %} required{% endif %}
value="{{ item.0 }}" value="{{ item.0 }}"
@@ -257,7 +337,8 @@
/> />
<label <label
onmousedown="hideErrors(this)"
id="id_cargo_lable"
for="id_cargo_type_{{ forloop.counter }}" > for="id_cargo_type_{{ forloop.counter }}" >
<span>{{ item.1 }}</span> <span>{{ item.1 }}</span>
</label> </label>
@@ -266,7 +347,7 @@
{% if not errors_off and form.errors and form.errors.cargo_type %} {% 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 %} {% endif %}
</div> </div>
@@ -316,6 +397,7 @@
<input <input
type="phone" type="phone"
name="phone" name="phone"
onkeydown="hideErrors(this)"
autocomplete="off" autocomplete="off"
maxlength="13" maxlength="13"
minlength="11" minlength="11"
@@ -327,7 +409,7 @@
/> />
{% if not errors_off and form.errors and form.errors.phone %} {% 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 %} {% endif %}
</div> </div>
@@ -357,7 +439,13 @@
<div> <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"> <label for="id_receive_msg_by_email">
<div class="receive_msg_by_email">{{ form.fields.receive_msg_by_email.label }}</div> <div class="receive_msg_by_email">{{ form.fields.receive_msg_by_email.label }}</div>

View File

@@ -35,12 +35,12 @@
{% if profileForm.errors.lastname %}<div class="error_form_profile">{{ profileForm.errors.lastname }}</div>{% endif %} {% if profileForm.errors.lastname %}<div class="error_form_profile">{{ profileForm.errors.lastname }}</div>{% endif %}
</div> </div>
<div class="container_el_form_profile"> <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 %}> <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>
<div class="container_el_form_profile"> <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> <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 %}> <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 %} {% if profileForm.errors.email %}<div class="error_form_profile">{{ profileForm.errors.email }}</div>{% endif %}
</div> </div>
@@ -58,14 +58,23 @@
<div class="line_f_form_profile"></div> <div class="line_f_form_profile"></div>
<div class="container_el_form_profile"> <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 %}> <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>
<div class="container_el_form_profile"> <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 %}> <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> </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> </div>
</form> </form>

View File

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

View File

@@ -13,15 +13,32 @@
{# <h1>Техническая поддержка</h1>#} {# <h1>Техническая поддержка</h1>#}
{# </div>#} {# </div>#}
{% if user.is_staff or staff %} {% 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"> <div class="container_block_list_of_users">
{% include 'blocks/profile/b_list_of_tickets_support_chat.html' %} {% include 'blocks/profile/b_list_of_tickets_support_chat.html' %}
</div> </div>
<div class="handler_menu close" onclick="open_curtain_w_contacts()"> {# <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' %}"> {# <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> {# <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' %}"> {# <img class="btns_f_curtain close right" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
<div class="clear_both"></div> {# <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>
</div> </div>
{% endif %} {% endif %}
@@ -62,13 +79,13 @@
{# {% endfor %}#} {# {% endfor %}#}
{# {% endif %}#} {# {% endif %}#}
{# </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='{{ ticket.id }}'> <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" %} {% include "blocks/profile/b_messages_container.html" %}
</div> </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"> <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 }}"> <input class="enter-message-inp" onfocus="check_new_messages_timeout()" onkeypress="sendMessageEnter(event,{{ ticket.id }},{{ user.id }},{{ cur_receiver.id }})" placeholder="{{ p_send_msg }}">
@@ -86,9 +103,10 @@
{# <button class="send-message" onclick="send_ws_msg('message')"></button>#} {# <button class="send-message" onclick="send_ws_msg('message')"></button>#}
</div> </div>
</div> </div>
</div> {# </div>#}
</div> </div>
<div class="clear_both"></div>
{% endif %} {% endif %}
</div> </div>

View File

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

View File

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

View File

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

View File

@@ -18,7 +18,7 @@
<div class="text_wrapper"> <div class="text_wrapper">
<span>{% translate "Trip With Bonus- это сервис, который соединяет отправителя посылки и перевозчика." %}</span> <span>{% translate "Trip With Bonus- это сервис, который соединяет отправителя посылки и перевозчика." %}</span>
<span>{% translate "Вы можете разместить объявление о перевозке посылки и перевозчики со всего мира откликнуться на ваше объявление или воспользовавшись поиском на сайте найти перевозчика, который будет готов взять Вашу посылку и доставить в указанное место авто- или авива транспортом." %}</span> <span>{% translate "Вы можете разместить объявление о перевозке посылки и перевозчики со всего мира откликнутся на ваше объявление или воспользовавшись поиском на сайте найти перевозчика, который будет готов взять Вашу посылку и доставить в указанное место наземным или авиатранспортом." %}</span>
<span>{% translate "Если же Вы часто путешествуете или в разъездах, Вы можете самостоятельно перевозить посылки и при этом получать бонусы и благодарности." %}</span> <span>{% translate "Если же Вы часто путешествуете или в разъездах, Вы можете самостоятельно перевозить посылки и при этом получать бонусы и благодарности." %}</span>
</div> </div>

View File

@@ -36,7 +36,9 @@
</div> </div>
<div class="button_container"> <div class="button_container">
<button id="more_button">{% translate "Перевезти посылку" %}</button> <button id="send_parcel_button">
{% translate "Перевезти посылку" %}
</button>
</div> </div>

View File

@@ -27,7 +27,7 @@
onkeydown = "hideErrors(this)" onkeydown = "hideErrors(this)"
placeholder="{% translate 'Телефон' %}"{% if form.phone %} value="{{ form.phone }}"{% endif %}> placeholder="{% translate 'Телефон' %}"{% if form.phone %} value="{{ form.phone }}"{% endif %}>
{% if form.errors.phone %} {% if form.errors.phone %}
<span id="error_com_offer">{{ form.errors.phone }}</span> <span id="error_com_offer">{{ form.errors.phone|safe }}</span>
{% endif %} {% endif %}
</div> </div>

View File

@@ -42,7 +42,7 @@
onkeydown ="hideErrors(this)" onkeydown ="hideErrors(this)"
placeholder="{% translate 'Телефон' %}"{% if form.phone %} value="{{ form.phone }}"{% endif %}> placeholder="{% translate 'Телефон' %}"{% if form.phone %} value="{{ form.phone }}"{% endif %}>
{% if form.errors.phone %} {% if form.errors.phone %}
<span id="error_feedback">{{ form.errors.phone }}</span> <span id="error_feedback">{{ form.errors.phone|safe }}</span>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@@ -34,9 +34,13 @@
{% if route_form.initial.from_address_point_txt %}value="{{ route_form.initial.from_address_point_txt }}"{% endif %} {% if route_form.initial.from_address_point_txt %}value="{{ route_form.initial.from_address_point_txt }}"{% endif %}
/> />
<div id="abbreviation_airport_in_search" onclick="focusOnInput(this)" class="abbreviation_airport_in_search {% if route_form.initial.from_address_point_txt %}hide{% endif %}"></div> <div id="abbreviation_airport_in_search" onclick="focusOnInput(this)" class="abbreviation_airport_in_search {% if route_form.initial.from_address_point_txt %}hide{% endif %}"></div>
<div class="input_list find_route" name="from_address_point_txt_list"> <div class="input_list find_route" name="from_address_point_txt_list">
</div> </div>
</div> </div>
</div> </div>
<div class="cont-el-form-search-carrier"> <div class="cont-el-form-search-carrier">
@@ -88,7 +92,7 @@
<div id="displayRegervation"></div> <div id="displayRegervation"></div>
</div> </div>
<div class="cont-el-form-search-carrier last"> <div class="cont-el-form-search-carrier last">
<label>test</label> <label for ="id_cargo_type">{% translate "Тип груза" %}</label>
<select class="custom_select el_form_find_route" name="cargo_type" id="id_cargo_type" {% if route_form.fields.cargo_type.required %} {% endif %}> <select class="custom_select el_form_find_route" name="cargo_type" id="id_cargo_type" {% if route_form.fields.cargo_type.required %} {% endif %}>
<option value="" selected="selected">{% translate "не имеет значения" %}</option> <option value="" selected="selected">{% translate "не имеет значения" %}</option>
{% for item in route_form.fields.cargo_type.choices %} {% for item in route_form.fields.cargo_type.choices %}
@@ -101,7 +105,7 @@
<div class="cont-el-form-search-carrier el_form_find_route"> <div class="cont-el-form-search-carrier el_form_find_route">
<label style="opacity: 0">test</label> <label style="opacity: 0">test</label>
{% if show_filter_and_results %} {% if show_filter_and_results %}
<button class="btn_find_routes" onclick="filters_func_find_route_main(this)" data-owner_type='{{ owner_type }}'>{% translate "Найти" %}</button> <button class="btn_find_routes" onclick="filters_func_find_route_main(this,'{{ owner_type }}')" data-owner_type='{{ owner_type }}'>{% translate "Найти" %}</button>
{% else %} {% else %}
<button class="btn_find_routes" onclick="filters_func_find_route_main(this,'{{ owner_type }}','{% url "route_search_results_View" %}')" data-owner_type='{{ owner_type }}'>{% translate "Найти" %}</button> <button class="btn_find_routes" onclick="filters_func_find_route_main(this,'{{ owner_type }}','{% url "route_search_results_View" %}')" data-owner_type='{{ owner_type }}'>{% translate "Найти" %}</button>
{% endif %} {% endif %}

View File

@@ -1,12 +1,13 @@
{% load i18n %} {% load i18n %}
{% load socialaccount %}
{% trans "Логин" as p_login %} {% trans "Логин" as p_login %}
{% trans "Пароль" as p_password %} {% trans "Пароль" as p_password %}
<section class="login"> <section class="login">
<h1>{% translate "Войдите в профиль" %}</h1> <h1>{% translate "Войдите в профиль" %}</h1>
<form class="login_form" name="login_form" method="post"> <form class="login_form" name="login_form" method="post">
{% csrf_token %} {% csrf_token %}
<div> <div>
{% if form.errors.all__ %} {% if form.errors.all__ %}
@@ -16,7 +17,14 @@
{% endif %} {% endif %}
<div class="inputs_l"> <div class="inputs_l">
<input name="username" type="text" placeholder="{{ p_login }}" {% if form.data.username %} value="{{ form.data.username }}"{% endif %}> <input
name="username"
type="text"
placeholder="{{ p_login }}"
{% if form.data.username %} value="{{ form.data.username }}"{% endif %}
id="login_email_input"
>
{% if form.username and form.errors.username %} {% if form.username and form.errors.username %}
<span>{{ form.errors.username }}</span> <span>{{ form.errors.username }}</span>
{% endif %} {% endif %}
@@ -29,10 +37,17 @@
</div> </div>
<div class="button_register"><button onclick="SendLoginForm(this)">{% translate "Войти" %}</button></div> <div class="button_register"><button onclick="SendLoginForm(this)">{% translate "Войти" %}</button></div>
<div class="agree_text_l">{% translate "Авторизуясь, вы соглашаетесь с Лицензионным соглашением Политикой конфиденциальности" %}</div> <div class="agree_text_l">{% translate "Авторизуясь, вы соглашаетесь с Лицензионным соглашением Политикой конфиденциальности" %}</div>
{# <div>Или</div>#}
{# <div id = "google_text" class="google"><img src="/static/img/png/google.png" alt="">#} {% if auth_google_allow %}
{# <div>Войти через Google</div>#} <div id="reg_or_text">{% translate "Или" %}</div>
{# </div>#}
<a href="{% provider_login_url 'google' %}">
<div id = "google_text" class="google"><img src="/static/img/png/google.png" alt="">
<div> {% translate "Войти через" %} Google</div>
</div>
</a>
{% endif %}
<div class="call_to_reg">{% translate "Нет аккаунта?" %} <a href="/ru/profile/registration/">{% translate "Зарегистрируйтесь" %}</a></div> <div class="call_to_reg">{% translate "Нет аккаунта?" %} <a href="/ru/profile/registration/">{% translate "Зарегистрируйтесь" %}</a></div>
</div> </div>
</form> </form>

View File

@@ -7,14 +7,20 @@
data-name="msg_from_footer" data-name="msg_from_footer"
{% if form.form_name %}data-name="{{ form.form_name}}"{% endif %} {% if form.form_name %}data-name="{{ form.form_name}}"{% endif %}
> >
<div class="footer_input_wrap"> <div
onclick="event.stopPropagation()"
class="footer_input_wrap">
<input class="footer_input" <input class="footer_input"
name="email" name="email"
type="email" type="email"
{% if user.is_authenticated %}
readonly
value="{{ user.email }}"
{% endif %}
onkeydown = "hideErrors(this)" onkeydown = "hideErrors(this)"
{% if form.data.email %} value="{{ form.data.email }}"{% endif %} {% if form.data.email %} value="{{ form.data.email }}"{% endif %}
placeholder="{% trans "Введите ваш e-mail" %}"> placeholder="{% trans "Введите ваш e-mail" %}">
<button onclick="RequestCommercialOffer(this)" id="footer_input_button"> <button onclick="subscribeNewsletter(this)" id="footer_input_button">
<img class="svg" src="/static/img/svg/CaretCircleRight.svg"> <img class="svg" src="/static/img/svg/CaretCircleRight.svg">
</button> </button>

View File

@@ -47,6 +47,7 @@
onkeydown = "hideErrors(this)" onkeydown = "hideErrors(this)"
type="text" type="text"
placeholder="E-mail" placeholder="E-mail"
id="registration_email_input"
{% if form.data.email %} value="{{ form.data.email }}"{% endif %}> {% if form.data.email %} value="{{ form.data.email }}"{% endif %}>
{% if form.errors and form.errors.email %} {% if form.errors and form.errors.email %}
@@ -62,7 +63,7 @@
{% if form.data.tel %} value="{{ form.data.tel }}"{% endif %}> {% if form.data.tel %} value="{{ form.data.tel }}"{% endif %}>
{% if form.errors and form.errors.tel %} {% if form.errors and form.errors.tel %}
<span>{{ form.errors.tel }}</span> <span>{{ form.errors.tel|safe }}</span>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@@ -1,19 +1,11 @@
{% if page.seo_title %} <title>{{ page.get_title }}</title>
<title>{{ page.seo_title }}</title>
{% elif page.title %}
<title>{{ page.title }}</title>
{% elif page.name %}
<title>{{ page.name }}</title>
{% endif %}
{% if page.seo_description %} {% if page.get_description %}
<meta name="description" content="{{ page.seo_description }}"/> <meta name="description" content="{{ page.get_description }}"/>
{% elif page.description %}
<meta name="description" content="{{ page.description }}"/>
{% endif %} {% endif %}
{% if page.seo_keywords %} {% if page.seo_keywords %}
<meta name="keywords" content="{{ page.seo_keywords }}"/> <meta name="keywords" content="{{ page.seo_keywords }}"/>
{% elif page.description %} {% elif page.get_description %}
<meta name="keywords" content="{{ page.description }}"/> <meta name="keywords" content="{{ page.get_description }}"/>
{% endif %} {% endif %}

View File

@@ -0,0 +1,80 @@
<div style="font-family:Calibri,Candara,Segoe,'Segoe UI',Optima,Arial,sans-serif;
padding:10px; background-color: #F8F8F8;"
>
<div style="line-height:1.0em; width: 660px">
<div style="padding:5px; text-align: center;">
<img src="{{ logo }}" alt="{{ project_name }}" style="margin:0;padding:0;">
</div>
<p style="font-weight:700; font-size:25px; text-align:center;
padding:0; line-height:1em; text-transform: uppercase; color: #ff613a;
margin: auto; max-width: 90%;
">
Здравствуйте, {{ route.owner }}!
</p>
<div style="line-height:1.0em; font-size:18px; margin: 5px 30px;
box-shadow: -1px 4px 10px 0 rgba(198, 199, 203, 0.20), 0 -1px 10px 0 rgba(198, 199, 203, 0.20);
padding: 30px; border-radius: 10px; background-color: #FFF;">
<p>Ранее вы на сайте <a href="{{ domain }}/profile/page/my_routes/"> размещали объявление о поиске {% if search_owner_type == 'mover' %}Перевозчика{% else %}Отправителя{% endif %}</a> и попросили нас уведомить Вас о появлении объявлений, которые соответствуют Вашему критерию.</p>
<p><b>Хорошая новость!</b></p>
<p><b>По заданным критериям поиска мы нашли исполнителя!</b></p>
<p>Чтобы узнать подробности и открыть доступ к контактам, перейдите <a href="{{ find_routes_page_url }}">по этой ссылке и используйте свои учетные данные для входа</a>.
<p>Если у вас возникнут вопросы или вам потребуется помощь, наша служба поддержки всегда готова помочь. Свяжитесь с нами по адресу <a href="mailto:support@tripwb.com">support@tripwb.com</a></p>
<p>
Спасибо за то, что вы с нами!<br>
С уважением,<br>
Команда Trip With Bonus.<br>
</p>
</div>
{% for button in message_buttons %}
<div style="text-align:center;font-weight: 700;">
<a href="{{ button.url }}">
<div style="display:inline-block;text-align:center;font-size:18px;padding:5px 10px;margin:5px;border-radius:2px;background-color:#61aeb6;color:#fff;text-decoration:none;line-height:1.0em;cursor:pointer">
{{ button.caption }}
</div>
</a>
</div>
{% endfor %}
<div style="text-align:center;width: 660px;line-height:1.1em">
<div style="margin: 40px 10px 10px;">
<hr>
{# <nobr><b>Адрес кафе:</b> Минск, ул. Будславская, 2</nobr>#}
{# <br>#}
{# <nobr><b>График работы:</b> пн-вс 12:00 - 24:00</nobr>#}
{# <br>#}
{# <nobr><b>Телефоны кафе:</b> +375 44 77 321 77</nobr>#}
</div>
</div>
<div style="text-align: center;margin-top:5px">
{# <a href="https://baldenini.by/event/dostavka-edy" style="text-decoration: none;">#}
{# <div style="color: #311A12;#}
{# padding: 10px;#}
{# margin: 5px 10px 0 10px;#}
{# border: 2px solid #311A12;#}
{# border-radius: 5px;#}
{# font-size: 20px;#}
{# display: inline-block;#}
{# font-weight: 700;#}
{# text-transform: uppercase;">О ДОСТАВКЕ#}
{# </div>#}
{# </a>#}
{# <a href="https://baldenini.by/page/baldenini-cafe-o-nas" style="text-decoration: none;">#}
{# <div style="color: #311A12;#}
{# padding: 10px;#}
{# margin: 5px 10px 0 10px;#}
{# border: 2px solid #311A12;#}
{# border-radius: 5px;#}
{# font-size: 20px;#}
{# display: inline-block;#}
{# font-weight: 700;#}
{# text-transform: uppercase;">О BALDENINI CAFE#}
{# </div>#}
{# </a>#}
</div>
</div>
</div>

View File

@@ -0,0 +1,113 @@
{% load i18n %}
<div style="font-family:Calibri,Candara,Segoe,'Segoe UI',Optima,Arial,sans-serif;
padding:10px; background-color: #F8F8F8;"
>
<div style="line-height:1.0em; width: 660px">
<div style="padding:5px; text-align: center;">
<img src="{{ logo }}" alt="{{ project_name }}" style="margin:0;padding:0;">
</div>
<p style="font-weight:700; font-size:25px; text-align:center;
padding:0; line-height:1em; text-transform: uppercase; color: #ff613a;
margin: auto; max-width: 90%;
">
{{ message_title|safe }}
</p>
<div style="line-height:1.0em; font-size:18px; margin: 5px 30px;
box-shadow: -1px 4px 10px 0 rgba(198, 199, 203, 0.20), 0 -1px 10px 0 rgba(198, 199, 203, 0.20);
padding: 30px; border-radius: 10px; background-color: #FFF;">
<p style="font-weight: 600;">{% translate "Здравствуйте" %}{% if user.first_name %}, {{ user.first_name }}{% endif %}!</p>
<p>{% translate "Мы рады приветствовать вас в Trip With Bonus! Спасибо, за регистрацию на нашем сайте" %}.</p>
<p>
{% translate "Ваш аккаунт успешно создан." %}<br>
{% translate "Ваш логин" %}: <b>{{ user.email }}</b><br>
{% translate "Ваш пароль" %}: <b>{{ pass }}</b><br>
</p>
<div>
{% translate "Теперь вы можете воспользоваться всеми преимуществами нашего сервиса. Вот несколько полезных функций, которые вы можете исследовать:<br>" %}
<ul>
<li>{% translate "На главной странице нашего сайта Вы можете указать критерии поиска перевозчика посылки или отправителя и напрямую связаться с исполнителем." %}</li>
<li>{% translate "Также в личном кабинете пользователя Вы можете разместить объявление о перевозке посылки или о необходимости отправить посылку. Перевозчики и отправители со всего мира найдут Вас!" %}</li>
</ul>
</div>
<p>
{% blocktrans %}
Чтобы начать, просто перейдите на <a href="https://tripwb.com">сайт</a> и используйте свои учетные данные для входа.
{% endblocktrans %}
</p>
<p>
{% blocktrans %}
Если у вас возникнут вопросы или вам потребуется помощь, наша служба поддержки всегда готова помочь. Свяжитесь с нами по адресу <a href="mailto:support@tripwb.com">support@tripwb.com</a>
{% endblocktrans %}
</p>
<p>{% translate "Спасибо за то, что вы с нами!" %}</p>
<p>
{% blocktrans %}
С уважением,<br>
Команда Trip With Bonus.<br>
{% endblocktrans %}
</p>
</div>
{% for button in message_buttons %}
<div style="text-align:center;font-weight: 700;">
<a href="{{ button.url }}">
<div style="display:inline-block;text-align:center;font-size:18px;padding:5px 10px;margin:5px;border-radius:2px;background-color:#61aeb6;color:#fff;text-decoration:none;line-height:1.0em;cursor:pointer">
{{ button.caption }}
</div>
</a>
</div>
{% endfor %}
<div style="text-align:center;width: 660px;line-height:1.1em">
<div style="margin: 40px 10px 10px;">
<hr>
{# <nobr><b>Адрес кафе:</b> Минск, ул. Будславская, 2</nobr>#}
{# <br>#}
{# <nobr><b>График работы:</b> пн-вс 12:00 - 24:00</nobr>#}
{# <br>#}
{# <nobr><b>Телефоны кафе:</b> +375 44 77 321 77</nobr>#}
</div>
</div>
<div style="text-align: center;margin-top:5px">
{# <a href="https://baldenini.by/event/dostavka-edy" style="text-decoration: none;">#}
{# <div style="color: #311A12;#}
{# padding: 10px;#}
{# margin: 5px 10px 0 10px;#}
{# border: 2px solid #311A12;#}
{# border-radius: 5px;#}
{# font-size: 20px;#}
{# display: inline-block;#}
{# font-weight: 700;#}
{# text-transform: uppercase;">О ДОСТАВКЕ#}
{# </div>#}
{# </a>#}
{# <a href="https://baldenini.by/page/baldenini-cafe-o-nas" style="text-decoration: none;">#}
{# <div style="color: #311A12;#}
{# padding: 10px;#}
{# margin: 5px 10px 0 10px;#}
{# border: 2px solid #311A12;#}
{# border-radius: 5px;#}
{# font-size: 20px;#}
{# display: inline-block;#}
{# font-weight: 700;#}
{# text-transform: uppercase;">О BALDENINI CAFE#}
{# </div>#}
{# </a>#}
</div>
</div>
</div>

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