Changelog
A running log of what we've shipped, fixed, and improved.
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
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
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
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
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
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
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
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
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)
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
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