mirror of
https://github.com/linsa-io/linsa.git
synced 2026-01-11 20:00:23 +01:00
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:
@@ -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 (
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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] : []
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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] : []
|
||||||
|
|||||||
Reference in New Issue
Block a user