Skip to content

Commit

Permalink
Merge pull request #22 from gunet/ehic-pickup-code
Browse files Browse the repository at this point in the history
replaced all credential info attributes with new. also handled a case…
  • Loading branch information
kkmanos authored Sep 10, 2024
2 parents 21a75fd + 1a2f055 commit 0b17f60
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 63 deletions.
13 changes: 8 additions & 5 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Import Libraries
import React, { useEffect, Suspense } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import React, { useEffect, Suspense, useState } from 'react';
import { Routes, Route, useLocation } from 'react-router-dom';
import Spinner from './components/Spinner'; // Make sure this Spinner component exists and renders the spinner you want
// Import i18next and set up translations
import { I18nextProvider } from 'react-i18next';
Expand Down Expand Up @@ -31,7 +31,8 @@ const VerificationResult = React.lazy(() => import('./pages/VerificationResult/V

function App() {

const url = window.location.href;
const location = useLocation();
const [url, setUrl] = useState(window.location.href);
const {
showSelectCredentialsPopup,
setShowSelectCredentialsPopup,
Expand All @@ -46,6 +47,10 @@ function App() {
typeMessagePopup,
} = useCheckURL(url);

useEffect(() => {
setUrl(window.location.href);
}, [location])

useEffect(() => {
if (navigator?.serviceWorker) {
navigator.serviceWorker.addEventListener('message', handleMessage);
Expand All @@ -70,7 +75,6 @@ function App() {
<I18nextProvider i18n={i18n}>
<CredentialsProvider>
<Snowfalling />
<Router>
<Suspense fallback={<Spinner />}>
<HandlerNotification />
<Routes>
Expand All @@ -96,7 +100,6 @@ function App() {
<MessagePopup type={typeMessagePopup} message={textMessagePopup} onClose={() => setMessagePopup(false)} />
}
</Suspense>
</Router>
</CredentialsProvider>
</I18nextProvider>
);
Expand Down
41 changes: 19 additions & 22 deletions src/components/Credentials/CredentialInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,33 +77,30 @@ const CredentialInfo = ({ credential, mainClassName = "text-xs sm:text-sm md:tex
<tbody className="divide-y-4 divide-transparent">
{parsedCredential && (
<>
{renderRow('expdate', 'Valid From', parsedCredential.credentialSubject?.validityPeriod?.startingDate && formatDate(parsedCredential.credentialSubject?.validityPeriod?.startingDate))}
{renderRow('expdate', 'Expiration', parsedCredential.credentialSubject?.validityPeriod?.endingDate && formatDate(parsedCredential.credentialSubject?.validityPeriod?.endingDate))}

{renderRow('expdate', 'Valid From', parsedCredential.validFrom && formatDate(parsedCredential.validFrom))}
{renderRow('expdate', 'Expiration', parsedCredential.expirationDate && formatDate(parsedCredential.expirationDate))}

{renderRow('expdate', 'Valid From', parsedCredential.credentialSubject?.decisionOnApplicableLegislation?.validityPeriod?.startingDate && formatDate(parsedCredential.credentialSubject?.decisionOnApplicableLegislation?.validityPeriod?.startingDate))}
{renderRow('expdate', 'Expiration', parsedCredential.credentialSubject?.decisionOnApplicableLegislation?.validityPeriod?.endingDate && formatDate(parsedCredential.credentialSubject?.decisionOnApplicableLegislation?.validityPeriod?.endingDate))}


{renderRow('familyName', 'Family Name', parsedCredential.credentialSubject.familyName)}
{renderRow('firstName', 'First Name', parsedCredential.credentialSubject.firstName)}
{renderRow('id', 'Personal ID', parsedCredential.type.includes('urn:credential:vid') && parsedCredential.credentialSubject.personalIdentifier)}
{renderRow('familyName', 'Family Name', parsedCredential.credentialSubject.family_name)}
{renderRow('firstName', 'Given Name', parsedCredential.credentialSubject.given_name)}
{renderRow('id', 'Personal ID', parsedCredential.type.includes('urn:credential:vid') && parsedCredential.credentialSubject.personal_identifier)}
{renderRow('dateOfBirth', 'Birthday', parsedCredential.credentialSubject.dateOfBirth)}
{renderRow('dateOfBirth', 'Birthday', parsedCredential.credentialSubject.birthdate)}
{renderRow('dateOfBirth', 'Birthday', parsedCredential.credentialSubject?.birth_date && new Date(parsedCredential.credentialSubject?.birth_date).toDateString())}

{renderRow('id', 'SSN', parsedCredential.credentialSubject.social_security_pin)}
{renderRow('id', 'Document ID', parsedCredential.credentialSubject?.pda1_document_id ?? parsedCredential.credentialSubject?.ehic_card_identification_number ?? undefined )}

{renderRow('id', 'SSN', parsedCredential.credentialSubject.socialSecurityIdentification?.ssn)}
{renderRow('id', 'Document ID', parsedCredential.credentialSubject.documentId)}
{renderRow('id', 'ID Competent Institution', parsedCredential.credentialSubject.competentInstitution?.competentInstitutionId)}
{renderRow('institution', 'Name Competent Institution', parsedCredential.credentialSubject.competentInstitution?.competentInstitutionName)}
{renderRow('country', 'Country Competent Institution', parsedCredential.credentialSubject.competentInstitution?.competentInstitutionCountryCode)}
{renderRow('id', 'ID Competent Institution', parsedCredential.credentialSubject.ehic_institution_id)}
{renderRow('institution', 'Name Competent Institution', parsedCredential.credentialSubject.ehic_institution_name)}
{renderRow('country', 'Country Competent Institution', parsedCredential.credentialSubject.ehic_institution_country_code)}

{renderRow('id', 'MS Legislation', parsedCredential.credentialSubject.decisionOnApplicableLegislation?.decisionOnMSWhoseLegislationApplies.memberStateWhoseLegislationIsToBeApplied)}
{renderRow('familyName', 'Employer Name', parsedCredential.credentialSubject.employer?.name)}
{renderRow('country', 'Employer Country', parsedCredential.credentialSubject.employer?.countryCode)}
{renderRow('place', 'Place of Work', parsedCredential.credentialSubject.placeOfWork?.companyName)}
{renderRow('place', 'Town', parsedCredential.credentialSubject.placeOfWork?.town)}
{renderRow('place', 'Postal Code', parsedCredential.credentialSubject.placeOfWork?.postalCode)}
{renderRow('country', 'Country', parsedCredential.credentialSubject.placeOfWork?.countryCode)}
{renderRow('id', 'MS Legislation', parsedCredential.pda1_member_state)}
{renderRow('familyName', 'Employer Name', parsedCredential.credentialSubject.pda1_name)}
{renderRow('country', 'Employer Country', parsedCredential.credentialSubject.pda1_employer_country_code)}
{renderRow('place', 'Place of Work', parsedCredential.credentialSubject.pda1_pow_company_name)}
{renderRow('place', 'Town', parsedCredential.credentialSubject.pda1_pow_employer_town)}
{renderRow('place', 'Postal Code', parsedCredential.credentialSubject.pda1_pow_employer_postal_code)}
{renderRow('country', 'Country', parsedCredential.credentialSubject.pda1_pow_employer_country_code)}

{renderRow('id', 'Revocation ID', parsedCredential.credentialStatus && parsedCredential?.credentialStatus?.id?.split('#')[1])}
</>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Credentials/StatusRibbon.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const StatusRibbon = ({ credential }) => {
else if (CheckExpired(parsedCredential.expirationDate)) {
setCredentialStatus('expired');
}
});
}).catch(() => null);
}
}, [parsedCredential]);

Expand Down
11 changes: 5 additions & 6 deletions src/components/Popups/SelectCredentials.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useEffect, useMemo, useState, useContext } from 'react';
import Modal from 'react-modal';
import { useNavigate } from 'react-router-dom';
import { FaShare } from 'react-icons/fa';
import { MdOutlineCheckBox, MdOutlineCheckBoxOutlineBlank } from "react-icons/md";
import { FaShare, FaRegCircle, FaCheckCircle } from 'react-icons/fa';
import { useTranslation, Trans } from 'react-i18next';
import { useApi } from '../../api';
import { CredentialImage } from '../Credentials/CredentialImage';
Expand Down Expand Up @@ -225,19 +224,19 @@ function SelectCredentials({ showPopup, setShowPopup, setSelectionMap, conforman
<>
<div key={vcEntity.credentialIdentifier} className="m-3 flex flex-col items-center">
<button
className={`relative rounded-xl w-2/3 overflow-hidden transition-shadow shadow-md hover:shadow-xl cursor-pointer ${selectedCredential === vcEntity.credentialIdentifier ? 'opacity-100' : 'opacity-50'}`}
className={`relative rounded-xl w-2/3 transition-shadow shadow-md hover:shadow-xl cursor-pointer ${selectedCredential === vcEntity.credentialIdentifier ? 'opacity-100' : 'opacity-50'}`}
onClick={() => handleClick(vcEntity.credentialIdentifier)}
aria-label={`${vcEntity.friendlyName}`}
title={t('selectCredentialPopup.credentialSelectTitle', { friendlyName: vcEntity.friendlyName })}
>
<CredentialImage key={vcEntity.credentialIdentifier} credential={vcEntity.credential}
className={"w-full object-cover rounded-xl"}
/>
<div className="absolute bottom-2 right-2" style={{ zIndex: "2000" }}>
<div className="absolute top-[-5px] right-[-5px]" style={{ zIndex: "3000" }}>
{selectedCredential === vcEntity.credentialIdentifier ? (
<MdOutlineCheckBox size={20} className="text-white" />
<FaCheckCircle size={20} className="rounded-full bg-gray-50 dark:bg-white text-primary dark:text-primary-light" />
) : (
<MdOutlineCheckBoxOutlineBlank size={20} className="text-white" />
<FaRegCircle size={20} className="rounded-full bg-gray-50 dark:bg-gray-800 text-primary dark:text-white" />
)}
</div>
</button>
Expand Down
57 changes: 31 additions & 26 deletions src/components/QRCodeScanner/QRCodeScanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const QRScanner = ({ onClose }) => {
const currentCameraType = devices[currentDeviceIndex]?.label.toLowerCase().includes('back') ? 'back' : 'front';
const maxResolution = bestCameraResolutions[currentCameraType];

let idealWidth, idealHeight;
let idealHeight;
if (maxResolution) {
console.log(maxResolution);

Expand All @@ -173,11 +173,9 @@ const QRScanner = ({ onClose }) => {

// Cap the dimension at 1920 if it exceeds this value
if (smallerDimension > 1920) {
idealWidth = 1920;
idealHeight = 1920;
idealHeight = 1080;
} else {
idealWidth = smallerDimension;
idealHeight = smallerDimension;
idealHeight = maxResolution.height;
}
}

Expand All @@ -189,7 +187,7 @@ const QRScanner = ({ onClose }) => {
overlayClassName="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
>
{hasCameraPermission === false ? (
<div className="bg-white dark:bg-gray-700 p-4 rounded-lg shadow-lg w-full lg:w-[33.33%] sm:w-[66.67%] z-10 relative m-4">
<div className="bg-white dark:bg-gray-700 p-4 rounded-lg shadow-lg w-full lg:w-[33.33%] sm:w-[66.67%] z-10 relative m-4 max-h-[80%] overflow-auto">
<div className="flex items-start justify-between border-b rounded-t dark:border-gray-600">
<h2 className="text-lg font-bold mb-2 text-primary dark:text-white">
<BsQrCodeScan size={20} className="inline mr-1 mb-1" />
Expand All @@ -216,7 +214,7 @@ const QRScanner = ({ onClose }) => {
<Spinner />
</div>
) : (
<div className="bg-white dark:bg-gray-700 p-4 rounded-lg shadow-lg w-full lg:w-[33.33%] sm:w-[66.67%] z-10 relative m-4">
<div className="bg-white max-h-[80%] dark:bg-gray-700 p-4 rounded-lg shadow-lg w-full lg:w-[33.33%] sm:w-[66.67%] z-10 relative m-4">
<div className="flex items-start justify-between border-b rounded-t dark:border-gray-600">
<h2 className="text-lg font-bold mb-2 text-primary dark:text-white">
<BsQrCodeScan size={20} className="inline mr-1 mb-1" />
Expand All @@ -237,25 +235,32 @@ const QRScanner = ({ onClose }) => {
<p className="italic pd-2 text-gray-700 dark:text-gray-300">
{t('qrCodeScanner.description')}
</p>
<div className="webcam-container mt-4" style={{ position: 'relative', overflow: 'hidden' }}>
<Webcam
key={devices[currentDeviceIndex]?.deviceId}
audio={false}
ref={webcamRef}
screenshotFormat="image/jpeg"
videoConstraints={{
deviceId: devices[currentDeviceIndex]?.deviceId,
height: { ideal: idealHeight },
width: { ideal: idealWidth }
}}
style={{ transform: `scale(${zoomLevel})` }}
onUserMedia={onUserMedia}
/>
{qrDetected && (
<div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }}>
<FaCheckCircle size={100} color="green" />
</div>
)}
<div className="webcam-container mt-4 relative flex items-center justify-center">
<div className="relative w-full max-h-[50vh] flex justify-center items-center overflow-hidden">
<Webcam
key={devices[currentDeviceIndex]?.deviceId}
audio={false}
ref={webcamRef}
screenshotFormat="image/jpeg"
videoConstraints={{
deviceId: devices[currentDeviceIndex]?.deviceId,
height: { ideal: idealHeight, max: maxResolution.height }
}}
style={{
transform: `scale(${zoomLevel})`,
width: "100%",
height: "100%",
objectFit: "contain",
maxHeight: '100%',
}}
onUserMedia={onUserMedia}
/>
{qrDetected && (
<div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }}>
<FaCheckCircle size={100} color="green" />
</div>
)}
</div>
</div>
<div className='flex justify-between align-center'>
<div className="flex items-center my-4 pr-4 w-full">
Expand Down
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as offlineSW from './offlineRegistrationSW';
import * as firebaseSW from './firebase';
import Modal from 'react-modal';
import './index.css';
import { BrowserRouter } from "react-router-dom";

// ConsoleBehavior();

Expand All @@ -26,7 +27,7 @@ const RootComponent = () => {
initDB();
}, []);

return <App />;
return <BrowserRouter><App /></BrowserRouter>;
};

const root = createRoot(document.getElementById('root'));
Expand Down
14 changes: 12 additions & 2 deletions src/pages/Login/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,15 @@ const WebauthnSignupLogin = ({
setIsSubmitting,
isLoginCache,
setIsLoginCache,
error,
setError,
}) => {
const { isOnline } = useContext(OnlineStatusContext);
const { keystore } = useContext(SessionContext);

const api = useApi(isOnline);
const [inProgress, setInProgress] = useState(false);
const [name, setName] = useState("");
const [error, setError] = useState('');
const [needPrfRetry, setNeedPrfRetry] = useState(false);
const [resolvePrfRetryPrompt, setResolvePrfRetryPrompt] = useState(null);
const [prfRetryAccepted, setPrfRetryAccepted] = useState(false);
Expand Down Expand Up @@ -487,6 +488,7 @@ const Login = () => {
confirmPassword: '',
});
const [error, setError] = useState('');
const [webauthnError, setWebauthnError] = useState('');
const [isLogin, setIsLogin] = useState(true);
const [isSubmitting, setIsSubmitting] = useState(false);
const [isContentVisible, setIsContentVisible] = useState(false);
Expand Down Expand Up @@ -580,6 +582,12 @@ const Login = () => {
};
}

const useOtherAccount = () => {
setIsLoginCache(false);
setError('');
setWebauthnError('');
}

const getPasswordStrength = (password) => {
const lengthScore = password.length >= 8 ? 25 : 0;
const capitalScore = /[A-Z]/.test(password) ? 25 : 0;
Expand Down Expand Up @@ -747,6 +755,8 @@ const Login = () => {
setIsSubmitting={setIsSubmitting}
isLoginCache={isLoginCache}
setIsLoginCache={setIsLoginCache}
error={webauthnError}
setError={setWebauthnError}
/>

{!isLoginCache ? (
Expand All @@ -765,7 +775,7 @@ const Login = () => {
<p className="text-sm font-light text-gray-500 dark:text-gray-200 cursor-pointer">
<a
className="font-medium text-primary hover:underline dark:text-primary-light"
onClick={() => setIsLoginCache(false)}
onClick={useOtherAccount}
>
{t('loginSignup.useOtherAccount')}
</a>
Expand Down

0 comments on commit 0b17f60

Please sign in to comment.