Initial commit: json-render crepes demo
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
This commit is contained in:
BIN
app/favicon.ico
Normal file
BIN
app/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
26
app/globals.css
Normal file
26
app/globals.css
Normal file
@@ -0,0 +1,26 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
21
app/layout.tsx
Normal file
21
app/layout.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { Metadata } from "next";
|
||||
import "./globals.css";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Les Crêpes de Maîtres | Famous French Chef Recipes",
|
||||
description: "Discover authentic crêpe recipes from legendary French chefs. Powered by json-render.",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className="antialiased">
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
117
app/page.tsx
Normal file
117
app/page.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
"use client";
|
||||
|
||||
import { Renderer } from "@json-render/react";
|
||||
import { registry, Provider } from "@/lib/registry";
|
||||
import { recipes } from "@/lib/recipes";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
export default function Home() {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
if (!mounted) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-orange-100 via-amber-50 to-yellow-100 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<div className="text-6xl mb-4">🥞</div>
|
||||
<p className="text-gray-600 text-lg">Loading recipes...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-orange-100 via-amber-50 to-yellow-100">
|
||||
<header className="bg-white shadow-lg sticky top-0 z-50 border-b-4 border-orange-400">
|
||||
<div className="container mx-auto px-4 py-6">
|
||||
<h1 className="text-5xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-orange-600 to-amber-600 text-center">
|
||||
🥞 Les Crêpes de Maîtres
|
||||
</h1>
|
||||
<p className="text-center text-gray-600 mt-2 text-lg">
|
||||
Famous French Chefs' Crêpe Recipes
|
||||
</p>
|
||||
<p className="text-center text-gray-500 mt-1 text-sm">
|
||||
Powered by <span className="font-mono font-semibold">json-render</span> ✨
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="container mx-auto px-4 py-12 max-w-6xl">
|
||||
<div className="bg-blue-50 border-l-4 border-blue-500 p-6 rounded-lg shadow-md mb-12">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-3 flex items-center gap-2">
|
||||
ℹ️ About This Demo
|
||||
</h2>
|
||||
<p className="text-gray-700 mb-2">
|
||||
This application demonstrates <strong>json-render</strong> by Vercel Labs —
|
||||
a library that enables AI-generated UIs with guardrailed components.
|
||||
</p>
|
||||
<p className="text-gray-700 mb-2">
|
||||
Below, each recipe is defined as a <strong>JSON specification</strong> and
|
||||
rendered through the <code className="bg-gray-200 px-2 py-1 rounded">Renderer</code> component
|
||||
using our type-safe component catalog.
|
||||
</p>
|
||||
<p className="text-gray-700 mb-4">
|
||||
In production, AI would generate these specs from user prompts—safely constrained
|
||||
to only use components we've defined (RecipeHeader, ChefInfo, IngredientList, etc.).
|
||||
</p>
|
||||
<div className="bg-white p-4 rounded-lg shadow-sm mb-4">
|
||||
<h3 className="font-bold text-gray-900 mb-2 flex items-center gap-2">
|
||||
<span className="text-green-600">✓</span> Guardrailed
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600 mb-3">
|
||||
AI can only use components in your catalog
|
||||
</p>
|
||||
<h3 className="font-bold text-gray-900 mb-2 flex items-center gap-2">
|
||||
<span className="text-green-600">✓</span> Predictable
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600 mb-3">
|
||||
JSON output matches your schema, every time
|
||||
</p>
|
||||
<h3 className="font-bold text-gray-900 mb-2 flex items-center gap-2">
|
||||
<span className="text-green-600">✓</span> Fast
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600">
|
||||
Stream and render progressively as the model responds
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-4 border-t border-blue-200">
|
||||
<p className="text-sm text-gray-600 flex items-center gap-2">
|
||||
<span>🔗</span>
|
||||
<a
|
||||
href="https://github.com/vercel-labs/json-render"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="underline hover:text-blue-700 font-semibold"
|
||||
>
|
||||
github.com/vercel-labs/json-render
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{recipes.map((recipe, index) => (
|
||||
<div key={index} className="mb-8">
|
||||
<Provider>
|
||||
<Renderer spec={recipe as any} registry={registry} />
|
||||
</Provider>
|
||||
</div>
|
||||
))}
|
||||
</main>
|
||||
|
||||
<footer className="bg-gray-900 text-white py-8 mt-20">
|
||||
<div className="container mx-auto px-4 text-center">
|
||||
<p className="text-lg font-semibold mb-2">🇫🇷 Bon Appétit!</p>
|
||||
<p className="text-gray-400 text-sm">
|
||||
Built with Next.js, Tailwind CSS, and json-render
|
||||
</p>
|
||||
<p className="text-gray-500 text-xs mt-4">
|
||||
Recipe sources linked in each chef's information card
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user