62 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
58 changed files with 826 additions and 148 deletions

View File

@@ -8,6 +8,7 @@ from BaseModels.print_funcs import print_ext
def get_and_set_lang(request):
from django.utils.translation import activate, get_language
lang = None

View File

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

View File

@@ -7,6 +7,13 @@ from timezonefinder import TimezoneFinder
tzf = TimezoneFinder()
def get_city_by_id(city_id):
try:
return City.objects.get(id=city_id)
except City.DoesNotExist:
return None
def search_cities_in_db(search_str):
res_data = []
Q_obj = Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \
@@ -18,7 +25,7 @@ def search_cities_in_db(search_str):
for item in objs_wo_tz:
item.get_n_save_timezone()
res_data = City.objects.filter(id__in=ids).values(
'id', 'name', 'country__name', 'timezone', 'country__flag', 'country__short_code'
'id', 'name', 'country__name', 'timezone', 'country__flag', 'country__code'
)
return list(res_data)

View File

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

View File

@@ -58,7 +58,8 @@ class RouteForm(forms.ModelForm):
try:
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:
from BaseModels.validators.form_field_validators import get_phone_valid_error

View File

@@ -201,29 +201,17 @@ def get_routes_Dict(user=None, data=None):
})
if key not in (
'from_address_point_txt', 'to_address_point_txt', 'csrfmiddlewaretoken', 'sort', 'weight',
'from_el', 'to_el', 'from_address_point', 'to_address_point', 'type_transport',
'from_city', 'to_city', 'csrfmiddlewaretoken', 'sort', 'weight',
'from_el', 'to_el', 'type_transport',
'departure_DT', 'arrival_DT'
):
kwargs.update({key: val})
if key == 'from_address_point': # в from_address_point всегда город
# city = get_city_by_type_transport_and_address_point(type_transport, val)
city = get_city_by_address_point(val)
kwargs.update({f'from_city': city})
if key == 'from_city':
kwargs.update({f'from_city_id': val})
res_Dict.update({
'from_address_point_txt': city.get_country_n_city_str()
})
if key == 'to_address_point': # в to_address_point всегда город
# city = get_city_by_type_transport_and_address_point(type_transport, val)
city = get_city_by_address_point(val)
kwargs.update({f'to_city': city})
res_Dict.update({
'to_address_point_txt': city.get_country_n_city_str()
})
if key == 'to_city':
kwargs.update({f'to_city_id': val})
if key == 'from_el':
from_el = int(val)
@@ -257,7 +245,8 @@ def get_routes_Dict(user=None, data=None):
).order_by(
F('rising_DT').desc(nulls_last=True),
# '-rising_DT',
'-departure_DT', '-arrival_DT', '-modifiedDT'
'-arrival_DT', '-modifiedDT'
# '-departure_DT',
)
routes_count = routes.count()
@@ -309,7 +298,8 @@ def get_routes_Dict(user=None, data=None):
'routes': routes,
'last_block': last_block,
'last_el': to_el,
'next_page_els_count': next_page_els_count
'next_page_els_count': next_page_els_count,
'now_DT': datetime.now(),
})
return res_Dict

View File

@@ -408,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_block_by_owner_type = 'v2/blocks/b_create_mover_route.html'
if 'route_id' in data and data['route_id']:
route_id = data['route_id']
# del data['route_id']
route = None
if route_id:
route = Route.objects.get(id=route_id)

View File

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

View File

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

View File

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

View File

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

View File

