Enhanced WSDC registration flow with auto-lookup and account validation: Backend changes: - Add accountExists flag to WSDC lookup endpoint - Check database for existing users with WSDC ID - Fix Prisma binary target for Alpine Linux Docker containers Frontend changes: - Auto-lookup WSDC data after entering 4+ digits (500ms debounce) - Show live preview dropdown with dancer information - Display warning if account with WSDC ID already exists - Block registration and suggest login for existing accounts - Improve UX with real-time validation feedback - Add CheckCircle, XCircle, AlertCircle icons for visual feedback This prevents duplicate WSDC ID registrations and provides immediate feedback to users, improving the registration experience. Tested with: - ID 26111 (Vince Yap) - new account allowed - ID 26997 (Radoslaw) - existing account blocked
84 lines
2.2 KiB
JavaScript
84 lines
2.2 KiB
JavaScript
/**
|
|
* WSDC API Controller
|
|
* Provides proxy endpoint for World Swing Dance Council (WSDC) dancer lookup
|
|
*/
|
|
|
|
const { prisma } = require('../utils/db');
|
|
const WSDC_API_BASE = 'https://points.worldsdc.com/lookup2020/find';
|
|
|
|
/**
|
|
* Lookup dancer by WSDC ID
|
|
* GET /api/wsdc/lookup?id=26997
|
|
*/
|
|
exports.lookupDancer = async (req, res) => {
|
|
try {
|
|
const { id } = req.query;
|
|
|
|
// Validate WSDC ID
|
|
if (!id) {
|
|
return res.status(400).json({
|
|
error: 'Bad Request',
|
|
message: 'WSDC ID is required'
|
|
});
|
|
}
|
|
|
|
// Validate WSDC ID format (numeric, max 10 digits)
|
|
if (!/^\d{1,10}$/.test(id)) {
|
|
return res.status(400).json({
|
|
error: 'Bad Request',
|
|
message: 'Invalid WSDC ID format. Must be numeric.'
|
|
});
|
|
}
|
|
|
|
// Fetch from WSDC API
|
|
const url = `${WSDC_API_BASE}?q=${id}`;
|
|
const response = await fetch(url);
|
|
|
|
if (!response.ok) {
|
|
console.error(`WSDC API error: ${response.status} ${response.statusText}`);
|
|
return res.status(502).json({
|
|
error: 'Bad Gateway',
|
|
message: 'Failed to fetch data from WSDC API'
|
|
});
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
// Check if dancer was found
|
|
if (!data || !data.dancer_wsdcid) {
|
|
return res.status(404).json({
|
|
error: 'Not Found',
|
|
message: 'Dancer with this WSDC ID not found'
|
|
});
|
|
}
|
|
|
|
// Extract relevant fields
|
|
const dancerData = {
|
|
wsdcId: data.dancer_wsdcid,
|
|
firstName: data.dancer_first || '',
|
|
lastName: data.dancer_last || '',
|
|
// Optional: include competitive level info if needed
|
|
recentYear: data.recent_year,
|
|
dominateRole: data.dominate_data?.short_dominate_role || null
|
|
};
|
|
|
|
// Check if user with this WSDC ID already exists in our database
|
|
const existingUser = await prisma.user.findUnique({
|
|
where: { wsdcId: String(data.dancer_wsdcid) }
|
|
});
|
|
|
|
return res.status(200).json({
|
|
success: true,
|
|
dancer: dancerData,
|
|
accountExists: !!existingUser
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Error in lookupDancer:', error);
|
|
return res.status(500).json({
|
|
error: 'Internal Server Error',
|
|
message: 'An error occurred while looking up dancer'
|
|
});
|
|
}
|
|
};
|