Spotta
Available for work
Spotta Case Study
Case Study – Civic Tech · Founder Project

Honest street reviews for Lagos. From zero to live.

I designed and built Spotta, Nigeria's first street review platform, from concept to production in under two months. 1,590 streets. 1,083 reviews. 28 neighborhoods. Next.js, Supabase, and AI tools turning Figma files into live code.

RoleFounder · Designer · Developer
ScopeConcept → Design → Full-Stack Build
StackNext.js · Supabase · v0 · Claude
Spotta street page - Deji Olamiju Street
The Problem

Moving in Lagos is a gamble.

When someone in Lagos is looking for a place to live, they're asking real questions: Does this street have stable power? Does it flood? Is it safe at night? Is the water situation manageable? There's no reliable way to find out. You ask around, you visit, you hope. Google Maps tells you the street exists. Not whether the power supply will keep your fridge running.

I wanted to build the platform that answers those questions. A "Yelp for streets" where real residents review infrastructure (power, water, security, roads, flooding, internet, noise, and environment) so the next person moving in knows exactly what they're getting into.

The catch? I'm a product designer, not a full-stack engineer. I'd need to design the product, build the front-end, configure the database, handle authentication, manage street data for an entire city, optimize for search engines, and ship it live. So I used AI as my engineering partner.

1,590
Streets covered
Across 28 neighborhoods in Lagos, with structured data for each.
1,083
Reviews submitted
Real experiences from residents. Category-level ratings, not just star counts.
8
Review categories
Power, water, security, roads, flooding, internet, noise, environment.
<2mo
Design to live
From Figma concept to production web app, built with AI tooling.
The Data Challenge

Before designing screens, I needed streets.

A street review platform is only as good as its street data. I needed structured, accurate records for thousands of Lagos streets (name, area, local government area), organized in a way that prevents duplicates and supports search. Three approaches, each with tradeoffs:

1

Google Maps API – too expensive

The obvious choice. Google's Places API has excellent Lagos coverage, but the pricing at scale made it a non-starter for a bootstrapped civic project. Every search query, every place detail call. Costs add up fast when you're covering an entire city.

2

OpenStreetMap – the normalization trap

Free and open. I implemented OSM search so the homepage fetched from OSM, and streets would only be created in my database when a user left their first review, keeping the database lean. But I immediately hit a critical problem: boundary inconsistencies. The same street appeared under different area names depending on which OSM boundary polygon contained it. A street on the edge of two neighborhoods could show up twice with different parents. This defeated the entire purpose of a structured review platform.

3

Build my own system – with AI deduplication

I built an external tool using AI to scan the OSM-sourced data, find and flag duplicates across boundary zones, and present them for manual resolution. I'd resolve the conflicts, export clean data to XLSX, then bulk-import it through my admin dashboard. Way faster than adding streets individually. And the data was mine to control.

Design Evolution

The review form I shipped first was wrong.

The first version of the review form let users select multiple categories (Parking Lot, Nightlife, Hospitals…) but only give one overall star rating. This felt simpler, but the data it produced was useless. A street with great security but terrible roads would get 3.5 stars. And that number tells you nothing about either.

After user feedback, I rebuilt the form so every selected category gets its own rating. Each user's individual category ratings combine into their overall score, and those aggregate into the street's per-category breakdown. Now when you look at a street page, you see Security ★4.5, Power ★3.3, Roads ★2.0, information you can actually act on.

Version 1 – Single Rating

One score for everything

Users pick categories but give one star rating. Simple form, but produces a meaningless average that masks what actually matters about a street.

One score for everything
Visual Reference
The 'Review Location' modal screenshot
Version 2 – Per-Category

Rate what you selected

Each category gets its own input. Stars for quality metrics (Power, Security). Frequency sliders for yes/no phenomena (Flood: Never→Always, Noise). Overall auto-calculated.

Rate what you selected
Visual Reference
The 'Rate Street' modal screenshot
The Frequency Problem

Not everything is a star rating.

When I started implementing per-category ratings, I hit a design problem: flooding isn't a quality you rate on a scale. A street either floods or it doesn't, with frequency in between. Same with noise. You don't give noise "4 stars". That doesn't mean anything.

The solution was contextual input types. Power, water, security, roads, and internet use star ratings, because quality is what matters. Flood and noise use frequency sliders (Never → Rarely → Sometimes → Often → Always). The slider maps to a 0–5 value: "Never" = 5 (best), "Always" = 0 (worst). This lets the system compute a meaningful aggregate while giving users an input that matches how they actually think about the data.

On the street page, these render differently too. Stars show as bar charts with numeric ratings. Flood and noise show as badges: "Never floods", "Mostly quiet", human-readable summaries derived from aggregate slider positions.

The Street Page

A dashboard for every street in Lagos.

Each street page is a living profile: reviews with threaded replies, category filter pills, photo uploads with lightbox, a shareable deep link per review, and the Street Analysis sidebar with ratings, sentiment analysis, cost of living, and property tabs.

Ratings Tab
Ratings Tab
Street reviews, category filters, and detailed analysis sidebar
Sentiment Tab
Sentiment Tab
AI-powered sentiment analysis with confidence meter and mixed feedback tracking
Photo Lightbox
Photo Lightbox
User-uploaded street photos with intuitive navigation and lightbox view
Share Modal
Share Modal
Deep-link sharing with review preview cards and quick-copy functionality
Technical Gauntlet

The problems that made me a better builder.

