385 Commits

Author SHA1 Message Date
f6f4bfa2ab reklama code insert 2025-03-21 17:53:06 +03:00
f625537b6f reklama code insert 2025-03-21 17:52:35 +03:00
794d5e810d reklama code insert 2025-03-21 16:58:12 +03:00
a5c0985093 reklama code insert 2025-03-21 16:54:43 +03:00
70b481480f reklama code insert 2025-03-21 16:53:40 +03:00
a37e009109 reklama code insert 2025-03-21 16:52:37 +03:00
191ceaca36 reklama code insert 2025-03-21 16:51:46 +03:00
53ec69d27c reklama code insert 2025-03-21 16:50:03 +03:00
26f29e4353 reklama code insert 2025-03-21 16:47:19 +03:00
e1f239d6ee reklama code insert 2025-03-21 16:44:30 +03:00
355abb1add yandex code insert 2025-03-21 16:40:27 +03:00
a3795dd267 tik tok code insert 2025-03-21 15:37:40 +03:00
90ffcd090c tik tok code insert 2025-03-21 15:37:05 +03:00
acb52aef73 Merge remote-tracking branch 'origin/dev' into dev 2025-03-11 10:59:50 +03:00
fa04e5275f google code insert 2025-03-11 10:59:39 +03:00
SBD
0288c05e2b correct registration js metrics 2025-03-05 15:03:41 +03:00
9c96d8c253 pixel code replace 2025-02-24 13:31:54 +03:00
SBD
423394a9d9 0.0.165 routes 2025-02-17 22:53:58 +03:00
SDE
3b0e1f6524 2.1.39 fix users_notify_by_result_search_matches 2025-02-17 18:22:23 +03:00
c57eec05c9 pixel code replace 2025-02-12 15:01:47 +03:00
197f910b82 pixel code replace 2025-02-12 15:00:30 +03:00
a940f2ff0d pixel code replace 2025-02-10 17:17:09 +03:00
66a1170221 pixel code replace 2025-02-10 14:59:53 +03:00
5f403710d1 pixel code replace 2025-02-09 01:07:16 +03:00
529fb3fc5d pixel code replace 2025-02-07 11:21:34 +03:00
cae627f0b0 facebook domain verification add 2025-02-03 00:49:56 +03:00
5ff75a4a80 facebook domain verification add 2025-02-03 00:32:03 +03:00
80deab3c42 facebook domain verification add 2025-02-03 00:12:08 +03:00
6030998018 facebook domain verification add 2025-01-29 09:45:18 +03:00
abaff023cd facebook domain verification add 2025-01-27 23:16:40 +03:00
4dbe424f84 meta pixel add 2025-01-24 18:05:48 +03:00
7488a9f8c8 telegram link fix 2025-01-17 14:52:56 +03:00
SDE
b759ce2d5a 2.1.23 fix send support mail 2025-01-16 15:28:06 +03:00
84c88ba406 telegram link fix 2024-12-13 16:41:40 +03:00
b2f7612452 TRI-303 correct texts mistakes 2024-12-11 14:54:56 +03:00
09769542f9 TRI-302 add yandex metrika and goals for buttons and urls for landings 2024-12-09 12:19:29 +03:00
a90d7c06a9 TRI-302 add yandex metrika for landings 2024-12-07 16:22:23 +03:00
SDE
4ce12a5428 1.8.11 fix stat landings 2024-12-05 14:02:24 +03:00
7ba65e73ae TRI-283: fix video2 2024-12-04 15:00:44 +03:00
4a58a47a8e TRI-283: fix video1 2024-12-04 10:02:23 +03:00
e8506e1b4e TRI-297 add facebook pixel 2024-12-03 23:33:09 +03:00
61805df66b TRI-297 add facebook pixel 2024-12-03 12:47:18 +03:00
e98d426324 TRI-297 add facebook pixel 2024-12-03 12:46:13 +03:00
6c062ce3c8 TRI-297 add facebook pixel 2024-12-03 12:43:29 +03:00
8f47d4fb65 TRI-283: reload images 2024-12-02 13:38:09 +03:00
63e507d0ff TRI-283: reload images + text edit 2024-11-29 13:39:44 +03:00
5a16466766 Merge remote-tracking branch 'origin/dev' into dev 2024-11-28 13:37:30 +03:00
4b0c923ec0 1.3.6 recovery password TRI-261 2024-11-28 13:37:14 +03:00
87f67aa24a TRI-283: fix nags 2024-11-28 07:47:48 +03:00
93e48f3cbc TRI-283: fix scroll 2024-11-27 16:23:28 +03:00
baadc67fcf Merge remote-tracking branch 'origin/dev' into dev 2024-11-27 16:14:00 +03:00
bc16aea3a4 1.3.5 registration TRI-265 2024-11-27 16:13:50 +03:00
8041e3eb4d TRI-283: edit fixed 2024-11-27 15:54:51 +03:00
3e4c0b2ab5 1.3.4 TRI-288 phone in my routes 2024-11-27 15:50:47 +03:00
960c9ba5b0 Merge remote-tracking branch 'origin/dev' into dev 2024-11-27 15:38:19 +03:00
3efec91d74 1.3.3 TRI-288 phone in my routes 2024-11-27 15:38:05 +03:00
9e48c72245 TRI-283: edit bg 2024-11-27 15:31:03 +03:00
4dac9a5eec TRI-283: edit sticky2 2024-11-27 15:09:34 +03:00
bf25c67f1e TRI-283: edit sticky 2024-11-27 15:04:29 +03:00
1245899c07 TRI-283: edit ыешслн 2024-11-27 15:02:24 +03:00
66f25b6937 TRI-283: edit img 2024-11-27 14:55:46 +03:00
2d44edf5ab TRI-283: edit some code 2024-11-27 14:41:38 +03:00
7062c756b6 TRI-283: edit customer 2024-11-27 12:24:21 +03:00
7c173c9195 TRI-283: edit mover 2024-11-27 12:06:11 +03:00
e070ab15ac TRI-283: edit 2 height btn, text, image 2024-11-27 10:15:51 +03:00
400498c6fa TRI-283: edit height btn, text, image 2024-11-27 10:14:03 +03:00
3c5331c2d3 TRI-283: edit images xs 2024-11-23 09:00:55 +03:00
800b7ba493 TRI-283: edit dropdown 2024-11-22 15:21:54 +03:00
bc2689d1cf TRI-283: edit logo 2024-11-22 13:55:53 +03:00
ce9be11c0a TRI-283: post btns 2024-11-22 12:44:54 +03:00
43ba192496 TRI-283: edit footer 2024-11-22 12:38:11 +03:00
ee410315ee TRI-283: edit btns 2024-11-22 12:20:27 +03:00
f3c78f0575 TRI-283: end editors pages 2024-11-22 08:59:49 +03:00
b98a4a5364 TRI-283: edits btns reg landing_page 2024-11-22 07:24:46 +03:00
68aad97e46 TRI-283: save for show p_customer_landing_page 2024-11-22 06:38:22 +03:00
8de6676b40 TRI-283: end p_mover_landing_page 2024-11-21 19:49:38 +03:00
7a345a6c80 TRI-283: edit chatterbox 2024-11-21 14:24:47 +03:00
e3adbeeea4 TRI-283: start 768> 2024-11-21 13:10:25 +03:00
b0db3534f2 TRI-283: add feader fixed 2024-11-20 22:55:34 +03:00
6f646264dc TRI-283: end 1280 2024-11-20 22:00:18 +03:00
d83940b47d TRI-283: end header + start adaptive 1400> 2024-11-20 01:38:34 +03:00
4996d02f71 TRI-283: end adaptive 1920 + start header 2024-11-19 00:25:47 +03:00
SDE
da6f47f439 1.8.9 p_customer_landing_page.html media_items 2024-11-18 15:46:07 +03:00
SDE
54fbc3f4b2 1.8.8 p_mover_landing_page.html media_items 2024-11-18 15:38:28 +03:00
SDE
6e2c54eccf 1.8.7 Billing migrations 2024-11-17 16:48:38 +03:00
89166100e3 TRI-283: start adaptive 1920 2024-11-16 20:03:47 +03:00
3d28a1ee86 TRI-283: end pade move 2024-11-16 18:28:26 +03:00
034d5faa0d TRI-283: add scss posterinvideo 2024-11-16 15:02:40 +03:00
f58038ab90 TRI-283: add benefits animate about 2024-11-15 21:07:29 +03:00
SDE
ad25cc67ec 1.8.6 search_matches fix weight params 2024-11-15 18:21:17 +03:00
SDE
384d1e8aec 1.8.5 search_matches fix weight params 2024-11-15 17:12:40 +03:00
SDE
b0a1007a76 1.8.4 media for landing 2024-11-15 16:21:40 +03:00
SDE
0419ba7847 1.8.3 media for landing 2024-11-15 16:05:07 +03:00
SDE
c52dbca9a1 1.8.2 media for landing 2024-11-15 15:14:50 +03:00
SDE
43153a9fdf Merge remote-tracking branch 'origin/dev' into dev 2024-11-15 13:55:04 +03:00
SDE
c23dd1ff4c 1.8.1 landing_customer 2024-11-15 13:54:53 +03:00
67d9528614 TRI-283: добавил и настроил видео 2024-11-15 13:48:11 +03:00
1151744247 TRI-283: вёрстка лендинга 2024-11-14 21:10:53 +03:00
9dd3fbe47d youtube link repair 2024-11-14 14:39:39 +03:00
f42e155f2b add some code 2024-11-13 23:49:01 +03:00
SDE
f5a084684a 1.8.0 landing_mover 2024-11-12 20:05:07 +03:00
SDE
b22adac365 1.7.19 get_my_routes_ajax log fail 2024-11-12 17:34:49 +03:00
SDE
a329720f1c 1.7.18 w_carrier_card.html fix route.highlight_end_DT 2024-11-12 16:04:12 +03:00
SDE
e03f4a015a 1.7.18 generate routes 2024-11-12 14:06:58 +03:00
SDE
94f677ae6f 1.7.17 get_routes_Dict send techmail if user undefined 2024-11-12 12:52:46 +03:00
SDE
8afdfc87c5 1.7.16 registration send mail test 2024-11-12 12:42:10 +03:00
cc3739f701 Merge remote-tracking branch 'origin/dev' into dev 2024-11-12 12:33:27 +03:00
dbee8dabb1 1.3.2 phone is not required TRI-249, TRI-265 2024-11-12 12:33:10 +03:00
SDE
cfb7acfddb 1.7.15 fix user_profile.js 1312 2024-11-12 12:15:52 +03:00
SDE
e14072e829 1.7.15 fix registration.js 71 2024-11-12 12:01:28 +03:00
SDE
f80f8d8c7e 1.7.14 route phone is not exists 2024-11-12 10:51:40 +03:00
SDE
e9b3dc1da9 1.7.13 route phone is not exists 2024-11-12 10:50:15 +03:00
63137188e5 instagram link repair 2024-11-11 07:38:36 +03:00
Rewardio
07031d693c TRI-265 adding checks to eliminate getting null at classList.add 2024-11-08 17:01:44 +03:00
SDE
531955bdc7 Merge remote-tracking branch 'origin/dev' into dev 2024-11-06 15:52:02 +03:00
SDE
2cfa314c3c 1.7.12 fix search_matches sendmail link 2024-11-06 15:51:54 +03:00
cfe37ec57d 1.3.1 counters in footer TRI-276 2024-11-01 14:58:11 +03:00
995733d6e3 TRI-275 disable googlesindicator script in head section 2024-10-25 13:04:25 +03:00
aec622831d TRI-275 disable googlesindicator script in head section 2024-10-25 13:03:17 +03:00
e8f092a88b TRI-275 disable googlesindicator script in head section 2024-10-24 10:39:15 +03:00
a1da574c04 TRI-274 replace password recovery text 2024-10-23 13:54:33 +03:00
08e28d14c9 TRI-274 replace password recovery text 2024-10-23 13:44:47 +03:00
cffd810184 TRI-274 replace password recovery text 2024-10-23 13:31:28 +03:00
SDE
774ee85f8d 1.7.11 Admin_Route add search_fields 2024-10-22 17:11:34 +03:00
SDE
a1c6db28a8 1.7.10 Admin_Route add search_fields 2024-10-22 17:06:29 +03:00
SDE
bcd0c8900d 1.7.9 fix html b_profile call to select_tab_profile 2024-10-21 14:15:57 +03:00
SDE
f3e3b608f1 1.7.8 fix js dublicates login section 2024-10-21 13:42:32 +03:00
SDE
a839114cdf 1.7.7 fix js dublicates login section 2024-10-21 13:24:08 +03:00
SDE
a315a52791 Merge remote-tracking branch 'origin/dev' into dev 2024-10-21 12:53:00 +03:00
SDE
fc0d9f07c0 1.7.6 fix get_profile_change_page_content_html 2024-10-21 12:52:51 +03:00
26b4b77271 TRI-262 replace invocation in subscription mail template 2024-10-18 00:46:08 +03:00
SDE
09cfe8938f Merge remote-tracking branch 'origin/dev' into dev 2024-10-17 17:58:05 +03:00
SDE
8989d13928 1.7.5 admin search for Admin_SubscribeForUser 2024-10-17 17:56:47 +03:00
a39c96cc61 TRI-260 replace placeholder login 2024-10-10 14:30:19 +03:00
db8beca609 TRI-260 replace placeholder login 2024-10-10 14:28:35 +03:00
94e7881aa0 fix tiktok link 2024-10-05 11:23:33 +03:00
e4a07e2c88 TRI-258 Replace logo in email templates 2024-10-02 13:36:32 +03:00
1414003e3f TRI-258 Replace logo in email templates 2024-10-02 13:30:56 +03:00
b9f4804d74 Merge pull request 'main' (#13) from main into dev
Reviewed-on: #13
2024-10-02 13:22:01 +03:00
e2b63f6706 Merge remote-tracking branch 'origin/dev' into dev 2024-09-24 15:05:13 +03:00
393f165095 1.3.0 get_routes in my_routes TRI-251 2024-09-24 15:05:01 +03:00
547e4e8f9f TRI-258 Replace logo in email templates 2024-09-24 02:28:59 +03:00
ffeab227c9 TRI-258 Replace logo in email templates 2024-09-23 23:35:51 +03:00
4452398773 TRI-258 Replace logo in email templates 2024-09-23 23:34:03 +03:00
454f4711f3 TRI-258 Replace logo in email templates 2024-09-23 23:31:52 +03:00
46c456af2c TRI-258 Replace logo in email templates 2024-09-23 23:29:26 +03:00
2f459e982a TRI-258 Replace logo in email templates 2024-09-23 23:25:40 +03:00
b8d934fa28 TRI-258 Replace logo in email templates 2024-09-23 23:22:14 +03:00
1107c01d5c TRI-258 Replace logo in email templates 2024-09-23 23:18:21 +03:00
b8ca85c20e TRI-258 Replace logo in email templates 2024-09-23 23:16:57 +03:00
a29cf29041 TRI-258 Replace logo in email templates 2024-09-23 23:13:55 +03:00
05bf1d59df TRI-258 Replace logo in email templates 2024-09-23 23:08:01 +03:00
2cf129d0b9 TRI-258 Replace logo in email templates 2024-09-23 23:03:01 +03:00
488cd72f2c 1.2.9 add favicon TRI-255 2024-09-23 23:01:07 +03:00
6fab07fd79 1.2.8 add favicon TRI-255 2024-09-23 16:32:23 +03:00
382b2d122c 1.2.7 comment popup TRI-257 2024-09-23 16:08:11 +03:00
b4beac26a7 1.2.6 password recovery TRI-108 2024-09-23 16:02:27 +03:00
SDE
86d78fdd06 1.7.4 password recovery 2024-09-20 20:41:42 +03:00
SDE
92ad985355 1.7.3 password recovery 2024-09-20 18:51:53 +03:00
SDE
eaf94f0ceb 1.7.2 password recovery 2024-09-20 18:43:37 +03:00
SDE
acee0ccec5 1.7.1 password recovery 2024-09-20 18:32:18 +03:00
fddea097d3 1.2.6 password recovery TRI-108 2024-09-20 18:16:00 +03:00
SDE
7dc25532a3 1.7.0 password recovery 2024-09-20 16:43:33 +03:00
SDE
19721cf5da Merge remote-tracking branch 'origin/dev' into dev 2024-09-10 13:51:14 +03:00
SDE
a6d9d1595a 1.6.19 generate routes w change date 2024-09-10 13:51:04 +03:00
5e0d5f4b91 TRI-254 Replace placeholder text for registration form 2024-09-09 23:49:40 +03:00
09a6de1544 TRI-254 Replace placeholder text for registration form 2024-09-09 23:42:13 +03:00
a20b502b70 TRI-254 Replace placeholder text for registration form 2024-09-09 23:40:15 +03:00
8bb8013f67 TRI-254 Replace placeholder text for registration form 2024-09-09 23:37:37 +03:00
94c7c54cc1 TRI-254 Replace placeholder text for registration form 2024-09-09 23:36:19 +03:00
c257d22618 TRI-254 Replace placeholder text for registration form 2024-09-09 23:34:14 +03:00
b57dbb75e8 TRI-254 Replace placeholder text for registration form 2024-09-09 23:30:22 +03:00
9781f33440 TRI-254 Replace placeholder text for registration form 2024-09-09 23:29:33 +03:00
45b4236748 TRI-254 Replace placeholder text for registration form 2024-09-09 23:23:33 +03:00
8b0c82c3ca TRI-254 Replace placeholder text for registration form 2024-09-09 23:21:46 +03:00
5518a99ee9 TRI-254 Replace placeholder text for registration form 2024-09-09 23:20:39 +03:00
63124a350e Replace Main text on main page 2024-09-09 23:16:25 +03:00
SDE
c7de08ca49 Merge remote-tracking branch 'origin/dev' into dev 2024-09-09 16:45:29 +03:00
SDE
41e4b23317 1.6.18 fix reset highlight after change route 2024-09-09 16:45:20 +03:00
b23f379db0 1.2.5 new init for calendar in create_route TRI-247 2024-09-05 11:26:50 +03:00
SDE
1faf9e0cc7 Merge remote-tracking branch 'origin/dev' into dev 2024-09-02 15:14:17 +03:00
SDE
90e1a87bf4 1.6.17 registration not required phone 2024-09-02 15:14:06 +03:00
9ec8d4189f Replace Main text on main page 2024-08-29 23:53:13 +03:00
8f08e360ef Replace Main text on main page 2024-08-29 23:52:18 +03:00
SDE
4371cd1a85 1.6.16 generate routes road 2024-08-26 17:55:49 +03:00
SDE
f6ba0ab1ad 1.6.15 split send mail to user and copy for dev 2024-08-23 15:19:33 +03:00
SDE
c60b9942f6 Merge remote-tracking branch 'origin/dev' into dev 2024-08-22 13:41:47 +03:00
SDE
85f6e69d63 1.6.14 generate routes 2024-08-22 13:41:34 +03:00
83aeab9341 1.2.4 upd meta_OpenGraph_Schema.html TRI-200 2024-08-20 13:27:29 +03:00
8a539a2868 1.2.2 limitation of color selection for 24 hours TRI-228 2024-08-20 12:18:52 +03:00
379db1cb39 Merge pull request '1.2.2 upd mover search card TRI-246' (#12) from dev into main
Reviewed-on: #12
2024-08-19 18:03:25 +03:00
e51b23cb91 1.2.2 upd mover search card TRI-246 2024-08-19 16:27:31 +03:00
e824a258ea Merge pull request 'dev' (#11) from dev into main
Reviewed-on: #11
2024-08-18 17:48:09 +03:00
SDE
526f035659 1.6.13 fix next package for my_routes 2024-08-13 15:03:20 +03:00
SDE
42c2843cab 1.6.12 fix next package for my_routes 2024-08-13 14:41:11 +03:00
SDE
a99ffcc9d2 1.6.11 fix next package for my_routes 2024-08-13 12:58:41 +03:00
40a2412b9b 1.2.2 add url check for my_route dynamic_loading_routes.js 2024-08-13 12:49:08 +03:00
cd2985a170 Merge pull request 'Add text if email in spam and translate it' (#10) from dev into main
Reviewed-on: #10
2024-08-09 23:50:40 +03:00
cb84352475 Add text if email in spam and translate it 2024-08-09 23:49:10 +03:00
a19b4fe212 Merge pull request 'dev' (#9) from dev into main
Reviewed-on: #9
2024-08-09 22:44:34 +03:00
SDE
f718df47c8 Merge remote-tracking branch 'origin/dev' into dev 2024-08-09 21:53:33 +03:00
SDE
7620f97042 1.6.10 adds for search timezone for cities 2024-08-09 21:53:25 +03:00
3bfb7d040d Merge pull request 'replace tb_base.html' (#8) from dev into main
Reviewed-on: #8
2024-08-09 21:08:58 +03:00
aea50ed806 replace tb_base.html 2024-08-09 21:08:02 +03:00
7dab17905b Merge pull request 'dev' (#7) from dev into main
Reviewed-on: #7
2024-08-09 18:55:31 +03:00
a3a3565189 add rightpaneluser from dev 2024-08-09 18:53:53 +03:00
3f82f42e1e add chatsocketfunctions from dev 2024-08-09 18:52:23 +03:00
0de00c5a34 add chatsocketfunctions from dev 2024-08-09 18:51:14 +03:00
0daee07086 add models.py from dev 2024-08-09 18:49:10 +03:00
2619539415 add django.po from dev 2024-08-09 18:46:00 +03:00
aa8bed6efb add tb_base from main 2024-08-09 18:42:48 +03:00
9b01d79955 1.0.25 password text in registration mail 2024-08-09 18:30:03 +03:00
17f21a25bb 1.0.26 translate 2024-08-09 18:29:41 +03:00
8c523e8c65 1.6.3 parsing timezones 2024-08-09 18:25:07 +03:00
d7956e24a6 1.6.2 parsing timezones 2024-08-09 18:23:52 +03:00
eaafbec1ea 1.6.1 parsing timezones 2024-08-09 18:23:29 +03:00
4ba5f6492f 1.6.0 parsing timezones 2024-08-09 18:21:12 +03:00
SDE
4355586afc Merge remote-tracking branch 'origin/dev' into dev 2024-08-09 14:33:52 +03:00
SDE
ed4dce4bf2 1.6.9 admin routes search by cities 2024-08-09 14:33:41 +03:00
a8c4d22b51 1.2.1 add Telegram icon 2024-08-08 08:52:08 +03:00
92f08b5174 1.1.60 add Meta Pixel Code 2024-08-06 21:22:24 +03:00
a7128908f4 1.1.59 upd the calendar initialization after receiving an error when submitting the form 2024-08-02 17:35:17 +03:00
d86a531495 1.1.58 add TikTok Pixel Code to registration.js 2024-08-02 15:55:28 +03:00
f894cec38b 1.1.57 add TikTok Pixel Code 2024-08-01 17:26:14 +03:00
0ef2f9aeb1 1.1.56 upd meta OG 2024-08-01 17:17:58 +03:00
312a706d00 1.1.55 fix function selectItemAddrPoint on main page 2024-08-01 17:06:05 +03:00
d1ad6cfa24 1.1.54 add readonly for departure/arrival input 2024-08-01 11:12:26 +03:00
2bc9aa7a1c 1.1.53 added a local time reference when editing route 2024-08-01 11:04:23 +03:00
3a497d09df 1.1.51 upd initialization for init_departure_DT() init_arrival_DT() 2024-08-01 10:44:18 +03:00
1301af9d84 1.1.51 upd the local time check of the selected city 2024-08-01 10:22:44 +03:00
SDE
822a029104 Merge remote-tracking branch 'origin/dev' into dev 2024-07-31 23:13:41 +03:00
SDE
257ae371f9 1.6.8 user admin add fields to list 2024-07-31 23:13:34 +03:00
ec1d52f694 1.1.50 add pagination for b_my_routes.html && upd conditional rendering for carrier card based on departure date 2024-07-31 16:13:28 +03:00
SDE
46c7b6327d Merge remote-tracking branch 'origin/dev' into dev 2024-07-31 12:02:22 +03:00
SDE
72d8ae6616 1.6.7 get_address_point_ajax add cur time for city 2024-07-31 12:02:13 +03:00
b905fab6c5 1.1.50 add pagination for b_my_routes.html && upd conditional rendering for carrier card based on departure date 2024-07-29 19:32:13 +03:00
3b10299249 1.1.49 add new gtag to MAIN branch 2024-07-29 14:43:19 +03:00
2098032d81 1.1.48 add new gtag to MAIN branch 2024-07-29 13:20:44 +03:00
d37b694d5a 1.1.47 add new gtag 2024-07-29 12:41:07 +03:00
345969fd61 1.1.46 upd poup url 2024-07-25 17:41:02 +03:00
632ff3c812 1.1.44 setTimeout for popup display 2024-07-25 17:19:45 +03:00
bb60f9d914 1.1.43 add popup display functionality with cookie-based visibility control 2024-07-25 16:55:35 +03:00
111a7eaff7 1.1.43 add popup display functionality with cookie-based visibility control 2024-07-25 16:55:13 +03:00
61161e6335 1.0.26 translate 2024-07-25 01:22:12 +03:00
327681d3db 1.0.26 translate 2024-07-25 01:17:57 +03:00
68c5bfe275 1.0.26 translate 2024-07-25 01:08:27 +03:00
10814e9e5f Merge remote-tracking branch 'origin/dev' into dev 2024-07-25 01:03:20 +03:00
617f90e1ac 1.0.26 translate 2024-07-25 01:03:05 +03:00
81af5990ae 1.1.42 Fix date formatting issue in template 2024-07-23 14:28:41 +03:00
92e9b1ce63 1.1.41 show/hide unanswered_msgs_count 2024-07-23 13:41:41 +03:00
87b21c5f55 1.1.40 show/hide unanswered_msgs_count 2024-07-18 12:53:04 +03:00
f61482ded6 1.1.39 show/hide unanswered_msgs_count 2024-07-18 12:05:54 +03:00
c999d994d6 1.1.38 show/hide unanswered_msgs_count 2024-07-18 11:42:29 +03:00
f609361ee9 1.1.37 show/hide unanswered_msgs_count 2024-07-17 15:24:42 +03:00
c3f116fbc3 1.1.36 show/hide unanswered_msgs_count 2024-07-17 13:58:21 +03:00
79059796c8 Merge remote-tracking branch 'origin/dev' into dev 2024-07-17 13:10:27 +03:00
61facdb5fb 1.1.35 refactor date comparison logic in Django template 2024-07-17 13:10:15 +03:00
SDE
b007c3ad23 1.6.6 parsing timezones 2024-07-16 15:53:12 +03:00
SDE
0b5e37281b 1.6.5 parsing timezones 2024-07-16 15:34:35 +03:00
SDE
6e5e82401b 1.6.4 parsing timezones 2024-07-16 15:19:40 +03:00
d419131eab 1.1.34 upd chat_counter 2024-07-16 15:10:43 +03:00
b8b3c19bfc 1.1.33 upd chat_socket 2024-07-16 09:47:58 +03:00
e95062c6eb Merge remote-tracking branch 'origin/main' 2024-07-16 09:34:37 +03:00
2f4c472a41 1.1.32 upd chat_socket 2024-07-16 09:34:13 +03:00
3f0f1d4408 1.0.25 password text in registration mail 2024-07-15 23:55:17 +03:00
f23ad1a33a 1.0.25 password text in registration mail 2024-07-15 23:40:42 +03:00
SDE
1486879a58 1.6.3 parsing timezones 2024-07-13 01:29:36 +03:00
SDE
3d6fb38937 1.6.2 parsing timezones 2024-07-12 21:07:07 +03:00
SDE
d981a83652 1.6.1 parsing timezones 2024-07-12 19:01:58 +03:00
SDE
3bfe64d57c Merge remote-tracking branch 'origin/dev' into dev 2024-07-12 18:54:24 +03:00
SDE
1ad58b05ef 1.6.0 parsing timezones 2024-07-12 18:54:14 +03:00
225a958cb4 1.0.24 robots 2024-07-10 17:58:30 +03:00
0ac8e906a2 1.0.24 robots 2024-07-10 17:56:29 +03:00
a42f3c7e71 1.0.24 robots 2024-07-10 17:38:02 +03:00
ddf8428884 Merge pull request 'dev в main' (#1) from dev into main
Reviewed-on: #1
2024-07-10 17:34:03 +03:00
807edecbf4 1.0.23 add tenge currency 2024-07-10 16:34:37 +03:00
6254b1dcda 1.0.23 add tenge currency 2024-07-10 16:21:35 +03:00
SDE
9df1bf2743 1.5.2 change currency pay 2024-07-10 16:20:48 +03:00
a678fb467d 1.0.22 robots.txt modify 2024-07-09 21:25:20 +03:00
SDE
c24b7107a7 Merge remote-tracking branch 'origin/main' 2024-07-09 16:59:23 +03:00
SDE
c0596871da 1.5.1 rosetta translate 2024-07-09 16:59:13 +03:00
f0ad2d654d 0.0.22 translate 2024-07-09 16:54:35 +03:00
SDE
c2ef76b69b 1.5.0 rosetta translate 2024-07-09 16:51:05 +03:00
SDE
96f58732ba 1.4.8 bank res log w full info 2024-07-09 16:19:55 +03:00
SDE
15340d254c 1.4.7 bank res log w full info 2024-07-09 16:17:00 +03:00
SDE
890986c5de 1.4.6 bank res log w full info 2024-07-09 16:12:33 +03:00
SDE
3d137aefad 1.4.5 move pay_system sets to settings 2024-07-09 16:09:01 +03:00
SDE
6c911dde43 1.4.4 move pay_system sets to settings 2024-07-09 16:07:16 +03:00
SDE
37981602dd 1.4.3 move pay_system sets to settings 2024-07-09 16:03:16 +03:00
SDE
d64d858f15 Merge remote-tracking branch 'origin/main' 2024-07-09 13:40:42 +03:00
SDE
f9906ea8fc 1.4.2 move pay_system url to settings 2024-07-09 13:40:32 +03:00
c660831146 1.1.31 upd chats markers 2024-07-04 14:42:27 +03:00
a8ba3f9a3a 1.1.30 upd chats markers 2024-07-04 13:49:42 +03:00
8439fc8736 1.1.29 upd tik tok url 2024-07-04 09:44:25 +03:00
04f7fbdbb2 1.1.29 upd msg counter 2024-07-03 21:54:40 +03:00
e2b205240e 1.1.28 upd msg counter and news 2024-07-03 18:24:35 +03:00
2695738ae3 1.1.27 hide .advertisement_block_news 2024-07-03 17:22:17 +03:00
5a3336a657 Merge remote-tracking branch 'origin/main' 2024-07-03 17:18:56 +03:00
b67b290279 1.1.26 upd msg counter and styles for news 2024-07-03 17:18:40 +03:00
f34664cbb3 0.0.19 add articles indexing 2024-07-02 20:48:03 +03:00
4919560500 0.0.19 add articles indexing 2024-07-02 19:07:47 +03:00
c2b6890311 1.1.24 upd msg counter 2024-07-02 15:30:34 +03:00
38c4f3426d 1.1.23 add h1 for all pages 2024-07-01 17:53:54 +03:00
2400c334a9 1.1.23 upd title and description 2024-07-01 16:52:08 +03:00
SDE
114675703b 1.4.1 sitemap 2024-06-29 16:46:37 +03:00
SDE
0be38ac466 1.4.0 sitemap 2024-06-29 16:34:36 +03:00
SDE
0e184f0b87 1.3.6 add unanswered_msgs_count to all responses 2024-06-29 14:44:19 +03:00
SDE
75258f1706 1.3.5 send_mail_for_user_subscribes_that_is_going_to_finish 2024-06-28 18:24:23 +03:00
SDE
ce591345d3 1.3.4 send_mail_for_user_subscribes_that_is_going_to_finish 2024-06-28 18:12:01 +03:00
SDE
0770009443 1.3.3 send_mail_for_user_subscribes_that_is_going_to_finish 2024-06-28 18:10:35 +03:00
SDE
bf39639acc 1.3.2 send_mail_for_user_subscribes_that_is_going_to_finish 2024-06-28 18:02:57 +03:00
SDE
947f46c5ff 1.3.1 receive_finish_subscribe_msg 2024-06-28 15:27:29 +03:00
651423ce90 1.1.22 fix function for checking the status of the switch finish_subscribe_msg 2024-06-28 15:24:58 +03:00
afb0ea0bed 1.1.21 add function for checking the status of the switch finish_subscribe_msg 2024-06-28 15:17:39 +03:00
SDE
e2b7b0d356 Merge remote-tracking branch 'origin/main' 2024-06-27 19:15:02 +03:00
SDE
c55d5c6676 1.3.0 receive_finish_subscribe_msg, find errors by tickets 2024-06-27 19:14:52 +03:00
eb60bcec56 1.1.20 upd css for .menu_profile right 2024-06-26 13:02:52 +03:00
62325eb9fa 1.1.19 upd css for block-chat 2024-06-26 12:32:53 +03:00
18aae945ae 1.1.18 fix height for container_inf_about_moving 2024-06-25 18:33:54 +03:00
4afe61546a 1.1.17 add YandexMetrika tag for create_routes, registration button in header/footer v2 2024-06-25 13:10:32 +03:00
b6a0fcdf07 1.1.17 add YandexMetrika tag for create_routes, registration button in header/footer v2 2024-06-21 15:41:19 +03:00
2fc153843f 1.1.16 add YandexMetrika tag for create_routes, registration button in header/footer 2024-06-21 14:54:30 +03:00
729f03ca47 1.1.15 add YandexMetrika tag for feedback form v4 2024-06-21 13:48:37 +03:00
96c0111428 1.1.14 add YandexMetrika tag for feedback form v3 2024-06-21 13:17:35 +03:00
d0ccbb494f 1.1.13 add YandexMetrika tag for feedback form v2 2024-06-20 17:10:20 +03:00
f8aa0162a5 1.1.12 add YandexMetrika tag for feedback form 2024-06-20 16:56:21 +03:00
2b94d3f851 1.1.12 add YandexMetrika tag for registration page 2024-06-20 16:00:23 +03:00
fddda1ef0a 1.1.11 fix height for cards in search 2024-06-20 14:28:42 +03:00
035634df67 0.0.18 add footer social networks 2024-06-18 11:57:13 +03:00
8267d99b4a 0.0.18 add footer social networks 2024-06-18 11:56:14 +03:00
854faf56f5 0.0.18 add footer social networks 2024-06-18 11:52:15 +03:00
4bbb3428c0 0.0.18 add footer social networks 2024-06-18 11:46:31 +03:00
7a40ca0986 0.0.18 add footer social networks 2024-06-18 11:44:49 +03:00
c93a15025b 0.0.18 add footer social networks 2024-06-18 11:43:38 +03:00
57a1c82db2 0.0.18 add social network icons 2024-06-18 11:39:40 +03:00
b6af2c7997 0.0.18 add social network icons 2024-06-18 11:37:35 +03:00
df7b3e1a8b 0.0.17 social network link added 2024-06-15 18:07:41 +03:00
b7a6163251 0.0.17 social network link added 2024-06-15 18:06:15 +03:00
9c39f9e07c 0.0.17 social network link added 2024-06-15 17:57:04 +03:00
d33eff4935 0.0.17 social network link added 2024-06-15 17:55:34 +03:00
11ea66f576 0.0.17 social network link added 2024-06-15 17:53:45 +03:00
d31f019afb 0.0.17 social network instagram link added 2024-06-15 17:42:55 +03:00
52361a6a16 0.0.17 social network instagram link added 2024-06-15 17:37:58 +03:00
e04ec83877 0.0.17 social network instagram link added 2024-06-15 17:35:46 +03:00
SDE
301f301868 1.2.7 reset rising_DT in past routes 2024-06-15 17:18:07 +03:00
SDE
b2cb5463ef Merge remote-tracking branch 'origin/main' 2024-06-15 17:15:05 +03:00
SDE
d2754db97a 1.2.6 reset rirsing_DT in past routes 2024-06-15 17:14:57 +03:00
568906b2df 0.0.16 twb-tripwb replace 2024-06-14 09:32:27 +03:00
fbae553657 1.1.10 fix webpush button footer 2024-06-12 23:33:24 +03:00
03ecd45316 1.1.9 fix webpush button footer 2024-06-12 22:45:36 +03:00
b8aba1d951 1.1.9 fix width for container-carrier 2024-06-12 15:38:28 +03:00
SDE
4d76569131 Merge remote-tracking branch 'origin/main' 2024-06-11 16:48:50 +03:00
SDE
f90d87a301 1.2.5 fix get_routes_Dict rising 2024-06-11 16:48:39 +03:00
fe6375b6f9 1.1.8 add registration message 2024-06-11 14:54:15 +03:00
SDE
a30156cc1c 1.2.5 add get_permission_for_highlight 2024-06-11 01:09:40 +03:00
SDE
f8a8aa7577 Merge remote-tracking branch 'origin/main' 2024-06-11 01:03:34 +03:00
SDE
b527d18a3c 1.2.4 add get_permission_for_highlight 2024-06-11 01:03:25 +03:00
fc6a864f7c 0.0.15 robots.txt add allow/disallow options 2024-06-10 23:37:54 +03:00
8eaff8ebbc 0.0.15 robots.txt add allow/disallow options 2024-06-10 23:35:37 +03:00
SDE
3a18688143 Merge remote-tracking branch 'origin/main' 2024-06-10 18:47:07 +03:00
SDE
0e40bae701 1.2.3 get_my_routes_ajax add remains_routes_count operations 2024-06-10 18:46:50 +03:00
7aa7e32fda 1.1.8 upd raise and highlight function in my_routes 2024-06-10 17:48:10 +03:00
SDE
1aced3d20b 1.2.2 get_my_routes_ajax add remains_routes_count operations 2024-06-10 16:58:59 +03:00
SDE
9566082283 Merge remote-tracking branch 'origin/main' 2024-06-10 16:56:43 +03:00
SDE
152c92bf65 1.2.1 get_my_routes_ajax add remains_routes_count operations 2024-06-10 16:56:19 +03:00
4622424b9b Merge remote-tracking branch 'origin/main' 2024-06-10 12:40:31 +03:00
ef8337582f 1.1.6 upd raise and highlight function in my_routes 2024-06-10 12:40:20 +03:00
SDE
133fa7ea5f Merge remote-tracking branch 'origin/main' 2024-06-09 16:37:20 +03:00
SDE
74e76fe6e7 1.2.0 confirm email after registration 2024-06-09 16:37:08 +03:00
2996e84433 1.1.5 fix show_contact if user is not authenticated 2024-06-06 14:25:25 +03:00
f8d1de5d30 1.1.4 update rising and highlight my_routes 2024-06-05 17:47:01 +03:00
d33278faff 1.1.3 update meta_names.html 2024-06-05 16:55:09 +03:00
22e40409d7 1.1.3 rising and highlight my_route counter 2024-06-05 16:48:12 +03:00
632cf0b9b4 1.1.3 change meta_names.html 2024-06-05 16:47:10 +03:00
a9ed3e0bef 0.0.14 add yandex and google verification meta 2024-06-05 15:06:46 +03:00
28b505310d 0.0.14 add yandex and google verification meta 2024-06-05 15:00:58 +03:00
c9aea0b778 1.1.3 rising and highlight my_route 2024-06-05 14:26:36 +03:00
e1694cdc9c 1.1.3 update dropdown-content lang 2024-06-05 14:22:19 +03:00
SDE
3a235b4f60 1.1.13 not send to pay system if subscribe price is null 2024-06-05 12:03:00 +03:00
SDE
90405f64de 1.1.12 funcs for raise and highlight routes 2024-06-04 22:28:43 +03:00
35073f77c8 1.1.3 rising and highlight my_route 2024-06-04 20:02:54 +03:00
5cd0146c8c 1.1.2 upd description for user_profile 2024-06-04 11:09:28 +03:00
SDE
ffabffb2ef 1.1.11 funcs for raise and highlight routes 2024-06-04 00:19:10 +03:00
bb1e3e9691 Merge remote-tracking branch 'origin/main' 2024-06-03 21:35:30 +03:00
d89730ffbf 1.1.1 highlighting and raising routes 2024-06-03 21:35:15 +03:00
262 changed files with 11051 additions and 1079 deletions

4
.gitignore vendored
View File

@@ -415,3 +415,7 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# packages for node
package.json
package-lock.json

View File

@@ -45,6 +45,9 @@ def get_articles_block_ajax(request):
# 'form': RouteForm(initial=data)
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:

View File

@@ -6,7 +6,7 @@ from datetime import datetime, date
from django.http import Http404, HttpResponse
from django.template import loader
from .funcs import *
from GeneralApp.funcs import get_inter_http_respose
from GeneralApp.funcs import get_inter_http_response
from django.utils.translation import gettext_lazy as _
# from django.contrib.auth.decorators import login_required
@@ -85,14 +85,14 @@ def ArticlesPageView(request, year=None):
Dict = get_articles(art_kwargs=kwargs)
Dict.update({
'page': {
'title': _('Новости сервиса доставки посылок | TWB'),
'description': _('Обновления, полезные статьи и свежие новости от TWB ✓ Актуальные новости в мире доставок по всему СНГ ➡️ Следите за нашими новостями'),
'title': _('Новости сервиса доставки посылок | TripWB'),
'description': _('Обновления, полезные статьи и свежие новости от TripWB ✓ Актуальные новости в мире доставок по всему СНГ ➡️ Следите за нашими новостями'),
'keywords': _('Все новости сайта tripwb.com'),
}
})
t = loader.get_template('pages/p_articles.html')
return get_inter_http_respose(t, Dict, request)
return get_inter_http_response(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -125,7 +125,7 @@ def UserPageView(request, page_url):
t = loader.get_template('pages/p_user_page.html')
return get_inter_http_respose(t, Dict, request)
return get_inter_http_response(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -155,5 +155,5 @@ def ArticlesOnePageView(request, art_url):
t = loader.get_template('pages/p_article.html')
return get_inter_http_respose(t, Dict, request)
return get_inter_http_response(t, Dict, request)
# return HttpResponse(t.render(Dict, request))

View File

@@ -97,12 +97,14 @@ class Admin_User(UserAdmin):
save_on_top = True
list_display = ['id', 'last_name', 'first_name', 'mailing_on', 'email', 'is_staff',
'is_active']
'is_active', 'date_joined', 'last_login']
list_editable = ['is_staff', 'is_active']
list_display_links = ['first_name', 'last_name', 'email']
search_fields = ['first_name', 'last_name', 'email']
list_filter = ['user_profile__mailing_on', 'is_staff', 'is_active']
readonly_fields = ['date_joined', 'last_login']
list_filter = ['user_profile__mailing_on', 'is_staff', 'is_active', 'date_joined', 'last_login']
inlines = (Admin_ProfileInline,)
# actions = ['del_all_temp_users', ]

View File

@@ -26,7 +26,7 @@ class RegistrationForm(forms.Form):
email = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput())
confirm_password = forms.CharField(widget=forms.PasswordInput())
tel = forms.CharField()
tel = forms.CharField(required=False)
agreement = forms.BooleanField(initial=False, required=True)
def __init__(self, *args, **kwargs):

View File

@@ -1,3 +1,4 @@
from django.http import QueryDict
from django.template.loader import render_to_string
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
@@ -56,7 +57,7 @@ def get_profile_page_content_html(request, page_name, data):
return None
def get_profile_change_page_content_html(request):
def get_profile_change_page_content_html(request, data=None):
init_Dict = {
'firstname': request.user.first_name,
@@ -66,6 +67,25 @@ def get_profile_change_page_content_html(request):
'country': request.user.user_profile.country,
'city': request.user.user_profile.city,
}
if data:
if type(data) == QueryDict:
data = data.dict()
init_Dict.update(data)
# if 'firstname' in data:
# init_Dict.update({'first_name': data['firstname']})
# if 'lastname' in data:
# init_Dict.update({'last_name': data['lastname']})
# if 'email' in data:
# init_Dict.update({'email': data['email']})
# init_Dict.update({'username': data['email']})
# if 'country' in data:
# init_Dict.update({'country': data['country']})
# if 'city' in data:
# init_Dict.update({'city': data['city']})
# if 'tel' in data:
# init_Dict.update({'tel': data['tel']})
from .forms import RegistrationForm
form = RegistrationForm(initial=init_Dict)

View File

@@ -23,6 +23,8 @@ urlpatterns = [
path('support_tickets/', support_tickets_ajax, name='support_tickets_ajax'),
path('password_recovery/', password_recovery_ajax, name='password_recovery_ajax'),
path('password_recovery_confirm/', password_recovery_confirm_ajax, name='password_recovery_confirm_ajax'),
path('change_profile/', change_profile_ajax, name='change_profile_ajax'),
path('change_profile_confirm/', change_profile_confirm_ajax, name='change_profile_confirm_ajax'),

View File

@@ -31,6 +31,125 @@ from GeneralApp.funcs import get_and_set_lang
# html = render_to_string('blocks/profile/b_subscribe.html', Dict, request=request)
# return JsonResponse({'html': html}, status=200)
def password_recovery_confirm_ajax(request):
if request.method != 'POST':
raise Http404
if not 'pass' in request.POST or not 'pass_confirm' in request.POST or not 'user_id' in request.POST:
raise Http404
lang = get_and_set_lang(request)
try:
if not request.POST['pass'] or request.POST['pass'] != request.POST['pass_confirm']:
return JsonResponse({
'status': 'error',
'error': _('Пароли не совпадают')
}, status=400)
user = User.objects.get(id=request.POST['user_id'])
user.set_password(request.POST['pass'])
user.user_profile.authMailCode = None
user.user_profile.save(update_fields=['authMailCode'])
user.is_active = True
user.save()
return JsonResponse({
'status': 'success',
'message': _('Пароль был успешно изменен')
})
except Exception as e:
return JsonResponse({
'status': 'error',
'error': str(e)
}, status=400)
def password_recovery_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
email = request.POST['email']
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
msg = _('Пользователь с указанным email не зарегистрирован на сайте')
return JsonResponse({
'status': 'error',
'error': msg
}, status=400)
user.user_profile.authMailCode = uuid1().hex
user.user_profile.save(update_fields=['authMailCode'])
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 = _('Изменение пароля учетной записи на сайте tripwb.com')
mail_txt = _('Вы получили это письмо потому что '
'был произведен запрос на изменение пароля '
'для данного email на сайте tripwb.com.<br>'
'<br>'
'Если Вы не выполняли запрос - просто проигнорируйте это письмо.<br><br>'
'Если же это были Вы и Вам требуется изменить пароль от учетной записи - '
'перейдите по ссылке, указанной ниже.<br><br>')
link = sets["domain"] + f'/profile/reset_password/{str(user.id)}/{user.user_profile.authMailCode}/'
link_str = f'<a href="{link}">ИЗМЕНИТЬ ПАРОЛЬ</a><br><br>'
sign_txt = _('Спасибо за то, что вы с нами!<br>'
'С уважением,<br>'
'Команда Trip With Bonus.<br>')
Dict = {
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
'project_name': sets['project_name'],
'message_title': subject,
'message_text': f'<p style="padding-left: 20px; line-height: 30px;">'
f'{mail_txt}'
f'{link_str}'
f'{sign_txt}'
f'</p>'
}
html = render_to_string('mail/m_request_offer.html', Dict, request)
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
mail_sets = get_mail_send_options()
to = [email]
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
to = ['web@syncsystems.net']
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
return JsonResponse({
'status': 'sended',
'message': _('На email') + ' ' + email + ' '
+ _('отправлено письмо с инструкциями для восстановления пароля. Если не пришло письмо, проверьте папку СПАМ')
})
except Exception as e:
return JsonResponse({
'status': 'error',
'error': str(e)
}, status=400)
def mailing_subscribe_ajax(request):
if request.method != 'POST':
@@ -47,11 +166,13 @@ def mailing_subscribe_ajax(request):
user.user_profile.mailing_on = True
user.user_profile.save(update_fields=['mailing_on'])
return JsonResponse({
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {
'status': 'sended',
'del_form': True,
'html': _('Подписка на рассылку для адреса ') + user.email + _(' одобрена')
})
}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
if not user:
try:
@@ -64,11 +185,14 @@ def mailing_subscribe_ajax(request):
else:
redirect_url = f"{reverse('registration_page')}?mailingSubscribeRequired=true"
return JsonResponse({
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {
'status': 'sended',
'redirect_url': redirect_url,
'email': email
})
}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
@@ -190,7 +314,18 @@ def send_message_ajax(request):
html = render_to_string('mail/m_request_offer.html', Dict, request)
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
mail_sets = get_mail_send_options()
to = [mail_sets['sender_email'], 'web@syncsystems.net']
opts = get_options_by_opt_types('support_email', only_vals=True)
if opts and 'support_email' in opts:
to = [opts['support_email']]
else:
to = [mail_sets['sender_email']]
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
to = ['web@syncsystems.net']
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
@@ -200,10 +335,14 @@ def send_message_ajax(request):
html = render_to_string('widgets/w_msg_send_success.html', Dict, request)
return JsonResponse({
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {
'status': 'sended',
'html': html
})
}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
return JsonResponse({
'status': 'error',
@@ -241,7 +380,11 @@ def chats_ajax(request):
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string('blocks/profile/b_chats.html', Dict, request=request)
return JsonResponse({'html': html}, status=200)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {'html': html}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@login_required()#login_url='/profile/login/')
def support_tickets_ajax(request):
@@ -252,7 +395,10 @@ def support_tickets_ajax(request):
html = get_profile_support_page_content_html(request)
return JsonResponse({'html': html}, status=200)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {'html': html}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@login_required()#login_url='/profile/login/')
@@ -283,7 +429,10 @@ def change_avatar_confirm_ajax(request):
print(msg)
return JsonResponse({'error': msg}, status=400)
return JsonResponse({'url': request.user.user_profile.avatar.url})
res_Dict = {'url': request.user.user_profile.avatar.url}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@login_required()#login_url='/profile/login/')
@@ -357,8 +506,11 @@ def change_profile_confirm_ajax(request):
if data_for_save:
user_profiles.update(**data_for_save)
html = get_profile_change_page_content_html(request)
return JsonResponse({'html': html}, status=200)
html = get_profile_change_page_content_html(request, data)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {'html': html}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@login_required()#login_url='/profile/login/')
@@ -403,7 +555,10 @@ def my_routes_ajax(request):
}
html = render_to_string('blocks/profile/b_my_routes.html', Dict, request=request)
return JsonResponse({'html': html}, status=200)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@@ -451,6 +606,8 @@ def login_ajax(request):
'redirect_url': redirect_url
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
@@ -466,41 +623,52 @@ def login_ajax(request):
def send_registration_mail(data_Dict, user):
def send_check_email_after_registration(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!')
subject = _('Trip With Bonus - Подтверждение регистрации ')
Dict = {
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
'project_name': sets['project_name'],
'domain': sets['domain'],
'message_title': subject,
}
Dict.update(data_Dict)
html = render_to_string('mail/m_registration.html', Dict)
html = render_to_string('mail/m_confirm_email.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']
to = [user.email]
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
to = ['web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
return res
except Exception as e:
print(f'send_registration_mail Error = {str(e)}')
return None
def registration_ajax(request):
if request.method != 'POST':
raise Http404
@@ -528,28 +696,34 @@ def registration_ajax(request):
user = User.objects.create_user(username=form.data['email'], email=form.data['email'], password=form.data['password'])
# user = auth.authenticate(username=new_user_Dict['name'], password=new_user_Dict['pass'])
if user:
auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
# if user:
# auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
if 'mailingSubscribeRequired' in data and data['mailingSubscribeRequired'] == 'true':
user.user_profile.mailing_on = True
user.last_name = form.data['lastname']
user.first_name = form.data['firstname']
user.is_active = False
user.save()
user.user_profile.phone = form.data['tel']
user.user_profile.authMailCode = uuid1().hex
user.user_profile.save()
mail_Dict = {
'user': user,
'pass': form.data['password']
}
res = send_registration_mail(mail_Dict, user)
res = send_check_email_after_registration(mail_Dict, user)
print(str(res))
# res = send_registration_mail(mail_Dict, user)
res_Dict = {
'redirect_url': reverse('profile_page', args=['dashboard'])
# 'redirect_url': reverse('profile_page', args=['dashboard'])
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:

View File

@@ -8,6 +8,9 @@ from django.contrib.auth import views
urlpatterns = [
path('registration/', registration_View, name='registration_page'),
path('reset_password/<int:user_id>/<str:token>/',
recovery_password_page_View, name='recovery_password_page'),
# path('', user_profile_View, name='user_profile'),
# path('page/chat/<int:user_id>/', chat_w_user_View, name='chat_w_user'),
# path('page/chat/', chat_w_user_View, name='chat_w_user_wo_user_id'),
@@ -46,9 +49,9 @@ urlpatterns = [
#
# # -----------------------
#
# url(r'^check_user_registration_and_activate/(?P<user_id>[\d+]*)/(?P<authCode>[0-9a-z\+\-\_]+)$',
# check_user_registration_and_activate,
# name='check_user_registration_and_activate'),
path('check_user_registration_and_activate/<int:user_id>/<str:authMailCode>/',
check_user_registration_and_activate,
name='check_user_registration_and_activate'),
#
# # url(r'^user/password/reset/$',
# # 'django.contrib.auth.views.password_reset',

View File

@@ -5,7 +5,8 @@ from django.shortcuts import render
from uuid import uuid1
from AuthApp.models import *
from django.contrib import auth
from django.http import HttpResponse, Http404
from django.urls import reverse
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.template import loader, RequestContext
from django.contrib.auth.decorators import login_required
from BaseModels.mailSender import techSendMail
@@ -13,9 +14,69 @@ from django.utils.translation import gettext as _
from datetime import datetime
from django.contrib.auth.decorators import login_required
from .funcs import *
from GeneralApp.funcs import get_inter_http_respose
from GeneralApp.funcs import get_inter_http_response
from GeneralApp.funcs import get_and_set_lang
def send_registration_mail(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,
'user': user
}
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]
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
to = ['web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
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 check_user_registration_and_activate(request, user_id, authMailCode):
try:
user = User.objects.get(
id=user_id,
is_active=False,
user_profile__authMailCode=authMailCode
)
user.is_active = True
user.save(update_fields=['is_active'])
res = send_registration_mail(user)
return HttpResponseRedirect(reverse('login_profile'))
except User.DoesNotExist:
user = None
raise Http404
def registration_View(request):
Dict = {}
@@ -26,7 +87,7 @@ def registration_View(request):
# if request.p
t = loader.get_template('pages/profile/p_registration.html')
return get_inter_http_respose(t, Dict, request)
return get_inter_http_response(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -78,7 +139,7 @@ def profile_page_View(request, page_name, id=None):
# })
t = loader.get_template('pages/profile/p_user_profile.html')
return get_inter_http_respose(t, Dict, request)
return get_inter_http_response(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -120,7 +181,7 @@ def user_profile_View(request):
# request.COOKIES['user_id'] = request.user.id
t = loader.get_template('pages/profile/p_user_profile.html')
response = get_inter_http_respose(t, Dict, request)
response = get_inter_http_response(t, Dict, request)
# response = HttpResponse(t.render(Dict, request))
response.set_cookie('user_id', request.user.id)
return response
@@ -145,7 +206,7 @@ def login_View(request):
request.session['mailingSubscribeRequired'] = 'true'
t = loader.get_template('pages/profile/p_login.html')
return get_inter_http_respose(t, Dict, request)
return get_inter_http_response(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -217,12 +278,19 @@ def decode_get_param(data):
def recovery_password_user(request, uidb64=None, token=None):
from django.contrib.auth.views import PasswordResetConfirmView
def recovery_password_page_View(request, user_id, token):
try:
user = User.objects.get(id=user_id, user_profile__authMailCode=token)
except User.DoesNotExist:
raise Http404
return PasswordResetConfirmView(request=request, uidb64=uidb64, token=token
)
Dict = {
'user': user
}
t = loader.get_template('pages/profile/p_password_recovery.html')
response = get_inter_http_response(t, Dict, request)
return response

View File

@@ -29,12 +29,31 @@ class BaseModel(models.Model):
json_data = models.JSONField(verbose_name=_('Дополнительные данные'), default=dict, blank=True)
media_items = GenericRelation('GeneralApp.MediaItem', related_query_name='grel_%(class)s_for_media_item')
def __str__(self):
if self.name:
return self.name
else:
return str(self.id)
def get_media_items(self, exclude_kwargs=None):
if not exclude_kwargs:
exclude_kwargs = {}
return self.media_items.exclude(
**exclude_kwargs
).filter(
enable=True
).order_by('order')
def get_video_items(self):
exclude_kwargs = {'video': None}
return self.get_media_items(exclude_kwargs=exclude_kwargs)
def get_picture_items(self):
exclude_kwargs = {'picture': None}
return self.get_media_items(exclude_kwargs=exclude_kwargs)
def pop_node_by_name(self, node_name):
if not self.json_data or not node_name in self.json_data:
return None
@@ -108,7 +127,6 @@ class BaseModelViewPage(BaseModel):
FAQ_title = models.CharField(max_length=250, verbose_name=_(u'FAQ Заголовок'), null=True, blank=True)
FAQ_items = GenericRelation('GeneralApp.FAQitem', related_query_name='grel_%(class)s_for_faq_item')
class Meta:
abstract = True

View File

@@ -145,8 +145,8 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
res = None
if type(to) in (list, tuple):
if sets['sender_email'] in to:
to.remove(sets['sender_email'])
# if sets['sender_email'] in to:
# to.remove(sets['sender_email'])
if len(to) > 1:
to_str = u', '.join(to)

View File

@@ -1,22 +1,31 @@
import json
from django.conf import settings
import requests
from requests_pkcs12 import get,post
pkcs12_filename = 'dvldigitalprojects.p12'
pkcs12_password = 'QNlhRStcY7mB'
# для песочницы
# pkcs12_filename = 'dvldigitalprojects.p12'
# pkcs12_password = 'QNlhRStcY7mB'
# api_pass = 'aPqSRVZhxFjjSqbB'
# для прода
# pkcs12_filename = 'dvldigitalprojects.p12'
# pkcs12_password = 'fzSBm6WISje7'
# api_pass = 't9g2+bZSvxNxCu+t'
def get_domain_url():
return 'https://sandboxapi.paymtech.kz/'
return settings.PAY_SYSTEM_URL #'https://sandboxapi.paymtech.kz/'
def get_kwargs_for_request():
return {
'headers': {
'content-type': 'application/json',
},
'auth': ('dvldigitalprojects', 'aPqSRVZhxFjjSqbB'),
'pkcs12_filename': pkcs12_filename,
'pkcs12_password': pkcs12_password
'auth': ('dvldigitalprojects', settings.API_PASS),
'pkcs12_filename': settings.PKCS12_FILENAME,
'pkcs12_password': settings.PKCS12_PASS
}
def ping():
@@ -90,10 +99,14 @@ def create_order(data):
**get_kwargs_for_request()
)
msg = f'create_order answer received = {str(res)}'
msg = f'create_order answer received = {str(res.text)}'
# if res:# and res.status_code > 300:
# msg += f' > ({str(res.text)})'
print(msg)
except Exception as e:
msg = f'Exception create_order POST {url} = {str(e)} ({str(res)})'
if res:
msg += f' > ({str(res.text)})'
print(msg)
res = None

View File

@@ -8,6 +8,9 @@ def get_order_status(order):
from BaseModels.pay_systems.DVL_Group_kaz.api.funcs import get_order_status
res_status = None
if not order or not order.bank_order_id:
return order
try:
res_data = get_order_status(order.bank_order_id)
@@ -67,6 +70,7 @@ def create_subscribe_order(data):
f'{data["subscribe"].name} '
f'для пользователя {data["user"].username}',
'options': {
'force3d': 1,
'auto_charge': 1,
'return_url': f'{sets["domain"]}/profile/page/my_subscribe/'
}

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2024-07-12 17:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('BillingApp', '0005_subscribeorder_last_operation_status'),
]
operations = [
migrations.AlterField(
model_name='subscribeorder',
name='currency',
field=models.CharField(default='KZT', max_length=3, verbose_name='Валюта'),
),
]

View File

@@ -25,7 +25,7 @@ class SubscribeOrder(BaseModel):
)
sum = models.PositiveSmallIntegerField(verbose_name=_('Сумма'), default=0)
currency = models.CharField(verbose_name=_('Валюта'), max_length=3, default='USD')
currency = models.CharField(verbose_name=_('Валюта'), max_length=3, default='KZT')
segment = models.CharField(verbose_name=_('ID Сегмента'), null=True, default=None)
merchant_order_id = models.CharField(verbose_name=_('merchant_order_id'), null=True, default=None)
bank_order_id = models.CharField(verbose_name=_('ID заказа в банке'), null=True, default=None)

View File

@@ -17,6 +17,9 @@ from AuthApp.funcs import get_user_timezone_Dict
def get_unanswered_msgs_count_for_user(user):
if not user or not user.is_authenticated:
return 0
msgs = Message.objects.filter(receiver=user, status='sended', group=None)
return msgs.count()

View File

@@ -38,7 +38,9 @@ def get_file_from_msg_ajax(request):
res_Dict = file
break
return JsonResponse(res_Dict, status=200)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
msg = f'get_file_from_msg_ajax Error = {str(e)}'
@@ -63,10 +65,12 @@ def show_chat_w_user_ajax(request):
tpl_name = 'blocks/profile/b_chats.html'
html = render_to_string(tpl_name, Dict, request=request)
return JsonResponse({'html': html}, status=200)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
msg = f'show_chat_w_user_ajax Error = {str(e)}'
@@ -157,7 +161,9 @@ def update_chat_ajax2(request):
res_Dict.update({
'required_beep': required_beep,
})
return JsonResponse(res_Dict, status=200)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
msg = f'update_chat_ajax2 Error = {str(e)}'
@@ -268,7 +274,10 @@ def update_chat_ajax(request):
res_Dict.update({
'required_beep': required_beep,
})
return JsonResponse(res_Dict, status=200)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
msg = f'update_chat_ajax Error = {str(e)}'
@@ -435,7 +444,11 @@ def support_show_chat_by_ticket_ajax(request):
tpl_name = 'blocks/profile/b_support_chat.html'
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string(tpl_name, Dict, request=request)
return JsonResponse({'html': html}, status=200)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
msg = f'support_show_chat_by_ticket_ajax Error = {str(e)}'
@@ -461,7 +474,11 @@ def support_create_ticket_form_ajax(request):
tpl_name = 'blocks/profile/b_create_ticket.html'
html = render_to_string(tpl_name, Dict, request=request)
return JsonResponse({'html': html}, status=200)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@login_required()#login_url='/profile/login/')
@@ -532,6 +549,8 @@ def create_ticket_ajax(request):
'html': html
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:

View File

@@ -3,6 +3,8 @@ from .models import *
from django.contrib import admin
from django.utils.translation import gettext as _
class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
fieldsets = [

View File

@@ -30,6 +30,17 @@ def get_and_set_lang(request):
return lang
def get_add_to_ajax_response_Dict(user):
context_Dict = {}
from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user
context_Dict.update({
'unanswered_msgs_count': get_unanswered_msgs_count_for_user(user)
})
return context_Dict
def get_inter_Dict(user):
@@ -51,7 +62,7 @@ def get_inter_Dict(user):
return Dict
def get_inter_http_respose(template_obj, context_Dict, request):
def get_inter_http_response(template_obj, context_Dict, request):
context_Dict.update(get_inter_Dict(request.user))
@@ -72,4 +83,9 @@ def get_inter_http_respose(template_obj, context_Dict, request):
# if text and title and not request.user.is_anonymous:
# send_push(user=request.user, title=title, text=text)
from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user
context_Dict.update({
'unanswered_msgs_count': get_unanswered_msgs_count_for_user(request.user)
})
return HttpResponse(template_obj.render(context_Dict, request))

View File

@@ -13,15 +13,15 @@ def get_options_by_opt_types(opt_types, only_vals=False):
res = {}
opts = opts.values('opt_type', 'value', 'prefix')
for item in opts:
if item['opt_type'] == 'domain':
try:
from django.contrib.sites.models import Site
current_site = Site.objects.get_current()
res.update({item['opt_type']: current_site.domain})
continue
except Exception as e:
print(str(e))
# if item['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']}"})

View File

@@ -0,0 +1,48 @@
from django.core.management.base import BaseCommand
from datetime import datetime
from BaseModels.mailSender import techSendMail
from ...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 RoutesApp.search_matches import search_matches
msg = search_matches()
if msg:
print(msg)
log += f'\n{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 datetime.now().hour == 19:
try:
from SubscribesApp.reports import send_mail_for_user_subscribes_that_is_going_to_finish
msg = send_mail_for_user_subscribes_that_is_going_to_finish()
if msg:
print(msg)
log += f'\n{msg}'
except Exception as e:
msg = f'send_mail_for_user_subscribes_that_is_going_to_finish search_matches fail = {str(e)}'
print(msg)
techSendMail(mail_sets, msg, title='every_1hour_start send_mail_for_user_subscribes_that_is_going_to_finish')
if log:
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,41 @@
# Generated by Django 4.2.2 on 2024-11-15 14:50
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('GeneralApp', '0005_option_name_en_option_name_ru_option_prefix_en_and_more'),
]
operations = [
migrations.CreateModel(
name='MediaItem',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_ru', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_en', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_plural', models.TextField(blank=True, null=True, verbose_name='Название (множественное число)')),
('order', models.IntegerField(blank=True, null=True, verbose_name='Очередность отображения')),
('createDT', models.DateTimeField(auto_now_add=True, verbose_name='Дата и время создания')),
('modifiedDT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего изменения')),
('enable', models.BooleanField(db_index=True, default=True, verbose_name='Включено')),
('json_data', models.JSONField(blank=True, default=dict, verbose_name='Дополнительные данные')),
('object_id', models.PositiveIntegerField()),
('picture', models.ImageField(blank=True, null=True, upload_to='media/', verbose_name='Фото')),
('video', models.FileField(blank=True, null=True, upload_to='media/video/', verbose_name='Видео')),
('comment', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
('comment_ru', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
('comment_en', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
('content_type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='contenttypes.contenttype')),
],
options={
'verbose_name': 'Медиа элемент',
'verbose_name_plural': 'Медиа элементы',
},
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 4.2.2 on 2024-11-15 15:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('GeneralApp', '0006_mediaitem'),
]
operations = [
migrations.AlterField(
model_name='mediaitem',
name='picture',
field=models.ImageField(blank=True, null=True, upload_to='uploads/', verbose_name='Фото'),
),
migrations.AlterField(
model_name='mediaitem',
name='video',
field=models.FileField(blank=True, null=True, upload_to='uploads/video/', verbose_name='Видео'),
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 4.2.2 on 2024-11-15 15:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('GeneralApp', '0007_alter_mediaitem_picture_alter_mediaitem_video'),
]
operations = [
migrations.AlterField(
model_name='mediaitem',
name='picture',
field=models.ImageField(blank=True, null=True, upload_to='media_items/photo/', verbose_name='Фото'),
),
migrations.AlterField(
model_name='mediaitem',
name='video',
field=models.FileField(blank=True, null=True, upload_to='media_items/video/', verbose_name='Видео'),
),
]

View File

@@ -3,6 +3,26 @@ from BaseModels.base_models import BaseModelViewPage, BaseModel
from django.utils.translation import gettext_lazy as _
# from ckeditor.fields import RichTextField
from ckeditor_uploader.fields import RichTextUploadingField
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
class MediaItem(BaseModel):
content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
picture = models.ImageField(upload_to='media_items/photo/', verbose_name=_('Фото'), null=True, blank=True)
video = models.FileField(upload_to='media_items/video/', verbose_name=_('Видео'), null=True, blank=True)
comment = models.TextField(verbose_name=_('Комментарий'), null=True, blank=True)
class Meta:
verbose_name = _('Медиа элемент')
verbose_name_plural = _('Медиа элементы')
class StaticPage(BaseModelViewPage):
promo_header = models.BooleanField(verbose_name=_('Промо-хэдер'), default=False)
@@ -29,9 +49,6 @@ class Option(BaseModel):
class FAQitem(BaseModel):
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')

View File

@@ -27,3 +27,9 @@ class FAQitem_TranslationOptions(TranslationOptions):
)
translator.register(FAQitem, FAQitem_TranslationOptions)
class MediaItem_TranslationOptions(TranslationOptions):
fields = (
'name', 'comment',
)
translator.register(MediaItem, MediaItem_TranslationOptions)

View File

@@ -6,6 +6,11 @@ from .views import *
urlpatterns = [
path('', MainPage, name='main'),
path('mover_landing_page/', LandingMoverPage, name='mover_landing_page'),
path('customer_landing_page/', LandingCustomerPage, name='customer_landing_page'),
path('page/<str:url>/', StaticPageView, name='static_page'),
path('test_code', test_code, name='test_code'),
path('generate_routes/<int:routes_count>/', generate_routes, name='generate_routes'),
]

View File

@@ -1,11 +1,12 @@
import json
from django.http import HttpResponse, Http404, FileResponse
from django.http import HttpResponse, Http404, FileResponse, HttpResponseRedirect
from django.template import loader, RequestContext
from django.contrib.auth.decorators import login_required
from .models import *
from django.conf import settings
from .funcs import get_inter_http_respose
from .funcs import get_inter_http_response
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
@@ -14,73 +15,119 @@ from django.views.decorators.csrf import csrf_exempt
from webpush import send_user_notification
import json
from datetime import datetime, timedelta
from django.urls import reverse
def generate_routes(request, routes_count):
if (not request.user
or not request.user.is_active
or not request.user.is_authenticated
or not request.user.is_staff
):
raise Http404
def test_code(request):
from RoutesApp.funcs import get_city_by_type_transport_and_address_point
from RoutesApp.models import Route
from ReferenceDataApp.models import Airport, City
res = None
# import allauth
# from allauth.socialaccount.models import SocialApp
# apps = SocialApp.objects.all()
# apps.delete()
from_air = Airport.objects.get(iata_code='MSQ')
to_air = Airport.objects.get(iata_code='SVO')
# from PushMessages.views import send_push
# send_push(request.user, 'test_title', 'test_content')
routes = [
Route(
type_transport='road',
departure_DT=datetime.now() + timedelta(days=7),
arrival_DT=datetime.now() + timedelta(days=8),
from_address_point=to_air.city.id,
to_address_point=from_air.city.id,
from_city=to_air.city,
to_city=from_air.city,
weight=item,
phone='0987654321',
owner=request.user
) for item in range(routes_count)
]
# from BaseModels.pay_systems.DVL_Group_kaz.api.funcs import create_order
# create_order()
Route.objects.bulk_create(routes)
if res:
if type(res) == str:
return HttpResponse(res)
else:
return res
return HttpResponse('finished')
def test_code(request):
if (not request.user
or not request.user.is_active
or not request.user.is_authenticated
or not request.user.is_staff
):
raise Http404
res = ''
from RoutesApp.search_matches import search_matches
from RoutesApp.models import Route
search_matches(Route.objects.filter(id=17158))
# from RoutesApp.funcs import get_city_by_type_transport_and_address_point
# from RoutesApp.models import Route
# from ReferenceDataApp.models import Airport, City
#
# res = None
#
# from_air = Airport.objects.get(iata_code='MSQ')
# to_air = Airport.objects.get(iata_code='SVO')
#
# routes = [
# Route(
# type_transport='road',
# departure_DT=datetime.now() + timedelta(days=7),
# arrival_DT=datetime.now() + timedelta(days=8),
# from_address_point=to_air.city.id,
# to_address_point=from_air.city.id,
# from_city=to_air.city,
# to_city=from_air.city,
# weight=item,
# phone='0987654321',
# owner=request.user
# ) for item in range(100)
# ]
# routes = [
# Route(
# type_transport='avia',
# departure_DT=datetime(year=2024, month=9, day=1),
# arrival_DT=datetime(year=2024, month=9, day=3),
# from_address_point = from_air.id,
# to_address_point = to_air.id,
# from_city = from_air.city,
# to_city = to_air.city,
# weight = item,
# phone = '1234567890',
# owner = request.user
# ) for item in range(1000)
# ]
#
# Route.objects.bulk_create(routes)
# from AuthApp.models import User
# from SubscribesApp.models import SubscribeForUser, Subscribe
# subscribes_null_price = Subscribe.objects.filter(price=0)
# if not subscribes_null_price:
# res = 'Subscribe not found'
# else:
# subscribe = subscribes_null_price[0]
# users_wo_subscribe = User.objects.filter(rel_userSubscribes_for_user=None)
# for user in users_wo_subscribe:
# u_sub = SubscribeForUser.objects.create(
# user=user,
# subscribe=subscribe,
# paid_period_from_DT=datetime.now(),
# paid_period_to_DT=datetime.now() + timedelta(hours=subscribe.period)
# )
# from RoutesApp.search_matches import search_matches
# search_matches()
# routes = Route.objects.filter()[:10]
# msg = search_matches(routes)
# try:
# # body = request.body
# # data = json.loads(body)
# # if 'head' not in data or 'body' not in data or 'id' not in data:
# # return JsonResponse(status=400, data={"message": "Invalid data format"})
# # user_id = data['id']
# user = request.user
# payload = {'head': '123', 'body': 'qwerty'}
# send_user_notification(user=user, payload=payload, ttl=1000)
# return JsonResponse(status=200, data={"message": "Web push successful"})
# except TypeError:
# return JsonResponse(status=500, data={"message": "An error occurred"})
# from ReferenceDataApp.funcs import parse_data
# parse_data()
# from SubscribesApp.reports import send_mail_for_user_subscribes_that_is_going_to_finish
# send_mail_for_user_subscribes_that_is_going_to_finish()
# routes = Route.objects.all()
#
# for route in routes:
# print(route.id)
# required_save = False
# if not route.from_city:
# route.from_city = get_city_by_type_transport_and_address_point(route.type_transport, route.from_address_point)
# required_save = True
#
# if not route.to_city:
# route.to_city = get_city_by_type_transport_and_address_point(route.type_transport,
# route.to_address_point)
# required_save = True
#
# if required_save:
# route.save()
if res:
if type(res) == str:
return HttpResponse(res)
@@ -97,12 +144,57 @@ def Page404(request, exeption=None):
t = loader.get_template('404.html')
try:
res = get_inter_http_respose(t, Dict, request)
res = get_inter_http_response(t, Dict, request)
return HttpResponse(res, status=404)
except Exception as e:
return HttpResponse(str(e))
def LandingMoverPage(request):
from .init_options import init_options
init_options()
print(f'LOCALE_PATHS = {str(settings.LOCALE_PATHS)}')
page, is_created = StaticPage.objects.get_or_create(url='landing_mover')
Dict = {
'page': page,
}
breadcrumbs_Dict = {
}
Dict.update({'breadcrumbs': breadcrumbs_Dict})
t = loader.get_template('pages/p_mover_landing_page.html')
return get_inter_http_response(t, Dict, request)
def LandingCustomerPage(request):
from .init_options import init_options
init_options()
print(f'LOCALE_PATHS = {str(settings.LOCALE_PATHS)}')
page, is_created = StaticPage.objects.get_or_create(url='landing_customer')
Dict = {
'page': page,
}
breadcrumbs_Dict = {
}
Dict.update({'breadcrumbs': breadcrumbs_Dict})
t = loader.get_template('pages/p_customer_landing_page.html')
return get_inter_http_response(t, Dict, request)
def MainPage(request):
@@ -134,7 +226,7 @@ def MainPage(request):
Dict.update({'breadcrumbs': breadcrumbs_Dict})
t = loader.get_template('pages/p_main.html')
return get_inter_http_respose(t, Dict, request)
return get_inter_http_response(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -157,6 +249,12 @@ def StaticPageView(request, url):
'route_form': RouteForm(),
'owner_type': 'mover'
})
elif url in ['landing_customer', 'landing_mover']:
raise Http404
# return HttpResponseRedirect(reverse('customer_landing_page'))
# elif url == 'landing_mover':
# return HttpResponseRedirect(reverse('mover_landing_page'))
# elif url == 'works':
# return WorksPage(request)
elif url in ['main']:
@@ -182,7 +280,7 @@ def StaticPageView(request, url):
# send_push(user=request.user, title='title', text='text')
t = loader.get_template('pages/p_static_page.html')
return get_inter_http_respose(t, Dict, request)
return get_inter_http_response(t, Dict, request)
# return HttpResponse(t.render(Dict, request))

View File

@@ -2,6 +2,7 @@ from django.contrib import admin
from sets.admin import Admin_Trans_BaseModel
from .models import *
from modeltranslation.admin import TranslationAdmin
from django.utils.translation import gettext as _
class Admin_Country(Admin_Trans_BaseModel):
fieldsets = [
@@ -10,11 +11,20 @@ class Admin_Country(Admin_Trans_BaseModel):
'fields': [
'name', 'enable', 'short_code', 'code',
]
}]
}],
[_('Дополнительно'), {
'classes': ['wide', 'collapse'],
'fields': (
'timezone',
'geo_lat', 'geo_lon',
'json_data',
)
}],
]
list_display = [
'id', 'name', 'name_en', 'name_ru',
'timezone',
'short_code', 'code',
'enable', 'area_id', 'parsing_finished_DT',
'order', 'modifiedDT', 'createDT']
@@ -22,18 +32,35 @@ class Admin_Country(Admin_Trans_BaseModel):
admin.site.register(Country, Admin_Country)
class Admin_City(Admin_Trans_BaseModel):
def cur_dt(self, obj):
if obj.timezone:
return obj.get_current_datetime()
else:
return '-'
cur_dt.short_description = 'текущее время'
fieldsets = [
[None, {
'classes': ['wide'],
'fields': [
'name', 'enable', 'country',
]
}]
}],
[_('Дополнительно'), {
'classes': ['wide', 'collapse'],
'fields': (
'timezone',
'geo_lat', 'geo_lon',
'json_data',
)
}],
]
list_display = [
'id', 'name', 'name_en', 'name_ru',
'country',
'timezone', 'cur_dt',
'enable', 'area_id', 'parsing_finished_DT',
'order', 'modifiedDT', 'createDT']
search_fields = ['id', 'name_en', 'name_ru', 'country__name']
@@ -50,12 +77,21 @@ class Admin_Airport(Admin_Trans_BaseModel):
'international_name',
# 'area_id'
]
}]
}],
[_('Дополнительно'), {
'classes': ['wide', 'collapse'],
'fields': (
'timezone',
'geo_lat', 'geo_lon',
'json_data',
)
}],
]
list_display = [
'id', 'name', 'name_en', 'name_ru',
'city', 'iata_code', 'icao_code',
'timezone',
'international_name',
'enable', 'area_id', 'parsing_finished_DT',
'order', 'modifiedDT', 'createDT']

View File

@@ -3,24 +3,45 @@ from .models import *
import hashlib, json
from datetime import datetime, timedelta
from django.db.models import Q
from timezonefinder import TimezoneFinder
tzf = TimezoneFinder()
def search_cities_in_db(search_str):
res_data = []
Q_obj = Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \
Q(country__name_en__icontains=search_str) | Q(country__name_ru__icontains=search_str)
res_data = City.objects.filter(Q_obj).values('id', 'name', 'country__name')
objs = City.objects.filter(Q_obj)
if objs:
ids = objs.values_list('id', flat=True)
objs_wo_tz = objs.filter(timezone=None)
for item in objs_wo_tz:
item.get_n_save_timezone()
res_data = City.objects.filter(id__in=ids).values(
'id', 'name', 'country__name', 'timezone'
)
return list(res_data)
def search_airports_in_db(search_str):
res_data = []
Q_obj = Q(iata_code__icontains=search_str) | \
Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \
Q(city__name_en__icontains=search_str) | Q(city__name_ru__icontains=search_str) | \
Q(city__country__name_en__icontains=search_str) | \
Q(city__country__name_ru__icontains=search_str)
res_data = Airport.objects.filter(Q_obj).values('id', 'name', 'iata_code', 'city__name', 'city__country__name')
objs = Airport.objects.filter(Q_obj)
if objs:
ids = objs.values_list('id', flat=True)
objs_wo_tz = objs.filter(city__timezone=None)
for item in objs_wo_tz:
item.city.get_n_save_timezone()
res_data = Airport.objects.filter(id__in=ids).values(
'id', 'name', 'iata_code',
'city__name', 'city__country__name', 'city__timezone'
)
return list(res_data)
@@ -57,25 +78,39 @@ def create_airports_by_airportsList(airportsList, city=None):
if airport_Dict['iata']:
kwargs.update({'iata_code': airport_Dict['iata']})
airport = Airport.objects.get(**kwargs)
if airport.geo_lat and airport.geo_lon and not airport.timezone:
airport.timezone = tzf.timezone_at(
lng=float(airport.geo_lon), lat=float(airport.geo_lat))
airport.modifiedDT = datetime.now()
airport.save()
print(f'airport {airport.international_name} - {airport.timezone}')
except Airport.DoesNotExist:
print(f' - - {airport_Dict["iata"]} не найден в БД > добавляем')
except Exception as e:
print(f'error = {str(e)}')
if not airport:
geo_lat = float(airport_Dict['@lat'])
geo_lon = float(airport_Dict['@lon'])
tz = tzf.timezone_at(lng=geo_lon, lat=geo_lat)
print(f'airport {airport_Dict["int_name"]} - {tz}')
airport_kwargs = {
'city': city,
# 'name_ru': airport_Dict['name:ru'],
# 'name_en': airport_Dict['name:en'],
'timezone': tz,
'geo_lat': str(airport_Dict['@lat']),
'geo_lon': str(airport_Dict['@lon']),
'geo_lat': str(geo_lat),
'geo_lon': str(geo_lon),
'international_name': airport_Dict['int_name'],
'iata_code': airport_Dict['iata'],
'icao_code': airport_Dict['icao'],
'modifiedDT': datetime.now(),
}
if airport_Dict['name:ru']:
@@ -119,7 +154,10 @@ def parse_data():
country = Country.objects.get(**kwargs)
if country.parsing_finished_DT and (datetime.now() - country.parsing_finished_DT).days < 30:
if (country.parsing_finished_DT
and (datetime.now() - country.parsing_finished_DT).days < 30
and country.timezone
):
print(f' + {country.name} - существует в БД, не требует парсинга')
continue
@@ -194,6 +232,12 @@ def parse_data():
else:
print(f'error = {str(e)}')
geo_lat = float(city_Dict['@lat'])
geo_lon = float(city_Dict['@lon'])
tz = tzf.timezone_at(lng=geo_lon, lat=geo_lat)
if not city or not city.timezone:
print(f'city {city_Dict["name:en"]} - {tz}')
# собираем данные
city_kwargs = {
'country': country,
@@ -201,8 +245,11 @@ def parse_data():
# 'name_ru': city_Dict['name:ru'],
# 'name_en': city_Dict['name:en'],
'geo_lat': str(city_Dict['@lat']),
'geo_lon': str(city_Dict['@lon']),
'timezone': tz,
'geo_lat': str(geo_lat),
'geo_lon': str(geo_lon),
}
if city_Dict['name:ru']:
@@ -232,8 +279,12 @@ def parse_data():
hash_data = hashlib.md5(json.dumps(country_Dict, sort_keys=True, ensure_ascii=True).encode('utf-8')).hexdigest()
country.add_node_to_json_data({'hash': hash_data})
if not country.timezone:
country.timezone = tzf.timezone_at(lng=float(country.geo_lon), lat=float(country.geo_lat))
print(f'country {country.name} - {country.timezone}')
if 'parsing_status' in country_Dict and country_Dict['parsing_status'] == 'finished':
country.parsing_finished_DT = datetime.now()
country.save(update_fields=['parsing_finished_DT'])
country.save()
return True

View File

@@ -13,7 +13,7 @@ from django.template.loader import render_to_string
from django.urls import reverse
from django.db.models import Q
import json
from GeneralApp.funcs import get_inter_http_respose
from GeneralApp.funcs import get_inter_http_response
from GeneralApp.funcs import get_and_set_lang
def get_address_point_ajax(request):
@@ -56,10 +56,12 @@ def get_address_point_ajax(request):
item['fullname'] = f'{item["iata_code"]} - {item["name"]}'
item['city_name'] = item['city__name']
item['country_name'] = item['city__country__name']
item['city_DT'] = datetime.now(tz=pytz.timezone(item['city__timezone']))
else:
item['city_name'] = item['name']
item['country_name'] = item['country__name']
item['fullname'] = f'{item["city_name"]} / {item["country_name"]}'
item['city_DT'] = datetime.now(tz=pytz.timezone(item['timezone']))
html = f"{html}{render_to_string('widgets/w_ac_input_address_point.html', item)}"
i += 1
@@ -68,6 +70,8 @@ def get_address_point_ajax(request):
'res_search_list': html
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:

View File

@@ -0,0 +1,28 @@
# Generated by Django 4.2.2 on 2024-07-12 17:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ReferenceDataApp', '0005_remove_airport_parsing_finished_and_more'),
]
operations = [
migrations.AddField(
model_name='airport',
name='timezone',
field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона'),
),
migrations.AddField(
model_name='city',
name='timezone',
field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона'),
),
migrations.AddField(
model_name='country',
name='timezone',
field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона'),
),
]

View File

@@ -1,6 +1,8 @@
import pytz
from django.db import models
from BaseModels.base_models import BaseModel
from django.utils.translation import gettext_lazy as _
from datetime import datetime
class Country(BaseModel):
international_name = models.CharField(max_length=250, verbose_name=_('Международное название'), blank=True, null=True)
@@ -15,6 +17,8 @@ class Country(BaseModel):
geo_lat = models.CharField(max_length=20, verbose_name=_('GPS широта'), blank=True, null=True)
geo_lon = models.CharField(max_length=20, verbose_name=_('GPS долгота'), blank=True, null=True)
timezone = models.CharField(max_length=250, verbose_name=_('Часовая зона'), blank=True, null=True)
area_id = models.BigIntegerField(blank=True, null=True)
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
@@ -46,6 +50,8 @@ class City(BaseModel):
area_id = models.BigIntegerField(blank=True, null=True)
timezone = models.CharField(max_length=250, verbose_name=_('Часовая зона'), blank=True, null=True)
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
def __str__(self):
@@ -54,6 +60,17 @@ class City(BaseModel):
else:
return f'{self.id}'
def get_n_save_timezone(self):
from ReferenceDataApp.funcs import tzf
self.timezone = tzf.timezone_at(lng=float(self.geo_lon), lat=float(self.geo_lat))
self.save(update_fields=['timezone'])
return self.timezone
def get_current_datetime(self):
if not self.timezone:
self.timezone = self.get_n_save_timezone()
return datetime.now(tz=pytz.timezone(self.timezone))
def get_country_n_city_str(self):
country = _('Неизвестно')
city = self.name
@@ -83,6 +100,8 @@ class Airport(BaseModel):
geo_lat = models.CharField(max_length=20, verbose_name=_('GPS широта'), blank=True, null=True)
geo_lon = models.CharField(max_length=20, verbose_name=_('GPS долгота'), blank=True, null=True)
timezone = models.CharField(max_length=250, verbose_name=_('Часовая зона'), blank=True, null=True)
area_id = models.BigIntegerField(blank=True, null=True)
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)

View File

@@ -3,17 +3,33 @@ from .models import *
from django.contrib import admin
class Admin_Route(Admin_Trans_BaseModel):
readonly_fields = [
# 'highlight_end_DT',
'rising_DT'
]
list_display = [
'id', 'owner_type', 'receive_msg_by_email', 'type_transport', 'cargo_type',
'id', 'owner_type',
'rising_DT',
'receive_msg_by_email', 'type_transport', 'cargo_type',
'departure_DT', 'from_city', 'from_place',
'arrival_DT', 'to_city', 'to_place', 'owner',
'order', 'modifiedDT', 'createDT'
]
list_editable = ['rising_DT']
list_display_links = ['id']
list_filter = ['owner_type', 'type_transport', 'cargo_type', 'from_place', 'arrival_DT', 'modifiedDT', 'createDT']
search_fields = ['owner__first_name', 'owner__last_name']
raw_id_fields = ['from_city', 'to_city']
list_filter = [
'owner_type', 'type_transport',
'rising_DT',
'cargo_type',
'from_place', 'arrival_DT',
'modifiedDT', 'createDT'
]
admin.site.register(Route,Admin_Route)
search_fields = [
'owner__first_name', 'owner__last_name', 'from_city__name', 'to_city__name', 'owner__email'
]
raw_id_fields = ['from_city', 'to_city', 'owner']
admin.site.register(Route, Admin_Route)

View File

@@ -1,8 +1,11 @@
from BaseModels.mailSender import techSendMail
from GeneralApp.funcs_options import get_mail_send_options
from .models import *
from .forms import *
from django.utils.translation import gettext as _
from django.template.loader import render_to_string
from datetime import datetime
from datetime import datetime, timedelta
from django.db.models import F, Q
elements_on_page = 25
@@ -108,9 +111,9 @@ def get_profile_new_route_page_html(request, data):
return html
def get_country_n_city_str_by_type_transport_and_address_point(type_transport, address_point):
city = get_city_by_type_transport_and_address_point(type_transport, address_point)
return city.get_country_n_city_str()
# def get_country_n_city_str_by_type_transport_and_address_point(type_transport, address_point):
# city = get_city_by_type_transport_and_address_point(type_transport, address_point)
# return city.get_country_n_city_str()
def get_city_by_type_transport_and_address_point(type_transport, address_point):
@@ -126,6 +129,16 @@ def get_city_by_type_transport_and_address_point(type_transport, address_point):
print(msg)
return None
def get_city_by_address_point(address_point):
from ReferenceDataApp.models import Airport, City
try:
return City.objects.get(id=address_point)
except Exception as e:
msg = f'get_city_by_address_point Error = {str(e)}, address_point = {address_point}'
print(msg)
return None
def get_profile_my_routes_page_content_html(request):
routes_Dict = get_routes_Dict(request.user)
@@ -159,6 +172,7 @@ def get_routes_Dict(user=None, data=None):
'owner': user
})
from_el = None
to_el = None
@@ -208,16 +222,19 @@ def get_routes_Dict(user=None, data=None):
):
kwargs.update({key: val})
if key == 'from_address_point':
city = get_city_by_type_transport_and_address_point(type_transport, val)
if key == 'from_address_point': # в from_address_point всегда город
# city = get_city_by_type_transport_and_address_point(type_transport, val)
city = get_city_by_address_point(val)
kwargs.update({f'from_city': city})
res_Dict.update({
'from_address_point_txt': city.get_country_n_city_str()
})
if key == 'to_address_point':
city = get_city_by_type_transport_and_address_point(type_transport, val)
if key == 'to_address_point': # в to_address_point всегда город
# city = get_city_by_type_transport_and_address_point(type_transport, val)
city = get_city_by_address_point(val)
kwargs.update({f'to_city': city})
res_Dict.update({
'to_address_point_txt': city.get_country_n_city_str()
@@ -228,9 +245,41 @@ def get_routes_Dict(user=None, data=None):
if key == 'to_el':
to_el = int(val)
routes = Route.objects.filter(**kwargs).order_by('-departure_DT', '-arrival_DT', '-modifiedDT')
# rising_routes = Route.objects.filter(
# **kwargs,
# ).exclude(
# rising_DT=None
# ).order_by(
# '-rising_DT', '-departure_DT', '-arrival_DT', '-modifiedDT'
# )
# routes = Route.objects.exclude(
# rising_DT=None
# ).filter(
# departure_DT__lt=datetime.now()
# )
# routes.update(
# rising_DT=None
# )
routes_rising_off = Route.objects.exclude(rising_DT=None).filter(
Q(rising_DT__lt=datetime.now() - timedelta(days=1)) | Q(departure_DT__lt=datetime.now())
)
if routes_rising_off:
routes_rising_off.update(rising_DT=None)
routes = Route.objects.filter(
**kwargs
).order_by(
F('rising_DT').desc(nulls_last=True),
# '-rising_DT',
'-departure_DT', '-arrival_DT', '-modifiedDT'
)
routes_count = routes.count()
if from_el and to_el:
routes = routes[from_el:to_el]
elif from_el:

View File

@@ -1,4 +1,5 @@
import json
from copy import deepcopy
from django.shortcuts import render
@@ -10,7 +11,7 @@ from django.template import loader, RequestContext
from django.contrib.auth.decorators import login_required
from BaseModels.mailSender import techSendMail
from django.utils.translation import gettext as _
from datetime import datetime
from datetime import datetime, timedelta
from django.template.loader import render_to_string
from django.urls import reverse
from .forms import *
@@ -37,12 +38,23 @@ def highlight_route_ajax(request):
msg = _('Не найден маршрут')
return JsonResponse({'errors': msg})
if not route.get_permission_for_raise():
if not route.get_permission_for_highlight():
msg = _('Нет доступа к выделению')
return JsonResponse({'errors': msg})
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(request.user)
user_subscribe.used_route_highlight_count += 1
user_subscribe.save(update_fields=['used_route_highlight_count'])
route.highlight_color = '#FF0000'
route.save(update_fields=['highlight_color'])
highlight_hours = user_subscribe.get_highlight_hours()
route.highlight_end_DT = datetime.now() + timedelta(hours=highlight_hours)
route.save(update_fields=['highlight_color', 'highlight_end_DT'])
Dict = {
'route': route,
@@ -53,7 +65,10 @@ def highlight_route_ajax(request):
res_Dict = {
'html': html
}
res_Dict.update(user_subscribe.remains_route_adding_options())
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@@ -82,7 +97,17 @@ def raise_route_ajax(request):
route.rising_DT = datetime.now()
route.save(update_fields=['rising_DT'])
return JsonResponse({'status': 'ok'})
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(request.user)
user_subscribe.used_route_rising_count += 1
user_subscribe.save(update_fields=['used_route_rising_count'])
res_Dict = {'status': 'ok'}
res_Dict.update(user_subscribe.remains_route_adding_options())
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
def del_route_ajax(request):
@@ -113,6 +138,8 @@ def del_route_ajax(request):
'html': html
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
@@ -166,11 +193,13 @@ def edit_route_ajax(request):
return JsonResponse({'errors': msg})
html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
resDict = {
res_Dict = {
'html': html,
'btn_title': _('Сохранить изменения')
}
return JsonResponse(resDict, status=200)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@@ -209,7 +238,10 @@ def new_route_view_ajax(request):
# html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
return JsonResponse({'html': html}, status=200)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
def find_routes_ajax(request):
@@ -233,6 +265,7 @@ def find_routes_ajax(request):
if 'errors' in routes_Dict:
return JsonResponse(routes_Dict, status=400)
if routes_Dict['routes']:
html = render_to_string('blocks/b_search_routes.html', routes_Dict, request=request)
else:
@@ -245,6 +278,8 @@ def find_routes_ajax(request):
# 'form': RouteForm(initial=data)
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
@@ -265,11 +300,28 @@ def get_my_routes_ajax(request):
lang = get_and_set_lang(request)
data = request.POST.dict()
if not data and request.body:
data = json.loads(request.body)
try:
routes_Dict = get_routes_Dict(request.user)
if not request.user or request.user.is_anonymous:
msg = (f'get_my_routes_ajax not have user - user={str(request.user)}<br>'
f'data={str(data)}<br>'
f'request={str(request)}')
mail_sets = get_mail_send_options()
techSendMail(mail_sets, msg)
routes_Dict = get_routes_Dict(request.user, data)
if 'errors' in routes_Dict:
return JsonResponse(routes_Dict, status=400)
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(request.user)
if user_subscribe:
routes_Dict.update(user_subscribe.remains_route_adding_options())
html = render_to_string('blocks/profile/b_my_routes.html', routes_Dict, request=request)
@@ -277,6 +329,8 @@ def get_my_routes_ajax(request):
'html': html
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
@@ -302,6 +356,7 @@ def create_or_change_route_ajax(request, route_id=None):
lang = get_and_set_lang(request)
Dict = {}
route_old_Dict = None
try:
@@ -316,6 +371,7 @@ def create_or_change_route_ajax(request, route_id=None):
if route:
form = RouteForm(data, instance=route)
Dict.update({'route': route})
route_old_Dict = deepcopy(route.__dict__)
else:
form = RouteForm(data)
@@ -336,6 +392,16 @@ def create_or_change_route_ajax(request, route_id=None):
if obj.to_address_point:
obj.to_city = get_city_by_type_transport_and_address_point(obj.type_transport, obj.to_address_point)
if route_old_Dict:
if route_old_Dict['highlight_color'] != obj.highlight_color:
obj.highlight_color = route_old_Dict['highlight_color']
if route_old_Dict['highlight_end_DT'] != obj.highlight_end_DT:
obj.highlight_end_DT = route_old_Dict['highlight_end_DT']
if route_old_Dict['rising_DT'] != obj.rising_DT:
obj.rising_DT = route_old_Dict['rising_DT']
obj.owner = request.user
obj.save()
@@ -343,6 +409,11 @@ def create_or_change_route_ajax(request, route_id=None):
routes_Dict = get_routes_Dict(request.user)
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(request.user)
if user_subscribe:
routes_Dict.update(user_subscribe.remains_route_adding_options())
if 'errors' in routes_Dict:
form.errors.update(routes_Dict['errors'])
Dict.update({'form': form})
@@ -356,6 +427,8 @@ def create_or_change_route_ajax(request, route_id=None):
'route_id': route_id
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:

View File

@@ -1,36 +0,0 @@
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,18 @@
# Generated by Django 4.2.2 on 2024-08-13 13:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RoutesApp', '0007_rename_select_color_route_highlight_color'),
]
operations = [
migrations.AddField(
model_name='route',
name='highlight_end_DT',
field=models.DateTimeField(blank=True, null=True, verbose_name='Дата и время окончания выделения'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2024-11-12 10:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RoutesApp', '0008_route_highlight_end_dt'),
]
operations = [
migrations.AlterField(
model_name='route',
name='phone',
field=models.CharField(blank=True, null=True, verbose_name='Укажите номер для связи'),
),
]

View File

@@ -57,7 +57,7 @@ class Route(BaseModel):
verbose_name=_('Куда можете доставить?'))
cargo_type = models.CharField(choices=cargo_type_choices, default='parcel', verbose_name=_('Могу перевезти'))
weight = models.IntegerField(verbose_name=_('Укажите вес до (кг)'))
phone = models.CharField(verbose_name=_('Укажите номер для связи'))
phone = models.CharField(verbose_name=_('Укажите номер для связи'), blank=True, null=True)
extra_phone = models.CharField(verbose_name=_('Дополнительный номер'), blank=True, null=True)
receive_msg_by_email = models.BooleanField(default=False, verbose_name=_('Получать уведомления по E-mail'))
receive_msg_by_sms = models.BooleanField(default=False, verbose_name=_('Получать уведомления по SMS'))
@@ -71,6 +71,10 @@ class Route(BaseModel):
verbose_name=_('Цвет выделения'),
blank=True, null=True
)
highlight_end_DT = models.DateTimeField(
verbose_name=_('Дата и время окончания выделения'),
blank=True, null=True
)
def __str__(self):
if self.name:
@@ -95,6 +99,17 @@ class Route(BaseModel):
return False
def get_permission_for_highlight(self):
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(self.owner)
if not user_subscribe:
return False
data_Dict = user_subscribe.remains_route_adding_options()
if data_Dict['remains_route_highlight_count'] > 0:
return True
return False
def from_country_n_city_str(self):
res = _('Неизвестно')

View File

@@ -47,7 +47,7 @@ def send_push_message_for_found_matches_routes(route, data_Dict):
def send_mail_found_matches_routes(route, data_Dict):
def send_mail_found_matches_routes(route, matched_route, data_Dict):
print(f'send_mail_found_matches_routes to route id = {route.id}')
Dict = {
@@ -59,7 +59,7 @@ def send_mail_found_matches_routes(route, data_Dict):
mail_sets = get_mail_send_options()
to = [route.owner.email, 'web@syncsystems.net']
to = [route.owner.email]
subject = _('Мы нашли исполнителя по Вашему объявлению!')
res = admin_send_mail_by_SMTPlib(
mail_sets,
@@ -68,9 +68,68 @@ def send_mail_found_matches_routes(route, data_Dict):
html_content=html
)
subject = f'route matches {route.id} <> {matched_route.id} send to {route.owner.email}'
to = ['web@syncsystems.net', 'sa@a3-global.com']
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
return res
def user_notify_by_result_search_matches(route_for_send, founded_route, params):
log = ''
data_Dict = None
try:
data_Dict = get_Dict_for_send_msgs(params, founded_route.owner_type)
except Exception as e:
msg = f'<br>\n! search_matches Error get_Dict_for_send_msgs = {str(e)}'
print(msg)
log += msg
if data_Dict and check_option_in_cur_user_subscribe(
route_for_send.owner, 'push уведомления'
):
try:
msg = send_push_message_for_found_matches_routes(route_for_send, data_Dict)
if msg:
log += msg
except Exception as e:
msg = f'<br>\n! search_matches Error send_push_message_for_found_matches_routes = {str(e)}'
print(msg)
log += msg
if data_Dict and check_option_in_cur_user_subscribe(
route_for_send.owner,
'уведомление на e-mail о появлении перевозчика по заданным критериям'
):
try:
msg = send_mail_found_matches_routes(route_for_send, founded_route, data_Dict)
if msg:
log += msg
except Exception as e:
msg = f'<br>\n! search_matches Error send_mail_found_matches_routes = {str(e)}'
print(msg)
log += msg
return log
def users_notify_by_result_search_matches(source_route, found_routes, params):
log = ''
log += user_notify_by_result_search_matches(source_route, found_routes[0], params)
for route in found_routes:
log += user_notify_by_result_search_matches(route, source_route, params)
return log
def search_matches(for_routes=None):
print('search_matches')
@@ -84,8 +143,11 @@ def search_matches(for_routes=None):
)
check_fields = [
'type_transport', 'departure_DT', 'arrival_DT', 'from_address_point', 'to_address_point',
'from_place', 'to_place', 'cargo_type', 'weight'
'type_transport', 'departure_DT', 'arrival_DT',
# 'from_address_point', 'to_address_point',
'from_place', 'to_place',
'cargo_type', 'weight',
'from_city', 'to_city',
]
if for_routes:
@@ -106,11 +168,20 @@ def search_matches(for_routes=None):
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':
# params.update({f"{field_name}__lte": field_val})
kwargs.update({f"{field_name}__lte": field_val})
else:
# params.update({f"{field_name}__gte": field_val})
kwargs.update({f"{field_name}__gte": field_val})
elif field_name == 'from_city':
params.update({'from_address_point': field_val.id})
kwargs.update({field_name: field_val})
elif field_name == 'to_city':
params.update({'to_address_point': field_val.id})
kwargs.update({field_name: field_val})
# elif field_name in ['from_address_point', 'to_address_point']:
# kwargs.update({field_name: field_val})
else:
kwargs.update({field_name: field_val})
params.update({field_name: field_val})
@@ -128,39 +199,9 @@ def search_matches(for_routes=None):
if found_routes:
msg = f'found routes for send messages = {found_routes.count()}'
print(msg)
data_Dict = None
try:
data_Dict = get_Dict_for_send_msgs(params, found_routes[0].owner_type)
except Exception as e:
msg = f'<br>\n! search_matches Error get_Dict_for_send_msgs = {str(e)}'
print(msg)
log += msg
if data_Dict and check_option_in_cur_user_subscribe(
route.owner, 'push уведомления'
):
try:
msg = send_push_message_for_found_matches_routes(route, data_Dict)
if msg:
log += msg
except Exception as e:
msg = f'<br>\n! search_matches Error send_push_message_for_found_matches_routes = {str(e)}'
print(msg)
log += msg
if data_Dict and check_option_in_cur_user_subscribe(
route.owner,
'уведомление на e-mail о появлении перевозчика по заданным критериям'
):
try:
msg = send_mail_found_matches_routes(route, data_Dict)
if msg:
log += msg
except Exception as e:
msg = f'<br>\n! search_matches Error send_mail_found_matches_routes = {str(e)}'
print(msg)
log += msg
log += users_notify_by_result_search_matches(route, found_routes, params)
except Exception as e:
msg = f'<br>\n! search_matches Error = {str(e)}'

View File

@@ -11,7 +11,7 @@ from django.utils.translation import gettext as _
from datetime import datetime
from .funcs import *
from .forms import *
from GeneralApp.funcs import get_inter_http_respose
from GeneralApp.funcs import get_inter_http_response
@@ -58,7 +58,9 @@ def route_search_results_View(request):
})
t = loader.get_template('pages/p_results_find_route.html')
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
return get_inter_http_response(t, Dict, request)
except Exception as e:
msg = f'!!! --- route_search_results_View Exception {str(e)}'
print(msg)
raise Http404

0
SitemapApp/__init__.py Normal file
View File

3
SitemapApp/models.py Normal file
View File

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

16
SitemapApp/tests.py Normal file
View File

@@ -0,0 +1,16 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)

