Skip to content

Commit

Permalink
Merge pull request #367 from wwWallet/refactor-ui
Browse files Browse the repository at this point in the history
Refactor UI
  • Loading branch information
gkatrakazas authored Oct 22, 2024
2 parents 1b7ae4b + 590d853 commit 692df88
Show file tree
Hide file tree
Showing 68 changed files with 1,448 additions and 1,207 deletions.
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,12 @@
"react-modal": "^3.16.1",
"react-router-dom": "^6.14.1",
"react-scripts": "5.0.1",
"react-slick": "^0.29.0",
"react-snowfall": "^1.2.1",
"react-transition-group": "^4.4.5",
"react-webcam": "^7.2.0",
"reactour": "^1.19.2",
"slick-carousel": "^1.8.1",
"styled-components": "^6.1.8",
"styled-components": "^6.1.13",
"swiper": "^11.1.14",
"tailwindcss": "^3.3.2",
"ts-results": "^3.3.0",
"typescript": "^5.1.6",
Expand Down
Binary file removed public/logo.png
Binary file not shown.
31 changes: 19 additions & 12 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import { CredentialsProvider } from './context/CredentialsContext';
import { withSessionContext } from './context/SessionContext';
import { checkForUpdates } from './offlineRegistrationSW';

import FadeInContentTransition from './components/FadeInContentTransition';
import HandlerNotification from './components/HandlerNotification';
import FadeInContentTransition from './components/Transitions/FadeInContentTransition';
import HandlerNotification from './components/Notifications/HandlerNotification';
import Snowfalling from './components/ChristmasAnimation/Snowfalling';
import Spinner from './components/Spinner';
import Spinner from './components/Shared/Spinner';

import { ContainerContextProvider } from './context/ContainerContext';

import UpdateNotification from './components/UpdateNotification';
import UpdateNotification from './components/Notifications/UpdateNotification';
import CredentialDetails from './pages/Home/CredentialDetails';

