Mobile responsive: hamburger menu, stacked forms, card layout on mobile
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
<% const activePage = 'history'; %>
|
<% const activePage = 'history'; %>
|
||||||
<%- include('partials/sidebar') %>
|
<%- include('partials/sidebar') %>
|
||||||
|
|
||||||
<main class="flex-1 ml-56 p-6">
|
<main class="flex-1 md:ml-56 mt-14 md:mt-0 p-4 md:p-6">
|
||||||
<h2 class="text-lg font-bold mb-4">Search History</h2>
|
<h2 class="text-lg font-bold mb-4">Search History</h2>
|
||||||
|
|
||||||
<% if (!searches || searches.length === 0) { %>
|
<% if (!searches || searches.length === 0) { %>
|
||||||
|
|||||||
@@ -5,35 +5,39 @@
|
|||||||
<% const activePage = 'search'; %>
|
<% const activePage = 'search'; %>
|
||||||
<%- include('partials/sidebar') %>
|
<%- include('partials/sidebar') %>
|
||||||
|
|
||||||
<main class="flex-1 ml-56">
|
<main class="flex-1 md:ml-56 mt-14 md:mt-0">
|
||||||
<!-- Search Bar -->
|
<!-- Search Bar -->
|
||||||
<div class="bg-sidebar/50 border-b border-white/5 p-4">
|
<div class="bg-sidebar/50 border-b border-white/5 p-3 md:p-4">
|
||||||
<form id="searchForm" class="flex items-end gap-3 max-w-5xl">
|
<form id="searchForm" class="flex flex-col md:flex-row md:items-end gap-2 md:gap-3 max-w-5xl">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<label class="block text-xs text-gray-500 mb-1">Keyword</label>
|
<label class="block text-xs text-gray-500 mb-1">Keyword</label>
|
||||||
<input type="text" name="keyword" placeholder="e.g. Restaurants, Plumbers..."
|
<input type="text" name="keyword" placeholder="e.g. Restaurants, Plumbers..."
|
||||||
class="w-full bg-card border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-gray-500 focus:outline-none focus:border-accent" required>
|
class="w-full bg-card border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-gray-500 focus:outline-none focus:border-accent" required>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex gap-2 flex-1">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<label class="block text-xs text-gray-500 mb-1">City</label>
|
<label class="block text-xs text-gray-500 mb-1">City</label>
|
||||||
<input type="text" name="city" placeholder="e.g. Austin"
|
<input type="text" name="city" placeholder="e.g. Austin"
|
||||||
class="w-full bg-card border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-gray-500 focus:outline-none focus:border-accent" required>
|
class="w-full bg-card border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-gray-500 focus:outline-none focus:border-accent" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-40">
|
<div class="flex-1 md:w-40 md:flex-none">
|
||||||
<label class="block text-xs text-gray-500 mb-1">State</label>
|
<label class="block text-xs text-gray-500 mb-1">State</label>
|
||||||
<input type="text" name="state" placeholder="e.g. Texas"
|
<input type="text" name="state" placeholder="e.g. Texas"
|
||||||
class="w-full bg-card border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-gray-500 focus:outline-none focus:border-accent">
|
class="w-full bg-card border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-gray-500 focus:outline-none focus:border-accent">
|
||||||
</div>
|
</div>
|
||||||
<div class="w-24">
|
</div>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<div class="w-20 md:w-24">
|
||||||
<label class="block text-xs text-gray-500 mb-1">Max</label>
|
<label class="block text-xs text-gray-500 mb-1">Max</label>
|
||||||
<input type="number" name="maxResults" value="20" min="1" max="100"
|
<input type="number" name="maxResults" value="20" min="1" max="100"
|
||||||
class="w-full bg-card border border-white/10 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-accent">
|
class="w-full bg-card border border-white/10 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-accent">
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" id="searchBtn"
|
<button type="submit" id="searchBtn"
|
||||||
class="bg-accent hover:bg-accent-hover text-white px-5 py-2 rounded-lg text-sm font-medium transition-colors flex items-center gap-2">
|
class="bg-accent hover:bg-accent-hover text-white px-5 py-2 rounded-lg text-sm font-medium transition-colors flex items-center gap-2 self-end flex-1 md:flex-none justify-center">
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
|
||||||
Search
|
Search
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -95,7 +99,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Detail Panel -->
|
<!-- Detail Panel -->
|
||||||
<div id="detailPanel" class="fixed top-0 right-0 w-96 h-full bg-sidebar border-l border-white/10 z-50 hidden overflow-y-auto scrollbar-thin">
|
<div id="detailPanel" class="fixed top-0 right-0 w-full md:w-96 h-full bg-sidebar border-l border-white/10 z-50 hidden overflow-y-auto scrollbar-thin">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<% const activePage = 'leads'; %>
|
<% const activePage = 'leads'; %>
|
||||||
<%- include('partials/sidebar') %>
|
<%- include('partials/sidebar') %>
|
||||||
|
|
||||||
<main class="flex-1 ml-56 p-6">
|
<main class="flex-1 md:ml-56 mt-14 md:mt-0 p-4 md:p-6">
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<h2 class="text-lg font-bold">Saved Leads</h2>
|
<h2 class="text-lg font-bold">Saved Leads</h2>
|
||||||
<span class="text-xs text-gray-500"><%= leads.length %> leads</span>
|
<span class="text-xs text-gray-500"><%= leads.length %> leads</span>
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
<a href="/" class="mt-4 bg-accent hover:bg-accent-hover text-white px-4 py-2 rounded-lg text-sm transition-colors">Search Leads</a>
|
<a href="/" class="mt-4 bg-accent hover:bg-accent-hover text-white px-4 py-2 rounded-lg text-sm transition-colors">Search Leads</a>
|
||||||
</div>
|
</div>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<div class="overflow-x-auto rounded-lg border border-white/5">
|
<!-- Desktop table -->
|
||||||
|
<div class="hidden md:block overflow-x-auto rounded-lg border border-white/5">
|
||||||
<table class="w-full text-sm">
|
<table class="w-full text-sm">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-card text-gray-400 text-left text-xs uppercase tracking-wider">
|
<tr class="bg-card text-gray-400 text-left text-xs uppercase tracking-wider">
|
||||||
@@ -63,6 +64,28 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Mobile cards -->
|
||||||
|
<div class="md:hidden space-y-2">
|
||||||
|
<% leads.forEach(l => { %>
|
||||||
|
<div class="bg-card border border-white/5 rounded-lg p-4" id="lead-mobile-<%= l.placeId %>">
|
||||||
|
<div class="flex items-start justify-between">
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<p class="font-medium text-white text-sm truncate"><%= l.title %></p>
|
||||||
|
<p class="text-xs text-gray-500"><%= l.categoryName %></p>
|
||||||
|
</div>
|
||||||
|
<button onclick="removeLead('<%= l.placeId %>')" class="text-red-400 hover:text-red-300 ml-2 flex-shrink-0">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 space-y-1 text-xs text-gray-400">
|
||||||
|
<% if (l.phone) { %><p>📞 <a href="tel:<%= l.phone %>" class="text-accent"><%= l.phone %></a></p><% } %>
|
||||||
|
<% if (l.email) { %><p>✉️ <%= l.email %></p><% } %>
|
||||||
|
<% if (l.website) { %><p>🌐 <a href="<%= l.website %>" target="_blank" class="text-accent truncate block"><%= l.website.replace(/^https?:\/\//, '').replace(/\/$/, '') %></a></p><% } %>
|
||||||
|
<% if (l.totalScore) { %><p><span class="text-yellow-400">★</span> <%= l.totalScore.toFixed(1) %> (<%= l.reviewsCount %> reviews)</p><% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% }) %>
|
||||||
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
body { font-family: 'Inter', system-ui, sans-serif; }
|
html, body { font-family: 'Inter', system-ui, sans-serif; overflow-x: hidden; }
|
||||||
.scrollbar-thin::-webkit-scrollbar { width: 6px; }
|
.scrollbar-thin::-webkit-scrollbar { width: 6px; }
|
||||||
.scrollbar-thin::-webkit-scrollbar-track { background: transparent; }
|
.scrollbar-thin::-webkit-scrollbar-track { background: transparent; }
|
||||||
.scrollbar-thin::-webkit-scrollbar-thumb { background: #333; border-radius: 3px; }
|
.scrollbar-thin::-webkit-scrollbar-thumb { background: #333; border-radius: 3px; }
|
||||||
|
|||||||
@@ -1,4 +1,34 @@
|
|||||||
<aside class="w-56 bg-sidebar h-screen flex flex-col fixed left-0 top-0 z-40">
|
<!-- Mobile top bar -->
|
||||||
|
<div class="md:hidden fixed top-0 left-0 right-0 z-50 bg-sidebar border-b border-white/10 flex items-center justify-between px-4 py-3">
|
||||||
|
<h1 class="text-sm font-bold text-white flex items-center gap-2">
|
||||||
|
<svg class="w-4 h-4 text-accent" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||||
|
Lead Scraper
|
||||||
|
</h1>
|
||||||
|
<button id="mobileMenuBtn" onclick="document.getElementById('mobileSidebar').classList.toggle('hidden')" class="text-gray-400 hover:text-white">
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mobile nav overlay -->
|
||||||
|
<div id="mobileSidebar" class="hidden md:hidden fixed inset-0 z-50 bg-black/60" onclick="this.classList.add('hidden')">
|
||||||
|
<nav class="bg-sidebar w-56 h-full p-4 pt-16 space-y-1" onclick="event.stopPropagation()">
|
||||||
|
<a href="/" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors <%= typeof activePage !== 'undefined' && activePage === 'search' ? 'bg-accent/20 text-accent' : 'text-gray-400 hover:bg-white/5 hover:text-white' %>">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
|
||||||
|
Search
|
||||||
|
</a>
|
||||||
|
<a href="/history" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors <%= typeof activePage !== 'undefined' && activePage === 'history' ? 'bg-accent/20 text-accent' : 'text-gray-400 hover:bg-white/5 hover:text-white' %>">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||||
|
History
|
||||||
|
</a>
|
||||||
|
<a href="/leads" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors <%= typeof activePage !== 'undefined' && activePage === 'leads' ? 'bg-accent/20 text-accent' : 'text-gray-400 hover:bg-white/5 hover:text-white' %>">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"/></svg>
|
||||||
|
Leads
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Desktop sidebar -->
|
||||||
|
<aside class="hidden md:flex w-56 bg-sidebar h-screen flex-col fixed left-0 top-0 z-40">
|
||||||
<div class="p-5 border-b border-white/10">
|
<div class="p-5 border-b border-white/10">
|
||||||
<h1 class="text-lg font-bold text-white flex items-center gap-2">
|
<h1 class="text-lg font-bold text-white flex items-center gap-2">
|
||||||
<svg class="w-5 h-5 text-accent" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
<svg class="w-5 h-5 text-accent" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||||
|
|||||||
Reference in New Issue
Block a user