97 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
76 changed files with 2364 additions and 418 deletions

View File

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

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

@@ -1,6 +1,13 @@
from asgiref.sync import async_to_sync
from django.http import HttpResponse, Http404, FileResponse from django.http import HttpResponse, Http404, FileResponse
from django.conf import settings from django.conf import settings
from BaseModels.exceptions import exception_processing
from BaseModels.print_funcs import print_ext
def get_and_set_lang(request): def get_and_set_lang(request):
from django.utils.translation import activate, get_language from django.utils.translation import activate, get_language
@@ -30,6 +37,27 @@ def get_and_set_lang(request):
return lang 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): def get_add_to_ajax_response_Dict(user):
context_Dict = {} context_Dict = {}

View File

@@ -26,7 +26,6 @@ def generate_routes(request, routes_count):
): ):
raise Http404 raise Http404
from RoutesApp.funcs import get_city_by_type_transport_and_address_point
from RoutesApp.models import Route from RoutesApp.models import Route
from ReferenceDataApp.models import Airport, City from ReferenceDataApp.models import Airport, City

View File

@@ -7,6 +7,13 @@ from timezonefinder import TimezoneFinder
tzf = 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): def search_cities_in_db(search_str):
res_data = [] res_data = []
Q_obj = Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \ 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: for item in objs_wo_tz:
item.get_n_save_timezone() item.get_n_save_timezone()
res_data = City.objects.filter(id__in=ids).values( 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) return list(res_data)

View File

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

View File

@@ -58,7 +58,8 @@ class RouteForm(forms.ModelForm):
try: try:
if 'type_transport' in self.errors: if 'type_transport' in self.errors:
self.errors.pop('type_transport') if self.instance and self.instance.owner_type == 'customer':
self.errors.pop('type_transport')
if 'phone' in cleaned_data and 'phone' in cleaned_data: if 'phone' in cleaned_data and 'phone' in cleaned_data:
from BaseModels.validators.form_field_validators import get_phone_valid_error from BaseModels.validators.form_field_validators import get_phone_valid_error

View File

@@ -135,6 +135,8 @@ def get_profile_my_routes_page_content_html(request):
if user_subscribe: if user_subscribe:
routes_Dict.update(user_subscribe.remains_route_adding_options()) routes_Dict.update(user_subscribe.remains_route_adding_options())
routes_Dict.update({'editable_routes': True})
html = render_to_string('v2/blocks/b_my_routes.html', routes_Dict, request=request) html = render_to_string('v2/blocks/b_my_routes.html', routes_Dict, request=request)
return html return html
@@ -199,29 +201,17 @@ def get_routes_Dict(user=None, data=None):
}) })
if key not in ( if key not in (
'from_address_point_txt', 'to_address_point_txt', 'csrfmiddlewaretoken', 'sort', 'weight', 'from_city', 'to_city', 'csrfmiddlewaretoken', 'sort', 'weight',
'from_el', 'to_el', 'from_address_point', 'to_address_point', 'type_transport', 'from_el', 'to_el', 'type_transport',
'departure_DT', 'arrival_DT' 'departure_DT', 'arrival_DT'
): ):
kwargs.update({key: val}) kwargs.update({key: val})
if key == 'from_address_point': # в from_address_point всегда город if key == 'from_city':
# city = get_city_by_type_transport_and_address_point(type_transport, val) kwargs.update({f'from_city_id': val})
city = get_city_by_address_point(val)
kwargs.update({f'from_city': city})
if key == 'to_city':
res_Dict.update({ kwargs.update({f'to_city_id': val})
'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 == 'from_el': if key == 'from_el':
from_el = int(val) from_el = int(val)
@@ -255,7 +245,8 @@ def get_routes_Dict(user=None, data=None):
).order_by( ).order_by(
F('rising_DT').desc(nulls_last=True), F('rising_DT').desc(nulls_last=True),
# '-rising_DT', # '-rising_DT',
'-departure_DT', '-arrival_DT', '-modifiedDT' '-arrival_DT', '-modifiedDT'
# '-departure_DT',
) )
routes_count = routes.count() routes_count = routes.count()
@@ -307,7 +298,8 @@ def get_routes_Dict(user=None, data=None):
'routes': routes, 'routes': routes,
'last_block': last_block, 'last_block': last_block,
'last_el': to_el, '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 return res_Dict

View File

