151 Commits

Author SHA1 Message Date
SBD
e74731b789 0.0.185 route forms 2025-03-05 14:46:06 +03:00
SBD
8694856fc9 Merge remote-tracking branch 'origin/v2' into v2 2025-03-05 14:31:28 +03:00
SBD
3d2b70609d 0.0.184 w_route_card 2025-03-05 14:30:00 +03:00
SDE
dd260e229a 2.1.46 get_routes_Dict change sort routes 2025-02-28 17:53:50 +03:00
SBD
0bc8f85bee 0.0.183 routes 2025-02-28 17:51:42 +03:00
SBD
496534f76a 0.0.182 routes 2025-02-28 17:37:20 +03:00
SBD
d681f6739b 0.0.181 routes 2025-02-28 17:24:17 +03:00
SDE
64de7ea34c 2.1.45 country short_code > code 2025-02-28 17:22:50 +03:00
SBD
25c913c572 0.0.180 routes 2025-02-28 17:21:37 +03:00
SBD
f34a54a33c 0.0.179 routes 2025-02-28 17:14:58 +03:00
SBD
b511cbbdaf 0.0.178 routes 2025-02-28 17:09:16 +03:00
SBD
17c040f0d3 Merge remote-tracking branch 'origin/v2' into v2 2025-02-28 17:06:01 +03:00
SBD
f4a1da9ded 0.0.177 routes 2025-02-28 17:05:56 +03:00
SDE
79de035ae7 2.1.45 fixes text in create routes forms 2025-02-28 16:49:43 +03:00
SDE
ddc844456d 2.1.44 get_routes_Dict add now_DT 2025-02-28 16:24:50 +03:00
SBD
fef72df927 Merge remote-tracking branch 'origin/v2' into v2 2025-02-28 16:07:58 +03:00
SBD
134216c5f5 0.0.176 routes 2025-02-28 16:07:53 +03:00
SDE
685c201840 2.1.43 fix 2025-02-28 15:42:44 +03:00
SBD
fd343f098e 0.0.175 routes 2025-02-28 15:26:10 +03:00
SBD
053d7f79da Merge remote-tracking branch 'origin/v2' into v2 2025-02-28 15:17:05 +03:00
SBD
60a088236b 0.0.174 routes 2025-02-28 15:16:49 +03:00
SDE
768d82a026 2.1.42 elements_on_page set 25 2025-02-28 15:15:48 +03:00
SDE
1c51c7fbf5 2.1.41 create_or_change_route_ajax get route_id by POST 2025-02-28 15:12:58 +03:00
SBD
2196890105 0.0.173 routes 2025-02-28 15:12:04 +03:00
SBD
4bf27702a4 Merge remote-tracking branch 'origin/v2' into v2 2025-02-28 14:53:31 +03:00
SBD
4bf65b6eef 0.0.172 routes 2025-02-28 14:53:26 +03:00
SDE
98c6622e1f 2.1.40 cargo_type default change 2025-02-28 14:43:34 +03:00
SBD
e0baa07c4f 0.0.171 routes 2025-02-28 14:42:21 +03:00
SBD
e2d951ccbf Merge remote-tracking branch 'origin/v2' into v2 2025-02-28 14:33:00 +03:00
SBD
cdff6c1966 0.0.170 routes 2025-02-28 14:32:54 +03:00
SDE
00fe34bc0e 2.1.40 cargo_type_for_show сге 2025-02-28 14:24:44 +03:00
SBD
910ea908c3 0.0.169 routes 2025-02-24 17:49:24 +03:00
SBD
017d3b18ef 0.0.168 routes 2025-02-24 17:46:38 +03:00
SBD
61efc14b9a 0.0.167 routes 2025-02-24 17:44:03 +03:00
SBD
f3a28ddb30 0.0.166 routes 2025-02-24 17:13:29 +03:00
SBD
1dc8a64f9f 0.0.164 routes 2025-02-17 20:16:48 +03:00
SBD
56371267bc 0.0.163 routes 2025-02-17 20:01:54 +03:00
SBD
a68fe3970f 0.0.162 routes 2025-02-17 19:16:54 +03:00
SBD
217b1d89ea Merge remote-tracking branch 'origin/v2' into v2 2025-02-17 17:20:10 +03:00
SBD
4f2e3776ed 0.0.161 routes 2025-02-17 17:20:04 +03:00
SDE
3c6f90f103 2.1.38 find_routes paging 2025-02-17 17:05:39 +03:00
SBD
e3fd8457c0 0.0.160 routes 2025-02-17 16:53:45 +03:00
SBD
8119955f52 0.0.159 routes 2025-02-17 16:13:53 +03:00
SBD
b4b79e185e 0.0.158 routes 2025-02-17 15:59:04 +03:00
SDE
fb07005e9a 2.1.36 route is_highlighted_now 2025-02-17 15:51:52 +03:00
SBD
cd7bfa07bb 0.0.157 routes 2025-02-17 15:37:06 +03:00
SDE
48a21b319a Merge remote-tracking branch 'origin/v2' into v2 2025-02-17 15:23:20 +03:00
SDE
808d44555c 2.1.35 route_search_results_View fix cities 2025-02-17 15:23:11 +03:00
SBD
f7857cb5c2 0.0.156 routes 2025-02-17 15:21:12 +03:00
SBD
15b5911013 Merge remote-tracking branch 'origin/v2' into v2 2025-02-17 15:18:22 +03:00
SBD
8e6111dfb1 0.0.155 routes 2025-02-17 15:18:16 +03:00
SDE
c476fa6d77 2.1.34 route_search_results_View fix cities 2025-02-17 15:14:35 +03:00
SBD
c59c5d929b 0.0.153 routes 2025-02-17 14:59:02 +03:00
SBD
e1053073a1 0.0.152 routes 2025-02-14 16:20:26 +03:00
SBD
0a56555f35 0.0.151 routes 2025-02-05 19:19:31 +03:00
SBD
1188b45c20 0.0.150 routes 2025-02-05 18:47:30 +03:00
SBD
97ffcf417e 0.0.149 routes 2025-02-05 18:17:31 +03:00
SBD
5801e10f80 0.0.148 routes 2025-02-04 21:54:27 +03:00
SBD
3c08686f21 0.0.147 routes 2025-02-04 20:06:22 +03:00
SBD
eff021b4e2 0.0.146 routes 2025-02-04 19:27:36 +03:00
SDE
8e2f5f6bac Merge remote-tracking branch 'origin/v2' into v2 2025-02-04 18:08:38 +03:00
SDE
05798c4b49 2.1.33 short names for type_trasport and cargo_type in route widget 2025-02-04 18:08:29 +03:00
SBD
876d91de01 0.0.145 routes 2025-02-04 18:07:53 +03:00
SBD
a67436b854 0.0.144 routes 2025-02-04 17:28:43 +03:00
SDE
6e8db45cb8 Merge remote-tracking branch 'origin/v2' into v2 2025-02-04 17:02:15 +03:00
SDE
51abe338c0 2.1.32 avatar in admin 2025-02-04 17:02:04 +03:00
SBD
84aecc715e 0.0.143 routes 2025-02-03 19:08:21 +03:00
SBD
93764163d4 0.0.142 routes 2025-02-03 16:45:42 +03:00
SBD
9e3888bccf 0.0.141 routes 2025-02-02 21:38:03 +03:00
SBD
293b7c9f6f 0.0.140 routes 2025-02-01 14:07:30 +03:00
SBD
70dd911445 0.0.139 routes 2025-01-31 20:00:42 +03:00
SBD
8496a0844c 0.0.138 scroll search route results 2025-01-31 19:15:37 +03:00
SBD
fe110b1eb9 0.0.137 scroll search route results 2025-01-31 19:03:01 +03:00
SBD
0407cadd50 0.0.136 scroll search route results 2025-01-28 15:10:45 +03:00
SBD
b825504063 0.0.136 scroll search route results 2025-01-25 23:20:24 +03:00
SBD
ec55fa787f 0.0.135 scroll search route results 2025-01-25 21:37:23 +03:00
SBD
cd55111003 0.0.134 fix form textarea 2025-01-25 13:43:37 +03:00
SBD
ee31eb045f 0.0.134 search routes 2025-01-25 13:34:20 +03:00
SBD
56bcd5bee9 0.0.133 search routes 2025-01-25 00:50:06 +03:00
SBD
b5155e7ce2 0.0.132 search routes 2025-01-25 00:05:00 +03:00
SBD
ca05de3d7d 0.0.131 search routes 2025-01-24 21:43:03 +03:00
SDE
04af851875 2.1.28 editable_routes property 2025-01-24 19:54:53 +03:00
SBD
4c7126f414 0.0.130 search routes 2025-01-24 18:14:22 +03:00
SBD
e217506627 0.0.56 p search res 2025-01-24 07:44:18 +03:00
SBD
6e0c5d1662 0.0.55 p search res 2025-01-23 19:43:08 +03:00
SBD
15143188b7 0.0.54 p search res 2025-01-23 19:35:11 +03:00
SDE
da9dc4bb03 2.1.27 route_search_results_View change tpl 2025-01-23 18:17:35 +03:00
SBD
ad34c1b670 0.0.53 p search res 2025-01-23 18:13:51 +03:00
SBD
bb691a6ad0 0.0.52 w route card 2025-01-23 18:10:44 +03:00
SBD
2c00a38ceb 0.0.51 w route card 2025-01-21 16:48:19 +03:00
SBD
8291f956c2 0.0.50 w route card 2025-01-21 00:10:01 +03:00
SBD
a8335f10ee 0.0.49 w route card 2025-01-20 23:40:34 +03:00
SBD
db135af725 Merge remote-tracking branch 'origin/v2' into v2 2025-01-18 15:08:35 +03:00
SBD
feb2b9d697 0.0.48 w route card 2025-01-18 15:08:26 +03:00
SDE
2f0e1bb396 2.1.26 check_post_request_and_get_data 2025-01-18 13:55:49 +03:00
SBD
2a7a666f7d Merge remote-tracking branch 'origin/v2' into v2 2025-01-18 13:31:47 +03:00
SBD
9bfcb00861 0.0.47 w route card 2025-01-18 13:31:38 +03:00
SDE
06eba5ff25 2.1.25 fix edit_route 2025-01-18 04:33:30 +03:00
SBD
3c1f03de26 0.0.46 w route card 2025-01-17 20:49:35 +03:00
SBD
01ffddf9ef 0.0.45 w route card 2025-01-17 19:52:01 +03:00
SBD
b3f4eec2e9 0.0.44 w route card 2025-01-17 19:43:35 +03:00
SBD
34ef2f23b7 0.0.43 w route card 2025-01-16 18:27:06 +03:00
SBD
529b324817 0.0.42 fix form 2025-01-16 17:18:12 +03:00
SBD
b3e8d75539 0.0.41 fix form 2025-01-16 16:27:29 +03:00
SBD
81e0812c66 0.0.40 fix form 2025-01-16 16:20:25 +03:00
SBD
e667e5a0c9 0.0.39 fix form 2025-01-16 15:58:22 +03:00
SBD
6f9bfb38f5 Merge remote-tracking branch 'origin/v2' into v2 2025-01-16 15:53:07 +03:00
SBD
6656457bcc 0.0.38 fix form 2025-01-16 15:52:49 +03:00
SDE
07ee30f360 2.1.24 fix send support mail 2025-01-16 15:29:30 +03:00
SDE
5f4ea5910d 2.1.22 routes funcs 2025-01-16 15:08:58 +03:00
SBD
c568494a8e 0.0.38 forms 2025-01-15 21:46:24 +03:00
SBD
fd211c464f 0.0.37 forms 2025-01-15 21:35:50 +03:00
SBD
ff58c07ca6 0.0.36 forms 2025-01-15 21:07:52 +03:00
SBD
2ea6d61d39 0.0.35 forms 2025-01-15 21:05:51 +03:00
SBD
c5214d830f Merge remote-tracking branch 'origin/v2' into v2 2025-01-15 20:51:59 +03:00
SBD
8f3bba620c 0.0.34 forms 2025-01-15 20:51:50 +03:00
SDE
9116b9efe1 2.1.21 fix cargo_type choices 2025-01-15 19:55:09 +03:00
SDE
575ee074b1 2.1.20 reference_data_tags 2025-01-15 19:17:26 +03:00
SBD
2d650cd51f Merge remote-tracking branch 'origin/v2' into v2 2025-01-15 18:40:48 +03:00
SBD
4fab7ba2c0 0.0.33 forms 2025-01-15 18:40:11 +03:00
SDE
72c658c594 Merge remote-tracking branch 'origin/v2' into v2 2025-01-15 18:12:24 +03:00
SDE
89058ed264 2.1.19 route form 2025-01-15 18:12:12 +03:00
SBD
c247bfcefa 0.0.32 forms 2025-01-15 18:11:01 +03:00
SBD
74742c3e8e 0.0.31 forms 2025-01-15 18:04:57 +03:00
SBD
33239e3c90 0.0.30 forms 2025-01-15 18:00:11 +03:00
SBD
97be421ee3 Merge remote-tracking branch 'origin/v2' into v2 2025-01-14 20:09:25 +03:00
SBD
8484e48c56 0.0.29 forms 2025-01-14 20:09:16 +03:00
SDE
c07bf2538d 2.1.18 route form 2025-01-14 20:09:05 +03:00
SDE
8ac11d6234 2.1.17 route form 2025-01-14 19:56:36 +03:00
SBD
a0b08a9a94 0.0.28 my routes 2025-01-14 19:25:52 +03:00
SBD
9bc6d488f1 Merge remote-tracking branch 'origin/v2' into v2 2025-01-14 19:11:29 +03:00
SBD
b7a830ab6f 0.0.27 my routes 2025-01-14 19:11:20 +03:00
SDE
7b915f0c6c 2.1.16 change cargo_type and transport_type names 2025-01-14 19:00:19 +03:00
SBD
a68d469eda 0.0.26 my routes 2025-01-14 18:41:07 +03:00
SBD
a5b106edfe 0.0.25 my routes 2025-01-14 18:39:12 +03:00
SDE
a40ae5d37d 2.1.15 change cargo_type and transport_type names 2025-01-14 18:38:38 +03:00
SBD
4b57ad3f8b 0.0.24 my routes 2025-01-14 18:23:00 +03:00
SBD
cdedebd9f6 0.0.23 my routes 2025-01-14 17:50:56 +03:00
SBD
c237875732 0.0.22 form mover 2025-01-14 17:06:06 +03:00
SBD
7f7a3d19fb 0.0.21 form mover 2025-01-14 17:05:41 +03:00
SBD
1db2b0edb9 0.0.20 form mover 2025-01-14 16:52:29 +03:00
SDE
9280025f1c 2.1.15 get_cargo_type_by_transport_type_ajax 2025-01-14 16:31:18 +03:00
SBD
9666c9dbf4 0.0.19 form mover 2025-01-14 16:28:32 +03:00
SBD
aac673f212 0.0.18 form mover 2025-01-14 16:27:45 +03:00
SBD
9a2a2d9aa2 0.0.17 form mover 2025-01-14 16:23:14 +03:00
SBD
9e8a5d1f37 Merge remote-tracking branch 'origin/v2' into v2 2025-01-14 16:19:52 +03:00
SBD
e938d5915a 0.0.16 form mover 2025-01-14 16:19:40 +03:00
SDE
b35ff27654 2.1.14 get_cargo_type_by_transport_type_ajax 2025-01-14 16:05:53 +03:00
SDE
cfe1a9d585 2.1.13 get_cargo_type_by_transport_type_ajax 2025-01-14 16:04:16 +03:00
SDE
04f097c1a9 Merge remote-tracking branch 'origin/v2' into v2 2025-01-14 11:30:58 +03:00
SDE
c81448e43d 2.1.12 create mover route form fix type_transport 2025-01-14 11:30:49 +03:00
100 changed files with 3243 additions and 325 deletions

View File

@@ -41,6 +41,7 @@ class Admin_ProfileInline(admin.StackedInline):
'fields': (
# ('account_type',),
('enable',),
('avatar',),
('phone',),
('country', 'city'),
('mailing_on', ),

View File

@@ -314,7 +314,11 @@ 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']]
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,
@@ -550,7 +554,7 @@ def my_routes_ajax(request):
Dict = {
}
html = render_to_string('blocks/profile/b_my_routes.html', Dict, request=request)
html = render_to_string('v2/blocks/b_my_routes.html', Dict, request=request)
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))

View File

@@ -0,0 +1,11 @@
from datetime import datetime
import pytz
def get_cur_DT_by_timezone(timezone, DT=None):
if not DT:
DT = datetime.now()
if not timezone:
return DT
return DT.astimezone(tz=pytz.timezone(timezone))

49
BaseModels/exceptions.py Normal file
View File

@@ -0,0 +1,49 @@
import asyncio
import traceback
from asgiref.sync import sync_to_async
from BaseModels.mailSender import techSendMail
from BaseModels.print_funcs import print_ext
from GeneralApp.funcs_options import get_mail_send_options
# from MessageBotsApp.telegram.tg_bot import send_message
async def send_exception_msg(msgr_msg, mail_msg):
# from MessageBotsApp.funcs import send_msg_to_staff
mail_sets = await sync_to_async(get_mail_send_options)()
# await send_msg_to_staff('telegram', msgr_msg)
await sync_to_async(techSendMail)(sets=mail_sets, html_content=mail_msg, title='iBaked Exception')
return True
async def exception_processing(exc, user=None):
tb = traceback.format_exc()
cutted_tb = tb[:500]
msgr_msg = f'user {str(user)} Exception = {str(exc)}\n{str(cutted_tb)}'
mail_msg = f'user {str(user)} Exception = {str(exc)}<br>\n{str(tb)}'
print_ext(msgr_msg)
# try:
# loop = asyncio.get_event_loop()
# except RuntimeError:
# loop = asyncio.new_event_loop()
# asyncio.set_event_loop(loop)
#
# loop = asyncio.new_event_loop()
# asyncio.set_event_loop(loop)
# async_result = loop.run_until_complete(send_exception_msg(msgr_msg, mail_msg))
# loop.close()
loop = asyncio.get_event_loop()
task = loop.create_task(send_exception_msg(msgr_msg, mail_msg))
status_code = 400
return msgr_msg, status_code

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,6 +1,13 @@
from asgiref.sync import async_to_sync
from django.http import HttpResponse, Http404, FileResponse
from django.conf import settings
from BaseModels.exceptions import exception_processing
from BaseModels.print_funcs import print_ext
def get_and_set_lang(request):
from django.utils.translation import activate, get_language
@@ -30,6 +37,27 @@ def get_and_set_lang(request):
return lang
import json
from urllib.parse import unquote
def check_post_request_and_get_data(request, allow_unauthorized=False):
if request.method != 'POST':
return None
if not allow_unauthorized:
if not request.user or not request.user.is_authenticated:
return None
try:
data = request.POST.dict()
if not data and request.body:
data = json.loads(unquote(request.body))
except Exception as e:
msg, status_code = async_to_sync(exception_processing)(e, request.user)
return msg
return data
def get_add_to_ajax_response_Dict(user):
context_Dict = {}

View File

@@ -26,7 +26,6 @@ def generate_routes(request, routes_count):
):
raise Http404
from RoutesApp.funcs import get_city_by_type_transport_and_address_point
from RoutesApp.models import Route
from ReferenceDataApp.models import Airport, City
@@ -247,10 +246,12 @@ def MainPage(request):
from ArticlesApp.models import ArticleModel
arts = ArticleModel.objects.filter(enable=True).order_by('-createDT')[:3]
owner_type = 'mover'
Dict = {
'page': page,
'FAQ': page.FAQ_items.filter(enable=True),
'route_form': RouteForm(),
'route_form': RouteForm(owner_type=owner_type),
'articles': arts,
'owner_type': 'mover'
}
@@ -273,18 +274,19 @@ def StaticPageView(request, url):
Dict = {}
owner_type = None
if url == '':
return MainPage(request)
elif url == 'for_movers':
Dict.update({
'route_form': RouteForm(),
'owner_type': 'customer',
})
owner_type = 'customer'
elif url == 'for_customers':
owner_type = 'mover'
if owner_type:
Dict.update({
'route_form': RouteForm(),
'owner_type': 'mover'
'route_form': RouteForm(owner_type=owner_type),
'owner_type': owner_type,
})
# elif url == 'works':
# return WorksPage(request)
elif url in ['main']:

View File

