Skip to content

Commit 1c0dcc1

Browse files
committed
feat(dashboard): integrate layout-based skeleton loaders on all main project pages
1 parent 5259847 commit 1c0dcc1

6 files changed

Lines changed: 206 additions & 11 deletions

File tree

apps/web-dashboard/src/pages/Auth.jsx

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,38 @@ export default function Auth() {
230230

231231
const filteredUsers = users.filter(u => u.email?.toLowerCase().includes(searchTerm.toLowerCase()));
232232

233-
if (loading) return <div className="container spinner"></div>;
233+
if (loading) return (
234+
<div className="container" style={{ maxWidth: '1200px', margin: '0 auto', paddingBottom: '4rem' }}>
235+
{/* Header Skeleton */}
236+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '2.5rem' }}>
237+
<div>
238+
<div className="skeleton" style={{ width: '180px', height: '24px', borderRadius: '4px' }} />
239+
<div className="skeleton" style={{ width: '250px', height: '14px', marginTop: '6px', borderRadius: '4px' }} />
240+
</div>
241+
<div style={{ display: 'flex', gap: '10px' }}>
242+
<div className="skeleton" style={{ width: '200px', height: '32px', borderRadius: '6px' }} />
243+
<div className="skeleton" style={{ width: '120px', height: '32px', borderRadius: '6px' }} />
244+
</div>
245+
</div>
246+
247+
{/* Main Content Layout Skeleton */}
248+
<div className="card" style={{ padding: '0', overflow: 'hidden' }}>
249+
<div style={{ padding: '16px 24px', borderBottom: '1px solid var(--color-border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
250+
<div className="skeleton" style={{ width: '100px', height: '16px', borderRadius: '4px' }} />
251+
<div className="skeleton" style={{ width: '120px', height: '32px', borderRadius: '6px' }} />
252+
</div>
253+
<div style={{ padding: '24px' }}>
254+
{/* Table skeleton */}
255+
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
256+
<div className="skeleton" style={{ width: '100%', height: '40px', borderRadius: '4px' }} />
257+
{[1, 2, 3, 4].map(i => (
258+
<div key={i} className="skeleton" style={{ width: '100%', height: '32px', borderRadius: '4px' }} />
259+
))}
260+
</div>
261+
</div>
262+
</div>
263+
</div>
264+
);
234265

235266
return (
236267
<div className="container" style={{ maxWidth: '1200px', margin: '0 auto', paddingBottom: '4rem' }}>

apps/web-dashboard/src/pages/Database.jsx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,35 @@ export default function Database() {
253253

254254
if (loadingProject) {
255255
return (
256-
<div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', height: 'calc(100vh - var(--header-height))', background: 'var(--color-bg-main)' }}>
257-
<div className="spinner"></div>
256+
<div className="db-layout" style={{ height: 'calc(100vh - var(--header-height))', display: 'flex', background: 'var(--color-bg-main)' }}>
257+
{/* Database Sidebar Skeleton */}
258+
<aside className="db-sidebar" style={{ background: 'var(--color-bg-sidebar)', borderRight: '1px solid var(--color-border)', width: '280px', display: 'flex', flexDirection: 'column', padding: '1.5rem' }}>
259+
<div className="skeleton" style={{ width: '100px', height: '16px', marginBottom: '1.5rem', borderRadius: '4px' }} />
260+
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', flex: 1 }}>
261+
{[1, 2, 3, 4].map(i => (
262+
<div key={i} className="skeleton" style={{ width: '80%', height: '24px', borderRadius: '4px' }} />
263+
))}
264+
</div>
265+
</aside>
266+
267+
{/* Database Main Skeleton */}
268+
<main className="db-main" style={{ flex: 1, display: 'flex', flexDirection: 'column', margin: '12px', border: '1px solid var(--color-border)', borderRadius: '8px', background: 'var(--color-bg-card)', padding: '1.5rem' }}>
269+
{/* Header skeleton */}
270+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '1.5rem' }}>
271+
<div className="skeleton" style={{ width: '120px', height: '20px', borderRadius: '4px' }} />
272+
<div style={{ display: 'flex', gap: '8px' }}>
273+
<div className="skeleton" style={{ width: '120px', height: '32px', borderRadius: '6px' }} />
274+
<div className="skeleton" style={{ width: '80px', height: '32px', borderRadius: '6px' }} />
275+
</div>
276+
</div>
277+
{/* Table skeleton */}
278+
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', flex: 1 }}>
279+
<div className="skeleton" style={{ width: '100%', height: '40px', borderRadius: '4px' }} />
280+
{[1, 2, 3, 4, 5].map(i => (
281+
<div key={i} className="skeleton" style={{ width: '100%', height: '32px', borderRadius: '4px' }} />
282+
))}
283+
</div>
284+
</main>
258285
</div>
259286
);
260287
}

apps/web-dashboard/src/pages/MailPlatform.jsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,34 @@ export default function MailPlatform() {
231231
};
232232

233233
if (loading) return (
234-
<div className="container" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '60vh' }}>
235-
<div className="spinner" />
234+
<div className="container" style={{ maxWidth: '1200px', margin: '0 auto', paddingBottom: '4rem', padding: '0 1rem' }}>
235+
{/* Header Skeleton */}
236+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '2rem', flexWrap: 'wrap', gap: '1rem' }}>
237+
<div style={{ display: 'flex', gap: '14px', alignItems: 'center' }}>
238+
<div className="skeleton" style={{ width: '44px', height: '44px', borderRadius: '10px' }} />
239+
<div>
240+
<div className="skeleton" style={{ width: '150px', height: '24px', borderRadius: '4px' }} />
241+
<div className="skeleton" style={{ width: '220px', height: '14px', marginTop: '6px', borderRadius: '4px' }} />
242+
</div>
243+
</div>
244+
</div>
245+
246+
{/* Navigation Tabs Skeleton */}
247+
<div style={{ display: 'flex', gap: '10px', marginBottom: '2rem', borderBottom: '1px solid var(--color-border)', paddingBottom: '0.75rem' }}>
248+
<div className="skeleton" style={{ width: '100px', height: '32px', borderRadius: '6px' }} />
249+
<div className="skeleton" style={{ width: '100px', height: '32px', borderRadius: '6px' }} />
250+
<div className="skeleton" style={{ width: '100px', height: '32px', borderRadius: '6px' }} />
251+
</div>
252+
253+
{/* Body Skeleton */}
254+
<div className="card" style={{ padding: '2rem' }}>
255+
<div className="skeleton" style={{ width: '200px', height: '18px', marginBottom: '1.5rem', borderRadius: '4px' }} />
256+
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
257+
<div className="skeleton" style={{ width: '100%', height: '14px', borderRadius: '4px' }} />
258+
<div className="skeleton" style={{ width: '90%', height: '14px', borderRadius: '4px' }} />
259+
<div className="skeleton" style={{ width: '80%', height: '14px', borderRadius: '4px' }} />
260+
</div>
261+
</div>
236262
</div>
237263
);
238264

