Skip to content
Merged
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
66 changes: 35 additions & 31 deletions client/src/pages/ApplyReferral/ApplyReferral.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';

import { Html5Qrcode } from 'html5-qrcode';
import { useNavigate } from 'react-router-dom';
Expand All @@ -19,6 +19,39 @@ export default function ApplyReferral() {
const scannerRef = useRef<Html5Qrcode | null>(null);
const readerRef = useRef<HTMLDivElement | null>(null);

// Function to handle successful QR code scan
const onScanSuccess = useCallback((decodedText: string) => {
if (scannerRef.current) {
scannerRef.current
.stop()
.then(() => {
scannerRef.current?.clear();
console.log('Scanner stopped after successful scan.');
})
.catch(error =>
console.error('Failed to stop scanner:', error)
);
}
setIsScanning(false);

// Extract referral code from scanned text
const code = decodedText.trim();

if (!code) {
alert('Invalid QR Code. Could not extract referral code.');
return;
}

// Clear any existing survey data and navigate to survey with the referral code
clearSurvey();
navigate(`/survey?ref=${code}`);
}, []);

// Function to handle QR code scan failure
const onScanFailure = useCallback((error: string) => {
console.warn(`QR Code scan error: ${error}`);
}, []);

// Effect to initialize the QR scanner
// This effect runs when the component mounts and when isScanning changes
// Defaults to back camera unless there is no back camera
Expand Down Expand Up @@ -67,36 +100,7 @@ export default function ApplyReferral() {
}
}
};
}, [isScanning]);

// Function to handle successful QR code scan
const onScanSuccess = (decodedText: string) => {
if (scannerRef.current) {
scannerRef.current
.stop()
.then(() => {
scannerRef.current?.clear();
console.log('Scanner stopped after successful scan.');
})
.catch(error =>
console.error('Failed to stop scanner:', error)
);
}
setIsScanning(false);

// Check if the scanned text is a valid URL
try {
const url = new URL(decodedText);
window.location.href = url.href; // Redirect user to the scanned URL
} catch (error) {
alert('Invalid QR Code. Please scan a valid link.');
}
};

// Function to handle QR code scan failure
const onScanFailure = (error: string) => {
console.warn(`QR Code scan error: ${error}`);
};
}, [isScanning, onScanSuccess, onScanFailure]);

// Function to handle referral code submission
const handleStartSurvey = async () => {
Expand Down
25 changes: 7 additions & 18 deletions scripts/generateSeeds.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env tsx
/**
* NOTE: Make sure to set CLIENT_URL in .env to the correct deployment URL
* Script to generate N seeds for a given location
* Usage: npm run generate-seeds -- <hubName|objectId> <count>
* Example: npm run generate-seeds -- "Main Hub" 10
Expand Down Expand Up @@ -49,9 +48,9 @@ function generateTimestampFilename(locationName: string, outputDir: string): str
return path.join(outputDir, filename);
}

async function generateQRCodeBuffer(surveyCode: string, baseUrl: string, qrSize: number): Promise<Buffer> {
const qrUrl = `${baseUrl}/survey?ref=${surveyCode}`;
const qrDataUrl = await QRCode.toDataURL(qrUrl, {
async function generateQRCodeBuffer(surveyCode: string, qrSize: number): Promise<Buffer> {
// Encode only the referral code (no URL) so QR codes work across any deployment
const qrDataUrl = await QRCode.toDataURL(surveyCode, {
width: qrSize,
margin: 1,
errorCorrectionLevel: 'M',
Expand All @@ -63,8 +62,7 @@ async function addQRCodePage(
doc: any,
surveyCode: string,
locationName: string,
baseUrl: string,
isFirstPage: boolean,
isFirstPage: boolean
): Promise<void> {
if (!isFirstPage) {
doc.addPage();
Expand Down Expand Up @@ -136,8 +134,8 @@ async function addQRCodePage(
// QR Code and Referral Code
const qrSize = 100;
const qrX = (pageWidth - qrSize) / 2;

const qrBuffer = await generateQRCodeBuffer(surveyCode, baseUrl, qrSize);
const qrBuffer = await generateQRCodeBuffer(surveyCode, qrSize);
doc.image(qrBuffer, qrX, currentY, {
width: qrSize,
height: qrSize,
Expand Down Expand Up @@ -219,7 +217,7 @@ async function generatePDF(seeds: any[], locationName: string): Promise<void> {

// Generate one page per seed
for (let i = 0; i < seeds.length; i++) {
await addQRCodePage(doc, seeds[i].surveyCode, locationName, baseUrl, i === 0);
await addQRCodePage(doc, seeds[i].surveyCode, locationName, i === 0);
}

doc.end();
Expand Down Expand Up @@ -331,15 +329,6 @@ async function generateSeeds(locationIdentifier: string, count: number): Promise
}
}

// Require CLIENT_URL to be set
const baseUrl = process.env.CLIENT_URL;
if (!baseUrl) {
console.error('\nβœ— Error: CLIENT_URL environment variable is not set');
console.error(' Please set CLIENT_URL in your .env file before running this script.');
console.error(' Example: CLIENT_URL=https://your-domain.com\n');
process.exit(1);
}

// Parse command line arguments
const args = process.argv.slice(2);

Expand Down
Loading