Files
jungwoo choi 919afe56f2 feat: SAPIENS Mobile App - Initial commit
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>
2025-10-23 14:30:25 +09:00

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'] });
},
});
}