apps/web-dashboard/src/pages/ProjectDetails.jsx

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,90 @@ function ProjectDetails() {
102102
}, [completeStep, loading, project, projectId, searchParams, setSearchParams, user?.isVerified]);
103103

104104
if (loading) return (
105-
<div className="container" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '60vh', color: 'var(--color-text-muted)', gap: '10px' }}>
106-
<div className="spinner"></div>
105+
<div className="container" style={{ maxWidth: '1200px', margin: '0 auto', paddingBottom: '4rem' }}>
106+
{/* Header Skeleton */}
107+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '2.5rem' }}>
108+
<div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
109+
<div className="skeleton" style={{ width: '42px', height: '42px', borderRadius: '10px' }} />
110+
<div>
111+
<div className="skeleton" style={{ width: '180px', height: '24px', borderRadius: '4px' }} />
112+
<div className="skeleton" style={{ width: '220px', height: '14px', marginTop: '6px', borderRadius: '4px' }} />
113+
</div>
114+
</div>
115+
<div className="skeleton" style={{ width: '80px', height: '32px', borderRadius: '6px' }} />
116+
</div>
117+
118+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 380px', gap: '2.5rem' }}>
119+
{/* Left Column Skeleton */}
120+
<div style={{ display: 'flex', flexDirection: 'column', gap: '2.5rem' }}>
121+
{/* Traffic Card Skeleton */}
122+
<div>
123+
<div className="skeleton" style={{ width: '120px', height: '16px', marginBottom: '0.75rem', borderRadius: '4px' }} />
124+
<div className="card" style={{ padding: '1.25rem' }}>
125+
<div style={{ display: 'flex', gap: '2rem', marginBottom: '1.5rem' }}>
126+
<div style={{ width: '100px' }}>
127+
<div className="skeleton" style={{ width: '70px', height: '10px', borderRadius: '4px' }} />
128+
<div className="skeleton" style={{ width: '50px', height: '18px', marginTop: '6px', borderRadius: '4px' }} />
129+
</div>
130+
<div style={{ width: '100px' }}>
131+
<div className="skeleton" style={{ width: '75px', height: '10px', borderRadius: '4px' }} />
132+
<div className="skeleton" style={{ width: '60px', height: '18px', marginTop: '6px', borderRadius: '4px' }} />
133+
</div>
134+
</div>
135+
<div className="skeleton" style={{ width: '100%', height: '180px', borderRadius: '8px' }} />
136+
</div>
137+
</div>
138+
{/* Quickstart Tabs Skeleton */}
139+
<div>
140+
<div className="skeleton" style={{ width: '150px', height: '16px', marginBottom: '0.75rem', borderRadius: '4px' }} />
141+
<div className="card" style={{ padding: '1.5rem', height: '250px' }}>
142+
<div style={{ display: 'flex', gap: '1rem', marginBottom: '1.5rem', borderBottom: '1px solid var(--color-border)', paddingBottom: '0.75rem' }}>
143+
<div className="skeleton" style={{ width: '80px', height: '16px', borderRadius: '4px' }} />
144+
<div className="skeleton" style={{ width: '80px', height: '16px', borderRadius: '4px' }} />
145+
<div className="skeleton" style={{ width: '80px', height: '16px', borderRadius: '4px' }} />
146+
</div>
147+
<div className="skeleton" style={{ width: '100%', height: '14px', borderRadius: '4px' }} />
148+
<div className="skeleton" style={{ width: '90%', height: '14px', marginTop: '8px', borderRadius: '4px' }} />
149+
<div className="skeleton" style={{ width: '80%', height: '14px', marginTop: '8px', borderRadius: '4px' }} />
150+
</div>
151+
</div>
152+
</div>
153+
154+
{/* Right Column Skeleton */}
155+
<div style={{ display: 'flex', flexDirection: 'column', gap: '2.5rem' }}>
156+
{/* Status Card Skeleton */}
157+
<div>
158+
<div className="skeleton" style={{ width: '100px', height: '16px', marginBottom: '0.75rem', borderRadius: '4px' }} />
159+
<div className="card" style={{ padding: '1.25rem' }}>
160+
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '1rem' }}>
161+
<div className="skeleton" style={{ width: '120px', height: '14px', borderRadius: '4px' }} />
162+
<div className="skeleton" style={{ width: '80px', height: '14px', borderRadius: '4px' }} />
163+
</div>
164+
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
165+
<div className="skeleton" style={{ width: '100px', height: '14px', borderRadius: '4px' }} />
166+
<div className="skeleton" style={{ width: '90px', height: '14px', borderRadius: '4px' }} />
167+
</div>
168+
</div>
169+
</div>
170+
{/* Collections Card Skeleton */}
171+
<div>
172+
<div className="skeleton" style={{ width: '120px', height: '16px', marginBottom: '0.75rem', borderRadius: '4px' }} />
173+
<div className="card" style={{ padding: '0', overflow: 'hidden' }}>
174+
<div style={{ padding: '12px 16px', background: 'var(--color-surface-hover)' }}>
175+
<div className="skeleton" style={{ width: '60px', height: '12px', borderRadius: '4px' }} />
176+
</div>
177+
<div style={{ padding: '16px', display: 'flex', flexDirection: 'column', gap: '1rem' }}>
178+
{[1, 2, 3].map(i => (
179+
<div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
180+
<div className="skeleton" style={{ width: '100px', height: '14px', borderRadius: '4px' }} />
181+
<div className="skeleton" style={{ width: '50px', height: '14px', borderRadius: '4px' }} />
182+
</div>
183+
))}
184+
</div>
185+
</div>
186+
</div>
187+
</div>
188+
</div>
107189
</div>
108190
);
109191

