Skip to main content
Week 02 • Track 08 • The Vision

The Napkin
Flow.

You are not building an app. You are building a Demo Tape. Limit yourself to 4 connected screens. No backend. Fake data only.

1Landing
2Dashboard
3Action
4Success

The Mental Model

The 4-Screen Rule.

Beginners get stuck building "Settings" pages and "Forgot Password" flows. Stop.

1

The Hook: Landing Page: Sell the promise. One headline, one CTA.

2

The Home: Dashboard: Show the state. What does the user have?

3

The Work: Action Page: The form, the creator, the editor.

4

The Payoff: Success State: Confetti, receipt, confirmation.

// The Mindset

To validate an idea, you only need the "Happy Path", the exact sequence of clicks a user takes to solve their problem. Ignore edge cases.

Landing
→
Dashboard
→
Action
→
✓
Success

The Screens

1

Landing Page

THE HOOK

One job: make them click the button. Hero headline, subtext, CTA.

✓Clear value proposition
✓Single primary CTA
✓Social proof (optional)
2

Dashboard

THE HOME

Show what the user "has." List of items, stats, recent activity.

✓Data grid or card list
✓Empty state design
✓"Create New" button
3

Action Page

THE WORK

The form. The editor. Where the user does the thing.

✓Clear form labels
✓Primary submit button
✓Cancel/back option
4

Success State

THE PAYOFF

Dopamine hit. Confirmation, receipt, celebration.

✓Clear success message
✓Next action CTA
✓Return to dashboard

The Data Layer

Key Concept
No Backend Needed

Hardcode Everything.

Do not build a database. Do not build an API. Create a file with your dream data inside it. This is your "mock."

  • SpeedIterate on UI without waiting for backend.
  • FocusDesign the ideal data shape for your UI first.
  • LaterReplace with real API calls when ready.

// src/lib/data.ts

export const listings = [

{

id: 1,

title: "Luxury Beach Villa",

price: 250,

image: "/villa.jpg",

rating: 4.9,

},

{

id: 2,

title: "Mountain Cabin",

price: 120,

// ...

},

];

export type Listing = typeof listings[0];

Usage
📥

Import & Map

Import your fake data and map over it like it's a real API response.

import { listings } from "@/lib/data";

export default function Dashboard() {

return (

<div>

{listings.map((item) => (

<Card key={item.id} {...item} />

))}

</div>

);

}

Dynamic
🎭

Fake Mutations

For "create" or "delete" actions, use local state. It won't persist on refresh, but it'll feel real.

const [items, setItems] = useState(listings);

const addItem = (newItem) => {

setItems([...items, {

...newItem,

id: Date.now(), // fake ID

}]);

};

The State Machine

You don't need a router yet. Use a simple state variable to swap between views. It's fast and easy to debug.

The "If" Router

const [view, setView] = useState("landing");

return (

<>

{view === "landing" && <Landing />}

{view === "dashboard" && <Dashboard />}

{view === "action" && <ActionPage />}

{view === "success" && <Success />}

</>

);

Trigger Navigation

// In Landing component

<Button

onClick={() => setView("dashboard")}

>

Get Started

</Button>

// In ActionPage after form submit

const handleSubmit = () => {

addItem(formData);

setView("success");

};

Pro tip: Pass setView as a prop to child components, or use React Context if it gets messy.

Common Patterns

✗ Scope Creep

"I need user authentication"

No you don't. Use a fake "logged in" boolean for the demo.

"I need a database"

No you don't. Hardcode an array. It's faster to iterate.

"I need error handling"

For a demo? Just assume everything works. Handle errors later.

"I need a settings page"

Settings pages don't validate ideas. Build the happy path first.

✓ Demo Mindset

Fake the login

setLoggedIn(true) on button click. Done.

Use placeholder images

Unsplash URLs or placehold.co. Don't waste time on assets.

Hardcode happy data

5 perfect items. No edge cases. No empty states (yet).

Ship it ugly

A working demo beats a polished mockup. Get clicks first.

The Exercises

Week 02 Final Exam.

01

The Dictionary

Create Fake Data

  • →Create src/lib/data.ts
  • →Export an array of 5 items
  • →Include: id, title, price, image
  • →Export the type
Goal: One source of truth for mock data
02

The Flow

Wire Up Navigation

  • →Create 4 component files
  • →Add useState("landing")
  • →Wire button clicks to setView
  • →Test the full flow
Goal: Landing → Dashboard → Action → Success
03

The Demo

Ship It

  • →Map data to Dashboard cards
  • →Add a form to Action page
  • →On submit, show Success
  • →Record a 30-second demo video
Goal: A clickable prototype you can show

📋 Quick Reference Cheatsheet

Data File

export const items = [...]

State Router

{view === "x" && <X />}

Navigate

onClick={() => setView("next")}