11
SitemapApp/urls.py Normal file
View File

@@ -0,0 +1,11 @@
from django.urls import include, path
from django.contrib.sitemaps import views as sitemaps_views
from django.views.decorators.cache import cache_page
from django.contrib.sitemaps.views import sitemap
from SitemapApp.views import sitemaps
urlpatterns = [
path('sitemap.xml', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap')
]

149
SitemapApp/views.py Normal file
View File

@@ -0,0 +1,149 @@
# coding=utf-8
from django.contrib.sitemaps import Sitemap
from django.urls import reverse
from BaseModels.mailSender import techSendMail
import json
from datetime import datetime, time, timezone
# from PageSetsApp.models import *
# from ArticlesApp.models import *
# from BaseModels.base_api_requests import base_api_request
# from tEsiteProj.settings import API_URL
from django.db.models import Q
limit_records = 1000
sitemaps = {
}
protocol = 'https'
class sm_StaticPage(Sitemap):
changefreq = 'monthly'
priority = 1
i18n = True
protocol = protocol
def items(self):
from GeneralApp.models import StaticPage
return StaticPage.objects.filter(enable=True)
def location(self, item):
if item.url == 'main':
return reverse('main')
else:
return reverse('static_page', args=[item.url])
def lastmod(self, obj):
return obj.modifiedDT
sitemaps.update({'static_pages': sm_StaticPage})
class sm_ArticlesPage(Sitemap):
changefreq = 'daily'
priority = 2
i18n = True
protocol = protocol
def items(self):
return ['']
def location(self, item):
return reverse('articles')
def lastmod(self, obj):
from ArticlesApp.models import ArticleModel
article = ArticleModel.objects.filter(enable=True).order_by('-modifiedDT').first()
if article:
return article.modifiedDT
else:
return datetime.now()
sitemaps.update({'articles_page': sm_ArticlesPage})
class sm_Article(Sitemap):
changefreq = 'yearly'
priority = 2
i18n = True
protocol = protocol
def items(self):
from ArticlesApp.views import ArticleModel
objs = ArticleModel.objects.filter(enable=True)
return objs
def location(self, item):
return reverse('article_one', args=[item.url])
def lastmod(self, obj):
return obj.modifiedDT
sitemaps.update({'article': sm_Article})
class sm_UserPage(Sitemap):
changefreq = 'yearly'
priority = 2
i18n = True
protocol = protocol
def items(self):
from ArticlesApp.views import UserPageModel
objs = UserPageModel.objects.filter(enable=True)
return objs
def location(self, item):
return reverse('user_page', args=[item.url])
def lastmod(self, obj):
return obj.modifiedDT
sitemaps.update({'user_page': sm_UserPage})
class sm_Registration(Sitemap):
changefreq = 'never'
priority = 1
i18n = True
protocol = protocol
def items(self):
return ['']
def location(self, item):
return reverse('registration_page')
def lastmod(self, obj):
return datetime(2024, 6, 1)
sitemaps.update({'registration': sm_Registration})
class sm_Login(Sitemap):
changefreq = 'never'
priority = 1
i18n = True
protocol = protocol
def items(self):
return ['']
def location(self, item):
return reverse('login_profile')
def lastmod(self, obj):
return datetime(2024, 6, 1)
sitemaps.update({'login': sm_Login})

View File

@@ -45,7 +45,8 @@ class Admin_SubscribeOption(Admin_Trans_BaseModel):
(None, {
'classes': ['wide'],
'fields': (
'allow_route_rising_count', 'allow_route_highlight_count'
('allow_route_rising_count',),
('allow_route_highlight_count', 'route_highlight_hours'),
)
}),
)
@@ -53,6 +54,8 @@ class Admin_SubscribeOption(Admin_Trans_BaseModel):
list_display = [
'id', 'enable',
'name',
'allow_route_rising_count',
'allow_route_highlight_count', 'route_highlight_hours',
'order', 'modifiedDT', 'createDT'
]
list_editable = ['enable']
@@ -96,6 +99,6 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
'modifiedDT', 'createDT'
]
list_editable = ['enable']
search_fields = ['name']
search_fields = ['name', 'id', 'user__email', 'user__first_name', 'user__last_name']
admin.site.register(SubscribeForUser,Admin_SubscribeForUser)

