Skip to content

PMFrancisco/whiteboard

Repository files navigation

Whiteboard Editor with tldraw

This application is a whiteboard editor built using tldraw, Next.js, and tRPC for type-safe API implementation.

Known Issues

Deployment Limitations

  • The PostgreSQL database on Render's free tier may experience cold starts, meaning the first connection after a period of inactivity might take a few seconds to establish
  • The OpenAI API key used in production is on the free tier, which means the AI image generation feature will not work in the deployed version, but it will in a local built one

Deployment

The application is deployed on:

To deploy your own instance:

  1. Fork this repository
  2. Create a new project on Vercel and connect it to your repository
  3. Set up a PostgreSQL database on Render
  4. Configure the following environment variables in Vercel:
    • DATABASE_URL: Your Render PostgreSQL connection string
    • OPENAI_API_KEY: Your OpenAI API key
  5. Deploy!

Technologies Used

  • Next.js: App router for robust server-side rendering and API routes
  • TailwindCSS: Utility-first CSS framework for styling
  • Shadcn UI: Component library built on top of Tailwind for consistent design
  • tRPC: End-to-end typesafe API layer
  • tldraw: Feature-rich drawing library
  • Prisma: Type-safe ORM for database operations
  • PostgreSQL: Database for storing whiteboard data
  • OpenAI: AI integration for image generation

Features

  • Create and manage multiple whiteboards
  • Real-time saving of whiteboard state
  • Shape styling controls (color, fill, stroke style)
  • Export drawings as SVG
  • Persistent storage of whiteboard data in PostgreSQL
  • Type-safe API endpoints for retrieving and storing data
  • AI-powered image generation for whiteboard elements
  • Custom UI with tools panel, styles panel, and AI panel

Getting Started

Prerequisites

  • Node.js (v18 or higher)
  • PostgreSQL database

Installation

  1. Clone this repository
git clone <repository-url>
cd whiteboard
  1. Install dependencies
npm install
  1. Set up environment variables

Create a .env file in the root directory with the following:

DATABASE_URL="postgresql://username:password@localhost:5432/whiteboard_db"
OPENAI_API_KEY="your-openai-api-key" # Required for AI image generation
  1. Run Prisma migrations to set up your database
npx prisma migrate dev --name init
  1. Start the development server
npm run dev
  1. Open http://localhost:3000 in your browser

API Endpoints

The application uses tRPC for type-safe API calls. The main endpoints are:

  • drawing.getDrawing: Retrieves a specific whiteboard by ID
  • drawing.saveDrawing: Saves the current state of a whiteboard
  • drawing.listDrawings: Lists all available whiteboards
  • drawing.deleteDrawing: Deletes a specific whiteboard
  • openAI.generateImage: Generates images using AI based on text prompts

Testing API Calls

The application uses tRPC for type-safe API calls. Here's how to test the API endpoints:

Using the Browser

  1. Navigate to the whiteboard list page at http://localhost:3000/whiteboard
  2. Create a new whiteboard or select an existing one
  3. Make changes to the whiteboard and observe that they are automatically saved
  4. Check the browser's developer tools Network tab to see the tRPC API calls

Using cURL

You can test the API endpoints directly using cURL:

List all whiteboards (Query)

curl -X GET http://localhost:3000/api/trpc/drawing.listDrawings \
  -H "Content-Type: application/json"

Get a specific whiteboard (Query)

curl -X GET http://localhost:3000/api/trpc/drawing.getDrawing \
  -H "Content-Type: application/json" \
  -d '{"json":{"0":{"json":"your-whiteboard-id"}}}'

Save a whiteboard (Mutation)

curl -X POST http://localhost:3000/api/trpc/drawing.saveDrawing \
  -H "Content-Type: application/json" \
  -d '{"json":{"0":{"json":{"id":"your-whiteboard-id","content":{"schemaVersion":1,"document":{},"session":{}}}}}}'

Delete a whiteboard (Mutation)

curl -X POST http://localhost:3000/api/trpc/drawing.deleteDrawing \
  -H "Content-Type: application/json" \
  -d '{"json":{"0":{"json":"your-whiteboard-id"}}}'

Generate an image using AI (Mutation)

curl -X POST http://localhost:3000/api/trpc/openAI.generateImage \
  -H "Content-Type: application/json" \
  -d '{"json":{"0":{"json":{"prompt":"A happy dog playing with a ball"}}}}'

Using tRPC Client in Code

You can also test the API calls programmatically using the tRPC client:

import { trpc } from '@/utils/trpc';

// List all whiteboards
const drawings = await trpc.drawing.listDrawings.query();

// Get a specific whiteboard
const drawing = await trpc.drawing.getDrawing.query('your-whiteboard-id');

// Save a whiteboard
const result = await trpc.drawing.saveDrawing.mutate({
  id: 'your-whiteboard-id',
  content: {
    schemaVersion: 1,
    document: {},
    session: {}
  }
});

// Delete a whiteboard
const deleteResult = await trpc.drawing.deleteDrawing.mutate('your-whiteboard-id');

// Generate an image using AI
const imageResult = await trpc.openAI.generateImage.mutate({
  prompt: 'A happy dog playing with a ball'
});

Project Structure

  • /app: Next.js app directory with page components
    • /whiteboard: Whiteboard list page
    • /whiteboard/[uuid]: Dynamic route for individual whiteboards
    • /api: API routes
  • /components: Reusable UI components
    • /tldraw: Custom tldraw UI components and tools
    • /ui: Shadcn UI components
    • /layout: Layout components
    • /buttons: Button components
    • /cards: Card components
    • /lists: List components
    • /skeletons: Loading skeleton components
  • /server: Server-side code
    • /routers: tRPC router definitions
    • /api: API route handlers
    • /trpc.ts: tRPC server configuration
    • /prisma.ts: Prisma client configuration
    • /context.ts: tRPC context definition
    • /actions.ts: Server actions
    • /openAiClient.ts: OpenAI client configuration
  • /prisma: Database schema and migrations
  • /hooks: Custom React hooks for whiteboard functionality
    • /useDeleteKey.ts: Hook for handling delete key press
    • /useImageUploader.ts: Hook for image upload functionality
    • /useImageGeneration.ts: Hook for AI image generation
  • /utils: Utility functions
    • /trpc.tsx: tRPC client configuration
    • /uuidGenerator.ts: UUID generation utility
  • /lib: Library code
    • /utils.ts: General utility functions
  • /data: Sample data
    • /drawings.json: Sample drawing data

Custom Features

  • Auto-saving: Changes to the whiteboard are automatically saved to the database
  • Style Controls: Customize colors, fills, and stroke styles of shapes
  • AI Integration: Generate images from text descriptions using OpenAI
  • Status Indicators: Visual feedback when saving or encountering errors
  • Shape Styling: Buttons to modify shape appearance (colors, fills, strokes)

Development Notes

  • The application uses tRPC's optimistic updates for a smoother user experience
  • The whiteboard state is persisted in PostgreSQL using a JSON data type
  • Error handling is implemented at both client and server levels

About

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors