Skip to content

Commit

Permalink
Merge pull request #210 from wwWallet/feat/onselect-display-details
Browse files Browse the repository at this point in the history
Enhance Credential Display in Presentation Selection Popup
  • Loading branch information
gkatrakazas authored Mar 27, 2024
2 parents f837907 + c3af656 commit c10e145
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 55 deletions.
4 changes: 2 additions & 2 deletions src/components/Credentials/CredentialInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const renderRow = (fieldName, fieldValue) => {
return null;
};

const CredentialInfo = ({ credential }) => {
const CredentialInfo = ({ credential, mainClassName="pt-5 pr-2 w-full" }) => {

const [parsedCredential, setParsedCredential] = useState(null);

Expand All @@ -56,7 +56,7 @@ const CredentialInfo = ({ credential }) => {
}, []);

return (
<div className=" pt-5 pr-2 w-full">
<div className={mainClassName}>
<table className="lg:w-4/5">
<tbody className="divide-y-4 divide-transparent">
{parsedCredential && (
Expand Down
101 changes: 53 additions & 48 deletions src/components/Popups/SelectCredentials.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { FaShare } from 'react-icons/fa';
import { useTranslation } from 'react-i18next';
import { useApi } from '../../api';
import { CredentialImage } from '../Credentials/CredentialImage';

import CredentialInfo from '../Credentials/CredentialInfo';

function SelectCredentials({ showPopup, setShowPopup, setSelectionMap, conformantCredentialsMap, verifierDomainName }) {
const api = useApi();
const [images, setImages] = useState([]);
const [vcEntities, setVcEntities] = useState([]);
const navigate = useNavigate();
const { t } = useTranslation();

Expand All @@ -17,8 +17,7 @@ function SelectCredentials({ showPopup, setShowPopup, setSelectionMap, conforman
const [currentSelectionMap, setCurrentSelectionMap] = useState({});
const [requestedFields, setRequestedFields] = useState([]);
const [showRequestedFields, setShowRequestedFields] = useState(false);
const [renderContent, setRenderContent] = useState(showRequestedFields);
const [applyTransition, setApplyTransition] = useState(false);
const [credentialDisplay, setCredentialDisplay] = useState({});

useEffect(() => {
const getData = async () => {
Expand All @@ -30,13 +29,13 @@ function SelectCredentials({ showPopup, setShowPopup, setSelectionMap, conforman

try {
const response = await api.get('/storage/vc');
const simplifiedCredentials = response.data.vc_list
const vcEntities = response.data.vc_list
.filter(vcEntity =>
conformantCredentialsMap[keys[currentIndex]].credentials.includes(vcEntity.credentialIdentifier)
);

setRequestedFields(conformantCredentialsMap[keys[currentIndex]].requestedFields);
setImages(simplifiedCredentials);
setVcEntities(vcEntities);
} catch (error) {
console.error('Failed to fetch data', error);
}
Expand All @@ -45,17 +44,6 @@ function SelectCredentials({ showPopup, setShowPopup, setSelectionMap, conforman
getData();
}, [api, currentIndex]);

useEffect(() => {
if (showRequestedFields) {
setRenderContent(true);
} else if (applyTransition) {
setTimeout(() => setRenderContent(false), 500);
} else {
setRenderContent(false);
}
}, [showRequestedFields, applyTransition]);


const goToNextSelection = () => {
setCurrentIndex((i) => i + 1);
}
Expand All @@ -66,12 +54,9 @@ function SelectCredentials({ showPopup, setShowPopup, setSelectionMap, conforman
currentMap[descriptorId] = credentialIdentifier;
return currentMap;
});
setApplyTransition(false);
setShowRequestedFields(false);
goToNextSelection();
};


const handleCancel = () => {
setShowPopup(false);
navigate('/'); // Navigate to home page or any other route
Expand All @@ -81,10 +66,21 @@ function SelectCredentials({ showPopup, setShowPopup, setSelectionMap, conforman
return null;
};

const toggleRequestedFields = () => {
setShowRequestedFields(!showRequestedFields);
};

const toggleCredentialDisplay = (identifier) => {
setCredentialDisplay(prev => ({
...prev,
[identifier]: !prev[identifier]
}));
};

return (
<div className="fixed inset-0 flex items-center justify-center z-50">
<div className="absolute inset-0 bg-black opacity-50"></div>
<div className="bg-white p-4 rounded-lg shadow-lg w-full lg:max-w-[33.33%] sm:max-w-[66.67%] max-h-[90vh] z-10 relative m-4 overflow-y-auto">
<div className="bg-white p-4 rounded-lg shadow-md w-full lg:max-w-[33.33%] sm:max-w-[66.67%] max-h-[90vh] z-10 relative m-4 overflow-y-auto">
<h2 className="text-lg font-bold mb-2 text-custom-blue">
<FaShare size={20} className="inline mr-1 mb-1" />
{t('selectCredentialPopup.title')}
Expand All @@ -94,47 +90,56 @@ function SelectCredentials({ showPopup, setShowPopup, setSelectionMap, conforman
{t('selectCredentialPopup.description')}
</p>
{requestedFields && (


<div className="lg:p-0 p-2 mt-4 w-full">
<div className="my-3 w-full">
<div className="mb-2 flex items-center">
<button
onClick={() => { setApplyTransition(true); setShowRequestedFields(!showRequestedFields) }}
className="px-2 py-2 text-white cursor-pointer flex items-center bg-custom-blue hover:bg-custom-blue-hover font-medium rounded-lg text-sm px-4 py-2 text-center dark:bg-custom-blue-hover dark:hover:bg-custom-blue-hover"
onClick={toggleRequestedFields}
className="px-2 py-2 text-white cursor-pointer flex items-center bg-custom-blue hover:bg-custom-blue-hover font-medium rounded-lg text-xs px-4 py-2 text-center dark:bg-custom-blue-hover dark:hover:bg-custom-blue-hover"
>
{showRequestedFields ? `${t('selectCredentialPopup.requestedFieldsHide')}` : `${t('selectCredentialPopup.requestedFieldsShow')}`}
</button>
</div>

<hr className="border-t border-gray-300 py-1" />

<div
className={`overflow-hidden transition-height ${showRequestedFields ? 'max-h-96' : 'max-h-0'}`}
style={{ transition: 'max-height 0.5s ease-in-out' }}
<hr className="border-t border-gray-300" />

>
{renderContent && (
<>
<div className={`transition-all ease-in-out duration-1000 p-2 overflow-hidden rounded-xl shadow-md bg-gray-50 ${showRequestedFields ? 'max-h-[500px] opacity-100' : 'max-h-0 opacity-0 m-0 p-0'}`}>
<>
{verifierDomainName && (
<p className='mb-2 text-sm italic text-gray-700'>{t('selectCredentialPopup.requestedFieldsinfo')} {verifierDomainName}</p>
<textarea
readOnly
value={requestedFields.join('\n')}
className="w-full border rounded p-2 rounded-xl"
rows={Math.min(3, Math.max(1, requestedFields.length))}
></textarea>
</>
)}
)}
<textarea
readOnly
value={requestedFields.join('\n')}
className="p-2 border rounded-lg text-sm"
style={{ width: '-webkit-fill-available' }}
rows={Math.min(3, Math.max(1, requestedFields.length))}
></textarea>
</>
</div>
</div>
)}

<div className='flex flex-wrap justify-center flex overflow-y-auto max-h-[40vh]'>
{images.map(image => (
<div className="m-3 flex justify-center">
<div className="relative rounded-xl w-2/3 overflow-hidden transition-shadow shadow-md hover:shadow-lg cursor-pointer">
<CredentialImage key={image.credentialIdentifier} credential={image.credential} onClick={() => handleClick(image.credentialIdentifier)} className={"w-full object-cover rounded-xl"} />
<div className='flex flex-wrap justify-center flex overflow-y-auto max-h-[40vh] custom-scrollbar bg-gray-50 shadow-md rounded-xl'>
{vcEntities.map(vcEntity => (
<>
<div key={vcEntity.credentialIdentifier} className="m-3 flex flex-col items-center">
<div className="relative rounded-xl w-2/3 overflow-hidden transition-shadow shadow-md hover:shadow-xl cursor-pointer">
<CredentialImage key={vcEntity.credentialIdentifier} credential={vcEntity.credential} onClick={() => handleClick(vcEntity.credentialIdentifier)} className={"w-full object-cover rounded-xl"} />
</div>
<div className='w-2/3 mt-2'>
<button
onClick={() => toggleCredentialDisplay(vcEntity.credentialIdentifier)}
className="text-xs py-2 w-full bg-custom-blue hover:bg-custom-blue-hover text-white font-medium rounded-lg">
{credentialDisplay[vcEntity.credentialIdentifier] ? 'Hide Details' : 'Show Details'}
</button>
<div
className={`transition-all ease-in-out duration-1000 overflow-hidden shadow-md rounded-lg ${credentialDisplay[vcEntity.credentialIdentifier] ? 'max-h-[500px] opacity-100' : 'max-h-0 opacity-0'}`}
>
<CredentialInfo credential={vcEntity.credential} mainClassName={"text-xs w-full"} />
</div>
</div>
</div>
</div>
</>
))}
</div>
<button
Expand Down
20 changes: 15 additions & 5 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,34 @@
margin: 0 5px !important;
}

/* Custom scrollbar in login */
/* Custom scrollbar */
.custom-scrollbar {
scrollbar-width: thin;
scrollbar-color: #ccc #f0f0f0;
padding-right: 5px;
padding-right: 10px;
}

.custom-scrollbar::-webkit-scrollbar {
width: 5px;
width: 10px;
}

.custom-scrollbar::-webkit-scrollbar-track {
background-color: #f0f0f0;
border-radius: 5px;
}

.custom-scrollbar::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 5px;
border: 2px solid #f0f0f0;
}

.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background-color: #888;
width: 15px;
border: 2px solid #888;
}

.custom-scrollbar::-webkit-scrollbar:hover {
width: 15px;
}

/* Nav item animation on Hover */
Expand Down

0 comments on commit c10e145

Please sign in to comment.