View File

@@ -5,6 +5,17 @@ from datetime import datetime, timedelta
import json
def get_user_subscribes_that_is_going_to_finish():
user_subscribes = SubscribeForUser.objects.filter(
enable=True,
subscribe__price__gt=0,
paid_period_to_DT__lt=datetime.now() + timedelta(days=3),
paid_period_to_DT__gt=datetime.now()
)
return user_subscribes
def extension_free_subscribes():
subscribe = get_null_price_subscribe()
if not subscribe:

View File

@@ -6,9 +6,12 @@ from .js_views import *
from django.contrib.auth import views
from RoutesApp.js_views import new_route_view_ajax
# /subscribes/receive_finish_subscribe_msg/
urlpatterns = [
path('show_cur_subscribe/', show_cur_subscribe_ajax, name='show_cur_subscribe_ajax'),
path('subscribe_now/', subscribe_now_ajax, name='subscribe_now_ajax'),
path('receive_finish_subscribe_msg/', receive_finish_subscribe_msg_ajax, name='receive_finish_subscribe_msg_ajax'),
# path('create_ticket/', create_ticket_ajax, name='create_ticket_ajax'),
# path('support_show_chat_by_ticket/', support_show_chat_by_ticket_ajax, name='support_show_chat_by_ticket_ajax'),
# # path('send_msg/', send_msg_ajax, name='send_msg_ajax'),

View File

@@ -20,6 +20,30 @@ from GeneralApp.funcs import get_and_set_lang
from django.shortcuts import redirect
def receive_finish_subscribe_msg_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
data = json.loads(request.body)
user_subscribe = get_cur_user_subscribe(request.user)
user_subscribe.receive_finish_subscribe_msg = data['receive_finish_subscribe_msg']
user_subscribe.save(update_fields=['receive_finish_subscribe_msg'])
except Exception as e:
msg = f'msg_send_after_subscribe_end_ajax Exception = {str(e)}'
return JsonResponse({'error': msg}, status=400)
res_Dict = {'status': user_subscribe.receive_finish_subscribe_msg}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@login_required()#login_url='/profile/login/')
def subscribe_now_ajax(request):
@@ -37,27 +61,35 @@ def subscribe_now_ajax(request):
kwargs_for_order = {
'user': request.user,
'subscribe': subscribe,
'currency': 'USD',
'currency': 'KZT',
'sum': subscribe.price,
}
from BillingApp.funcs import create_subscribe_order
order = create_subscribe_order(kwargs_for_order)
if order:
return JsonResponse({'redirect_url': order.pay_page})
subscribe_for_user = None
kwargs = {
'user': request.user,
'subscribe': subscribe,
'last_paid_DT': datetime.now(),
'paid_period_from_DT': datetime.now(),
'paid_period_to_DT': datetime.now() + timedelta(hours=subscribe.period),
'receive_finish_subscribe_msg': True,
}
subscribe_for_user = SubscribeForUser.objects.filter(enable=True, user=request.user)
if subscribe_for_user:
subscribe_for_user.update(**kwargs)
subscribe_for_user = subscribe_for_user[0]
if subscribe.price > 0:
from BillingApp.funcs import create_subscribe_order
order = create_subscribe_order(kwargs_for_order)
if order:
res_Dict = {'redirect_url': order.pay_page}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
else:
subscribe_for_user = subscribe_user_to_null_price_subscribe(request.user)
# kwargs = {
# 'user': request.user,
# 'subscribe': subscribe,
# 'last_paid_DT': datetime.now(),
# 'paid_period_from_DT': datetime.now(),
# 'paid_period_to_DT': datetime.now() + timedelta(hours=subscribe.period),
# 'receive_finish_subscribe_msg': True,
# }
# subscribe_for_user = SubscribeForUser.objects.filter(enable=True, user=request.user)
# if subscribe_for_user:
# subscribe_for_user.update(**kwargs)
# subscribe_for_user = subscribe_for_user[0]
if not subscribe_for_user:
tpl_name = 'blocks/profile/b_subscribe_variants.html'
@@ -76,7 +108,11 @@ def subscribe_now_ajax(request):
}
html = render_to_string(tpl_name, Dict, request=request)
return JsonResponse({'html': html}, status=200)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
msg = f'show_cur_subscribe_ajax Error = {str(e)}'
@@ -91,8 +127,11 @@ def show_cur_subscribe_ajax(request):
lang = get_and_set_lang(request)
Dict = get_profile_subscribe_page_content_Dict(request)
return JsonResponse(Dict, status=200)
res_Dict = get_profile_subscribe_page_content_Dict(request)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
# try:
#

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2024-08-13 13:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('SubscribesApp', '0006_rename_allow_route_select_count_subscribeoption_allow_route_highlight_count'),
]
operations = [
migrations.AddField(
model_name='subscribeoption',
name='route_highlight_hours',
field=models.IntegerField(default=24, verbose_name='Количество часов выделения цветом объявлений'),
),
]

