backend - edit main tab

This commit is contained in:
2025-05-20 12:02:52 +03:00
parent c0da94f3dc
commit a132c8a314
4 changed files with 119 additions and 15 deletions

View File

@@ -4,10 +4,12 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import action
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
from api.auth.serializers import UserResponseSerializer
from api.models import UserProfile
from api.utils.decorators import handle_exceptions
class UserDataView(ViewSet):
@@ -32,4 +34,52 @@ class UserDataView(ViewSet):
return Response(
{"error": "User profile not found"},
status=status.HTTP_404_NOT_FOUND
)
)
class AccountActions(ViewSet):
permission_classes = [IsAuthenticated]
@action(detail=False, methods=['patch'])
@handle_exceptions
def change_data_main_tab(self, request):
"""Обновление данных на главной странице аккаунта"""
user = request.user
user_profile = get_object_or_404(UserProfile, user=user)
# обновляем данные пользователя
if 'firstName' in request.data:
user.first_name = request.data['firstName']
if 'lastName' in request.data:
user.last_name = request.data['lastName']
if 'email' in request.data:
email = request.data['email']
validate_email(email) # handle_exceptions обработает ValidationError
user.email = email
user.username = email
# обновляем номер телефона
if 'phone_number' in request.data:
phone = request.data['phone_number']
if phone:
if len(phone) < 13: # +375XXXXXXXXX
raise ValidationError("Номер телефона слишком короткий")
if len(phone) > 18:
raise ValidationError("Номер телефона слишком длинный")
# проверка на уникальность
if UserProfile.objects.filter(phone_number=phone).exclude(user=user).exists():
raise ValidationError("Этот номер телефона уже используется")
user_profile.phone_number = phone
# сохраняем изменения
user.save()
user_profile.save()
return Response({
"message": "Данные успешно обновлены",
"user": UserResponseSerializer(user).data
}, status=status.HTTP_200_OK)

View File

@@ -14,6 +14,8 @@ class UserResponseSerializer(serializers.Serializer):
phone_number = serializers.CharField(source='userprofile.phone_number')
image = serializers.CharField(source='userprofile.image')
uuid = serializers.SerializerMethodField()
country = serializers.CharField(source='userprofile.country')
city = serializers.CharField(source='userprofile.city')
def get_uuid(self, obj):
try:
return str(obj.userprofile.uuid)[:6]

View File

@@ -4,6 +4,7 @@ import Link from 'next/link'
import Burger from './ui/Burger'
import LangSwitcher from './LangSwitcher'
import Button from './ui/Button'
import UserLogin from './UserLogin'
const Header = () => {
return (
@@ -34,18 +35,7 @@ const Header = () => {
className="hidden md:block bg-orange hover:bg-orange/80 px-4 py-3 text-white"
/>
<div className="hidden md:block text-base font-medium">
<Link
href="/register"
className="hover:text-orange transition-colors"
>
Регистрация
</Link>
<span> / </span>
<Link href="/login" className="hover:text-orange transition-colors">
Войти
</Link>
</div>
<UserLogin />
<div className="flex items-center space-x-4 md:hidden">
<Link href="/login">

View File

@@ -0,0 +1,62 @@
'use client'
import React from 'react'
import Link from 'next/link'
import Button from './ui/Button'
import useUserStore from '@/app/store/userStore'
const UserLogin = () => {
const { isAuthenticated, user } = useUserStore()
const isUserAuth = isAuthenticated && user
// определяем отображаемое имя и путь для редиректа
const getDisplayNameAndPath = () => {
if (isUserAuth) {
return {
name: user?.name || 'пользователь',
path: '/account',
}
}
return {
name: 'Зарегистрироваться',
path: '/register',
}
}
const { name, path } = getDisplayNameAndPath()
if (!isUserAuth) {
return (
<div className="hidden md:block text-base font-medium">
<Link href="/register" className="hover:text-orange transition-colors">
Регистрация
</Link>
<span> / </span>
<Link href="/login" className="hover:text-orange transition-colors">
Войти
</Link>
</div>
)
}
return (
<Link href={path} className="ml-2 sm:ml-5">
<Button
text={isUserAuth ? `Привет, ${name}!` : name}
className={`
text-sm sm:text-base
py-2 sm:py-3
px-3 sm:px-4
bg-orange text-white
flex items-center
rounded-2xl
whitespace-nowrap
hover:bg-orange/80
`}
/>
</Link>
)
}
export default UserLogin