Skip to content
Merged

fixes #210

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 5 additions & 12 deletions apps/next-frontend/app/api/inscribirse/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@repo/db';
import { Resend } from 'resend';
import { generateQRCode, createQRData, getQRCodeURL } from '@/lib/qr-utils';
import { generateQRCode, getQRCodeURL } from '@/lib/qr-utils';

const resend = new Resend(process.env.RESEND_API_KEY);

Expand Down Expand Up @@ -108,15 +108,8 @@ async function createSignup({
},
});

// Generar código QR
// Generar código QR simple (mismo formato que los QRs de cortesía)
const codigoQR = generateQRCode();
const datosQR = createQRData({
inscripcionid: inscripcion.inscripcionid,
eventoid: eventId,
codigo: codigoQR,
nombre,
correo,
});

// Crear registro de código QR
let codigoRegistro;
Expand All @@ -126,7 +119,7 @@ async function createSignup({
inscripcionid: inscripcion.inscripcionid,
eventoid: eventId,
codigo: codigoQR,
datos_qr: datosQR,
datos_qr: codigoQR,
},
});
} catch (qrError) {
Expand All @@ -144,8 +137,8 @@ async function createSignup({
);
}

// Generar URL del QR
const qrImageUrl = getQRCodeURL(datosQR);
// Generar URL del QR (contenido simple)
const qrImageUrl = getQRCodeURL(codigoQR);

// Enviar email con QR
try {
Expand Down
43 changes: 38 additions & 5 deletions apps/next-frontend/components/qr-scanner-free-event.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export function QRScannerFreeEvent({ eventoid }: ScannerFreeEventProps) {
const inputRef = useRef<HTMLInputElement>(null);
const isProcessingScanRef = useRef(false);
const lastScanRef = useRef<{ code: string; timestamp: number } | null>(null);
const lastToastRef = useRef<{ code: string; type: 'success' | 'already' | 'error' } | null>(null);

const {
data: scannerData,
Expand Down Expand Up @@ -207,6 +208,10 @@ export function QRScannerFreeEvent({ eventoid }: ScannerFreeEventProps) {
return;
}

if (lastToastRef.current && lastToastRef.current.code !== normalizedCode) {
lastToastRef.current = null;
}

const now = Date.now();
const lastScan = lastScanRef.current;
if (lastScan && lastScan.code === normalizedCode && now - lastScan.timestamp < 5000) {
Expand All @@ -225,17 +230,44 @@ export function QRScannerFreeEvent({ eventoid }: ScannerFreeEventProps) {
const esYaValidado = data.message?.includes('ya fue validado');

if (esYaValidado) {
toast.info(
`⚠️ ${data.data.inscripcion.nombre} - Ya validado el ${new Date(data.data.fecha_validacion || '').toLocaleString('es-AR')}`,
);
if (
!(
lastToastRef.current &&
lastToastRef.current.code === normalizedCode &&
lastToastRef.current.type === 'already'
)
) {
toast.info(
`⚠️ ${data.data.inscripcion.nombre} - Ya validado el ${new Date(data.data.fecha_validacion || '').toLocaleString('es-AR')}`,
);
lastToastRef.current = { code: normalizedCode, type: 'already' };
}
} else {
toast.success(`✓ ${data.data.inscripcion.nombre} - Entrada validada`);
if (
!(
lastToastRef.current &&
lastToastRef.current.code === normalizedCode &&
lastToastRef.current.type === 'success'
)
) {
toast.success(`✓ ${data.data.inscripcion.nombre} - Entrada validada`);
lastToastRef.current = { code: normalizedCode, type: 'success' };
}
}
setShowCameraModal(false);
}
} catch (error) {
const message = error instanceof Error ? error.message : 'Error al validar código QR';
toast.error(message);
if (
!(
lastToastRef.current &&
lastToastRef.current.code === normalizedCode &&
lastToastRef.current.type === 'error'
)
) {
toast.error(message);
lastToastRef.current = { code: normalizedCode, type: 'error' };
}
lastScanRef.current = { code: normalizedCode, timestamp: Date.now() }; // evitar reintentos instantáneos
} finally {
isProcessingScanRef.current = false;
Expand All @@ -249,6 +281,7 @@ export function QRScannerFreeEvent({ eventoid }: ScannerFreeEventProps) {
e.preventDefault();
if (manualCode.trim()) {
lastScanRef.current = null;
lastToastRef.current = null;
handleScan(manualCode);
}
};
Expand Down
24 changes: 1 addition & 23 deletions apps/next-frontend/lib/qr-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,9 @@ export function generateQRCode(): string {
}

/**
* Crea los datos del QR en formato JSON
*/
export function createQRData(params: {
inscripcionid: string;
eventoid: string;
codigo: string;
nombre: string;
correo: string;
}): string {
return JSON.stringify({
inscripcionid: params.inscripcionid,
eventoid: params.eventoid,
codigo: params.codigo,
nombre: params.nombre,
correo: params.correo,
timestamp: new Date().toISOString(),
});
}

/**
* Genera un data URL de QR usando qr-code.js
* Devuelve la URL para generar el QR con una API externa
* Genera un data URL de QR usando una API pública
*/
export function getQRCodeURL(data: string): string {
const encoded = encodeURIComponent(data);
// Usar QR Code API gratuita
return `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encoded}`;
}
Loading