Corp/frontend/src/hooks/useApi.ts
igor_nadein acc511f4b8 fix: исправлена ошибка notifications.slice is not a function
- Добавлена проверка Array.isArray() в NotificationCenter
- Добавлена защита от non-array в useNotifications хук
- Исправлен импорт date-fns/locale для версии 4+
- В случае ошибки API устанавливается пустой массив []
2026-02-27 19:41:20 +03:00

222 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useEffect, useState } from 'react';
import apiClient from '@/lib/api';
import type { User, Post, PaginatedResponse } from '@/types/api';
export function useCurrentUser() {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function fetchUser() {
try {
const data = await apiClient.getCurrentUser();
setUser(data);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
}
fetchUser();
}, []);
return { user, loading, error };
}
export function useEmployees(params?: { search?: string; department?: string }) {
const [employees, setEmployees] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function fetchEmployees() {
try {
setLoading(true);
const data = await apiClient.getEmployees(params);
setEmployees(data.results || data);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
}
fetchEmployees();
}, [params?.search, params?.department]);
return { employees, loading, error, refetch: () => {} };
}
export function useDepartments() {
const [departments, setDepartments] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function fetchDepartments() {
try {
const data = await apiClient.getDepartments();
setDepartments(data.results || data);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
}
fetchDepartments();
}, []);
return { departments, loading, error };
}
export function usePosts(params?: { page?: number; search?: string }) {
const [posts, setPosts] = useState<Post[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
const [hasMore, setHasMore] = useState(false);
useEffect(() => {
async function fetchPosts() {
try {
setLoading(true);
const data: PaginatedResponse<Post> = await apiClient.getPosts(params);
setPosts(data.results);
setHasMore(!!data.next);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
}
fetchPosts();
}, [params?.page, params?.search]);
return { posts, loading, error, hasMore, refetch: () => {} };
}
export function useDocuments(params?: { search?: string; type?: string }) {
const [documents, setDocuments] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function fetchDocuments() {
try {
const data = await apiClient.getDocuments(params);
setDocuments(data.results || data);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
}
fetchDocuments();
}, [params?.search, params?.type]);
return { documents, loading, error };
}
export function useRequests(params?: { status?: string; type?: string }) {
const [requests, setRequests] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function fetchRequests() {
try {
const data = await apiClient.getRequests(params);
setRequests(data.results || data);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
}
fetchRequests();
}, [params?.status, params?.type]);
return { requests, loading, error };
}
export function useChats() {
const [chats, setChats] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function fetchChats() {
try {
const data = await apiClient.getChats();
setChats(data.results || data);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
}
fetchChats();
}, []);
return { chats, loading, error };
}
export function useNotifications() {
const [notifications, setNotifications] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
const [unreadCount, setUnreadCount] = useState(0);
useEffect(() => {
async function fetchNotifications() {
try {
const data = await apiClient.getNotifications();
const notifs = data.results || data;
// Убеждаемся что notifs это массив
const notificationsArray = Array.isArray(notifs) ? notifs : [];
setNotifications(notificationsArray);
setUnreadCount(notificationsArray.filter((n: any) => !n.is_read).length);
} catch (err) {
setError(err as Error);
setNotifications([]); // В случае ошибки устанавливаем пустой массив
} finally {
setLoading(false);
}
}
fetchNotifications();
}, []);
const markAsRead = async (id: number) => {
try {
await apiClient.markNotificationAsRead(id);
setNotifications(prev =>
prev.map(n => (n.id === id ? { ...n, is_read: true } : n))
);
setUnreadCount(prev => Math.max(0, prev - 1));
} catch (err) {
console.error('Failed to mark notification as read:', err);
}
};
const markAllAsRead = async () => {
try {
await apiClient.markAllNotificationsAsRead();
setNotifications(prev => prev.map(n => ({ ...n, is_read: true })));
setUnreadCount(0);
} catch (err) {
console.error('Failed to mark all notifications as read:', err);
}
};
return { notifications, loading, error, unreadCount, markAsRead, markAllAsRead };
}