diff --git a/src/actions/analytics.ts b/src/actions/analytics.ts index 1d6c99f..38bd544 100644 --- a/src/actions/analytics.ts +++ b/src/actions/analytics.ts @@ -284,7 +284,7 @@ export async function getRecentOrders(limit: number = 10): Promise( `SELECT o.id::text AS id, - c.name AS customer_name, + TRIM(COALESCE(c.first_name, '') || ' ' || COALESCE(c.last_name, '')) AS customer_name, o.total_cents::float / 100.0 AS subtotal, o.status, o.placed_at::text AS created_at, diff --git a/src/actions/dashboard.ts b/src/actions/dashboard.ts index 97a41c6..3293d2a 100644 --- a/src/actions/dashboard.ts +++ b/src/actions/dashboard.ts @@ -42,24 +42,22 @@ export async function getDashboardStats(): Promise { const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate()); const endOfDay = new Date(startOfDay.getTime() + 24 * 60 * 60 * 1000); - // Fetch today's orders. `orders` and `stops` use the legacy schema - // (column names like `subtotal`, `brand_id`, `date`); the new-schema - // Drizzle `orders` table doesn't have these. Raw SQL via the shared - // pg pool. + // Fetch today's orders. New schema: `total_cents` (int, divide by 100 + // for dollars) and `placed_at` (not legacy `subtotal` / `created_at`). const todayOrdersRes = brandId - ? await pool.query<{ subtotal: number; status: string }>( - `SELECT subtotal, status + ? await pool.query<{ total_cents: number; status: string }>( + `SELECT total_cents, status FROM orders - WHERE created_at >= $1 - AND created_at < $2 + WHERE placed_at >= $1 + AND placed_at < $2 AND brand_id = $3`, [startOfDay.toISOString(), endOfDay.toISOString(), brandId], ) - : await pool.query<{ subtotal: number; status: string }>( - `SELECT subtotal, status + : await pool.query<{ total_cents: number; status: string }>( + `SELECT total_cents, status FROM orders - WHERE created_at >= $1 - AND created_at < $2`, + WHERE placed_at >= $1 + AND placed_at < $2`, [startOfDay.toISOString(), endOfDay.toISOString()], ); const todayOrders = todayOrdersRes.rows; @@ -67,7 +65,7 @@ export async function getDashboardStats(): Promise { // Calculate today's revenue and orders const validOrders = todayOrders.filter((o) => o.status !== "cancelled"); const todayRevenue = validOrders.reduce( - (sum, o) => sum + (o.subtotal || 0), + (sum, o) => sum + ((o.total_cents || 0) / 100), 0, ); const todayOrderCount = validOrders.length; @@ -106,7 +104,7 @@ export async function getDashboardStats(): Promise { ); const activeProducts = productsRes.rows.length; - // Fetch weekly orders for chart (last 7 days) + // Fetch weekly orders for chart (last 7 days). New schema uses `placed_at`. const weeklyOrders: number[] = []; for (let i = 6; i >= 0; i--) { const dayStart = new Date(startOfDay); @@ -116,48 +114,60 @@ export async function getDashboardStats(): Promise { const dayRes = brandId ? await pool.query<{ id: string }>( `SELECT id FROM orders - WHERE created_at >= $1 - AND created_at < $2 + WHERE placed_at >= $1 + AND placed_at < $2 AND brand_id = $3 LIMIT 1`, [dayStart.toISOString(), dayEnd.toISOString(), brandId], ) : await pool.query<{ id: string }>( `SELECT id FROM orders - WHERE created_at >= $1 - AND created_at < $2 + WHERE placed_at >= $1 + AND placed_at < $2 LIMIT 1`, [dayStart.toISOString(), dayEnd.toISOString()], ); weeklyOrders.push(dayRes.rows.length > 0 ? 1 : 0); } - // Fetch recent orders (last 10) + // Fetch recent orders (last 10). New schema: `total_cents`/`placed_at` + // on `orders`; customer name comes from a `customers` join (no + // `customer_name` column on `orders`). const recentRes = brandId ? await pool.query<{ id: string; customer_name: string; - subtotal: number; + total_cents: number; status: string; - created_at: string; + placed_at: string; }>( - `SELECT id, customer_name, subtotal, status, created_at - FROM orders - WHERE brand_id = $1 - ORDER BY created_at DESC + `SELECT o.id::text AS id, + TRIM(COALESCE(c.first_name, '') || ' ' || COALESCE(c.last_name, '')) AS customer_name, + o.total_cents, + o.status, + o.placed_at::text AS placed_at + FROM orders o + LEFT JOIN customers c ON c.id = o.customer_id + WHERE o.brand_id = $1 + ORDER BY o.placed_at DESC LIMIT 10`, [brandId], ) : await pool.query<{ id: string; customer_name: string; - subtotal: number; + total_cents: number; status: string; - created_at: string; + placed_at: string; }>( - `SELECT id, customer_name, subtotal, status, created_at - FROM orders - ORDER BY created_at DESC + `SELECT o.id::text AS id, + TRIM(COALESCE(c.first_name, '') || ' ' || COALESCE(c.last_name, '')) AS customer_name, + o.total_cents, + o.status, + o.placed_at::text AS placed_at + FROM orders o + LEFT JOIN customers c ON c.id = o.customer_id + ORDER BY o.placed_at DESC LIMIT 10`, ); @@ -166,9 +176,9 @@ export async function getDashboardStats(): Promise { .map((o) => ({ id: o.id || "", customer_name: o.customer_name || "Guest", - total: o.subtotal || 0, + total: (o.total_cents || 0) / 100, status: o.status || "unknown", - created_at: formatTimeAgo(o.created_at), + created_at: formatTimeAgo(o.placed_at), })); return { diff --git a/src/actions/shipping.ts b/src/actions/shipping.ts index a6ce67d..323f5e0 100644 --- a/src/actions/shipping.ts +++ b/src/actions/shipping.ts @@ -73,9 +73,9 @@ export async function getShippingOrders(): Promise { }>( `SELECT o.id::text AS id, - c.name AS customer_name, - c.email AS customer_email, - c.phone AS customer_phone, + TRIM(COALESCE(c.first_name, '') || ' ' || COALESCE(c.last_name, '')) AS customer_name, + c.primary_email AS customer_email, + c.primary_phone AS customer_phone, o.status, o.total_cents::float / 100.0 AS subtotal, o.placed_at::text AS created_at,