diff --git a/src/app/[username]/page.jsx b/src/app/[username]/page.jsx index 1a1a6f8..6f2606c 100644 --- a/src/app/[username]/page.jsx +++ b/src/app/[username]/page.jsx @@ -6,6 +6,7 @@ import toast, { Toaster } from 'react-hot-toast'; import { items } from './exportTools'; import { selects } from './selectTools'; import { checks } from './checkboxTools'; +import Loader from "@/components/Loader"; export default function previewCard({ params }) { const username = params.username; @@ -16,6 +17,7 @@ export default function previewCard({ params }) { const configCalled = useRef(false); const userConfigRef = useRef({}); const [imageUrl, setImageUrl] = useState(""); + const [loading, setLoading] = useState(false); const defaultConfig = { theme: "dark", @@ -151,8 +153,11 @@ export default function previewCard({ params }) { const fetchImage = async () => { if (isUrlComplete()) { const url = `${process.env.NEXT_PUBLIC_BASE_URL}/${username}/image?${getUrlParams(config)}`; + // Start loading until the image element confirms onLoad + setLoading(true); setImageUrl(url); } else { + setLoading(false); setImageUrl(""); } }; @@ -163,6 +168,7 @@ export default function previewCard({ params }) { return (
+ {loading && }
{imageUrl && ( @@ -170,6 +176,8 @@ export default function previewCard({ params }) { src={imageUrl} alt={`Background image of ${username}`} title={`Background preview for ${username}`} + onLoad={() => setLoading(false)} + onError={() => { setLoading(false); toast.error("Failed to load image."); }} /> )}
diff --git a/src/components/Loader.jsx b/src/components/Loader.jsx new file mode 100644 index 0000000..bc8cba4 --- /dev/null +++ b/src/components/Loader.jsx @@ -0,0 +1,14 @@ +import React from 'react' + +const Loader = ({ message = 'Loading...' }) => { + return ( +
+
+
+

{message}

+
+
+ ) +} + +export default Loader \ No newline at end of file diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index 9422a61..9b97233 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -4,10 +4,12 @@ import { useRouter } from 'next/navigation' import toast, { Toaster } from 'react-hot-toast' import Typewriter from 'typewriter-effect' import Link from 'next/link' +import Loader from '@/components/Loader' function Home() { const [username, setUserName] = useState('') const [showContributors, setShowContributors] = useState(false) + const [loading, setLoading] = useState(false) const router = useRouter() const inputRef = useRef(null) @@ -26,6 +28,7 @@ function Home() { if (username.trim()) { try { + setLoading(true) const response = await fetch('/api/user', { method: 'POST', headers: { @@ -37,6 +40,7 @@ function Home() { if (response.ok) { const data = await response.json() if (data.exists) { + // Show loader while navigating to profile page router.push(`/${username.trim()}`) } else { toast.error('Username does not exist on GitHub') @@ -46,6 +50,9 @@ function Home() { } } catch (error) { toast.error('An unexpected error occurred. Please try again.') + } finally { + // Keep loading state true briefly to allow route transition loading UI to appear + setTimeout(() => setLoading(false), 800) } } else { toast.error('Please enter a username.') @@ -108,29 +115,38 @@ function Home() { value={username} onChange={handleUser} ref={inputRef} + disabled={loading} /> {/* Submit button */}
+ {loading && ( + + )} {/* Footer */}