50 Commits

Author SHA1 Message Date
Philip
15c9d589fe serializer 2024-03-05 20:06:38 +03:00
Philip
fa116c08c1 fix task 2024-03-05 13:47:36 +03:00
Philip
4f9129e718 sample 2024-02-28 14:10:20 +03:00
Philip
df45f3a704 not found 2024-02-25 13:41:26 +03:00
Philip
90ef093fca supscriptions 2024-02-24 19:54:57 +03:00
4331b26542 0.1.362 fix language bug redirect to main page 2024-02-22 18:54:15 +03:00
SDE
dd8a8ddd53 0.12.26 get_phone_valid_error change 2024-02-21 17:12:45 +03:00
SBD
abb0d488eb 14 2024-02-21 15:10:34 +03:00
SBD
be97b848d0 14 2024-02-21 14:56:25 +03:00
SBD
6bc112d689 13 2024-02-21 14:37:31 +03:00
SBD
dc534a0c51 12 2024-02-21 14:21:48 +03:00
SDE
e71ed05e6c 0.12.25 timezone in chat messages 2024-02-21 14:12:03 +03:00
SBD
2048ed6baf 11 2024-02-20 19:31:10 +03:00
SBD
c146bd6155 10 2024-02-20 18:57:17 +03:00
SBD
98665abf4d 9 2024-02-20 18:27:36 +03:00
SBD
9954140d3a 9 2024-02-20 17:43:08 +03:00
SBD
fafee63a64 7 2024-02-20 17:35:01 +03:00
c623d69767 0.1.361 comment red marker on mobile_header temp 2024-02-12 17:22:24 +03:00
670eb28bc0 0.1.360 add red marker on mobile_header temp 2024-02-12 17:17:21 +03:00
144ff286f6 0.1.359 add red marker on mobile_header temp 2024-02-12 17:12:44 +03:00
05f94de0b4 Merge remote-tracking branch 'origin/main' 2024-02-12 16:09:24 +03:00
c4650ce603 0.1.358 upd profile_button width 2024-02-12 16:09:13 +03:00
SDE
3971a8ee23 0.12.24 timezone in chat messages 2024-02-09 20:33:04 +03:00
SDE
a3ba6bc783 0.12.23 timezone in chat messages 2024-02-09 18:18:21 +03:00
SDE
b87df02714 0.12.22 timezone in chat messages 2024-02-09 18:01:11 +03:00
SDE
713695cf7d 0.12.21 timezone in chat messages 2024-02-09 17:00:28 +03:00
SDE
a25f30eda7 0.12.20 timezone in chat messages 2024-02-09 16:57:27 +03:00
SDE
eddb3a1858 0.12.19 timezone in chat messages 2024-02-09 15:12:10 +03:00
SDE
5a89200f1d Merge remote-tracking branch 'origin/main' 2024-02-08 14:51:27 +03:00
SDE
2f47a9e3db 0.12.18 registration mail to user 2024-02-08 14:51:19 +03:00
155b6272ec 0.1.357 upd mobile_styles.css for menu_profile 2024-02-08 14:20:50 +03:00
SDE
1479584bfc 0.12.17 change_avatar_confirm_ajax RequestDataTooBig 2024-02-05 23:02:11 +03:00
SDE
f86be5bd97 Merge remote-tracking branch 'origin/main' 2024-02-05 22:41:58 +03:00
SDE
c87a7095ad 0.12.16 change_avatar_confirm_ajax RequestDataTooBig 2024-02-05 22:41:50 +03:00
ac4df7a5f7 0.1.356 upd text_block 2024-02-05 14:34:15 +03:00
SDE
c48839ff8c 0.12.15 subscribe mailing 2024-02-02 18:50:51 +03:00
SDE
ea296e3f05 0.12.14 subscribe mailing 2024-02-02 18:15:51 +03:00
SDE
8124ed62fe 0.12.13 subscribe mailing 2024-02-02 18:08:28 +03:00
SDE
cc643d2641 0.12.12 subscribe mailing 2024-02-02 18:06:35 +03:00
SDE
6de42c5ba9 Merge remote-tracking branch 'origin/main' 2024-02-02 17:44:50 +03:00
SDE
36b7f4dee7 0.12.11 subscribe mailing 2024-02-02 17:44:43 +03:00
2328f09023 0.1.355 mailingSubscribeRequired functional UPD 2024-02-02 17:41:01 +03:00
60faeeace9 Merge remote-tracking branch 'origin/main' 2024-02-02 17:37:35 +03:00
abe53dd88b 0.1.354 mailingSubscribeRequired functional 2024-02-02 17:37:25 +03:00
SDE
c76a18c5ff Merge remote-tracking branch 'origin/main' 2024-02-02 15:51:45 +03:00
SDE
3725ce1882 0.12.10 routes order 2024-02-02 15:51:37 +03:00
6a69ff02b1 0.1.353 add font-display for lcp test 2024-02-02 15:04:30 +03:00
6ba41af305 0.1.352 small bug_fix 2024-02-02 12:50:59 +03:00
SDE
5815a08b55 0.12.9 subscribe mailing 2024-02-01 19:13:26 +03:00
SDE
7805161829 0.12.8 subscribe mailing 2024-02-01 19:07:48 +03:00
47 changed files with 532 additions and 95 deletions

1
.gitignore vendored
View File

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

View File

@@ -107,7 +107,7 @@ class Admin_User(UserAdmin):
inlines = (Admin_ProfileInline,) inlines = (Admin_ProfileInline,)
# actions = ['del_all_temp_users', ] # actions = ['del_all_temp_users', ]
ordering = ['is_staff', 'last_name', 'first_name'] ordering = ['is_staff', '-id', 'last_name', 'first_name']
# Re-register UserAdmin # Re-register UserAdmin
admin.site.unregister(User) admin.site.unregister(User)

View File

@@ -1,5 +1,19 @@
from django.template.loader import render_to_string from django.template.loader import render_to_string
def get_user_timezone_Dict(user, request=None):
tz = None
if request:
tz = request.COOKIES.get("user_tz")
if not tz and user.is_authenticated:
tz = user.user_profile.get_timezone()
if not tz:
from django.conf import settings
tz = settings.TIME_ZONE
return {'user_tz': tz}
def get_dashboard_page_content_html(request): def get_dashboard_page_content_html(request):
from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user
@@ -76,5 +90,7 @@ def get_profile_support_page_content_html(request, data=None):
} }
tpl_name = 'blocks/profile/b_support_tickets.html' tpl_name = 'blocks/profile/b_support_tickets.html'
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string(tpl_name, Dict, request=request) html = render_to_string(tpl_name, Dict, request=request)
return html return html

View File

