{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "blog-page",
  "type": "registry:block",
  "title": "Blog Page",
  "description": "Clean blog listing page with article cards, category filters, author info, and pagination. Optimized for readability and content discovery with a fully responsive layout.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "avatar",
    "card",
    "badge",
    "button"
  ],
  "files": [
    {
      "path": "examples/blog-page/blog-posts.ts",
      "content": "export const blogPosts = [\n  {\n    imageSrc:\n      \"https://images.unsplash.com/photo-1498050108023-c5249f4df085?auto=format&fit=crop&w=600&q=80\",\n    imageAlt: \"Mastering UI Elements: A Practical Guide for Designers\",\n    title: \"Mastering UI Elements: A Practical Guide for Designers\",\n    description:\n      \"Dive into the world of user interfaces with our expert guides, latest trends, and practical tips.\",\n    authorName: \"Jennifer Taylor\",\n    authorAvatarSrc: \"https://i.pravatar.cc/48?img=5\",\n    readTime: \"3 min\",\n    publishedAt: \"2026-03-12\"\n  },\n  {\n    imageSrc:\n      \"https://images.unsplash.com/photo-1545239351-1141bd82e8a6?auto=format&fit=crop&w=600&q=80\",\n    imageAlt: \"Crafting Seamless Experiences: The Art of Intuitive UI Design\",\n    title: \"Crafting Seamless Experiences: The Art of Intuitive UI Design\",\n    description:\n      \"Explore the principles and techniques that drive user-centric UI design, ensuring a seamless and intuitive experience for your audience.\",\n    authorName: \"Jennifer Taylor\",\n    authorAvatarSrc: \"https://i.pravatar.cc/48?img=5\",\n    readTime: \"5 min\",\n    publishedAt: \"2026-03-10\"\n  },\n  {\n    imageSrc:\n      \"https://images.unsplash.com/photo-1485827404703-89b55fcc595e?auto=format&fit=crop&w=600&q=80\",\n    imageAlt: \"Beyond Aesthetics: The Power of Emotional UX Design\",\n    title: \"Beyond Aesthetics: The Power of Emotional UX Design\",\n    description:\n      \"Delve into the realm of emotional design and discover how incorporating empathy and psychological insights can elevate user experiences.\",\n    authorName: \"Ryan A.\",\n    authorAvatarSrc: \"https://i.pravatar.cc/48?img=12\",\n    readTime: \"2 min\",\n    publishedAt: \"2026-03-08\"\n  },\n  {\n    imageSrc:\n      \"https://images.unsplash.com/photo-1519389950473-47ba0277781c?auto=format&fit=crop&w=600&q=80\",\n    imageAlt: \"Revolutionizing industries through SaaS implementation\",\n    title: \"Revolutionizing industries through SaaS implementation\",\n    isFeatured: true,\n    readTime: \"10 min\",\n    publishedAt: \"2026-03-11\"\n  },\n  {\n    imageSrc:\n      \"https://images.unsplash.com/photo-1559028012-481c04fa702d?auto=format&fit=crop&w=600&q=80\",\n    imageAlt: \"Synergizing saas and UX design for elevating digital experiences\",\n    title: \"Synergizing saas and UX design for elevating digital experiences\",\n    isFeatured: true,\n    readTime: \"8 min\",\n    publishedAt: \"2026-03-07\"\n  },\n  {\n    imageSrc:\n      \"https://images.unsplash.com/photo-1522071820081-009f0129c71c?auto=format&fit=crop&w=600&q=80\",\n    imageAlt: \"Navigating saas waters with intuitive UI and UX\",\n    title: \"Navigating saas waters with intuitive UI and UX\",\n    isFeatured: true,\n    readTime: \"9 min\",\n    publishedAt: \"2026-03-06\"\n  },\n  {\n    imageSrc:\n      \"https://images.unsplash.com/photo-1521737604893-d14cc237f11d?auto=format&fit=crop&w=600&q=80\",\n    imageAlt: \"Sculpting saas success - the art of UI and UX design\",\n    title: \"Sculpting saas success - the art of UI and UX design\",\n    isFeatured: true,\n    readTime: \"4 min\",\n    publishedAt: \"2026-03-05\"\n  },\n  {\n    imageSrc:\n      \"https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?auto=format&fit=crop&w=600&q=80\",\n    imageAlt: \"Transforming saas platforms - a UI/UX design odyssey\",\n    title: \"Transforming saas platforms - a UI/UX design odyssey\",\n    isFeatured: true,\n    readTime: \"12 min\",\n    publishedAt: \"2026-03-04\"\n  }\n] as const;\n\nexport type BlogPost = (typeof blogPosts)[number];\nexport type FeaturedBlogPost = Extract<BlogPost, { isFeatured: true }>;\nexport type RegularBlogPost = Exclude<BlogPost, FeaturedBlogPost>;\n",
      "type": "registry:block",
      "target": "app/blog-page/blog-posts.ts"
    },
    {
      "path": "examples/blog-page/components/blog-post-card.tsx",
      "content": "import Image from \"next/image\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport type { RegularBlogPost } from \"../blog-posts\";\nimport Link from \"next/link\";\n\nexport function BlogPostCard({ post }: { post: RegularBlogPost }) {\n  return (\n    <Link href=\"#\" className=\"block transition-opacity hover:opacity-80\">\n      <Card className=\"overflow-hidden py-0 shadow-none gap-0\">\n        <Image\n          src={post.imageSrc}\n          alt={post.imageAlt}\n          width={400}\n          height={225}\n          className=\"aspect-video w-full object-cover\"\n        />\n        <CardContent className=\"grid gap-2 p-4\">\n          <h3 className=\"text-lg leading-relaxed font-semibold line-clamp-2\">{post.title}</h3>\n          <p className=\"text-muted-foreground line-clamp-2 text-sm\">{post.description}</p>\n          <div className=\"text-muted-foreground flex items-center gap-2 text-xs\">\n            <Avatar className=\"h-6 w-6\">\n              <AvatarImage src={post.authorAvatarSrc} />\n              <AvatarFallback>\n                {post.authorName\n                  .split(\" \")\n                  .map((n: string) => n[0])\n                  .join(\"\")}\n              </AvatarFallback>\n            </Avatar>\n            <span>{post.authorName}</span>\n            <span>•</span>\n            <span>{post.readTime} read</span>\n          </div>\n        </CardContent>\n      </Card>\n    </Link>\n  );\n}\n",
      "type": "registry:block",
      "target": "app/blog-page/components/blog-post-card.tsx"
    },
    {
      "path": "examples/blog-page/components/featured-post-sidebar-item.tsx",
      "content": "import Image from \"next/image\";\nimport type { BlogPost } from \"../blog-posts\";\nimport { ClockIcon } from \"lucide-react\";\nimport Link from \"next/link\";\n\nexport function FeaturedPostSidebarItem({ post }: { post: BlogPost }) {\n  return (\n    <Link href=\"#\" className=\"flex items-center gap-4 transition-opacity hover:opacity-80\">\n      <Image\n        src={post.imageSrc}\n        alt={post.imageAlt}\n        width={64}\n        height={64}\n        className=\"aspect-square max-w-14 rounded-md object-cover\"\n      />\n      <div className=\"space-y-1\">\n        <h4 className=\"line-clamp-2 text-sm leading-snug font-medium\">{post.title}</h4>\n        <p className=\"text-muted-foreground flex items-center gap-1 text-xs\">\n          <ClockIcon className=\"size-3\" /> {post.readTime}\n        </p>\n      </div>\n    </Link>\n  );\n}\n",
      "type": "registry:block",
      "target": "app/blog-page/components/featured-post-sidebar-item.tsx"
    },
    {
      "path": "examples/blog-page/page.tsx",
      "content": "import Link from \"next/link\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\n\nimport { BlogPostCard } from \"./components/blog-post-card\";\nimport {\n  blogPosts,\n  type BlogPost,\n  type FeaturedBlogPost,\n  type RegularBlogPost\n} from \"./blog-posts\";\nimport { FeaturedPostSidebarItem } from \"./components/featured-post-sidebar-item\";\nimport Image from \"next/image\";\nimport { ArrowRightIcon } from \"lucide-react\";\n\nconst sortByDateDesc = <T extends { publishedAt: string }>(posts: readonly T[]) =>\n  [...posts].sort((a, b) => new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime());\n\nconst isFeaturedPost = (post: BlogPost): post is FeaturedBlogPost =>\n  \"isFeatured\" in post && post.isFeatured === true;\n\nconst isRegularPost = (post: BlogPost): post is RegularBlogPost => !isFeaturedPost(post);\n\nconst featuredSidebarPosts = blogPosts.filter(isFeaturedPost);\nconst sortedRecentPosts = sortByDateDesc(blogPosts.filter(isRegularPost));\nconst latestPost = sortByDateDesc(blogPosts)[0];\n\nexport default function BlogPage() {\n  return (\n    <section className=\"py-10 lg:py-16\">\n      <div className=\"mx-auto max-w-7xl px-4\">\n        <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-3\">\n          <div className=\"relative overflow-hidden rounded-lg lg:col-span-2\">\n            <Image\n              width={400}\n              height={300}\n              src={latestPost.imageSrc}\n              alt={latestPost.imageAlt}\n              className=\"aspect-video w-full object-cover\"\n            />\n            <div className=\"absolute inset-0 flex flex-col justify-end bg-linear-to-t from-black/70 to-transparent p-6 text-white\">\n              <Badge className=\"mb-2 w-fit bg-white/20 text-white backdrop-blur-sm\">Business</Badge>\n              <h2 className=\"text-2xl leading-tight font-bold md:text-2xl\">{latestPost.title}</h2>\n            </div>\n          </div>\n\n          <Card className=\"shadow-none lg:col-span-1\">\n            <CardHeader>\n              <CardTitle>Other Featured Posts</CardTitle>\n            </CardHeader>\n            <CardContent className=\"space-y-4\">\n              {featuredSidebarPosts.map((post) => (\n                <FeaturedPostSidebarItem key={post.title} post={post} />\n              ))}\n            </CardContent>\n          </Card>\n        </div>\n\n        <div className=\"mt-12\">\n          <div className=\"mb-6 flex items-center justify-between\">\n            <h2 className=\"text-2xl font-bold\">Recent Posts</h2>\n            <Button variant=\"outline\" size=\"sm\" asChild>\n              <Link href=\"#\">\n                All Posts <ArrowRightIcon />\n              </Link>\n            </Button>\n          </div>\n          <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n            {sortedRecentPosts.map((post) => (\n              <BlogPostCard key={post.title} post={post} />\n            ))}\n          </div>\n        </div>\n      </div>\n    </section>\n  );\n}\n",
      "type": "registry:block",
      "target": "app/blog-page/page.tsx"
    }
  ]
}