import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { trpc } from "@/lib/trpc"; import { FileText, Plus, Sparkles, Trash2 } from "lucide-react"; import { DemoCard, LoadingSpinner, InlineSpinner, EmptyState, StatusBadge, } from "@/components/demo"; interface Post { id: number; title: string; content: string | null; published: boolean; } export function PostsExample() { const [title, setTitle] = useState(""); const [content, setContent] = useState(""); const [authorId, setAuthorId] = useState("1"); const utils = trpc.useUtils(); const { data: posts, isLoading } = trpc.posts.getAll.useQuery(); const createMutation = trpc.posts.create.useMutation({ onSuccess: () => { utils.posts.getAll.invalidate(); setTitle(""); setContent(""); }, }); const publishMutation = trpc.posts.publish.useMutation({ onSuccess: () => utils.posts.getAll.invalidate(), }); const deleteMutation = trpc.posts.delete.useMutation({ onSuccess: () => utils.posts.getAll.invalidate(), }); const handleCreate = () => { createMutation.mutate({ title, content, authorId: parseInt(authorId), published: false, }); }; return ( {/* Create Form */} {/* Posts List */} {isLoading ? ( ) : (
{posts?.length === 0 && ( )} {posts?.map((post) => ( publishMutation.mutate({ id: post.id })} onDelete={() => deleteMutation.mutate({ id: post.id })} /> ))}
)}
); } // ============================================================================ // Sub-components // ============================================================================ interface CreatePostFormProps { title: string; content: string; authorId: string; onTitleChange: (value: string) => void; onContentChange: (value: string) => void; onAuthorIdChange: (value: string) => void; onSubmit: () => void; isLoading: boolean; } function CreatePostForm({ title, content, authorId, onTitleChange, onContentChange, onAuthorIdChange, onSubmit, isLoading, }: CreatePostFormProps) { return (
onTitleChange(e.target.value)} placeholder="Post title..." className="flex-1" />
onAuthorIdChange(e.target.value)} type="number" />
onContentChange(e.target.value)} placeholder="Write something amazing..." className="flex-1" />
); } interface PostCardProps { post: Post; onPublish: () => void; onDelete: () => void; } function PostCard({ post, onPublish, onDelete }: PostCardProps) { return (

{post.title}

{post.published ? "Published" : "Draft"}

{post.content}

{!post.published && ( )}
); }