Add loading skeletons for server data display in Servers component
This commit is contained in:
@@ -32,6 +32,37 @@ interface ServerData extends ServerInfo {
|
||||
error?: string
|
||||
}
|
||||
|
||||
// Loading Skeleton Component
|
||||
const LoadingSkeleton = ({ width = '60px', height = '40px', className = '', style = {} }: { width?: string, height?: string, className?: string, style?: React.CSSProperties }) => (
|
||||
<div
|
||||
className={`loading-skeleton ${className}`}
|
||||
style={{
|
||||
width,
|
||||
height,
|
||||
background: 'linear-gradient(135deg, var(--bg-secondary) 0%, var(--border-color) 50%, var(--bg-secondary) 100%)',
|
||||
backgroundSize: '200% 200%',
|
||||
animation: 'loading-shimmer 2.5s infinite ease-in-out, loading-pulse 1.5s infinite ease-in-out',
|
||||
borderRadius: '8px',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.08)',
|
||||
...style
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: '-100%',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
background: 'linear-gradient(90deg, transparent, rgba(255,255,255,0.12), transparent)',
|
||||
animation: 'loading-wave 2.5s infinite ease-in-out'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
function Servers() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
@@ -49,6 +80,7 @@ function Servers() {
|
||||
]
|
||||
|
||||
const [servers, setServers] = useState<ServerData[]>([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>('All')
|
||||
|
||||
// Fetch A2S data for all servers
|
||||
@@ -84,6 +116,7 @@ function Servers() {
|
||||
|
||||
const results = await Promise.all(serverPromises)
|
||||
setServers(results)
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
fetchServerData()
|
||||
@@ -174,7 +207,69 @@ function Servers() {
|
||||
gridTemplateColumns: 'repeat(auto-fit, minmax(350px, 1fr))',
|
||||
gap: '2rem'
|
||||
}}>
|
||||
{filteredServers.map((server) => (
|
||||
{loading ? (
|
||||
// Show loading skeletons
|
||||
serverList.map((_, index) => (
|
||||
<div
|
||||
key={`loading-${index}`}
|
||||
className="server-card"
|
||||
style={{
|
||||
background: 'var(--bg-secondary)',
|
||||
border: '1px solid var(--border-color)',
|
||||
borderRadius: '12px',
|
||||
padding: '1.5rem',
|
||||
position: 'relative',
|
||||
overflow: 'hidden'
|
||||
}}
|
||||
>
|
||||
{/* Status Indicator Skeleton */}
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
top: '1rem',
|
||||
right: '1rem',
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
borderRadius: '50%',
|
||||
backgroundColor: 'var(--border-color)'
|
||||
}} />
|
||||
|
||||
{/* Server Header Skeleton */}
|
||||
<div style={{ marginBottom: '1rem' }}>
|
||||
<LoadingSkeleton width="180px" height="24px" style={{ marginBottom: '0.5rem' }} />
|
||||
<div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
|
||||
<LoadingSkeleton width="60px" height="16px" />
|
||||
<LoadingSkeleton width="40px" height="16px" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Server Stats Skeleton */}
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr 1fr',
|
||||
gap: '1rem',
|
||||
marginBottom: '1rem'
|
||||
}}>
|
||||
<div>
|
||||
<LoadingSkeleton width="50px" height="14px" style={{ marginBottom: '0.25rem' }} />
|
||||
<LoadingSkeleton width="40px" height="20px" />
|
||||
</div>
|
||||
<div>
|
||||
<LoadingSkeleton width="50px" height="14px" style={{ marginBottom: '0.25rem' }} />
|
||||
<LoadingSkeleton width="40px" height="20px" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Server Details Skeleton */}
|
||||
<div style={{ marginBottom: '1rem' }}>
|
||||
<LoadingSkeleton width="120px" height="16px" style={{ marginBottom: '0.5rem' }} />
|
||||
</div>
|
||||
|
||||
{/* Join Button Skeleton */}
|
||||
<LoadingSkeleton width="100%" height="40px" />
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
filteredServers.map((server) => (
|
||||
<div
|
||||
key={`${server.ip}:${server.port}`}
|
||||
className="server-card"
|
||||
@@ -328,7 +423,8 @@ function Servers() {
|
||||
{server.status === 'online' ? t('servers.joinServer') : t('servers.offline')}
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user