@@ -7,6 +7,13 @@ from timezonefinder import TimezoneFinder
tzf = TimezoneFinder()
def get_city_by_id(city_id):
try:
return City.objects.get(id=city_id)
except City.DoesNotExist:
return None
def search_cities_in_db(search_str):
res_data = []
Q_obj = Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \
@@ -18,7 +25,7 @@ def search_cities_in_db(search_str):
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', 'country__flag', 'country__short_code'
'id', 'name', 'country__name', 'timezone', 'country__flag', 'country__code'
)
return list(res_data)

View File

@@ -70,7 +70,7 @@ def search_city_ajax(request):
res_Dict = {
'res_search_list': html
'res_search_list': html,
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict

View File

@@ -0,0 +1 @@
__author__ = 'SDE'

View File

@@ -0,0 +1,17 @@
__author__ = 'SDE'
from django import template
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe
from BaseModels.datetime_funcs import get_cur_DT_by_timezone
register = template.Library()
@register.filter
@stringfilter
def get_cur_DT_by_tz(timezone, DT=None):
return get_cur_DT_by_timezone(timezone, DT).strftime('%Y-%m-%d %H:%M:%S')

View File

@@ -30,6 +30,7 @@ class Admin_Route(Admin_Trans_BaseModel):
]
search_fields = [
'id',
'owner__first_name', 'owner__last_name', 'from_city__name', 'to_city__name', 'owner__email'
]
raw_id_fields = ['from_city', 'to_city']

View File

@@ -3,47 +3,12 @@ from django import forms
from django.contrib.auth.forms import AuthenticationForm
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError
from .funcs import get_cargo_types_by_type_transport
from .models import *
import copy
def routeForm_assign_choices_by_type_transport(form, type_transport):
if type_transport == 'avia':
transfer_location_choices = (
('airport', _('В аэропорту')),
('city', _('По городу')),
('other', _('По договоренности'))
)
cargo_type_choices = (
('cargo', _('Груз')),
('parcel', _('Бандероль')),
('package', _('Посылка')),
('letter', _('Письмо\Документ'))
)
else:
transfer_location_choices = (
('city', _('По городу')),
('other', _('По договоренности'))
)
cargo_type_choices = (
('passenger', _('Пассажир')),
('cargo', _('Груз')),
('parcel', _('Бандероль')),
('package', _('Посылка')),
('letter', _('Письмо\Документ'))
)
form.fields['from_place'].choices = transfer_location_choices
form.fields['to_place'].choices = transfer_location_choices
form.fields['cargo_type'].choices = cargo_type_choices
form.base_fields['from_place'].choices = transfer_location_choices
form.base_fields['to_place'].choices = transfer_location_choices
form.base_fields['cargo_type'].choices = cargo_type_choices
return form
@@ -63,10 +28,28 @@ class RouteForm(forms.ModelForm):
'from_place', 'to_place', 'receive_msg_by_sms'
]
def __init__(self, *args, **kwargs):
def __init__(self, owner_type, *args, **kwargs):
super(RouteForm, self).__init__(*args, **kwargs)
self.fields['from_city'].required = True
self.fields['to_city'].required = True
self.fields['type_transport'].required = True
data = None
if kwargs and 'data' in kwargs:
data= kwargs['data']
if owner_type == 'mover':
self.fields['departure_DT'].required = True
self.fields['type_transport'].choices = type_transport_choices[:-1]
else:
self.fields['type_transport'].choices = type_transport_choices
cargo_types = copy.deepcopy(cargo_type_choices)
if data and 'type_transport' in data and data['type_transport'] == 'avia':
cargo_types = cargo_types[:2] + cargo_types[3:]
self.fields['cargo_type'].choices = cargo_types
def clean(self):
# print('check')
@@ -74,11 +57,16 @@ class RouteForm(forms.ModelForm):
try:
if 'type_transport' in self.errors:
if self.instance and self.instance.owner_type == 'customer':
self.errors.pop('type_transport')
if 'phone' in cleaned_data and 'phone' in cleaned_data:
from BaseModels.validators.form_field_validators import get_phone_valid_error
error = get_phone_valid_error(cleaned_data["phone"])
if error:
self.add_error('phone', error)
cleaned_data['phone'] = self.data['phone']
# if 'extra_phone' in cleaned_data and 'extra_phone' in cleaned_data:
# from BaseModels.validators.form_field_validators import get_phone_valid_error

View File

@@ -1,91 +1,79 @@
from django.http import JsonResponse
from BaseModels.mailSender import techSendMail
from GeneralApp.funcs_options import get_mail_send_options
from .models import *
from .forms import *
# from .forms import *
from django.utils.translation import gettext as _
from django.template.loader import render_to_string
from datetime import datetime, timedelta
from django.db.models import F, Q
import copy
elements_on_page = 25
def get_cargo_types_by_type_transport(type_transport, form=None):
cargo_types = copy.deepcopy(cargo_type_choices)
if type_transport in ['avia']:
cargo_types = cargo_types[:2] + cargo_types[3:]
if not form:
return cargo_types
form.fields['cargo_type'].choices = cargo_types
form.base_fields['cargo_type'].choices = cargo_types
return form
def get_profile_new_route_page_html(request, data):
from .forms import RouteForm
form = RouteForm()
Dict = {
'form': form
}
if not 'owner_type' in data:
msg = 'не достаточно данных'
return JsonResponse({'error': msg}, status=400)
tpl = None
owner_type = data['owner_type']
if data['owner_type'] == 'mover':
tpl = 'v2/blocks/b_create_mover_route.html'
# form.fields['type_transport'].choices = type_transport_choices[:-1]
else:
tpl = 'v2/blocks/b_create_customer_route.html'
# form.fields['type_transport'].choices = type_transport_choices
# form = RouteForm(owner_type=owner_type)
# form.initial['owner_type'] = owner_type
#
# Dict = {
# 'form': form
# }
Dict = {}
try:
errors_off = True
# if 'from_address_point' in data:
# del data['from_address_point']
# if 'from_address_point_txt' in data:
# del data['from_address_point_txt']
#
# if 'to_address_point' in data:
# del data['to_address_point']
# if 'to_address_point_txt' in data:
# del data['to_address_point_txt']
# if data['type_transport'] == 'avia':
# transfer_location_choices = (
# ('airport', _('В аэропорту')),
# ('city', _('По городу')),
# ('other', _('По договоренности'))
# )
#
# cargo_type_choices = (
# ('cargo', _('Груз')),
# ('parcel', _('Бандероль')),
# ('package', _('Посылка')),
# ('letter', _('Письмо\Документ'))
# )
#
#
# else:
# transfer_location_choices = (
# ('city', _('По городу')),
# ('other', _('По договоренности'))
# )
#
# cargo_type_choices = (
# ('passenger', _('Пассажир')),
# ('cargo', _('Груз')),
# ('parcel', _('Бандероль')),
# ('package', _('Посылка')),
# ('letter', _('Письмо\Документ'))
# )
form = RouteForm(data)
form = RouteForm(data=data, owner_type=owner_type)
if not form.is_valid():
pass
form = RouteForm(initial=form.cleaned_data)
form = RouteForm(initial=form.cleaned_data, owner_type=owner_type)
if 'type_transport' in data:
form = routeForm_assign_choices_by_type_transport(form, data['type_transport'])
# if 'type_transport' in data:
# form = get_cargo_types_by_type_transport(data['type_transport'], form)
Dict.update({'owner_type': owner_type})
if 'owner_type' in data:
form.initial['owner_type'] = data['owner_type']
if data['owner_type'] == 'mover':
tpl = 'v2/blocks/b_make_mover_order.html'
if not 'cargo_type' in form.initial or not form.initial['cargo_type']:
if form.instance:
form.initial['cargo_type'] = form.instance.cargo_type
else:
tpl = 'v2/blocks/b_make_poster_order.html'
Dict.update({'owner_type': data['owner_type']})
form.initial['cargo_type'] = form.fields['cargo_type'].initial
if request.user and request.user.is_authenticated and request.user.user_profile and request.user.user_profile.phone:
@@ -147,7 +135,9 @@ def get_profile_my_routes_page_content_html(request):
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)
routes_Dict.update({'editable_routes': True})
html = render_to_string('v2/blocks/b_my_routes.html', routes_Dict, request=request)
return html
@@ -211,29 +201,17 @@ def get_routes_Dict(user=None, data=None):
})
if key not in (
'from_address_point_txt', 'to_address_point_txt', 'csrfmiddlewaretoken', 'sort', 'weight',
'from_el', 'to_el', 'from_address_point', 'to_address_point', 'type_transport',
'from_city', 'to_city', 'csrfmiddlewaretoken', 'sort', 'weight',
'from_el', 'to_el', 'type_transport',
'departure_DT', 'arrival_DT'
):
kwargs.update({key: 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})
if key == 'from_city':
kwargs.update({f'from_city_id': val})
res_Dict.update({
'from_address_point_txt': city.get_country_n_city_str()
})
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()
})
if key == 'to_city':
kwargs.update({f'to_city_id': val})
if key == 'from_el':
from_el = int(val)
@@ -267,7 +245,8 @@ def get_routes_Dict(user=None, data=None):
).order_by(
F('rising_DT').desc(nulls_last=True),
# '-rising_DT',
'-departure_DT', '-arrival_DT', '-modifiedDT'
'-arrival_DT', '-modifiedDT'
# '-departure_DT',
)
routes_count = routes.count()
@@ -319,7 +298,8 @@ def get_routes_Dict(user=None, data=None):
'routes': routes,
'last_block': last_block,
'last_el': to_el,
'next_page_els_count': next_page_els_count
'next_page_els_count': next_page_els_count,
'now_DT': datetime.now(),
})
return res_Dict

View File

