production auth: signup, login, protected dashboard, landing page, WAHA QR fix
AUTH: - NextAuth with credentials provider (bcrypt password hashing) - /api/auth/signup: creates org + user in transaction - /login, /signup pages with clean minimal UI - Middleware protects all /dashboard/* routes → redirects to /login - Session-based org resolution (no more hardcoded 'demo' headers) - SessionProvider wraps entire app - Dashboard header shows org name + sign out button LANDING PAGE: - Full marketing page at / with hero, problem, how-it-works, features, CTA - 'Get Started Free' → /signup → auto-login → /dashboard/setup - Clean responsive design, no auth required for public pages WAHA QR FIX: - WAHA CORE doesn't expose QR value via API or webhook - Now uses /api/screenshot (full browser capture) with CSS crop to QR area - Settings panel shows cropped screenshot with overflow:hidden - Auto-polls every 5s, refresh button MULTI-TENANT: - getOrgId() tries session first, then header, then first-org fallback - All dashboard APIs use session-based org - Signup creates isolated org per charity
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import { NextRequest, NextResponse } from "next/server"
|
||||
import prisma from "@/lib/prisma"
|
||||
import { resolveOrgId } from "@/lib/org"
|
||||
import { getOrgId } from "@/lib/session"
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
if (!prisma) return NextResponse.json({ error: "DB not configured" }, { status: 503 })
|
||||
const orgId = await resolveOrgId(request.headers.get("x-org-id") || "demo")
|
||||
const orgId = await getOrgId(request.headers.get("x-org-id"))
|
||||
if (!orgId) return NextResponse.json({ error: "Org not found" }, { status: 404 })
|
||||
|
||||
const org = await prisma.organization.findUnique({ where: { id: orgId } })
|
||||
@@ -39,7 +39,7 @@ export async function PUT(request: NextRequest) {
|
||||
const body = await request.json()
|
||||
|
||||
// Try to find existing org first
|
||||
const orgId = await resolveOrgId(request.headers.get("x-org-id") || "default")
|
||||
const orgId = await getOrgId(request.headers.get("x-org-id"))
|
||||
|
||||
if (orgId) {
|
||||
// Update existing
|
||||
@@ -76,7 +76,7 @@ export async function PUT(request: NextRequest) {
|
||||
export async function PATCH(request: NextRequest) {
|
||||
try {
|
||||
if (!prisma) return NextResponse.json({ error: "DB not configured" }, { status: 503 })
|
||||
const orgId = await resolveOrgId(request.headers.get("x-org-id") || "demo")
|
||||
const orgId = await getOrgId(request.headers.get("x-org-id"))
|
||||
if (!orgId) return NextResponse.json({ error: "Org not found" }, { status: 404 })
|
||||
|
||||
const body = await request.json()
|
||||
|
||||
Reference in New Issue
Block a user