View File

@@ -0,0 +1,14 @@
# Generated by Django 4.2.2 on 2025-02-17 17:48
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('SubscribesApp', '0004_alter_subscribe_bg_color_alter_subscribe_text_color'),
('SubscribesApp', '0007_subscribeoption_route_highlight_hours'),
]
operations = [
]

View File

@@ -17,8 +17,12 @@ from datetime import datetime, timedelta
class SubscribeOption(BaseModel):
allow_route_rising_count = models.IntegerField(verbose_name=_('Количество поднятий объявлений') ,default=0)
allow_route_highlight_count = models.IntegerField(verbose_name=_('Количество выделений объявлений'), default=0)
allow_route_rising_count = models.IntegerField(
verbose_name=_('Количество поднятий объявлений') ,default=0)
allow_route_highlight_count = models.IntegerField(
verbose_name=_('Количество выделений объявлений'), default=0)
route_highlight_hours = models.IntegerField(
verbose_name=_('Количество часов выделения цветом объявлений'), default=24)
class Meta:
verbose_name = _('Опция подписки')
@@ -88,6 +92,14 @@ class SubscribeForUser(BaseModel):
res += f' {str(self.id)}'
return res
def get_highlight_hours(self):
options = self.subscribe.options.filter(
allow_route_highlight_count__gt=0,
)
if options:
return options[0].route_highlight_hours
return 0
def remains_route_adding_options(self):
total_data = SubscribeOption.objects.filter(
@@ -132,6 +144,10 @@ class SubscribeForUser(BaseModel):
).exclude(
id=self.id
)
subscribes_for_user.update(enable=False)
subscribes_for_user.update(
enable=False,
used_route_rising_count=0,
used_route_highlight_count=0,
)
return self

