[object Object]

← back to Ventura Claw Leads

yolo tick 28: home 'Recently joined' rail (conditional ≥3 claimed)

91c32a207a37536838026e384ab3ceee6e6ab35e · 2026-05-07 03:11:50 -0700 · Steve Abrams

routes/public.js GET /: extra query — newest 6 businesses where
claim_status IN ('self','claimed') AND claimed_at IS NOT NULL, ORDER BY
claimed_at DESC. Pulls photo_path so the rail can show real photos
without an extra query.

views/public/home.ejs: new section between FAQ and Featured. Renders only
when ≥3 businesses are claimed (a 1-2 entry rail looks anemic on a
half-empty home page; better to hide). Compact card layout — 240px
minmax columns vs the standard 300px on /find. Same hero treatment as
elsewhere (photo or gradient + glyph).

Drives FOMO + creates social proof: 'businesses ARE actually onboarding'
is a signal new visitors look for.

Verified: with 4 claimed → rail renders with title + 6 cards. With 0
claimed → rail hidden entirely. 46/46 tests pass.

Files touched

Diff

commit 91c32a207a37536838026e384ab3ceee6e6ab35e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu May 7 03:11:50 2026 -0700

    yolo tick 28: home 'Recently joined' rail (conditional ≥3 claimed)
    
    routes/public.js GET /: extra query — newest 6 businesses where
    claim_status IN ('self','claimed') AND claimed_at IS NOT NULL, ORDER BY
    claimed_at DESC. Pulls photo_path so the rail can show real photos
    without an extra query.
    
    views/public/home.ejs: new section between FAQ and Featured. Renders only
    when ≥3 businesses are claimed (a 1-2 entry rail looks anemic on a
    half-empty home page; better to hide). Compact card layout — 240px
    minmax columns vs the standard 300px on /find. Same hero treatment as
    elsewhere (photo or gradient + glyph).
    
    Drives FOMO + creates social proof: 'businesses ARE actually onboarding'
    is a signal new visitors look for.
    
    Verified: with 4 claimed → rail renders with title + 6 cards. With 0
    claimed → rail hidden entirely. 46/46 tests pass.
---
 routes/public.js      | 14 +++++++++++++-
 views/public/home.ejs | 29 +++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/routes/public.js b/routes/public.js
index fa93a3e..1c684b1 100644
--- a/routes/public.js
+++ b/routes/public.js
@@ -16,6 +16,18 @@ router.get('/', async (req, res, next) => {
                WHERE status = 'active' AND claim_status IN ('self','claimed')) AS claimed_count
         FROM businesses WHERE status = 'active'
     `);
+    // Recently-joined rail. Only claimed (real onboarded) businesses;
+    // unclaimed seed shells would game this. Cap at 6 so it stays a single
+    // row on desktop. Fall through to no rendering when fewer than 3.
+    const recentlyJoined = await db.many(`
+      SELECT slug, business_name, vertical, neighborhood, city, photo_path, claimed_at
+        FROM businesses
+       WHERE status = 'active'
+         AND claim_status IN ('self','claimed')
+         AND claimed_at IS NOT NULL
+       ORDER BY claimed_at DESC
+       LIMIT 6
+    `);
     const featured = await db.many(`
       SELECT slug, business_name, vertical, neighborhood, city, headline, photo_path
         FROM businesses
@@ -33,7 +45,7 @@ router.get('/', async (req, res, next) => {
     res.render('public/home', {
       title: 'Ventura Claw — directory of Ventura Blvd small businesses',
       metaDescription: `Find local restaurants, salons, retail, fitness, pet, auto detail, cleaning, and creative businesses on Ventura Blvd. ${stats.total} verified listings across Sherman Oaks, Studio City, Encino, Tarzana, and Woodland Hills.`,
-      stats, featured, verticals: VERTICALS, verticalCountMap
+      stats, featured, recentlyJoined, verticals: VERTICALS, verticalCountMap
     });
   } catch (err) { next(err); }
 });
diff --git a/views/public/home.ejs b/views/public/home.ejs
index f72e818..e9bed3a 100644
--- a/views/public/home.ejs
+++ b/views/public/home.ejs
@@ -83,6 +83,35 @@
   </details>
 </section>
 
+<% if (typeof recentlyJoined !== 'undefined' && recentlyJoined && recentlyJoined.length >= 3) { %>
+  <section class="find-page">
+    <div style="display:flex;align-items:baseline;justify-content:space-between;flex-wrap:wrap;gap:12px;margin:0 0 16px">
+      <h2 style="margin:0">Recently joined</h2>
+      <p class="muted" style="margin:0;font-size:13px">Latest businesses to claim their listing on Ventura Claw.</p>
+    </div>
+    <div class="business-grid" style="grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px">
+      <% recentlyJoined.forEach(function(b){
+           var vMeta = verticals.find(function(v){return v.key===b.vertical});
+      %>
+        <a class="business-card" href="/business/<%= b.slug %>" style="padding:14px 16px">
+          <% if (b.photo_path) { %>
+            <div class="biz-card-hero biz-card-hero-photo" style="aspect-ratio:16/9;margin:-14px -16px 12px">
+              <img src="<%= b.photo_path %>" alt="<%= b.business_name %>" loading="lazy" decoding="async">
+            </div>
+          <% } else { %>
+            <div class="biz-card-hero vertical-hero-<%= b.vertical %>" aria-hidden="true" style="aspect-ratio:16/9;margin:-14px -16px 12px">
+              <span class="biz-card-glyph"><%= vMeta ? vMeta.icon : '•' %></span>
+            </div>
+          <% } %>
+          <p class="biz-vertical" style="font-size:10px"><%= vMeta ? vMeta.label : b.vertical %></p>
+          <p class="biz-name" style="font-size:16px;margin:2px 0"><%= b.business_name %></p>
+          <p class="biz-loc" style="font-size:11px;margin:0"><%= [b.neighborhood, b.city].filter(Boolean).join(' · ') %></p>
+        </a>
+      <% }); %>
+    </div>
+  </section>
+<% } %>
+
 <% if (featured && featured.length > 0) { %>
 <section class="find-page">
   <h2>Featured this week</h2>

← f40cfda yolo tick 27: 'More <vertical> nearby' rail at the bottom of  ·  back to Ventura Claw Leads  ·  yolo tick 29: weekly-digest worker — Monday-morning summary 826d347 →