Refactor loading states to render empty divs for better UX consistency

- Replace "Loading..." text with empty divs in various components
- Simplify loading placeholders to improve visual stability during data fetches
This commit is contained in:
Nikita
2025-12-31 18:04:45 +02:00
parent 6baa6a91ac
commit b5d55cbf54
10 changed files with 13 additions and 73 deletions

View File

@@ -233,7 +233,7 @@ export function CommentBox({ username }: CommentBoxProps) {
{/* Comments list */}
<div className="flex-1 overflow-y-auto px-4 py-3 space-y-3">
{!comments ? (
<div className="text-center text-white/40 text-sm py-4">Loading...</div>
<div className="py-4" />
) : comments.length === 0 ? (
<div className="text-center text-white/40 text-sm py-4">
No messages yet. Be the first to say hi!
@@ -275,7 +275,7 @@ export function CommentBox({ username }: CommentBoxProps) {
{/* Input area */}
<div className="border-t border-white/10 p-3">
{sessionLoading ? (
<div className="text-center text-white/40 text-sm py-2">Loading...</div>
<div className="py-2" />
) : isAuthenticated ? (
<div className="space-y-2">
{/* Image preview */}
@@ -442,11 +442,7 @@ function CommentImage({ image }: { image: FileStream }) {
}, [image])
if (!url) {
return (
<div className="mt-2 w-32 h-24 bg-white/5 rounded-lg animate-pulse flex items-center justify-center">
<span className="text-xs text-white/30">Loading...</span>
</div>
)
return <div className="mt-2 w-32 h-24 bg-white/5 rounded-lg animate-pulse" />
}
return (

View File

@@ -4,11 +4,7 @@ export function RegularPlanButton() {
const { createCheckoutSession, loaded, errors } = useBilling()
if (!loaded || !createCheckoutSession) {
return (
<button type="button" disabled>
Loading checkout
</button>
)
return <button type="button" disabled className="opacity-50" />
}
if (errors) {

View File

@@ -99,11 +99,6 @@ function ArchivePage() {
</p>
</div>
<div className="flex flex-col items-end gap-2 text-sm text-white/60">
{loading && (
<span className="text-xs uppercase tracking-[0.3em] text-white/40">
Loading
</span>
)}
<button
type="button"
className="flex items-center gap-2 rounded-full bg-white/90 px-5 py-2 text-sm font-semibold uppercase tracking-[0.3em] text-slate-900 transition hover:bg-white disabled:cursor-not-allowed disabled:bg-white/40"

View File

@@ -48,17 +48,7 @@ function CanvasDetailPage() {
}, [canvasId])
if (loading) {
return (
<div className="flex h-screen w-screen flex-col items-center justify-center gap-4 bg-[#03050a] text-white/70">
<p className="text-xs uppercase tracking-[0.4em]">Loading canvas</p>
<Link
to="/canvas"
className="text-[11px] uppercase tracking-[0.3em] text-white/40 hover:text-white"
>
Back to projects
</Link>
</div>
)
return <div className="h-screen w-screen bg-[#03050a]" />
}
if (error || !snapshot) {

View File

@@ -87,11 +87,6 @@ function CanvasProjectsPage() {
</p>
</div>
<div className="flex flex-col items-end gap-2 text-sm text-white/60">
{loading ? (
<span className="text-xs uppercase tracking-[0.3em] text-white/40">
Loading
</span>
) : null}
<button
type="button"
className="rounded-full bg-white/90 px-5 py-2 text-sm font-semibold uppercase tracking-[0.3em] text-slate-900 transition hover:bg-white disabled:cursor-not-allowed disabled:bg-white/40"

View File

@@ -86,11 +86,7 @@ function GlidePage() {
}
if (!me.$isLoaded || !root?.$isLoaded) {
return (
<div className="min-h-screen text-white grid place-items-center">
<p className="text-slate-400">Loading Jazz...</p>
</div>
)
return <div className="min-h-screen" />
}
const canvasItems: GlideCanvasItem[] = canvasList?.$isLoaded ? [...canvasList] : []

View File

@@ -95,11 +95,7 @@ function Dashboard() {
}
if (!me.$isLoaded || !root?.$isLoaded) {
return (
<div className="min-h-screen bg-black text-white grid place-items-center">
<p className="text-neutral-400">Loading...</p>
</div>
)
return <div className="min-h-screen bg-black" />
}
return (
@@ -290,11 +286,7 @@ function HomePage() {
const { data: session, isPending } = authClient.useSession()
if (isPending) {
return (
<div className="min-h-screen bg-black text-white grid place-items-center">
<p className="text-neutral-400">Loading...</p>
</div>
)
return <div className="min-h-screen bg-black" />
}
if (session?.user) {

View File

@@ -57,11 +57,7 @@ function SessionsPage() {
const [importJson, setImportJson] = useState("")
if (authPending) {
return (
<div className="min-h-screen text-white grid place-items-center">
<p className="text-slate-400">Loading...</p>
</div>
)
return <div className="min-h-screen" />
}
if (!session?.user) {
@@ -83,11 +79,7 @@ function SessionsPage() {
const root = me.$isLoaded ? me.root : null
if (!me.$isLoaded || !root?.$isLoaded) {
return (
<div className="min-h-screen text-white grid place-items-center">
<p className="text-slate-400">Loading Jazz...</p>
</div>
)
return <div className="min-h-screen" />
}
// Initialize browserSessions if not present

View File

@@ -153,11 +153,7 @@ function StreamsPage() {
}
if (!me.$isLoaded || !root?.$isLoaded) {
return (
<div className="min-h-screen text-white grid place-items-center">
<p className="text-slate-400">Loading Jazz...</p>
</div>
)
return <div className="min-h-screen" />
}
const recordings: StreamRecording[] = recordingsList?.$isLoaded

View File

@@ -19,11 +19,7 @@ function UrlsPage() {
const [isAdding, setIsAdding] = useState(false)
if (authPending) {
return (
<div className="min-h-screen text-white grid place-items-center">
<p className="text-slate-400">Loading...</p>
</div>
)
return <div className="min-h-screen" />
}
if (!session?.user) {
@@ -46,11 +42,7 @@ function UrlsPage() {
const urlList = root?.$isLoaded ? root.savedUrls : null
if (!me.$isLoaded || !root?.$isLoaded) {
return (
<div className="min-h-screen text-white grid place-items-center">
<p className="text-slate-400">Loading Jazz...</p>
</div>
)
return <div className="min-h-screen" />
}
const savedUrls: SavedUrl[] = urlList?.$isLoaded ? [...urlList] : []