58
SubscribesApp/reports.py Normal file
View File

@@ -0,0 +1,58 @@
from .models import *
from datetime import datetime, timedelta
from .funcs import *
from django.utils.translation import gettext as _
def send_mail_for_user_subscribes_that_is_going_to_finish():
log = ''
user_subscribes = get_user_subscribes_that_is_going_to_finish()
for user_subscribe in user_subscribes:
if not user_subscribe.receive_finish_subscribe_msg:
continue
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 = _('tripwb.com - Уведомление о скором окончании срока подписки')
Dict = {
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
'message_title': subject,
'user_subscribe': user_subscribe
}
Dict.update(sets)
html = render_to_string('mail/m_user_subscribes_that_is_going_to_finish.html', Dict)
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
mail_sets = get_mail_send_options()
to = [user_subscribe.user.email]
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
if res and type(res) == str:
print(res)
# log += f'\n{res}'
to = ['web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
except Exception as e:
msg = (f'send_mail_for_user_subscribes_that_is_going_to_finish '
f'for user {user_subscribe.user} '
f'Exception = {str(e)}')
print(msg)
log += f'\n{msg}'
return log

View File

@@ -36,6 +36,15 @@ WEBPUSH_SETTINGS = {
"VAPID_ADMIN_EMAIL": "tripwithbonus@gmail.com"
}
PAY_SYSTEM_URL = 'https://sandboxapi.paymtech.kz/'
PKCS12_PASS = 'QNlhRStcY7mB'
API_PASS = 'aPqSRVZhxFjjSqbB'
PKCS12_FILENAME = 'dvldigitalprojects.p12'
# PAY_SYSTEM_URL = 'https://api.paymtech.kz/'
# PKCS12_PASS = 'fzSBm6WISje7'
# API_PASS = 't9g2+bZSvxNxCu+t'
# PKCS12_FILENAME = 'dvldigitalprojects_prod.p12'
SOCIALACCOUNT_LOGIN_ON_GET=True
ACCOUNT_DEFAULT_HTTP_PROTOCOL='https'
@@ -95,6 +104,8 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'django.contrib.humanize',
'django.contrib.sitemaps',
'django.contrib.sites',
'colorfield',
@@ -109,6 +120,8 @@ INSTALLED_APPS = [
'allauth.socialaccount',
'allauth.socialaccount.providers.google',
'rosetta',
'GeneralApp',
'AuthApp',
'RoutesApp',
@@ -342,6 +355,10 @@ CKEDITOR_CONFIGS = {
}
ROSETTA_MESSAGES_PER_PAGE = 100
ROSETTA_SHOW_AT_ADMIN_PANEL = True
# CKEDITOR_OPTIONS = {
# 'height': 291,
# 'width': '95%',

View File

@@ -1,6 +1,6 @@
from django.contrib import admin
from django.urls import path, include
from django.urls import path, include, re_path
from django.conf.urls.static import static
from django.conf import settings
from GeneralApp.views import Page404
@@ -40,7 +40,9 @@ urlpatterns = [
path('test_404', Page404, name='page_404'),
path('', include('PushMessages.urls'))
path('', include('PushMessages.urls')),
path('', include('SitemapApp.urls')),
]
from django.conf.urls.i18n import i18n_patterns
@@ -59,4 +61,9 @@ urlpatterns += i18n_patterns(
)
if 'rosetta' in settings.INSTALLED_APPS:
urlpatterns += [
re_path(r'^rosetta/', include('rosetta.urls'))
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

BIN
dvldigitalprojects_prod.p12 Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -15,4 +15,6 @@ django-allauth==0.60.0
pytz==2024.1
requests-pkcs12==1.24
#django-tz-detect==0.4.0
django-rosetta==0.10.0
timezonefinder==6.5.2

View File

@@ -1,4 +1,5 @@
User-agent: *
Disallow: /
Disallow: */admin/*
Host: tripwb.com
Host: dev.tripwb.com

View File

@@ -1,6 +1,10 @@
from BaseModels.admin_utils import Admin_GenericBaseIconStackedInline, Admin_BaseIconModel, GenericStackedInline
from BaseModels.admin_utils import (
Admin_GenericBaseIconStackedInline, Admin_BaseIconModel, GenericStackedInline,
AdminImageWidget, get_image_thumb
)
from copy import deepcopy
from django.db import models
from django.utils.translation import gettext as _
class Admin_BaseModel(Admin_BaseIconModel):
@@ -86,12 +90,17 @@ class AdminTranslationBase(TranslationAdmin):
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
}
from modeltranslation.admin import TranslationGenericStackedInline
class AdminStacked_FAQitem(TranslationGenericStackedInline):
from GeneralApp.models import FAQitem
model = FAQitem
extra = 0
fields = ['order', 'question', 'answer']
from modeltranslation.admin import TranslationGenericStackedInline, TranslationGenericTabularInline
class TranslationGenericTabularInlineCustom(TranslationGenericTabularInline):
formfield_overrides = {
models.ImageField: {'widget': AdminImageWidget},
}
def image_thumb(self, obj):
return get_image_thumb(self, obj)
image_thumb.short_description = _('Миниатюра')
image_thumb.allow_tags = True
class Media:
@@ -105,6 +114,46 @@ class AdminStacked_FAQitem(TranslationGenericStackedInline):
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
}
class TranslationGenericStackedInlineCustom(TranslationGenericStackedInline):
formfield_overrides = {
models.ImageField: {'widget': AdminImageWidget},
}
def image_thumb(self, obj):
return get_image_thumb(self, obj)
image_thumb.short_description = _('Миниатюра')
image_thumb.allow_tags = True
class Media:
js = (
'modeltranslation/js/force_jquery.js',
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'modeltranslation/js/tabbed_translation_fields.js',
)
css = {
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
}
class AdminStacked_FAQitem(TranslationGenericStackedInlineCustom):
from GeneralApp.models import FAQitem
model = FAQitem
extra = 0
fields = ['order', 'question', 'answer']
class AdminTabular_Mediaitem(TranslationGenericTabularInlineCustom):
from GeneralApp.models import MediaItem
model = MediaItem
extra = 0
fields = ['order', 'video', 'picture']
class Admin_BaseModelViewPage(Admin_BaseIconModel):
pass
# def get_fieldsets(self, request, obj=None):
@@ -129,7 +178,7 @@ class Admin_BaseModelViewPage(Admin_BaseIconModel):
# else:
# return {}
#
inlines = [AdminStacked_FAQitem]
inlines = [AdminStacked_FAQitem, AdminTabular_Mediaitem]

View File

@@ -116,6 +116,10 @@
}
@media (max-width: 1180px){
.container_inf_about_moving{
padding: 15px;
}
.input_list.find_route{
left: unset;
width: 70%;
@@ -367,7 +371,7 @@
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
width: 100%;
width: 98%;
}
@@ -730,7 +734,7 @@
margin-bottom: 25px;
}
ч
.arrange_subscribe{
margin: 20px auto 20px auto;
}
@@ -1114,9 +1118,12 @@
.left-part-carrier-card, .inf_carrier_container{
width: unset;
float: none;
padding: 1px 15px;
padding: 1px 20px;
border-right: unset;
}
.control_frame{
top: 3px;
}
.inf_carrier_container{
padding-top: 70px;
padding-bottom: 10px;
@@ -1194,7 +1201,7 @@
.from-to-city-text{
font-size: 12px;
font-weight: 400;
padding-bottom: 10px;
/*padding-bottom: 10px;*/
/*padding-top: unset;*/
}
.arrow_inf_about_moving{
@@ -1503,11 +1510,19 @@
width: 153px;
}
.popup_content{
width: 41%;
}
}
@media (max-width: 950px){
#title_static_small{
display: none;
}
.info_profile{
width: 65%;
float: none;
@@ -1543,6 +1558,9 @@
.pag_news_item_text{
width: unset;
}
.popup_content{
width: 52%;
}
}
@media (max-width: 850px){
@@ -1656,6 +1674,11 @@
}
@media (max-width: 800px) {
.line_inf_about_moving{
margin-bottom: 40px;
}
.marker_messages_mobile{
position: absolute;
top: 0;
@@ -1671,6 +1694,9 @@
.marker_messages_mobile.show{
display: block;
}
.popup_content>.confirm_profile_btn{
width: 90%;
}
}
@media (max-width: 828px){
@@ -1762,6 +1788,10 @@
background: #ffffff;
}
.dropdown-content-lang{
z-index: 1 ;
}
.menu_buttons.right.open .handler_menu{
background: #FFFFFF;
color: #000000;
@@ -1824,6 +1854,9 @@
.inf_carrier_icon{
/*width: 3%;*/
}
.popup_content{
width: 70%;
}
}
@media (max-width: 687px){
/*.to_address_point_txt.find_route {*/
@@ -1832,6 +1865,10 @@
/*.from_address_point_txt.find_route.first {*/
/* width: 52.1%;*/
/*}*/
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
width: 98%;
}
.container_inf_about_moving {
width: 97%;
@@ -1872,6 +1909,10 @@
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
width: 89%;
}
.phones_carrier{
display: block;
}
@@ -1897,6 +1938,7 @@
.container_inf_about_moving{
width: 100%;
padding: 16px;
}
.arrow_inf_about_moving{

2
static/css/moover.css Normal file

File diff suppressed because one or more lines are too long

178
static/css/moover/about.css Normal file
View File

@@ -0,0 +1,178 @@
.about {
margin-bottom: 168px;
}
@media (min-width: 1720px) {
.about {
margin-bottom: 188px;
}
}
@media (max-width: 1304.98px) {
.about {
margin-bottom: 138px;
}
}
@media (max-width: 991.98px) {
.about {
margin-bottom: 110px;
}
}
.about .title {
margin-bottom: 60px;
}
@media (min-width: 1720px) {
.about .title {
margin-bottom: 49px;
}
}
@media (max-width: 1304.98px) {
.about .title {
margin-bottom: 39px;
}
}
@media (max-width: 991.98px) {
.about .title {
margin-bottom: 48px;
}
}
@media (max-width: 479.98px) {
.about .title {
margin-bottom: 37px;
}
}
.about__grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
@media (max-width: 991.98px) {
.about__grid {
display: block;
}
}
.about__img {
box-shadow: inset 18.19px 1.21px 18.19px 0 #FFFFFFCC, inset -18.19px -1.21px 18.19px 0 #4052801A, 48.5px 36.38px 36.38px 0 #6B7F9933;
border-radius: 31px;
margin-left: -20px;
margin-top: 8px;
}
@media (min-width: 1720px) {
.about__img {
margin-top: 19px;
}
}
@media (max-width: 1304.98px) {
.about__img {
margin-left: -10px;
}
}
@media (max-width: 991.98px) {
.about__img {
margin-left: 0;
margin-bottom: 49px;
display: block;
}
}
@media (max-width: 479.98px) {
.about__img {
margin-bottom: 38px;
}
}
.about__right {
text-align: left;
padding-top: 43px;
padding-left: 50px;
}
@media (min-width: 1720px) {
.about__right {
padding-top: 90px;
padding-left: 21px;
}
}
@media (max-width: 1304.98px) {
.about__right {
padding-left: 11px;
padding-top: 19px;
}
}
@media (max-width: 991.98px) {
.about__right {
padding: 0 8px;
text-align: center;
}
}
@media (max-width: 479.98px) {
.about__right {
padding: 0;
}
}
.about__right::after {
content: '';
display: block;
clear: both;
}
.about__half {
max-width: 50%;
float: left;
}
@media (max-width: 991.98px) {
.about__half {
max-width: initial;
}
}
.about__half:last-child {
padding-left: 16px;
max-width: 47%;
}
@media (max-width: 991.98px) {
.about__half:last-child {
max-width: initial;
padding-left: 0;
}
}
.about b {
letter-spacing: 0.4px;
}
@media (min-width: 1720px) {
.about b {
font-weight: 700;
letter-spacing: 0;
}
}
@media (max-width: 479.98px) {
.about b {
letter-spacing: 0.9px;
}
}
@media (min-width: 1720px) {
.about p {
margin-bottom: 39px;
}
}

1
static/css/moover/animate.css vendored Normal file
View File

@@ -0,0 +1 @@
.animate{padding:60px 40px 49px;opacity:0;background-color:var(--color-black2);border-radius:30px;color:white;margin-bottom:160px}@media (min-width: 1720px){.animate{padding-top:100px;padding-bottom:89px;margin-bottom:180px}}@media (max-width: 1304.98px){.animate{margin-bottom:141px}}@media (max-width: 991.98px){.animate{padding-top:40px;padding-bottom:29px;margin-bottom:121px}}@media (max-width: 479.98px){.animate{padding:30px 7px 19px}}.animate.left{transform:scale(0);opacity:0}.animate.right{opacity:0;transform:scale(0)}.animate.right .title{margin-bottom:17px}@media (min-width: 1720px){.animate.right .title{max-width:80%;margin-bottom:40px}}@media (max-width: 1304.98px){.animate.right .title{margin-bottom:25px}}@media (max-width: 991.98px){.animate.right .title{margin-bottom:31px}}@media (max-width: 479.98px){.animate.right .title{margin-bottom:20px}}@media (max-width: 991.98px){.animate.right .subtitle{margin-bottom:31px}}@media (max-width: 479.98px){.animate.right .use__btn{margin-top:-11px}}.animate__link{color:var(--color-orange);text-decoration:underline !important}.animate .title{margin-bottom:25px;max-width:87%}@media (min-width: 1720px){.animate .title{margin-bottom:40px}}@media (max-width: 1304.98px){.animate .title{max-width:99%}}@media (max-width: 991.98px){.animate .title{max-width:85%;font-size:24px;line-height:29.05px}}@media (max-width: 767.98px){.animate .title{max-width:100%;margin-bottom:14px}}.animate .subtitle{width:47%;margin:0 auto 23px}@media (min-width: 1720px){.animate .subtitle{line-height:26px;letter-spacing:0.1px;margin-bottom:40px}}@media (max-width: 1304.98px){.animate .subtitle{width:54%}}@media (max-width: 991.98px){.animate .subtitle{width:102%;margin-bottom:26px}}@media (max-width: 479.98px){.animate .use__btn{margin-top:-6px;padding-left:15px;padding-right:15px;display:flex}}

View File

@@ -0,0 +1,157 @@
.benefits {
margin-bottom: 132px;
}
@media (min-width: 1720px) {
.benefits {
margin-bottom: 147px;
}
}
@media (max-width: 1304.98px) {
.benefits {
margin-bottom: 101px;
}
}
@media (max-width: 991.98px) {
.benefits {
margin-bottom: 93px;
}
}
@media (max-width: 479.98px) {
.benefits {
margin-bottom: 103px;
}
}
.benefits__grid {
text-align: left;
display: grid;
grid-template-columns: 1.5fr 3fr 1.5fr;
}
@media (max-width: 991.98px) {
.benefits__grid {
grid-template-columns: 1fr 1fr;
}
}
@media (max-width: 479.98px) {
.benefits__grid {
grid-template-columns: 1fr;
text-align: center;
}
}
.benefits__item {
min-height: 122px;
padding-right: 7px;
margin-bottom: 22px;
}
@media (min-width: 1720px) {
.benefits__item {
min-height: 145px;
}
}
@media (max-width: 991.98px) {
.benefits__item {
padding-right: 25px;
}
}
@media (max-width: 479.98px) {
.benefits__item {
padding-right: 0;
margin-bottom: 19px;
min-height: 90px;
}
}
@media (max-width: 991.98px) {
.benefits__second {
grid-column: 1 / 3;
order: -1;
margin-bottom: 56px;
}
}
@media (max-width: 479.98px) {
.benefits__second {
grid-column: 1/2;
margin-bottom: 31px;
}
}
.benefits__third {
padding-left: 16px;
}
@media (min-width: 1720px) {
.benefits__third {
padding-left: 31px;
margin-right: 5px;
}
}
@media (max-width: 991.98px) {
.benefits__third {
padding-left: 11px;
}
}
@media (max-width: 479.98px) {
.benefits__third {
padding-left: 0;
}
}
.benefits .title {
margin-bottom: 76px;
}
@media (min-width: 1720px) {
.benefits .title {
margin-bottom: 93px;
}
}
@media (max-width: 991.98px) {
.benefits .title {
margin-bottom: 19px;
}
}
.benefits img {
position: relative;
top: 14px;
right: -11px;
}
@media (min-width: 1720px) {
.benefits img {
top: -33px;
}
}
@media (max-width: 1304.98px) {
.benefits img {
top: 20px;
right: 0;
}
}
@media (min-width: 1720px) {
.benefits h2 {
margin-bottom: 10px;
}
}
@media (max-width: 479.98px) {
.benefits p {
margin-bottom: 13px;
}
}

194
static/css/moover/cards.css Normal file
View File

@@ -0,0 +1,194 @@
.cards__list {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
.cards__item {
position: relative;
}
@media (max-width: 991.98px) {
.cards__item {
max-width: 270px;
}
}
@media (max-width: 767.98px) {
.cards__item {
max-width: 251px;
margin-right: 18px;
}
}
.slick-active .cards__item .cards__desc, .cards__item:hover .cards__desc, .cards__item:focus .cards__desc {
-webkit-line-clamp: initial;
/* number of lines to show */
line-clamp: initial;
max-height: 17em;
}
.cards__img {
margin-bottom: 5px;
}
@media (min-width: 1720px) {
.cards__img {
width: 100%;
margin-bottom: 15px;
}
}
@media (max-width: 1304.98px) {
.cards__img {
margin-bottom: 8px;
}
}
@media (max-width: 991.98px) {
.cards__img {
margin-bottom: 8px;
}
}
@media (max-width: 767.98px) {
.cards__img {
margin-bottom: 10px;
}
}
.cards__img:hover {
scale: 1.05;
transition: scale 0.15s linear;
}
.cards__desc {
font-weight: 500;
line-height: 22px;
padding: 0 5px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 7;
/* number of lines to show */
line-clamp: 7;
-webkit-box-orient: vertical;
transition: all 0.3s ease-in-out;
max-height: 10em;
}
@media (min-width: 1720px) {
.cards__desc {
font-size: 20px;
line-height: 26px;
padding-left: 20px;
padding-right: 20px;
}
}
@media (max-width: 1279.98px) {
.cards__desc {
padding-left: 5px;
padding-right: 5px;
margin-bottom: 3px;
}
}
@media (max-width: 991.98px) {
.cards__desc {
padding-left: 8px;
padding-right: 8px;
}
}
.slick-active .cards__desc, .cards__desc:hover, .cards__desc:focus {
-webkit-line-clamp: initial;
/* number of lines to show */
line-clamp: initial;
max-height: 999em;
}
.cards__desc a {
color: var(--color-orange);
}
.cards__arrow {
width: 62px;
height: 20px;
position: absolute;
right: -30px;
top: -21px;
background-image: url("/static/img/svg/Arrow23.svg");
}
@media (min-width: 1720px) {
.cards__arrow {
right: -45px;
top: -29px;
}
}
@media (max-width: 1304.98px) {
.cards__arrow {
top: -8%;
}
}
@media (max-width: 991.98px) {
.cards__arrow {
display: none;
}
}
.cards .slick-list {
overflow: visible;
}
@media (max-width: 767.98px) {
.cards .slick-list {
margin-bottom: 1px;
padding-left: 58px;
}
}
.cards .slick-dots {
display: flex;
justify-content: center;
margin: 0;
padding: 1rem 0;
list-style-type: none;
}
.cards .slick-dots li {
margin: 0 0.25rem;
}
@media (max-width: 767.98px) {
.cards .slick-dots li {
margin: 0 0.31rem;
}
}
.cards .slick-dots button {
display: block;
width: 8px;
height: 8px;
padding: 0;
border: none;
border-radius: 100%;
background-color: #D9D9D9;
text-indent: -9999px;
}
.cards .slick-dots li.slick-active button {
background-color: var(--color-orange);
}
.cards--cstmr .cards__desc {
padding: 0 50px;
}
@media (max-width: 1304.98px) {
.cards--cstmr .cards__desc {
padding-left: 10px;
padding-right: 10px;
}
}

View File

@@ -0,0 +1 @@
.chatterbox{margin-bottom:160px}@media (min-width: 1720px){.chatterbox{margin-bottom:180px}}@media (max-width: 1304.98px){.chatterbox{margin-bottom:142px}}@media (max-width: 991.98px){.chatterbox{margin-left:-50vw;margin-right:-50vw;margin-bottom:122px}}@media (max-width: 767.98px){.chatterbox{max-width:100vw;margin:0 auto 121px;position:relative}}.chatterbox__slider{max-width:1200px;margin:0 auto}@media (min-width: 1720px){.chatterbox__slider{max-width:1640px}}@media (max-width: 1304.98px){.chatterbox__slider{max-width:1100px}}@media (max-width: 991.98px){.chatterbox__slider{max-width:720px}}@media (max-width: 767.98px){.chatterbox__slider{max-width:830px;width:830px;left:50%;transform:translateX(-50%)}}@media (max-width: 479.98px){.chatterbox__slider{max-width:initial}}.chatterbox__slide{width:335px;height:615px;background:url("/static/img/webp/phone-border.webp") center no-repeat;transition:scale 0.2s ease-in-out;margin:auto;position:relative}@media (min-width: 1720px){.chatterbox__slide{width:456px;height:836px;background-size:456px 836px}}@media (max-width: 1304.98px){.chatterbox__slide{width:308px;height:565px;background-size:308px 565px}}@media (max-width: 991.98px){.chatterbox__slide{width:206px;height:377px;background-size:206px 377px}}@media (max-width: 767.98px){.chatterbox__slide{width:234px;height:429px;background-size:234px 429px}}.chatterbox__slide.loaded video{opacity:1}.chatterbox__slide.loaded img{z-index:-10}.chatterbox__slide video{max-width:100%;opacity:0;transition:opacity 0.2s ease-in-out;pointer-events:none;position:relative}@media (min-width: 1720px){.chatterbox__slide video{top:-2px}}@media (max-width: 1304.98px){.chatterbox__slide video{top:10px}}@media (max-width: 991.98px){.chatterbox__slide video{top:-4px}}@media (max-width: 767.98px){.chatterbox__slide video{top:22px}}.chatterbox__slide img{position:absolute;scale:1.32;top:11%}.chatterbox__wrap{position:absolute;left:8px;right:8px;top:8px;bottom:8px;border-radius:25px;background-color:grey;overflow:hidden}@media (min-width: 1720px){.chatterbox__wrap{border-radius:50px}}.chatterbox__vbtn{position:absolute;left:0;right:0;top:0;bottom:0;opacity:0;transition:opacity 0.2s ease-in-out;pointer-events:none}.loaded .chatterbox__vbtn{display:none}.chatterbox__vbtn::before{width:80px;height:80px;display:flex;align-items:center;justify-content:center;background:var(--color-primary);border:0;border-radius:50%;transition:opacity 100ms linear}@media (min-width: 1720px){.chatterbox__vbtn::before{width:109px;height:109px}}@media (max-width: 991.98px){.chatterbox__vbtn::before{width:48px;height:48px}}@media (max-width: 767.98px){.chatterbox__vbtn::before{width:55px;height:55px}}.chatterbox__vbtn::before,.chatterbox__vbtn::after{content:"";position:absolute;left:50%;top:50%;transform:translate(-50%, -50%);cursor:pointer}.chatterbox__vbtn::after{border-color:transparent transparent transparent #ffffff;border-style:solid;border-width:15px 0 15px 25px;display:inline-block;margin-left:2px}@media (min-width: 1720px){.chatterbox__vbtn::after{border-width:23px 0 23px 35px;margin-left:4px}}@media (max-width: 991.98px){.chatterbox__vbtn::after{border-width:10px 0 10px 14px}}.chatterbox__vbox{position:relative;display:flex;justify-content:center;align-items:center;height:600px}@media (min-width: 1720px){.chatterbox__vbox{height:827px}}@media (max-width: 1304.98px){.chatterbox__vbox{height:530px}}@media (max-width: 991.98px){.chatterbox__vbox{height:370px}}.chatterbox__mbtns{position:absolute;top:58%;transform:translateY(-50%);left:0;right:0}@media (max-width: 479.98px){.chatterbox__mbtns{top:61.6%}}.chatterbox .title{margin-bottom:60px}@media (max-width: 1304.98px){.chatterbox .title{margin-bottom:39px}}@media (max-width: 767.98px){.chatterbox .title{margin-bottom:50px}}.chatterbox .slick-next{right:-40px}@media (max-width: 1304.98px){.chatterbox .slick-next{right:-10px}}@media (max-width: 991.98px){.chatterbox .slick-next{width:40px;height:40px;background-size:32%;right:5%}}@media (max-width: 479.98px){.chatterbox .slick-next{right:0}}.chatterbox .slick-prev{left:-40px}@media (max-width: 1304.98px){.chatterbox .slick-prev{left:-10px}}@media (max-width: 991.98px){.chatterbox .slick-prev{width:40px;height:40px;background-size:32%;left:5%}}@media (max-width: 479.98px){.chatterbox .slick-prev{left:0}}@media (max-width: 991.98px){.chatterbox .slick-list{overflow:visible}}.slick-slide:not(.slick-center) .chatterbox__slide{scale:0.72}@media (max-width: 1304.98px){.slick-slide:not(.slick-center) .chatterbox__slide{scale:0.69}}@media (max-width: 991.98px){.slick-slide:not(.slick-center) .chatterbox__slide{scale:0.8}}@media (max-width: 479.98px){.slick-slide:not(.slick-center) .chatterbox__slide{scale:0.85}}.slick-center .chatterbox__vbtn{opacity:1;pointer-events:initial;z-index:1}.slick-center .chatterbox__vbox video{pointer-events:initial;cursor:pointer}

347
static/css/moover/diff.css Normal file
View File

@@ -0,0 +1,347 @@
.diff {
margin-bottom: 179px;
}
@media (min-width: 1720px) {
.diff {
margin-bottom: 172px;
}
}
@media (max-width: 1304.98px) {
.diff {
margin-bottom: 140px;
}
}
@media (max-width: 991.98px) {
.diff {
margin-bottom: 125px;
}
}
@media (max-width: 767.98px) {
.diff {
margin-bottom: 139px;
}
}
.diff .title {
width: 60%;
margin-bottom: 65px;
}
@media (min-width: 1720px) {
.diff .title {
width: 49%;
margin-bottom: 60px;
}
}
@media (max-width: 1304.98px) {
.diff .title {
width: 73%;
margin-bottom: 40px;
}
}
@media (max-width: 991.98px) {
.diff .title {
width: 90%;
margin-bottom: 40px;
}
}
@media (max-width: 767.98px) {
.diff .title {
width: 100%;
margin-bottom: 30px;
}
}
.diff__grid {
display: flex;
position: relative;
margin-bottom: 30px;
}
.diff__grid::before {
content: '';
position: absolute;
height: 96%;
width: 5px;
border-radius: 5px;
background-color: #EDEDED;
left: 50%;
transform: translateX(-50%);
bottom: 0;
}
@media (max-width: 1304.98px) {
.diff__grid::before {
height: 90%;
}
}
@media (max-width: 991.98px) {
.diff__grid::before {
display: none;
}
}
@media (max-width: 991.98px) {
.diff__grid {
display: block;
}
}
.diff__coll {
width: 50%;
}
@media (max-width: 991.98px) {
.diff__coll {
width: 100%;
}
}
.diff__coll.left {
margin-right: 29px;
}
@media (min-width: 1720px) {
.diff__coll.left {
margin-right: 12px;
}
}
@media (max-width: 1304.98px) {
.diff__coll.left {
margin-right: 10px;
}
}
@media (max-width: 991.98px) {
.diff__coll.left {
margin-right: 0;
}
}
.diff__coll.left .diff__coll-title {
padding-left: 39px;
}
@media (min-width: 1720px) {
.diff__coll.left .diff__coll-title {
padding-left: 2px;
}
}
@media (max-width: 1304.98px) {
.diff__coll.left .diff__coll-title {
padding-left: 0;
}
}
@media (max-width: 991.98px) {
.diff__coll.left .diff__coll-title {
padding-left: 0;
}
}
.diff__coll.right {
margin-left: 29px;
}
@media (max-width: 1304.98px) {
.diff__coll.right {
margin-left: 10px;
}
}
@media (max-width: 991.98px) {
.diff__coll.right {
margin-left: 0;
display: none;
}
}
.diff__coll.right .diff__coll-title {
padding-right: 39px;
}
@media (min-width: 1720px) {
.diff__coll.right .diff__coll-title {
padding-right: 0;
}
}
@media (max-width: 1304.98px) {
.diff__coll.right .diff__coll-title {
padding-right: 0;
}
}
@media (max-width: 991.98px) {
.diff__coll.right .diff__coll-title {
padding-right: 0;
}
}
.diff__coll-title {
margin-bottom: 38px;
}
@media (max-width: 1304.98px) {
.diff__coll-title {
margin-bottom: 18px;
}
}
@media (max-width: 991.98px) {
.diff__coll-title {
margin-bottom: 19px;
}
}
@media (max-width: 767.98px) {
.diff__coll-title {
margin-bottom: 29px;
}
}
.diff__item {
position: relative;
text-align: left;
padding-left: 10px;
padding-top: 11px;
padding-bottom: 11px;
display: flex;
gap: 11px;
align-items: center;
background-color: #FFFFFF;
border-radius: 15px;
font-weight: 500;
font-size: 20px;
line-height: 28px;
margin-bottom: 35px;
cursor: default;
}
@media (min-width: 1720px) {
.diff__item {
padding: 20px;
gap: 20px;
margin-bottom: 40px;
}
}
@media (max-width: 1304.98px) {
.diff__item {
margin-bottom: 18px;
}
}
@media (max-width: 991.98px) {
.diff__item {
font-size: 18px;
margin-bottom: 25px;
padding-bottom: 9px;
}
}
@media (max-width: 767.98px) {
.diff__item {
font-size: 16px;
line-height: 19.36px;
padding-right: 15px;
margin-bottom: 14px;
}
}
.diff__item:last-child {
margin-bottom: 0;
}
.diff__item:hover .diff__status::before {
scale: 1.2;
}
.diff__status {
position: relative;
height: 48px;
width: 48px;
border-radius: 5px;
flex-shrink: 0;
}
@media (min-width: 1720px) {
.diff__status {
border-radius: 12px;
}
}
@media (max-width: 1304.98px) {
.diff__status {
border-radius: 13px;
}
}
@media (max-width: 991.98px) {
.diff__status {
border-radius: 11px;
}
}
@media (max-width: 767.98px) {
.diff__status {
width: 35px;
height: 35px;
}
}
.diff__status::before {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
transform-origin: 0% 15%;
}
.diff__status::before {
content: '';
width: 36px;
height: 36px;
}
.diff__item--done .diff__status {
background-color: #CCF9D9;
}
.diff__item--done .diff__status::before {
width: 26px;
height: 26px;
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjYiIGhlaWdodD0iMjYiIHZpZXdCb3g9IjAgMCAyNiAyNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTI0IDJMOS4zMzMzMyAyNEwyIDEzLjAwMDUiIHN0cm9rZT0iIzQ1QzIyNiIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+Cg==);
}
@media (max-width: 767.98px) {
.diff__item--done .diff__status::before {
scale: 0.7;
}
}
.diff__item--error .diff__status {
background-color: #F9CCCC;
}
.diff__item--error .diff__status::before {
width: 36px;
height: 36px;
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTI4LjEyNSA3Ljg3NUw3Ljg3NSAyOC4xMjUiIHN0cm9rZT0iI0ZGMDAwMCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTI4LjEyNSAyOC4xMjVMNy44NzUgNy44NzUiIHN0cm9rZT0iI0ZGMDAwMCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+Cg==);
}
@media (max-width: 767.98px) {
.diff__item--error .diff__status::before {
scale: 0.7;
}
}

418
static/css/moover/easy.css Normal file
View File

@@ -0,0 +1,418 @@
.easy {
margin-bottom: 162px;
}
@media (min-width: 1720px) {
.easy {
margin-bottom: 180px;
}
}
@media (max-width: 1304.98px) {
.easy {
margin-bottom: 140px;
}
}
@media (max-width: 991.98px) {
.easy {
margin-bottom: 121px;
}
}
.easy .title {
max-width: 55%;
margin-bottom: 21px;
}
@media (min-width: 1720px) {
.easy .title {
max-width: 45%;
margin-bottom: 23px;
}
}
@media (max-width: 991.98px) {
.easy .title {
max-width: 75%;
}
}
@media (max-width: 767.98px) {
.easy .title {
max-width: 95%;
margin-bottom: 30px;
}
}
.easy .subtitle {
margin-bottom: 41px;
}
@media (min-width: 1720px) {
.easy .subtitle {
margin-bottom: 59px;
}
}
@media (max-width: 767.98px) {
.easy .subtitle {
max-width: 90%;
margin: 0 auto 23px;
}
}
.easy__grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: repeat(2, minmax(186px, auto));
grid-template-areas: 'a b' 'a c';
grid-column-gap: 20px;
grid-row-gap: 80px;
margin-bottom: 46px;
}
@media (min-width: 1720px) {
.easy__grid {
grid-column-gap: 147px;
grid-template-rows: repeat(2, minmax(245px, auto));
grid-row-gap: 136px;
margin-bottom: 63px;
}
}
@media (max-width: 1304.98px) {
.easy__grid {
grid-column-gap: 69px;
grid-template-rows: repeat(2, minmax(172px, auto));
margin-bottom: 41px;
}
}
@media (max-width: 991.98px) {
.easy__grid {
display: block;
margin-bottom: 37px;
}
}
@media (max-width: 767.98px) {
.easy__grid {
margin-bottom: 40px;
}
}
.easy__item {
border-radius: 30px;
background-color: var(--color-grey);
/*background-color: #a72525;*/
text-align: left;
padding: 21px;
box-shadow: var(--box-shadow-primary);
}
.easy__item--fir {
grid-area: a;
margin-right: 60px;
padding-bottom: 0;
}
@media (min-width: 1720px) {
.easy__item--fir {
margin-right: -10px;
padding-top: 31px;
}
}
@media (max-width: 1304.98px) {
.easy__item--fir {
margin-right: 13px;
}
}
@media (max-width: 991.98px) {
.easy__item--fir {
padding-top: 17px;
margin-right: 0;
margin-bottom: 49px;
}
}
@media (max-width: 767.98px) {
.easy__item--fir {
margin-bottom: 42px;
}
}
.easy__item--fir p {
width: 93%;
margin-bottom: 29px;
}
@media (min-width: 1720px) {
.easy__item--fir p {
width: 89%;
margin-bottom: 53px;
}
}
@media (max-width: 991.98px) {
.easy__item--fir p {
max-width: 78%;
}
}
.easy__item--sec {
grid-area: b;
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0;
padding-top: 0;
padding-bottom: 0;
}
@media (min-width: 1720px) {
.easy__item--sec {
padding-left: 15px;
}
}
@media (max-width: 991.98px) {
.easy__item--sec {
padding-top: 35px;
padding-bottom: 37px;
margin-bottom: 46px;
}
}
@media (max-width: 767.98px) {
.easy__item--sec {
display: block;
padding-top: 0;
padding-bottom: 0;
margin-bottom: 49px;
}
}
.easy__item--sec img {
margin-bottom: -10px;
margin-right: -5px;
max-width: 50.1%;
}
@media (min-width: 1720px) {
.easy__item--sec img {
max-width: 53%;
}
}
@media (max-width: 1304.98px) {
.easy__item--sec img {
max-width: 42%;
margin-bottom: -4px;
margin-right: 0;
}
}
@media (max-width: 991.98px) {
.easy__item--sec img {
margin-right: 0;
margin-bottom: 0;
}
}
@media (max-width: 767.98px) {
.easy__item--sec img {
max-width: 104%;
position: relative;
left: -6px;
top: -4px;
}
}
.easy__item--sec p {
margin-bottom: 0;
padding-top: 0;
padding-bottom: 0;
}
@media (max-width: 767.98px) {
.easy__item--sec p {
margin-bottom: 22px;
}
}
.easy__item--thr {
grid-area: c;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0;
padding-top: 0;
padding-bottom: 0;
}
@media (min-width: 1720px) {
.easy__item--thr {
padding-left: 15px;
}
}
@media (max-width: 991.98px) {
.easy__item--thr {
padding-top: 42px;
padding-bottom: 46px;
}
}
@media (max-width: 767.98px) {
.easy__item--thr {
display: block;
padding-top: 0;
padding-bottom: 0;
}
}
.easy__item--thr .img {
margin-bottom: -10px;
margin-right: 24px;
max-width: 80%;
}
@media (max-width: 1279.98px) {
.easy__item--thr .img {
max-width: 35%;
}
}
@media (max-width: 1304.98px) {
.easy__item--thr .img {
margin-right: 2px;
}
}
@media (max-width: 991.98px) {
.easy__item--thr .img {
margin-right: 0;
max-width: 34%;
}
}
@media (max-width: 767.98px) {
.easy__item--thr .img img {
display: block;
margin: 0 auto;
}
}
.easy__item--thr p {
max-width: 50%;
margin-bottom: 0;
padding-top: 0;
padding-bottom: 0;
}
@media (max-width: 991.98px) {
.easy__item--thr p {
max-width: 60%;
}
}
@media (max-width: 767.98px) {
.easy__item--thr p {
margin-bottom: 22px;
max-width: 100%;
}
}
.easy__arrow {
width: 68px;
height: 18px;
background-image: url("/static/img/svg/Arrow08.svg");
position: absolute;
z-index: 1;
}
@media (min-width: 1720px) {
.easy__arrow {
scale: 1.4;
}
}
@media (max-width: 1304.98px) {
.easy__arrow {
scale: 0.8;
}
}
@media (max-width: 991.98px) {
.easy__arrow {
display: none;
}
}
.easy__arrow--fir {
top: 46%;
right: 101%;
}
@media (min-width: 1720px) {
.easy__arrow--fir {
right: 105%;
top: 34%;
}
}
@media (max-width: 1304.98px) {
.easy__arrow--fir {
top: 48%;
}
}
.easy__arrow--sec {
top: 117%;
left: 30%;
transform: rotate(90deg);
}
@media (min-width: 1720px) {
.easy__arrow--sec {
left: 45%;
top: 124%;
}
}
@media (max-width: 1304.98px) {
.easy__arrow--sec {
left: 38%;
}
}
.easy__btn {
margin-top: -21px;
}
@media (max-width: 1304.98px) {
.easy__btn {
margin-top: -20px;
}
}
@media (max-width: 991.98px) {
.easy__btn {
margin-top: -19px;
padding-left: 54px;
padding-right: 54px;
}
}
@media (max-width: 767.98px) {
.easy__btn {
padding-left: 50px;
padding-right: 50px;
margin-top: -8px;
max-width: 100%;
}
}

View File

@@ -0,0 +1 @@
.header{margin-top:0;position:fixed;display:block;left:0;top:0;width:100vw;padding:15px 5px;transition:all 0.1s ease-in-out;background-color:white}@media (max-width: 991.98px){.header{padding-top:7px;padding-bottom:7px}}.header.scrolled{padding-top:7px;padding-bottom:7px;box-shadow:var(--box-shadow-primary);border-bottom:1px solid var(--color-grey)}.header__grid,.header__list{display:flex;align-items:center;justify-content:space-between}.header__logo{width:48px;height:48px;position:relative;left:5px}@media (max-width: 1304.98px){.header__logo{left:6px}}@media (max-width: 991.98px){.header__logo{left:0}}@media (max-width: 767.98px){.header__logo{left:-3px}}.header__nav{flex-grow:1;max-width:41%;margin-left:auto}@media (min-width: 1720px){.header__nav{max-width:34%}}@media (max-width: 1304.98px){.header__nav{max-width:46.5%}}.header__link{color:var(--color-black2);text-decoration:none}.header__btn{padding:8px 0 6px;font-size:16px;margin-left:61px;margin-right:-3px}@media (min-width: 1720px){.header__btn{margin-left:81px}}@media (max-width: 1304.98px){.header__btn{margin-right:0}}@media (max-width: 991.98px){.header__btn{display:none}}.header .dropdown{left:-4px}@media (max-width: 767.98px){.header .dropdown{left:-8px}}.header .dropdown-content{right:0;height:initial}@media (max-width: 575px){.header .dropdown-content{right:0;left:initial}}

View File

@@ -0,0 +1,189 @@
.presentation {
margin: 12px -65px 140px;
}
@media (min-width: 1720px) {
.presentation {
margin-left: 0;
margin-right: 0;
margin-bottom: 160px;
}
}
@media (max-width: 1304.98px) {
.presentation {
margin-bottom: 118px;
}
}
@media (max-width: 991.98px) {
.presentation {
margin-bottom: 105px;
}
}
.presentation__top {
position: relative;
min-height: 270px;
margin: 0 auto 116px;
padding: 29px 0 40px;
background-image: url(/static/img/png/Box9.png), url(/static/img/png/Box10.png), url(/static/img/png/Box11.png), url(/static/img/png/Box12.png);
background-position: top -4px left 46px, top -30px right -14px, bottom 73px left 278px, bottom 71px right 276px;
background-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
background-size: 17.5%, 21.8%, 8.5%, 8.8%;
}
@media (min-width: 1720px) {
.presentation__top {
background-size: 18.5%, 22%, 9%, 10.1%;
background-position: top -47px left 58px, top -31px right 20px, bottom 8px left 347px, bottom -5px right 352px;
padding-top: 95px;
margin-bottom: 176px;
}
}
@media (max-width: 1304.98px) {
.presentation__top {
background-size: 16%, 20%, 9.5%, 10.1%;
background-position: top -2.8% left 6.5%, top -19% right 3.5%, bottom 32% left 23%, bottom 29% right 22.6%;
margin-bottom: 96px;
}
}
@media (max-width: 991.98px) {
.presentation__top {
background-size: 14.5%, 17%, 8.3%, 9.1%;
background-position: top 9% left 7%, top 5% right 6%, bottom 51% left 14.8%, bottom 47.5% right 13.8%;
padding-top: 31px;
margin-bottom: 76px;
}
}
@media (max-width: 767.98px) {
.presentation__top {
margin-bottom: 77px;
}
}
@media (max-width: 991.98px) {
.presentation__bottom .subtitle {
max-width: 40%;
margin: 0 auto 30px;
}
}
@media (max-width: 767.98px) {
.presentation__bottom .subtitle {
max-width: 65%;
margin-bottom: 21px;
}
}
.presentation__title {
margin-bottom: 23px;
}
@media (max-width: 991.98px) {
.presentation__title {
max-width: 75%;
margin: 0 auto 19px;
}
}
@media (max-width: 767.98px) {
.presentation__title {
margin-bottom: 15px;
}
}
.presentation__subtitle {
margin-bottom: 41px;
font-weight: 600;
}
@media (max-width: 991.98px) {
.presentation__subtitle {
max-width: 55%;
margin: 0 auto 40px;
font-size: 16px;
}
}
@media (max-width: 767.98px) {
.presentation__subtitle {
margin-bottom: 30px;
max-width: 77%;
}
}
.presentation__btn {
margin-bottom: 40px;
}
@media (max-width: 991.98px) {
.presentation__btn {
padding-left: 82px;
padding-right: 82px;
}
}
@media (max-width: 767.98px) {
.presentation__btn {
margin-bottom: 30px;
}
}
.presentation__next {
font-weight: 500;
line-height: 22px;
padding-right: 5px;
}
.presentation__arrows {
padding-top: 2px;
animation: jump 2s ease-in-out infinite;
}
.presentation__cards {
max-width: 1300px;
margin: 0 auto;
}
@media (min-width: 1720px) {
.presentation__cards {
max-width: initial;
margin-left: -10px;
margin-right: -10px;
}
}
@media (max-width: 1304.98px) {
.presentation__cards {
max-width: 1140px;
}
}
.presentation__bottom .presentation__title {
margin-bottom: 13px;
}
@keyframes jump {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-5px);
}
60% {
transform: translateY(20px);
}
70% {
transform: translateY(0px);
}
80% {
transform: translateY(20px);
}
100% {
transform: translateY(0px);
}
}

