Changelog

A running log of what we've shipped, fixed, and improved.

Phase 4

Admin Portal & Businesses Data Table

Built a complete admin portal with authentication, role-based access control, and a full-featured businesses data table for managing listings.

  • Supabase Auth login at /admin with email/password
  • Role-based access control (super_admin, city_admin, business, user)
  • Protected admin layout with sidebar navigation
  • Dashboard with business, event, and deal counts
  • Businesses data table: search, sort, pagination, inline editing
  • Instagram URL auto-parsing (paste full URL → extracts username)
  • Sticky first column with frosted glass effect
  • Fixed vanity URL rewrites for Next.js 16 compatibility
Infrastructure

Instagram Handle Vanity URLs

Businesses with Instagram handles now get short vanity URLs — /charlotte/@merchantandtrade instead of /charlotte/businesses/merchant-and-trade. The @ prefix naturally disambiguates from neighborhood slugs.

  • Middleware rewrite: /<city>/@<handle> internally routes to the business detail page while keeping the short URL in the browser
  • Dual resolution: business detail page resolves both @handle and slug lookups, with permanent redirect from slug → vanity URL when IG handle exists
  • Centralized businessUrl() utility generates the preferred URL format across all components, search results, and sitemap
  • BusinessCard, BusinessMiniCard, and BusinessInfoCard updated with instagramHandle prop for correct link generation
  • Sitemap emits /@handle vanity URLs as canonical for SEO
  • Partial unique index on (city_id, instagram_handle) for fast lookups and data integrity
  • Fallback: businesses without Instagram still use /businesses/<slug> URLs
Infrastructure

IP-Based City Redirect & Data Integrity

Added automatic city detection for visitors, cleaned up the city homepage hero, and established a strict real-data-only policy for all seed content.

  • Next.js edge middleware reads Vercel x-vercel-ip-city header to auto-redirect Charlotte visitors from / to /charlotte
  • Non-Charlotte visitors see the existing landing page — no change for them
  • Static ACTIVE_CITIES map for O(1) lookups with no database calls from the edge
  • CityHero redesigned — headline left, search right, removed redundant quick link pills
  • Removed all fabricated seed data — only verified, sourced content remains (Merchant & Trade)
  • Established source/source_url requirement for all future seed data
Rename

Shops → Businesses

Renamed "shops" to "businesses" throughout the entire stack — database, types, queries, API routes, components, pages, URLs, sitemap, and documentation. The term "businesses" is more inclusive for restaurants, bars, venues, services, and breweries.

  • Database migration: ALTER TABLE shops RENAME TO businesses, updated constraints, indexes, and triggers
  • Type definitions: Shop → Business, ShopCard → BusinessCard, all type unions updated
  • Query layer: getShops → getBusinesses, getShopBySlug → getBusinessBySlug, and 6 more function renames
  • URL routes: /[city]/shops → /[city]/businesses (listing and detail pages)
  • Components: ShopCard → BusinessCard, SearchOverlay, CityMap, Footer, MapPageClient updated
  • API routes: /api/map/markers and /api/search return "businesses" key instead of "shops"
  • Sitemap, OpenGraph image, and all page metadata updated
  • CLAUDE.md and all context docs updated to reflect new naming
Phase 2.6

Spotlight Search

Built a Spotlight-style command palette search overlay triggered from the navigation. Real-time search across events, deals, shops, and jobs with keyboard navigation, recent search history, and quick links.

  • SearchOverlay component with Apple-inspired frosted glass panel, portaled above all content
  • Cmd+K / Ctrl+K global keyboard shortcut to toggle search
  • Multi-field search — queries titles, descriptions, business/venue names across all content types
  • Jobs added to search results alongside events, deals, and shops
  • Keyboard navigation — Arrow Up/Down to browse results, Enter to select, Escape to close
  • Recent searches persisted in localStorage with clear option
  • Quick links panel when search is empty (Tonight, This Weekend, Events, Deals, Shops, Jobs, Calendar, Map)
  • "See all results" link bridges to full search page for deeper exploration
  • useSearchOverlay custom hook encapsulating all search state, debouncing, and keyboard handling
  • GET /api/search endpoint for client-side search fetching with city validation
  • Accessible combobox pattern with ARIA roles, live region announcements, and focus management
  • Responsive — full-screen on mobile, centered modal on desktop
Redesign

Apple-Inspired UI Overhaul