apps/web-dashboard/src/pages/ProjectSettings.jsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,28 @@ export default function ProjectSettings() {
155155
};
156156

157157
if (loading) return (
158-
<div className="container" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '60vh' }}>
159-
<div className="spinner" />
158+
<div className="container" style={{ maxWidth: '860px', margin: '0 auto', paddingBottom: '3rem' }}>
159+
{/* Page header Skeleton */}
160+
<div style={{ display: 'flex', gap: '10px', alignItems: 'center', marginBottom: '1.5rem' }}>
161+
<div className="skeleton" style={{ width: '32px', height: '32px', borderRadius: '6px' }} />
162+
<div>
163+
<div className="skeleton" style={{ width: '150px', height: '20px', borderRadius: '4px' }} />
164+
<div className="skeleton" style={{ width: '220px', height: '12px', marginTop: '4px', borderRadius: '4px' }} />
165+
</div>
166+
</div>
167+
168+
{/* Sections Skeletons */}
169+
<div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
170+
{[1, 2, 3].map(i => (
171+
<div key={i} className="card" style={{ padding: '1.5rem' }}>
172+
<div className="skeleton" style={{ width: '150px', height: '18px', marginBottom: '1.25rem', borderRadius: '4px' }} />
173+
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
174+
<div className="skeleton" style={{ width: '100%', height: '36px', borderRadius: '6px' }} />
175+
<div className="skeleton" style={{ width: '100%', height: '36px', borderRadius: '6px' }} />
176+
</div>
177+
</div>
178+
))}
179+
</div>
160180
</div>
161181
);
162182

apps/web-dashboard/src/pages/TeamMembers.jsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,17 @@ export default function TeamMembers() {
215215
</div>
216216

217217
{loading ? (
218-
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', padding: 48 }}>
219-
<Loader2 size={24} className="spin" color="var(--text-muted)" />
218+
<div style={{ padding: '0 24px' }}>
219+
{[1, 2].map(i => (
220+
<div key={i} style={{ display: 'flex', alignItems: 'center', gap: '14px', padding: '14px 0', borderBottom: '1px solid var(--color-border)' }}>
221+
<div className="skeleton" style={{ width: '32px', height: '32px', borderRadius: '50%' }} />
222+
<div style={{ flex: 1 }}>
223+
<div className="skeleton" style={{ width: '120px', height: '14px', borderRadius: '4px' }} />
224+
<div className="skeleton" style={{ width: '180px', height: '10px', marginTop: '6px', borderRadius: '4px' }} />
225+
</div>
226+
<div className="skeleton" style={{ width: '60px', height: '20px', borderRadius: '4px' }} />
227+
</div>
228+
))}
220229
</div>
221230
) : members.length === 0 ? (
222231
<div style={{ padding: 48, textAlign: 'center', color: 'var(--text-muted)' }}>

0 commit comments

Comments
 (0)