View File

@@ -0,0 +1,2 @@
.container{margin:0 auto;width:1280px;position:relative}@media (min-width: 1720px){.container{width:1720px}}@media (max-width: 1304.98px){.container{width:1120px;max-width:88vw}}@media (max-width: 991.98px){.container{width:640px;max-width:100vw}}@media (max-width: 767.98px){.container{margin:0 16px;width:auto}}:root{--color-primary: #FF613A;--color-white: #FFFFFF;--color-black: #000000;--color-black2: #272424;--color-grey: #F1F1F1;--color-grey2: #7A7979;--color-orange: #FF613A;--box-shadow-primary: -1px 4px 10px 0 rgba(198, 199, 203, 0.20),
0 -1px 10px 0 rgba(198, 199, 203, 0.20);text-align:center;color:var(--color-black2)}html,body{max-width:100vw;max-height:initial}body{height:100%;position:relative}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-weight:700}h1,.h1{font-size:44px;line-height:52px}@media (min-width: 1720px){h1,.h1{font-size:48px;line-height:52px}}h2,.h2{font-size:24px;line-height:36px;margin-bottom:10px}@media (min-width: 1720px){h2,.h2{font-size:28px;margin-bottom:20px}}h3,.h3{font-size:20px;line-height:28px;margin-bottom:12px}@media (max-width: 1304.98px){h3,.h3{margin-bottom:13px}}h4,.h4{font-size:18px;line-height:26px;margin-bottom:20px}p{line-height:22px;margin-bottom:20px}@media (min-width: 1720px){p{font-size:20px;line-height:26px}}@media (max-width: 991.98px){p{margin-bottom:18px}}@media (max-width: 479.98px){p{margin-bottom:14px}}b{font-weight:500}@media (max-width: 991.98px){b{font-size:16px;line-height:22px}}.btn{display:inline-flex;text-decoration:none;color:black;line-height:22px;border-radius:10px;padding:20px 76px 18px;justify-content:center;align-items:center;margin:0 3px;letter-spacing:0.2px;font-size:18px}.btn--primary{background:var(--color-primary);color:var(--color-white)}.title{font-size:44px;font-weight:700;line-height:52px;margin-bottom:13px;margin-left:auto;margin-right:auto}@media (min-width: 1720px){.title{font-size:48px;margin-bottom:22px}}@media (max-width: 1304.98px){.title{margin-bottom:20px}}@media (max-width: 991.98px){.title{font-size:32px;line-height:38.73px}}@media (max-width: 767.98px){.title{margin-bottom:14px}}.subtitle{margin-bottom:81px;line-height:22px}@media (min-width: 1720px){.subtitle{font-size:20px;margin-bottom:105px}}@media (max-width: 1304.98px){.subtitle{margin-bottom:71px}}.hide{display:none}.hide__xxl{display:inline-flex}@media (min-width: 1720px){.hide__xxl{display:none}}@media (max-width: 991.98px){.hide__md{display:none}}@media (max-width: 479.98px){.hide__xs{display:none}}.show__xxl{display:none}@media (min-width: 1720px){.show__xxl{display:block}}.show__md{display:none}@media (max-width: 991.98px){.show__md{display:initial}}@media (min-width: 480px){.show__xs{display:none}}@media (min-width: 1440px){.br--xxl{display:none}}@media (max-width: 991.98px){.br--md{display:none}}@media (max-width: 767.98px){.br--sm{display:none}}.is-container.wrapper_main{overflow-x:hidden}.is-container.wrapper_main>.container{padding-top:129px}@media (max-width: 1304.98px){.is-container.wrapper_main>.container{padding-top:126px}}@media (max-width: 991.98px){.is-container.wrapper_main>.container{padding-top:85px}}@media (max-width: 767.98px){.is-container.wrapper_main>.container{padding-top:57px}}@media (min-width: 1440px){.is-container.wrapper_main{max-width:initial}}.is-container.wrapper_main>.container{position:relative;left:15px}@media (min-width: 1720px){.is-container.wrapper_main>.container{left:17px}}@media (max-width: 767.98px){.is-container.wrapper_main>.container{left:0}}

