fix: align frontend types and forms with api_yal backend (name→first_name+last_name, token→access_token)

This commit is contained in:
valitovgaziz
2026-06-12 01:41:23 +05:00
parent ba7b757541
commit 9c793bad1b
7 changed files with 61 additions and 49 deletions
@@ -31,8 +31,7 @@
<span v-if="notifCount" class="badge">{{ notifCount }}</span>
</NuxtLink>
<NuxtLink to="/profile" class="header__profile">
<img v-if="user?.avatar" :src="user.avatar" alt="" class="avatar avatar--sm" />
<span v-else class="avatar avatar--sm header__avatar-placeholder">{{ userInitials }}</span>
<span class="avatar avatar--sm header__avatar-placeholder">{{ userInitials }}</span>
</NuxtLink>
</template>
<template v-else>
@@ -62,8 +61,8 @@ const menuOpen = ref(false)
const notifCount = ref(0)
const userInitials = computed(() => {
if (!user.value?.name) return '?'
return user.value.name.charAt(0).toUpperCase()
if (!user.value?.full_name) return '?'
return user.value.full_name.charAt(0).toUpperCase()
})
</script>
@@ -12,11 +12,10 @@ export const useAuth = () => {
}
const register = async (data: {
name: string
first_name: string
last_name: string
email: string
password: string
password_confirm: string
phone?: string
}) => {
await authStore.register(data)
}
@@ -7,14 +7,27 @@
<div class="form-group">
<label class="form-label">Имя</label>
<input
v-model="name"
v-model="firstName"
type="text"
class="form-input"
:class="{ 'form-input--error': errors.name }"
:class="{ 'form-input--error': errors.firstName }"
placeholder="Ваше имя"
required
/>
<span v-if="errors.name" class="form-error">{{ errors.name }}</span>
<span v-if="errors.firstName" class="form-error">{{ errors.firstName }}</span>
</div>
<div class="form-group">
<label class="form-label">Фамилия</label>
<input
v-model="lastName"
type="text"
class="form-input"
:class="{ 'form-input--error': errors.lastName }"
placeholder="Ваша фамилия"
required
/>
<span v-if="errors.lastName" class="form-error">{{ errors.lastName }}</span>
</div>
<div class="form-group">
@@ -30,16 +43,6 @@
<span v-if="errors.email" class="form-error">{{ errors.email }}</span>
</div>
<div class="form-group">
<label class="form-label">Телефон</label>
<input
v-model="phone"
type="tel"
class="form-input"
placeholder="+7 (XXX) XXX-XX-XX"
/>
</div>
<div class="form-group">
<label class="form-label">Пароль</label>
<input
@@ -91,13 +94,14 @@ definePageMeta({
middleware: 'guest',
})
const name = ref('')
const firstName = ref('')
const lastName = ref('')
const email = ref('')
const phone = ref('')
const password = ref('')
const passwordConfirm = ref('')
const errors = reactive({
name: '',
firstName: '',
lastName: '',
email: '',
password: '',
passwordConfirm: '',
@@ -108,13 +112,15 @@ const loading = ref(false)
const { register } = useAuth()
async function handleRegister() {
errors.name = ''
errors.firstName = ''
errors.lastName = ''
errors.email = ''
errors.password = ''
errors.passwordConfirm = ''
apiError.value = ''
if (!name.value) { errors.name = 'Введите имя'; return }
if (!firstName.value) { errors.firstName = 'Введите имя'; return }
if (!lastName.value) { errors.lastName = 'Введите фамилию'; return }
if (!email.value) { errors.email = 'Введите email'; return }
if (!password.value || password.value.length < 6) {
errors.password = 'Пароль минимум 6 символов'
@@ -128,11 +134,10 @@ async function handleRegister() {
loading.value = true
try {
await register({
name: name.value,
first_name: firstName.value,
last_name: lastName.value,
email: email.value,
password: password.value,
password_confirm: passwordConfirm.value,
phone: phone.value || undefined,
})
navigateTo('/')
} catch (e: any) {
@@ -18,13 +18,12 @@
<template v-else-if="user">
<div class="profile__header">
<div class="profile__avatar">
<img v-if="user.avatar" :src="user.avatar" alt="" class="avatar avatar--lg" />
<span v-else class="avatar avatar--lg profile__avatar-placeholder">
<span class="avatar avatar--lg profile__avatar-placeholder">
{{ userInitials }}
</span>
</div>
<div class="profile__info">
<h2>{{ user.name }}</h2>
<h2>{{ user.full_name }}</h2>
<p class="body-text--gray">{{ user.email }}</p>
<span class="tag" style="margin-top: 8px">
{{ user.role === 'admin' ? 'Администратор' : user.role === 'moderator' ? 'Модератор' : 'Пользователь' }}
@@ -82,8 +81,8 @@ const reviewsCount = ref(0)
const favoritesCount = ref(0)
const userInitials = computed(() => {
if (!user.value?.name) return '?'
return user.value.name.charAt(0).toUpperCase()
if (!user.value?.full_name) return '?'
return user.value.full_name.charAt(0).toUpperCase()
})
function handleLogout() {
@@ -1,5 +1,5 @@
import { defineStore } from 'pinia'
import type { User, LoginRequest, RegisterRequest } from '~/types'
import type { User, LoginRequest, RegisterRequest, AuthResponse } from '~/types'
interface AuthState {
user: User | null
@@ -23,8 +23,8 @@ export const useAuthStore = defineStore('auth', {
this.loading = true
try {
const api = useApi()
const response = await api.post<{ access_token: string; user: User }>('/auth/login', { email, password })
this.token = response.access_token
const response = await api.post<AuthResponse>('/auth/login', { email, password })
this.token = response.token
this.user = response.user
await this.fetchUser()
} finally {
@@ -36,8 +36,8 @@ export const useAuthStore = defineStore('auth', {
this.loading = true
try {
const api = useApi()
const response = await api.post<{ access_token: string; user: User }>('/auth/register', data)
this.token = response.access_token
const response = await api.post<AuthResponse>('/auth/register', data)
this.token = response.token
this.user = response.user
} finally {
this.loading = false
@@ -48,7 +48,8 @@ export const useAuthStore = defineStore('auth', {
if (!this.token) return
try {
const api = useApi()
this.user = await api.get<User>('/me')
const profile = await api.get<Partial<User>>('/me')
this.user = this.user ? { ...this.user, ...profile } : (profile as User)
} catch {
this.token = null
this.user = null
@@ -58,8 +59,8 @@ export const useAuthStore = defineStore('auth', {
async refreshToken(): Promise<boolean> {
try {
const api = useApi()
const response = await api.post<{ access_token: string }>('/auth/refresh')
this.token = response.access_token
const response = await api.post<{ token: string }>('/auth/refresh')
this.token = response.token
return true
} catch {
this.token = null
@@ -1,16 +1,19 @@
export interface User {
id: number
name: string
email: string
phone?: string
avatar?: string
first_name: string
last_name: string
full_name: string
role: 'user' | 'admin' | 'moderator'
phone?: string
city?: string
created_at?: string
updated_at?: string
}
export interface AuthTokens {
access_token: string
refresh_token?: string
token: string
expires_at: string
}
export interface LoginRequest {
@@ -19,11 +22,10 @@ export interface LoginRequest {
}
export interface RegisterRequest {
name: string
first_name: string
last_name: string
email: string
password: string
password_confirm: string
phone?: string
}
export interface ResetPasswordRequest {
@@ -98,6 +100,12 @@ export interface Review {
comments_count?: number
}
export interface AuthResponse {
token: string
expires_at: string
user: User
}
export interface ApiError {
message: string
errors?: Record<string, string[]>