const reactLazyWithNonDefaultExports = (load, ...names) => {
const nonDefaults = (names ?? []).map(name => {
Expand Down Expand Up @@ -56,18 +58,20 @@ const reactLazyWithNonDefaultExports = (load, ...names) => {
return defaultExport;
};

const Layout = React.lazy(() => import('./components/Layout'));
const Layout = React.lazy(() => import('./components/Layout/Layout'));
const MessagePopup = React.lazy(() => import('./components/Popups/MessagePopup'));
const PinInputPopup = React.lazy(() => import('./components/Popups/PinInput'));
const PrivateRoute = reactLazyWithNonDefaultExports(
() => import('./components/PrivateRoute'),
() => import('./components/Auth/PrivateRoute'),
'NotificationPermissionWarning',
);
const SelectCredentialsPopup = React.lazy(() => import('./components/Popups/SelectCredentials'));
const SelectCredentialsPopup = React.lazy(() => import('./components/Popups/SelectCredentialsPopup'));

const AddCredentials = React.lazy(() => import('./pages/AddCredentials/AddCredentials'));
const CredentialDetail = React.lazy(() => import('./pages/Home/CredentialDetail'));
const Credential = React.lazy(() => import('./pages/Home/Credential'));
const CredentialHistory = React.lazy(() => import('./pages/Home/CredentialHistory'));
const History = React.lazy(() => import('./pages/History/History'));
const HistoryDetail = React.lazy(() => import('./pages/History/HistoryDetail'));
const Home = React.lazy(() => import('./pages/Home/Home'));
const Login = React.lazy(() => import('./pages/Login/Login'));
const LoginState = React.lazy(() => import('./pages/Login/LoginState'));
Expand Down Expand Up @@ -126,7 +130,7 @@ function App() {
<Snowfalling />
<Suspense fallback={<Spinner />}>
<HandlerNotification />
<UpdateNotification/>
<UpdateNotification />
<Routes>
<Route element={
<PrivateRoute>
Expand All @@ -142,8 +146,11 @@ function App() {
}>
<Route path="/settings" element={<Settings />} />
<Route path="/" element={<Home />} />
<Route path="/credential/:id" element={<CredentialDetail />} />
<Route path="/credential/:credentialId" element={<Credential />} />
<Route path="/credential/:credentialId/history" element={<CredentialHistory />} />
<Route path="/credential/:credentialId/details" element={<CredentialDetails />} />
<Route path="/history" element={<History />} />
<Route path="/history/:historyId" element={<HistoryDetail />} />
<Route path="/add" element={<AddCredentials />} />
<Route path="/send" element={<SendCredentials />} />
<Route path="/verification/result" element={<VerificationResult />} />
Expand All @@ -160,10 +167,10 @@ function App() {
</Route>
</Routes>
{showSelectCredentialsPopup &&
<SelectCredentialsPopup showPopup={showSelectCredentialsPopup} setShowPopup={setShowSelectCredentialsPopup} setSelectionMap={setSelectionMap} conformantCredentialsMap={conformantCredentialsMap} verifierDomainName={verifierDomainName} />
<SelectCredentialsPopup isOpen={showSelectCredentialsPopup} setIsOpen={setShowSelectCredentialsPopup} setSelectionMap={setSelectionMap} conformantCredentialsMap={conformantCredentialsMap} verifierDomainName={verifierDomainName} />
}
{showPinInputPopup &&
<PinInputPopup showPopup={showPinInputPopup} setShowPopup={setShowPinInputPopup} />
<PinInputPopup isOpen={showPinInputPopup} setIsOpen={setShowPinInputPopup} />
}
{showMessagePopup &&
<MessagePopup type={typeMessagePopup} message={textMessagePopup} onClose={() => setMessagePopup(false)} />
Expand Down
4 changes: 4 additions & 0 deletions src/assets/images/verifier_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as config from '../../config';
import logo from '../../assets/images/logo.png';


export default function LoginPageLayout({ children, heading }: { children: React.ReactNode, heading: React.ReactNode }) {
export default function LoginLayout({ children, heading }: { children: React.ReactNode, heading: React.ReactNode }) {
const { t } = useTranslation();
return (
<section className="bg-gray-100 dark:bg-gray-900 h-full">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from "react";


function passwordStrength(password: string): number {
const lengthScore = password.length >= 8 ? 25 : 0;
const capitalScore = /[A-Z]/.test(password) ? 25 : 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { createContext, useContext, useEffect, useState } from 'react';
import { Navigate, useLocation } from 'react-router-dom';
import { fetchToken, notificationApiIsSupported } from '../firebase';
import { fetchToken, notificationApiIsSupported } from '../../firebase';
import { FaExclamationTriangle, FaTimes } from 'react-icons/fa';
import { Trans } from 'react-i18next';

import Spinner from './Spinner'; // Import your spinner component
import { useSessionStorage } from '../hooks/useStorage';
import StatusContext from '../context/StatusContext';
import SessionContext from '../context/SessionContext';
import Spinner from '../Shared/Spinner'; // Import your spinner component
import { useSessionStorage } from '../../hooks/useStorage';
import StatusContext from '../../context/StatusContext';
import SessionContext from '../../context/SessionContext';


type PrivateRouteContextValue = {
Expand Down
5 changes: 3 additions & 2 deletions src/components/Buttons/QRButton.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react';
import { BsQrCodeScan } from 'react-icons/bs';
import Button from './Button';
import useScreenType from '../../hooks/useScreenType';

const QRButton = ({ openQRScanner, isSmallScreen }) => {
const isMobile = window.innerWidth <= 480;
const screenType = useScreenType();

if (isSmallScreen && !isMobile) {
if (screenType === 'tablet') {
return (
<div className="mb-2">
<Button
Expand Down
27 changes: 27 additions & 0 deletions src/components/Credentials/AddCredentialCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// AddCredentialButton.js
import React from 'react';
import { BsPlusCircle } from 'react-icons/bs';
import addImage from '../../assets/images/cred.png';
import { useTranslation } from 'react-i18next';

const AddCredentialCard = ({ onClick }) => {
const { t } = useTranslation();
return (
<button
className="step-1 relative rounded-xl overflow-hidden transition-shadow shadow-md hover:shadow-lg cursor-pointer"
onClick={onClick}
>
<img
src={addImage}
className="w-full h-auto rounded-xl opacity-100 hover:opacity-120"
alt=""
/>
<div className="absolute inset-0 flex flex-col items-center justify-center text-center">
<BsPlusCircle size={60} className="text-white mb-2 mt-4" />
<span className="text-white font-semibold">{t('pageCredentials.addCardTitle')}</span>
</div>
</button>
);
};

export default AddCredentialCard;
19 changes: 9 additions & 10 deletions src/components/Credentials/CredentialDeleteButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,15 @@ const CredentialDeleteButton = ({ onDelete }) => {
};

return (
<div className="lg:p-0 p-2 w-full lg:mt-5 mt-2">
<Button
onClick={handleClick}
variant="delete"
disabled={!isOnline}
title={!isOnline && t('common.offlineTitle')}
>
<MdDelete size={20} /> {t('common.delete')}
</Button>
</div>
<Button
onClick={handleClick}
variant="delete"
disabled={!isOnline}
title={!isOnline && t('common.offlineTitle')}
additionalClassName='xm:w-full'
>
<MdDelete size={20} /> {t('pageCredentials.delete')}
</Button>
);
};

Expand Down
5 changes: 3 additions & 2 deletions src/components/Credentials/CredentialImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import StatusRibbon from '../../components/Credentials/StatusRibbon';
import ContainerContext from '../../context/ContainerContext';
import RenderSvgTemplate from "./RenderSvgTemplate";

export const CredentialImage = ({ credential, className, onClick, showRibbon = true }) => {
const CredentialImage = ({ credential, className, onClick, showRibbon = true }) => {
const [parsedCredential, setParsedCredential] = useState(null);
const [svgImage, setSvgImage] = useState(null);
const container = useContext(ContainerContext);
Expand All @@ -14,7 +14,6 @@ export const CredentialImage = ({ credential, className, onClick, showRibbon = t
if ('error' in c) {
return;
}
console.log('->',c)
setParsedCredential(c);
});
}
Expand Down Expand Up @@ -44,3 +43,5 @@ export const CredentialImage = ({ credential, className, onClick, showRibbon = t
</>
);
};

export default CredentialImage;
39 changes: 20 additions & 19 deletions src/components/Credentials/CredentialInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { MdTitle, MdGrade, MdOutlineNumbers } from 'react-icons/md';
import { GiLevelEndFlag } from 'react-icons/gi';
import { formatDate } from '../../functions/DateFormat';
import ContainerContext from '../../context/ContainerContext';
import useScreenType from '../../hooks/useScreenType';

const getFieldIcon = (fieldName) => {
switch (fieldName) {
Expand All @@ -31,29 +32,30 @@ const getFieldIcon = (fieldName) => {
}
};

const renderRow = (fieldName, label, fieldValue) => {
const renderRow = (fieldName, label, fieldValue, screenType) => {

if (fieldValue) {
return (
<tr className="text-left">
<td className="font-bold text-primary dark:text-primary-light py-2 px-2 rounded-l-xl">
<div className="flex md:flex-row flex-col items-left">
{getFieldIcon(fieldName)}
<td className="font-bold text-primary dark:text-primary-light py-2 xm:py-1 px-2 rounded-l-xl">
<div className="flex flex-row items-left">
{screenType !== 'mobile' && getFieldIcon(fieldName)}
<span className="md:ml-1 flex items-center">{label}:</span>
</div>
</td>
<td className="text-gray-700 dark:text-white py-2 px-2 rounded-r-xl">{fieldValue}</td>
<td className="text-gray-700 dark:text-white py-2 xm:py-1 px-2 rounded-r-xl">{fieldValue}</td>
</tr>
);
} else {
return null;
}
};

const CredentialInfo = ({ credential, mainClassName = "text-xs sm:text-sm md:text-base pt-5 pr-2 w-full" }) => {
const CredentialInfo = ({ credential, mainClassName = "text-sm lg:text-base w-full" }) => {

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

const container = useContext(ContainerContext);
const screenType = useScreenType();

useEffect(() => {
if (container) {
Expand All @@ -73,18 +75,17 @@ const CredentialInfo = ({ credential, mainClassName = "text-xs sm:text-sm md:tex
<tbody className="divide-y-4 divide-transparent">
{parsedCredential && (
<>
{renderRow('expdate', 'Expiration', formatDate(new Date(parsedCredential?.exp * 1000).toISOString()))}
{renderRow('familyName', 'Family Name', parsedCredential?.family_name)}
{renderRow('firstName', 'Given Name', parsedCredential?.given_name)}
{renderRow('id', 'Personal ID', parsedCredential?.personal_identifier)}
{renderRow('dateOfBirth', 'Birthday', parsedCredential?.dateOfBirth)}
{renderRow('dateOfBirth', 'Birthday', parsedCredential?.birth_date)}
{renderRow('diplomaTitle', 'Title', parsedCredential?.title)}
{renderRow('eqfLevel', 'EQF', parsedCredential?.eqf_level)}
{renderRow('grade', 'Grade', parsedCredential?.grade)}
{renderRow('id', 'Social Security Number', parsedCredential?.ssn)}
{renderRow('id', 'Document Number', parsedCredential?.document_number)}

{renderRow('expdate', 'Expiration', formatDate(new Date(parsedCredential?.exp * 1000).toISOString()), screenType)}
{renderRow('familyName', 'Family Name', parsedCredential?.family_name, screenType)}
{renderRow('firstName', 'Given Name', parsedCredential?.given_name, screenType)}
{renderRow('id', 'Personal ID', parsedCredential?.personal_identifier, screenType)}
{renderRow('dateOfBirth', 'Birthday', formatDate(parsedCredential?.dateOfBirth, 'date'), screenType)}
{renderRow('dateOfBirth', 'Birthday', formatDate(parsedCredential?.birth_date, 'date'), screenType)}
{renderRow('diplomaTitle', 'Title', parsedCredential?.title, screenType)}
{renderRow('eqfLevel', 'EQF', parsedCredential?.eqf_level, screenType)}
{renderRow('grade', 'Grade', parsedCredential?.grade, screenType)}
{renderRow('id', 'Social Security Number', parsedCredential?.ssn, screenType)}
{renderRow('id', 'Document Number', parsedCredential?.document_number, screenType)}
</>
)}
</tbody>
Expand Down
34 changes: 5 additions & 29 deletions src/components/Credentials/CredentialJson.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,10 @@

import React, { useEffect, useState, useContext } from 'react';

import { AiOutlineDown, AiOutlineUp } from 'react-icons/ai';
import ContainerContext from '../../context/ContainerContext';
import Button from '../Buttons/Button';

const CredentialJson = ({ credential }) => {
const [showJsonCredentials, setShowJsonCredentials] = useState(false);


const CredentialJson = ({ credential, textAreaRows='10' }) => {
const container = useContext(ContainerContext);

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

useEffect(() => {
Expand All @@ -26,34 +20,16 @@ const CredentialJson = ({ credential }) => {
}, [credential, container]);

return (
<div className=" lg:p-0 p-2 w-full">
<div className="mb-4 flex items-center">
<Button
onClick={() => setShowJsonCredentials(!showJsonCredentials)}
variant="primary"
>
{showJsonCredentials ? 'Hide Credentials Details' : 'Show Credentials Details'}
{showJsonCredentials ? (
<AiOutlineUp className="ml-1" />
) : (
<AiOutlineDown className="ml-1" />
)}
</Button>
</div>

<hr className="my-2 border-t border-primary dark:border-primary-light py-2" />

{showJsonCredentials && parsedCredential ? (
<div className='w-full'>
{parsedCredential && (
<div>
<textarea
rows="10"
rows={textAreaRows}
readOnly
className="w-full dark:bg-gray-900 dark:text-white border rounded p-2 rounded-xl"
className="dark:bg-gray-900 dark:text-white border rounded p-2 text-sm w-full rounded-xl"
value={JSON.stringify(parsedCredential, null, 2)}
/>
</div>
) : (
<p></p>
)}
</div>
);
Expand Down
Loading

0 comments on commit 692df88

Please sign in to comment.