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

View File

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

View File

@@ -99,11 +99,6 @@ function ArchivePage() {
</p> </p>
</div> </div>
<div className="flex flex-col items-end gap-2 text-sm text-white/60"> <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 <button
type="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" 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]) }, [canvasId])
if (loading) { if (loading) {
return ( return <div className="h-screen w-screen bg-[#03050a]" />
<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>
)
} }
if (error || !snapshot) { if (error || !snapshot) {

View File

@@ -87,11 +87,6 @@ function CanvasProjectsPage() {
</p> </p>
</div> </div>
<div className="flex flex-col items-end gap-2 text-sm text-white/60"> <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 <button
type="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" 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) { if (!me.$isLoaded || !root?.$isLoaded) {
return ( return <div className="min-h-screen" />
<div className="min-h-screen text-white grid place-items-center">
<p className="text-slate-400">Loading Jazz...</p>
</div>
)
} }
const canvasItems: GlideCanvasItem[] = canvasList?.$isLoaded ? [...canvasList] : [] const canvasItems: GlideCanvasItem[] = canvasList?.$isLoaded ? [...canvasList] : []

View File

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

View File

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

View File

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

View File

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