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")}