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>
This commit is contained in:
104
sapiense-ai-app/hooks/useApi.ts
Normal file
104
sapiense-ai-app/hooks/useApi.ts
Normal file
@ -0,0 +1,104 @@
|
||||
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'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user