Почему данные не попадают в таблицу после отправки через API?
index.vue
<template>
<div class="flex flex-col gap-2">
<h1 class="text-2xl font-bold mb-4">{{ $t('system_users') }}</h1>
<div
class="flex flex-col gap-4 bg-white border border-gray-200 shadow-sm rounded-xl p-4 h-[calc(100vh-200px)]"
>
<div class="flex justify-between">
<custom-button
@click="isAddModalVisible = true"
type="button"
:text="$t('add_user')"
mode="py-2 px-4 rounded-xl bg-[#009FC2] hover:bg-[#009ec2cf] focus:ring-[#009ec2cf] shadow-sm text-white"
>
<template #icon>
<icon-add class="w-5 h-5 text-white" />
</template>
</custom-button>
<div class="flex justify-end gap-2">
<custom-search type="text" class="w-[20rem]"></custom-search>
<custom-button
type="button"
:text="$t('download_excel')"
mode="py-2 px-4 border border-gray-300 rounded-xl bg-white hover:bg-gray-100 shadow-sm"
>
<template #icon>
<icon-download class="w-5 h-5" :fontControlled="false" />
</template>
</custom-button>
</div>
</div>
<custom-data-table :columns="columns" :data="user" :loading="isLoading">
<template #cell-fullName="{ row }">
{{ row.fullName }}
</template>
<template #cell-email="{ row }">
{{ row.email }}
</template>
<template #cell-creationDate="{ row }">
{{ row.creationDate }}
</template>
<template #cell-roles="{ row }">
<div v-for="role in row.roles" :key="role.name">
{{ role.name }} ({{ role.value }})
</div>
</template>
</custom-data-table>
<custom-modal
v-model="isAddModalVisible"
:title="$t('add_user')"
:confirm-text="$t('add')"
:show-cancel="true"
@confirm="addUser"
mode="w-[880px]"
>
<template #default>
<p class="text-red-500 text-sm font-medium mb-3">
{{ $t('requirement_about_form_components') }}
</p>
<div class="grid grid-cols-2 gap-4">
<custom-input
v-model="userData.fullName"
:label="$t('user_fullname')"
name="fullName"
required
mode="border border-[#dfdfdf] rounded-[12px] px-3 py-2 w-[416px] h-[40px]"
/>
<custom-input
v-model="userData.email"
:label="$t('user_email')"
name="email"
required
mode="border border-[#dfdfdf] rounded-[12px] px-3 py-2 w-[416px] h-[40px]"
/>
<div>
<label for="role" class="block text-sm font-medium text-gray-700 mb-1">
{{ $t('user_role') }}
</label>
<custom-select
v-model="userData.role"
:id="'role'"
:name="'role'"
:data="roles"
:required="true"
:valueExpr="'name'"
:displayExpr="'name'"
:placeholder="$t('select')"
mode="border border-[#dfdfdf] rounded-[12px] px-3 py-2 w-[416px] h-[40px]"
/>
</div>
<div class="relative">
<custom-input
v-model="userData.password"
:type="isPasswordVisible ? 'text' : 'password'"
:label="$t('password')"
name="password"
required
mode="border border-[#dfdfdf] rounded-[12px] px-3 py-2 w-[416px] h-[40px]"
/>
<component
:is="isPasswordVisible ? 'icon-eye-open' : 'icon-eye-close'"
@click="togglePasswordVisibility"
class="text-[#767676] absolute right-4 top-9 cursor-pointer w-[1.5rem] h-[1rem]"
:fontControlled="false"
/>
</div>
<div class="relative">
<custom-input
v-model="userData.confirmPassword"
:type="isConfirmPasswordVisible ? 'text' : 'password'"
:label="$t('confirm_password')"
name="confirmPassword"
required
mode="border border-[#dfdfdf] rounded-[12px] px-3 py-2 w-[416px] h-[40px]"
/>
<component
:is="isConfirmPasswordVisible ? 'icon-eye-open' : 'icon-eye-close'"
@click="toggleConfirmPasswordVisibility"
class="text-[#767676] absolute right-4 top-9 cursor-pointer w-[1.5rem] h-[1rem]"
:fontControlled="false"
/>
</div>
</div>
</template>
</custom-modal>
</div>
</div>
</template>
<script lang="ts" setup>
import { useApi } from '@/composables/useApi';
import { type InternalUserResponse, type Role } from '@/types';
import { ref, onMounted, reactive } from 'vue';
import { useNuxtApp } from '#imports';
const { $toast } = useNuxtApp();
const api = useApi();
const user = ref<InternalUserResponse[]>([]); // Список пользователей
const isLoading = ref(true);
const isAddModalVisible = ref(false);
const isPasswordVisible = ref(false);
const isConfirmPasswordVisible = ref(false);
const userData = reactive<Omit<InternalUserResponse, 'roles'> & { role: string; confirmPassword: string }>({
fullName: '',
email: '',
password: '',
confirmPassword: '',
role: '',
});
const roles = ref<Role[]>([
{ name: 'Admin', value: 1 }, // Роли пользователей
{ name: 'Fond əməkdaşı', value: 2 },
{ name: 'EN əməkdaşı', value: 3 },
]);
const togglePasswordVisibility = () => {
isPasswordVisible.value = !isPasswordVisible.value;
};
const toggleConfirmPasswordVisibility = () => {
isConfirmPasswordVisible.value = !isConfirmPasswordVisible.value;
};
// Подготовка данных о ролях для API
const prepareRoles = (role: string): Role[] => {
const selectedRole = roles.value.find((r) => r.name === role);
return selectedRole ? [{ name: selectedRole.name, value: selectedRole.value }] : [];
};
// Добавление нового пользователя
const addUser = async () => {
if (userData.password !== userData.confirmPassword) {
$toast.error('Пароли не совпадают!');
return;
}
try {
const preparedData: InternalUserResponse = {
fullName: userData.fullName,
email: userData.email,
password: userData.password,
roles: prepareRoles(userData.role),
};
console.log('Отправляемые данные:', preparedData);
const response = await api.post('/api/endpoint', preparedData);
console.log('Ответ от сервера:', response);
if (response.status >= 200 && response.status < 300) {
$toast.success('Пользователь успешно создан!');
isAddModalVisible.value = false;
await loadUser();
Object.keys(userData).forEach((key) => (userData[key] = ''));
} else {
console.error('Ошибка создания пользователя:', response.status, response.data);
$toast.error('Не удалось создать пользователя. Ошибка API: ' + response.status);
}
} catch (error) {
console.error('Ошибка создания пользователя:', error);
$toast.error('Не удалось создать пользователя. ' + error.message);
if (error.response) {
console.error('Детали ошибки:', error.response.status, error.response.data);
}
}
};
// Загрузка данных о пользователях
onMounted(async () => {
await loadUser();
});
const loadUser = async () => {
try {
isLoading.value = true;
user.value = await api.get<InternalUserResponse[]>('/api/endpoint');
} catch (error) {
console.error('Ошибка загрузки пользователей:', error);
$toast.error('Не удалось загрузить пользователей.');
} finally {
isLoading.value = false;
}
};
// Колонки для таблицы
const columns = [
{ key: 'fullName', label: 'İstifadəçi adı və soyadı' },
{ key: 'email', label: 'İstifadəçi log-ini' },
{ key: 'creationDate', label: 'Yaradılma tarixi' },
{ key: 'roles', label: 'İstifadəçi rolu' },
];
</script>
index.ts
export interface InternalUserResponse {
fullName: string;
email: string;
password?: string;
roles: Role[];
}
export interface Role {
name: string;
value: number;
}
POST API Request body
{
"fullName": "string",
"email": "string",
"password": "string",
"roles": [
{
"name": "string",
"value": 0
}
]
}
GET API Responses
[
{
"id": "string",
"email": "string",
"fullName": "string"
}
]