Admin: stats privacy toggle, clickable event rows, fix payment method display
- Add useStatsPrivacy hook with localStorage persistence for stats visibility - Single event page: desktop privacy button, hide capacity chip when stats hidden - Events list: row/card click navigates to event detail; stopPropagation on actions - Backend GET /tickets: include payment for each ticket (removes N+1) - Bookings page: use list payment data, show — when payment method unknown Made-with: Cursor
This commit is contained in:
@@ -2,7 +2,7 @@ import { Hono } from 'hono';
|
||||
import { zValidator } from '@hono/zod-validator';
|
||||
import { z } from 'zod';
|
||||
import { db, dbGet, dbAll, tickets, events, users, payments, paymentOptions, siteSettings } from '../db/index.js';
|
||||
import { eq, and, or, sql } from 'drizzle-orm';
|
||||
import { eq, and, or, sql, inArray } from 'drizzle-orm';
|
||||
import { requireAuth, getAuthUser } from '../lib/auth.js';
|
||||
import { generateId, generateTicketCode, getNow, calculateAvailableSeats, isEventSoldOut } from '../lib/utils.js';
|
||||
import { createInvoice, isLNbitsConfigured } from '../lib/lnbits.js';
|
||||
@@ -1394,7 +1394,7 @@ ticketsRouter.post('/admin/manual', requireAuth(['admin', 'organizer', 'staff'])
|
||||
}, 201);
|
||||
});
|
||||
|
||||
// Get all tickets (admin)
|
||||
// Get all tickets (admin) - includes payment for each ticket
|
||||
ticketsRouter.get('/', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
const eventId = c.req.query('eventId');
|
||||
const status = c.req.query('status');
|
||||
@@ -1413,9 +1413,25 @@ ticketsRouter.get('/', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
query = query.where(and(...conditions));
|
||||
}
|
||||
|
||||
const result = await dbAll(query);
|
||||
|
||||
return c.json({ tickets: result });
|
||||
const ticketsList = await dbAll(query);
|
||||
const ticketIds = ticketsList.map((t: any) => t.id);
|
||||
|
||||
let paymentByTicketId: Record<string, any> = {};
|
||||
if (ticketIds.length > 0) {
|
||||
const paymentsList = await dbAll(
|
||||
(db as any).select().from(payments).where(inArray((payments as any).ticketId, ticketIds))
|
||||
);
|
||||
for (const p of paymentsList as any[]) {
|
||||
paymentByTicketId[p.ticketId] = p;
|
||||
}
|
||||
}
|
||||
|
||||
const ticketsWithPayment = ticketsList.map((t: any) => ({
|
||||
...t,
|
||||
payment: paymentByTicketId[t.id] || null,
|
||||
}));
|
||||
|
||||
return c.json({ tickets: ticketsWithPayment });
|
||||
});
|
||||
|
||||
export default ticketsRouter;
|
||||
|
||||
Reference in New Issue
Block a user