Security recovery: hold sweep, dashboard updates, and admin fixes.

This commit is contained in:
Michilis
2026-07-01 05:51:38 +00:00
parent 38526f17b5
commit cacc52ec24
45 changed files with 1452 additions and 474 deletions
+5
View File
@@ -46,4 +46,9 @@ export const paymentsApi = {
refund: (id: string) =>
fetchApi<{ message: string }>(`/api/payments/${id}/refund`, { method: 'POST' }),
reactivate: (id: string) =>
fetchApi<{ payment: Payment; message: string }>(`/api/payments/${id}/reactivate`, {
method: 'POST',
}),
};
+4 -2
View File
@@ -37,7 +37,7 @@ export interface Ticket {
attendeePhone?: string;
attendeeRuc?: string;
preferredLanguage?: string;
status: 'pending' | 'confirmed' | 'cancelled' | 'checked_in';
status: 'pending' | 'confirmed' | 'cancelled' | 'checked_in' | 'on_hold';
checkinAt?: string;
checkedInByAdminId?: string;
qrCode: string;
@@ -111,7 +111,7 @@ export interface Payment {
provider: 'bancard' | 'lightning' | 'cash' | 'bank_transfer' | 'tpago';
amount: number;
currency: string;
status: 'pending' | 'pending_approval' | 'paid' | 'refunded' | 'failed';
status: 'pending' | 'pending_approval' | 'paid' | 'refunded' | 'failed' | 'on_hold';
reference?: string;
userMarkedPaidAt?: string;
payerName?: string; // Name of payer if different from attendee
@@ -131,6 +131,7 @@ export interface PaymentWithDetails extends Payment {
attendeeLastName?: string;
attendeeEmail?: string;
attendeePhone?: string;
attendeeRuc?: string;
status: string;
} | null;
event: {
@@ -325,6 +326,7 @@ export interface ExportedPayment {
attendeeFirstName: string;
attendeeLastName?: string;
attendeeEmail?: string;
attendeeRuc?: string;
eventId: string;
eventTitle: string;
eventDate: string;
+27 -3
View File
@@ -1,10 +1,34 @@
import { fetchApi } from './client';
import type { User } from './types';
export interface UsersListParams {
role?: string;
search?: string;
accountStatus?: string;
hasBookings?: 'yes' | 'no';
registeredAfter?: string;
registeredBefore?: string;
eventId?: string;
page?: number;
pageSize?: number;
}
export const usersApi = {
getAll: (role?: string) => {
const query = role ? `?role=${role}` : '';
return fetchApi<{ users: User[] }>(`/api/users${query}`);
getAll: (params?: UsersListParams | string) => {
// Back-compat: allow the old `getAll(role)` call shape.
const p: UsersListParams = typeof params === 'string' ? { role: params } : params || {};
const query = new URLSearchParams();
if (p.role) query.set('role', p.role);
if (p.search) query.set('search', p.search);
if (p.accountStatus) query.set('accountStatus', p.accountStatus);
if (p.hasBookings) query.set('hasBookings', p.hasBookings);
if (p.registeredAfter) query.set('registeredAfter', p.registeredAfter);
if (p.registeredBefore) query.set('registeredBefore', p.registeredBefore);
if (p.eventId) query.set('eventId', p.eventId);
if (p.page) query.set('page', String(p.page));
if (p.pageSize) query.set('pageSize', String(p.pageSize));
const qs = query.toString();
return fetchApi<{ users: User[]; total: number; page: number; pageSize: number }>(`/api/users${qs ? `?${qs}` : ''}`);
},
getById: (id: string) => fetchApi<{ user: User }>(`/api/users/${id}`),