diff --git a/frontend/src/components/shared/SkeletonLoader.jsx b/frontend/src/components/shared/SkeletonLoader.jsx
new file mode 100644
index 0000000..b8f8604
--- /dev/null
+++ b/frontend/src/components/shared/SkeletonLoader.jsx
@@ -0,0 +1,49 @@
+import React from 'react';
+
+/**
+ * Reusable Skeleton Loader component to provide visual loading feedback.
+ * @param {string} className - Optional Tailwind utility classes.
+ */
+export function Skeleton({ className = "" }) {
+ return (
+
+ );
+}
+
+/**
+ * Skeleton loader designed for loading table or list rows.
+ */
+export function TableRowSkeleton({ rows = 5 }) {
+ return (
+
+ {Array.from({ length: rows }).map((_, i) => (
+
+
+
+
+
+
+
+ ))}
+
+ );
+}
+
+/**
+ * Skeleton loader designed for dashboard stat cards.
+ */
+export function CardSkeleton({ cards = 3 }) {
+ return (
+
+ {Array.from({ length: cards }).map((_, i) => (
+
+
+
+
+
+ ))}
+
+ );
+}
+
+export default Skeleton;
diff --git a/frontend/src/pages/ContestCodeforcesPage.jsx b/frontend/src/pages/ContestCodeforcesPage.jsx
index 634cfac..57a401e 100644
--- a/frontend/src/pages/ContestCodeforcesPage.jsx
+++ b/frontend/src/pages/ContestCodeforcesPage.jsx
@@ -1,7 +1,16 @@
-import { useState } from "react";
+import { useState, useEffect } from "react";
+import { CardSkeleton } from "../components/shared/SkeletonLoader";
export default function ContestCodeforcesPage() {
const [selectedDivision, setSelectedDivision] = useState("all");
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ setLoading(false);
+ }, 800);
+ return () => clearTimeout(timer);
+ }, []);
const contestSolutions = [
{
@@ -33,6 +42,10 @@ export default function ContestCodeforcesPage() {
},
];
+ const filteredContests = contestSolutions.filter(
+ (c) => selectedDivision === "all" || c.division === selectedDivision
+ );
+
return (
{/* Hero Section */}
@@ -82,7 +95,7 @@ export default function ContestCodeforcesPage() {
{["all", "Div. 1", "Div. 2", "Div. 3", "Div. 4", "Educational", "Global"].map((div) => (