Skip to content

Commit fbf57ff

Browse files
Add Skeleton Loaders for Pages During Data Fetch (#22)
* added Skeleton in Analytics and dashboard * added Skeleton in Analytics and dashboard * Update frontend/src/pages/Dashboard.jsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * added Skeleton in Overview * Delete urBackend/backend/.env --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent d3acbba commit fbf57ff

23,497 files changed

Lines changed: 3012336 additions & 10 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/src/pages/Analytics.jsx

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,40 @@ export default function Analytics() {
3232
fetchData();
3333
}, [fetchData]);
3434

35-
if (loading) return <div className="container" style={{ display: 'flex', justifyContent: 'center', marginTop: '4rem', color: '#666' }}>Loading Analytics...</div>;
35+
const SkeletonLoader = () => (
36+
<div className="container" style={{ maxWidth: '1200px', margin: '0 auto', paddingBottom: '4rem' }}>
37+
38+
{/* Stats Cards Skeleton */}
39+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '1.5rem', marginBottom: '2rem' }}>
40+
{[1,2,3].map(i => (
41+
<div key={i} className="card" style={{ padding: '1rem', position: 'relative' }}>
42+
<div className="skeleton skeleton-text" style={{ width: '40%', height: '16px' }} />
43+
<div className="skeleton skeleton-text" style={{ width: '60%', height: '36px', marginTop: '8px' }} />
44+
<div className="skeleton skeleton-text" style={{ width: '100%', height: '6px', marginTop: '12px' }} />
45+
</div>
46+
))}
47+
</div>
48+
49+
{/* Chart & Logs Skeleton */}
50+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(450px, 1fr))', gap: '2rem' }}>
51+
52+
{/* Chart Skeleton */}
53+
<div className="card" style={{ height: '400px', padding: '1.5rem', display: 'flex', flexDirection: 'column' }}>
54+
<div className="skeleton skeleton-text" style={{ width: '50%', height: '16px', marginBottom: '12px' }} />
55+
<div className="skeleton skeleton-text" style={{ width: '100%', height: '340px' }} />
56+
</div>
57+
58+
{/* Logs Skeleton */}
59+
<div className="card" style={{ height: '400px', padding: '1.5rem', overflowY: 'auto' }}>
60+
{[1,2,3,4,5,6,7,8,9,10].map(i => (
61+
<div key={i} className="skeleton-row">
62+
<div className="skeleton skeleton-text" style={{ width: '100%' }} />
63+
</div>
64+
))}
65+
</div>
66+
</div>
67+
</div>
68+
);
3669

3770
// Helper to format bytes
3871
const formatBytes = (bytes) => {
@@ -67,6 +100,11 @@ export default function Analytics() {
67100
</button>
68101
</div>
69102

103+
{/* Main Content with Skeleton*/}
104+
{loading ? (
105+
<SkeletonLoader />
106+
) : (
107+
<>
70108
{/* Stats Cards Grid */}
71109
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '1.5rem', marginBottom: '2rem' }}>
72110

@@ -236,12 +274,43 @@ export default function Analytics() {
236274
</div>
237275
</div>
238276
</div>
277+
</>
278+
)}
239279

240-
{/* Inline Styles for Spin Animation & Hover */}
280+
241281
<style>{`
282+
/* Inline Styles for Spin Animation & Hover */
283+
242284
.spin { animation: spin 1s linear infinite; }
243285
@keyframes spin { 100% { transform: rotate(360deg); } }
244286
.log-row:hover { background-color: var(--color-bg-input); }
287+
288+
/* Loading states */
289+
290+
.skeleton {
291+
position: relative;
292+
overflow: hidden;
293+
background: rgba(255,255,255,0.05);
294+
border-radius: 4px;
295+
}
296+
297+
.skeleton::after {
298+
content: '';
299+
position: absolute;
300+
top: 0; left: -150%;
301+
width: 150%; height: 100%;
302+
background: linear-gradient(
303+
90deg,
304+
transparent,
305+
rgba(255,255,255,0.08),
306+
transparent
307+
);
308+
animation: shimmer 1.8s infinite;
309+
}
310+
311+
@keyframes shimmer {
312+
100% { left: 150%; }
313+
}
245314
`}</style>
246315
</div>
247316
);

