diff --git a/surfsense_web/app/(home)/blog/[slug]/loading.tsx b/surfsense_web/app/(home)/blog/[slug]/loading.tsx new file mode 100644 index 000000000..0cce7f80b --- /dev/null +++ b/surfsense_web/app/(home)/blog/[slug]/loading.tsx @@ -0,0 +1,66 @@ +import { Skeleton } from "@/components/ui/skeleton"; + +export default function BlogPostLoading() { + return ( +
+
+ {/* Breadcrumb */} +
+ + + + + +
+ + {/* Tags */} +
+ + +
+ + {/* Title */} +
+ + +
+ + {/* Description */} + + + + {/* Author + date */} +
+ +
+ + +
+
+ + {/* Cover image */} + + + {/* Article body paragraphs */} + {Array.from({ length: 5 }).map((_, i) => ( +
+ + + +
+ ))} + + {/* Sub-heading */} + + + {Array.from({ length: 3 }).map((_, i) => ( +
+ + + +
+ ))} +
+
+ ); +} diff --git a/surfsense_web/app/(home)/blog/loading.tsx b/surfsense_web/app/(home)/blog/loading.tsx new file mode 100644 index 000000000..ddaf345f6 --- /dev/null +++ b/surfsense_web/app/(home)/blog/loading.tsx @@ -0,0 +1,50 @@ +import { Skeleton } from "@/components/ui/skeleton"; + +export default function BlogIndexLoading() { + return ( +
+
+ {/* Header */} +
+ +
+ + {/* Featured post skeleton */} +
+ +
+ + + +
+ + + +
+
+
+ + {/* Search bar skeleton */} +
+ +
+ + {/* Grid of article cards */} +
+ {Array.from({ length: 6 }).map((_, i) => ( +
+ + + + +
+ + +
+
+ ))} +
+
+
+ ); +} diff --git a/surfsense_web/app/(home)/changelog/loading.tsx b/surfsense_web/app/(home)/changelog/loading.tsx new file mode 100644 index 000000000..648f5a5e6 --- /dev/null +++ b/surfsense_web/app/(home)/changelog/loading.tsx @@ -0,0 +1,63 @@ +import { Skeleton } from "@/components/ui/skeleton"; + +export default function ChangelogLoading() { + return ( +
+ {/* Header */} +
+
+
+
+ {/* Breadcrumb */} +
+ + + +
+ + +
+
+
+
+ + {/* Timeline */} +
+
+ {Array.from({ length: 3 }).map((_, i) => ( +
+ {/* Left: date + version */} +
+ + +
+ + {/* Right: content */} +
+
+ {/* Title */} + + {/* Tags */} +
+ + +
+ {/* Body paragraphs */} +
+ + + +
+
+ + +
+
+
+
+ ))} +
+
+
+ ); +} diff --git a/surfsense_web/app/(home)/free/[model_slug]/loading.tsx b/surfsense_web/app/(home)/free/[model_slug]/loading.tsx new file mode 100644 index 000000000..97660188d --- /dev/null +++ b/surfsense_web/app/(home)/free/[model_slug]/loading.tsx @@ -0,0 +1,65 @@ +import { Skeleton } from "@/components/ui/skeleton"; + +export default function FreeModelLoading() { + return ( + <> + {/* Chat area skeleton - fills viewport */} +
+ {/* Chat header */} +
+ + +
+ + {/* Chat messages area */} +
+
+ +
+
+ + + +
+
+ + {/* Input bar */} +
+ +
+
+ + {/* SEO section skeleton */} +
+
+ {/* Breadcrumb */} +
+ + + + + +
+ + + + + +
+ + {/* FAQ skeleton */} + +
+ {Array.from({ length: 4 }).map((_, i) => ( +
+ + + +
+ ))} +
+
+
+ + ); +} diff --git a/surfsense_web/app/(home)/free/loading.tsx b/surfsense_web/app/(home)/free/loading.tsx new file mode 100644 index 000000000..08a4ed6b6 --- /dev/null +++ b/surfsense_web/app/(home)/free/loading.tsx @@ -0,0 +1,60 @@ +import { Skeleton } from "@/components/ui/skeleton"; + +export default function FreeChatLoading() { + return ( +
+
+ {/* Breadcrumb */} +
+ + + +
+ + {/* Hero section */} +
+ + + + +
+ {Array.from({ length: 4 }).map((_, i) => ( + + ))} +
+
+ +
+ + {/* Model table */} +
+ + + +
+ {/* Table header */} +
+ + + + +
+ + {/* Table rows */} + {Array.from({ length: 8 }).map((_, i) => ( +
+
+ + +
+ + + +
+ ))} +
+
+
+
+ ); +} diff --git a/surfsense_web/app/docs/[[...slug]]/loading.tsx b/surfsense_web/app/docs/[[...slug]]/loading.tsx new file mode 100644 index 000000000..6bedcfc40 --- /dev/null +++ b/surfsense_web/app/docs/[[...slug]]/loading.tsx @@ -0,0 +1,55 @@ +import { Skeleton } from "@/components/ui/skeleton"; + +export default function DocsLoading() { + return ( +
+ {/* Title */} + + + {/* Description */} + + +
+ {/* Paragraph block 1 */} +
+ + + +
+ + {/* Sub-heading */} + + + {/* Paragraph block 2 */} +
+ + + + +
+ + {/* Code block placeholder */} + + + {/* Sub-heading */} + + + {/* List items */} +
+ {Array.from({ length: 4 }).map((_, i) => ( +
+ + +
+ ))} +
+ + {/* Paragraph block 3 */} +
+ + +
+
+
+ ); +}