View File

@@ -0,0 +1 @@
.sore{margin-bottom:160px;margin-top:1px}@media (min-width: 1720px){.sore{margin-bottom:178px}}@media (max-width: 1304.98px){.sore{margin-bottom:140px}}@media (max-width: 991.98px){.sore{margin-bottom:60px}}@media (max-width: 479.98px){.sore{margin-bottom:40px}}.sore__img{margin:0 auto 13px;position:relative;left:-17px;top:-13px}@media (min-width: 1720px){.sore__img{margin-bottom:40px;top:-5px;left:-21px}}@media (max-width: 1304.98px){.sore__img{left:2px;top:-22px;margin-bottom:4px}}@media (max-width: 991.98px){.sore__img{top:-8px;left:-15px;margin-bottom:18px}}@media (max-width: 479.98px){.sore__img{max-width:108.5%;top:-26px;left:-18px;margin-bottom:-9px}}.sore .title{margin-bottom:40px}@media (min-width: 1720px){.sore .title{margin-bottom:61px}}@media (max-width: 991.98px){.sore .title{margin-bottom:20px}}@media (max-width: 479.98px){.sore .title{margin-bottom:29px}}.sore .subtitle{max-width:62%;margin:0 auto 10px}@media (min-width: 1720px){.sore .subtitle{line-height:26px;max-width:60%}}@media (max-width: 1304.98px){.sore .subtitle{max-width:65%}}@media (max-width: 991.98px){.sore .subtitle{max-width:85%}}@media (max-width: 479.98px){.sore .subtitle{max-width:99%}}.sore .h3{max-width:47%;margin:0 auto 19px}@media (min-width: 1720px){.sore .h3{max-width:38%}}@media (max-width: 1304.98px){.sore .h3{max-width:50%}}@media (max-width: 991.98px){.sore .h3{max-width:65%;margin-bottom:21px}}@media (max-width: 479.98px){.sore .h3{max-width:100%;margin-bottom:17px}}@media (max-width: 767.98px){.sore__btn{padding-left:50px;padding-right:50px}}@media (max-width: 479.98px){.sore__btn{box-sizing:border-box;padding:8px 15px;min-height:60px;display:flex}}

