fix planet
This commit is contained in:
1
.github/workflows/gh-pages.yml
vendored
1
.github/workflows/gh-pages.yml
vendored
@@ -30,5 +30,6 @@ jobs:
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./dist
|
||||
force_orphan: true
|
||||
user_name: 'ai[bot]'
|
||||
user_email: '138105980+yui-syui-ai[bot]@users.noreply.github.com'
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ package-lock.json
|
||||
yarn.lock
|
||||
**DS_Store
|
||||
.claude
|
||||
repos
|
||||
|
@@ -1,14 +1,35 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useEffect } from 'react';
|
||||
import Navigation from '../common/Navigation';
|
||||
import { fetchUsers } from '../../utils/api';
|
||||
import { fetchUsersWithCache } from '../../utils/api';
|
||||
import { api } from '../../utils/api';
|
||||
|
||||
export default function HomePage() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { data: users, isLoading } = useQuery({
|
||||
queryKey: ['users'],
|
||||
queryFn: () => fetchUsers()
|
||||
queryFn: () => fetchUsersWithCache(),
|
||||
staleTime: 0, // Always consider data stale
|
||||
});
|
||||
|
||||
// Refresh with API data after cache load
|
||||
useEffect(() => {
|
||||
if (users?.isFromCache) {
|
||||
// Fetch fresh data from API in background
|
||||
api.get('users?itemsPerPage=8000').then(response => {
|
||||
console.log('Background API fetch successful, got', response.data.length, 'users with planet data');
|
||||
// Update the query cache with fresh data
|
||||
queryClient.setQueryData(['users'], {
|
||||
data: response.data,
|
||||
isFromCache: false
|
||||
});
|
||||
}).catch(error => {
|
||||
console.error('Background API fetch failed:', error);
|
||||
});
|
||||
}
|
||||
}, [users?.isFromCache, queryClient]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center">
|
||||
|
@@ -4,17 +4,27 @@ import Navigation from '../common/Navigation';
|
||||
import CardGrid from '../card/CardGrid';
|
||||
import UserProfile from '../user/UserProfile';
|
||||
import SpecialCard from '../card/SpecialCard';
|
||||
import { fetchUsers, fetchUserCards } from '../../utils/api';
|
||||
import { fetchUsers, fetchUserCards, fetchUser } from '../../utils/api';
|
||||
|
||||
export default function UserPage() {
|
||||
const { username } = useParams<{ username: string }>();
|
||||
|
||||
// First get users list to find the user ID
|
||||
const { data: users, isLoading } = useQuery({
|
||||
queryKey: ['users'],
|
||||
queryFn: () => fetchUsers(),
|
||||
});
|
||||
|
||||
const user = users?.data.find(u => u.username === username);
|
||||
const userId = users?.data.find(u => u.username === username)?.id;
|
||||
|
||||
// Then fetch full user data from API to get planet value
|
||||
const { data: userResponse } = useQuery({
|
||||
queryKey: ['user', userId],
|
||||
queryFn: () => fetchUser(userId!),
|
||||
enabled: !!userId,
|
||||
});
|
||||
|
||||
const user = userResponse?.data || users?.data.find(u => u.username === username);
|
||||
|
||||
const { data: cards, isLoading: cardsLoading } = useQuery({
|
||||
queryKey: ['userCards', user?.id],
|
||||
|
@@ -6,14 +6,6 @@ interface UserProfileProps {
|
||||
}
|
||||
|
||||
export default function UserProfile({ user, cards }: UserProfileProps) {
|
||||
const formatPlanet = (planet: number) => {
|
||||
if (planet >= 1000000) {
|
||||
return `${(planet / 1000000).toFixed(2)}M`;
|
||||
} else if (planet >= 1000) {
|
||||
return `${(planet / 1000).toFixed(2)}K`;
|
||||
}
|
||||
return planet.toLocaleString();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-lg p-6 mb-8">
|
||||
@@ -38,7 +30,7 @@ export default function UserProfile({ user, cards }: UserProfileProps) {
|
||||
)}
|
||||
</h3>
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
|
||||
<div className="grid grid-cols-2 md:grid-cols-5 gap-4 text-sm">
|
||||
<div>
|
||||
<strong>ID:</strong> {user.id}
|
||||
</div>
|
||||
@@ -54,12 +46,10 @@ export default function UserProfile({ user, cards }: UserProfileProps) {
|
||||
<span className="icon-ai"></span>
|
||||
{cards.filter(c => c.card >= 96 && c.card <= 121).length}
|
||||
</div>
|
||||
{user.planet && (
|
||||
<div className="flex items-center gap-1">
|
||||
<i className="fa-solid fa-earth-americas"></i>
|
||||
{formatPlanet(user.planet)}
|
||||
{user.planet?.toLocaleString() || '0'}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Badge Images */}
|
||||
|
@@ -15,32 +15,44 @@ export const api = axios.create({
|
||||
// API関数
|
||||
export const fetchUsers = async (itemsPerPage = 8000): Promise<{ data: User[] }> => {
|
||||
try {
|
||||
// First try to load cached users.json for fast initial loading
|
||||
const cachedResponse = await axios.get('/json/users.json');
|
||||
|
||||
// Background fetch for fresh data
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
await api.get(`users?itemsPerPage=${itemsPerPage}`);
|
||||
} catch (error) {
|
||||
console.error('Background fetch failed:', error);
|
||||
}
|
||||
}, 100);
|
||||
|
||||
return { data: cachedResponse.data };
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch cached users:', error);
|
||||
// Fallback to API if cached JSON fails
|
||||
try {
|
||||
// Directly fetch from API to get complete user data including planet
|
||||
const response = await api.get(`users?itemsPerPage=${itemsPerPage}`);
|
||||
return { data: response.data };
|
||||
} catch (apiError) {
|
||||
console.error('API fallback failed:', apiError);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch users from API:', error);
|
||||
// Fallback to cached data (but it doesn't have planet field)
|
||||
try {
|
||||
const cachedResponse = await axios.get('/json/users.json');
|
||||
return { data: cachedResponse.data };
|
||||
} catch (cacheError) {
|
||||
console.error('Cache fallback failed:', cacheError);
|
||||
return { data: [] };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Fetch users with cache-first strategy for home page
|
||||
export const fetchUsersWithCache = async (): Promise<{ data: User[], isFromCache?: boolean }> => {
|
||||
try {
|
||||
// First, try to get cached data
|
||||
console.log('Attempting to load cached users.json');
|
||||
const cachedResponse = await axios.get('/json/users.json');
|
||||
console.log('Successfully loaded cached data:', cachedResponse.data.length, 'users');
|
||||
return { data: cachedResponse.data, isFromCache: true };
|
||||
} catch (error) {
|
||||
console.error('Cache read failed, fetching from API:', error);
|
||||
// If cache fails, fetch from API
|
||||
try {
|
||||
const response = await api.get('users?itemsPerPage=8000');
|
||||
console.log('Successfully loaded from API:', response.data.length, 'users');
|
||||
return { data: response.data, isFromCache: false };
|
||||
} catch (apiError) {
|
||||
console.error('API fetch also failed:', apiError);
|
||||
return { data: [], isFromCache: false };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchUserCards = async (userId: number, itemsPerPage = 8000): Promise<{ data: Card[] }> => {
|
||||
try {
|
||||
const response = await api.get(`users/${userId}/card?itemsPerPage=${itemsPerPage}`);
|
||||
|
Reference in New Issue
Block a user