Skip to content

Commit 56c80cd

Browse files
patrickrbclaude
andauthored
feat(dashboard): inline Quick log form on the dashboard hero (#217)
Replaces the placeholder Quick log card (which only linked to /new-contact) with a real inline form: callsign with debounced QRZ lookup, frequency with auto-band derivation, mode-aware RST defaults, station picker when multiple are configured, and a Save button that posts to /api/contacts. Matches the new-design/dashboard.html mockup. Saving refreshes the contacts table and stat cards on the parent page, then refocuses the callsign input for rapid sequential logging. Also bumps the README stack blurb to Next.js 16 / React 19 / TS 5.8 and notes the Drizzle Kit + raw-pg runtime split. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b722e05 commit 56c80cd

3 files changed

Lines changed: 427 additions & 47 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ A modern, web-based amateur radio logging application built with Next.js and Pos
1818

1919
## Technology Stack
2020

21-
- **Frontend**: Next.js 15 with TypeScript
21+
- **Frontend**: Next.js 16, React 19, TypeScript 5.8
2222
- **Backend**: Next.js API Routes
23-
- **Database**: PostgreSQL with native SQL
23+
- **Database**: PostgreSQL (raw `pg` at runtime); schema-as-code via Drizzle Kit (`drizzle/schema.ts`)
2424
- **Authentication**: JWT-based authentication
2525
- **Styling**: Tailwind CSS
2626
- **Deployment**: Vercel-ready
@@ -29,7 +29,7 @@ A modern, web-based amateur radio logging application built with Next.js and Pos
2929

3030
### Prerequisites
3131

32-
- Node.js 18+
32+
- Node.js 20.9+ (required by Next.js 16)
3333
- PostgreSQL 13+ database
3434
- Docker and Docker Compose (recommended)
3535
- Git

src/app/dashboard/page.tsx

Lines changed: 7 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import EditContactDialog from '@/components/EditContactDialog';
1111
import DXpeditionWidget from '@/components/DXpeditionWidget';
1212
import QslMatrix from '@/components/QslMatrix';
1313
import Pagination from '@/components/Pagination';
14+
import QuickLogCard from '@/components/QuickLogCard';
1415
import { Button } from '@/components/ui/button';
1516
import { Card } from '@/components/ui/card';
1617
import { Chip } from '@/components/ui/chip';
@@ -366,50 +367,12 @@ export default function DashboardPage() {
366367
</div>
367368
</Card>
368369

369-
<Card className="p-4 sm:p-7 flex flex-col gap-5">
370-
<div className="flex items-center justify-between">
371-
<h2 className="text-[17px] font-semibold">Quick log</h2>
372-
<Chip variant="accent" size="sm">
373-
<Dot tone="ok" live />
374-
Live
375-
</Chip>
376-
</div>
377-
<p className="text-sm text-fg-2">
378-
Need more fields? Open the full new-contact form for callsign
379-
lookup, RST defaults by mode, station picker, and notes.
380-
</p>
381-
<Button asChild size="lg" className="w-full">
382-
<Link href="/new-contact">
383-
<Plus />
384-
Log a QSO
385-
</Link>
386-
</Button>
387-
<div className="flex items-center gap-2 text-xs text-fg-2">
388-
Press <Kbd>L</Kbd> on any page to jump straight in.
389-
</div>
390-
<div className="border-t border-line pt-4">
391-
<div className="text-[13px] font-medium uppercase tracking-[0.06em] text-fg-2 mb-3">
392-
Recent
393-
</div>
394-
<div className="flex flex-col gap-2">
395-
{contacts.slice(0, 4).map((contact) => (
396-
<button
397-
key={contact.id}
398-
type="button"
399-
onClick={() => handleContactClick(contact)}
400-
className="flex justify-between items-center px-3 py-2 rounded-[10px] bg-bg-1 border border-line text-left hover:border-line-hi transition-colors cursor-pointer"
401-
>
402-
<span className="font-mono font-semibold text-fg">
403-
{contact.callsign}
404-
</span>
405-
<span className="text-xs text-fg-2 font-mono">
406-
{contact.band} · {contact.mode} · {formatUtc(contact.datetime)}
407-
</span>
408-
</button>
409-
))}
410-
</div>
411-
</div>
412-
</Card>
370+
<QuickLogCard
371+
onSaved={() => {
372+
fetchContacts(1, pagination.limit);
373+
fetchStats();
374+
}}
375+
/>
413376
</div>
414377

415378
{/* Band activity */}

0 commit comments

Comments
 (0)