@@ -239,7 +239,7 @@ body {
}
header {
margin-top: 20px;
/*margin-top: 20px;*/
padding: 5px 20px;
position: sticky;
top: 0;

View File

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

View File

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

@@ -5,6 +5,8 @@
height: fit-content;
box-sizing: border-box;
z-index: 1000;
.overlay{
--bg: #F8F8F8CC;
--backdrop-filter: blur(2px);

View File

@@ -13,12 +13,79 @@
gap: 5px;
[data-type="location"] {
&:first-of-type{
.w_select_country_header{--select-border-radius: 10px 0 0 10px!important;}
.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_select_country_header{--select-border-radius: 0!important;}
}
.w_daterangepicker{
--range-picker-border-radius: 0 10px 10px 0!important;
--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{

View File

@@ -35,6 +35,7 @@
display: block;
color: var(--label-color);
font-weight: var(--label-font-weight);
font-size: var(--label-font-size);
&:has(div){
display: flex;
align-items: center;
@@ -53,6 +54,7 @@
font-family: var(--main-font-family), serif;
box-sizing: border-box;
outline: none;
min-width: 0;
&.dropped{
border: none;
outline: none;

View File

@@ -12,7 +12,27 @@
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: 1fr;
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

@@ -70,3 +70,10 @@
cursor: pointer;
}
.container_btns{
width: 100%;
display: flex;
align-items: center;
justify-content: var(--justify);
gap: 5px;
}

View File

@@ -1,5 +1,8 @@
.modal {
display: none;
--modal-bg: #fff;
--modal-ba: 30px;
&.open{
display: block;
}
@@ -16,4 +19,20 @@
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

@@ -65,6 +65,104 @@
--route-text-container-bg: #FFFFFF;
--route-text-img-filter: unset;
}
&.disabled{
--route-card-bg: #FFFFFF;
--card-splitter-bg: #E6E6E6;
--route-text-container-bg: #F1F1F1;
--route-text-img-filter: brightness(0) saturate(100%) invert(100%) sepia(2%) saturate(256%) hue-rotate(113deg) brightness(115%) contrast(89%);
.route_card_info_data{
.route_card_text_container{
color: #A9A9A9!important;
}
}
.card_owner_type.mover, .card_owner_type.customer{
--route-owner-type-color: #A9A9A9!important;
}
.route_btn.inactive, .route_btn, .route_btn.solid{
--route-btn-bg: #FFF;
&.solid{
--route-btn-bg: #A9A9A9;
&:hover{
--route-btn-hover-bg: #A9A9A9!important;
--route-btn-hover-text-color: #FFF!important;
}
.route_btn_title{
--route-btn-title-color: #FFF!important;
}
}
--route-btn-border: 1.5px solid #A9A9A9;
--route-btn-text-data-color: #A9A9A9!important;
--route-btn-hover-text-color: #A9A9A9!important;
box-shadow: none!important;
&:hover{
--route-btn-hover-bg: #FFF!important;
}
.route_btn_title{
--route-btn-title-color: #A9A9A9!important;
}
}
.route_btn img{
filter: brightness(0) saturate(100%) invert(77%) sepia(0%) saturate(270%) hue-rotate(138deg) brightness(90%) contrast(83%);
}
--route-cargo-type-color: #A9A9A9;
.route_card_owner_avatar{
filter: grayscale(1);
}
.card_owner_name, div.orange{
color: #A9A9A9!important;
}
.route_card_route_data{
.route_way_data{
.route_transport{
.route_transport_name{
color: #A9A9A9!important;
}
img{
filter: grayscale(1);
}
}
}
.from_to_place_data{
.label{
color: #A9A9A9!important;
}
.place{
.place_title{
color: #A9A9A9!important;
}
.country{
.country_code{
color: #A9A9A9!important;
}
}
img{
filter: grayscale(1);
}
}
}
}
.route_number{
color: #A9A9A9!important;
}
.route_date_data{
color: #A9A9A9!important;
}
.way_progress_line_container{
.way_progress_arrows_line{display: none!important;}
.way_progress_line{
background: #A9A9A9!important;
}
.way_progress_round:first-of-type, .way_progress_round:last-of-type{
border: 3px solid #A9A9A9!important;
}
}
.route_card_actions_container{
.delete_route{
color: #FF613A;
}
}
}
.route_card_info_data{
&.mobile{display: none}
@media (max-width: 1024px) {
@@ -122,6 +220,7 @@
}
.route_card_text_container{
position: relative;
overflow-wrap: anywhere;
@media (max-width: 992px) {
--big-font-size: 14px;
}
@@ -131,6 +230,15 @@
border-radius: var(--route-text-container-border-radius);
font-size: var(--big-font-size);
&.wrapped{
.route_card_text_container_txt{
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
&.msg{
.route_card_text_container_txt{
background-image: linear-gradient(94.66deg, rgba(0, 0, 0, 1) 0%, rgba(241, 241, 241, 0) 8.64%, rgba(241, 241, 241, 0.98) 16.62%);
@@ -265,12 +373,6 @@
}
}
.place_title{
width: 100%;
--max-width: var(--from-to-place-data-width)!important;
background-image: linear-gradient(90deg, rgb(0 0 0) 0%, #FFFFFF var(--max-width))!important;
}
.route_transport, .route_date_data {
&.route_transport {
margin-bottom: 0;
@@ -345,16 +447,25 @@
}
}
.place_title{
--max-width: calc(var(--from-to-place-data-width) - 45.3px);
--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;
color: transparent;
background-clip: text;
-webkit-background-clip: text;
background-image: linear-gradient(90deg, rgb(0 0 0) 0%, #FFFFFF calc(var(--max-width) - 30px));
&.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);
}
}
}
}
@@ -408,8 +519,8 @@
}
}
.way_progress_line{
width: calc(100% - 10px);
margin-left: 10px;
width: calc(100% - 20px);
margin-left: 11px;
height: 4px;
position: absolute;
top: 2px;
@@ -418,7 +529,7 @@
}
.way_progress_arrows_line{
width: calc(100% - 10px);
margin-left: 10px;
margin-left: 11px;
height: 4px;
position: absolute;
top: 2px;
@@ -490,8 +601,15 @@
align-items: center;
justify-content: center;
text-align: unset;
.route_btn_title{
max-width: calc(100% - 21px);
font-size: 14px!important;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
&:not(&.inactive) and &:not(&.unhovered){
&:not(&.inactive):not(&.unhovered){
&:hover{
background: var(--route-btn-hover-bg);
.route_btn_title{color: var(--route-btn-hover-text-color);}
@@ -563,6 +681,10 @@
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;
@@ -575,4 +697,4 @@
filter: invert(1);
}
}
}
}

View File

@@ -3,7 +3,7 @@
--header-padding: 20px 10px;
--select-border: #E6E6E6;
--select-border-radius: 10px 10px 0 0;
--select-height: 68px;
--select-height: 60px;
&.closed{
--select-border-radius: 10px;
@@ -54,7 +54,7 @@
.w_select_country_content{
position: absolute;
top: var(--select-height);
z-index: 100;
z-index: 10000;
width: 100%;
background: #FFFFFF;
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

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

@@ -1,22 +1,64 @@
function searchRoutes (form) {
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(form);
let formData = getFormData($search_form);
formData = getFormData($filter_form, formData);
formData.append('owner_type', 'customer');
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]
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;
resetFieldError(el);
@@ -6,6 +6,7 @@ function chooseCheckbox(el) {
let $checkbox = $parent.querySelector('.checkbox')
$checkbox.classList.toggle("checked");
if (callback) callback($checkbox.classList.contains('checked'));
}
function getFormData(form, formData=new FormData()) {
@@ -205,7 +206,71 @@ function checkFieldEmpty($field) {
let $date = $field.querySelector('input');
if ($date.value) empty = false;
break;
case 'select':
let $select = el.querySelector('select');
if (!$select) return;
if ($select.value) empty = false;
break;
}
return empty;
}
}
function getFormDataElValue($field) {
if (!$field) return;
switch ($field.dataset.type) {
case 'checkbox':
let $checkbox = $field.querySelector('.checkbox');
let c_value = $checkbox.classList.contains('checked');
return c_value;
case 'radio':
let $radio = $field.querySelector('.radio.checked');
if ($radio){
$radio = $radio.closest('.cw_w_radio_inputs_radio_input').dataset.name;
return $radio
} else {
return ``
}
case 'location':
let $location = $field.querySelector('input');
let l_value = $location.dataset.id;
return l_value;
case 'input':
let $input = $field.querySelector('input');
return $input.value;
case 'textarea':
let $textarea = $field.querySelector('textarea');
return $textarea.value;
case 'date':
let $date = $field.querySelector('input');
return $date.value;
case 'select':
let $select = $field.querySelector('select');
if (!$select) return;
return $select.value;
}
}
function formDataToQueryString (formData, forms) {
let str = ``
formData.forEach((value, name) => {
str+=`${name}=${value}&`;
})
return str;
}

View File

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

View File

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

View File

@@ -10,7 +10,7 @@ $(document).ready(function() {
el: $(".b_filter_routes")[0],
recover_el_view: true,
ghost_block:{name: 'route_filters'},
$unnatach_bottom_el: $("footer")[0]
$unnatach_bottom_el: $(".b_dont_found_anth")[0]
})
_scroll.init()
$('body')[0].onscroll = function() {

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

@@ -14,7 +14,8 @@ class scroll{
}
attachElementWhenScroll(){
if (!this.attached_by_bottom_el && this.$unnatach_bottom_el && this.$unnatach_bottom_el.getBoundingClientRect().top <= window.innerHeight && this.attached){
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')
@@ -26,7 +27,7 @@ class scroll{
} 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) {
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";

View File

@@ -36,18 +36,19 @@ function datarangepickerinitAll(){
}
function daterangepickerInit(el, callback, date) {
let $datarangepicker = el.querySelector('input')
let min_date = moment()
if (date){
min_date = moment(date);
let $datarangepicker = el.querySelector('input');
let min_date = moment(date)
if ($datarangepicker.dataset.set_min_date === 'false' || $datarangepicker.dataset.set_min_date === false) {
min_date = moment('1900-01-01');
}
$($datarangepicker).daterangepicker({
"autoapply": true,
"linkedCalendars": false,
"singleDatePicker": !!el.dataset.range,
"singleDatePicker": !!!$datarangepicker.dataset.range,
"timePicker": false,
"timePicker24Hour": false,
"minDate": moment(date),
"minDate": min_date,
"locale": setLocalSets(),
}, function (start, end, label) {
let $parent = el.closest('.w_daterangepicker')

View File

@@ -1,5 +1,5 @@
function changeRoute(el) {
if (!el) return;
if (!el || el.closest('.disabled')) return;
let $parent = el.closest(".w_route_card")
if (!$parent) return;
@@ -14,6 +14,12 @@ function changeRoute(el) {
success: (res) => {
if (!res.html) return;
$(".info_profile")[0].innerHTML = res.html;
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
});
datarangepickerinitAll()
}, error: (res) => {
}
@@ -46,7 +52,7 @@ function deleteRoute(el) {
}
function raiseRoute(el) {
if (!el || el.dataset.actions_count === '0') return;
if (!el || el.dataset.actions_count === '0' || el.closest('.disabled')) return;
let $parent = el.closest(".w_route_card")
if (!$parent) return;
@@ -89,7 +95,7 @@ function raiseRoute(el) {
}
function highlightRoute(el) {
if (!el || el.dataset.actions_count === '0') return;
if (!el || el.dataset.actions_count === '0' || el.closest('.disabled')) return;
let $parent = el.closest(".w_route_card")
if (!$parent) return;
@@ -117,7 +123,7 @@ function highlightRoute(el) {
}
function respondBtnClickEvent(el, authentificated) {
if (!el) return;
if (!el || el.closest('.disabled')) return;
if (authentificated !== 'False') {
let $parent = el.closest(".w_route_card")
let $responde_cont = $parent.querySelector(".respond_route_cont")
@@ -134,8 +140,16 @@ function respondBtnClickEvent(el, authentificated) {
}
function clickedUnregisteredMsgRoute (el) {
if (!el) return;
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

@@ -37,6 +37,7 @@
<script src='{% static "v2/js/widgets/w_textarea_w_counter.js" %}'></script>
<script src='{% static "v2/js/forms/f_make_poster_order.js" %}'></script>
<script src='{% static "v2/js/forms/f_make_mover_order.js" %}'></script>
<script src='{% static "v2/js/blocks/b_my_routes.js" %}'></script>
{% include "connect_ws_js.html" %}
<link rel="stylesheet" href="{% static "v2/css/widgets/w_route_card.css" %}">

View File

@@ -103,6 +103,7 @@ function gtag_report_conversion(url) {
<script src="{% static "js/ion.rangeSlider.min.js" %}"></script>
<script src="{% static "v2/js/forms.js" %}"></script>
<script src="{% static "v2/js/service/modal.js" %}"></script>
<script src="{% static "v2/js/service/general.js" %}"></script>
<link rel="stylesheet" href="{% static "css/ion.rangeSlider.min.css" %}">

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

@@ -16,20 +16,20 @@
<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 route_form.initial.type_transport %} checked{% endif %}" data-value="road" onclick="chooseCheckbox(this)"></div>
<div class="checkbox_label" onclick="chooseCheckbox(this)">{% trans "Автоперевозка" %}</div>
{% if route_form.errors.type_transport %}<div class="error_container">{{ route_form.errors.type_transport.0 }}</div>{% endif %}
<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 route_form.initial.type_transport %} checked{% endif %}" data-value="avia" onclick="chooseCheckbox(this)"></div>
<div class="checkbox_label" onclick="chooseCheckbox(this)">{% trans "Авиатранспорт" %}</div>
{% if route_form.errors.type_transport %}<div class="error_container">{{ route_form.errors.type_transport.0 }}</div>{% endif %}
<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">
<select name="cargo_type" id="id_cargo_type" onchange="searchRoutes()">
<option value="">{% trans "Любой" %}</option>
{% for cargo_type in route_form.fields.cargo_type.choices %}
{% for cargo_type in form.fields.cargo_type.choices %}
<option value="{{ cargo_type.0 }}">{{ cargo_type.1 }}</option>
{% endfor %}
</select>

View File

@@ -5,4 +5,15 @@
{% for route in routes %}
{% include 'v2/widgets/w_route_card.html' with route=route %}
{% 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

@@ -5,18 +5,30 @@
<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">{% trans "Выезжает из" %}</label>
<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">{% trans "Прибывает в" %}</label>
<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 name='arrival_DT' range='true' initial=form.initial.arrival_DT %}
{% 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>

View File

@@ -1,6 +1,18 @@
{% load static %}
{% load i18n %}
{% for route in routes %}
{% include "v2/widgets/w_route_card_for_search.html" %}
{% endfor %}
<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 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">
<img src="{{ MEDIA_URL }}{{ country__flag }}" alt="">
<div class="cw_country_code">{{ country__short_code }}</div>
<div class="cw_country_code">{{ country__code }}</div>
</div>
<div class="cw_name_country">{{ name }}/{{ country__name }}</div>
</div>

View File

@@ -17,10 +17,10 @@
</div>
</div>
</div>
<div class="route_btn mobile inactive" style="--route-btn-width: auto;--route-btn-height: min-content;--route-btn-padding: 7.5px 11px;--route-btn-margin: 20.5px 0 0 0;">
<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>
</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>

View File

@@ -2,15 +2,15 @@
{% load i18n %}
<div class="respond_route_cont mobile" style="display: none;margin-top: 23px;">
<div class="route_btn unhovered" style="--route-btn-width: max-content;--route-btn-height: min-content;--route-btn-padding: 7.5px 11px;">
<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="">
<div class="route_btn_title big">
<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 %}
</div>
</a>
</div>
<div class="chat_btn">
<img src="{% static "v2/icons/widgets/w_route_card/chat.png" %}" alt="">

View File

@@ -1,20 +1,21 @@
{% 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 }}{% endif %}">
<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.get_cargo_type_display }}</div></div>
<div class="card_cargo_type">{% trans "Тип посылки:" %} <div class="orange">{{ route.cargo_type|get_cargo_type_for_show }}</div></div>
</div>
<div class="route_btn inactive" style="--route-btn-width: max-content;--route-btn-height: min-content;--route-btn-padding: 7.5px 11px;">
<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>
</div>
</a>
</div>
<div class="route_card_text_container">
{% if route.comment %}
@@ -31,11 +32,7 @@
<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.get_cargo_type_display }}</div></div>
</div>
<div class="route_btn 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 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>

View File

@@ -1,26 +1,27 @@
{% 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 }}{% endif %}">
<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.get_cargo_type_display }}</div></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="">
<div class="route_btn_title big">
<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 %}
</div>
</a>
</div>
<div class="chat_btn">
<img src="{% static "v2/icons/widgets/w_route_card/chat.png" %}" alt="">
@@ -30,7 +31,7 @@
<div class="route_btn_title big">{% trans "Откликнуться" %}</div>
</div>
</div>
<div class="route_card_text_container{% if not user.is_authenticated %} msg{% endif %}">
<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 }}
@@ -58,11 +59,11 @@
<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.get_cargo_type_display }}</div></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 not user.is_authenticated %} msg{% endif %}">
<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 }}

View File

@@ -1,23 +1,24 @@
{% 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">{% trans "Забрать из:" %}</div>
<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">
<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.get_type_transport_display }}</div>
<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="">
@@ -41,13 +42,13 @@
{% endif %}
</div>
<div class="from_to_place_data">
<div class="label arrival_to">{% trans "Доставить в:" %}</div>
<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">
<div class="place_title{% if route.to_city.name|length > 14 %} gradient{% endif %}">
{{ route.to_city.name }}
</div>
</div>
@@ -61,7 +62,7 @@
</div>
{% endif %}
{% if route.owner_type == 'mover' %}
<div class="route_date_data" style="--route-date-data-justify: right;--route-date-data-margin: 10px 0 0 0;">
<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>
@@ -79,20 +80,20 @@
</div>
<div class="right_part_route_card">
<div class="from_to_place_data">
<div class="label departure_from">{% trans "Забрать из:" %}</div>
<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">
{{ route.from_city.name }}/{{ route.from_city.country.name }}
<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.get_type_transport_display }}</div>
<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="">
@@ -120,14 +121,14 @@
{% endif %}
</div>
<div class="from_to_place_data">
<div class="label arrival_to">{% trans "Доставить в:" %}</div>
<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">
{{ route.to_city.name }}/{{ route.to_city.country.name }}
<div class="place_title gradient">
{{ route.to_city.name }}
</div>
</div>
</div>

