Day 14: Building the dashboard - usage stats and key management

Day 14 of 30. Week 2 ends. Tomorrow is our first customer deadline.

#ui #react

Day 14 of 30. Week 2 ends. Tomorrow is our “first customer” deadline.

We have a landing page, authentication, and a working API. But users have nowhere to see their usage or manage their keys. Today we build the dashboard, and try to focus on what users actually need, not what’s impressive to build. Though we might do that too, a little bit…

What the dashboard needs to do

We asked ourselves: if we were a developer using this API, what would we need?

  1. Manage API keys - Create new ones, revoke old ones
  2. Know my usage - How many screenshots have we made this month? Am I near my limit?
  3. Get started quickly - Copy-paste code to make my first screenshot
  4. Manage my account - Update email, change password, basic stuff

What we’re explicitly NOT building:

  • Detailed analytics (which URLs, response times, etc.)
  • Team features (invites, shared keys)
  • Billing management (Stripe handles that)

Our goal is to build a minimal viable dashboard. Then we’ll ship it and hopefully learn from real users.

The layout

The layout of the dashboard is pretty standard. We have a simple sidebar navigation, with content on the right:

┌─────────────────────────────────────────────────────────┐
│  Logo                              user@email.com  [▼]  │
├────────────────┬────────────────────────────────────────┤
│                │                                        │
│   Dashboard    │    Welcome back, Erik                  │
│                │                                        │
│   API Keys     │    ┌─────────┐ ┌─────────┐ ┌────────┐  │
│                │    │   847   │ │  99.2%  │ │   2    │  │
│   Usage        │    │ captured│ │ success │ │  keys  │  │
│                │    └─────────┘ └─────────┘ └────────┘  │
│   Settings     │                                        │
│                │    Quick Start                         │
│                │    ┌────────────────────────────────┐  │
│                │    │ curl -X POST ...               │  │
│                │    └────────────────────────────────┘  │
│                │                                        │
│                │    Recent Screenshots                  │
│                │    ┌────────────────────────────────┐  │
│                │    │ example.com    2.3s    Success │  │
│                │    │ mysite.io      1.8s    Success │  │
│                │    └────────────────────────────────┘  │
│                │                                        │
└────────────────┴────────────────────────────────────────┘

Right now, we have four pages total. That should be enough to get started.

Interactive dashboard

Explore the dashboard pages:

dashboard - Dashboard preview
Welcome back!
E erik@example.com
847
Screenshots
+12% this week
99.2%
Success Rate
-0.1%
2
API Keys
Active
Quick Start
curl -X POST api.allscreenshots.com/v1/screenshots \
  -H "X-API-Key: sk_live_..." \
  -d 'url=example.com'
Recent Screenshots
🖼
github.com
2.3s • Desktop • PNG
🖼
stripe.com
1.8s • Mobile • PNG
🖼
vercel.com
3.1s • Tablet • JPEG

Page 1: Dashboard (Overview)

This is what users see after login, and should give some insight in their usage, and what to do.

The three stats cards show what developers care about:

  • Screenshots captured this month
  • Success rate (builds confidence)
  • Active API keys

Quick Start section with copy-paste code examples. Tabs for cURL, Node.js, Python. One click to copy. This is quite important; we want to make the life of people using our service as simple as possible, and you should be able to make your first screenshot within 30 seconds of signing up.

Recent Screenshots shows the most recent screenshot captures including URL, time taken, and status.

Design decisions:

  • No graphs or charts on the overview, but we might have some more advanced usage later.
  • Recent screenshots are clickable, so you can see the actual image in a simple image gallery.

Page 2: API Keys

This page has one job: let users manage their credentials securely.

┌─────────────────────────────────────────────────────────┐
│  API Keys                           [+ Create New Key]  │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  ⚠️  Save your key now - you won't see it again!        │
│  ┌────────────────────────────────────────────────────┐ │
│  │ sk_live_a8f2k9d3m5n7p1q4r6t8v0x2y4z6...            │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
│  Your Keys                                              │
│  ┌────────────────────────────────────────────────────┐ │
│  │ Production Key    sk_live_a8f2...    Never used    │ │
│  │ Created Jan 15    [Revoke]                         │ │
│  ├────────────────────────────────────────────────────┤ │
│  │ Testing Key       sk_live_x7y9...    2 hours ago   │ │
│  │ Created Jan 14    [Revoke]                         │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
└─────────────────────────────────────────────────────────┘

Key UX decisions:

Show the full key exactly once. When you create a key, we show it in a highlighted box with a warning. After you leave this page, you’ll only see the prefix (sk_live_a8f2...). This is similar to how Stripe does it, and for good reason: it’s secure.

Big obvious copy button. (Only when creating the key). With one click it’s in your clipboard. This prevents mistakes by copying and pasting the key manually.

“Last used” timestamp. This helps users identify which keys are active and which are forgotten.

Revoke requires confirmation. “Are you sure? This cannot be undone.” This hopefully prevents accidents. Normally, an undo functionality is more user-friendly, but this is a little challenging with API keys.

Naming keys is optional but encouraged. “Production Key” and “Testing Key” are clearer than two identical entries.

Page 3: Usage

Developers want to know: am I going to hit my limit?

