G5 — Age-Aware UX:
- useStageCheck hook: maps birth date → BabyStage (newborn/infant/sitter/crawler/toddler/walker)
- Time-of-day fast-log suggestion chip on home page (time × stage matrix)
- Milestones page: 25 WHO/AAP milestones, category filter, progress bar, inline date picker
- Milestones API: GET (merged definitions + achievements), POST (upsert), DELETE (un-mark)
- DB: milestone_achievements table with unique(child_id, milestone_key)
- Milestones 🌟 added to menu
G6 — Mama Affiliate Page:
- member_profiles, recommended_products, product_clicks tables
- /api/profile CRUD (GET/PUT), /api/profile/products (GET/POST/PATCH/DELETE)
- Public routes: /api/profile/[slug] and /api/profile/[slug]/click (IP hashed)
- /settings/profile: slug + bio editor, product list with ↑↓ reorder + click counts
- /m/[slug]: beautiful public page (gradient bg, product grid, Shop → click tracking)
- Settings page link to profile setup
DB migrations: 0014_milestones, 0015_affiliate.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
19 lines
655 B
TypeScript
19 lines
655 B
TypeScript
import { NextResponse } from "next/server";
|
|
import { sql } from "@/db";
|
|
|
|
export async function GET(_req: Request, { params }: { params: Promise<{ slug: string }> }) {
|
|
const { slug } = await params;
|
|
|
|
const profiles = await sql`
|
|
SELECT * FROM member_profiles WHERE slug = ${slug} AND is_public = true LIMIT 1
|
|
`;
|
|
if (!profiles[0]) return NextResponse.json({ error: "Not found" }, { status: 404 });
|
|
|
|
const profile = profiles[0];
|
|
const products = await sql`
|
|
SELECT * FROM recommended_products
|
|
WHERE profile_id = ${profile.id} AND is_active = true
|
|
ORDER BY display_order ASC
|
|
`;
|
|
return NextResponse.json({ profile, products });
|
|
}
|