@@ -40,7 +40,7 @@ def mailing_subscribe_ajax(request):
email = request.POST['email'] email = request.POST['email']
user = None user = None
if request.user and request.user.is_authenticated(): if request.user and request.user.is_authenticated:
user = request.user user = request.user
user.user_profile.mailing_on = True user.user_profile.mailing_on = True
user.user_profile.save(update_fields=['mailing_on']) user.user_profile.save(update_fields=['mailing_on'])
@@ -58,9 +58,9 @@ def mailing_subscribe_ajax(request):
user = None user = None
if user: if user:
redirect_url = f"{reverse('login_profile')}" redirect_url = f"{reverse('login_profile')}?mailingSubscribeRequired=true"
else: else:
redirect_url = f"{reverse('registration_page')}" redirect_url = f"{reverse('registration_page')}?mailingSubscribeRequired=true"
return JsonResponse({ return JsonResponse({
'status': 'sended', 'status': 'sended',
@@ -232,6 +232,7 @@ def chats_ajax(request):
'receivers': receivers, 'receivers': receivers,
# 'messages': cur_chat_msgs # 'messages': cur_chat_msgs
} }
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string('blocks/profile/b_chats.html', Dict, request=request) html = render_to_string('blocks/profile/b_chats.html', Dict, request=request)
return JsonResponse({'html': html}, status=200) return JsonResponse({'html': html}, status=200)
@@ -249,6 +250,7 @@ def support_tickets_ajax(request):
@login_required(login_url='/profile/login/') @login_required(login_url='/profile/login/')
def change_avatar_confirm_ajax(request): def change_avatar_confirm_ajax(request):
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.exceptions import RequestDataTooBig
if request.method != 'POST': if request.method != 'POST':
raise Http404 raise Http404
@@ -261,11 +263,15 @@ def change_avatar_confirm_ajax(request):
file = ContentFile(content) file = ContentFile(content)
request.user.user_profile.avatar.save(file_data['file_name'], file) request.user.user_profile.avatar.save(file_data['file_name'], file)
request.user.user_profile.save(update_fields=['avatar']) request.user.user_profile.save(update_fields=['avatar'])
except RequestDataTooBig:
msg = _('Слишком большой размер файла. Размер файла не должен быть больше 3МБ')
print(msg)
return JsonResponse({'error': msg}, status=400)
except Exception as e: except Exception as e:
msg = f'change_avatar_confirm_ajax Error = {str(e)}' msg = f'change_avatar_confirm_ajax Error = {str(e)}'
print(msg) print(msg)
JsonResponse({'error': msg}) return JsonResponse({'error': msg}, status=400)
return JsonResponse({'url': request.user.user_profile.avatar.url}) return JsonResponse({'url': request.user.user_profile.avatar.url})
@@ -405,6 +411,9 @@ def login_ajax(request):
user = authenticate(username=form.data['username'], password=form.data['password']) user = authenticate(username=form.data['username'], password=form.data['password'])
if user is not None: if user is not None:
auth.login(request, user) auth.login(request, user)
if 'mailingSubscribeRequired' in data and data['mailingSubscribeRequired'] == 'true':
user.user_profile.mailing_on = True
user.user_profile.save(update_fields=['mailing_on'])
else: else:
errors_Dict = { errors_Dict = {
'errors': { 'errors': {
@@ -436,7 +445,7 @@ def login_ajax(request):
def send_registration_mail(data_Dict): def send_registration_mail(data_Dict, user):
try: try:
@@ -455,7 +464,7 @@ def send_registration_mail(data_Dict):
html = render_to_string('mail/m_registration.html', Dict) html = render_to_string('mail/m_registration.html', Dict)
from BaseModels.mailSender import admin_send_mail_by_SMTPlib from BaseModels.mailSender import admin_send_mail_by_SMTPlib
mail_sets = get_mail_send_options() mail_sets = get_mail_send_options()
to = [mail_sets['sender_email'], 'web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com'] to = [user.email, 'web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
res = admin_send_mail_by_SMTPlib( res = admin_send_mail_by_SMTPlib(
mail_sets, mail_sets,
subject=subject, subject=subject,
@@ -497,6 +506,9 @@ def registration_ajax(request):
if user: if user:
auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend') auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
if 'mailingSubscribeRequired' in data and data['mailingSubscribeRequired'] == 'true':
user.user_profile.mailing_on = True
user.last_name = form.data['lastname'] user.last_name = form.data['lastname']
user.first_name = form.data['firstname'] user.first_name = form.data['firstname']
user.save() user.save()
@@ -507,7 +519,7 @@ def registration_ajax(request):
'user': user, 'user': user,
'pass': form.data['password'] 'pass': form.data['password']
} }
res = send_registration_mail(mail_Dict) res = send_registration_mail(mail_Dict, user)
res_Dict = { res_Dict = {
'redirect_url': reverse('profile_page', args=['dashboard']) 'redirect_url': reverse('profile_page', args=['dashboard'])

View File

@@ -53,6 +53,12 @@ class UserProfile(BaseModel):
mailing_on = models.BooleanField(default=False, verbose_name=_('Рассылка')) mailing_on = models.BooleanField(default=False, verbose_name=_('Рассылка'))
def get_timezone(self):
tz = None
if 'user_timezone' in self.json_data:
tz = self.json_data['user_timezone']
return tz
def save_user_alerts_to_session(self, request): def save_user_alerts_to_session(self, request):
for_save_to_session = self.get_node_by_name('for_save_to_session') for_save_to_session = self.get_node_by_name('for_save_to_session')
if for_save_to_session: if for_save_to_session:

View File

@@ -19,6 +19,9 @@ def registration_View(request):
Dict = {} Dict = {}
if request.GET and 'mailingSubscribeRequired' in request.GET and request.GET['mailingSubscribeRequired'] == 'true':
request.session['mailingSubscribeRequired'] = 'true'
# if request.p # if request.p
t = loader.get_template('pages/profile/p_registration.html') t = loader.get_template('pages/profile/p_registration.html')
@@ -46,6 +49,11 @@ def profile_page_View(request, page_name, id=None):
'page_type': 'profile' 'page_type': 'profile'
} }
if request.session and 'mailingSubscribeRequired' in request.session and request.session['mailingSubscribeRequired'] == 'true':
request.user.user_profile.mailing_on = True
request.user.user_profile.save(update_fields=['mailing_on'])
del request.session['mailingSubscribeRequired']
title = f"{_('Личный кабинет пользователя')} {request.user.first_name} {request.user.last_name}" title = f"{_('Личный кабинет пользователя')} {request.user.first_name} {request.user.last_name}"
Dict.update({ Dict.update({
@@ -125,6 +133,9 @@ def login_View(request):
'auth_google_allow': auth_google_allow 'auth_google_allow': auth_google_allow
} }
if request.GET and 'mailingSubscribeRequired' in request.GET and request.GET['mailingSubscribeRequired'] == 'true':
request.session['mailingSubscribeRequired'] = 'true'
t = loader.get_template('pages/profile/p_login.html') t = loader.get_template('pages/profile/p_login.html')
return get_inter_http_respose(t, Dict, request) return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request)) # return HttpResponse(t.render(Dict, request))

View File

@@ -3,7 +3,7 @@ from django.utils.safestring import mark_safe
def get_phone_valid_error(val): def get_phone_valid_error(val):
allow_chars = '01234567890()+ -' allow_chars = '01234567890()+ -'
error_msg = mark_safe(_('Некорректные символы в номере телефона,<br> пример корректного ввода +7 925 8600100')) error_msg = mark_safe(_('Некорректные символы в номере, введите номер в международном формате с кодом страны'))
if not val: if not val:
return None return None

View File

@@ -13,7 +13,7 @@ from django.urls import reverse
import json import json
from datetime import datetime, time from datetime import datetime, time
from django.conf import settings from django.conf import settings
from AuthApp.funcs import get_user_timezone_Dict
def get_unanswered_msgs_count_for_user(user): def get_unanswered_msgs_count_for_user(user):
@@ -56,7 +56,6 @@ def get_update_chat_Dict(data):
if data['sender'] == data['cur_user']: if data['sender'] == data['cur_user']:
user = copy.copy(sender) user = copy.copy(sender)
cur_receiver = copy.copy(receiver) cur_receiver = copy.copy(receiver)
# context_Dict.update({'user': sender})
else: else:
user = copy.copy(receiver) user = copy.copy(receiver)
cur_receiver = copy.copy(sender) cur_receiver = copy.copy(sender)
@@ -65,8 +64,9 @@ def get_update_chat_Dict(data):
# context_Dict.update({'cur_receiver': receiver}) # context_Dict.update({'cur_receiver': receiver})
context_Dict.update({ context_Dict.update({
'cur_receiver': cur_receiver, 'cur_receiver': cur_receiver,
'user': user 'user': user,
}) })
context_Dict.update(get_user_timezone_Dict(user))
if sender == receiver: if sender == receiver:
print('!') print('!')
@@ -112,7 +112,7 @@ def get_update_chat_Dict(data):
context_Dict.update({ context_Dict.update({
'messages': msgs, 'messages': msgs,
'MEDIA_URL': settings.MEDIA_URL 'MEDIA_URL': settings.MEDIA_URL,
}) })
html = render_to_string(tpl_name, context_Dict) html = render_to_string(tpl_name, context_Dict)
if required_full_support_chat_html: if required_full_support_chat_html:
@@ -288,6 +288,7 @@ def send_msg(data):
def get_chat_page_content_html(request, receiver_id=None): def get_chat_page_content_html(request, receiver_id=None):
from AuthApp.models import User from AuthApp.models import User
from AuthApp.funcs import get_user_timezone_Dict
msgs = [] msgs = []
try: try:
@@ -307,6 +308,7 @@ def get_chat_page_content_html(request, receiver_id=None):
'receivers': receivers, 'receivers': receivers,
'page': 'chat', 'page': 'chat',
} }
Dict.update(get_user_timezone_Dict(request.user, request=request))
tpl_name = 'blocks/profile/b_chats.html' tpl_name = 'blocks/profile/b_chats.html'
html = render_to_string(tpl_name, Dict, request=request) html = render_to_string(tpl_name, Dict, request=request)

View File

@@ -53,6 +53,7 @@ def show_chat_w_user_ajax(request):
data = json.loads(request.body) data = json.loads(request.body)
Dict = get_chat_page_content_Dict(request, data['user_id']) Dict = get_chat_page_content_Dict(request, data['user_id'])
Dict.update(get_user_timezone_Dict(request.user, request=request))
tpl_name = 'blocks/profile/b_chats.html' tpl_name = 'blocks/profile/b_chats.html'
@@ -99,7 +100,7 @@ def update_chat_ajax2(request):
receiver = User.objects.get(id=data['receiver']) receiver = User.objects.get(id=data['receiver'])
context_Dict.update({'cur_receiver': receiver}) context_Dict.update({'cur_receiver': receiver})
context_Dict.update(get_user_timezone_Dict(request.user, request=request))
if not ticket: if not ticket:
@@ -123,6 +124,7 @@ def update_chat_ajax2(request):
# формируем правую панель # формируем правую панель
context_Dict.update({'receivers': receivers}) context_Dict.update({'receivers': receivers})
users_list_html = render_to_string( users_list_html = render_to_string(
'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request) 'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request)
res_Dict.update({ res_Dict.update({
@@ -190,6 +192,7 @@ def update_chat_ajax(request):
receiver = User.objects.get(id=data['receiver']) receiver = User.objects.get(id=data['receiver'])
context_Dict.update({'cur_receiver': receiver}) context_Dict.update({'cur_receiver': receiver})
context_Dict.update(get_user_timezone_Dict(request.user, request=request))
if ticket: if ticket:
@@ -201,6 +204,8 @@ def update_chat_ajax(request):
context_Dict.update({'messages': msgs}) context_Dict.update({'messages': msgs})
context_Dict = get_ticketsDict_for_staff(request.user) context_Dict = get_ticketsDict_for_staff(request.user)
context_Dict.update(get_user_timezone_Dict(request.user))
tickets_list_html = render_to_string( tickets_list_html = render_to_string(
'blocks/profile/b_list_of_tickets_support_chat.html', context_Dict, request=request) 'blocks/profile/b_list_of_tickets_support_chat.html', context_Dict, request=request)
res_Dict.update({ res_Dict.update({
@@ -220,6 +225,8 @@ def update_chat_ajax(request):
required_beep = True required_beep = True
context_Dict.update({'receivers': receivers}) context_Dict.update({'receivers': receivers})
context_Dict.update(get_user_timezone_Dict(request.user))
users_list_html = render_to_string( users_list_html = render_to_string(
'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request) 'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request)
res_Dict.update({ res_Dict.update({
@@ -408,8 +415,10 @@ def support_show_chat_by_ticket_ajax(request):
} }
Dict.update(get_ticketsDict_for_staff(request.user)) Dict.update(get_ticketsDict_for_staff(request.user))
tpl_name = 'blocks/profile/b_support_chat.html' Dict.update(get_user_timezone_Dict(request.user))
tpl_name = 'blocks/profile/b_support_chat.html'
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string(tpl_name, Dict, request=request) html = render_to_string(tpl_name, Dict, request=request)
return JsonResponse({'html': html}, status=200) return JsonResponse({'html': html}, status=200)
@@ -429,6 +438,9 @@ def support_create_ticket_form_ajax(request):
Dict = { Dict = {
'form': TicketForm() 'form': TicketForm()
} }
Dict.update(get_user_timezone_Dict(request.user))
tpl_name = 'blocks/profile/b_create_ticket.html' tpl_name = 'blocks/profile/b_create_ticket.html'
html = render_to_string(tpl_name, Dict, request=request) html = render_to_string(tpl_name, Dict, request=request)
@@ -450,6 +462,8 @@ def create_ticket_ajax(request):
if not form.is_valid(): if not form.is_valid():
form.initial = form.cleaned_data form.initial = form.cleaned_data
Dict = {'form': form} Dict = {'form': form}
Dict.update(get_user_timezone_Dict(request.user))
html = render_to_string('blocks/profile/b_create_ticket.html', Dict, request=request) html = render_to_string('blocks/profile/b_create_ticket.html', Dict, request=request)
return JsonResponse({'html': html}, status=400) return JsonResponse({'html': html}, status=400)
@@ -490,6 +504,8 @@ def create_ticket_ajax(request):
'messages': msgs_for_ticket 'messages': msgs_for_ticket
} }
Dict.update(get_user_timezone_Dict(request.user))
html = render_to_string('blocks/profile/b_support_chat.html', Dict, request=request) html = render_to_string('blocks/profile/b_support_chat.html', Dict, request=request)
res_Dict = { res_Dict = {
@@ -500,9 +516,11 @@ def create_ticket_ajax(request):
except Exception as e: except Exception as e:
msg = f'{_("ошибка в запросе")} = {str(e)}'
errors_Dict = { errors_Dict = {
'errors': { 'errors': {
'all__': f'{_("ошибка в запросе")} = {str(e)}' 'all__': msg
} }
} }
Dict = {'form': errors_Dict} Dict = {'form': errors_Dict}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
celery -A TWB.celery:app worker -l info
celery -A TWB.celery:app beat -l info

View File

@@ -223,7 +223,7 @@ def get_routes_Dict(user=None, data=None):
if key == 'to_el': if key == 'to_el':
to_el = int(val) to_el = int(val)
routes = Route.objects.filter(**kwargs).order_by('departure_DT', 'arrival_DT', '-modifiedDT') routes = Route.objects.filter(**kwargs).order_by('-departure_DT', '-arrival_DT', '-modifiedDT')
routes_count = routes.count() routes_count = routes.count()
if from_el and to_el: if from_el and to_el:

View File

@@ -0,0 +1,7 @@
from rest_framework import serializers
class SubscribersSerializer(serializers.Serializer):
email = serializers.EmailField(error_messages={'invalid': 'Invalid email'})
email_notification = serializers.BooleanField()
auto_subscribe = serializers.BooleanField()

9
SubscribesApp/urls.py Normal file
View File

@@ -0,0 +1,9 @@
from django.urls import path
from SubscribesApp.views import SubscribersView
urlpatterns = [
path('auto-subscribe/', SubscribersView.as_view(), name='auto_subscribe'),
]

View File

@@ -1,3 +1,43 @@
from django.shortcuts import render from django.contrib.auth.models import User
from django.http import JsonResponse
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
# Create your views here. from SubscribesApp.models import SubscribeForUser
from SubscribesApp.serializers import SubscribersSerializer
class SubscribersView(APIView):
# permission_classes = [IsAuthenticated]
def post(self, request):
serializer = SubscribersSerializer(data=request.data)
if serializer.is_valid():
validated_data = serializer.validated_data
email = validated_data['email']
email_notification = validated_data['email_notification']
auto_subscribe = validated_data['auto_subscribe']
user = User.objects.filter(email=email)
if user:
subscribe_for_user = SubscribeForUser.objects.filter(user_id=user[0].id)
if email_notification:
subscribe_for_user.update(receive_finish_subscribe_msg=True)
else:
subscribe_for_user.update(receive_finish_subscribe_msg=False)
if auto_subscribe:
subscribe_for_user.update(auto_continue=True)
else:
subscribe_for_user.update(auto_continue=False)
return JsonResponse({"message": "Subscriptions updated successfully"}, status=status.HTTP_200_OK)
else:
return JsonResponse({"message": "User not found"}, status=status.HTTP_404_NOT_FOUND)
else:
return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

27
TWB/celery.py Executable file
View File

@@ -0,0 +1,27 @@
from __future__ import absolute_import
import os
from celery import Celery
from celery.schedules import crontab
from django.conf import settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "TWB.settings")
app = Celery('bo', include=['TWB.tasks'])
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
app.conf.beat_schedule = {
'update-currency-rates': {
'task': 'TWB.tasks.check_auto_subscribe',
'schedule': crontab(minute=0, hour='*/1'),
},
'subscription_expiration_check': {
'task': 'TWB.tasks.subscription_expiration_check',
'schedule': crontab(hour=0, minute=0),
# 'schedule': crontab(minute='*', hour='*'),
},
}
app.conf.broker_url = settings.CELERY_BROKER_URL

View File

@@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.2/ref/settings/
""" """
from pathlib import Path from pathlib import Path
from decouple import config
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
@@ -60,7 +61,6 @@ AUTHENTICATION_BACKENDS = [
] ]
SOCIALACCOUNT_PROVIDERS = { SOCIALACCOUNT_PROVIDERS = {
'google': { 'google': {
'SCOPE': [ 'SCOPE': [
@@ -126,6 +126,8 @@ MIDDLEWARE = [
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'AuthApp.middleware.ResponseInterceptionMiddleware', 'AuthApp.middleware.ResponseInterceptionMiddleware',
'TWB.tz_middelware.TimezoneMiddleware',
# 'tz_detect.middleware.TimezoneMiddleware',
"allauth.account.middleware.AccountMiddleware", "allauth.account.middleware.AccountMiddleware",
] ]
@@ -170,11 +172,8 @@ CHANNEL_LAYERS = {
} }
POSTGRES_DB = config('POSTGRES_DB')
POSTGRES_USER = config('POSTGRES_USER')
# Database # Database
@@ -183,8 +182,8 @@ CHANNEL_LAYERS = {
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'twbDB', 'NAME': POSTGRES_DB,
'USER': 'test_user', 'USER': POSTGRES_USER,
'PASSWORD': 'test_db_pass', 'PASSWORD': 'test_db_pass',
'HOST': '127.0.0.1', 'HOST': '127.0.0.1',
'PORT': '5432', 'PORT': '5432',
@@ -270,6 +269,7 @@ django.conf.locale.LANG_INFO = LANG_INFO
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DATA_UPLOAD_MAX_MEMORY_SIZE = 4145728
CKEDITOR_BASEPATH = "/static/ckeditor/ckeditor/" CKEDITOR_BASEPATH = "/static/ckeditor/ckeditor/"
CKEDITOR_UPLOAD_PATH = "uploads/" CKEDITOR_UPLOAD_PATH = "uploads/"
@@ -333,6 +333,16 @@ CKEDITOR_CONFIGS = {
} }
} }
CELERY_BROKER_URL = config('CELERY_BROKER_URL')
CELERY_RESULT_BACKEND = config('CELERY_RESULT_BACKEND')
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = config('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD')
# CKEDITOR_OPTIONS = { # CKEDITOR_OPTIONS = {
# 'height': 291, # 'height': 291,

40
TWB/tasks.py Normal file
View File

@@ -0,0 +1,40 @@
from datetime import datetime, timedelta, timezone
from SubscribesApp.models import SubscribeForUser
from TWB import settings
from TWB.celery import app
from django.core.mail import send_mail
@app.task
def check_auto_subscribe():
current_time = datetime.now()
subscribes = SubscribeForUser.objects.filter(auto_continue=True)
if subscribes:
for subscribe in subscribes:
if subscribe.paid_period_to_DT and subscribe.paid_period_to_DT <= current_time + timedelta(hours=1):
user_email = subscribe.user.email
subject = 'Подписка продлена!'
message = 'Ваша подписка успешно продлена!'
send_mail(subject, message, settings.EMAIL_HOST_USER, [user_email], fail_silently=False)
else:
print('Нету подписок')
@app.task
def subscription_expiration_check():
current_time = datetime.now()
subscribes = SubscribeForUser.objects.filter(paid_period_to_DT__gte=current_time)
if subscribes:
for subscribe in subscribes:
expiration_date = subscribe.paid_period_to_DT
remaining_days = (expiration_date - current_time).days
if remaining_days <= 7:
message = f'Ваша подписка заканчивается через {remaining_days} дня. Пожалуйста, продлите её.'
user_email = subscribe.user.email
subject = 'Подписка истекает!'
send_mail(subject, message, settings.EMAIL_HOST_USER, [user_email], fail_silently=False)
else:
print('Нету подписок')

22
TWB/tz_middelware.py Normal file
View File

@@ -0,0 +1,22 @@
import zoneinfo
from django.utils import timezone
from django.shortcuts import render
class TimezoneMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
tz = request.COOKIES.get("user_tz")
if tz:
if request.user.is_authenticated:
if not 'user_timezone' in request.user.user_profile.json_data or request.user.user_profile.json_data['user_timezone'] != tz:
request.user.user_profile.json_data['user_timezone'] = tz
request.user.user_profile.save(update_fields=['json_data'])
msg = f'user={str(request.user.id)} tz={str(tz)}'
print(msg)
timezone.activate(zoneinfo.ZoneInfo(tz))
else:
timezone.activate(zoneinfo.ZoneInfo("UTC"))
return self.get_response(request)

View File

@@ -1,4 +1,3 @@
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from django.conf.urls.static import static from django.conf.urls.static import static
@@ -9,10 +8,11 @@ from AuthApp.views import login_View
handler404 = Page404 handler404 = Page404
urlpatterns = [ urlpatterns = [
# path('admin/', admin.site.urls),
path('ckeditor/', include('ckeditor_uploader.urls')), path('ckeditor/', include('ckeditor_uploader.urls')),
path('i18n/', include('django.conf.urls.i18n')), path('i18n/', include('django.conf.urls.i18n')),
# path('tz_detect/', include('tz_detect.urls')),
path('accounts/signup/', login_View, name='signup'), path('accounts/signup/', login_View, name='signup'),
path('accounts/login/cancelled/', login_View), path('accounts/login/cancelled/', login_View),
@@ -37,7 +37,9 @@ urlpatterns = [
path('test_404', Page404, name='page_404'), path('test_404', Page404, name='page_404'),
path('', include('PushMessages.urls')) path('', include('PushMessages.urls')),
path('', include('SubscribesApp.urls')),
] ]
from django.conf.urls.i18n import i18n_patterns from django.conf.urls.i18n import i18n_patterns

8
env.sample Normal file
View File

@@ -0,0 +1,8 @@
EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=
POSTGRES_DB=
POSTGRES_USER=
CELERY_BROKER_URL=
CELERY_RESULT_BACKEND=

View File

@@ -580,7 +580,7 @@ msgstr ""
#: .\templates\blocks\static_pages_blocks\b_partners.html:18 #: .\templates\blocks\static_pages_blocks\b_partners.html:18
msgid "" msgid ""
"Вы можете разместить объявление о перевозке посылки и перевозчики со всего " "Вы можете разместить объявление о перевозке посылки и перевозчики со всего "
"мира откликнуться на ваше объявление или воспользовавшись поиском на сайте " "мира откликнутся на ваше объявление или воспользовавшись поиском на сайте "
"найти перевозчика, который будет готов взять Вашу посылку и доставить в " "найти перевозчика, который будет готов взять Вашу посылку и доставить в "
"указанное место наземным или авиатранспортом." "указанное место наземным или авиатранспортом."
msgstr "" msgstr ""

View File

@@ -2,7 +2,6 @@ Django==4.2.2
django-ckeditor==6.5.1 django-ckeditor==6.5.1
psycopg2-binary==2.9.6 psycopg2-binary==2.9.6
requests requests
Pillow==9.5.0
django-modeltranslation==0.18.10 django-modeltranslation==0.18.10
overpass overpass
geopy geopy
@@ -12,4 +11,7 @@ channels-redis==4.1.0
django-colorfield django-colorfield
django-webpush==0.3.5 django-webpush==0.3.5
django-allauth==0.60.0 django-allauth==0.60.0
pytz==2024.1
celery==5.3.6
djangorestframework==3.14.0
python-decouple==3.8

View File

@@ -1634,6 +1634,25 @@
} }
@media (max-width: 800px) {
.marker_messages_mobile{
position: absolute;
top: 0;
right: 0;
border-radius: 100%;
background: #ff0000;
height: 14px;
width: 15px;
}
.marker_messages_mobile.hide{
display: none;
}
.marker_messages_mobile.show{
display: block;
}
}
@media (max-width: 828px){ @media (max-width: 828px){
/*.to_address_point_txt.find_route {*/ /*.to_address_point_txt.find_route {*/
/*width: 54.6%;*/ /*width: 54.6%;*/
@@ -1694,6 +1713,7 @@
} }
@media (max-width: 699px){ @media (max-width: 699px){
.block-chat.support { .block-chat.support {
/*height: calc(100vh - 190px);*/ /*height: calc(100vh - 190px);*/
/*1. 100svh 2. 45px - header 3. name_ticket 4. just padding */ /*1. 100svh 2. 45px - header 3. name_ticket 4. just padding */
@@ -1746,6 +1766,28 @@
background: #FFF; background: #FFF;
} }
.menu_buttons.right.open .menu_profile{
padding-top: unset;
}
.menu_profile>div{
height: 30px;
margin-top: 3px;
margin-bottom: 8px;
}
#customer>.text_btn_profile, #mover>.text_btn_profile{
top: 8px;
}
/*.text_btn_profile{*/
/* top: 14px;*/
/*}*/
.menu_profile > .subscribe_type_txt{
margin-bottom: 12px;
padding-top: 12px;
}
.menu_profile>div>img.svg{
margin-top: 4px;
}
.info_profile{ .info_profile{
width: 100%; width: 100%;
} }
@@ -1804,6 +1846,8 @@
} }
@media (max-width: 575px){ @media (max-width: 575px){
.phones_carrier{ .phones_carrier{
display: block; display: block;
} }
@@ -2060,6 +2104,13 @@
} }
@media (max-width: 360px){ @media (max-width: 360px){
#customer>.text_btn_profile, #mover>.text_btn_profile{
width: 53%;
}
.loader_chat_f_sw_chats.show { .loader_chat_f_sw_chats.show {
display: block; display: block;
height: 100px; height: 100px;

View File

@@ -2131,7 +2131,7 @@ a.open_inf_carrier{
.button_profile_header{ .button_profile_header{
height: 50px; height: 50px;
width: 150px; width: 155px;
background: #FF613A; background: #FF613A;
color: #FFF; color: #FFF;
/* Heading 5 */ /* Heading 5 */

View File

@@ -23,24 +23,28 @@
src: url("/static/fonts/inter/Inter-Regular.ttf") format('truetype'); src: url("/static/fonts/inter/Inter-Regular.ttf") format('truetype');
font-weight: 400; font-weight: 400;
font-style: normal; font-style: normal;
font-display: swap;
} }
@font-face{ @font-face{
font-family: 'Inter'; font-family: 'Inter';
src: url("/static/fonts/inter/Inter-Medium.ttf") format('truetype') ; src: url("/static/fonts/inter/Inter-Medium.ttf") format('truetype') ;
font-weight: 500; font-weight: 500;
font-style: normal; font-style: normal;
font-display: swap;
} }
@font-face{ @font-face{
font-family: 'Inter'; font-family: 'Inter';
src: url("/static/fonts/inter/Inter-SemiBold.ttf") format('truetype') ; src: url("/static/fonts/inter/Inter-SemiBold.ttf") format('truetype') ;
font-weight: 600; font-weight: 600;
font-style: normal; font-style: normal;
font-display: swap;
} }
@font-face{ @font-face{
font-family: 'Inter'; font-family: 'Inter';
src: url("/static/fonts/inter/Inter-Bold.ttf") format('truetype') ; src: url("/static/fonts/inter/Inter-Bold.ttf") format('truetype') ;
font-weight: 700; font-weight: 700;
font-style: normal; font-style: normal;
font-display: swap;
} }
/* Links */ /* Links */
@@ -267,11 +271,15 @@ section.register>h1 {
border-radius: 10px; border-radius: 10px;
border: 1px solid black; border: 1px solid black;
} }
.footer_input_wrap.hide{
display: none;
}
.footer_input_wrap { .footer_input_wrap {
display: flex; display: flex;
color: #FF613A;
} }
.footer_input::placeholder { .footer_input::placeholder {
color: rgba(39, 36, 36, 0.60); color: rgba(39, 36, 36, 0.60);
font-size: 16px; font-size: 16px;

View File

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

View File

@@ -39,6 +39,16 @@ function wsReceiveData (e) {
console.log(data) console.log(data)
} else if (data.type === "update_chat") { } else if (data.type === "update_chat") {
let msg_cont = document.querySelector(".container-messages") let msg_cont = document.querySelector(".container-messages")
if (getInfoAboutUser('screen_width') < 800){
if (!window.location.href.includes("chat") && !window.location.href.includes("support")){
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('hide')){
marker_new_messages.classList.add('show')
marker_new_messages.classList.remove('hide')
}
setCokie(365,'twb_new_messages',true)
}
}
update_chat_html(data,msg_cont) update_chat_html(data,msg_cont)
// document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'end',inline:'end'}); // document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'end',inline:'end'});
@@ -99,14 +109,25 @@ function wsReceiveData (e) {
} }
// } // }
// if // if
if (window.location.href.includes("chat")){
update_list_w_users(data,old_item_tab_user,el_tab) update_list_w_users(data,old_item_tab_user,el_tab)
}
} else if (data.type === "update_support_chat"){ } else if (data.type === "update_support_chat"){
update_support_chat_func(data,msg_cont) update_support_chat_func(data,msg_cont)
} }
if (data.unread_msgs_count > 0){ if (data.unread_msgs_count > 0){
if (getInfoAboutUser('screen_width') < 800){
if (!window.location.href.includes("chat") && !window.location.href.includes("support")){
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('hide')){
marker_new_messages.classList.add('show')
marker_new_messages.classList.remove('hide')
}
setCokie(365,'twb_new_messages',true)
}
}
update_count_unread_messages(data) update_count_unread_messages(data)
} }
if (data.required_beep === true) { if (data.required_beep === true) {

View File

@@ -1,4 +1,5 @@
$(document).ready(function (){ $(document).ready(function (){
hide_or_show_new_messages_marker()
checkStateCookie() checkStateCookie()
}) })
@@ -12,6 +13,7 @@ window.onload = function (){
openOrCloseCurtainSupportChat() openOrCloseCurtainSupportChat()
openOverlayOrClose() openOverlayOrClose()
goToChatIfChat() goToChatIfChat()
// let body = document.querySelector("body") // let body = document.querySelector("body")
// const viewPortH = body.getBoundingClientRect().height; // const viewPortH = body.getBoundingClientRect().height;
// const windowH = window.innerHeight; // const windowH = window.innerHeight;
@@ -43,19 +45,28 @@ window.onload = function (){
} }
} }
} }
function hide_or_show_new_messages_marker () {
if (getInfoAboutUser('screen_width') < 800){
if (window.location.href.includes("chat") || window.location.href.includes("support")){
setCokie(365,'twb_new_messages','false')
}
}
}
// //
function goToChatIfChat () { function goToChatIfChat () {
if (document.querySelector('.block-chat')){ if (document.querySelector('.block-chat')){
let scroll_el = document.querySelector('.block-chat') let scroll_el = document.querySelector('.block-chat')
if (document.querySelector(".name_ticket")){ if (document.querySelector(".name_ticket")){
scroll_el = document.querySelector(".name_ticket") scroll_el = document.querySelector(".name_ticket")
} }
let top = scroll_el.offsetTop let top = scroll_el.offsetTop
window.scrollTo({top:top}) window.scrollTo({top:top})
} document.addEventListener('focusout', function(e,scroll_el) {
document.addEventListener('focusout', function(e,scroll_el) { window.scrollTo(scroll_el, 0)
window.scrollTo(scroll_el, 0)
}); });
}
} }
@@ -131,7 +142,7 @@ function getTypeOfData (data) {
} }
function getInfoAboutUser (){ function getInfoAboutUser (screen_width){
let user_type = '' let user_type = ''
if (screen.width <= 700){ if (screen.width <= 700){
user_type = 'mobile' user_type = 'mobile'
@@ -140,7 +151,11 @@ function getInfoAboutUser (){
} else if (screen.width > 700 && screen.width <= 1180) { } else if (screen.width > 700 && screen.width <= 1180) {
user_type = 'laptop' user_type = 'laptop'
} }
return user_type if (screen_width){
return screen.width
} else {
return user_type
}
} }
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
@@ -157,17 +172,28 @@ document.addEventListener('DOMContentLoaded', function() {
img.style.backgroundPosition = "center" img.style.backgroundPosition = "center"
// img.style.backgroundSize = '50%' // img.style.backgroundSize = '50%'
} }
let login_email = document.getElementById('login_email_input')
let registration_email = document.getElementById('registration_email_input')
if(login_email){
login_email.value = sessionStorage.getItem('email')
}else if(registration_email){
registration_email.value = sessionStorage.getItem('email')
}
}); });
window.addEventListener('scroll', () => { // window.addEventListener('scroll', () => {
// let headerBG = document.getElementById('header_bg') // // let headerBG = document.getElementById('header_bg')
// // //
// headerBG.style.backgroundColor = 'rgb(248 248 248 / 90%)' // // headerBG.style.backgroundColor = 'rgb(248 248 248 / 90%)'
// headerBG.style.padding = '20px 40px' // // headerBG.style.padding = '20px 40px'
// headerBG.style.paddingBottom = 'padding: 10px 40px 10px 40px' // // headerBG.style.paddingBottom = 'padding: 10px 40px 10px 40px'
// headerBG.style.paddingRight = 'padding: 10px 40px 10px 40px' // // headerBG.style.paddingRight = 'padding: 10px 40px 10px 40px'
// headerBG.style.paddingLeft = 'padding: 10px 40px 10px 40px' // // headerBG.style.paddingLeft = 'padding: 10px 40px 10px 40px'
}) // })
// Действия при изменении URL // Действия при изменении URL
@@ -201,6 +227,23 @@ function checkStateCookie () {
if (!window.document.cookie.includes("allow_cookie=true")){ if (!window.document.cookie.includes("allow_cookie=true")){
document.querySelector(".cookie_block").classList.add("show") document.querySelector(".cookie_block").classList.add("show")
} }
if (window.document.cookie.includes("twb_new_messages=true")){
if (getInfoAboutUser('screen_width') < 800) {
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('hide')) {
marker_new_messages.classList.remove('hide')
marker_new_messages.classList.add('show')
}
}
} else if (window.document.cookie.includes("twb_new_messages=false")){
if (getInfoAboutUser('screen_width') < 800) {
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('show')) {
marker_new_messages.classList.add('hide')
marker_new_messages.classList.remove('show')
}
}
}
} }
function getCsrfCookie () { function getCsrfCookie () {
@@ -215,11 +258,15 @@ function getCsrfCookie () {
return csrf return csrf
} }
function setCokie () { function setCokie (days,name,val) {
let date = new Date(); let date = new Date();
let days = 182; // let days = 182;
date.setTime(+ date + (days * 86400000)); date.setTime(+ date + (days * 86400000));
window.document.cookie = "allow_cookie=true" + "; expires=" + date.toGMTString() + "; path=/"; window.document.cookie = `${name}=${val}` + "; expires=" + date.toGMTString() + "; path=/";
document.querySelector(".cookie_block").classList.remove("show") document.querySelector(".cookie_block").classList.remove("show")
return value; // return value;
}
function getInCookieTime (time) {
return time * 24 * 60 * 60
} }

View File

@@ -2,6 +2,8 @@ function SendRegistrationForm(el){
event.preventDefault() event.preventDefault()
let form = el.form; let form = el.form;
let formData = new FormData(form); let formData = new FormData(form);
let msr = sessionStorage.getItem('mailingSubscribeRequired')
formData.set('mailingSubscribeRequired',msr)
$.ajax({ $.ajax({
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() }, headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
@@ -16,6 +18,8 @@ function SendRegistrationForm(el){
success: function(data){ success: function(data){
location.href = `/profile/page/dashboard/` location.href = `/profile/page/dashboard/`
window.sessionStorage.removeItem('mailingSubscribeRequired')
window.sessionStorage.removeItem('email')
}, },
error: function (data, exception){ error: function (data, exception){
document.querySelector(".register").innerHTML = data.responseJSON.html document.querySelector(".register").innerHTML = data.responseJSON.html

View File

@@ -1002,9 +1002,6 @@ function subscribeNewsletter (el){
disable_btn_f.setAttribute('disabled', true); disable_btn_f.setAttribute('disabled', true);
let form = el.form; let form = el.form;
let formData = new FormData(form); let formData = new FormData(form);
let form_name = form.dataset['name'] let form_name = form.dataset['name']
@@ -1026,6 +1023,18 @@ function subscribeNewsletter (el){
// el.style.background = '#FF613A'; // el.style.background = '#FF613A';
el.removeAttribute('style') el.removeAttribute('style')
if(data.status === 'sended' && data.del_form === true){
document.querySelector('.footer_input_wrap').innerHTML = data.html;
} else if(data.redirect_url){
window.sessionStorage.setItem('email', data.email)
window.sessionStorage.setItem('mailingSubscribeRequired','true')
window.location.replace(data.redirect_url)
}
if(el.id !== 'footer_input_button'){ if(el.id !== 'footer_input_button'){
@@ -1036,12 +1045,14 @@ function subscribeNewsletter (el){
let insert_text_2 = document.querySelector(".commercial_offer") let insert_text_2 = document.querySelector(".commercial_offer")
if(insert_text_2){ if(insert_text_2){
$(data.html).insertBefore(insert_text_2) $(data.html).insertBefore(insert_text_2)
} }
} else { } else {
let disable_btn_f = document.getElementById('footer_input_button'); let disable_btn_f = document.getElementById('footer_input_button');
disable_btn_f.removeAttribute('disabled'); if(disable_btn_f){
disable_btn_f.removeAttribute('disabled');
}
let clear_footer_form = document.getElementById('clear_input'); let clear_footer_form = document.getElementById('clear_input');
clear_footer_form.reset(); clear_footer_form.reset();
@@ -1071,14 +1082,7 @@ function subscribeNewsletter (el){
// $(data.responseJSON.html).insertBefore(footer_form) // $(data.responseJSON.html).insertBefore(footer_form)
} }
// document.querySelector(".info_profile").innerHTML = data.html; // document.querySelector(".info_profile").innerHTML = data.html;
} }
}); });

View File

@@ -86,6 +86,16 @@ function select_tab_profile (el,url,owner_type=null) {
deleteMarkerMessages(el) deleteMarkerMessages(el)
checkStatesAfterTransitionToAnotherTabProfile() checkStatesAfterTransitionToAnotherTabProfile()
goToChatIfChat() goToChatIfChat()
if (window.location.href.includes("chat") || window.location.href.includes("support")) {
if (getInfoAboutUser('screen_width') < 800) {
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('show')) {
marker_new_messages.classList.remove('show')
marker_new_messages.classList.add('hide')
}
}
}
setCokie(365,'twb_new_messages','false')
}, },
error: function (data){ error: function (data){
console.log(data) console.log(data)
@@ -469,8 +479,8 @@ async function upload_photo_f_profile (el,files) {
}, },
error: function (data){ error: function (data){
document.querySelector(".avatar_user_profile").innerHTML = data.responseJSON.html; alert(data.responseJSON.error);
el.value = ''
} }
}); });
// } // }

View File

@@ -6,13 +6,12 @@
<div class="first-column"> <div class="first-column">
<div class="footer_logo"><img class="svg" src="/static/img/svg/LogoWhite.svg"></div> <div class="footer_logo"><img class="svg" src="/static/img/svg/LogoWhite.svg"></div>
<div> <div>
<div class="footer_text_sub">{% trans "Подпишись и будь в курсе всех событий, а также получай подарки и бонусы от Trip With Bonus" %}</div> {% if not user.user_profile.mailing_on %}
<div class="insert_form"> <div class="footer_text_sub">{% trans "Подпишись и будь в курсе всех событий, а также получай подарки и бонусы от Trip With Bonus" %}</div>
{% if not user.user_profile.mailing_on %} <div class="insert_form">
{% include "forms/f_one_field_form.html" %} {% include "forms/f_one_field_form.html" %}
{% endif %} </div>
</div> {% endif %}
</div> </div>

View File

@@ -6,10 +6,13 @@
<div class="wrapper_header_content"> <div class="wrapper_header_content">
<div class="header-first"> <div class="header-first">
<div class="header_logo"> <div class="header_logo">
<a href="/"><img class="svg" src="/static/img/svg/Logo.svg"></a> <a href="{% url 'main' %}">
<img class="svg" src="/static/img/svg/Logo.svg">
</a>
</div> </div>
<div class="header_logo_mobile"> <div class="header_logo_mobile">
<a href="/"><img class="svg" src="/static/img/svg/LogoMobile.svg"></a> {# <a href="/"><img class="svg" src="/static/img/svg/LogoMobile.svg"></a>#}
<a href="{% url 'main' %}"><img class="svg" src="/static/img/svg/LogoMobile.svg"></a>
</div> </div>
<div class="dropdown"> <div class="dropdown">
@@ -76,7 +79,12 @@
</div> </div>
</div> </div>
<div class="button_profile_header_mobile" onclick="open_curtain_w_btn_profile()"> <div class="button_profile_header_mobile" onclick="open_curtain_w_btn_profile()">
<div class="marker_messages_mobile hide"></div>
<img src="/static/img/svg/userMobile.svg" alt=""> <img src="/static/img/svg/userMobile.svg" alt="">
{# <div class="icon_unread_messages" style="position:absolute;right: 5px;top: 0;">#}
{# <div class="cost-messages-in-user-tab-messenger" style="background: #ff0000;">#}
{# </div>#}
{# </div>#}
</div> </div>
{# <div class="menu_profile_btn">#} {# <div class="menu_profile_btn">#}
{# {% if user_subscribe %}<div class="subscribe_type_txt"><span class="f-l">Подписка:</span> <span class="f-r">{{ user_subscribe.subscribe.name }}</span><div class="clear_both"></div></div>{% endif %}#} {# {% if user_subscribe %}<div class="subscribe_type_txt"><span class="f-l">Подписка:</span> <span class="f-r">{{ user_subscribe.subscribe.name }}</span><div class="clear_both"></div></div>{% endif %}#}
@@ -110,6 +118,7 @@
<div class="button_profile_header_mobile" onclick="show_header_list()"> <div class="button_profile_header_mobile" onclick="show_header_list()">
<div class="marker_messages_mobile hide"></div>
<img src="/static/img/svg/userMobile.svg" alt=""> <img src="/static/img/svg/userMobile.svg" alt="">
</div> </div>

View File

@@ -6,7 +6,7 @@
{%trans "Тема запроса" as p_create_ticket %} {%trans "Тема запроса" as p_create_ticket %}
<form class="form-create-ticket" name="create-ticket"> <form class="form-create-ticket" name="create-ticket">
{% if errors.all__ %}<div class="errors_all" style="margin-bottom: 12px;width: 100%;font-size: 16px;">{{ errors.all__ }}</div>{% endif %} {% if form.errors.all__ %}<div class="errors_all" style="margin-bottom: 12px;width: 100%;font-size: 16px;">{{ form.errors.all__ }}</div>{% endif %}
{% csrf_token %} {% csrf_token %}
<div class="container-input-form-create-ticket"> <div class="container-input-form-create-ticket">

View File

@@ -1,5 +1,5 @@
{% load static %} {% load static %}
{% load tz %}
{#{% include "widgets/w_file.html" %}#} {#{% include "widgets/w_file.html" %}#}
{% if not messages and ticket %} {% if not messages and ticket %}
@@ -8,7 +8,9 @@
{% for msg in messages %} {% for msg in messages %}
{% include "widgets/w_message.html" %} {% include "widgets/w_message.html" %}
{% if forloop.first %} {% if forloop.first %}
<span style="display: none" class="date_n_time_last_message" data-modifiedDT="{{ msg.modifiedDT|date:"d.m.Y H:i:s:u" }}"></span> {% timezone user_tz %}
<span style="display: none" class="date_n_time_last_message" data-modifiedDT="{{ msg.modifiedDT|date:"d.m.Y H:i:s:u" }}"></span>
{% endtimezone %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}

View File

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

View File

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

View File

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

View File

@@ -17,7 +17,14 @@
{% endif %} {% endif %}
<div class="inputs_l"> <div class="inputs_l">
<input name="username" type="text" placeholder="{{ p_login }}" {% if form.data.username %} value="{{ form.data.username }}"{% endif %}> <input
name="username"
type="text"
placeholder="{{ p_login }}"
{% if form.data.username %} value="{{ form.data.username }}"{% endif %}
id="login_email_input"
>
{% if form.username and form.errors.username %} {% if form.username and form.errors.username %}
<span>{{ form.errors.username }}</span> <span>{{ form.errors.username }}</span>
{% endif %} {% endif %}

View File

@@ -7,10 +7,16 @@
data-name="msg_from_footer" data-name="msg_from_footer"
{% if form.form_name %}data-name="{{ form.form_name}}"{% endif %} {% if form.form_name %}data-name="{{ form.form_name}}"{% endif %}
> >
<div class="footer_input_wrap"> <div
onclick="event.stopPropagation()"
class="footer_input_wrap">
<input class="footer_input" <input class="footer_input"
name="email" name="email"
type="email" type="email"
{% if user.is_authenticated %}
readonly
value="{{ user.email }}"
{% endif %}
onkeydown = "hideErrors(this)" onkeydown = "hideErrors(this)"
{% if form.data.email %} value="{{ form.data.email }}"{% endif %} {% if form.data.email %} value="{{ form.data.email }}"{% endif %}
placeholder="{% trans "Введите ваш e-mail" %}"> placeholder="{% trans "Введите ваш e-mail" %}">

View File

@@ -47,6 +47,7 @@
onkeydown = "hideErrors(this)" onkeydown = "hideErrors(this)"
type="text" type="text"
placeholder="E-mail" placeholder="E-mail"
id="registration_email_input"
{% if form.data.email %} value="{{ form.data.email }}"{% endif %}> {% if form.data.email %} value="{{ form.data.email }}"{% endif %}>
{% if form.errors and form.errors.email %} {% if form.errors and form.errors.email %}

View File

@@ -24,6 +24,7 @@
<script src="{% static "js/global_js.js" %}"></script> <script src="{% static "js/global_js.js" %}"></script>
<script src="{% static "js/chat_socket_start.js" %}"></script> <script src="{% static "js/chat_socket_start.js" %}"></script>
{% if user and not user.is_anonymous %} {% if user and not user.is_anonymous %}
{% include "connect_ws_js.html" %}
<script src='{% static "js/chat_sockets.js" %}'></script> <script src='{% static "js/chat_sockets.js" %}'></script>
<script> <script>
@@ -71,7 +72,7 @@
<div class="txt_cookie">Сайт использует файлы cookie. Просматривая этот сайт, Вы соглашаетесь <div class="txt_cookie">Сайт использует файлы cookie. Просматривая этот сайт, Вы соглашаетесь
<a class="a_cookie" href="#">с условиями использования cookie-файлов</a> <a class="a_cookie" href="#">с условиями использования cookie-файлов</a>
</div> </div>
<button class="cookie_btn" onclick="setCokie()">Понятно</button> <button class="cookie_btn" onclick="setCokie(182,'allow_cookie','true')">Понятно</button>
</div> </div>
</div> </div>
@@ -134,6 +135,14 @@
{% include 'blocks/b_footer.html' %} {% include 'blocks/b_footer.html' %}
<script>
let tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (!tz) {
tz = "UTC"
}
document.cookie = "user_tz=" + tz + ";path=/";
</script>
</body>
</body> </body>

View File

@@ -11,7 +11,9 @@
</div> </div>
{% if item.unread_msgs_count %} {% if item.unread_msgs_count %}
<div class="right-part-tab-user"> <div class="right-part-tab-user">
<div class="cost-messages-in-user-tab-messenger"><span>{{ item.unread_msgs_count }}</span></div> <div class="cost-messages-in-user-tab-messenger">
{# <span>{{ item.unread_msgs_count }}</span>#}
</div>
</div> </div>
{% endif %} {% endif %}
</div> </div>

View File

@@ -11,7 +11,9 @@
</div> </div>
{% if item.unread_msgs_count %} {% if item.unread_msgs_count %}
<div class="right-part-tab-user"> <div class="right-part-tab-user">
<div class="cost-messages-in-user-tab-messenger"><span>{{ item.unread_msgs_count }}</span></div> <div class="cost-messages-in-user-tab-messenger">
{# <span>{{ item.unread_msgs_count }}</span>#}
</div>
</div> </div>
{% endif %} {% endif %}
</div> </div>

View File

@@ -1,5 +1,6 @@
{% load static %} {% load static %}
{% load tt_chat %} {% load tt_chat %}
{% load tz %}
<div style="width: 100%;"> <div style="width: 100%;">
<div class="container-message_support_chat {% get_msg_side user ticket msg %}"> <div class="container-message_support_chat {% get_msg_side user ticket msg %}">
@@ -20,7 +21,9 @@
</div> </div>
</div> </div>
<div class="data_send_message {% get_msg_side user ticket msg %}"> <div class="data_send_message {% get_msg_side user ticket msg %}">
<span>{% if msg %}{{ msg.modifiedDT }}{% else %}{{ ticket.modifiedDT }}{% endif %}</span> {% timezone user_tz %}
<span>{% if msg %}{{ msg.modifiedDT }}{% else %}{{ ticket.modifiedDT }}{% endif %}</span>
{% endtimezone %}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,7 @@
{% load static %} {% load static %}
{% load tt_chat %} {% load tt_chat %}
{% load tz %}
<div style="width: 100%;"> <div style="width: 100%;">
<div class="container-message_support_chat {% get_msg_side user ticket msg %}"> <div class="container-message_support_chat {% get_msg_side user ticket msg %}">
@@ -34,12 +36,17 @@
{% endif %} {% endif %}
</div> </div>
<div class="data_send_message {% get_msg_side user ticket msg %}"> <div class="data_send_message {% get_msg_side user ticket msg %}">
<span>{% if msg %}{{ msg.modifiedDT }}{% else %}{{ ticket.modifiedDT }}{% endif %}</span> {% timezone user_tz %}
<span>
{% if msg %}{{ msg.modifiedDT|localtime }}{% else %}{{ ticket.modifiedDT|localtime }}{% endif %}
</span>
{% endtimezone %}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{#{% tz_detect %}#}
{#<div class="container-message_support_chat{% if msg.sender == ticket.manager %} left{% else %} right{% endif %}">#} {#<div class="container-message_support_chat{% if msg.sender == ticket.manager %} left{% else %} right{% endif %}">#}
{# <div class="block_avatar_message">#} {# <div class="block_avatar_message">#}

View File

@@ -1,5 +1,8 @@
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
{% load tz %}
<div class="container-message-req-sprt" onclick="openTicket({{ ticket.id }})"> <div class="container-message-req-sprt" onclick="openTicket({{ ticket.id }})">
<div class="message-sprt-inf"> <div class="message-sprt-inf">
<div> <div>
@@ -10,8 +13,9 @@
{# <img>#} {# <img>#}
<span id="modified_date"> <span id="modified_date">
{# 10.02.2023#} {# 10.02.2023#}
{{ ticket.modifiedDT|date:"d.m.Y" }} {% timezone user_tz %}
{{ ticket.modifiedDT|date:"d.m.Y" }}
{% endtimezone %}
</span> </span>
</div> </div>