React Native mobile application for SAPIENS news platform. Consolidated all previous history into single commit. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
105 lines
3.1 KiB
TypeScript
105 lines
3.1 KiB
TypeScript
import { useQuery, useMutation, useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
|
|
import { outletsApi, articlesApi, searchApi, feedApi } from '../lib/api';
|
|
|
|
// Outlets hooks
|
|
export function useOutlets(category?: string, language = 'ko') {
|
|
return useQuery({
|
|
queryKey: ['/outlets', category, language],
|
|
queryFn: () => outletsApi.getAll(category, language),
|
|
});
|
|
}
|
|
|
|
export function useOutlet(id: string, language = 'ko') {
|
|
return useQuery({
|
|
queryKey: ['outlet', id, language],
|
|
queryFn: () => outletsApi.getById(id, language),
|
|
enabled: !!id && id.trim().length > 0,
|
|
});
|
|
}
|
|
|
|
// Articles hooks
|
|
export function useArticles(language = 'en') {
|
|
return useQuery({
|
|
queryKey: ['/articles', language],
|
|
queryFn: () => articlesApi.getAll(language),
|
|
});
|
|
}
|
|
|
|
export function useArticlesByOutlet(outletId: string, language = 'en') {
|
|
return useQuery({
|
|
queryKey: ['/articles', outletId, language],
|
|
queryFn: () => articlesApi.getByOutlet(outletId, language),
|
|
enabled: !!outletId,
|
|
});
|
|
}
|
|
|
|
export function useFeaturedArticles(limit = 10, language = 'en') {
|
|
return useQuery({
|
|
queryKey: ['/articles', 'featured', limit, language],
|
|
queryFn: () => articlesApi.getFeatured(limit, language),
|
|
});
|
|
}
|
|
|
|
export function useArticle(id: string, language = 'en', useNewsId = true) {
|
|
return useQuery({
|
|
queryKey: ['/articles', id, language, useNewsId],
|
|
queryFn: () => articlesApi.getById(id, language, useNewsId),
|
|
enabled: !!id,
|
|
});
|
|
}
|
|
|
|
// Search hooks
|
|
export function useSearch(
|
|
query: string,
|
|
type: 'all' | 'articles' | 'outlets' = 'all',
|
|
language = 'en',
|
|
outletId?: string
|
|
) {
|
|
return useQuery({
|
|
queryKey: ['/search', query, type, language, outletId],
|
|
queryFn: () => searchApi.search(query, type, language, outletId),
|
|
enabled: !!query.trim(),
|
|
});
|
|
}
|
|
|
|
export function useSearchArticles(query: string, language = 'en') {
|
|
return useQuery({
|
|
queryKey: ['/search', query, 'articles', language],
|
|
queryFn: () => searchApi.articles(query, language),
|
|
enabled: !!query.trim(),
|
|
});
|
|
}
|
|
|
|
// Feed hooks for YouTube-style interface
|
|
export function useFeed(filter: 'all' | 'people' | 'topics' | 'companies' = 'all') {
|
|
return useInfiniteQuery({
|
|
queryKey: ['/feed', filter],
|
|
queryFn: ({ pageParam }) => {
|
|
return feedApi.getFeed({
|
|
cursor: pageParam,
|
|
limit: 10,
|
|
filter: filter,
|
|
});
|
|
},
|
|
initialPageParam: undefined as string | undefined,
|
|
getNextPageParam: (lastPage: any) => lastPage?.nextCursor,
|
|
});
|
|
}
|
|
|
|
export function useIncrementView(filter?: 'all' | 'people' | 'topics' | 'companies') {
|
|
const queryClient = useQueryClient();
|
|
|
|
return useMutation({
|
|
mutationFn: feedApi.incrementView,
|
|
onSuccess: (_, articleId) => {
|
|
console.log(`[DEBUG] View incremented for article ${articleId}, invalidating cache with filter:`, filter);
|
|
if (filter) {
|
|
queryClient.invalidateQueries({ queryKey: ['/feed', filter] });
|
|
} else {
|
|
queryClient.invalidateQueries({ queryKey: ['/feed'] });
|
|
}
|
|
queryClient.invalidateQueries({ queryKey: ['/articles'] });
|
|
},
|
|
});
|
|
}
|