frontend/src/pages/Dashboard.jsx

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,25 @@ export default function Dashboard() {
3030
if (token) fetchProjects();
3131
}, [token]);
3232

33+
const SkeletonLoader = () => (
34+
<div
35+
style={{
36+
display: 'grid',
37+
gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',
38+
gap: '1.5rem'
39+
}}
40+
>
41+
{[1, 2, 3].map(i => (
42+
<div key={i} className="card" style={{ padding: '1.5rem' }}>
43+
<div className="skeleton skeleton-text" style={{ width: '50%', height: '14px' }} />
44+
<div className="skeleton skeleton-text" style={{ width: '100%', height: '22px', marginTop: '10px' }} />
45+
<div className="skeleton skeleton-text" style={{ width: '80%', height: '14px', marginTop: '8px' }} />
46+
<div className="skeleton skeleton-text" style={{ width: '60%', height: '14px', marginTop: '12px' }} />
47+
</div>
48+
))}
49+
</div>
50+
);
51+
3352
// Inline Styles for Cards to match Landing Page aesthetic
3453
const cardStyle = {
3554
background: 'var(--color-bg-card)',
@@ -44,12 +63,6 @@ export default function Dashboard() {
4463
overflow: 'hidden'
4564
};
4665

47-
if (isLoading) return (
48-
<div className="container" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '60vh', color: 'var(--color-text-muted)', gap: '10px' }}>
49-
<div className="spinner"></div> Loading workspace...
50-
</div>
51-
);
52-
5366
return (
5467
<div className="container" style={{ maxWidth: '1400px', margin: '0 auto', paddingBottom: '4rem' }}>
5568

@@ -112,7 +125,8 @@ export default function Dashboard() {
112125
<div style={{ height: '1px', flex: 1, background: 'var(--color-border)' }}></div>
113126
</div>
114127

115-
{projects.length === 0 ? (
128+
{isLoading ? (
129+
< SkeletonLoader /> ) : projects.length === 0 ? (
116130
<div style={{
117131
...cardStyle,
118132
textAlign: 'center',
@@ -254,6 +268,40 @@ export default function Dashboard() {
254268
animation: spin 1s linear infinite;
255269
}
256270
@keyframes spin { 100% { transform: rotate(360deg); } }
271+
272+
/* Loading states */
273+
.skeleton {
274+
position: relative;
275+
overflow: hidden;
276+
background: rgba(255,255,255,0.05);
277+
border-radius: 4px;
278+
}
279+
280+
.skeleton-text {
281+
border-radius: 2px;
282+
}
283+
284+
.skeleton::after {
285+
content: '';
286+
position: absolute;
287+
top: 0;
288+
left: -150%;
289+
width: 150%;
290+
height: 100%;
291+
background: linear-gradient(
292+
90deg,
293+
transparent,
294+
rgba(255,255,255,0.08),
295+
transparent
296+
);
297+
animation: shimmer 1.8s infinite;
298+
}
299+
300+
@keyframes shimmer {
301+
100% {
302+
left: 50%;
303+
}
304+
}
257305
`}</style>
258306
</div>
259307
);

package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

urBackend/backend/node_modules/.bin/baseline-browser-mapping

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

urBackend/backend/node_modules/.bin/baseline-browser-mapping.cmd

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

urBackend/backend/node_modules/.bin/baseline-browser-mapping.ps1

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

urBackend/backend/node_modules/.bin/bcrypt

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

urBackend/backend/node_modules/.bin/bcrypt.cmd

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

urBackend/backend/node_modules/.bin/bcrypt.ps1

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)