@@ -7,8 +7,17 @@ from .js_views import *
# /routes/
urlpatterns = [
path('change_route/<int:route_id>/', create_or_change_route_ajax, name='change_route_ajax'),
path('create_or_change_route/', create_or_change_route_ajax, name='create_or_change_route_ajax'),
path(
'change_route/<int:route_id>/',
create_or_change_route_ajax, name='change_route_ajax'),
path(
'create_or_change_route/',
create_or_change_route_ajax, name='create_or_change_route_ajax'),
path(
'get_cargo_type_by_transport_type/',
get_cargo_type_by_transport_type_ajax,
name='get_cargo_type_by_transport_type_ajax'),
path('edit_route/', edit_route_ajax, name='edit_route_ajax'),
path('del_route/', del_route_ajax, name='del_route_ajax'),

View File

@@ -1,3 +1,4 @@
import copy
import json
from copy import deepcopy
@@ -5,6 +6,9 @@ from django.conf import settings
from django.shortcuts import render
from uuid import uuid1
from twisted.web.http import stringToDatetime
from .models import *
from django.contrib import auth
from django.http import HttpResponse, Http404, JsonResponse
@@ -17,31 +21,30 @@ from django.template.loader import render_to_string
from django.urls import reverse
from .forms import *
from .funcs import *
from GeneralApp.funcs import get_and_set_lang
from GeneralApp.funcs import get_and_set_lang, check_post_request_and_get_data
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
def highlight_route_ajax(request):
if request.method != 'POST':
raise Http404
data = request.POST
if not data and request.body:
data = json.loads(request.body)
data = check_post_request_and_get_data(request)
if data == None:
return Http404
elif type(data) == str:
return JsonResponse({'error': data}, status=400)
if not data or not 'route_id' in data:
msg = _('Недостаточно данных')
return JsonResponse({'errors': msg})
return JsonResponse({'errors': msg}, status=400)
try:
route = Route.objects.get(owner=request.user, id=data['route_id'])
except Route.DoesNotExist:
msg = _('Не найден маршрут')
return JsonResponse({'errors': msg})
return JsonResponse({'errors': msg}, status=400)
if not route.get_permission_for_highlight():
msg = _('Нет доступа к выделению')
return JsonResponse({'errors': msg})
return JsonResponse({'errors': msg}, status=403)
from SubscribesApp.funcs import get_cur_user_subscribe
@@ -74,26 +77,25 @@ def highlight_route_ajax(request):
def raise_route_ajax(request):
if request.method != 'POST':
raise Http404
data = request.POST
if not data and request.body:
data = json.loads(request.body)
data = check_post_request_and_get_data(request)
if data == None:
return Http404
elif type(data) == str:
return JsonResponse({'error': data}, status=400)
if not data or not 'route_id' in data:
msg = _('Недостаточно данных')
return JsonResponse({'errors': msg})
return JsonResponse({'errors': msg}, status=400)
try:
route = Route.objects.get(owner=request.user, id=data['route_id'])
except Route.DoesNotExist:
msg = _('Не найден маршрут')
return JsonResponse({'errors': msg})
return JsonResponse({'errors': msg}, status=400)
if not route.get_permission_for_raise():
msg = _('Нет доступных поднятий')
return JsonResponse({'errors': msg})
return JsonResponse({'errors': msg}, status=403)
route.rising_DT = datetime.now()
route.save(update_fields=['rising_DT'])
@@ -112,8 +114,11 @@ def raise_route_ajax(request):
def del_route_ajax(request):
if request.method != 'POST':
raise Http404
data = check_post_request_and_get_data(request)
if data == None:
return Http404
elif type(data) == str:
return JsonResponse({'error': data}, status=400)
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
return JsonResponse({'html': 'нет доступа'}, status=403)
@@ -122,7 +127,7 @@ def del_route_ajax(request):
try:
data = json.loads(request.body)
# data = json.loads(request.body)
if not 'route_id' in data:
msg = f'Недостаточно данных'
return JsonResponse({'errors': msg})
@@ -133,7 +138,7 @@ def del_route_ajax(request):
if 'errors' in routes_Dict:
return JsonResponse(routes_Dict, status=400)
html = render_to_string('blocks/profile/b_my_routes.html', routes_Dict, request=request)
html = render_to_string('v2/blocks/b_my_routes.html', routes_Dict, request=request)
res_Dict = {
'html': html
@@ -152,15 +157,18 @@ def del_route_ajax(request):
def edit_route_ajax(request):
if request.method != 'POST':
raise Http404
data = check_post_request_and_get_data(request)
if data == None:
return Http404
elif type(data) == str:
return JsonResponse({'error': data}, status=400)
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
return JsonResponse({'html': 'нет доступа'}, status=403)
lang = get_and_set_lang(request)
data = json.loads(request.body)
# data = json.loads(request.body)
Dict = {}
@@ -172,14 +180,15 @@ def edit_route_ajax(request):
route = Route.objects.get(id=data['route_id'])
form = RouteForm(instance=route)
form = routeForm_assign_choices_by_type_transport(form, route.type_transport)
form = RouteForm(instance=route, owner_type=route.owner_type)
form = get_cargo_types_by_type_transport(route.type_transport, form)
# routeForm_assign_choices_by_type_transport(form, route.type_transport)
route_address_points_Dict = route.get_address_points()
form.initial.update({
'from_address_point_txt': route_address_points_Dict['from_address_point_txt'],
'to_address_point_txt': route_address_points_Dict['to_address_point_txt'],
})
# route_address_points_Dict = route.get_address_points()
# form.initial.update({
# 'from_address_point_txt': route_address_points_Dict['from_address_point_txt'],
# 'to_address_point_txt': route_address_points_Dict['to_address_point_txt'],
# })
Dict = {
@@ -193,7 +202,9 @@ def edit_route_ajax(request):
print(msg)
return JsonResponse({'errors': msg})
html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
tpl_name = f'v2/blocks/b_create_{ route.owner_type }_route.html'
html = render_to_string(tpl_name, Dict, request=request)
res_Dict = {
'html': html,
'btn_title': _('Сохранить изменения')
@@ -268,7 +279,7 @@ def find_routes_ajax(request):
if routes_Dict['routes']:
html = render_to_string('blocks/b_search_routes.html', routes_Dict, request=request)
html = render_to_string('v2/blocks/b_search_routes_result.html', routes_Dict, request=request)
else:
html = render_to_string('templates_js_translate/not_found_find_routes.html', routes_Dict, request=request)
@@ -323,8 +334,9 @@ def get_my_routes_ajax(request):
if user_subscribe:
routes_Dict.update(user_subscribe.remains_route_adding_options())
routes_Dict.update({'editable_routes': True})
html = render_to_string('blocks/profile/b_my_routes.html', routes_Dict, request=request)
html = render_to_string('v2/blocks/b_my_routes.html', routes_Dict, request=request)
res_Dict = {
'html': html
@@ -344,6 +356,26 @@ def get_my_routes_ajax(request):
return JsonResponse(errors_Dict, status=400)
def get_cargo_type_by_transport_type_ajax(request):
if request.method != 'POST':
raise Http404
try:
data = request.POST
if not data:
data = json.loads(request.body)
if not data or not 'type_transport' in data:
return JsonResponse({'html': 'недостаточно данных'}, status=400)
cargo_types = get_cargo_types_by_type_transport(data['type_transport'])
return JsonResponse({'cargo_types': cargo_types})
except Exception as e:
msg = f'get_cargo_type_by_transport_type_ajax Exception = {str(e)}'
return JsonResponse({'error': msg}, status=400)
def create_or_change_route_ajax(request, route_id=None):
@@ -359,8 +391,8 @@ def create_or_change_route_ajax(request, route_id=None):
route_old_Dict = None
owner_type = None
tpl_form_by_owner_type = 'v2/forms/f_make_poster_order.html'
tpl_block_by_owner_type = 'v2/blocks/b_make_poster_order.html'
tpl_form_by_owner_type = 'v2/forms/f_create_customer_route.html'
tpl_block_by_owner_type = 'v2/blocks/b_create_customer_route.html'
try:
@@ -373,19 +405,23 @@ def create_or_change_route_ajax(request, route_id=None):
owner_type = data['owner_type']
if owner_type == 'mover':
tpl_form_by_owner_type = 'v2/forms/f_make_mover_order.html'
tpl_block_by_owner_type = 'v2/blocks/b_make_mover_order.html'
tpl_form_by_owner_type = 'v2/forms/f_create_mover_route.html'
tpl_block_by_owner_type = 'v2/blocks/b_create_mover_route.html'
if 'route_id' in data and data['route_id']:
route_id = data['route_id']
# del data['route_id']
route = None
if route_id:
route = Route.objects.get(id=route_id)
if route:
form = RouteForm(data, instance=route)
form = RouteForm(data=data, instance=route, owner_type=owner_type)
Dict.update({'route': route})
route_old_Dict = deepcopy(route.__dict__)
else:
form = RouteForm(data)
form = RouteForm(data=data, owner_type=owner_type)
if not form.is_valid():
form.initial = form.cleaned_data
@@ -435,7 +471,7 @@ def create_or_change_route_ajax(request, route_id=None):
html = render_to_string(tpl_form_by_owner_type, Dict, request=request)
return JsonResponse({'html': html}, status=400)
html = render_to_string('blocks/profile/b_my_routes.html', routes_Dict, request=request)
html = render_to_string('v2/blocks/b_my_routes.html', routes_Dict, request=request)
res_Dict = {
'html': html,

View File

@@ -0,0 +1,23 @@
# Generated by Django 4.2.2 on 2025-01-14 18:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RoutesApp', '0011_alter_route_from_address_point_and_more'),
]
operations = [
migrations.AlterField(
model_name='route',
name='cargo_type',
field=models.CharField(choices=[('package', 'Посылка (до 30кг)'), ('letter', 'Письмо\\Документы'), ('passenger', 'Попутчик'), ('parcel', 'Бандероль (до 5кг)'), ('cargo', 'Груз (свыше 30 кг)')], default='parcel', verbose_name='Могу перевезти'),
),
migrations.AlterField(
model_name='route',
name='type_transport',
field=models.CharField(blank=True, choices=[('road', 'Авто (любой наземный транспорт)'), ('avia', 'Авиа'), ('', 'Мне без разницы')], default='', verbose_name='Выберите способ перевозки'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2025-01-14 18:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RoutesApp', '0012_alter_route_cargo_type_alter_route_type_transport'),
]
operations = [
migrations.AlterField(
model_name='route',
name='cargo_type',
field=models.CharField(choices=[('letter', 'Письмо\\Документы'), ('package', 'Посылка (до 30кг)'), ('passenger', 'Попутчик'), ('parcel', 'Бандероль (до 5кг)'), ('cargo', 'Груз (свыше 30 кг)')], default='parcel', verbose_name='Могу перевезти'),
),
]

View File

@@ -2,12 +2,13 @@ from django.db import models
from django.utils.translation import gettext_lazy as _
from BaseModels.base_models import BaseModel
from colorfield.fields import ColorField
from datetime import datetime
type_transport_choices = [
('road', _('Авто (любой наземный транспорт)')),
('avia', _('Авиа')),
('', _('Мне без разницы')),
('avia', _('Авиатранспорт')),
('road', _('Наземный транспорт'))
]
transfer_location_choices = (
@@ -17,11 +18,11 @@ transfer_location_choices = (
)
cargo_type_choices = (
('passenger', _('Пассажир')),
('cargo', _('Груз (свыше 30 кг)')),
('parcel', _('Бандероль (до 5кг)')),
('letter', _('Письмо\Документы')),
('package', _('Посылка (до 30кг)')),
('letter', _('Письмо\Документы'))
('passenger', _('Попутчик')),
('parcel', _('Бандероль (до 5кг)')),
('cargo', _('Груз (свыше 30 кг)')),
)
owner_type_choices = (
@@ -75,7 +76,9 @@ class Route(BaseModel):
verbose_name=_('Куда можете доставить?'),
null=True, blank=True
)
cargo_type = models.CharField(choices=cargo_type_choices, default='parcel', verbose_name=_('Могу перевезти'))
cargo_type = models.CharField(
choices=cargo_type_choices, default='letter', verbose_name=_('Могу перевезти')
)
# не используем с v2
weight = models.IntegerField(verbose_name=_('Укажите вес до (кг)'), null=True, blank=True)
phone = models.CharField(verbose_name=_('Укажите номер для связи'), blank=True, null=True)
@@ -116,6 +119,13 @@ class Route(BaseModel):
verbose_name_plural = _(u'Маршруты')
ordering = ('name',)
def is_highlighted_now(self):
if self.highlight_end_DT and datetime.now() < self.highlight_end_DT:
return True
return False
def get_permission_for_raise(self):
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(self.owner)

View File

@@ -3,10 +3,38 @@ __author__ = 'SDE'
from django import template
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
register = template.Library()
cargo_type_for_show = {
'letter': _('Документы'),
'package': _('Посылка'),
'passenger': _('Попутчик'),
'parcel': _('Бандероль'),
'cargo': _('Груз'),
}
type_transport_for_show = {
'road': _('Автоперевозка'),
'avia': _('Авиатранспорт'),
'': _('Авто/Авиаперевозка'),
}
@register.filter
@stringfilter
def get_type_transport_for_show(value):
return mark_safe(type_transport_for_show[value])
@register.filter
@stringfilter
def get_cargo_type_for_show(value):
return mark_safe(cargo_type_for_show[value])
@register.filter
@stringfilter
def get_splited_cargo_type(value):
@@ -14,8 +42,10 @@ def get_splited_cargo_type(value):
return value
splited_list = value.split('(')
splited_list[1] = splited_list[1].replace(')', '')
s = splited_list[0] + '<span>(' + splited_list[1] + ')</span>'
s = f'<div>{splited_list[0]}</div><div class="annotation">({splited_list[1]})</div>'
return mark_safe(s)

View File

@@ -1,6 +1,8 @@
from django.shortcuts import render
from uuid import uuid1
from ReferenceDataApp.funcs import get_city_by_id
from .models import *
from django.contrib import auth
from django.http import HttpResponse, Http404
@@ -26,28 +28,36 @@ def route_search_results_View(request):
if request.GET:
data = request.GET.dict()
owner_type = data['owner_type']
routes_Dict = get_routes_Dict(data=data)
if routes_Dict:
Dict = {
'routes': routes_Dict['routes'],
'last_block': routes_Dict['last_block'],
'show_filter_and_results': True,
'owner_type': data['owner_type'],
'owner_type': owner_type,
'last_el': routes_Dict['last_el'],
'page_type': 'routes',
'next_page_els_count': routes_Dict['next_page_els_count'],
}
if 'from_address_point_txt' in routes_Dict:
data.update({'from_address_point_txt': routes_Dict['from_address_point_txt']})
if 'to_address_point_txt' in routes_Dict:
data.update({'to_address_point_txt': routes_Dict['to_address_point_txt']})
Dict.update({'route_form': RouteForm(initial=data)})
from_city = None
to_city = None
if 'from_city' in data and data['from_city']:
from_city = get_city_by_id(data['from_city'])
data.update({'from_city': from_city})
if 'to_city' in data and data['to_city']:
to_city = get_city_by_id(data['to_city'])
data.update({'to_city': to_city})
Dict.update({'form': RouteForm(initial=data, owner_type=owner_type)})
title = _('Результат поиска маршрутов')
if 'from_address_point_txt' in data:
title = f'{title} из {data["from_address_point_txt"]}'
if 'to_address_point_txt' in data:
title = f'{title} в {data["to_address_point_txt"]}'
if from_city:
title = f'{title} из {from_city.name}'
if to_city:
title = f'{title} в {to_city.name}'
Dict.update({
'page': {
@@ -57,7 +67,7 @@ def route_search_results_View(request):
}
})
t = loader.get_template('pages/p_results_find_route.html')
t = loader.get_template('v2/pages/p_search_route_results.html')
return get_inter_http_response(t, Dict, request)
except Exception as e:

View File

@@ -77,7 +77,8 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
'last_paid_DT',
'paid_period_from_DT', 'paid_period_to_DT',
'auto_continue', 'receive_finish_subscribe_msg',
'order'
'order',
'used_route_rising_count', 'used_route_highlight_count',
)
}),
)
@@ -94,6 +95,7 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
list_display_links = ['id']
list_filter = [
'enable',
'subscribe', 'last_paid_DT', 'paid_period_from_DT', 'paid_period_to_DT',
'auto_continue', 'receive_finish_subscribe_msg',
'modifiedDT', 'createDT'

View File

@@ -154,7 +154,7 @@ html, body{
.wrapper_content {
margin: 20px;
max-width: 1720px;
position: relative;
/*position: relative;*/
min-height: 695px;
max-height: 100%;
}
@@ -239,7 +239,7 @@ body {
}
header {
margin-top: 20px;
/*margin-top: 20px;*/
padding: 5px 20px;
position: sticky;
top: 0;

View File

@@ -25,9 +25,10 @@ const initialiseState = (reg) => {
}
const showNotAllowed = (message) => {
const button = document.querySelector('form>button');
button.innerHTML = `${message}`;
button.setAttribute('disabled', 'true');
// const button = document.querySelector('form>button');
// button.innerHTML = `${message}`;
// button.setAttribute('disabled', 'true');
console.log(message);
};

View File

@@ -61,7 +61,7 @@ function select_tab_profile (el,url,owner_type=null, check_orders_required) {
document.querySelector("#ru_lang").href = confirm_url_f_lang_ru
document.querySelector("#en_lang").href = confirm_url_f_lang_en
daterangepickerInit($('.w_daterangepicker'), daterangepickerInit)
datarangepickerinitAll()
// let header = document.querySelector("header")
// header.scrollIntoView({
// behavior: "smooth",

View File

@@ -0,0 +1,28 @@
.b_chat_modal {
--modal-width: 35%;
--modal-height: calc(100dvh - 100px);
--modal-padding: 0;
.chat_header{
height: 104px;
padding: 10px 20px 26px 20px;
}
.close_chat_container{
display: flex;
justify-content: right;
.close_btn{
--filter: brightness(0) saturate(100%) invert(99%) sepia(12%) saturate(182%) hue-rotate(183deg) brightness(115%) contrast(100%);;
padding: 8.94px;
width: 28px;
height: 28px;
background: #FF613A;
border-radius: 100%;
box-sizing: border-box;
img{
width: 10.12px;
height: 10.12px;
display: block;
filter: var(--filter);
}
}
}
}

View File

@@ -0,0 +1,108 @@
.b_dont_found_anth{
padding: 9px 60px;
background: #fff;
border-radius: 10px;
position: relative;
min-height: 254px;
margin-top: 120px;
.first_imgs_line, .second_imgs_line {
display: flex;
align-items: center;
justify-content: space-between;
position: absolute;
&.first_imgs_line{
top: 9px;
left: 190px;
width: calc(100% - 380px);
}
&.second_imgs_line{
top: 117px;
left: 60px;
width: calc(100% - 120px);
}
}
.container_content{
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
min-height: 254px;
width: 100%;
}
.title{
font-size: 44px;
font-weight: 700;
margin: 0;
}
.description{
font-size: 16px;
font-weight: 400;
margin: 20px 0;
}
@media (max-width: 1440px) {
padding: 9px 25px;
.first_imgs_line, .second_imgs_line {
&.first_imgs_line{
top: 9px;
left: 140px;
width: calc(100% - 280px);
}
&.second_imgs_line{
top: 117px;
left: 25px;
width: calc(100% - 50px);
}
}
}
@media (max-width: 1200px) {
padding: 9px 25px;
.first_imgs_line, .second_imgs_line {
&.first_imgs_line{
display: none;
}
&.second_imgs_line{
min-height: 254px;
top: 0;
img{
width: 165px;
}
}
}
}
@media (max-width: 1024px) {
padding: 9px 11px;
.first_imgs_line, .second_imgs_line {
&.second_imgs_line{
min-height: 254px;
top: 0;
left: 11px;
width: calc(100% - 22px);
img{
width: 140px;
}
}
}
}
@media (max-width: 950px) {
.title{
font-size: 32px;
}
.first_imgs_line, .second_imgs_line {
&.second_imgs_line{
img{
width: 100px;
}
}
}
}
@media (max-width: 879px) {
.first_imgs_line, .second_imgs_line {
&.second_imgs_line{
display: none;
img{
width: 100px;
}
}
}
}
}

View File

@@ -0,0 +1,127 @@
.b_filter_routes{
--form-title-font-size: 24px;
border-radius: 10px;
height: fit-content;
box-sizing: border-box;
z-index: 1000;
.overlay{
--bg: #F8F8F8CC;
--backdrop-filter: blur(2px);
}
.b_filter_routes_content{
box-sizing: border-box;
border-radius: 10px;
padding: 20px;
background: #FFFFFF;
}
.title{
font-size: var(--form-title-font-size);
font-weight: 700;
margin-bottom: 20px;
margin-top: 0;
}
form{
.field_container{
margin: 0 0 10px 0;
}
}
@media (max-width: 800px) {
--modal-width: calc(100% - 32px);
position: fixed;
top: 0;
left: 0;
.b_filter_routes_content{
width: var(--modal-width);
position: fixed;
top: 169px;
z-index: 100000000;
left: calc(50dvw - (var(--modal-width) / 2));
}
}
}
.b_filter_routes_modal_handler{
--bg: #FF613A;
--border-radius: 0 10px 10px 0;
--left: 0;
--top: calc(50% - 63.5px);
--width: 25px;
--height: 127px;
--color: #fff;
background: var(--bg);
border-radius: var(--border-radius);
display: none;
position: fixed;
left: var(--left);
top: var(--top);
width: var(--width);
height: var(--height);
.b_filter_routes_modal_handler_content{
position: relative;
height: 127px;
rotate: 0deg;
top: 0;
left: 0;
}
img{
--filter: brightness(0) saturate(100%) invert(100%) sepia(0%) saturate(7500%) hue-rotate(74deg) brightness(122%) contrast(112%);
--rotate: 0;
filter: var(--filter);
rotate: var(--rotate);
width: 7px;
display: block;
position: absolute;
left: 8px;
&:first-of-type{
top: 19px;
}
&:last-of-type{
top: 94px;
}
}
div{
--rotate: 270deg;
--top: 56px;
--left: -9px;
color: var(--color);
font-size: 12px;
position: absolute;
rotate: var(--rotate);
top: var(--top);
left: var(--left);
}
z-index: 10000000000000;
&.active{
--bg: #E6E6E6;
--color: #27242499;
--border-radius: 10px 0 0 10px;
--left: calc(100% - var(--width));
div{
--rotate: 90deg;
}
img{
--rotate: 180deg;
--filter: brightness(0) saturate(100%) invert(16%) sepia(6%) saturate(406%) hue-rotate(2deg) brightness(96%) contrast(82%);
}
}
@media (max-width: 800px) {
display: block;
}
}

View File

@@ -0,0 +1,141 @@
.b_login_modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
--modal-width: 690px;
--modal-height: 492px;
--modal-padding: 28px 28.7px;
--modal-inf-padding: 8px 24px 0 24px;
box-sizing: border-box;
z-index: 10000000;
@media (max-width: 725px) {
--modal-width: calc(100% - 20px);
--modal-padding: 15px 15px 20px 10px;
.modal_description{
width: 100%!important;
}
} @media (max-height: 512px) {
.modal_description{
width: 100%;
}
--modal-height: calc(100% - 20px);
}
@media (max-width: 500px) {
.modal_title{
font-size: 26px!important;
}
.modal_description{
font-size: 18px!important;
}
}
@media (max-width: 360px) {
.modal_title{
font-size: 24px!important;
}
.modal_description{
font-size: 16px!important;
}
.primary_btn{
--padding: 7.5px 0;
--font-size: 14px;
--font-weight: 400;
}
.registr_btn{
font-size: 14px!important;
font-weight: 400!important;
}
}
.b_login_modal_container_content{
position: fixed;
background: #FFFFFF;
box-shadow: 0 3px 14px rgba(74, 58, 255, 0.03), 0 -2px 4px rgba(20, 20, 43, 0.12), 0 12px 44px rgba(20, 20, 43, 0.34);
border-radius: 30px;
width: var(--modal-width);
height: var(--modal-height);
padding: var(--modal-padding);
left: calc(50% - (var(--modal-width) / 2));
top: calc(50% - (var(--modal-height) / 2));
z-index: 1000000000;
box-sizing: border-box;
}
.b_login_modal_content{
position: relative;
text-align: -webkit-center;
}
.xmark{
position: absolute;
top: 0;
right: 0;
width: 16px;
height: 16px;
display: block;
cursor: pointer;
}
.lock_img_container{
position: relative;
background: #E1E1E1;
border-radius: 39px;
width: 140px;
height: 140px;
img{
width: 130px;
height: 130px;
position: absolute;
top: 5px;
left: 5px;
}
}
.modal_title{
margin-top: 40px;
font-size: 34px;
font-weight: 700;
color: #272424;
}
.modal_description{
margin: 20px 0;
font-size: 20px;
font-weight: 400;
color: #272424;
width: 495px;
overflow-wrap: break-word;
}
.registr_btn{
margin-top: 10px;
font-size: 18px;
font-weight: 600;
color: #27242499;
text-decoration: none;
display: block;
}
.b_login_modal_inf{
padding: var(--modal-inf-padding);
.primary_btn{
--width: 360px;
@media (max-width: 460px) {
--width: 100%;
}
}
}
}

View File

@@ -0,0 +1,99 @@
.b_search_routes {
--button-font-size: 18px;
padding: 16px 10px;
background: #FFF;
border-radius: 10px;
form{
display: grid;
/* +5px in grid for padding */
grid-template-columns: repeat(3, calc(33.3% - 77px)) 215px;
align-items: end;
gap: 5px;
[data-type="location"] {
&:first-of-type{
.w_select_country_header{
--select-border-radius: 10px 0 0 10px;
&.closed{
--select-border-radius: 10px 0 0 10px;
}
}
}
.w_select_country_header{
--select-border-radius: 0;
&.closed{
--select-border-radius: 0;
}
}
}
.w_daterangepicker{
--range-picker-border-radius: 0 10px 10px 0;
}
.field_container{
--label-font-size: 14px;
--label-font-weight: 400;
--label-color: #27242499;
}
@media (max-width: 800px) {
grid-template-columns: repeat(2, 1fr);
[data-type="date"], button {
grid-column: span 2;
height: fit-content;
}
.w_daterangepicker{
--range-picker-border-radius: 0 0 10px 10px;
}
[data-type="location"][data-name="to_city"] {
.w_select_country_header{
--select-border-radius: 0 10px 0 0;
&.closed{
--select-border-radius: 0 10px 0 0;
}
}
}
[data-type="location"][data-name="from_city"] {
.w_select_country_header{
--select-border-radius: 10px 0 0 0;
&.closed{
--select-border-radius: 10px 0 0 0;
}
}
}
}
@media (max-width: 576px) {
grid-template-columns: 1fr;
[data-type="date"], button {
grid-column: unset;
height: fit-content;
}
.w_daterangepicker{
--range-picker-border-radius: 0 0 10px 10px;
}
[data-type="location"][data-name="to_city"] {
.w_select_country_header{
--select-border-radius: 0 0 0 0;
&.closed{
--select-border-radius: 0 10px 0 0;
}
}
}
[data-type="location"][data-name="from_city"] {
.w_select_country_header{
--select-border-radius: 10px 10px 0 0;
&.closed{
--select-border-radius: 10px 10px 0 0;
}
}
}
}
}
button{
padding: 17px 0;
background: #FF613A;
font-size: var(--button-font-size);
font-weight: 600;
margin: 0;
height: calc(100% - 27px);
}
}

View File

@@ -24,7 +24,7 @@
--error-color: #FF0000;
box-sizing: border-box;
&.line{
display: flex;
align-items: center;
@@ -35,9 +35,11 @@
display: block;
color: var(--label-color);
font-weight: var(--label-font-weight);
font-size: var(--label-font-size);
&:has(div){
display: flex;
align-items: center;
gap: 5px;
}
.required_field_icon{
color: var(--label-required-color);
@@ -52,6 +54,7 @@
font-family: var(--main-font-family), serif;
box-sizing: border-box;
outline: none;
min-width: 0;
&.dropped{
border: none;
outline: none;
@@ -109,44 +112,85 @@
font-size: var(--error-font-size);
color: var(--error-color);
}
}
.form_line{
--display: flex;
&._50_grid {
--display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 40px;
select{
--select-padding: 14px 10px;
--select-bg: #FFFFFF;
--select-border: #E6E6E6;
--select-font-size: 14px;
--select-border-radius: 10px;
--select-width: 100%;
width: var(--select-width);
padding: var(--select-padding);
background: var(--select-bg);
border: 1px solid var(--select-border);
border-radius: var(--select-border-radius);
font-size: var(--select-font-size);
outline: none;
appearance: none;
background: white url(/static/img/png/icon-arrow.svg) no-repeat calc(100% - 15px) center;
}
display: var(--display);
justify-content: space-between;
}
button[type="submit"]{
--submit-button-bg: #FF613A;
--submit-button-box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.12);
form {
--submit-button-border: none;
--submit-button-border-radius: 10px;
--submit-button-font-size: 18px;
--submit-button-color: #FFFFFF;
--submit-button-font-weight: 600;
.form_line{
--display: flex;
&._50_grid {
--display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 40px;
}
display: var(--display);
justify-content: space-between;
}
--submit-button-width: 100%; /* initial */
--submit-button-padding: 17px;
button[type="submit"]{
--submit-button-bg: #FF613A;
--submit-button-box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.12);
outline: none;
--submit-button-border: none;
--submit-button-border-radius: 10px;
--submit-button-font-size: 18px;
--submit-button-color: #FFFFFF;
--submit-button-font-weight: 600;
background: var(--submit-button-bg);
box-shadow: var(--submit-button-box-shadow);
--submit-button-width: 100%; /* initial */
--submit-button-padding: 17px;
width: var(--submit-button-width);
padding: var(--submit-button-padding);
outline: none;
border: var(--submit-button-border);
border-radius: var(--submit-button-border-radius);
background: var(--submit-button-bg);
box-shadow: var(--submit-button-box-shadow);
color: var(--submit-button-color);
font-size: var(--submit-button-font-size);
font-weight: var(--submit-button-font-weight);
width: var(--submit-button-width);
padding: var(--submit-button-padding);
border: var(--submit-button-border);
border-radius: var(--submit-button-border-radius);
color: var(--submit-button-color);
font-size: var(--submit-button-font-size);
font-weight: var(--submit-button-font-weight);
}
--label-color: #000;
--label-required-color: #FF613A;
--label-font-size: 16px;
--label-font-weight: 500;
.label{
display: block;
color: var(--label-color);
font-weight: var(--label-font-weight);
&:has(div){
display: flex;
align-items: center;
gap: 5px;
}
.required_field_icon{
color: var(--label-required-color);
}
}
}

View File

@@ -15,11 +15,11 @@
}
@media (max-width: 992px) {
.w_radio_inputs{
grid-template-columns: repeat(2, 1fr);
grid-template-columns: repeat(2, max-content);
}
} @media (max-width: 768px) {
.w_radio_inputs{
grid-template-columns: repeat(1, 1fr);
grid-template-columns: repeat(1, max-content);
}
}
}

View File

@@ -0,0 +1,38 @@
.title{
font-size: 44px;
font-weight: 700;
margin-bottom: 80px;
margin-top: 60px;
width: 100%;
text-align: center;
}
.routes_content_part{
margin-top: 50px;
display: grid;
grid-template-columns: 30% calc(100% - 30% - 41px);
gap: 41px;
.routes_search_results{
.next_page{
margin: 50px 0;
width: 100%;
background: #212121;
height: 1px;
}
}
@media (max-width: 1440px) {
margin-top: 40px;
}
@media (max-width: 800px) {
grid-template-columns: 100%;
}
@media (max-width: 768px) {
margin-top: 40px;
}
@media (max-width: 576px) {
margin-top: 77px;
}
@media (max-width: 360px) {
margin-top: 40px;
}
}

View File

@@ -0,0 +1,79 @@
.primary_btn{
--background: #FF613A;
--border: none;
--box-shadow: 0px 3px 12px rgba(74, 58, 255, 0.18);
--border-radius: 10px;
--margin: 0;
--padding: 19px 0 21px 0;
--font-size: 18px;
--font-weight: 700;
--color: #FFFFFF;
--text-align: center;
--text-decoration: none;
--width: unset;
--display: block;
background: var(--background);
border: var(--border);
box-shadow: var(--box-shadow);
border-radius: var(--border-radius);
margin: var(--margin);
padding: var(--padding);
font-size: var(--font-size);
font-weight: var(--font-weight);
color: var(--color)!important;
text-align: var(--text-align);
text-decoration: var(--text-decoration);
width: var(--width)!important;
display: var(--display);
cursor: pointer;
}
.default_btn{
--background: #FFFFFF;
--border: none;
--box-shadow: none;
--border-radius: 8px;
--margin: 0;
--padding: 7px 0;
--font-size: 12px;
--font-weight: 500;
--color: #27242499;
--text-align: center;
--text-decoration: none;
--width: 85px;
--display: block;
background: var(--background);
border: var(--border);
box-shadow: var(--box-shadow);
border-radius: var(--border-radius);
margin: var(--margin);
padding: var(--padding);
font-size: var(--font-size);
font-weight: var(--font-weight);
color: var(--color)!important;
text-align: var(--text-align);
text-decoration: var(--text-decoration);
width: var(--width)!important;
display: var(--display);
cursor: pointer;
}
.container_btns{
width: 100%;
display: flex;
align-items: center;
justify-content: var(--justify);
gap: 5px;
}

View File

@@ -0,0 +1,38 @@
.modal {
display: none;
--modal-bg: #fff;
--modal-ba: 30px;
&.open{
display: block;
}
.overlay{
--bg: #0000009C;
--backdrop-filter: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--bg);
backdrop-filter: var(--backdrop-filter);
z-index: 10000000;
}
.modal_body{
position: fixed;
background: var(--modal-bg);
box-shadow: 0 3px 14px rgba(74, 58, 255, 0.03), 0 -2px 4px rgba(20, 20, 43, 0.12), 0 12px 44px rgba(20, 20, 43, 0.34);
border-radius: var(--modal-ba);
width: var(--modal-width);
height: var(--modal-height);
padding: var(--modal-padding);
left: calc(50% - (var(--modal-width) / 2));
top: calc(50% - (var(--modal-height) / 2));
z-index: 1000000000;
box-sizing: border-box;
}
}

View File

@@ -7,7 +7,7 @@
gap: 10px;
border: 2px solid var(--range-picker-border);
border-radius: var(--range-picker-border-radius);
padding: 24px 10px;
padding: 18px 10px;
background: #FFFFFF;
input{
width: calc(100% - 28px);

View File

@@ -1,11 +1,12 @@
.w_radio_inputs{
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(3, max-content);
gap: 20px 40px;
margin-top: 20px;
--radio-font-size: 16px;
.cw_w_radio_inputs_radio_input{
display: flex;
display: grid;
grid-template-columns: 30px auto;
align-items: center;
gap: 10px;
.radio{
@@ -24,6 +25,14 @@
}
.radio_label{
font-size: var(--radio-font-size);
&:has(div.annotation){
display: flex;
align-items: center;
gap: 5px;
}
div.annotation{
color: #27242499;
}
}
}
}

View File

@@ -0,0 +1,700 @@
.w_route_card {
padding: 20px;
--route-date_splitter-bg: #F1F1F1;
--route-date_splitter-width: 134px;
--route-date_splitter-height: 1.5px;
--route-date_splitter-margin: 5px 0;
--route-card-bg: #FFFFFF;
--route-card-margin: 20px 0;
--route-card-box_shadow: 0 -1px 10px rgba(198, 199, 203, 0.2), -1px 4px 10px rgba(198, 199, 203, 0.2);
--route-text-color: #272424;
--big-font-size: 16px;
--medium-font-size: 14px;
--small-font-size: 10px;
--route-text-container-bg: #F1F1F1;
--route-text-container-padding: 15px;
--route-text-container-margin: 0 0 0 51px;
--route-text-container-border-radius: 10px;
--route-text-img-filter: brightness(0) saturate(100%) invert(100%) sepia(2%) saturate(256%) hue-rotate(113deg) brightness(115%) contrast(89%);
--route-card-owner-avatar-size: 52px;
--route-owner-type-color: #065BFF;
--route-cargo-type-color: #272424;
--route_card_route_data-margin-top: 30px;
--route-btn-border: 1.5px solid #FF613A;
--route-btn-border-radius: 10px;
--route-btn-padding: 7.5px 0;
--route-btn-width: 171px;
--route-btn-height: 100%;
--route-btn-bg: #FFFFFF;
--route-btn-hover-bg: #FF613A;
--route-btn-hover-text-color: #FFFFFF;
--route-btn-title-color: #272424;
--route-btn-text-data-color: #27242499;
--route-btn-margin: 0;
--route-date-data-justify: center;
--route-date-data-margin: 4px 0 0 0;
--card-splitter-bg: #E6E6E6;
--route-number-font-size: 12px;
--route-number-margin-top: 5px;
--from-to-place-data-width: 205px;
@media (max-width: 1160px) {
--from-to-place-data-width: 100%;
}
background: var(--route-card-bg);
margin: var(--route-card-margin);
box-shadow: var(--route-card-box_shadow);
border-radius: 10px;
color: var(--route-text-color);
&.highlighted{
--route-card-bg: linear-gradient(90deg, #FBED96 0%, #ABECD6 100%), #FFFFFF;
--card-splitter-bg: #FFF;
--route-text-container-bg: #FFFFFF;
--route-text-img-filter: unset;
}
&.disabled{
--route-card-bg: #FFFFFF;
--card-splitter-bg: #E6E6E6;
--route-text-container-bg: #F1F1F1;
--route-text-img-filter: brightness(0) saturate(100%) invert(100%) sepia(2%) saturate(256%) hue-rotate(113deg) brightness(115%) contrast(89%);
.route_card_info_data{
.route_card_text_container{
color: #A9A9A9!important;
}
}
.card_owner_type.mover, .card_owner_type.customer{
--route-owner-type-color: #A9A9A9!important;
}
.route_btn.inactive, .route_btn, .route_btn.solid{
--route-btn-bg: #FFF;
&.solid{
--route-btn-bg: #A9A9A9;
&:hover{
--route-btn-hover-bg: #A9A9A9!important;
--route-btn-hover-text-color: #FFF!important;
}
.route_btn_title{
--route-btn-title-color: #FFF!important;
}
}
--route-btn-border: 1.5px solid #A9A9A9;
--route-btn-text-data-color: #A9A9A9!important;
--route-btn-hover-text-color: #A9A9A9!important;
box-shadow: none!important;
&:hover{
--route-btn-hover-bg: #FFF!important;
}
.route_btn_title{
--route-btn-title-color: #A9A9A9!important;
}
}
.route_btn img{
filter: brightness(0) saturate(100%) invert(77%) sepia(0%) saturate(270%) hue-rotate(138deg) brightness(90%) contrast(83%);
}
--route-cargo-type-color: #A9A9A9;
.route_card_owner_avatar{
filter: grayscale(1);
}
.card_owner_name, div.orange{
color: #A9A9A9!important;
}
.route_card_route_data{
.route_way_data{
.route_transport{
.route_transport_name{
color: #A9A9A9!important;
}
img{
filter: grayscale(1);
}
}
}
.from_to_place_data{
.label{
color: #A9A9A9!important;
}
.place{
.place_title{
color: #A9A9A9!important;
}
.country{
.country_code{
color: #A9A9A9!important;
}
}
img{
filter: grayscale(1);
}
}
}
}
.route_number{
color: #A9A9A9!important;
}
.route_date_data{
color: #A9A9A9!important;
}
.way_progress_line_container{
.way_progress_arrows_line{display: none!important;}
.way_progress_line{
background: #A9A9A9!important;
}
.way_progress_round:first-of-type, .way_progress_round:last-of-type{
border: 3px solid #A9A9A9!important;
}
}
.route_card_actions_container{
.delete_route{
color: #FF613A;
}
}
}
.route_card_info_data{
&.mobile{display: none}
@media (max-width: 1024px) {
display: none;
&.mobile {
display: block;
--route-text-container-margin: 50px 0 0 51px;
.route_card_owner_info {
height: unset;
margin-left: 0;
margin-bottom: 10px;
--medium-font-size: 12px;
}
.route_card_text_img{
top: 25px;
}
.route_card_owner_avatar{
top: 31px;
}
.card_owner_name{
position: absolute;
top: 40px;
left: 74px;
--big-font-size: 12px;
}
}
}
position: relative;
.card_owner_name{
font-weight: 600;
font-size: var(--big-font-size);
}
.route_card_text_img{
position: absolute;
top: 5px;
left: 0;
filter: var(--route-text-img-filter);
display: block;
z-index: 1;
}
.route_card_owner_avatar{
height: var(--route-card-owner-avatar-size);
width: var(--route-card-owner-avatar-size);
border-radius: 100%;
display: block;
position: absolute;
top: 11px;
left: 6px;
z-index: 10;
object-fit: cover;
object-position: center;
}
.route_card_text_container{
position: relative;
overflow-wrap: anywhere;
@media (max-width: 992px) {
--big-font-size: 14px;
}
background: var(--route-text-container-bg);
padding: var(--route-text-container-padding);
margin: var(--route-text-container-margin);
border-radius: var(--route-text-container-border-radius);
font-size: var(--big-font-size);
&.wrapped{
.route_card_text_container_txt{
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
&.msg{
.route_card_text_container_txt{
background-image: linear-gradient(94.66deg, rgba(0, 0, 0, 1) 0%, rgba(241, 241, 241, 0) 8.64%, rgba(241, 241, 241, 0.98) 16.62%);
color: transparent;
background-clip: text;
-webkit-background-clip: text;
}
.route_msg_for_unregistered_user, .route_clicked_msg_for_unregistered_user{
--filter: none;
position: absolute;
top: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
img{
width: 32px;
height: 32px;
display: block;
filter: var(--filter);
}
div{
font-size: 12px;
width: 215px;
overflow-wrap: break-word;
color: #27242499;
}
@media (max-width: 800px) {
div{
font-size: 10px;
}
img{
width: 24px;
height: 24px;
}
}
}
.route_clicked_msg_for_unregistered_user{
display: none;
div{
color: #272424;
}
--filter: brightness(0) saturate(100%) invert(43%) sepia(55%) saturate(1482%) hue-rotate(336deg) brightness(104%) contrast(101%);
}
&.clicked{
.route_clicked_msg_for_unregistered_user{
display: flex;
}
.route_msg_for_unregistered_user{
display: none;
}
}
}
}
.route_card_owner_info{
height: 47px;
margin-left: 75px;
display: flex;
align-items: center;
justify-content: space-between;
.route_card_info_left_part{
display: flex;
align-items: center;
gap: 10px;
.card_splitter{
height: 22px;
width: 2px;
background: var(--card-splitter-bg);
}
.card_owner_type{
&.mover{
--route-owner-type-color: #45C226;
}
font-size: var(--medium-font-size);
color: var(--route-owner-type-color);
font-weight: 600;
}
.card_cargo_type{
display: flex;
align-items: center;
gap: 5px;
font-size: var(--medium-font-size);
color: var(--route-cargo-type-color);
font-weight: 600;
div.orange{color: #FF613A}
}
}
}
}
.route_card_route_data_cont{
&.mobile{display: none}
@media (max-width: 1160px) {
display: none;
&.mobile{
display: block;
.route_card_route_data {
display: grid;
grid-template-columns: 20px calc(100% - 30px);
gap: 10px;
.way_progress_line_container {
margin-top: 20px;
height: calc(100% - 20px);
.way_progress_round:first-of-type {
left: unset;
top: 0;
}
.way_progress_round:last-of-type {
right: unset;
top: calc(100% - 20px);
}
.way_progress_line {
background: linear-gradient(180deg, rgba(6, 91, 255, 1) 0%, rgba(69, 194, 38, 1) 100%);
height: calc(100% - 10px);
width: 4px;
}
.way_progress_arrows_line {
height: calc(100% - 10px);
width: 4px;
background-repeat: repeat-y;
background-image: url("/static/v2/icons/widgets/w_route_card/route_arrow_mobile.svg");
background-size: 4px;
}
}
.route_transport, .route_date_data {
&.route_transport {
margin-bottom: 0;
margin-top: 35px;
}
&.route_date_data {
margin-top: 0;
margin-bottom: 5px;
&:last-of-type {
margin-bottom: 39px;
}
}
justify-content: left !important;
}
.arrival_to {
text-align: left !important;
}
}
}
}
.route_card_route_data{
margin-top: var(--route_card_route_data-margin-top);
display: flex;
justify-content: space-between;
gap: 60px;
.from_to_place_data{
width: var(--from-to-place-data-width);
@media (max-width: 992px) {
--big-font-size: 14px;
}
&:has(.arrival_to){
.place{justify-content: right}
} &:has(.departure_from){
.place{justify-content: left}
}
@media (max-width: 1160px) {.place{justify-content: left!important;}}
.label{
color: #27242499;
font-size: var(--big-font-size);
font-weight: 600;
margin-bottom: 10px;
&.departure_from{
text-align: left;
} &.arrival_to{
text-align: right;
}
}
.place{
display: flex;
align-items: center;
gap: 10px;
.country{
display: flex;
align-items: center;
gap: 5px;
img{
width: 16px;
height: 12px;
display: block;
object-fit: contain;
box-shadow: 0 -1px 4px rgba(0, 0, 0, 0.1);
}
.country_code{
color: #27242499;
font-size: var(--medium-font-size);
}
}
.place_title{
--gradient_end: var(--max-width);
--gradient_start: calc(var(--max-width) - 70px);
--max-width: calc(var(--from-to-place-data-width) - 62.3px);
font-size: var(--big-font-size);
font-weight: 800;
max-width: var(--max-width);
overflow: hidden;
white-space: nowrap;
&.gradient{
color: transparent;
background-clip: text;
-webkit-background-clip: text;
background-image: linear-gradient(90deg, rgb(0 0 0) 0%, #000 var(--gradient_start), #FFFFFF var(--gradient_end));
}
@media (max-width: 1160px) {
width: var(--max-width);
--gradient_end: var(--from-to-place-data-width);
--gradient_start: calc(var(--from-to-place-data-width) - 50px);
}
}
}
}
.route_way_data{
@media (max-width: 992px) {
--medium-font-size: 12px;
}
flex-grow: 1;
.route_transport{
display: flex;
align-items: center;
justify-content: center;
gap: 5px;
margin-bottom: 10px;
margin-top: 8px;
.route_transport_name{
font-size: var(--medium-font-size);
font-weight: 600;
}
img{
height: 12px;
display: block;
}
}
}
}
}
.dates_inf_cont{
display: flex;
justify-content: space-between;
}
.way_progress_line_container{
position: relative;
width: 100%;
height: 15px;
.way_progress_round{
height: 20px;
width: 20px;
background: #FFFFFF;
border-radius: 100%;
position: absolute;
top: -10px;
z-index: 11;
&:first-of-type{
border: 3px solid #065BFF;
left: 0;
}
&:last-of-type{
border: 3px solid #45C226;
right: 0;
}
}
.way_progress_line{
width: calc(100% - 20px);
margin-left: 11px;
height: 4px;
position: absolute;
top: 2px;
z-index: 1;
background: linear-gradient(90deg, rgba(6,91,255,1) 0%, rgba(69,194,38,1) 100%);
}
.way_progress_arrows_line{
width: calc(100% - 10px);
margin-left: 11px;
height: 4px;
position: absolute;
top: 2px;
z-index: 10;
background-image: url("/static/v2/icons/widgets/w_route_card/route_arrow.svg");
background-repeat: repeat-x;
background-size: 10px;
}
}
.route_card_actions_container{
margin-top: 23px;
display: flex;
justify-content: space-between;
align-items: center;
&.mobile{display: none;}
@media (max-width: 1160px) {
display: none;
&.mobile{
display: block;
.delete_route{text-align: center}
}
}
.delete_route{
cursor: pointer;
color: #27242499;
font-size: var(--medium-font-size);
&:hover{
color: #FF613A;
}
}
.right_part_action_btns{
display: flex;
align-items: center;
gap: 20px;
}
}
.route_btn{
&.mobile{display: none;}
@media (max-width: 1160px) {
&.mobile{display: flex;}
&.hide_in_mobile{display: none!important;};
}
cursor: pointer;
&.solid{
--route-btn-width: 222px;
--route-btn-padding: 12px 0;
--route-btn-bg: #FF613A;
--route-btn-title-color: #ffffff;
}
&.inactive{
cursor: default;
--route-btn-title-color: #27242499;
--route-btn-border: 1.5px solid #FF613A99;
}
width: var(--route-btn-width);
border: var(--route-btn-border);
border-radius: var(--route-btn-border-radius);
padding: var(--route-btn-padding);
background: var(--route-btn-bg);
height: var(--route-btn-height);
margin: var(--route-btn-margin);
text-align: center;
justify-content: center;
transition: 200ms all;
&:has(img){
display: flex;
gap: 5px;
align-items: center;
justify-content: center;
text-align: unset;
.route_btn_title{
max-width: calc(100% - 21px);
font-size: 14px!important;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
&:not(&.inactive):not(&.unhovered){
&:hover{
background: var(--route-btn-hover-bg);
.route_btn_title{color: var(--route-btn-hover-text-color);}
.route_btn_data{color: var(--route-btn-hover-text-color);}
box-shadow: 0 4px 4px rgba(189, 104, 104, 0.25);
}
}
.route_btn_title{
@media (max-width: 768px) {
--big-font-size: 14px;
--medium-font-size: 12px;
}
color: var(--route-btn-title-color);
font-size: var(--medium-font-size);
&.big{
font-size: var(--big-font-size);
}
}
.route_btn_data{
font-size: var(--small-font-size);
color: var(--route-btn-text-data-color);
}
img{
min-width: 16px;
display: block;
}
}
.route_date_data{
display: flex;
align-items: center;
gap: 5px;
justify-content: var(--route-date-data-justify);
margin: var(--route-date-data-margin);
font-size: var(--medium-font-size);
width: 100%;
.date_data_value{
font-weight: 600;
}
}
.route_date_splitter{
background: var(--route-date_splitter-bg);
width: var(--route-date_splitter-width);
height: var(--route-date_splitter-height);
margin: var(--route-date_splitter-margin);
}
.container_actions_mobile{
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 21px;
margin: 20px 0;
}
.route_number{
@media (max-width: 1160px) {
--route-number-font-size: 10px;
--route-number-margin-top: 10px;
}
color: #000000;
width: 100%;
text-align: right;
font-size: var(--route-number-font-size);
margin-top: var(--route-number-margin-top);
}
.respond_route_cont{
&.mobile{display: none;}
@media (max-width: 1160px) {
display: none;
&.mobile{display: grid;}
}
display: grid;
grid-template-columns: calc(100% - 47px) 37px;
gap: 10px;
.route_btn{
max-width: 155px!important;
width: fit-content;
}
}
.chat_btn{
padding: 6.5px;
background: #FF613A;
border-radius: 10px;
img{
display: block;
height: 24px;
width: 24px;
filter: invert(1);
}
}
}

View File

@@ -3,7 +3,7 @@
--header-padding: 20px 10px;
--select-border: #E6E6E6;
--select-border-radius: 10px 10px 0 0;
--select-height: 68px;
--select-height: 60px;
&.closed{
--select-border-radius: 10px;
@@ -17,7 +17,7 @@
justify-content: space-between;
border: 2px solid var(--select-border);
border-radius: var(--select-border-radius);
padding: 19px 10px;
padding: 15px 10px;
background: #FFFFFF;
.select_country_header_left_part{
@@ -54,9 +54,10 @@
.w_select_country_content{
position: absolute;
top: var(--select-height);
z-index: 10000;
width: 100%;
background: #FFFFFF;
border: 1px solid var(--select-border);
border: 2px solid var(--select-border);
border-top: none;
border-radius: 0 0 10px 10px;
box-sizing: border-box;

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,3 @@
<svg width="7" height="13" viewBox="0 0 7 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 1L6 6.5L1 12" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@@ -0,0 +1,4 @@
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.29785 17L17.2979 1" stroke="#272424" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M17.2979 17L1.29785 1" stroke="#272424" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,3 @@
<svg width="15" height="12" viewBox="0 0 15 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.2667 1.19438C13.1 0.78875 12.6333 0.5 12.0833 0.5H2.91667C2.36667 0.5 1.90833 0.78875 1.73333 1.19438L0.0916666 5.0925C0.0333332 5.23688 0 5.38812 0 5.54625V10.4688C0 11.0394 0.558333 11.5 1.25 11.5C1.94167 11.5 2.5 11.0394 2.5 10.4688V10.125H12.5V10.4688C12.5 11.0325 13.0583 11.5 13.75 11.5C14.4333 11.5 15 11.0394 15 10.4688V5.54625C15 5.395 14.9667 5.23688 14.9083 5.0925L13.2667 1.19438ZM2.91667 8.0625C2.225 8.0625 1.66667 7.60187 1.66667 7.03125C1.66667 6.46063 2.225 6 2.91667 6C3.60833 6 4.16667 6.46063 4.16667 7.03125C4.16667 7.60187 3.60833 8.0625 2.91667 8.0625ZM12.0833 8.0625C11.3917 8.0625 10.8333 7.60187 10.8333 7.03125C10.8333 6.46063 11.3917 6 12.0833 6C12.775 6 13.3333 6.46063 13.3333 7.03125C13.3333 7.60187 12.775 8.0625 12.0833 8.0625ZM1.66667 4.625L2.725 1.99875C2.84167 1.72375 3.15833 1.53125 3.51667 1.53125H11.4833C11.8417 1.53125 12.1583 1.72375 12.275 1.99875L13.3333 4.625H1.66667Z" fill="#FF613A"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.965 6.0925C4.045 8.215 5.785 9.9475 7.9075 11.035L9.5575 9.385C9.76 9.1825 10.06 9.115 10.3225 9.205C11.1625 9.4825 12.07 9.6325 13 9.6325C13.4125 9.6325 13.75 9.97 13.75 10.3825V13C13.75 13.4125 13.4125 13.75 13 13.75C5.9575 13.75 0.25 8.0425 0.25 1C0.25 0.5875 0.5875 0.25 1 0.25H3.625C4.0375 0.25 4.375 0.5875 4.375 1C4.375 1.9375 4.525 2.8375 4.8025 3.6775C4.885 3.94 4.825 4.2325 4.615 4.4425L2.965 6.0925Z" fill="#FF613A"/>
</svg>

After

Width:  |  Height:  |  Size: 545 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="15" viewBox="0 0 16 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.74083 6.54208C4.88083 8.7825 6.7175 10.6112 8.95792 11.7592L10.6996 10.0175C10.9133 9.80375 11.23 9.7325 11.5071 9.8275C12.3938 10.1204 13.3517 10.2788 14.3333 10.2788C14.7688 10.2788 15.125 10.635 15.125 11.0704V13.8333C15.125 14.2688 14.7688 14.625 14.3333 14.625C6.89958 14.625 0.875 8.60042 0.875 1.16667C0.875 0.73125 1.23125 0.375 1.66667 0.375H4.4375C4.87292 0.375 5.22917 0.73125 5.22917 1.16667C5.22917 2.15625 5.3875 3.10625 5.68042 3.99292C5.7675 4.27 5.70417 4.57875 5.4825 4.80042L3.74083 6.54208Z" fill="#FF613A" fill-opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 663 B

View File

@@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.58 2.6369L9.38918 4.6973L11.4757 10.4351L9.9108 12L6.79412 7.43581L5.21621 8.87027V10.4351L3.65135 12L2.72547 9.26801L0 8.34865L1.56486 6.78379H3.12973L4.69459 5.21892L0 2.0892L1.56486 0.524336L7.30269 2.61082L9.36962 0.426532L9.32398 0.459133C9.61796 0.165155 10.0167 0 10.4324 0C10.8482 0 11.2469 0.165155 11.5409 0.459133C11.8348 0.753111 12 1.15183 12 1.56758C12 1.98333 11.8348 2.38204 11.5409 2.67602L11.58 2.6369Z" fill="#FF613A"/>
</svg>

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

View File

@@ -0,0 +1,3 @@
<svg width="32" height="33" viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13 23C13 24.933 11.433 26.5 9.5 26.5C7.567 26.5 6 24.933 6 23C6 21.067 7.567 19.5 9.5 19.5C11.433 19.5 13 21.067 13 23ZM13 23H19M19 23C19 24.933 20.567 26.5 22.5 26.5C24.433 26.5 26 24.933 26 23C26 21.067 24.433 19.5 22.5 19.5C20.567 19.5 19 21.067 19 23ZM1 15.5H31M5 15.5L11.1625 6.7C11.2553 6.56663 11.3793 6.45789 11.5236 6.38321C11.6679 6.30852 11.8283 6.27013 11.9908 6.27136C12.1533 6.27259 12.313 6.31341 12.4562 6.39027C12.5994 6.46714 12.7217 6.57774 12.8125 6.7125L15.1625 10.25C15.2534 10.3893 15.3775 10.5037 15.5238 10.5829C15.67 10.6621 15.8337 10.7036 16 10.7036C16.1663 10.7036 16.33 10.6621 16.4762 10.5829C16.6225 10.5037 16.7466 10.3893 16.8375 10.25L19.1875 6.7125C19.2783 6.57774 19.4006 6.46714 19.5438 6.39027C19.687 6.31341 19.8467 6.27259 20.0092 6.27136C20.1717 6.27013 20.3321 6.30852 20.4764 6.38321C20.6207 6.45789 20.7447 6.56663 20.8375 6.7L27 15.5" stroke="#272424" stroke-opacity="0.6" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,27 @@
function toggleFiltersModal(el) {
if (!el) return;
if (el.classList.contains('active')) {
closeFiltersModal(el)
} else {
openFiltersModal(el)
}
}
function openFiltersModal(el) {
if (!el) return;
el.classList.add('active');
let $modal = $(".b_filter_routes.modal")
$modal.addClass('open');
}
function closeFiltersModal(el) {
if (!el) return;
el.classList.remove('active');
let $modal = $(".b_filter_routes.modal")
$modal.removeClass('open');
}

View File

@@ -0,0 +1,31 @@
function loadMoreMyRoutesRoutes (el){
if (!el) return;
let formData = new FormData();
let from_el = parseInt(el.dataset.from_el);
let to_el = from_el + parseInt(el.dataset.more_count);
formData.append('from_el', from_el);
formData.append('to_el', to_el);
let request = new api({
url: '/routes/get_routes/',
data: formData,
data_type: 'formData',
success: (res) => {
if (!res.html) return;
let $parent = $('.info_profile')[0];
let $next_page_btn = $parent.querySelector('.container_btns[data-next_page_btn]')
$next_page_btn.remove();
appendNodes($parent, templateStrToNode(`
<div class="next_page" style="
margin: 50px 0;
width: 100%;
background: #212121;
height: 1px;"></div>
`));
appendNodes($parent, templateStrToNode(res.html));
}
});
request.ajaxRequest()
}

View File

@@ -0,0 +1,64 @@
function searchRoutes (form=undefined) {
event.preventDefault()
let $filter_form = $('.b_filter_routes form')[0];
let $search_form = $('.b_search_routes form')[0];
let formData = getFormData($search_form);
formData = getFormData($filter_form, formData);
let owner_type = 'mover'
formData.append('owner_type', owner_type);
let query = formDataToQueryString(formData, [$filter_form, $search_form]);
query+=`owner_type=${owner_type}`
window.history.pushState(null, null, `?${query}`);
let request = new api({
url: '/routes/find_routes/',
data: formData,
data_type: 'formData',
success: function (res) {
if (!res.html) return;
let $parent = $('.routes_search_results')[0];
$parent.innerHTML = res.html;
}
})
request.ajaxRequest()
}
function loadMoreRoutes (el) {
if (!el) return;
let from_el = parseInt(el.dataset.from_el);
let to_el = from_el + parseInt(el.dataset.more_count);
let $filter_form = $('.b_filter_routes form')[0];
let $search_form = $('.b_search_routes form')[0];
let formData = getFormData($search_form);
formData = getFormData($filter_form, formData);
let owner_type = 'mover'
formData.append('owner_type', owner_type);
formData.append('from_el', from_el);
formData.append('to_el', to_el);
let query = formDataToQueryString(formData, [$filter_form, $search_form]);
query+=`owner_type=${owner_type}`
window.history.pushState(null, null, `?${query}`);
let request = new api({
url: '/routes/find_routes/',
data: formData,
data_type: 'formData',
success: function (res) {
if (!res.html) return;
let $parent = $('.routes_search_results')[0];
let $next_page_btn = $parent.querySelector('.container_btns[data-next_page_btn]')
$next_page_btn.remove();
appendNodes($parent, templateStrToNode(`
<div class="next_page"></div>
`));
appendNodes($parent, templateStrToNode(res.html));
}
})
request.ajaxRequest()
}

View File

@@ -1,15 +1,16 @@
function chooseCheckbox(el) {
function chooseCheckbox(el, callback) {
if (!el) return;
resetFieldError(el);
let $parent = el.closest('.field_container');
let $checkbox = $parent.querySelector('.checkbox')
$checkbox.classList.toggle("checked");
if (callback) callback($checkbox.classList.contains('checked'));
}
function getFormData(form) {
function getFormData(form, formData=new FormData()) {
if (!form) return;
let formData = new FormData();
let default_element_types = ['input', 'textarea', 'date'];
let form_elements = getFormElements(form);
@@ -51,8 +52,24 @@ function addCustomDataToFormData(el, formData) {
case 'checkbox':
let $checkbox = el.querySelector('.checkbox');
let c_value = $checkbox.classList.contains('checked');
if ($checkbox.dataset.value) c_value = $checkbox.dataset.value;
formData.append(name, c_value);
if ($checkbox.classList.contains('checked')){
if (formData.get(name) || formData.get(name) === false){
let previos_val = formData.get(name);
formData.delete(name);
formData.set(name, previos_val + "," + c_value);
break;
}
}
if (typeof c_value === 'string'){
if ($checkbox.classList.contains('checked')){
formData.append(name, c_value);
break;
}
} else {
formData.append(name, c_value);
}
break;
case 'radio':
@@ -74,6 +91,186 @@ function addCustomDataToFormData(el, formData) {
formData.append(name, l_value);
break;
case 'select':
let $select = el.querySelector('select');
if (!$select) return;
formData.append(name, $select.value);
}
return formData;
}
}
function getCargoTypesWTypeTransport (data) {
let type_transport = data.type_transport;
let owner_type = data.owner_type;
let success_callback = data.success_callback;
let error_callback = data.error_callback;
if (!owner_type) return;
let request_data = {
type_transport: type_transport,
owner_type: owner_type,
}
let formData = dataToFormData(request_data);
let request = new api({
url: '/routes/get_cargo_type_by_transport_type/',
data: formData,
data_type: 'formData',
success: success_callback,
error: error_callback,
})
request.ajaxRequest()
}
function getFormOwnerType(el){
let form = el.closest('form');
let owner_type = form.dataset.owner_type;
return owner_type;
}
function dataToFormData(data) {
let formData = new FormData();
for (let key of Object.keys(data)) {
formData.append(key, data[key]);
}
return formData;
}
function selectInputWContainer (el, callback) {
if (!el) return;
let $field = el.closest('.field_container');
if (!$field) return;
let $input = $field.querySelector('input');
$input.focus()
if (callback) callback(el);
}
function resetFieldError (el){
if (!el) return;
let $field = el.closest('.field_container');
if (!$field) return;
let $error = $field.querySelector('.error_container');
if (!$error) return;
if (!checkFieldEmpty($field)){
$error.remove()
}
}
function checkFieldEmpty($field) {
if (!$field) return;
let empty = true;
switch ($field.dataset.type) {
case 'checkbox':
let $checkbox = $field.querySelector('.checkbox');
let c_value = $checkbox.classList.contains('checked');
if (c_value) empty = false;
break;
case 'radio':
let $radio = $field.querySelector('.radio.checked');
if ($radio) empty = false;
break;
case 'location':
let $location = $field.querySelector('input');
let l_value = $location.dataset.id;
if (l_value) empty = false;
break;
case 'input':
let $input = $field.querySelector('input');
if ($input.value) empty = false;
break;
case 'textarea':
let $textarea = $field.querySelector('textarea');
if ($textarea.value) empty = false;
break;
case 'date':
let $date = $field.querySelector('input');
if ($date.value) empty = false;
break;
case 'select':
let $select = el.querySelector('select');
if (!$select) return;
if ($select.value) empty = false;
break;
}
return empty;
}
function getFormDataElValue($field) {
if (!$field) return;
switch ($field.dataset.type) {
case 'checkbox':
let $checkbox = $field.querySelector('.checkbox');
let c_value = $checkbox.classList.contains('checked');
return c_value;
case 'radio':
let $radio = $field.querySelector('.radio.checked');
if ($radio){
$radio = $radio.closest('.cw_w_radio_inputs_radio_input').dataset.name;
return $radio
} else {
return ``
}
case 'location':
let $location = $field.querySelector('input');
let l_value = $location.dataset.id;
return l_value;
case 'input':
let $input = $field.querySelector('input');
return $input.value;
case 'textarea':
let $textarea = $field.querySelector('textarea');
return $textarea.value;
case 'date':
let $date = $field.querySelector('input');
return $date.value;
case 'select':
let $select = $field.querySelector('select');
if (!$select) return;
return $select.value;
}
}
function formDataToQueryString (formData, forms) {
let str = ``
formData.forEach((value, name) => {
str+=`${name}=${value}&`;
})
return str;
}

View File

@@ -4,6 +4,7 @@ function makeMoverOrder(form) {
let formData = getFormData(form);
formData.append('owner_type', 'mover');
if (form.dataset.route_id) formData.set('route_id', form.dataset.route_id);
let request = new api({
url: '/routes/create_or_change_route/',
data: formData,
@@ -17,11 +18,11 @@ function makeMoverOrder(form) {
if (!profile_root) return;
profile_root.innerHTML = res.html
let created_route = document.querySelector(`[data-number-of-route="${created_route_id}"]`);
let created_route = document.querySelector(`.w_route_card[data-route_id="${created_route_id}"]`);
created_route.scrollIntoView({
behavior:"smooth",
block:'start',
inline:'start'
block:'center',
inline:'center'
});
let new_url = window.location.pathname
@@ -42,7 +43,7 @@ function makeMoverOrder(form) {
$(res.responseJSON.html).insertAfter($($title))
daterangepickerInit($('.w_daterangepicker'), daterangepickerInit)
datarangepickerinitAll()
}
})

View File

@@ -4,6 +4,7 @@ function makePosterOrder(form) {
let formData = getFormData(form);
formData.append('owner_type', 'customer');
if (form.dataset.route_id) formData.set('route_id', form.dataset.route_id);
let request = new api({
url: '/routes/create_or_change_route/',
data: formData,
@@ -17,7 +18,7 @@ function makePosterOrder(form) {
if (!profile_root) return;
profile_root.innerHTML = res.html
let created_route = document.querySelector(`[data-number-of-route="${created_route_id}"]`);
let created_route = document.querySelector(`.w_route_card[data-route_id="${created_route_id}"]`);
created_route.scrollIntoView({
behavior:"smooth",
block:'start',
@@ -42,9 +43,43 @@ function makePosterOrder(form) {
$(res.responseJSON.html).insertAfter($($title))
daterangepickerInit($('.w_daterangepicker'), daterangepickerInit)
datarangepickerinitAll()
}
})
request.ajaxRequest()
}
function updateCargoTypeInForm(el, type_transport='') {
getCargoTypesWTypeTransport({
type_transport: type_transport,
owner_type: getFormOwnerType(el),
success_callback: success_callback_func,
})
function success_callback_func(res) {
let cargo_types = res.cargo_types
if (!cargo_types) return;
let $widget = getWRadioInputsWidget('cargo_type');
let $selected_value = $widget.querySelector(".radio.checked")
resetWRadioInputs('cargo_type');
for (let cargo_type of cargo_types) {
let obj = {
name: cargo_type[0],
title: cargo_type[1],
}
let selected = false;
if ($selected_value && $selected_value.closest(".cw_w_radio_inputs_radio_input").dataset.name === obj.name) selected = true;
let html = generateRadioInput(obj, selected)
if ($widget.lastElementChild){
$(html).insertAfter($($widget.lastElementChild))
} else {
$widget.innerHTML = html
}
}
}
}

View File

@@ -0,0 +1,19 @@
$(document).ready(function() {
if (window.innerWidth <= 800) {
$(".b_filter_routes").addClass('modal');
return;
}
let header_height = $("#header_bg")[0].offsetHeight;
let _scroll = new scroll({
attach_top: header_height + 20,
top: header_height + 20,
el: $(".b_filter_routes")[0],
recover_el_view: true,
ghost_block:{name: 'route_filters'},
$unnatach_bottom_el: $(".b_dont_found_anth")[0]
})
_scroll.init()
$('body')[0].onscroll = function() {
_scroll.attachElementWhenScroll();
}
})

View File

@@ -29,6 +29,8 @@ class api {
request_data.contentType = false
}
if (this.data_type === 'json'){
request_data.processData = false
request_data.contentType = false
request_data.data = JSON.stringify(this.data)
}

View File

@@ -0,0 +1,11 @@
function templateStrToNode(template) {
let template_cont = document.createElement("template");
template_cont.innerHTML = template;
return template_cont.content.children;
}
function appendNodes($cont, nodes) {
while (nodes.length > 0){
$cont.append(nodes[0]);
}
}

View File

@@ -0,0 +1,6 @@
function closeModal(el) {
let $parent = el.closest('.modal');
$parent.classList.remove('open');
$("body")[0].style.overflow = "auto";
}

View File

@@ -0,0 +1,66 @@
class scroll{
constructor(props){
this.attach_top = props.attach_top;
this.top = props.top;
this.left = props.left;
this.$el = props.el;
this.recover_el_view = props.recover_el_view;
this.unattach_top = undefined;
this.$unnatach_bottom_el = props.$unnatach_bottom_el;
this.attached = false;
this.attached_by_bottom_el = false;
this.ghost_block = props.ghost_block;
this.$ghost_block = null;
}
attachElementWhenScroll(){
let bottom_el_in_screen = this.$unnatach_bottom_el.getBoundingClientRect().top <= window.innerHeight
if (!this.attached_by_bottom_el && this.$unnatach_bottom_el && bottom_el_in_screen && this.attached){
let $unnatach_bottom_el_margin_top= window.getComputedStyle(this.$unnatach_bottom_el)
$unnatach_bottom_el_margin_top = $unnatach_bottom_el_margin_top.getPropertyValue('margin-top');
$unnatach_bottom_el_margin_top = $unnatach_bottom_el_margin_top.split('p')
$unnatach_bottom_el_margin_top = $unnatach_bottom_el_margin_top.length > 0? $unnatach_bottom_el_margin_top[0] : 0;
this.$el.style.top = (window.scrollY - $unnatach_bottom_el_margin_top) + this.top + 'px';
this.$el.style.position = "absolute";
this.attached_by_bottom_el = true;
return;
} else if (this.attached_by_bottom_el && this.$unnatach_bottom_el && this.$unnatach_bottom_el.getBoundingClientRect().top >= window.innerHeight) {
this.attachFunc(false)
}
if (!this.attached && this.$el.getBoundingClientRect().top <= this.attach_top && !bottom_el_in_screen) {
this.attachFunc()
} else if ((this.$el.parentElement.getBoundingClientRect().top - this.attach_top) > 0){
this.$el.style.position = "unset";
this.attached = false;
if (this.$ghost_block) this.$ghost_block.style.display = "none";
}
}
attachFunc(set_unattach=true){
this.$el.style.top = this.top + 'px';
this.$el.style.position = "fixed";
this.attached = true;
this.attached_by_bottom_el = false;
if (this.$ghost_block) this.$ghost_block.style.display = "block";
}
init(){
if (this.recover_el_view){
$(this.$el).css({
height: this.$el.offsetHeight,
width: this.$el.offsetWidth
})
}
if (this.ghost_block){
let _ghost_block = `<div class="ghost_block" data-name="${this.ghost_block.name}" style="display: none;"></div>`
$(_ghost_block).insertAfter($(this.$el));
this.$ghost_block = $(`.ghost_block[data-name="${this.ghost_block.name}"]`)[0];
this.$ghost_block.width = this.$el.offsetWidth;
this.$ghost_block.height = this.$el.offsetHeight;
}
}
}

3
static/v2/js/twb.js Normal file
View File

@@ -0,0 +1,3 @@
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

View File

@@ -29,22 +29,41 @@ function setLocalSets() {
return locale_lang
}
$(function (){daterangepickerInit($('.w_daterangepicker'), daterangepickerInit)})
function datarangepickerinitAll(){
$('.w_daterangepicker').each(function () {
daterangepickerInit(this, daterangepickerInit)
})
}
function daterangepickerInit(el, callback) {
$('.date_range_input_cont input').daterangepicker({
function daterangepickerInit(el, callback, date) {
let $datarangepicker = el.querySelector('input');
let min_date = moment(date)
if ($datarangepicker.dataset.set_min_date === 'false' || $datarangepicker.dataset.set_min_date === false) {
min_date = moment('1900-01-01');
}
$($datarangepicker).daterangepicker({
"autoapply": true,
"linkedCalendars": false,
"singleDatePicker": true,
"singleDatePicker": !!!$datarangepicker.dataset.range,
"timePicker": false,
"timePicker24Hour": false,
"minDate": moment(),
"minDate": min_date,
"locale": setLocalSets(),
}, function (start, end, label) {
let $parent = el.closest('.w_daterangepicker')
if (!$parent) $parent = el.querySelector(".w_daterangepicker")
if (!$parent) return;
if (last_opened_daterangepicker) $parent = last_opened_daterangepicker.closest('.w_daterangepicker');
let $input = $parent.find(".date_range_input_cont input")
$input.val(start.format('DD.MM.YYYY'));
let $input = $parent.querySelector(".date_range_input_cont input")
let start_date = start.format('DD.MM.YYYY');
$input.value = start_date;
if (end){
let end_date = end.format('DD.MM.YYYY');
if (start_date !== end_date) $input.value = `${start_date} - ${end_date}`
}
resetFieldError(el);
if (callback) callback(el)
});
}
@@ -55,3 +74,6 @@ function clickOnDateIconE(el){
$input.focus()
}
$(document).ready(function () {
datarangepickerinitAll()
})

View File

@@ -1,5 +1,6 @@
function chooseRadioInput(el, callback){
if (!el) return;
let $parent = el.closest('.w_radio_inputs');
if (!$parent) return;
@@ -12,6 +13,40 @@ function chooseRadioInput(el, callback){
let $radio = $parent.querySelector('.radio');
$radio.classList.toggle("checked");
let checked_state = $radio.classList.contains("checked");
if (callback) callback(checked_state)
let el_name = $parent.dataset.name;
resetFieldError(el);
if (callback) callback(el, el_name)
}
function generateRadioInput(data, selected){
let title = data.title;
if (title.includes('(')){
title = title.replace(')', '')
title = title.split('(')
if (title.length > 1){
title = `<div>${title[0]}</div><div class="annotation">(${title[1]})</div>`
}
}
let html = `
<div class="cw_w_radio_inputs_radio_input" data-name="${data.name}">
<div class="radio${selected? ' checked' : ''}" onclick="chooseRadioInput(this, ${data.callback})"></div>
<div class="radio_label" onclick="chooseRadioInput(this, ${data.callback})">${title}</div>
</div>
`
return html;
}
function resetWRadioInputs(widget_name){
let $widget = getWRadioInputsWidget(widget_name);
if (!$widget) return;
$widget.innerHTML = '';
}
function getWRadioInputsWidget(widget_name){
if (!widget_name) return;
let $widget = $(`.field_container[data-type="radio"][data-name="${widget_name}"] .w_radio_inputs`)[0];
return $widget;
}

View File

@@ -0,0 +1,155 @@
function changeRoute(el) {
if (!el || el.closest('.disabled')) return;
let $parent = el.closest(".w_route_card")
if (!$parent) return;
let data = {
'route_id': $parent.dataset.route_id,
'owner_type': $parent.dataset.owner_type,
}
let request = new api({
url: '/routes/edit_route/',
data: data,
data_type: 'json',
success: (res) => {
if (!res.html) return;
$(".info_profile")[0].innerHTML = res.html;
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
});
datarangepickerinitAll()
}, error: (res) => {
}
});
request.ajaxRequest()
}
function deleteRoute(el) {
if (!el) return;
let $parent = el.closest(".w_route_card")
if (!$parent) return;
let data = {
'route_id': $parent.dataset.route_id,
'owner_type': $parent.dataset.owner_type,
}
let request = new api({
url: '/routes/del_route/',
data: data,
data_type: 'json',
success: (res) => {
$parent.remove()
}, error: (res) => {
}
});
request.ajaxRequest()
}
function raiseRoute(el) {
if (!el || el.dataset.actions_count === '0' || el.closest('.disabled')) return;
let $parent = el.closest(".w_route_card")
if (!$parent) return;
let data = {
'route_id': $parent.dataset.route_id,
'owner_type': $parent.dataset.owner_type,
}
let request = new api({
url: '/routes/raise_route/',
data: data,
data_type: 'json',
success: (res) => {
window.scrollTo(0, 0);
let $parent_list = $parent.closest('.b_my_routes').children
$($parent).insertBefore($($parent_list[0]))
if ($parent.dataset.owner_type === 'mover'){
$($parent).css('--route-card-box_shadow', '0 -1px 10px rgb(62 205 5 / 36%), -1px 4px 10px rgba(198, 199, 203, 0.2)')
} else {
$($parent).css('--route-card-box_shadow', '0 -1px 10px rgb(5 74 205 / 36%), -1px 4px 10px rgba(198, 199, 203, 0.2)')
}
let timeout = setTimeout(() =>{
$($parent).css('--route-card-box_shadow', '0 -1px 10px rgba(198, 199, 203, 0.2), -1px 4px 10px rgba(198, 199, 203, 0.2)');
clearTimeout(timeout);
}, 1000)
$('.route_btn[data-action="raise"]').each((i, el) => {
el.dataset.actions_count = res.remains_route_rising_count;
el.querySelector('.route_btn_data').innerHTML = el.querySelector('.route_btn_data').innerHTML.split(':')[0] + `: ${res.remains_route_rising_count}`;
})
}, error: (res) => {
}
});
request.ajaxRequest()
}
function highlightRoute(el) {
if (!el || el.dataset.actions_count === '0' || el.closest('.disabled')) return;
let $parent = el.closest(".w_route_card")
if (!$parent) return;
let data = {
'route_id': $parent.dataset.route_id,
'owner_type': $parent.dataset.owner_type,
}
let request = new api({
url: '/routes/highlight_route/',
data: data,
data_type: 'json',
success: (res) => {
$parent.classList.add('highlighted');
$('.route_btn[data-action="highlight"]').each((i, el) => {
el.dataset.actions_count = res.remains_route_highlight_count;
el.querySelector('.route_btn_data').innerHTML = el.querySelector('.route_btn_data').innerHTML.split(':')[0] + `: ${res.remains_route_highlight_count}`;
})
}, error: (res) => {
}
});
request.ajaxRequest()
}
function respondBtnClickEvent(el, authentificated) {
if (!el || el.closest('.disabled')) return;
if (authentificated !== 'False') {
let $parent = el.closest(".w_route_card")
let $responde_cont = $parent.querySelector(".respond_route_cont")
if (window.innerWidth < 1160) $responde_cont = $parent.querySelector(".respond_route_cont.mobile")
$(el).fadeOut(500);
sleep(500).then(() => {
$($responde_cont).fadeIn(500);
})
} else {
$(".b_login_modal").addClass('open');
$("body")[0].style.overflow = "hidden";
}
}
function clickedUnregisteredMsgRoute (el) {
if (!el || el.closest('.disabled')) return;
let $parent = el.closest(".route_card_text_container")
$parent.classList.add('clicked');
}
function unwrapRouteComment (el){
if (!el || el.closest('.disabled')) return;
let $parent = el.closest(".wrapped")
if (!$parent) return;
$parent.classList.remove('wrapped');
}

View File

@@ -87,6 +87,7 @@ function selectCountry(el, callback) {
id: el.dataset.id,
country_code: el.dataset.country_code,
flag: el.dataset.flag,
now: el.dataset.now
}
$flag.src = country_data.flag;
@@ -96,7 +97,20 @@ function selectCountry(el, callback) {
$input.dataset.name = country_data.full_name;
$input.dataset.id = country_data.id;
closeSelectCountry(el)
connectCountryWDateRangePicker(el, country_data)
closeSelectCountry(el);
resetFieldError(el);
}
function connectCountryWDateRangePicker (el, data) {
let $parent = el.closest(".field_container")
if (!$parent || !data || typeof daterangepickerInit === 'undefined') return;
let datepicker_name = $parent.dataset.datepicker;
let $datepicker = $(`.field_container[data-name="${datepicker_name}"]`)[0]
if (!$datepicker) return;
daterangepickerInit($datepicker, false, data.now)
}
function resetCountrySelect(el, callback) {

View File

@@ -1,12 +1,12 @@
function textareaInputE (el, callback){
if (!el) return;
resetFieldError(el);
let $counter = $(".symbols_counter")[0]
let $parent = el.closest(".w_textarea_w_counter")
if (el.value.length > $parent.dataset.max_val){
el.value = el.value.slice(0, -1)
return;
el.value = el.value.slice(0, -(el.value.length - $parent.dataset.max_val))
}
let str = `${el.value.length} ${getTransFromEl($parent)} ${$parent.dataset.max_val}`
$counter.innerHTML = str

View File

@@ -32,11 +32,14 @@
<script src='{% static "v2/js/widgets/w_select_country.js" %}'></script>
<script src='{% static "v2/js/widgets/w_radio_inputs.js" %}'></script>
<script src='{% static "v2/js/widgets/w_route_card.js" %}'></script>
<script src='{% static "v2/js/widgets/w_daterangepicker.js" %}'></script>
<script src='{% static "v2/js/widgets/w_textarea_w_counter.js" %}'></script>
<script src='{% static "v2/js/forms/f_make_poster_order.js" %}'></script>
<script src='{% static "v2/js/forms/f_make_mover_order.js" %}'></script>
<script src='{% static "v2/js/blocks/b_my_routes.js" %}'></script>
{% include "connect_ws_js.html" %}
<link rel="stylesheet" href="{% static "v2/css/widgets/w_route_card.css" %}">
<script defer src='{% static "js/check_new_messages.js" %}'></script>

View File

@@ -58,8 +58,10 @@ function gtag_report_conversion(url) {
<script type="text/javascript" src="{% static "js/moment_js.js" %}"></script>
<script type="text/javascript" src="{% static "js/moment-with-locales.js" %}"></script>
<script type="text/javascript" src="{% static "js/datarangepicker.js" %}"></script>
<script type="text/javascript" src="{% static "v2/js/service/scroll.js" %}"></script>
<script type="text/javascript" src="{% static "js/push/registerSw.js" %}"></script>
<script src="{% static "js/rangecalendartech.js" %}"></script>
<script src="{% static "v2/js/twb.js" %}"></script>
<link rel="stylesheet" href="{% static 'css/datarangepicker.css' %}" />
<script src="{% static "js/global_js.js" %}"></script>
@@ -89,6 +91,8 @@ function gtag_report_conversion(url) {
<link rel="stylesheet" href="{% static 'css/styles(boris).css' %}" >
<link rel="stylesheet" href="{% static 'css/mobile_styles.css' %}">
<link rel="stylesheet" href="{% static 'v2/css/widgets/w_additional_info.css' %}">
<link rel="stylesheet" href="{% static 'v2/css/service/modal.css' %}">
<link rel="stylesheet" href="{% static 'v2/css/service/btns.css' %}">
<script src='{% static "js/find_route.js" %}'></script>
<script src="{% static "js/filters_functions_find_route.js" %}"></script>
@@ -98,6 +102,8 @@ function gtag_report_conversion(url) {
<script src="{% static "js/user_profile_2.js" %}"></script>
<script src="{% static "js/ion.rangeSlider.min.js" %}"></script>
<script src="{% static "v2/js/forms.js" %}"></script>
<script src="{% static "v2/js/service/modal.js" %}"></script>
<script src="{% static "v2/js/service/general.js" %}"></script>
<link rel="stylesheet" href="{% static "css/ion.rangeSlider.min.css" %}">
@@ -200,24 +206,24 @@ function gtag_report_conversion(url) {
</div>
{% if page_type == 'routes' %}
<div class="cut_width_f_curtain{% if page_type == 'profile' %}{% else %} n_profile{% endif %} left">
<div class="menu_buttons curtain left open first filters" data-name="<img style='width: 15px;display: block;position: relative;bottom: 0;transform: rotate(270deg);' src='{% static "/img/svg/filter.svg" %}'>">
{% include "forms/f_find_route_filters_form.html" %}
{# <div class="menu_buttons curtain left open first filters" data-name="<img style='width: 15px;display: block;position: relative;bottom: 0;transform: rotate(270deg);' src='{% static "/img/svg/filter.svg" %}'>">#}
{##}
{# {% include "forms/f_find_route_filters_form.html" %}#}
{# <div class="handler_menu close" onclick="open_curtain_w_contacts()">#}
{# <img class="btns_f_curtain close left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
{# <div class="text_f_curtain left"><img style='width: 15px;display: block;position: relative;bottom: 0;transform: rotate(270deg);' src='{% static "/img/svg/filter.svg" %}'></div>#}
{# <img class="btns_f_curtain close right" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
{# <div class="clear_both"></div>#}
{# </div>#}
</div>
</div>
<div class="handler_curtain_left close" onclick="open_curtain_w_contacts()">
<div class="container_content_handler_curtain_left">
<img class="arrows_handler_curtain_left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">
<img class="filter_img" src='{% static "/img/svg/filter.svg" %}'>
<img class="arrows_handler_curtain_left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">
</div>
{# </div>#}
</div>
{# <div class="handler_curtain_left close" onclick="open_curtain_w_contacts()">#}
{# <div class="container_content_handler_curtain_left">#}
{# <img class="arrows_handler_curtain_left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
{# <img class="filter_img" src='{% static "/img/svg/filter.svg" %}'>#}
{# <img class="arrows_handler_curtain_left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
{# </div>#}
{# </div>#}
{% endif %}
<div class="{% if page.url == "landing_mover" or page.url == "landing_customer" %}container{% else %}wrapper_content{% endif %} {% if page.url == 'customer_service'%} m_h_0 {% elif page.url == 'contacts' %}m_h_0{% elif request.path == '/test_404' %}m_h_0{% endif %}">

View File

@@ -0,0 +1,22 @@
{% load static %}
{% load i18n %}
<link rel="stylesheet" href="{% static "v2/css/blocks/b_chat_modal.css" %}">
<div class="b_chat_modal open modal">
<div class="overlay"></div>
<div class="modal_body">
<div class="chat_header">
<div class="close_chat_container">
<div class="close_btn">
<img src="{% static 'v2/icons/service/modal/xmark.svg' %}">
</div>
</div>
<div class="chat_">
</div>
</div>
</div>
</div>

View File

@@ -12,5 +12,5 @@
<div class="b_make_poster_order">
<div class="make_poster_order_title">{% trans "Заполните форму, чтобы отправить посылку" %}</div>
{% include 'v2/forms/f_make_poster_order.html' %}
{% include 'v2/forms/f_create_customer_route.html' %}
</div>

View File

@@ -12,5 +12,5 @@
<div class="b_make_poster_order">
<div class="make_poster_order_title">{% trans "Заполните форму, чтобы перевезти посылку" %}</div>
{% include 'v2/forms/f_make_mover_order.html' %}
{% include 'v2/forms/f_create_mover_route.html' %}
</div>

View File

@@ -0,0 +1,23 @@
{% load static %}
{% load i18n %}
<link rel="stylesheet" href="{% static "v2/css/blocks/b_dont_found_anth.css" %}">
<div class="b_dont_found_anth">
<div class="first_imgs_line">
<img src="{% static "v2/icons/blocks/b_dont_found_anth/box1.png" %}" alt="">
<img src="{% static "v2/icons/blocks/b_dont_found_anth/box2.png" %}" alt="">
</div>
<div class="second_imgs_line">
<img src="{% static "v2/icons/blocks/b_dont_found_anth/box3.png" %}" alt="">
<img src="{% static "v2/icons/blocks/b_dont_found_anth/box4.png" %}" alt="">
</div>
<div class="container_content">
<div class="title">{% trans "Не нашли, что искали?" %}</div>
<div class="description">
{% trans "Создайте свое объявление и Вас начнут находить перевозчики со всего мира!" %}
</div>
<div class="container_btns" style="--justify: center;">
<a class="primary_btn" style="--padding: 19px 40px 21px 40px;">{% trans "Создать объявление" %}</a>
</div>
</div>
</div>

View File

@@ -0,0 +1,39 @@
{% load static %}
{% load i18n %}
<link rel="stylesheet" href="{% static "v2/css/blocks/b_filter_routes.css" %}">
<div class="b_filter_routes_modal_handler" onclick="toggleFiltersModal(this)">
<div class="b_filter_routes_modal_handler_content">
<img src="{% static "v2/icons/blocks/b_filter_routes/arrow.svg" %}" alt="">
<div>{% trans "Фильтр" %}</div>
<img src="{% static "v2/icons/blocks/b_filter_routes/arrow.svg" %}" alt="">
</div>
</div>
<div class="b_filter_routes">
<div class="overlay"></div>
<div class="b_filter_routes_content">
<div class="title">{% trans "Все фильтры" %}</div>
<form name="filter_routes">
<div class="label" style="margin-bottom: 16px;">{% trans "Способ перевозки" %}</div>
<div class="field_container line" data-type="checkbox" data-name="type_transport">
<div class="checkbox{% if 'road' in form.initial.type_transport %} checked{% endif %}" data-value="road" onclick="chooseCheckbox(this, searchRoutes)"></div>
<div class="checkbox_label" onclick="chooseCheckbox(this, searchRoutes)">{% trans "Автоперевозка" %}</div>
{% if form.errors.type_transport %}<div class="error_container">{{ form.errors.type_transport.0 }}</div>{% endif %}
</div>
<div class="field_container line" data-type="checkbox" data-name="type_transport">
<div class="checkbox{% if 'avia' in form.initial.type_transport %} checked{% endif %}" data-value="avia" onclick="chooseCheckbox(this, searchRoutes)"></div>
<div class="checkbox_label" onclick="chooseCheckbox(this, searchRoutes)">{% trans "Авиатранспорт" %}</div>
{% if form.errors.type_transport %}<div class="error_container">{{ form.errors.type_transport.0 }}</div>{% endif %}
</div>
<div class="field_container" data-type="select" data-name="cargo_type">
<label for="id_cargo_type">{% trans "Тип посылки" %}</label>
<select name="cargo_type" id="id_cargo_type" onchange="searchRoutes()">
<option value="">{% trans "Любой" %}</option>
{% for cargo_type in form.fields.cargo_type.choices %}
<option value="{{ cargo_type.0 }}">{{ cargo_type.1 }}</option>
{% endfor %}
</select>
</div>
</form>
</div>
</div>

View File

@@ -0,0 +1,21 @@
{% load static %}
{% load i18n %}
<link rel="stylesheet" href="{% static "v2/css/blocks/b_login_modal.css" %}">
<div class="b_login_modal modal">
<div class="overlay"></div>
<div class="b_login_modal_container_content">
<div class="b_login_modal_content">
<img onclick="closeModal(this)" class="xmark" src="{% static "v2/icons/service/modal/xmark.svg" %}" alt="">
<div class="b_login_modal_inf">
<div class="lock_img_container">
<img src="{% static "v2/icons/blocks/b_login_modal/lock.png" %}" alt="">
</div>
<div class="modal_title">{% trans "Войдите или зарегистрируйтесь" %}</div>
<div class="modal_description">{% trans "Чтобы увидеть контакты - войдите в свою учетную запись или зарегистрируйтесь" %}</div>
<a class="primary_btn" href="{% url "login_profile" %}">{% trans "Войти" %}</a>
<a class="registr_btn" href="{% url "registration_page" %}">{% trans "Зарегестрироватся" %}</a>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,19 @@
{% load static %}
{% load i18n %}
<div class="b_my_routes">
{% for route in routes %}
{% include 'v2/widgets/w_route_card.html' with route=route %}
{% endfor %}
</div>
{% if not last_block %}
<div class="container_btns" data-next_page_btn="true" style="--justify: center;margin-top: 20px">
<div class="primary_btn"
onclick="loadMoreMyRoutesRoutes(this)"
style="--padding: 19px 34px 21px 34px"
data-from_el="{{ last_el }}"
data-more_count="{{ next_page_els_count }}">
{% trans "Показать ещё" %} {{ next_page_els_count }}
</div>
</div>
{% endif %}

View File

@@ -0,0 +1,36 @@
{% load static %}
{% load i18n %}
<link rel="stylesheet" href="{% static "v2/css/blocks/b_search_routes.css" %}">
<div class="b_search_routes">
<form name="search_routes" onsubmit="searchRoutes(this)">
<div class="field_container" data-type="location" data-name="from_city">
<label for="id_from_city">
{% if owner_type == 'mover' %}
{% trans "Выезжает из" %}
{% else %}
{% trans "Забрать из" %}
{% endif %}
</label>
{% include 'v2/widgets/w_select_country.html' with name='from_city' placeholder='' initial=form.initial.from_city %}
{% if form.errors.from_city %}<div class="error_container">{{ form.errors.from_city.0 }}</div>{% endif %}
</div>
<div class="field_container" data-type="location" data-name="to_city">
<label for="id_from_city">
{% if owner_type == 'mover' %}
{% trans "Прибывает в" %}
{% else %}
{% trans "Доставить в" %}
{% endif %}
</label>
{% include 'v2/widgets/w_select_country.html' with name='to_city' placeholder='' initial=form.initial.to_city %}
{% if form.errors.to_city %}<div class="error_container">{{ form.errors.to_city.0 }}</div>{% endif %}
</div>
<div class="field_container" data-type="date" data-name="arrival_DT">
<label for="id_arrival_DT">{% trans "Дата (период) доставки" %}</label>
{% include 'v2/widgets/w_daterangepicker.html' with set_min_date='false' name='arrival_DT' range='true' initial=form.initial.arrival_DT %}
{% if form.errors.arrival_DT %}<div class="error_container">{{ form.errors.arrival_DT.0 }}</div>{% endif %}
</div>
<button type="submit">{% trans "Найти посылку" %}</button>
</form>
</div>

View File

@@ -0,0 +1,18 @@
{% load static %}
{% load i18n %}
<div class="routes_cont">
{% for route in routes %}
{% include "v2/widgets/w_route_card_for_search.html" %}
{% endfor %}
</div>
{% if not last_block %}
<div class="container_btns" data-next_page_btn="true" style="--justify: center;margin-top: 20px">
<div class="primary_btn"
onclick="loadMoreRoutes(this)"
style="--padding: 19px 34px 21px 34px"
data-from_el="{{ last_el }}"
data-more_count="{{ next_page_els_count }}">
{% trans "Показать ещё" %} {{ next_page_els_count }}
</div>
</div>
{% endif %}

View File

@@ -1,7 +1,8 @@
{% load static %}
{% load i18n %}
{% load routes_tags %}
<div class="cw_w_radio_inputs_radio_input" data-name="{{ item.0 }}">
<div class="radio{% if item.0 == initial %} checked{% endif %}" onclick="chooseRadioInput(this)"></div>
<div class="radio_label" onclick="chooseRadioInput(this)">{{ item.1 }}</div>
<div class="radio{% if item.0 == initial %} checked{% endif %}" onclick="chooseRadioInput(this, {{ callback }})"></div>
<div class="radio_label" onclick="chooseRadioInput(this, {{ callback }})">{{ item.1|get_splited_cargo_type|safe }}</div>
</div>

View File

@@ -1,10 +1,11 @@
{% load static %}
{% load i18n %}
{% load reference_data_tags %}
<div class="cw_w_select_widget_for_select" data-id="{{ id }}" data-name="{{ name }}/{{ country__name }}" data-country_code="{{ country__short_code }}" data-flag="{{ MEDIA_URL }}{{ country__flag }}" onclick="selectCountry(this)">
<div class="cw_w_select_widget_for_select" data-id="{{ id }}" data-name="{{ name }}/{{ country__name }}" data-country_code="{{ country__code }}" data-flag="{{ MEDIA_URL }}{{ country__flag }}" onclick="selectCountry(this)" data-now="{{ timezone|get_cur_DT_by_tz }}">
<div class="cw_country_inf_part">
<img src="{{ MEDIA_URL }}{{ country__flag }}" alt="">
<div class="cw_country_code">{{ country__short_code }}</div>
<div class="cw_country_code">{{ country__code }}</div>
</div>
<div class="cw_name_country">{{ name }}/{{ country__name }}</div>
</div>

View File

@@ -0,0 +1,39 @@
{% load static %}
{% load i18n %}
<div class="route_card_actions_container">
<div class="delete_route" onclick="deleteRoute(this)">{% trans "Удалить" %}</div>
<div class="right_part_action_btns">
<div class="route_btn" data-actions_count="{{ remains_route_rising_count }}" data-action="raise" onclick="raiseRoute(this)">
<div class="route_btn_title">{% trans "Поднять" %}</div>
<div class="route_btn_data">Осталось поднятий: {{ remains_route_rising_count }}</div>
</div>
<div class="route_btn" data-actions_count="{{ remains_route_highlight_count }}" data-action="highlight" onclick="highlightRoute(this)">
<div class="route_btn_title">{% trans "Выделить цветом" %}</div>
<div class="route_btn_data">Осталось выделений: {{ remains_route_highlight_count }}</div>
</div>
<div class="route_btn solid" data-action="change" onclick="changeRoute(this)">
<div class="route_btn_title">{% trans "Редактировать" %}</div>
</div>
</div>
</div>
<a class="route_btn mobile inactive" {% if now_DT <= route.arrival_DT %}href="tel:{{ route.phone }}"{% endif %} style="--route-btn-width: auto;--route-btn-height: min-content;--route-btn-padding: 7.5px 11px;--route-btn-margin: 20.5px 0 0 0;">
<img src="{% static "v2/icons/widgets/w_route_card/phone_half_opacity.svg" %}" alt="">
<div class="route_btn_title big">{{ route.phone }}</div>
</a>
<div class="route_card_actions_container mobile">
<div class="route_btn solid" style="--route-btn-width: auto;" data-action="change" onclick="changeRoute(this)">
<div class="route_btn_title">{% trans "Редактировать" %}</div>
</div>
<div class="container_actions_mobile">
<div class="route_btn" data-actions_count="{{ remains_route_rising_count }}" style="--route-btn-height: fit-content;--route-btn-width: auto;" data-action="raise" onclick="raiseRoute(this)">
<div class="route_btn_title">{% trans "Поднять" %}</div>
<div class="route_btn_data">Осталось поднятий: {{ remains_route_rising_count }}</div>
</div>
<div class="route_btn" data-actions_count="{{ remains_route_highlight_count }}" style="--route-btn-height: fit-content;--route-btn-width: auto;" data-action="highlight" onclick="highlightRoute(this)">
<div class="route_btn_title">{% trans "Выделить цветом" %}</div>
<div class="route_btn_data">Осталось выделений: {{ remains_route_highlight_count }}</div>
</div>
</div>
<div class="delete_route" onclick="deleteRoute(this)">{% trans "Удалить" %}</div>
</div>

View File

@@ -0,0 +1,21 @@
{% load static %}
{% load i18n %}
<div class="respond_route_cont mobile" style="display: none;margin-top: 23px;">
<div class="route_btn unhovered" style="--route-btn-height: min-content;--route-btn-padding: 7.5px 11px;">
<img src="{% static "v2/icons/widgets/w_route_card/phone.svg" %}" alt="">
<a {% if now_DT <= route.arrival_DT %}href="tel:{{ route.phone }}"{% endif %} class="route_btn_title big">
{% if route.phone %}
{{ route.phone|truncatechars:20 }}
{% else %}
{% trans "Номер не указан" %}
{% endif %}
</a>
</div>
<div class="chat_btn">
<img src="{% static "v2/icons/widgets/w_route_card/chat.png" %}" alt="">
</div>
</div>
<div class="route_btn mobile solid" onclick="respondBtnClickEvent(this, '{{ user.is_authenticated }}')" style="--route-btn-margin: 23px 0 0 0;--route-btn-width: 100%;--route-btn-height: min-content;--route-btn-padding: 7.5px 0;">
<div class="route_btn_title big">{% trans "Откликнуться" %}</div>
</div>

View File

@@ -0,0 +1,47 @@
{% load static %}
{% load i18n %}
{% load routes_tags %}
<div class="route_card_info_data">
<img class="route_card_text_img" src="{% static "v2/icons/widgets/w_route_card/route_card_avatar_spline.svg" %}">
<img class="route_card_owner_avatar" src="{% if route.owner.user_profile.avatar %}{{ route.owner.user_profile.avatar.url }}{% else %}{% static "v2/icons/widgets/w_route_card/avatar.png" %}{% endif %}">
<div class="route_card_owner_info">
<div class="route_card_info_left_part">
<div class="card_owner_name">{{ route.owner }}</div>
<div class="card_splitter"></div>
<div class="card_owner_type {{ route.owner_type }}">{% if route.owner_type == 'customer' %}{% trans "Нужен перевозчик" %}{% else %}{% trans "Могу перевезти" %}{% endif %}</div>
<div class="card_cargo_type">{% trans "Тип посылки:" %} <div class="orange">{{ route.cargo_type|get_cargo_type_for_show }}</div></div>
</div>
<a class="route_btn inactive" {% if now_DT <= route.arrival_DT %}href="tel:{{ route.phone }}"{% endif %} style="--route-btn-width: max-content;--route-btn-height: min-content;--route-btn-padding: 7.5px 11px;max-width: 155px;">
<img src="{% static "v2/icons/widgets/w_route_card/phone_half_opacity.svg" %}" alt="">
<div class="route_btn_title big">{{ route.phone }}</div>
</a>
</div>
<div class="route_card_text_container">
{% if route.comment %}
{{ route.comment|linebreaksbr }}
{% else %}
{% trans "Комментарий отсутствует" %}
{% endif %}
</div>
<div class="route_number">{% trans "Объявление №" %} {{ route.id }}</div>
</div>
<div class="route_card_info_data mobile">
<img class="route_card_text_img" src="{% static "v2/icons/widgets/w_route_card/route_card_avatar_spline.svg" %}">
<img class="route_card_owner_avatar" src="{% if route.owner.user_profile.avatar %}{{ route.owner.user_profile.avatar.url }}{% endif %}">
<div class="route_card_owner_info">
<div class="route_card_info_left_part">
<div class="card_owner_type {{ route.owner_type }}">{% if route.owner_type == 'customer' %}{% trans "Нужен перевозчик" %}{% else %}{% trans "Могу перевезти" %}{% endif %}</div>
<div class="card_cargo_type">{% trans "Тип посылки:" %} <div class="orange">{{ route.cargo_type|get_cargo_type_for_show }}</div></div>
</div>
</div>
<div class="card_owner_name">{{ route.owner }}</div>
<div class="route_card_text_container">
{% if route.comment %}
{{ route.comment|linebreaksbr }}
{% else %}
{% trans "Комментарий отсутствует" %}
{% endif %}
</div>
<div class="route_number">{% trans "Объявление №" %} {{ route.id }}</div>
</div>

View File

@@ -0,0 +1,87 @@
{% load static %}
{% load i18n %}
{% load routes_tags %}
<div class="route_card_info_data">
<img class="route_card_text_img" src="{% static "v2/icons/widgets/w_route_card/route_card_avatar_spline.svg" %}">
<img class="route_card_owner_avatar" src="{% if route.owner.user_profile.avatar %}{{ route.owner.user_profile.avatar.url }}{% else %}{% static "v2/icons/widgets/w_route_card/avatar.png" %}{% endif %}">
<div class="route_card_owner_info">
<div class="route_card_info_left_part">
<div class="card_owner_name">{{ route.owner }}</div>
<div class="card_splitter"></div>
<div class="card_owner_type {{ route.owner_type }}">{% if route.owner_type == 'customer' %}{% trans "Нужен перевозчик" %}{% else %}{% trans "Могу перевезти" %}{% endif %}</div>
<div class="card_cargo_type">{% trans "Тип посылки:" %} <div class="orange">{{ route.cargo_type|get_cargo_type_for_show }}</div></div>
</div>
<div class="respond_route_cont" style="display: none;">
<div class="route_btn unhovered" style="--route-btn-width: max-content;--route-btn-height: min-content;--route-btn-padding: 7.5px 11px;">
<img src="{% static "v2/icons/widgets/w_route_card/phone.svg" %}" alt="">
<a class="route_btn_title big" {% if now_DT <= route.arrival_DT %}href="tel:{{ route.phone }}"{% endif %}>
{% if route.phone %}
{{ route.phone|truncatechars:20 }}
{% else %}
{% trans "Номер не указан" %}
{% endif %}
</a>
</div>
<div class="chat_btn">
<img src="{% static "v2/icons/widgets/w_route_card/chat.png" %}" alt="">
</div>
</div>
<div class="route_btn hide_in_mobile solid" onclick="respondBtnClickEvent(this, '{{ user.is_authenticated }}')" style="--route-btn-width: max-content;--route-btn-height: min-content;--route-btn-padding: 7.5px 38.5px;">
<div class="route_btn_title big">{% trans "Откликнуться" %}</div>
</div>
</div>
<div class="route_card_text_container wrapped{% if not user.is_authenticated %} msg{% endif %}" onclick="unwrapRouteComment(this)">
<div class="route_card_text_container_txt">
{% if route.comment %}
{{ route.comment|linebreaksbr }}
{% else %}
{% trans "Комментарий отсутствует" %}
{% endif %}
</div>
{% if not user.is_authenticated %}
<div class="route_msg_for_unregistered_user" onclick="clickedUnregisteredMsgRoute(this)">
<img src="{% static "v2/icons/widgets/w_route_card/unregistered.svg" %}" alt="">
<div>{% trans "Текст сообщения доступен только авторизированным пользователям." %}</div>
</div>
<div class="route_clicked_msg_for_unregistered_user">
<img src="{% static "v2/icons/widgets/w_route_card/lock.png" %}" alt="">
<div>{% trans "Текст сообщения доступен только авторизированным пользователям." %}</div>
<a class="default_btn" href="{% url "login_profile" %}">{% trans "Войти" %}</a>
</div>
{% endif %}
</div>
<div class="route_number">{% trans "Объявление №" %} {{ route.id }}</div>
</div>
<div class="route_card_info_data mobile">
<img class="route_card_text_img" src="{% static "v2/icons/widgets/w_route_card/route_card_avatar_spline.svg" %}">
<img class="route_card_owner_avatar" src="{% if route.owner.user_profile.avatar %}{{ route.owner.user_profile.avatar.url }}{% endif %}">
<div class="route_card_owner_info">
<div class="route_card_info_left_part">
<div class="card_owner_type {{ route.owner_type }}">{% if route.owner_type == 'customer' %}{% trans "Нужен перевозчик" %}{% else %}{% trans "Могу перевезти" %}{% endif %}</div>
<div class="card_cargo_type">{% trans "Тип посылки:" %} <div class="orange">{{ route.cargo_type|get_cargo_type_for_show }}</div></div>
</div>
</div>
<div class="card_owner_name">{{ route.owner }}</div>
<div class="route_card_text_container wrapped{% if not user.is_authenticated %} msg{% endif %}" onclick="unwrapRouteComment(this)">
<div class="route_card_text_container_txt">
{% if route.comment %}
{{ route.comment|linebreaksbr }}
{% else %}
{% trans "Комментарий отсутствует" %}
{% endif %}
</div>
{% if not user.is_authenticated %}
<div class="route_msg_for_unregistered_user" onclick="clickedUnregisteredMsgRoute(this)">
<img src="{% static "v2/icons/widgets/w_route_card/unregistered.svg" %}" alt="">
<div>{% trans "Текст сообщения доступен только авторизированным пользователям." %}</div>
</div>
<div class="route_clicked_msg_for_unregistered_user">
<img src="{% static "v2/icons/widgets/w_route_card/lock.png" %}" alt="">
<div>{% trans "Текст сообщения доступен только авторизированным пользователям." %}</div>
<a class="default_btn" href="{% url "login_profile" %}">{% trans "Войти" %}</a>
</div>
{% endif %}
</div>
<div class="route_number">{% trans "Объявление №" %} {{ route.id }}</div>
</div>

View File

@@ -0,0 +1,137 @@
{% load static %}
{% load i18n %}
{% load routes_tags %}
<div class="route_card_route_data_cont">
<div class="route_card_route_data">
<div class="from_to_place_data">
<div class="label departure_from">{% if route.owner_type == 'mover' %}{% trans "Выезжаю из:" %}{% else %}{% trans "Забрать из:" %}{% endif %}</div>
<div class="place">
<div class="country">
<img src="{{ route.from_city.country.flag.url }}" alt="">
<div class="country_code">{{ route.from_city.country.code }}</div>
</div>
<div class="place_title{% if route.from_city.name|length > 14 %} gradient{% endif %}">
{{ route.from_city.name }}
</div>
</div>
</div>
<div class="route_way_data">
<div class="route_transport">
<div class="route_transport_name">{{ route.type_transport|get_type_transport_for_show }}</div>
{% if route.type_transport == '' %}
<img src="{% static "v2/icons/widgets/w_route_card/plane.svg" %}" alt="">
<img src="{% static "v2/icons/widgets/w_route_card/car.svg" %}" alt="">
{% elif route.type_transport == 'road' %}
<img src="{% static "v2/icons/widgets/w_route_card/car.svg" %}" alt="">
{% elif route.type_transport == 'avia' %}
<img src="{% static "v2/icons/widgets/w_route_card/plane.svg" %}" alt="">
{% endif %}
</div>
<div class="way_progress_line_container">
<div class="way_progress_round"></div>
<div class="way_progress_line"></div>
<div class="way_progress_arrows_line"></div>
<div class="way_progress_round"></div>
</div>
{% if route.owner_type == 'customer' %}
<div class="route_date_data">
{% trans "Дата доставки:" %}
<div class="date_data_value">{{ route.arrival_DT|date:'j E Y' }}</div>
</div>
{% endif %}
</div>
<div class="from_to_place_data">
<div class="label arrival_to">{% if route.owner_type == 'mover' %}{% trans "Прибываю в:" %}{% else %}{% trans "Доставить в:" %}{% endif %}</div>
<div class="place">
<div class="country">
<img src="{{ route.to_city.country.flag.url }}" alt="">
<div class="country_code">{{ route.to_city.country.code }}</div>
</div>
<div class="place_title{% if route.to_city.name|length > 14 %} gradient{% endif %}">
{{ route.to_city.name }}
</div>
</div>
</div>
</div>
<div class="dates_inf_cont">
{% if route.owner_type == 'mover' %}
<div class="route_date_data" style="--route-date-data-justify: left;--route-date-data-margin: 10px 0 0 0;">
{% trans "Отправка:" %}
<div class="date_data_value">{{ route.departure_DT|date:'j E Y' }}</div>
</div>
{% endif %}
{% if route.owner_type == 'mover' %}
<div class="route_date_data {% if route.to_city.name|length > 14 %} gradient{% endif %}" style="--route-date-data-justify: right;--route-date-data-margin: 10px 0 0 0;">
{% trans "Прибытие:" %}
<div class="date_data_value">{{ route.arrival_DT|date:'j E Y' }}</div>
</div>
{% endif %}
</div>
</div>
<div class="route_card_route_data_cont mobile">
<div class="route_card_route_data">
<div class="way_progress_line_container mobile">
<div class="way_progress_round"></div>
<div class="way_progress_line"></div>
<div class="way_progress_arrows_line"></div>
<div class="way_progress_round"></div>
</div>
<div class="right_part_route_card">
<div class="from_to_place_data">
<div class="label departure_from">{% if route.owner_type == 'mover' %}{% trans "Выезжаю из:" %}{% else %}{% trans "Забрать из:" %}{% endif %}</div>
<div class="place">
<div class="country">
<img src="{{ route.from_city.country.flag.url }}" alt="">
<div class="country_code">{{ route.from_city.country.code }}</div>
</div>
<div class="place_title gradient">
{{ route.from_city.name }}
</div>
</div>
</div>
<div class="route_way_data">
<div class="route_transport">
<div class="route_transport_name">{{ route.type_transport|get_type_transport_for_show }}</div>
{% if route.type_transport == '' %}
<img src="{% static "v2/icons/widgets/w_route_card/plane.svg" %}" alt="">
<img src="{% static "v2/icons/widgets/w_route_card/car.svg" %}" alt="">
{% elif route.type_transport == 'road' %}
<img src="{% static "v2/icons/widgets/w_route_card/car.svg" %}" alt="">
{% elif route.type_transport == 'avia' %}
<img src="{% static "v2/icons/widgets/w_route_card/plane.svg" %}" alt="">
{% endif %}
</div>
<div class="route_date_splitter"></div>
{% if route.owner_type == 'customer' %}
<div class="route_date_data">
{% trans "Дата доставки:" %}
<div class="date_data_value">{{ route.arrival_DT|date:'j E Y' }}</div>
</div>
{% else %}
<div class="route_date_data">
{% trans "Отправка:" %}
<div class="date_data_value">{{ route.departure_DT|date:'j E Y' }}</div>
</div>
<div class="route_date_data">
{% trans "Прибытие:" %}
<div class="date_data_value">{{ route.arrival_DT|date:'j E Y' }}</div>
</div>
{% endif %}
</div>
<div class="from_to_place_data">
<div class="label arrival_to">{% if route.owner_type == 'mover' %}{% trans "Прибываю в:" %}{% else %}{% trans "Доставить в:" %}{% endif %}</div>
<div class="place">
<div class="country">
<img src="{{ route.to_city.country.flag.url }}" alt="">
<div class="country_code">{{ route.to_city.country.code }}</div>
</div>
<div class="place_title gradient">
{{ route.to_city.name }}
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -1,24 +1,33 @@
{% load static %}
{% load i18n %}
<form name="make_poster_order" class="f_make_poster_order">
{% trans "Укажите город" as placeholder_for_city %}
<form name="make_poster_order" {% if form.instance.id %}data-route_id="{{ form.instance.id }}"{% endif %} class="f_make_poster_order" data-owner_type="customer">
<div class="form_line">
<div class="field_container" data-type="radio" data-name="type_transport">
{% trans "Обязательно учитывайте Правила и особенности перевозки выбранным Вами видом транспорта" as attention_type_transport %}
<label for="id_cargo_type"><div class="required_field_icon">*</div> {% trans "Каким способом Вы хотите отправить?" %}</label>
{% include 'v2/widgets/w_radio_inputs.html' with name='type_transport' callback='updateCargoTypeInForm' list=form.fields.type_transport.choices initial=form.initial.type_transport %}
{% if form.errors.type_transport %}<div class="error_container">{{ form.errors.type_transport.0 }}</div>{% endif %}
{% include 'v2/widgets/w_pay_attention.html' with text=attention_type_transport %}
</div>
</div>
{% trans "Укажите город" as placeholder_for_city %}
<div class="form_line _50_grid">
<div class="field_container" data-type="location" data-name="from_city">
<label for="id_from_city"><div class="required_field_icon">*</div> {% trans "Откуда забрать посылку" %}</label>
{% include 'v2/widgets/w_select_country.html' with name='from_city' placeholder=placeholder_for_city initial=form.initial.from_city %}
{% include 'v2/widgets/w_select_country.html' with name='from_city' placeholder=placeholder_for_city initial=form.instance.from_city %}
{% if form.errors.from_city %}<div class="error_container">{{ form.errors.from_city.0 }}</div>{% endif %}
</div>
<div class="field_container" data-type="location" data-name="to_city">
<div class="field_container" data-type="location" data-name="to_city" data-datepicker="arrival_DT">
<label for="id_from_city"><div class="required_field_icon">*</div> {% trans "Куда доставить посылку" %}</label>
{% include 'v2/widgets/w_select_country.html' with name='to_city' placeholder=placeholder_for_city initial=form.initial.to_city %}
{% include 'v2/widgets/w_select_country.html' with name='to_city' placeholder=placeholder_for_city initial=form.instance.to_city %}
{% if form.errors.to_city %}<div class="error_container">{{ form.errors.to_city.0 }}</div>{% endif %}
</div>
</div>
<div class="form_line">
<div class="field_container" data-type="radio" data-name="cargo_type">
<label for="id_cargo_type"><div class="required_field_icon">*</div> {% trans "Каким способом Вы хотите отправить?" %}</label>
<label for="id_cargo_type"><div class="required_field_icon">*</div> {% trans "Выберите кого (что) отправить" %}</label>
{% include 'v2/widgets/w_radio_inputs.html' with name='cargo_type' list=form.fields.cargo_type.choices initial=form.initial.cargo_type %}
{% if form.errors.cargo_type %}<div class="error_container">{{ form.errors.cargo_type.0 }}</div>{% endif %}
</div>
@@ -26,26 +35,17 @@
<div class="form_line _50_grid">
<div class="field_container" data-type="date" data-name="arrival_DT">
<label for="id_arrival_DT"><div class="required_field_icon">*</div> {% trans "Дата доставки посылки" %}</label>
{% include 'v2/widgets/w_daterangepicker.html' with name='arrival_DT' initial=form.initial.arrival_DT %}
{% include 'v2/widgets/w_daterangepicker.html' with set_min_date='true' name='arrival_DT' initial=form.initial.arrival_DT %}
{% if form.errors.arrival_DT %}<div class="error_container">{{ form.errors.arrival_DT.0 }}</div>{% endif %}
</div>
</div>
<div class="form_line">
<div class="field_container" data-type="radio" data-name="type_transport">
{% trans "Обязательно учитывайте Правила и особенности перевозки выбранным Вами видом транспорта" as attention_type_transport %}
<label for="id_cargo_type"><div class="required_field_icon">*</div> {% trans "Каким способом Вы хотите отправить?" %}</label>
{% include 'v2/widgets/w_radio_inputs.html' with name='type_transport' list=form.fields.type_transport.choices initial=form.initial.type_transport %}
{% include 'v2/widgets/w_pay_attention.html' with text=attention_type_transport %}
{% if form.errors.type_transport %}<div class="error_container">{{ form.errors.type_transport.0 }}</div>{% endif %}
</div>
</div>
<div class="form_line">
<div class="field_container" data-type="input" style="width: 100%" data-name="phone">
{% trans "Если вы оставите это поле пустым - перевозчики смогут только написать вам в личные сообщения на нашем сайте TripWB.com" as attention_phone %}
<label for="id_cargo_type">{% trans "Контактный номер телефона, по которому с Вами могут связаться перевозчики" %}</label>
<input class="half" style="height: unset;" type="text" name="phone" id="id_phone" placeholder="{% trans 'Укажите телефон' %}"{% if form.initial.phone %} value="{{ form.initial.phone }}" {% endif %}>
{% include 'v2/widgets/w_pay_attention.html' with text=attention_phone %}
<input class="half" style="height: unset;" type="text" name="phone" id="id_phone" placeholder="{% trans 'Укажите телефон' %}"{% if form.initial.phone %} value="{{ form.initial.phone }}" {% endif %} oninput="resetFieldError(this);">
{% if form.errors.phone %}<div class="error_container">{{ form.errors.phone.0 }}</div>{% endif %}
{% include 'v2/widgets/w_pay_attention.html' with text=attention_phone %}
</div>
</div>
<div class="form_line">
@@ -60,8 +60,8 @@
<div class="field_container line" data-type="checkbox" data-name="receive_msg_by_email">
<div class="checkbox{% if form.initial.receive_msg_by_email %} checked{% endif %}" onclick="chooseCheckbox(this)"></div>
<div class="checkbox_label" onclick="chooseCheckbox(this)">{% trans "Хочу получать уведомления на E-mail о появлении перевозчика по моим критериям" %}</div>
{% include 'v2/widgets/w_additional_info.html' %}
{% if form.errors.receive_msg_by_email %}<div class="error_container">{{ form.errors.receive_msg_by_email.0 }}</div>{% endif %}
{% include 'v2/widgets/w_additional_info.html' %}
</div>
</div>

View File

@@ -1,41 +1,41 @@
{% load static %}
{% load i18n %}
<form name="make_mover_order" class="f_make_poster_order">
<form name="make_mover_order" class="f_make_poster_order" {% if form.instance.id %}data-route_id="{{ form.instance.id }}"{% endif %} data-owner_type="mover">
<div class="form_line">
<div class="field_container" data-type="radio" data-name="type_transport">
{% trans "Обязательно учитывайте Правила и особенности перевозки выбранным Вами видом транспорта" as attention_type_transport %}
<label for="id_cargo_type"><div class="required_field_icon">*</div> {% trans "Укажите способ, которым вы можете перевезти" %}</label>
{% include 'v2/widgets/w_radio_inputs.html' with name='type_transport' list=form.fields.type_transport.choices initial=form.initial.type_transport %}
{% include 'v2/widgets/w_pay_attention.html' with text=attention_type_transport %}
{% include 'v2/widgets/w_radio_inputs.html' with name='type_transport' callback='updateCargoTypeInForm' list=form.fields.type_transport.choices initial=form.initial.type_transport %}
{% if form.errors.type_transport %}<div class="error_container">{{ form.errors.type_transport.0 }}</div>{% endif %}
{% include 'v2/widgets/w_pay_attention.html' with text=attention_type_transport %}
</div>
</div>
{% trans "Укажите город" as placeholder_for_city %}
<div class="form_line _50_grid">
<div class="field_container" data-type="location" data-name="from_city">
<div class="field_container" data-type="location" data-name="from_city" data-datepicker="departure_DT">
<label for="id_from_city"><div class="required_field_icon">*</div> {% trans "Пункт отправления" %}</label>
{% include 'v2/widgets/w_select_country.html' with name='from_city' placeholder=placeholder_for_city initial=form.initial.from_city %}
{% include 'v2/widgets/w_select_country.html' with name='from_city' placeholder=placeholder_for_city initial=form.instance.from_city %}
{% if form.errors.from_city %}<div class="error_container">{{ form.errors.from_city.0 }}</div>{% endif %}
</div>
<div class="field_container" data-type="location" data-name="to_city">
<div class="field_container" data-type="location" data-name="to_city" data-datepicker="arrival_DT">
<label for="id_from_city"><div class="required_field_icon">*</div> {% trans "Пункт прибытия" %}</label>
{% include 'v2/widgets/w_select_country.html' with name='to_city' placeholder=placeholder_for_city initial=form.initial.to_city %}
{% include 'v2/widgets/w_select_country.html' with name='to_city' placeholder=placeholder_for_city initial=form.instance.to_city %}
{% if form.errors.to_city %}<div class="error_container">{{ form.errors.to_city.0 }}</div>{% endif %}
</div>
</div>
<div class="form_line _50_grid">
<div class="field_container" data-type="date" data-name="arrival_DT">
<label for="id_arrival_DT"><div class="required_field_icon">*</div> {% trans "Дата доставки посылки" %}</label>
{% include 'v2/widgets/w_daterangepicker.html' with name='arrival_DT' initial=form.initial.arrival_DT %}
{% if form.errors.arrival_DT %}<div class="error_container">{{ form.errors.arrival_DT.0 }}</div>{% endif %}
</div>
<div class="field_container" data-type="date" data-name="departure_DT">
<label for="id_arrival_DT"><div class="required_field_icon">*</div> {% trans "Дата доставки посылки" %}</label>
{% include 'v2/widgets/w_daterangepicker.html' with name='departure_DT' initial=form.initial.departure_DT %}
<label for="id_departure_DT"><div class="required_field_icon">*</div> {% trans "Дата отправления" %}</label>
{% include 'v2/widgets/w_daterangepicker.html' with set_min_date='true' name='departure_DT' initial=form.initial.departure_DT %}
{% if form.errors.departure_DT %}<div class="error_container">{{ form.errors.departure_DT.0 }}</div>{% endif %}
</div>
<div class="field_container" data-type="date" data-name="arrival_DT">
<label for="id_arrival_DT"><div class="required_field_icon">*</div> {% trans "Дата прибытия" %}</label>
{% include 'v2/widgets/w_daterangepicker.html' with set_min_date='true' name='arrival_DT' initial=form.initial.arrival_DT %}
{% if form.errors.arrival_DT %}<div class="error_container">{{ form.errors.arrival_DT.0 }}</div>{% endif %}
</div>
</div>
<div class="form_line">
<div class="field_container" data-type="radio" data-name="cargo_type">
@@ -46,11 +46,11 @@
</div>
<div class="form_line">
<div class="field_container" data-type="input" style="width: 100%" data-name="phone">
{% trans "Если вы оставите это поле пустым - перевозчики смогут только написать вам в личные сообщения на нашем сайте TripWB.com" as attention_phone %}
<label for="id_cargo_type">{% trans "Контактный номер телефона, по которому с Вами могут связаться перевозчики" %}</label>
<input class="half" style="height: unset;" type="text" name="phone" id="id_phone" placeholder="{% trans 'Укажите телефон' %}"{% if form.initial.phone %} value="{{ form.initial.phone }}" {% endif %}>
{% include 'v2/widgets/w_pay_attention.html' with text=attention_phone %}
{% trans "Если вы оставите это поле пустым - отправители смогут только написать вам в личные сообщения на нашем сайте TripWB.com" as attention_phone %}
<label for="id_cargo_type">{% trans "Контактный номер телефона, по которому с Вами могут связаться отправители" %}</label>
<input class="half" style="height: unset;" type="text" name="phone" id="id_phone" placeholder="{% trans 'Укажите телефон' %}"{% if form.initial.phone %} value="{{ form.initial.phone }}" {% endif %} oninput="resetFieldError(this);">
{% if form.errors.phone %}<div class="error_container">{{ form.errors.phone.0 }}</div>{% endif %}
{% include 'v2/widgets/w_pay_attention.html' with text=attention_phone %}
</div>
</div>
<div class="form_line">
@@ -64,9 +64,9 @@
<div class="form_line">
<div class="field_container line" data-type="checkbox" data-name="receive_msg_by_email">
<div class="checkbox{% if form.initial.receive_msg_by_email %} checked{% endif %}" onclick="chooseCheckbox(this)"></div>
<div class="checkbox_label" onclick="chooseCheckbox(this)">{% trans "Хочу получать уведомления на E-mail о появлении перевозчика по моим критериям" %}</div>
{% include 'v2/widgets/w_additional_info.html' %}
<div class="checkbox_label" onclick="chooseCheckbox(this)">{% trans "Хочу получать уведомления на E-mail о появлении отправителя по моим критериям" %}</div>
{% if form.errors.receive_msg_by_email %}<div class="error_container">{{ form.errors.receive_msg_by_email.0 }}</div>{% endif %}
{% include 'v2/widgets/w_additional_info.html' %}
</div>
</div>

View File

@@ -0,0 +1,32 @@
{% extends "tb_base.html" %}
{% load static %}
{% load i18n %}
{% block meta %}
<link rel="stylesheet" href="{% static "v2/css/forms.css" %}">
<link rel="stylesheet" href="{% static "v2/css/widgets/w_select_country.css" %}">
<link rel="stylesheet" href="{% static "v2/css/widgets/w_datarangepicker.css" %}">
<link rel="stylesheet" href="{% static "v2/css/pages/p_search_route_results.css" %}">
<link rel="stylesheet" href="{% static "v2/css/widgets/w_route_card.css" %}">
<script src="{% static "v2/js/forms.js" %}"></script>
<script src="{% static "v2/js/widgets/w_select_country.js" %}"></script>
<script src="{% static "v2/js/widgets/w_daterangepicker.js" %}"></script>
<script src="{% static "v2/js/blocks/b_search_routes.js" %}"></script>
<script src="{% static "v2/js/widgets/w_route_card.js" %}"></script>
<script src="{% static "v2/js/pages/p_search_route_results.js" %}"></script>
<script src="{% static "v2/js/blocks/b_filter_routes.js" %}"></script>
{% endblock %}
{% block content %}
<div class="title">{% trans "Поиск посылки" %}</div>
{% include 'v2/blocks/b_search_routes.html' %}
{% if not user.is_authenticated %}{% include 'v2/blocks/b_login_modal.html' %}{% endif %}
{# {% include 'v2/blocks/b_chat_modal.html' %}#}
<div class="routes_content_part">
{% include "v2/blocks/b_filter_routes.html" %}
<div class="routes_search_results">
{% include "v2/blocks/b_search_routes_result.html" %}
</div>
</div>
{% include 'v2/blocks/b_dont_found_anth.html' %}
{% endblock %}

View File

@@ -2,7 +2,7 @@
{% load i18n %}
<div class="additional_info">
<img src="{% static "v2/icons/widgets/w_additional_info/info.svg" %}" alt="">
<img src="{% static "v2/icons/widgets/w_additional_info/Info.svg" %}" alt="">
<div class="additional_info_modal">
asd
</div>

View File

@@ -1,9 +1,9 @@
{% load static %}
{% load i18n %}
<div class="w_daterangepicker">
<div class="w_daterangepicker" onclick="selectInputWContainer(this)">
<div class="date_range_input_cont">
<input class="dropped" type="text" name="{{ name }}" id="id_{{ name }}" autocomplete="off"{% if initial %} value="{{ initial|date:'d.m.Y' }}"{% endif %}>
<input class="dropped" data-set_min_date="{{ set_min_date }}" {% if range %}data-range="{{ range }}"{% endif %} type="text" name="{{ name }}" id="id_{{ name }}" autocomplete="off"{% if initial and not range %} value="{{ initial|date:'d.m.Y' }}"{% else %} value="{{ initial }}"{% endif %}>
<img onclick="clickOnDateIconE(this)" src="{% static "v2/icons/widgets/w_datarangepicker/datarangepicker_icon.svg" %}" alt="">
</div>
</div>

View File

@@ -0,0 +1,8 @@
{% load i18n %}
{% load static %}
<div class="w_customer_route_card w_route_card{% if route.is_highlighted_now %} highlighted{% endif %}{% if now_DT > route.arrival_DT %} disabled{% endif %}" data-route_id="{{ route.id }}" data-owner_type="{{ route.owner_type }}">
{% include 'v2/content_widgets/w_route_card/route_card_info_data.html' %}
{% include 'v2/content_widgets/w_route_card/route_card_route_data.html' %}
{% include 'v2/content_widgets/w_route_card/route_card_actions_container.html' %}
</div>

View File

@@ -0,0 +1,8 @@
{% load i18n %}
{% load static %}
<div class="w_customer_route_card w_route_card{% if route.is_highlighted_now %} highlighted{% endif %}{% if now_DT > route.arrival_DT %} disabled{% endif %}" data-route_id="{{ route.id }}" data-owner_type="{{ route.owner_type }}">
{% include 'v2/content_widgets/w_route_card/route_card_info_data_for_search.html' %}
{% include 'v2/content_widgets/w_route_card/route_card_route_data.html' %}
{% include 'v2/content_widgets/w_route_card/route_card_actions_container_for_search.html' %}
</div>

View File

@@ -2,13 +2,13 @@
{% load i18n %}
<div class="w_select_country closed">
<div class="w_select_country_header" onclick="openCountruSelectIfDataEnter(this)">
<div class="w_select_country_header" onclick="selectInputWContainer(this, openCountruSelectIfDataEnter)">
<div class="select_country_header_left_part">
<div class="container_inf_about_country">
<img class="country_flag_img_container"{% if initial.country.flag %} src="{{ initial.country.flag.url }}"{% endif %}>
<div class="country_code">{% if initial.country.short_code %}{{ initial.country.short_code }}{% endif %}</div>
</div>
<input class="dropped" type="text" name="{{ name }}" id="id_{{ name }}" placeholder="{{ placeholder }}" oninput="searchCountry(this)" data-value="" data-id="" value="{% if initial.name %}{{ initial.name }}/{{ initial.country.name }}{% endif %}">
<input class="dropped" type="text" name="{{ name }}" id="id_{{ name }}" placeholder="{{ placeholder }}" oninput="searchCountry(this)" data-value="{% if initial %}{{ initial.name }}/{{ initial.country.name }}{% endif %}" data-id="{% if initial.id %}{{ initial.id }}{% endif %}" value="{% if initial.name %}{{ initial.name }}/{{ initial.country.name }}{% endif %}">
</div>
<img class="w_select_country_icon" src="{% static "v2/icons/widgets/w_select_country/pin.svg" %}" alt="">
</div>