View File

@@ -0,0 +1 @@
.use{margin-bottom:123px}@media (min-width: 1720px){.use{margin-bottom:184px}}@media (max-width: 1304.98px){.use{margin-bottom:142px}}@media (max-width: 991.98px){.use{margin-bottom:121px}}.use__img{width:67.5%;margin-left:16px;margin-bottom:31px}@media (min-width: 1720px){.use__img{width:50.2%;margin-left:15px;margin-bottom:46px}}@media (max-width: 1304.98px){.use__img{width:77%;margin-left:10px;margin-bottom:34px}}@media (max-width: 991.98px){.use__img{margin-left:0;width:100%;margin-bottom:40px}}@media (max-width: 767.98px){.use__img{margin-bottom:30px}}.use__btn{margin-bottom:11px;text-align:center}@media (max-width: 767.98px){.use__btn{max-width:100%;padding-left:50px;padding-right:50px}}.use__link{font-size:18px;font-weight:600;line-height:26px;color:var(--color-grey2)}.use .title{max-width:80%;margin-bottom:49px}@media (min-width: 1720px){.use .title{max-width:40%}}@media (max-width: 991.98px){.use .title{margin-bottom:40px}}@media (max-width: 767.98px){.use .title{max-width:100%;margin-bottom:29px}}.use--lett{margin-bottom:120px}@media (min-width: 1720px){.use--lett{margin-bottom:126px}}@media (max-width: 1304.98px){.use--lett{margin-bottom:106px}}@media (max-width: 991.98px){.use--lett{margin-bottom:79px}}@media (max-width: 767.98px){.use--lett{margin-bottom:81px}}.use--lett .title{margin-bottom:51px}@media (max-width: 1304.98px){.use--lett .title{margin-bottom:39px}}@media (max-width: 767.98px){.use--lett .title{margin-bottom:10px}}.use--lett .use__img{margin-left:-5px;margin-right:-5px;max-width:110%;width:1290px}@media (min-width: 1720px){.use--lett .use__img{width:initial}}@media (max-width: 1304.98px){.use--lett .use__img{margin-left:0;margin-right:0;max-width:100%;width:1120px}}@media (max-width: 767.98px){.use--lett .use__img{max-width:103%;margin-left:-5px;margin-top:-6px}}@media (max-width: 479.98px){.use--lett .use__img{margin-bottom:3px}}@media (max-width: 991.98px){.use .h3{max-width:75%;margin:0 auto 22px}}@media (max-width: 767.98px){.use .h3{max-width:100%;margin-bottom:16px}}

189
static/css/moover/uses.css Normal file
View File

@@ -0,0 +1,189 @@
.uses {
margin-bottom: 120px;
}
@media (min-width: 1720px) {
.uses {
margin-bottom: 136px;
}
}
@media (max-width: 1304.98px) {
.uses {
margin-bottom: 125px;
}
}
@media (max-width: 991.98px) {
.uses {
margin-bottom: 100px;
}
}
@media (max-width: 479.98px) {
.uses {
margin-bottom: 199px;
}
}
.uses__grid {
text-align: left;
display: grid;
grid-template-columns: repeat(3, 1fr);
/* max-width: 101.5%; */
/* width: 101.5%; */
}
@media (max-width: 991.98px) {
.uses__grid {
grid-template-columns: 1fr 1fr;
column-gap: 15px;
}
}
@media (max-width: 479.98px) {
.uses__grid {
display: block;
text-align: center;
}
}
.uses__item {
min-height: 50px;
margin-bottom: 19px;
padding: 0 50px 0 2px;
}
@media (min-width: 1720px) {
.uses__item {
margin-bottom: 22px;
}
}
@media (max-width: 991.98px) {
.uses__item {
padding-right: 0;
}
}
@media (max-width: 991.98px) {
.uses__item p:last-child {
margin-bottom: 0;
}
}
.uses__icon {
margin-bottom: 11px;
}
@media (min-width: 1720px) {
.uses__icon {
width: 147px;
height: 147px;
margin-bottom: 20px;
}
}
.uses .title {
max-width: 50%;
margin: 0 auto 60px;
}
@media (max-width: 1304.98px) {
.uses .title {
max-width: 70%;
margin-bottom: 39px;
}
}
@media (max-width: 479.98px) {
.uses .title {
margin-bottom: 30px;
}
}
.uses__title {
font-size: 24px;
font-weight: 700;
line-height: 36px;
margin-bottom: 10px;
}
.uses--cstmr .uses__item {
text-align: center;
padding: 0 15px;
}
@media (max-width: 991.98px) {
.uses--cstmr .uses__item {
margin-bottom: 42px;
min-height: 255px;
}
}
@media (max-width: 479.98px) {
.uses--cstmr .uses__item {
margin-bottom: 25px;
min-height: 194px;
}
}
@media (max-width: 991.98px) {
.uses--cstmr .uses__item p {
max-width: 90%;
margin: 0 auto;
}
}
@media (max-width: 479.98px) {
.uses--cstmr .uses__item p {
max-width: 100%;
}
}
.uses--cstmr .uses__icon {
width: 118px;
height: 118px;
}
@media (max-width: 991.98px) {
.uses--cstmr .uses__icon {
width: 142px;
height: 142px;
margin-bottom: 23px;
}
}
@media (max-width: 479.98px) {
.uses--cstmr .uses__icon {
width: 117px;
height: 117px;
margin-bottom: 8px;
}
}
@media (max-width: 991.98px) {
.uses--cstmr .uses__grid {
grid-template-columns: 1fr;
}
}
@media (max-width: 1304.98px) {
.uses--cstmr .title {
margin-bottom: 61px;
max-width: 80%;
}
}
@media (max-width: 991.98px) {
.uses--cstmr .title {
margin-bottom: 44px;
}
}
@media (max-width: 479.98px) {
.uses--cstmr .title {
max-width: 90%;
margin-bottom: 31px;
}
}

204
static/css/slick-theme.css Normal file
View File

@@ -0,0 +1,204 @@
@charset 'UTF-8';
/* Slider */
.slick-loading .slick-list
{
background: #fff url('./ajax-loader.gif') center center no-repeat;
}
/* Icons */
@font-face
{
font-family: 'slick';
font-weight: normal;
font-style: normal;
src: url('./fonts/slick.eot');
src: url('./fonts/slick.eot?#iefix') format('embedded-opentype'), url('./fonts/slick.woff') format('woff'), url('./fonts/slick.ttf') format('truetype'), url('./fonts/slick.svg#slick') format('svg');
}
/* Arrows */
.slick-prev,
.slick-next
{
font-size: 0;
line-height: 0;
position: absolute;
top: 50%;
display: block;
width: 20px;
height: 20px;
padding: 0;
-webkit-transform: translate(0, -50%);
-ms-transform: translate(0, -50%);
transform: translate(0, -50%);
cursor: pointer;
color: transparent;
border: none;
outline: none;
background: transparent;
}
.slick-prev:hover,
.slick-prev:focus,
.slick-next:hover,
.slick-next:focus
{
color: transparent;
outline: none;
background: transparent;
}
.slick-prev:hover:before,
.slick-prev:focus:before,
.slick-next:hover:before,
.slick-next:focus:before
{
opacity: 1;
}
.slick-prev.slick-disabled:before,
.slick-next.slick-disabled:before
{
opacity: .25;
}
.slick-prev:before,
.slick-next:before
{
font-family: 'slick';
font-size: 20px;
line-height: 1;
opacity: .75;
color: white;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.slick-prev
{
left: -25px;
}
[dir='rtl'] .slick-prev
{
right: -25px;
left: auto;
}
.slick-prev:before
{
content: '←';
}
[dir='rtl'] .slick-prev:before
{
content: '→';
}
.slick-next
{
right: -25px;
}
[dir='rtl'] .slick-next
{
right: auto;
left: -25px;
}
.slick-next:before
{
content: '→';
}
[dir='rtl'] .slick-next:before
{
content: '←';
}
/* Dots */
.slick-dotted.slick-slider
{
margin-bottom: 30px;
}
.slick-dots
{
position: absolute;
bottom: -25px;
display: block;
width: 100%;
padding: 0;
margin: 0;
list-style: none;
text-align: center;
}
.slick-dots li
{
position: relative;
display: inline-block;
width: 20px;
height: 20px;
margin: 0 5px;
padding: 0;
cursor: pointer;
}
.slick-dots li button
{
font-size: 0;
line-height: 0;
display: block;
width: 20px;
height: 20px;
padding: 5px;
cursor: pointer;
color: transparent;
border: 0;
outline: none;
background: transparent;
}
.slick-dots li button:hover,
.slick-dots li button:focus
{
outline: none;
}
.slick-dots li button:hover:before,
.slick-dots li button:focus:before
{
opacity: 1;
}
.slick-dots li button:before
{
font-family: 'slick';
font-size: 6px;
line-height: 20px;
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 20px;
content: '•';
text-align: center;
opacity: .25;
color: black;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.slick-dots li.slick-active button:before
{
opacity: .75;
color: black;
}

146
static/css/slick.css Normal file
View File

@@ -0,0 +1,146 @@
/* Slider */
.slick-slider {
position: relative;
display: block;
box-sizing: border-box;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
-khtml-user-select: none;
-ms-touch-action: pan-y;
touch-action: pan-y;
-webkit-tap-highlight-color: transparent;
}
.slick-list {
position: relative;
display: block;
overflow: hidden;
margin: 0;
padding: 0;
}
.slick-list:focus {
outline: none;
}
.slick-list.dragging {
cursor: pointer;
cursor: hand;
}
.slick-slider .slick-track,
.slick-slider .slick-list {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.slick-track {
position: relative;
top: 0;
left: 0;
display: block;
margin-left: auto;
margin-right: auto;
}
.slick-track:before,
.slick-track:after {
display: table;
content: '';
}
.slick-track:after {
clear: both;
}
.slick-loading .slick-track {
visibility: hidden;
}
.slick-slide {
display: none;
float: left;
height: 100%;
min-height: 1px;
}
[dir='rtl'] .slick-slide {
float: right;
}
.slick-slide img {
display: block;
}
.slick-slide.slick-loading img {
display: none;
}
.slick-slide.dragging img {
pointer-events: none;
}
.slick-initialized .slick-slide {
display: block;
}
.slick-loading .slick-slide {
visibility: hidden;
}
.slick-vertical .slick-slide {
display: block;
height: auto;
border: 1px solid transparent;
}
.slick-arrow.slick-hidden {
display: none;
}
.slick-prev, .slick-next {
font-size: 0;
line-height: 0;
position: absolute;
top: 50%;
display: block;
width: 80px;
height: 80px;
padding: 0;
-webkit-transform: translate(0, -50%);
-ms-transform: translate(0, -50%);
transform: translate(0, -50%);
cursor: pointer;
color: transparent;
outline: none;
background: transparent;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 1px solid var(--color-primary);
outline: 0;
border-radius: 50%;
box-sizing: border-box;
text-indent: -9999px;
z-index: 1;
background: var(--color-primary) url("/static/img/svg/slick-arrow.svg") no-repeat center;
transition: background-color .2s ease-in-out;
}
.slick-next {
right: 0;
transform: rotate(180deg) translate(0, 50%);
}
.slick-disabled {
display: none !important;
}

View File

@@ -443,7 +443,7 @@
.block-chat{
width: 63%;
height: calc(100vh - 120px);
height: calc(100vh - 150px);
border-radius: 10px;
border: 1px solid #E6E6E6;
background: #ffffff;
@@ -708,6 +708,13 @@
display: block;
}
.unredmessages_value_text{
padding-top: 8px;
padding-left: 0;
position:relative;
top: -6px;
}
.cost-messages-in-user-tab-messenger{
width: 15px;
@@ -719,8 +726,8 @@
}
.cost-messages-in-user-tab-messenger > span{
padding-top: 1px;
display: block;
padding-top: 7px;
/*display: block;*/
font-size: 10px;
}
@@ -1313,7 +1320,7 @@
}
.from-to-country-container-carrier{
width: calc(100% - 70px);
width: calc(100% - 60px);
margin: auto;
background: #F8F8F8;
box-shadow: -1px 4px 10px 0 rgba(198, 199, 203, 0.20), 0 -1px 10px 0 rgba(198, 199, 203, 0.20);
@@ -1322,6 +1329,7 @@
padding-left: 35px;
padding-right: 35px;
margin-bottom: 20px;
border-radius: 10px;
}
@@ -1384,6 +1392,9 @@
.container_inf_about_moving{
display: block;
width: 100%;
background: #F8F8F8;
padding: 5px;
border-radius: 10px;
}
@@ -1558,6 +1569,7 @@ a.open_inf_carrier{
width: 33%;
float: right;
padding: 2%;
position: relative;
}
.title_container_inf_carrier{
@@ -2518,7 +2530,7 @@ a.open_inf_carrier{
background: #FFFFFF;
border-radius: 10px;
max-height: calc(100vh - 125px);
overflow: unset;
/*overflow: unset;*/
left: -19px;
top: 0;
}
@@ -2591,6 +2603,9 @@ a.open_inf_carrier{
.menu_buttons.right.open .menu_profile{
padding-top: 45px;
}
.menu_buttons.right.padding_remove.open .menu_profile{
padding-top: unset;
}
@@ -2783,7 +2798,7 @@ a.open_inf_carrier{
/*}*/
.menu_profile>div>a{
/*font-size: 12px;*/
line-height: 13px;
/*line-height: 13px;*/
}
.menu_profile>div>.logout{
height: 100%;
@@ -2993,6 +3008,8 @@ a.open_inf_carrier{
display: none;
}
.cookie_block.show{
display: block;
}
@@ -3019,4 +3036,64 @@ a.open_inf_carrier{
height: 25px;
width: 95px;
cursor: pointer;
}
/*popup*/
.popup_wrapper{
display: none;
position: fixed; /* Используйте fixed, чтобы попап оставался на месте при прокрутке */
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5); /* Полупрозрачный фон */
justify-content: center;
align-items: center;
z-index: 9999;
}
.popup_wrapper.show{
display: flex;
}
.popup_content{
position: relative;
width: 38%;
height: fit-content;
background: #FFFFFF;
border-radius: 15px;
text-align: center;
padding: 28px;
font-family: Inter;
}
.popup_cross{
position: absolute;
right: 5%;
cursor: pointer;
}
.popup_img>img{
background: #E1E1E1;
border-radius: 39px;
padding: 5px;
}
.popup_title{
font-weight: 700;
font-size: 34px;
margin-top: 20px;
}
.popup_text{
line-height: 30px;
font-size: 20px;
margin-top: 10px;
color: #6F6C90;
}
.popup_content>.confirm_profile_btn{
width: 62%;
}
#poup_text_bold{
font-weight: 700;
color: #1d1e20;
}
#authenticated_img{
display: none;
}

View File

@@ -253,6 +253,7 @@ footer {
height: 318px;
background: #272424;
margin-top: 50px;
text-align: left;
}
section.register>h1 {
@@ -419,6 +420,7 @@ footer>div {
font-style: normal;
font-weight: 400;
line-height: 22px;
}
.footer_text_contact {
@@ -688,6 +690,67 @@ header .header-second {
display: inline-block;
}
.carrier-card.highlight-color{
background: linear-gradient(90deg, #FBED96 0%, #ABECD6 100%);
}
.control_frame{
display: none;
position: absolute;
background-color: white;
border-radius: 10px;
box-shadow: -1px 4px 10px 0px rgba(198, 199, 203, 0.20), 0px -1px 10px 0px rgba(198, 199, 203, 0.20);
z-index: 1;
border: 1px solid #FF613A;
padding: 0 10px;
left: 0;
right: 0;
margin: 0 18px;
}
.control_frame.show{
display: block;
}
button#send_upgrade {
font-size: 16px;
font-weight: 500;
line-height: 20px;
text-align: center;
color: #FF613A;
width: 100%;
padding: 10px;
margin: 10px 0;
}
button#send_upgrade:hover {
background: #FF613A;
color: white;
border-radius: 15px;
}
.success_rising{
display: none;
}
.success_rising.show{
display: block;
padding: 5px;
}
.success_rising_text{
text-align: center;
padding-bottom: 10px;
}
.close_success_rising{
cursor: pointer;
width: 100%;
padding-bottom: 5px;
}
.upd_form.hide{
display: none;
}
.from_address_point_txt.red_text{
color: #ff0000;
}
@@ -695,6 +758,24 @@ header .header-second {
color: #ff0000;
}
.info_text_wrapper{
padding-top: 20px;
text-align: center;
color: red;
}
.info_text{
display: none;
}
.info_text.show{
display: block;
}
button#webpush-subscribe-button {
color: white;
text-decoration: underline;
}
.header-second-item,
@@ -746,6 +827,7 @@ span.btn_profile_name {
display: none;
position: absolute;
background-color: #f9f9f9;
z-index: 1;
}
@@ -920,6 +1002,16 @@ section.register>form {
display: inline-block;
width: 90%;
}
.necessary_text {
color: rgba(39, 36, 36, 0.60);
/* Body text 3 */
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 20px;
display: inline-block;
width: 100%;
}
.button_register>button {
display: block;
@@ -1044,6 +1136,16 @@ input.deactive {
background-color: white;
}
.custom-checkbox.round+label::before {
border-radius: 20px;
width: 25px;
height: 25px;
border: 1px solid #E0E0E0;
background-color: #FAFAFA;
}
.custom-checkbox:not(:disabled):not(:checked)+label:hover::before {
@@ -1119,7 +1221,7 @@ section.login {
margin-bottom: 120px;
}
section.login>h1 {
section.login>h1, div.recovery_pas>h1 {
color: #272424;
text-align: center;
/* Heading 1 */
@@ -1131,7 +1233,7 @@ section.login>h1 {
margin-bottom: 40px;
}
section.login>form {
section.login>form, div.recovery_pas>form {
max-width: 420px;
margin: auto;
text-align: center;
@@ -1203,7 +1305,8 @@ section.login>form {
color: rgba(39, 36, 36, 0.60);
}
.call_to_reg {
cursor: pointer;
text-align: center;
color: rgba(39, 36, 36, 0.60);
font-style: normal;
font-weight: 500;
@@ -1483,6 +1586,21 @@ span.errorlist{
position: absolute;
bottom: 27%;
}
.label_text{
display: inline-block;
position: absolute;
bottom: 20%;
font-size: 14px;
}
label.route_label {
margin-bottom: unset;
padding-top: 10px;
}
.sub_label_text {
font-size: 14px;
margin-left: 35px;
}
/*create new route*/
select#id_type_transport{
@@ -1995,6 +2113,7 @@ button#raise_route {
border-radius: 10px;
text-align: center;
margin-bottom: 10px;
margin-top: 10px;
}
.edit_route{
@@ -2004,6 +2123,10 @@ button#raise_route {
background: #E6E6E6;
}
.edit_route.highlight-color{
background: #F8F8F8;
}
.edit_route.hide{
display: none;
}
@@ -2155,7 +2278,7 @@ button.cancel_remove.show, button.confirm_remove.show{
font-size: 26px;
}
#title_static{
#title_static, #title_static_small{
text-align: center;
font-size: 44px;
font-style: normal;
@@ -2165,6 +2288,10 @@ button.cancel_remove.show, button.confirm_remove.show{
}
#title_static_small{
font-size: 34px;
}
.ta_center{
margin: 120px auto 40px;
}
@@ -2227,12 +2354,12 @@ span#sub_title_static{
height: 60px;
}
.top_block_static{
.top_block_static {
position: relative;
width: 90%;
height: 194px;
height: 270px;
margin: 0 auto 0;
padding: 60px 40px 0 40px;
padding: 40px 40px 0 40px;
}
.top_block_static_wrapper{
@@ -2266,10 +2393,10 @@ span#sub_title_static{
url(/static/img/png/Box8.png),
url(/static/img/png/Box4.png);
background-position:
bottom -31px left -13px,
bottom 26px left -13px,
top 159px left 242px,
top 0px right -15px,
top 146px right 215px;
top 34px right -19px,
top 145px right 215px;
background-repeat:
no-repeat,
no-repeat,
@@ -3190,6 +3317,31 @@ details[open] summary ~ *{
text-decoration: underline;
}
.self_news_text>ul>li{
list-style: disc;
}
.self_news_text>ul{
margin-left: 20px;
}
.self_news_text>ol{
padding-left: 20px;
}
.self_news_text>ol>li{
margin: 10px 0;
}
.self_news_text>ol>li>ul{
list-style: disc;
margin-left: 20px;
}
.advertisement_block_news {
display: none;
}
.self_news_text>img{
margin: 15px 0;
}
.self_news_img{
float: right;
width: 40%;
@@ -3216,6 +3368,25 @@ details[open] summary ~ *{
/*END news articles all*/
.login.hide{
display: none;
}
.recovery_pas{
display: none;
}
.recovery_pas.show{
display: block;
}
.recovery.hide{
display: none;
}
input.error::placeholder {
color: red;
font-weight: bold;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

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