┌─────────────────────────────────────────────────────────┐
│  Usage                                    January 2024  │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  This Billing Period                                    │
│  ┌────────────────────────────────────────────────────┐ │
│  │                                                    │ │
│  │  ████████████████████░░░░░░░░░░░░░░░░░░░░  42%     │ │
│  │                                                    │ │
│  │  847 of 2,000 screenshots used                     │ │
│  │  1,153 remaining • Resets Feb 1                    │ │
│  │                                                    │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
│  Daily Breakdown                                        │
│  ┌────────────────────────────────────────────────────┐ │
│  │  Jan 15  ████████████████  156                     │ │
│  │  Jan 14  ████████████  98                          │ │
│  │  Jan 13  ██████████████████  187                   │ │
│  │  Jan 12  ██████  45                                │ │
│  │  ...                                               │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
│  [Need more? Upgrade to Pro →]                          │
│                                                         │
└─────────────────────────────────────────────────────────┘

UX decisions:

Progress bar for quick insights. The progress bar will give insight in your usage and how many screenshots can be made this period. This should help you to know your status at a glance.

Plain language. “847 of 2,000 screenshots used” not “42.35% of quota consumed”. We want to provide real numbers, not percentages, for accuracy.

Reset date is prominent. “Resets Feb 1” answers the question users might have.

Daily breakdown is simple. Horizontal bars, not a complex chart. You can see patterns (heavy days, quiet days) without needing a data science degree.

Upgrade nudge is subtle. A simple text which will be present when relevant, without being annoying.

We might add some predictive capabilities in the future, but for now, the above will do.

Page 4: Settings

This will allow you to manage certain settings of your account:

┌─────────────────────────────────────────────────────────┐
│  Settings                                               │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Email                                                  │
│  ┌────────────────────────────────────────────────────┐ │
│  │ erik@example.com                          [Change] │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
│  Password                                               │
│  ┌────────────────────────────────────────────────────┐ │
│  │ ••••••••••••                              [Change] │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
│  Plan                                                   │
│  ┌────────────────────────────────────────────────────┐ │
│  │ Free Plan (2,000 screenshots/mo)                   │ │
│  │ [Upgrade to Pro]  [Manage Billing]                 │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
│  Danger Zone                                            │
│  ┌────────────────────────────────────────────────────┐ │
│  │ [Delete Account]                                   │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
└─────────────────────────────────────────────────────────┘

Nothing surprising here we think, it’s a standard account settings pattern. “Manage Billing” opens the Stripe customer portal, since we don’t build the billing UI ourselves.

“Danger Zone” is visually separated and uses a red button. Delete requires typing “DELETE” to confirm. Please don’t click this, we’d hate to see you go, but if you do, please let us know how we can improve, we listen!

Design principles we followed

  1. Density is okay. We try to build information-dense, but user-friendly screens.
  2. Copy-paste is king. Anything a developer might want to copy (API keys, code examples, URLs) gets a copy button.
  3. Show, don’t tell. Recent screenshots prove the API works better than any explanation.
  4. Reduce anxiety. The usage bar, the “last used” timestamps, the success rate, these metrics help all to reduce “is this thing working?” anxiety.
  5. Get out of the way. The dashboard is a means to an end. Users want to integrate the API, not admire our dashboard. So, we make it fast to get what you need.

Visual design

We’re using Tailwind CSS with minimal customization:

  • White background, gray sidebar
  • Blue accent color for actions
  • Green/yellow/red for status indicators
  • System font stack (no custom fonts to load)
  • Plenty of whitespace

It’s quite minimal in styling and it’s functional. We can polish later, if needed.

What we built today

  • Four-page dashboard (Overview, API Keys, Usage, Settings)
  • Copy-to-clipboard for keys and code examples
  • Usage visualization with progress bar
  • Recent screenshots list
  • Basic account management

The dashboard is live. Users can now manage everything they need.

Week 2 retrospective

End of week 2. Let’s check in:

What we built this week:

  • Day 8: API contract design
  • Day 9: Job queue with Postgres
  • Day 10: Device emulation
  • Day 11: Storage with R2
  • Day 12: Landing page
  • Day 13: Authentication
  • Day 14: Dashboard

The product now:

  • [✓] Landing page
  • [✓] User signup/login
  • [✓] API key management
  • [✓] Screenshot API
  • [✓] Usage tracking
  • [✓] Dashboard

What’s missing for paid customers:

  • Stripe integration
  • Proper pricing tiers
  • Documentation

Are we ready for our first customer?

Almost. Someone could sign up, get an API key, and capture screenshots today, so this is great. But our users can’t upgrade to higher tiers yet, so that’s less great!

Tomorrow: pricing strategy

Tomorrow, on day 15 we, need to figure out what to charge. We’ll research competitors, understand our costs, and attempt to lay the foundation for a sustainable business.

Book of the day

Refactoring UI by Adam Wathan & Steve Schoger

This book (from the creators of Tailwind CSS) transformed how we approach UI design. It’s not about being a designer, it’s about making developer-built interfaces look professional.

For our dashboard, we applied their advice on spacing (use a consistent scale), typography (limit font sizes), color (start with gray, add one accent color), and visual hierarchy (size and weight matter more than color for emphasis).

The section on “designing with data” was particularly useful - how to display numbers, tables, and status information clearly.

The book is quite expensive ($99+), but absolutely worth it if you’re building products with a design focussed approach. Almost every page has actionable advice.


Day 14 stats

Hours
██████░░░░░░░░░
39h
</> Code
████████░░░░░░░
2,600
$ Revenue
░░░░░░░░░░░░░░░
$0
Customers
░░░░░░░░░░░░░░░
0
Hosting
████░░░░░░░░░░░
$5.5/mo
Achievements:
[✓] 4 dashboard pages built [✓] Copy-to-clipboard working [✓] Week 2 complete
╔════════════════════════════════════════════════════════════╗
E

Erik

Building Allscreenshots. Writes code, takes screenshots, goes diving.

Try allscreenshots

Screenshot API for the modern web. Capture any URL with a simple API call.

Get started