Complete visual redesign adopting Apple's design language across 55+ files. Monochrome palette with orange as the sole accent, frosted glass surfaces, generous whitespace, and restrained animation.

  • New apple-* color scale (Apple grays) replacing state/event/deal/shop/hood color systems
  • Inter font replaces Plus Jakarta Sans for all UI and body text; Fraunces preserved for editorial headlines
  • Frosted glass header with backdrop-blur-xl and semi-transparent white
  • Button, Card, and Badge variants simplified — removed per-content-type colors
  • All hover animations unified to scale-[1.01] with 200ms ease-out transitions
  • Rounded rectangles (rounded-xl/2xl) replace pill shapes on buttons and cards
  • Subtle diffused shadows replace colored glows and dramatic shadows
  • Content cards (DealCard, EventCard, ShopCard) unified with monochrome styling
  • Calendar components updated — uniform gray dots, frosted glass nav, Apple segmented controls
  • Neighborhood components cleaned up — removed multi-color vibe system, uniform badge styling
  • All 22 page files updated with new design tokens and layout patterns
  • Jobs components (6 files) updated — solid orange pricing, Apple form controls
  • GradientDivider simplified to single gray line divider
  • SearchInput redesigned with Apple-style gray background and focus transitions
Phase 5

SEO Fundamentals & Phase 2 Polish

Added comprehensive SEO infrastructure (structured data, sitemap, robots.txt, canonical URLs, OpenGraph) and Phase 2 polish features (share buttons, add-to-calendar, expiring-soon badges, ISR caching).

  • metadataBase + canonical URLs + OpenGraph meta tags on all 18+ pages
  • JSON-LD structured data: Event, LocalBusiness + Offer, BreadcrumbList schemas
  • Dynamic sitemap.xml querying all cities, neighborhoods, events, deals, and shops
  • robots.txt allowing all crawlers with sitemap reference
  • ShareButtons component (copy link, native share, post to X) on detail pages
  • AddToCalendarButton with ICS/iCal file download on event detail pages
  • "Expiring Soon" badge on DealCard and amber warning banner on deal detail pages
  • ISR with 5-minute revalidation on 6 high-traffic listing pages
Phase 2.5

TodayHero, Sidebar & Timeline UI

Added a reusable "Tonight / Today" hero section with carousel, vertical event timeline, and deals list. Extracted a global ad sidebar and wired everything into neighborhood, calendar, and tonight pages.

  • TodayHero component with crossfading carousel matching NeighborhoodHero pattern
  • Vertical event timeline with left-aligned times, connecting dots, and line spine
  • Deals list with discount tag/pill positioned on the right
  • Reusable Sidebar component (ads, newsletter, quick links) extracted from city page
  • Sidebar added to neighborhood, calendar, and tonight pages
  • CalendarWeekContent refactored to use TodayHero with ReactNode sidebar slot
  • Tonight page rebuilt with TodayHero and sidebar layout
Phase 2

Core Pages & Features

Built all browsing pages end-to-end: listing grids, detail pages, temporal views, neighborhoods, and search. Every header link now resolves to a real page.

  • Events listing with category, neighborhood, and free filters
  • Deals listing with category and neighborhood filters
  • Shops listing with category and neighborhood filters
  • Full detail pages for events, deals, and shops with related content sidebars
  • Tonight and This Weekend temporal view pages
  • Day-of-week specials pages with inline day navigation
  • Neighborhood mini-homepages with carousel sections
  • Search page with debounced input and grouped results
  • FilterBar client component with URL-driven state
  • ListingPageHeader component with variant-colored overlines
  • Centralized query layer (queries.ts) with 11 reusable functions
  • Header search button wired to search page
  • City layout now queries Supabase instead of hardcoded data
  • Seeded 33 realistic Charlotte listings (15 deals, 10 events, 8 shops)
Phase 0.3–0.4

Visual Identity Refinements & Changelog

Added editorial polish, reusable components, dynamic social images, and this changelog page.

  • Typographic "HereWithin" wordmark in the header
  • GradientDivider component for editorial section breaks
  • NeighborhoodIndicator component with vibe-based color dots
  • FeaturedArticleCard component extracted from city page
  • Dynamic Open Graph image via Next.js ImageResponse
  • Gradient dividers wired into the Charlotte city page
  • This changelog page with timeline UI
Phase 0.1–0.2

Foundation & Design Token Adoption

Established the design system, adopted semantic color tokens across every component and page, and removed dark mode.

  • Three-tier editorial typography: Fraunces / Plus Jakarta Sans / Inter (later simplified in Mar 2026 redesign)
  • Semantic color palette: city, hood, event, deal, shop, state tokens (later unified in Mar 2026 redesign)
  • Gradient tokens for branded accents (bg-gradient-city, etc.)
  • Token adoption across all 18 component and page files
  • Removed all hardcoded hex colors, slate-*, and dark: class prefixes
  • CarouselSection component with horizontal scroll and "See All" link
  • Header with day-of-week navigation and collapsible secondary bar
  • Footer with gradient wordmark and newsletter CTA
  • EventCard, DealCard, ShopCard listing components
  • Badge component with semantic variants (city, deal, event, etc.)
  • Modal, Input, Select, Skeleton base components