View File

@@ -1,7 +1,7 @@
{% load static %}
{% 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="field_container" data-type="radio" data-name="type_transport">
{% trans "Обязательно учитывайте Правила и особенности перевозки выбранным Вами видом транспорта" as attention_type_transport %}
@@ -16,12 +16,12 @@
<div class="form_line _50_grid">
<div class="field_container" data-type="location" data-name="from_city">
<label for="id_from_city"><div class="required_field_icon">*</div> {% trans "Откуда забрать посылку" %}</label>
{% include 'v2/widgets/w_select_country.html' with name='from_city' placeholder=placeholder_for_city initial=form.initial.from_city %}
{% include 'v2/widgets/w_select_country.html' with name='from_city' placeholder=placeholder_for_city initial=form.instance.from_city %}
{% if form.errors.from_city %}<div class="error_container">{{ form.errors.from_city.0 }}</div>{% endif %}
</div>
<div class="field_container" data-type="location" data-name="to_city" data-datepicker="arrival_DT">
<label for="id_from_city"><div class="required_field_icon">*</div> {% trans "Куда доставить посылку" %}</label>
{% include 'v2/widgets/w_select_country.html' with name='to_city' placeholder=placeholder_for_city initial=form.initial.to_city %}
{% include 'v2/widgets/w_select_country.html' with name='to_city' placeholder=placeholder_for_city initial=form.instance.to_city %}
{% if form.errors.to_city %}<div class="error_container">{{ form.errors.to_city.0 }}</div>{% endif %}
</div>
</div>
@@ -35,7 +35,7 @@
<div class="form_line _50_grid">
<div class="field_container" data-type="date" data-name="arrival_DT">
<label for="id_arrival_DT"><div class="required_field_icon">*</div> {% trans "Дата доставки посылки" %}</label>
{% include 'v2/widgets/w_daterangepicker.html' with name='arrival_DT' initial=form.initial.arrival_DT %}
{% include 'v2/widgets/w_daterangepicker.html' with set_min_date='true' name='arrival_DT' initial=form.initial.arrival_DT %}
{% if form.errors.arrival_DT %}<div class="error_container">{{ form.errors.arrival_DT.0 }}</div>{% endif %}
</div>
</div>

View File

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

View File

@@ -21,8 +21,12 @@
<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"></div>
<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

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

View File

@@ -1,7 +1,7 @@
{% 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="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' %}

View File

@@ -1,7 +1,7 @@
{% 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="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' %}