feat: Enhance FaceAI functionality and improve login process
All checks were successful
Publish FaceAI Container / publish (push) Successful in 4m43s

- Added a retry mechanism for page navigation in `live-site-test-utils.js` to handle transient errors during login.
- Introduced a new function `performLiveLoginRequest` to handle login requests via API, improving the login flow.
- Updated the login process to utilize the new API request method, ensuring a more robust authentication.
- Implemented new utility functions in `rus-ecom-240621.js` for managing FaceAI state and filtering.
- Created `faceai_photo_lookup.jsp` to handle photo lookups, returning JSON responses for better integration with the frontend.
- Updated `faceai_return.php` to redirect users with appropriate parameters after FaceAI processing.
- Modified `fotoCR.jsp` and `fotoCR-en.jsp` to include FaceAI photo IDs in the image elements for better tracking.
- Enhanced the UI to display the number of matched photos dynamically based on FaceAI results.
This commit is contained in:
MaddoScientisto 2026-04-19 14:18:00 +02:00
commit bba8026b7c
17 changed files with 1077 additions and 95 deletions

View file

@ -50,6 +50,8 @@ const copy = {
raceDataUnavailable: 'I dati FaceAI non sono disponibili per questa gara.',
invalidRaceData: 'I dati della gara ricevuti non sono validi. Torna alla pagina gara e riapri Face ID dalla gara corretta.',
searchCreateError: 'Impossibile avviare la ricerca.',
activeSearchExists: 'C\'e gia una ricerca in corso per questo utente. Attendi il completamento oppure ricarica la pagina.',
rateLimited: 'Hai avviato troppe ricerche in poco tempo. Attendi un momento e riprova.',
faceAiAlt: 'FaceAI',
dropzoneDisabled: 'Il caricamento non è disponibile per questa gara.'
},
@ -101,11 +103,23 @@ const copy = {
raceDataUnavailable: 'FaceAI data is not available for this race.',
invalidRaceData: 'The race data received for this session is invalid. Go back to the race page and reopen Face ID from the correct race.',
searchCreateError: 'Unable to start the search.',
activeSearchExists: 'There is already a search running for this user. Wait for it to finish or reload the page.',
rateLimited: 'Too many searches were started in a short time. Please wait a moment and try again.',
faceAiAlt: 'FaceAI',
dropzoneDisabled: 'Upload is not available for this race.'
}
};
const knownServerCodes = {
PROCESSOR_UNAVAILABLE: 'processorUnavailable',
ACTIVE_SEARCH_EXISTS: 'activeSearchExists',
RATE_LIMITED: 'rateLimited',
MISSING_SELFIE: 'chooseSelfie',
RACE_PKL_UNAVAILABLE: 'raceDataUnavailable',
RACE_DIRECTORY_NOT_FOUND: 'invalidRaceData',
MISSING_RACE_STORAGE: 'invalidRaceData'
};
const knownServerMessages = {
'No training dataset available for this race.': 'raceDataUnavailable',
'FaceAI data is not available for this race.': 'raceDataUnavailable',
@ -115,7 +129,9 @@ const knownServerMessages = {
'FaceAI processor is temporarily unavailable. Please try again shortly.': 'processorUnavailable',
'Unable to build return URL.': 'redirectError',
'Unable to create the search.': 'searchCreateError',
'Choose a selfie before starting the search.': 'chooseSelfie'
'Choose a selfie before starting the search.': 'chooseSelfie',
'There is already an operation being processed.': 'activeSearchExists',
'Too many search attempts. Please try again later.': 'rateLimited'
};
const simulatorUrl = legacyUrl('/faceai_simulator.php?raceId=101&lang=it');
@ -178,6 +194,15 @@ export function useFaceAiHome() {
return t(fallbackKey);
}
function localizeServerError(payload, fallbackKey) {
const mappedCodeKey = payload?.code ? knownServerCodes[payload.code] : null;
if (mappedCodeKey) {
return t(mappedCodeKey);
}
return localizeServerMessage(payload?.error, fallbackKey);
}
function getAvailabilityUserMessage(availability, fallbackKey = 'unavailableDefault') {
if (isInvalidRaceAvailability(availability)) {
return t('invalidRaceData');
@ -424,7 +449,7 @@ export function useFaceAiHome() {
const response = await fetch(`/api/searches/${searchId}`, { credentials: 'include' });
if (!response.ok) {
const payload = await response.json().catch(() => ({}));
errorMessage.value = localizeServerMessage(payload.error, 'pollError');
errorMessage.value = localizeServerError(payload, 'pollError');
isSubmitting.value = false;
logFaceAiDebug('Search polling failed', { searchId, status: response.status, payload });
return;
@ -451,7 +476,7 @@ export function useFaceAiHome() {
const redirectResponse = await fetch(`/api/searches/${searchId}/redirect`, { credentials: 'include' });
const payload = await redirectResponse.json();
if (!redirectResponse.ok) {
errorMessage.value = localizeServerMessage(payload.error, 'redirectError');
errorMessage.value = localizeServerError(payload, 'redirectError');
logFaceAiDebug('Redirect build failed', { searchId, payload });
return;
}
@ -498,7 +523,7 @@ export function useFaceAiHome() {
const payload = await response.json();
if (!response.ok) {
errorMessage.value = localizeServerMessage(payload.error, 'searchCreateError');
errorMessage.value = localizeServerError(payload, 'searchCreateError');
isSubmitting.value = false;
logFaceAiDebug('Search creation failed', { status: response.status, payload });
return;