@@ -6,6 +6,9 @@ from django.conf import settings
from django.shortcuts import render from django.shortcuts import render
from uuid import uuid1 from uuid import uuid1
from twisted.web.http import stringToDatetime
from .models import * from .models import *
from django.contrib import auth from django.contrib import auth
from django.http import HttpResponse, Http404, JsonResponse from django.http import HttpResponse, Http404, JsonResponse
@@ -18,31 +21,30 @@ from django.template.loader import render_to_string
from django.urls import reverse from django.urls import reverse
from .forms import * from .forms import *
from .funcs 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 from SubscribesApp.funcs import check_option_in_cur_user_subscribe
def highlight_route_ajax(request): def highlight_route_ajax(request):
if request.method != 'POST': data = check_post_request_and_get_data(request)
raise Http404 if data == None:
return Http404
data = request.POST elif type(data) == str:
if not data and request.body: return JsonResponse({'error': data}, status=400)
data = json.loads(request.body)
if not data or not 'route_id' in data: if not data or not 'route_id' in data:
msg = _('Недостаточно данных') msg = _('Недостаточно данных')
return JsonResponse({'errors': msg}) return JsonResponse({'errors': msg}, status=400)
try: try:
route = Route.objects.get(owner=request.user, id=data['route_id']) route = Route.objects.get(owner=request.user, id=data['route_id'])
except Route.DoesNotExist: except Route.DoesNotExist:
msg = _('Не найден маршрут') msg = _('Не найден маршрут')
return JsonResponse({'errors': msg}) return JsonResponse({'errors': msg}, status=400)
if not route.get_permission_for_highlight(): if not route.get_permission_for_highlight():
msg = _('Нет доступа к выделению') msg = _('Нет доступа к выделению')
return JsonResponse({'errors': msg}) return JsonResponse({'errors': msg}, status=403)
from SubscribesApp.funcs import get_cur_user_subscribe from SubscribesApp.funcs import get_cur_user_subscribe
@@ -75,12 +77,11 @@ def highlight_route_ajax(request):
def raise_route_ajax(request): def raise_route_ajax(request):
if request.method != 'POST': data = check_post_request_and_get_data(request)
raise Http404 if data == None:
return Http404
data = request.POST elif type(data) == str:
if not data and request.body: return JsonResponse({'error': data}, status=400)
data = json.loads(request.body)
if not data or not 'route_id' in data: if not data or not 'route_id' in data:
msg = _('Недостаточно данных') msg = _('Недостаточно данных')
@@ -94,7 +95,7 @@ def raise_route_ajax(request):
if not route.get_permission_for_raise(): if not route.get_permission_for_raise():
msg = _('Нет доступных поднятий') msg = _('Нет доступных поднятий')
return JsonResponse({'errors': msg}, status=400) return JsonResponse({'errors': msg}, status=403)
route.rising_DT = datetime.now() route.rising_DT = datetime.now()
route.save(update_fields=['rising_DT']) route.save(update_fields=['rising_DT'])
@@ -113,8 +114,11 @@ def raise_route_ajax(request):
def del_route_ajax(request): def del_route_ajax(request):
if request.method != 'POST': data = check_post_request_and_get_data(request)
raise Http404 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, 'размещение заявок'): if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
return JsonResponse({'html': 'нет доступа'}, status=403) return JsonResponse({'html': 'нет доступа'}, status=403)
@@ -123,7 +127,7 @@ def del_route_ajax(request):
try: try:
data = json.loads(request.body) # data = json.loads(request.body)
if not 'route_id' in data: if not 'route_id' in data:
msg = f'Недостаточно данных' msg = f'Недостаточно данных'
return JsonResponse({'errors': msg}) return JsonResponse({'errors': msg})
@@ -153,15 +157,18 @@ def del_route_ajax(request):
def edit_route_ajax(request): def edit_route_ajax(request):
if request.method != 'POST': data = check_post_request_and_get_data(request)
raise Http404 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, 'размещение заявок'): if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
return JsonResponse({'html': 'нет доступа'}, status=403) return JsonResponse({'html': 'нет доступа'}, status=403)
lang = get_and_set_lang(request) lang = get_and_set_lang(request)
data = json.loads(request.body) # data = json.loads(request.body)
Dict = {} Dict = {}
@@ -195,7 +202,9 @@ def edit_route_ajax(request):
print(msg) print(msg)
return JsonResponse({'errors': 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 = { res_Dict = {
'html': html, 'html': html,
'btn_title': _('Сохранить изменения') 'btn_title': _('Сохранить изменения')
@@ -270,7 +279,7 @@ def find_routes_ajax(request):
if routes_Dict['routes']: 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: else:
html = render_to_string('templates_js_translate/not_found_find_routes.html', routes_Dict, request=request) html = render_to_string('templates_js_translate/not_found_find_routes.html', routes_Dict, request=request)
@@ -325,6 +334,7 @@ def get_my_routes_ajax(request):
if user_subscribe: if user_subscribe:
routes_Dict.update(user_subscribe.remains_route_adding_options()) routes_Dict.update(user_subscribe.remains_route_adding_options())
routes_Dict.update({'editable_routes': True})
html = render_to_string('v2/blocks/b_my_routes.html', routes_Dict, request=request) html = render_to_string('v2/blocks/b_my_routes.html', routes_Dict, request=request)
@@ -398,6 +408,10 @@ def create_or_change_route_ajax(request, route_id=None):
tpl_form_by_owner_type = 'v2/forms/f_create_mover_route.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' 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 route = None
if route_id: if route_id:
route = Route.objects.get(id=route_id) route = Route.objects.get(id=route_id)

View File

@@ -2,6 +2,7 @@ from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from BaseModels.base_models import BaseModel from BaseModels.base_models import BaseModel
from colorfield.fields import ColorField from colorfield.fields import ColorField
from datetime import datetime
type_transport_choices = [ type_transport_choices = [
@@ -75,7 +76,9 @@ class Route(BaseModel):
verbose_name=_('Куда можете доставить?'), verbose_name=_('Куда можете доставить?'),
null=True, blank=True 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 # не используем с v2
weight = models.IntegerField(verbose_name=_('Укажите вес до (кг)'), null=True, blank=True) weight = models.IntegerField(verbose_name=_('Укажите вес до (кг)'), null=True, blank=True)
phone = models.CharField(verbose_name=_('Укажите номер для связи'), blank=True, null=True) phone = models.CharField(verbose_name=_('Укажите номер для связи'), blank=True, null=True)
@@ -116,6 +119,13 @@ class Route(BaseModel):
verbose_name_plural = _(u'Маршруты') verbose_name_plural = _(u'Маршруты')
ordering = ('name',) 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): def get_permission_for_raise(self):
from SubscribesApp.funcs import get_cur_user_subscribe from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(self.owner) user_subscribe = get_cur_user_subscribe(self.owner)

View File

@@ -3,10 +3,38 @@ __author__ = 'SDE'
from django import template from django import template
from django.template.defaultfilters import stringfilter from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
register = template.Library() 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 @register.filter
@stringfilter @stringfilter
def get_splited_cargo_type(value): def get_splited_cargo_type(value):

View File

@@ -1,6 +1,8 @@
from django.shortcuts import render from django.shortcuts import render
from uuid import uuid1 from uuid import uuid1
from ReferenceDataApp.funcs import get_city_by_id
from .models import * from .models import *
from django.contrib import auth from django.contrib import auth
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
@@ -39,17 +41,23 @@ def route_search_results_View(request):
'page_type': 'routes', 'page_type': 'routes',
'next_page_els_count': routes_Dict['next_page_els_count'], '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']}) from_city = None
if 'to_address_point_txt' in routes_Dict: to_city = None
data.update({'to_address_point_txt': routes_Dict['to_address_point_txt']}) if 'from_city' in data and data['from_city']:
Dict.update({'route_form': RouteForm(initial=data, owner_type=owner_type)}) 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 = _('Результат поиска маршрутов') title = _('Результат поиска маршрутов')
if 'from_address_point_txt' in data: if from_city:
title = f'{title} из {data["from_address_point_txt"]}' title = f'{title} из {from_city.name}'
if 'to_address_point_txt' in data: if to_city:
title = f'{title} в {data["to_address_point_txt"]}' title = f'{title} в {to_city.name}'
Dict.update({ Dict.update({
'page': { 'page': {
@@ -59,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) return get_inter_http_response(t, Dict, request)
except Exception as e: except Exception as e:

View File

@@ -77,7 +77,8 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
'last_paid_DT', 'last_paid_DT',
'paid_period_from_DT', 'paid_period_to_DT', 'paid_period_from_DT', 'paid_period_to_DT',
'auto_continue', 'receive_finish_subscribe_msg', '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_display_links = ['id']
list_filter = [ list_filter = [
'enable',
'subscribe', 'last_paid_DT', 'paid_period_from_DT', 'paid_period_to_DT', 'subscribe', 'last_paid_DT', 'paid_period_from_DT', 'paid_period_to_DT',
'auto_continue', 'receive_finish_subscribe_msg', 'auto_continue', 'receive_finish_subscribe_msg',
'modifiedDT', 'createDT' 'modifiedDT', 'createDT'

View File

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

View File

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

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; --error-color: #FF0000;
box-sizing: border-box; box-sizing: border-box;
&.line{ &.line{
display: flex; display: flex;
align-items: center; align-items: center;
@@ -35,6 +35,7 @@
display: block; display: block;
color: var(--label-color); color: var(--label-color);
font-weight: var(--label-font-weight); font-weight: var(--label-font-weight);
font-size: var(--label-font-size);
&:has(div){ &:has(div){
display: flex; display: flex;
align-items: center; align-items: center;
@@ -53,6 +54,7 @@
font-family: var(--main-font-family), serif; font-family: var(--main-font-family), serif;
box-sizing: border-box; box-sizing: border-box;
outline: none; outline: none;
min-width: 0;
&.dropped{ &.dropped{
border: none; border: none;
outline: none; outline: none;
@@ -110,44 +112,85 @@
font-size: var(--error-font-size); font-size: var(--error-font-size);
color: var(--error-color); color: var(--error-color);
} }
}
.form_line{ select{
--display: flex; --select-padding: 14px 10px;
&._50_grid { --select-bg: #FFFFFF;
--display: grid; --select-border: #E6E6E6;
grid-template-columns: repeat(2, 1fr); --select-font-size: 14px;
gap: 40px; --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"]{ form {
--submit-button-bg: #FF613A;
--submit-button-box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.12);
--submit-button-border: none; .form_line{
--submit-button-border-radius: 10px; --display: flex;
--submit-button-font-size: 18px; &._50_grid {
--submit-button-color: #FFFFFF; --display: grid;
--submit-button-font-weight: 600; grid-template-columns: repeat(2, 1fr);
gap: 40px;
}
display: var(--display);
justify-content: space-between;
}
--submit-button-width: 100%; /* initial */ button[type="submit"]{
--submit-button-padding: 17px; --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); --submit-button-width: 100%; /* initial */
box-shadow: var(--submit-button-box-shadow); --submit-button-padding: 17px;
width: var(--submit-button-width); outline: none;
padding: var(--submit-button-padding);
border: var(--submit-button-border); background: var(--submit-button-bg);
border-radius: var(--submit-button-border-radius); box-shadow: var(--submit-button-box-shadow);
color: var(--submit-button-color); width: var(--submit-button-width);
font-size: var(--submit-button-font-size); padding: var(--submit-button-padding);
font-weight: var(--submit-button-font-weight);
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

@@ -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; gap: 10px;
border: 2px solid var(--range-picker-border); border: 2px solid var(--range-picker-border);
border-radius: var(--range-picker-border-radius); border-radius: var(--range-picker-border-radius);
padding: 24px 10px; padding: 18px 10px;
background: #FFFFFF; background: #FFFFFF;
input{ input{
width: calc(100% - 28px); width: calc(100% - 28px);

View File

@@ -39,17 +39,165 @@
--route-btn-hover-text-color: #FFFFFF; --route-btn-hover-text-color: #FFFFFF;
--route-btn-title-color: #272424; --route-btn-title-color: #272424;
--route-btn-text-data-color: #27242499; --route-btn-text-data-color: #27242499;
--route-btn-margin: 0;
--route-date-data-justify: center; --route-date-data-justify: center;
--route-date-data-margin: 4px 0 0 0; --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); background: var(--route-card-bg);
margin: var(--route-card-margin); margin: var(--route-card-margin);
box-shadow: var(--route-card-box_shadow); box-shadow: var(--route-card-box_shadow);
border-radius: 10px; border-radius: 10px;
color: var(--route-text-color); 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{ .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; position: relative;
.card_owner_name{
font-weight: 600;
font-size: var(--big-font-size);
}
.route_card_text_img{ .route_card_text_img{
position: absolute; position: absolute;
top: 5px; top: 5px;
@@ -67,13 +215,86 @@
top: 11px; top: 11px;
left: 6px; left: 6px;
z-index: 10; z-index: 10;
object-fit: cover;
object-position: center;
} }
.route_card_text_container{ .route_card_text_container{
position: relative;
overflow-wrap: anywhere;
@media (max-width: 992px) {
--big-font-size: 14px;
}
background: var(--route-text-container-bg); background: var(--route-text-container-bg);
padding: var(--route-text-container-padding); padding: var(--route-text-container-padding);
margin: var(--route-text-container-margin); margin: var(--route-text-container-margin);
border-radius: var(--route-text-container-border-radius); border-radius: var(--route-text-container-border-radius);
font-size: var(--big-font-size); 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{ .route_card_owner_info{
height: 47px; height: 47px;
@@ -86,14 +307,10 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
.card_owner_name{
font-weight: 600;
font-size: var(--big-font-size);
}
.card_splitter{ .card_splitter{
height: 22px; height: 22px;
width: 2px; width: 2px;
background: #E6E6E6; background: var(--card-splitter-bg);
} }
.card_owner_type{ .card_owner_type{
&.mover{ &.mover{
@@ -116,117 +333,170 @@
} }
} }
} }
.route_card_route_data{ .route_card_route_data_cont{
margin-top: var(--route_card_route_data-margin-top);
display: flex;
justify-content: space-between;
gap: 60px;
&.mobile{display: none} &.mobile{display: none}
@media (max-width: 1160px) { @media (max-width: 1160px) {
display: none; display: none;
&.mobile{ &.mobile{
display: grid; display: block;
grid-template-columns: 20px calc(100% - 30px); .route_card_route_data {
gap: 10px; display: grid;
.way_progress_line_container{ grid-template-columns: 20px calc(100% - 30px);
margin-top: 20px; gap: 10px;
height: calc(100% - 20px);
.way_progress_round:first-of-type{ .way_progress_line_container {
left: unset; margin-top: 20px;
top: 0; 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;
}
} }
.way_progress_round:last-of-type{
right: unset; .route_transport, .route_date_data {
top: calc(100% - 20px); &.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;
} }
.way_progress_line{
background: linear-gradient(180deg, rgba(6, 91, 255, 1) 0%, rgba(69, 194, 38, 1) 100%); .arrival_to {
height: calc(100% - 10px); text-align: left !important;
width: 4px;
} }
.way_progress_arrows_line{
height: calc(100% - 10px);
width: 4px;
background-repeat: repeat-y;
}
}
.route_transport, .route_date_data{
&.route_transport{
margin-bottom: 0;
margin-top: 35px;
}
&.route_date_data{
margin-top: 0;
margin-bottom: 39px;
}
justify-content: left!important;
}
.arrival_to {
text-align: left!important;
} }
} }
} }
.from_to_place_data{ .route_card_route_data{
.label{ margin-top: var(--route_card_route_data-margin-top);
color: #27242499; display: flex;
font-size: var(--big-font-size); justify-content: space-between;
font-weight: 600; gap: 60px;
margin-bottom: 10px;
&.departure_from{ .from_to_place_data{
text-align: left; width: var(--from-to-place-data-width);
} &.arrival_to{ @media (max-width: 992px) {
text-align: right; --big-font-size: 14px;
} }
} &:has(.arrival_to){
.place{ .place{justify-content: right}
display: flex; } &:has(.departure_from){
align-items: center; .place{justify-content: left}
gap: 10px; }
.country{ @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; display: flex;
align-items: center; align-items: center;
gap: 5px; 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{ img{
width: 16px;
height: 12px; height: 12px;
display: block; 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{
font-size: var(--big-font-size);
font-weight: 800;
color: #272424;
}
}
}
.route_way_data{
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{ .way_progress_line_container{
position: relative; position: relative;
width: 100%; width: 100%;
@@ -249,8 +519,8 @@
} }
} }
.way_progress_line{ .way_progress_line{
width: calc(100% - 10px); width: calc(100% - 20px);
margin-left: 10px; margin-left: 11px;
height: 4px; height: 4px;
position: absolute; position: absolute;
top: 2px; top: 2px;
@@ -259,7 +529,7 @@
} }
.way_progress_arrows_line{ .way_progress_arrows_line{
width: calc(100% - 10px); width: calc(100% - 10px);
margin-left: 10px; margin-left: 11px;
height: 4px; height: 4px;
position: absolute; position: absolute;
top: 2px; top: 2px;
@@ -297,11 +567,11 @@
} }
} }
.route_btn{ .route_btn{
@media (max-width: 1160px) {
&.phone{display: none;};
&.mobile{display: block;}
}
&.mobile{display: none;} &.mobile{display: none;}
@media (max-width: 1160px) {
&.mobile{display: flex;}
&.hide_in_mobile{display: none!important;};
}
cursor: pointer; cursor: pointer;
&.solid{ &.solid{
@@ -321,7 +591,9 @@
padding: var(--route-btn-padding); padding: var(--route-btn-padding);
background: var(--route-btn-bg); background: var(--route-btn-bg);
height: var(--route-btn-height); height: var(--route-btn-height);
margin: var(--route-btn-margin);
text-align: center; text-align: center;
justify-content: center;
transition: 200ms all; transition: 200ms all;
&:has(img){ &:has(img){
display: flex; display: flex;
@@ -329,8 +601,15 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
text-align: unset; 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(&.inactive):not(&.unhovered){
&:hover{ &:hover{
background: var(--route-btn-hover-bg); background: var(--route-btn-hover-bg);
.route_btn_title{color: var(--route-btn-hover-text-color);} .route_btn_title{color: var(--route-btn-hover-text-color);}
@@ -339,6 +618,10 @@
} }
} }
.route_btn_title{ .route_btn_title{
@media (max-width: 768px) {
--big-font-size: 14px;
--medium-font-size: 12px;
}
color: var(--route-btn-title-color); color: var(--route-btn-title-color);
font-size: var(--medium-font-size); font-size: var(--medium-font-size);
&.big{ &.big{
@@ -378,4 +661,40 @@
gap: 21px; gap: 21px;
margin: 20px 0; 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; --header-padding: 20px 10px;
--select-border: #E6E6E6; --select-border: #E6E6E6;
--select-border-radius: 10px 10px 0 0; --select-border-radius: 10px 10px 0 0;
--select-height: 68px; --select-height: 60px;
&.closed{ &.closed{
--select-border-radius: 10px; --select-border-radius: 10px;
@@ -17,7 +17,7 @@
justify-content: space-between; justify-content: space-between;
border: 2px solid var(--select-border); border: 2px solid var(--select-border);
border-radius: var(--select-border-radius); border-radius: var(--select-border-radius);
padding: 19px 10px; padding: 15px 10px;
background: #FFFFFF; background: #FFFFFF;
.select_country_header_left_part{ .select_country_header_left_part{
@@ -54,7 +54,7 @@
.w_select_country_content{ .w_select_country_content{
position: absolute; position: absolute;
top: var(--select-height); top: var(--select-height);
z-index: 100; z-index: 10000;
width: 100%; width: 100%;
background: #FFFFFF; background: #FFFFFF;
border: 2px solid var(--select-border); border: 2px solid var(--select-border);

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

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="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,4 +1,4 @@
function chooseCheckbox(el) { function chooseCheckbox(el, callback) {
if (!el) return; if (!el) return;
resetFieldError(el); resetFieldError(el);
@@ -6,11 +6,11 @@ function chooseCheckbox(el) {
let $checkbox = $parent.querySelector('.checkbox') let $checkbox = $parent.querySelector('.checkbox')
$checkbox.classList.toggle("checked"); $checkbox.classList.toggle("checked");
if (callback) callback($checkbox.classList.contains('checked'));
} }
function getFormData(form) { function getFormData(form, formData=new FormData()) {
if (!form) return; if (!form) return;
let formData = new FormData();
let default_element_types = ['input', 'textarea', 'date']; let default_element_types = ['input', 'textarea', 'date'];
let form_elements = getFormElements(form); let form_elements = getFormElements(form);
@@ -52,8 +52,24 @@ function addCustomDataToFormData(el, formData) {
case 'checkbox': case 'checkbox':
let $checkbox = el.querySelector('.checkbox'); let $checkbox = el.querySelector('.checkbox');
let c_value = $checkbox.classList.contains('checked'); 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; break;
case 'radio': case 'radio':
@@ -75,6 +91,11 @@ function addCustomDataToFormData(el, formData) {
formData.append(name, l_value); formData.append(name, l_value);
break; break;
case 'select':
let $select = el.querySelector('select');
if (!$select) return;
formData.append(name, $select.value);
} }
return formData; return formData;
} }
@@ -185,7 +206,71 @@ function checkFieldEmpty($field) {
let $date = $field.querySelector('input'); let $date = $field.querySelector('input');
if ($date.value) empty = false; if ($date.value) empty = false;
break;
case 'select':
let $select = el.querySelector('select');
if (!$select) return;
if ($select.value) empty = false;
break; break;
} }
return empty; 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); let formData = getFormData(form);
formData.append('owner_type', 'mover'); formData.append('owner_type', 'mover');
if (form.dataset.route_id) formData.set('route_id', form.dataset.route_id);
let request = new api({ let request = new api({
url: '/routes/create_or_change_route/', url: '/routes/create_or_change_route/',
data: formData, data: formData,

View File

@@ -4,6 +4,7 @@ function makePosterOrder(form) {
let formData = getFormData(form); let formData = getFormData(form);
formData.append('owner_type', 'customer'); formData.append('owner_type', 'customer');
if (form.dataset.route_id) formData.set('route_id', form.dataset.route_id);
let request = new api({ let request = new api({
url: '/routes/create_or_change_route/', url: '/routes/create_or_change_route/',
data: formData, data: formData,

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 request_data.contentType = false
} }
if (this.data_type === 'json'){ if (this.data_type === 'json'){
request_data.processData = false
request_data.contentType = false
request_data.data = JSON.stringify(this.data) 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

@@ -36,18 +36,19 @@ function datarangepickerinitAll(){
} }
function daterangepickerInit(el, callback, date) { function daterangepickerInit(el, callback, date) {
let $datarangepicker = el.querySelector('input') let $datarangepicker = el.querySelector('input');
let min_date = moment()
if (date){ let min_date = moment(date)
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({ $($datarangepicker).daterangepicker({
"autoapply": true, "autoapply": true,
"linkedCalendars": false, "linkedCalendars": false,
"singleDatePicker": true, "singleDatePicker": !!!$datarangepicker.dataset.range,
"timePicker": false, "timePicker": false,
"timePicker24Hour": false, "timePicker24Hour": false,
"minDate": moment(date), "minDate": min_date,
"locale": setLocalSets(), "locale": setLocalSets(),
}, function (start, end, label) { }, function (start, end, label) {
let $parent = el.closest('.w_daterangepicker') let $parent = el.closest('.w_daterangepicker')
@@ -56,7 +57,12 @@ function daterangepickerInit(el, callback, date) {
if (last_opened_daterangepicker) $parent = last_opened_daterangepicker.closest('.w_daterangepicker'); if (last_opened_daterangepicker) $parent = last_opened_daterangepicker.closest('.w_daterangepicker');
let $input = $parent.querySelector(".date_range_input_cont input") let $input = $parent.querySelector(".date_range_input_cont input")
$input.value = start.format('DD.MM.YYYY'); 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); resetFieldError(el);
if (callback) callback(el) if (callback) callback(el)
}); });
@@ -68,3 +74,6 @@ function clickOnDateIconE(el){
$input.focus() $input.focus()
} }
$(document).ready(function () {
datarangepickerinitAll()
})

View File

@@ -1,5 +1,5 @@
function changeRoute(el) { function changeRoute(el) {
if (!el) return; if (!el || el.closest('.disabled')) return;
let $parent = el.closest(".w_route_card") let $parent = el.closest(".w_route_card")
if (!$parent) return; if (!$parent) return;
@@ -12,7 +12,14 @@ function changeRoute(el) {
data: data, data: data,
data_type: 'json', data_type: 'json',
success: (res) => { success: (res) => {
if (!res.html) return;
$(".info_profile")[0].innerHTML = res.html;
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
});
datarangepickerinitAll()
}, error: (res) => { }, error: (res) => {
} }
@@ -45,7 +52,7 @@ function deleteRoute(el) {
} }
function raiseRoute(el) { function raiseRoute(el) {
if (!el) return; if (!el || el.dataset.actions_count === '0' || el.closest('.disabled')) return;
let $parent = el.closest(".w_route_card") let $parent = el.closest(".w_route_card")
if (!$parent) return; if (!$parent) return;
@@ -59,6 +66,26 @@ function raiseRoute(el) {
data_type: 'json', data_type: 'json',
success: (res) => { 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) => { }, error: (res) => {
} }
@@ -68,7 +95,7 @@ function raiseRoute(el) {
} }
function highlightRoute(el) { function highlightRoute(el) {
if (!el) return; if (!el || el.dataset.actions_count === '0' || el.closest('.disabled')) return;
let $parent = el.closest(".w_route_card") let $parent = el.closest(".w_route_card")
if (!$parent) return; if (!$parent) return;
@@ -82,10 +109,47 @@ function highlightRoute(el) {
data_type: 'json', data_type: 'json',
success: (res) => { 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) => { }, error: (res) => {
} }
}); });
request.ajaxRequest() 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

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

View File

@@ -37,6 +37,7 @@
<script src='{% static "v2/js/widgets/w_textarea_w_counter.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_poster_order.js" %}'></script>
<script src='{% static "v2/js/forms/f_make_mover_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" %} {% include "connect_ws_js.html" %}
<link rel="stylesheet" href="{% static "v2/css/widgets/w_route_card.css" %}"> <link rel="stylesheet" href="{% static "v2/css/widgets/w_route_card.css" %}">

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_js.js" %}"></script>
<script type="text/javascript" src="{% static "js/moment-with-locales.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 "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 type="text/javascript" src="{% static "js/push/registerSw.js" %}"></script>
<script src="{% static "js/rangecalendartech.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' %}" /> <link rel="stylesheet" href="{% static 'css/datarangepicker.css' %}" />
<script src="{% static "js/global_js.js" %}"></script> <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/styles(boris).css' %}" >
<link rel="stylesheet" href="{% static 'css/mobile_styles.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/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/find_route.js" %}'></script>
<script src="{% static "js/filters_functions_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/user_profile_2.js" %}"></script>
<script src="{% static "js/ion.rangeSlider.min.js" %}"></script> <script src="{% static "js/ion.rangeSlider.min.js" %}"></script>
<script src="{% static "v2/js/forms.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" %}"> <link rel="stylesheet" href="{% static "css/ion.rangeSlider.min.css" %}">
@@ -200,24 +206,24 @@ function gtag_report_conversion(url) {
</div> </div>
{% if page_type == 'routes' %} {% if page_type == 'routes' %}
<div class="cut_width_f_curtain{% if page_type == 'profile' %}{% else %} n_profile{% endif %} left"> <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" %}'>"> {# <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" %} {# {% include "forms/f_find_route_filters_form.html" %}#}
{# <div class="handler_menu close" onclick="open_curtain_w_contacts()">#} {# <div class="handler_menu close" onclick="open_curtain_w_contacts()">#}
{# <img class="btns_f_curtain close left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#} {# <img class="btns_f_curtain close left" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
{# <div class="text_f_curtain left"><img style='width: 15px;display: block;position: relative;bottom: 0;transform: rotate(270deg);' src='{% static "/img/svg/filter.svg" %}'></div>#} {# <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' %}">#} {# <img class="btns_f_curtain close right" src="{% static 'img/svg/arrow_f_curtain.svg' %}">#}
{# <div class="clear_both"></div>#} {# <div class="clear_both"></div>#}
{# </div>#} {# </div>#}
</div> {# </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 %} {% 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 %}"> <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

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

@@ -3,6 +3,17 @@
<div class="b_my_routes"> <div class="b_my_routes">
{% for route in routes %} {% for route in routes %}
{% include 'v2/widgets/w_customer_route_card.html' with route=route %} {% include 'v2/widgets/w_route_card.html' with route=route %}
{% endfor %} {% endfor %}
</div> </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

@@ -2,10 +2,10 @@
{% load i18n %} {% load i18n %}
{% load reference_data_tags %} {% 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)" data-now="{{ timezone|get_cur_DT_by_tz }}"> <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"> <div class="cw_country_inf_part">
<img src="{{ MEDIA_URL }}{{ country__flag }}" alt=""> <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>
<div class="cw_name_country">{{ name }}/{{ country__name }}</div> <div class="cw_name_country">{{ name }}/{{ country__name }}</div>
</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,7 +1,7 @@
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
<form name="make_poster_order" class="f_make_poster_order" data-owner_type="customer"> <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="form_line">
<div class="field_container" data-type="radio" data-name="type_transport"> <div class="field_container" data-type="radio" data-name="type_transport">
{% trans "Обязательно учитывайте Правила и особенности перевозки выбранным Вами видом транспорта" as attention_type_transport %} {% trans "Обязательно учитывайте Правила и особенности перевозки выбранным Вами видом транспорта" as attention_type_transport %}
@@ -16,12 +16,12 @@
<div class="form_line _50_grid"> <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">
<label for="id_from_city"><div class="required_field_icon">*</div> {% trans "Откуда забрать посылку" %}</label> <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 %} {% if form.errors.from_city %}<div class="error_container">{{ form.errors.from_city.0 }}</div>{% endif %}
</div> </div>
<div class="field_container" data-type="location" data-name="to_city" data-datepicker="arrival_DT"> <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> <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 %} {% if form.errors.to_city %}<div class="error_container">{{ form.errors.to_city.0 }}</div>{% endif %}
</div> </div>
</div> </div>
@@ -35,7 +35,7 @@
<div class="form_line _50_grid"> <div class="form_line _50_grid">
<div class="field_container" data-type="date" data-name="arrival_DT"> <div class="field_container" data-type="date" data-name="arrival_DT">
<label for="id_arrival_DT"><div class="required_field_icon">*</div> {% trans "Дата доставки посылки" %}</label> <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 %} {% if form.errors.arrival_DT %}<div class="error_container">{{ form.errors.arrival_DT.0 }}</div>{% endif %}
</div> </div>
</div> </div>

View File

@@ -1,7 +1,7 @@
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
<form name="make_mover_order" class="f_make_poster_order" data-owner_type="mover"> <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="form_line">
<div class="field_container" data-type="radio" data-name="type_transport"> <div class="field_container" data-type="radio" data-name="type_transport">
{% trans "Обязательно учитывайте Правила и особенности перевозки выбранным Вами видом транспорта" as attention_type_transport %} {% trans "Обязательно учитывайте Правила и особенности перевозки выбранным Вами видом транспорта" as attention_type_transport %}
@@ -16,24 +16,24 @@
<div class="form_line _50_grid"> <div class="form_line _50_grid">
<div class="field_container" data-type="location" data-name="from_city" data-datepicker="departure_DT"> <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> <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 %} {% if form.errors.from_city %}<div class="error_container">{{ form.errors.from_city.0 }}</div>{% endif %}
</div> </div>
<div class="field_container" data-type="location" data-name="to_city" data-datepicker="arrival_DT"> <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> <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 %} {% if form.errors.to_city %}<div class="error_container">{{ form.errors.to_city.0 }}</div>{% endif %}
</div> </div>
</div> </div>
<div class="form_line _50_grid"> <div class="form_line _50_grid">
<div class="field_container" data-type="date" data-name="departure_DT"> <div class="field_container" data-type="date" data-name="departure_DT">
<label for="id_departure_DT"><div class="required_field_icon">*</div> {% trans "Дата отправления" %}</label> <label for="id_departure_DT"><div class="required_field_icon">*</div> {% trans "Дата отправления" %}</label>
{% include 'v2/widgets/w_daterangepicker.html' with name='departure_DT' initial=form.initial.departure_DT %} {% 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 %} {% if form.errors.departure_DT %}<div class="error_container">{{ form.errors.departure_DT.0 }}</div>{% endif %}
</div> </div>
<div class="field_container" data-type="date" data-name="arrival_DT"> <div class="field_container" data-type="date" data-name="arrival_DT">
<label for="id_arrival_DT"><div class="required_field_icon">*</div> {% trans "Дата прибытия" %}</label> <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 %} {% if form.errors.arrival_DT %}<div class="error_container">{{ form.errors.arrival_DT.0 }}</div>{% endif %}
</div> </div>
</div> </div>
@@ -46,8 +46,8 @@
</div> </div>
<div class="form_line"> <div class="form_line">
<div class="field_container" data-type="input" style="width: 100%" data-name="phone"> <div class="field_container" data-type="input" style="width: 100%" data-name="phone">
{% trans "Если вы оставите это поле пустым - перевозчики смогут только написать вам в личные сообщения на нашем сайте TripWB.com" as attention_phone %} {% trans "Если вы оставите это поле пустым - отправители смогут только написать вам в личные сообщения на нашем сайте TripWB.com" as attention_phone %}
<label for="id_cargo_type">{% trans "Контактный номер телефона, по которому с Вами могут связаться перевозчики" %}</label> <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);"> <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 %} {% 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 %} {% include 'v2/widgets/w_pay_attention.html' with text=attention_phone %}
@@ -64,7 +64,7 @@
<div class="form_line"> <div class="form_line">
<div class="field_container line" data-type="checkbox" data-name="receive_msg_by_email"> <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{% if form.initial.receive_msg_by_email %} checked{% endif %}" onclick="chooseCheckbox(this)"></div>
<div class="checkbox_label" onclick="chooseCheckbox(this)">{% trans "Хочу получать уведомления на E-mail о появлении перевозчика по моим критериям" %}</div> <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 %} {% 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' %} {% 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

@@ -1,169 +0,0 @@
{% load i18n %}
{% load static %}
<div class="w_customer_route_card w_route_card" data-route_id="{{ route.id }}" data-owner_type="{{ route.owner_type }}">
<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="{{ route.owner.user_profile.avatar.url }}">
<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.get_cargo_type_display }}</div></div>
</div>
<div class="route_btn phone inactive" 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_half_opacity.svg" %}" alt="">
<div class="route_btn_title big">{{ route.phone }}</div>
</div>
</div>
<div class="route_card_text_container">
{% if route.comment %}
{{ route.comment|linebreaksbr }}
{% else %}
{% trans "Комментарий отсутствует" %}
{% endif %}
</div>
</div>
<div class="route_card_route_data">
<div class="from_to_place_data">
<div class="label departure_from">{% trans "Забрать из:" %}</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">
{{ route.from_city.name }}/{{ route.from_city.country.name }}
</div>
</div>
</div>
<div class="route_way_data">
<div class="route_transport">
<div class="route_transport_name">{{ route.get_type_transport_display }}</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:'d F Y' }}</div>
</div>
{% endif %}
</div>
<div class="from_to_place_data">
<div class="label arrival_to">{% trans "Доставить в:" %}</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">
{{ route.to_city.name }}/{{ route.to_city.country.name }}
</div>
</div>
</div>
</div>
<div class="route_card_route_data mobile">
<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">{% trans "Забрать из:" %}</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">
{{ route.from_city.name }}/{{ route.from_city.country.name }}
</div>
</div>
</div>
<div class="route_way_data">
<div class="route_transport">
<div class="route_transport_name">{{ route.get_type_transport_display }}</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:'d F Y' }}</div>
</div>
{% endif %}
</div>
<div class="from_to_place_data">
<div class="label arrival_to">{% trans "Доставить в:" %}</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">
{{ route.to_city.name }}/{{ route.to_city.country.name }}
</div>
</div>
</div>
</div>
</div>
<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-action="raise" onclick="raiseRoute(this)">
<div class="route_btn_title">{% trans "Поднять" %}</div>
<div class="route_btn_data">Осталось поднятий: 2</div>
</div>
<div class="route_btn" data-action="highlight" onclick="highlightRoute(this)">
<div class="route_btn_title">{% trans "Выделить цветом" %}</div>
<div class="route_btn_data">Осталось выделений: 0</div>
</div>
<div class="route_btn solid" data-action="change" onclick="changeRoute(this)">
<div class="route_btn_title">{% trans "Редактировать" %}</div>
</div>
</div>
</div>
<div class="route_btn phone mobile inactive" style="--route-btn-width: 100%;--route-btn-height: min-content;--route-btn-padding: 7.5px 11px;">
<img src="{% static "v2/icons/widgets/w_route_card/phone_half_opacity.svg" %}" alt="">
<div class="route_btn_title big">{{ route.phone }}</div>
</div>
<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" 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">Осталось поднятий: 2</div>
</div>
<div class="route_btn" 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">Осталось выделений: 0</div>
</div>
</div>
<div class="delete_route" onclick="deleteRoute(this)">{% trans "Удалить" %}</div>
</div>
</div>

View File

@@ -3,7 +3,7 @@
<div class="w_daterangepicker" onclick="selectInputWContainer(this)"> <div class="w_daterangepicker" onclick="selectInputWContainer(this)">
<div class="date_range_input_cont"> <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=""> <img onclick="clickOnDateIconE(this)" src="{% static "v2/icons/widgets/w_datarangepicker/datarangepicker_icon.svg" %}" alt="">
</div> </div>
</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>