Building a production web app from a design background meant solving problems I'd never encountered in Figma. Each one taught me something about how software actually works, and made me a sharper designer for it.

1

The authentication puzzle

Google OAuth redirects users away from the app and back. During that redirect, the system lost track of profile creation – accounts existed but profiles didn't. The fix: localStorage flags written before the redirect, checked on return. Now every Google sign-in creates a complete profile with auto-generated avatar and username derived from email. localStorage

2

The speed problem – 150+ calculations per page load

Avatar display was recalculating the image source for every review on every re-render. With 20 reviews on a page, that's 20 recalculations per state change. I learned about memoization – calculate once, remember the answer, only recalculate when the source data changes. Went from 150+ calculations to 2–3 per page load.

3

The SEO breakthrough – client-side to server-side rendering

With client-side rendering, Google saw empty pages – all content loaded after JavaScript executed. Search engines couldn't index the reviews, ratings, or street data. I migrated to server-side rendering so pages arrive fully formed with structured data (JSON-LD). Now searching "Allen Avenue Ikeja reviews" can surface Spotta with star ratings directly in Google results.

4

The bookmark ghost – state persisting after logout

Users would log out but bookmarked streets still appeared bookmarked. The system wasn't checking for an active session before rendering bookmark state. A small detail, but one that erodes trust. The fix was a session check that resets bookmark UI on logout. Designing the code taught me how much "trust" lives in tiny state management details.

The admin dashboard:
controlling the data.

Managing 1,590 streets and 1,083 reviews across 28 neighborhoods requires tooling. I designed and built a full admin dashboard (overview analytics, area-level drill-downs, street management with inline review previews, category configuration, and user management), all with the same AI-assisted development workflow as the public site.

Overview Dashboard

Total users, reviews, streets covered, average rating. User activity chart and recent activity feed.

Area Analytics

28 areas with street count, total reviews, average rating, and growth percentage.

Street Management

Full street list with area, state, LGA. Click any street for a detail panel with recent reviews.

Category Performance

See which categories users care about most, with trend indicators.

Bulk Import

Upload XLSX with hundreds of streets. System validates, generates URL slugs automatically.

Category Config

Create, edit, enable/disable review categories. Assign colors, set display order.

Admin Dashboard
Admin Interface
Comprehensive management system: real-time analytics, area-level performance tracking, and streamlined street/review moderation.
User Experience

Building a community, not just a tool.

A review platform dies without contributors. I designed a user system that rewards participation: profile pages with review history and activity stats, a contributor level system (Neighborhood Scout → leveling up), and achievements.
First Steps, Regular Contributor, Area Explorer, Well-Rounded (review across 4+ categories), Monthly Enthusiast. Think Google Local Guides, built for Lagos streets.

Your review history, your impact
User Profile

Your review history, your impact

Every review you've written, organized by street. Sidebar shows activity stats (reviews, bookmarks, upvotes, replies), contributor level with progress bar, and key insights: most reviewed area, average rating, most active month.

Motivating local guides
Achievements

Motivating local guides

Structured achievement tiers (Beginner, Explorer) with progress tracking. First Steps, Bookmarker, Conversationalist – completed. Regular Contributor (2/5), Collection Builder (1/5), Area Explorer (2/5) – in progress. Forward-thinking design to motivate sustained contribution.

How I Built It

Figma → AI → Production.

I'm a product designer who leverages AI to ship. The workflow: design in Figma, then use v0, Claude, ChatGPT, and Trae to convert designs into production code. v0 handled initial component scaffolding. Claude and ChatGPT helped me solve backend logic I'd never written before: Row Level Security policies, OAuth flows, database migrations. Trae helped with iteration speed.

This isn't "AI built my product." I made every product decision, designed every screen, and directed every implementation. AI was the engineering team I didn't have. And learning to collaborate with it made me understand code in ways that fundamentally changed how I design. I now think about state management when I design interactions, data models when I design information architecture, and rendering strategies when I think about SEO.

Next.js
Framework · SSR
Supabase
Database · Auth · RLS
🎨
Figma
Design · Prototyping
🤖
v0 · Claude · Trae
AI Development
Outcomes

Live in production. Real users. Real data.

1,590
Streets with structured profiles across Lagos
1,083
Reviews from real Lagos residents
28
Neighborhoods covered with area-level analytics
<2mo
From Figma design to live production site
Reflection

What building taught me about designing.

Spotta changed how I work. Before this project, I was a product designer who handed off specs. After Spotta, I'm a product designer who understands what happens after the handoff, and that understanding makes every design decision sharper.

State is a design material

The bookmark ghost bug taught me that UI state isn't just 'checked vs unchecked', it's a function of session, authentication, and persistence. Now when I design interactive states, I think about where the truth lives.

Data models shape UX

The review form evolution happened because the data model (one rating vs per-category ratings) determined what the product could even show. Designing the database schema is designing the user experience.

Performance is a feature

150+ unnecessary calculations per page load is invisible in Figma but devastating on a phone in Lagos. The memoization lesson taught me that what I don't render matters as much as what I do.

SEO is information architecture

Switching from client-side to server-side rendering wasn't a 'dev task'. It was a product decision about discoverability. If Google can't read your page, it doesn't exist. Structured data is IA for machines.

"I didn't build Spotta to become a developer. I built it because the product needed to exist. And I learned that a designer who can ship is a designer who can think about the whole problem."
Next Project
Ayika

Designing an energy-aware calendar that respects your body's rhythms.

View Case Study