Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • orthmann/web-ui
  • vkalashn/web-ui
  • mxgor/web-ui
3 results
Show changes
Commits on Source (22)
Showing
with 417 additions and 456 deletions
......@@ -31,6 +31,7 @@
"react-hooks/exhaustive-deps": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/naming-convention": "off"
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/promise-function-async": "off"
}
}
......@@ -160,6 +160,7 @@
"enter-offering": "Geben Sie den Angebotslink ein",
"submit": "Einreichen",
"empty-offering": "Angebotslink darf nicht leer sein!",
"create-success": "Angebot erfolgreich erstellt!",
"accept-success": "Angebot erfolgreich akzeptiert!",
"deny-success": "Angebot erfolgreich abgelehnt!",
"did-empty": "DID darf nicht leer sein!"
......
......@@ -161,6 +161,7 @@
"submit": "Submit",
"empty-offering": "Offering link cannot be empty!",
"accept-success": "Offering accepted successfully!",
"create-success": "Offering created successfully!",
"deny-success": "Offering denied successfully!",
"did-empty": "DID cannot be empty!"
},
......
This diff is collapsed.
No preview for this file type
No preview for this file type
No preview for this file type
......@@ -4,7 +4,6 @@ import { Button, Container } from 'react-bootstrap';
import Table, { type TableBody, type TableBodyMap, type TableData } from '@/components/table/Table';
import { useContext, useEffect, useState } from 'react';
import { AppContext } from '@/store/AppContextProvider';
import { useAuth } from 'oidc-react';
import { genericFetch, useApiData } from '@/service/apiService';
import type { BackupList, BackupQrCodeData } from '@/service/types';
import { useTranslations } from 'next-intl';
......@@ -13,6 +12,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTrash } from '@fortawesome/free-solid-svg-icons';
import { toast } from 'react-toastify';
import AddBackupModal from '@/components/add-backup-modal/AddBackupModal';
import { useKeycloak } from '@react-keycloak/web';
import { useQueryClient } from '@tanstack/react-query';
interface QrCodeModalProps {
qrCode: string;
......@@ -20,27 +21,21 @@ interface QrCodeModalProps {
}
const Backup = (): JSX.Element => {
const { userData } = useAuth();
const { data, error, isLoading } = useApiData<BackupList>(
'backupList',
`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/backup/all`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
}
);
const [tableData, setTableData] = useState<TableData>();
const { keycloak } = useKeycloak();
const { setError } = useContext(AppContext);
const [rowData, setRowData] = useState<TableBodyMap>();
const t = useTranslations('Backup');
const queryClient = useQueryClient();
const [tableData, setTableData] = useState<TableData>();
const [rowData, setRowData] = useState<TableBodyMap>();
const [showQrModal, setShowQrModal] = useState(false);
const [showAddModal, setShowAddModal] = useState(false);
const [qrData, setQrData] = useState<QrCodeModalProps>();
useEffect(() => {
error && setError(error);
}, [error]);
const { data, isLoading } = useApiData<BackupList>(
'backupList',
`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/backup/all`,
{ headers: { Authorization: `Bearer ${keycloak.token}` } }
);
useEffect(() => {
if (!data || data.backups.length <= 0) return;
......@@ -73,7 +68,7 @@ const Backup = (): JSX.Element => {
`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/backup/link/download?bindingId=${value.bindingId}`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
Authorization: `Bearer ${keycloak.token}`,
},
}
).then(data => data.path),
......@@ -86,18 +81,12 @@ const Backup = (): JSX.Element => {
await genericFetch<BackupQrCodeData>(
`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/backup/${value.bindingId}`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
headers: { Authorization: `Bearer ${keycloak.token}` },
method: 'DELETE',
}
).then(() => {
toast.success(t('delete-success'));
setTableData({
head: tableData!.head,
body: tableData!.body.filter(row => row.id !== value.id),
});
void queryClient.invalidateQueries({ queryKey: ['backupList'] });
});
break;
......@@ -105,7 +94,7 @@ const Backup = (): JSX.Element => {
};
rowData.forEach((value, key) => {
handleAction(value, key).catch(error => setError(error));
handleAction(value, key).catch(setError);
});
}, [rowData]);
......
'use client';
import { Col, Container, Row } from 'react-bootstrap';
import css from './wallet.module.scss';
import CredentialColumn from '@/components/credential-column/CredentialColumn';
import Divider from '@/components/divider/Divider';
import { useContext, useEffect, useState } from 'react';
import { type VerifiableCredentials } from '@/service/types';
import LoadingSpinner from '@/components/loading-spinner/LoadingSpinner';
import NoData from '@/components/no-data/NoData';
import SearchButton from '@/components/search-button/SearchButton';
import { genericFetch, useApiData } from '@/service/apiService';
import type {
CredentialData,
CredentialList,
CodedVerifiableCredentials,
VerifiableCredentials,
} from '@/service/types';
import { AppContext } from '@/store/AppContextProvider';
import { useTranslations } from 'next-intl';
import { useAuth } from 'oidc-react';
import CredentialColumn from '@/components/credential-column/CredentialColumn';
import SearchButton from '@/components/search-button/SearchButton';
import { debounce } from '@/utils/timeUtils';
import LoadingSpinner from '@/components/loading-spinner/LoadingSpinner';
import NoData from '@/components/no-data/NoData';
import { useKeycloak } from '@react-keycloak/web';
import { digest } from '@sd-jwt/crypto-nodejs';
import { decodeSdJwt } from '@sd-jwt/decode';
import { useTranslations } from 'next-intl';
import { useCallback, useContext, useEffect, useState } from 'react';
import { Col, Container, Row } from 'react-bootstrap';
import css from './wallet.module.scss';
const Wallet = (): JSX.Element => {
const { userData } = useAuth();
const { data, error, isLoading } = useApiData<VerifiableCredentials[]>(
const { keycloak } = useKeycloak();
const { data, isLoading } = useApiData<CodedVerifiableCredentials[]>(
'credentialList',
`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/list`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
headers: { Authorization: `Bearer ${keycloak.token}` },
body: JSON.stringify({ search: '' }),
method: 'POST',
}
);
const { setError } = useContext(AppContext);
const t = useTranslations('CredentialsOverview');
const [filteredCredentials, setFilteredCredentials] = useState<VerifiableCredentials[]>([]);
useEffect(() => {
error && setError(error);
}, [error]);
useEffect(() => {
if (!data) return;
setFilteredCredentials(data);
getDecodedCredentials(data).then(setFilteredCredentials).catch(setError);
}, [data]);
const decodeCredential = async (credential: CodedVerifiableCredentials): Promise<VerifiableCredentials> => {
const { credentials, description } = credential;
const decodedEntries: CredentialList[] = await Promise.all(
Object.keys(credentials).map(async key => {
let decodedCredentials: CredentialData;
if (credentials[key].type === 'vc+sd-jwt') {
const decodedCredential = await decodeSdJwt(credentials[key].data, digest);
decodedCredentials = {
vct: decodedCredential.jwt.payload.vct as string,
issuer: decodedCredential.jwt.payload.iss as string,
issuanceDate: decodedCredential.jwt.payload.iat as string,
credentialSubject: decodedCredential.jwt.payload as Record<string, string>,
};
} else {
decodedCredentials = JSON.parse(credentials[key].data);
}
return {
[key]: decodedCredentials,
};
})
);
return {
description,
credentials: decodedEntries.reduce((acc, entry) => ({ ...acc, ...entry }), {}),
};
};
const getDecodedCredentials = useCallback(
async (credentials: CodedVerifiableCredentials[]): Promise<VerifiableCredentials[]> =>
await Promise.all(credentials.map(decodeCredential)),
[]
);
const handleOnSearch = debounce((searchValue: string): void => {
const getFilteredCredentials = async (): Promise<VerifiableCredentials[]> => {
return await genericFetch<VerifiableCredentials[]>(`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/list`, {
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
body: JSON.stringify({
search: searchValue,
}),
method: 'POST',
});
const getFilteredCredentials = async (): Promise<CodedVerifiableCredentials[]> => {
return await genericFetch<CodedVerifiableCredentials[]>(
`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/list`,
{
headers: { Authorization: `Bearer ${keycloak.token}` },
body: JSON.stringify({ search: searchValue }),
method: 'POST',
}
);
};
getFilteredCredentials()
.then(data => {
setFilteredCredentials(data);
})
.catch(error => {
setError(error);
});
.then(async data => await getDecodedCredentials(data))
.then(setFilteredCredentials)
.catch(setError);
}, 500);
const renderCredentials = (): JSX.Element | JSX.Element[] | null => {
if (isLoading) {
return (
<div className={`${css['flex-center']}`}>
<LoadingSpinner />
</div>
);
}
if (!filteredCredentials.length) {
return (
<div className={`${css['flex-center']} w-100`}>
<NoData />
</div>
);
}
return filteredCredentials.map((credential, i) => (
<CredentialColumn
key={credential?.description?.id ?? i}
credential={credential}
/>
));
};
return (
<Container fluid>
<Row>
......@@ -77,24 +139,7 @@ const Wallet = (): JSX.Element => {
<Divider className="my-2" />
<div className={css['cards-container']}>
{filteredCredentials && !isLoading ? (
filteredCredentials.map(credential => (
<CredentialColumn
key={credential.description.id}
credential={credential}
/>
))
) : isLoading ? (
<div className={`${css['flex-center']}`}>
<LoadingSpinner />
</div>
) : (
<div className={`${css['flex-center']} w-100`}>
<NoData />
</div>
)}
</div>
<div className={css['cards-container']}>{renderCredentials()}</div>
</Container>
);
};
......
......@@ -6,40 +6,30 @@ import type { DidData } from '@/service/types';
import { genericFetch, useApiData } from '@/service/apiService';
import { useContext, useEffect, useState } from 'react';
import { AppContext } from '@/store/AppContextProvider';
import { useAuth } from 'oidc-react';
import { formatDateString } from '@/utils/dateUtils';
import { useTranslations } from 'next-intl';
import CreateDidModal from '@/components/create-did-modal/CreateDidModal';
import { toast } from 'react-toastify';
import { useKeycloak } from '@react-keycloak/web';
import { useQueryClient } from '@tanstack/react-query';
const Did = (): JSX.Element => {
const { userData } = useAuth();
const { data, error, isLoading } = useApiData<DidData>(
'didList',
`${process.env.API_URL_ACCOUNT_SERVICE}/kms/did/list`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
}
);
const [tableData, setTableData] = useState<TableData>();
const { setError } = useContext(AppContext);
const { keycloak } = useKeycloak();
const t = useTranslations('Did');
const { setError } = useContext(AppContext);
const [tableData, setTableData] = useState<TableData>();
const [showModal, setShowModal] = useState(false);
const queryClient = useQueryClient();
const { data, isLoading } = useApiData<DidData>('didList', `${process.env.API_URL_ACCOUNT_SERVICE}/kms/did/list`, {
headers: { Authorization: `Bearer ${keycloak.token}` },
});
useEffect(() => {
error && setError(error);
}, [error]);
useEffect(() => {
if (!data || data.list.length <= 0) return;
const didData = data.list;
if (!data?.list.length) return;
setTableData({
head: ['id', 'did', 'timestamp'],
body: didData.map(({ ...did }) => {
body: data.list.map(({ ...did }) => {
return {
...did,
timestamp: formatDateString(did.timestamp),
......@@ -51,19 +41,15 @@ const Did = (): JSX.Element => {
const handleCreateDidOnSubmit = (keyType: string): void => {
const createDid = async (): Promise<void> => {
await genericFetch(`${process.env.API_URL_ACCOUNT_SERVICE}/kms/did/create`, {
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
body: JSON.stringify({
keyType,
}),
headers: { Authorization: `Bearer ${keycloak.token}` },
body: JSON.stringify({ keyType }),
method: 'POST',
});
};
createDid()
.then(() => {
window.location.reload();
void queryClient.invalidateQueries({ queryKey: ['didList'] });
toast.success(t('create-success'));
})
.catch(error => setError(error));
......
......@@ -3,46 +3,35 @@
import Table, { type TableData } from '@/components/table/Table';
import { useApiData } from '@/service/apiService';
import type { DefaultConfig, HistoryData } from '@/service/types';
import { AppContext } from '@/store/AppContextProvider';
import { useTranslations } from 'next-intl';
import { useAuth } from 'oidc-react';
import { useContext, useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { Col, Container, Row } from 'react-bootstrap';
import css from './history.module.scss';
import { useQueryClient } from '@tanstack/react-query';
import { formatDateString } from '@/utils/dateUtils';
import { useKeycloak } from '@react-keycloak/web';
const History = (): JSX.Element => {
const { userData } = useAuth();
const { data, error, isLoading } = useApiData<HistoryData>(
'historyList',
`${process.env.API_URL_ACCOUNT_SERVICE}/history/list`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
}
);
const { keycloak } = useKeycloak();
const t = useTranslations('History');
const config = useQueryClient().getQueryData<DefaultConfig>(['defaultConfig']);
const [tableData, setTableData] = useState<TableData>();
const [historyLength, setHistoryLength] = useState<number>(0);
const { setError } = useContext(AppContext);
const t = useTranslations('History');
useEffect(() => {
error && setError(error);
}, [error]);
const { data, isLoading } = useApiData<HistoryData>(
'historyList',
`${process.env.API_URL_ACCOUNT_SERVICE}/history/list`,
{ headers: { Authorization: `Bearer ${keycloak.token}` } }
);
useEffect(() => {
if (!data || data.events.length <= 0) return;
const historyData = data.events;
setHistoryLength(historyData.length);
setHistoryLength(data.events.length);
setTableData({
head: ['event', 'type', 'userId', 'timestamp'],
body: historyData
body: data.events
.map(({ ...history }, i) => {
return {
...history,
......
......@@ -3,7 +3,6 @@
import { useLocale, useTranslations } from 'next-intl';
import css from './issuance.module.scss';
import { Button, Col, Container, Row } from 'react-bootstrap';
import { useAuth } from 'oidc-react';
import type { CredentialOffer, IssuanceData, SchemaData } from '@/service/types';
import { genericFetch, useApiData } from '@/service/apiService';
import { type FormEvent, useContext, useEffect, useState } from 'react';
......@@ -14,40 +13,32 @@ import { type IChangeEvent } from '@rjsf/core';
import { type RJSFSchema } from '@rjsf/utils';
import { toast } from 'react-toastify';
import { getDetailedDisplay, getDisplayName } from '@/utils/objectUtils';
import { useKeycloak } from '@react-keycloak/web';
const Issuance = (): JSX.Element => {
const t = useTranslations('Issuance');
const { userData } = useAuth();
const { data, error, isLoading } = useApiData<IssuanceData[]>(
'schemaList',
`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/schemas`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
}
);
const { keycloak } = useKeycloak();
const { setError } = useContext(AppContext);
const locale = useLocale();
const [tableData, setTableData] = useState<TableData>();
const [rowData, setRowData] = useState<TableBodyMap>();
const [showModal, setShowModal] = useState(false);
const [credentialOfferLink, setCredentialOfferLink] = useState('');
const { setError } = useContext(AppContext);
const locale = useLocale();
useEffect(() => {
error && setError(error);
}, [error]);
const { data, isLoading } = useApiData<IssuanceData[]>(
'schemaList',
`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/schemas`,
{ headers: { Authorization: `Bearer ${keycloak.token}` } }
);
useEffect(() => {
if (!data || data.length <= 0) return;
// make sure it's an array of objects (only used for the mock data)
const schemaData = Array.isArray(data) ? data : [data];
setTableData({
head: ['', 'name', 'format', 'fields'],
body: schemaData.flatMap(item => {
body: [data].flatMap(item => {
return Object.keys(item).map(key => {
// @ts-expect-error
const { display, credential_definition, format } = item[key];
return {
logo: '/xfsc1.png',
......@@ -66,9 +57,7 @@ const Issuance = (): JSX.Element => {
useEffect(() => {
if (!rowData) return;
if (rowData.get('select')) {
setShowModal(true);
}
if (rowData.get('select')) setShowModal(true);
}, [rowData]);
const getSelectedData = (rowData: TableBody, data: IssuanceData[]): Record<string, SchemaData> => {
......@@ -89,7 +78,22 @@ const Issuance = (): JSX.Element => {
delete schema.data.$schema;
return {
[key]: schema,
[key]: {
data: {
...schema.data,
properties: {
...schema.data.properties,
pin_otp: {
title: 'Add One Time Code',
type: 'boolean',
},
},
},
ui: {
...schema.ui,
'ui:order': [...(schema.ui['ui:order'] ?? []), 'pin_otp'],
},
},
};
};
......@@ -98,9 +102,7 @@ const Issuance = (): JSX.Element => {
const getIssuedLink = async (): Promise<CredentialOffer> => {
return await genericFetch<CredentialOffer>(`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/issue`, {
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
headers: { Authorization: `Bearer ${keycloak.token}` },
body: JSON.stringify({
payload: {
...data.formData,
......@@ -116,9 +118,7 @@ const Issuance = (): JSX.Element => {
toast.success(t('success-message'));
setCredentialOfferLink(data.credential_offer);
})
.catch(error => {
setError(error);
});
.catch(setError);
};
return (
......
......@@ -7,7 +7,6 @@ import WalletSideMenu from '@/components/side-menu/WalletSideMenu';
import { WalletProvider } from '@/store/Provider';
import { type Metadata } from 'next';
import { NextIntlClientProvider, useMessages } from 'next-intl';
import { ToastContainer } from 'react-toastify';
export const metadata: Metadata = {
title: 'Wallet',
......@@ -31,17 +30,6 @@ const WalletLayout = ({
locale={locale}
messages={messages}
>
<ToastContainer
position="top-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>
<WalletSideMenu />
<div className={`${css['content-wrapper']}`}>
<div className={css.content}>
......
......@@ -7,42 +7,40 @@ import { genericFetch, useApiData } from '@/service/apiService';
import type { CredentialConfiguration, OfferingData } from '@/service/types';
import { AppContext } from '@/store/AppContextProvider';
import { getDetailedDisplay, getDisplayName } from '@/utils/objectUtils';
import { useKeycloak } from '@react-keycloak/web';
import { useQueryClient } from '@tanstack/react-query';
import { useLocale, useTranslations } from 'next-intl';
import { useAuth } from 'oidc-react';
import { useContext, useEffect, useState } from 'react';
import { Button, Container } from 'react-bootstrap';
import { toast } from 'react-toastify';
function getFields(offering: CredentialConfiguration, locale: string): string {
if (!offering.credential_definition.credentialSubject) return '';
const { credentialSubject } = offering.credential_definition;
return Object.keys(offering.credential_definition.credentialSubject)
.map(subKey => getDisplayName(offering.credential_definition.credentialSubject, subKey, locale))
if (!credentialSubject) return '';
return Object.keys(credentialSubject)
.map(subKey => getDisplayName(credentialSubject, subKey, locale))
.join(', ');
}
const Offering = (): JSX.Element => {
const { userData } = useAuth();
const { data, error, isLoading } = useApiData<OfferingData[]>(
'offeringList',
`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/offers/list`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
}
);
const [tableData, setTableData] = useState<TableData>();
const { keycloak } = useKeycloak();
const { setError } = useContext(AppContext);
const t = useTranslations('Offering');
const locale = useLocale();
const queryClient = useQueryClient();
const [tableData, setTableData] = useState<TableData>();
const [rowData, setRowData] = useState<TableBodyMap>();
const [showModal, setShowModal] = useState(false);
const [showAcceptModal, setShowAcceptModal] = useState(false);
const locale = useLocale();
useEffect(() => {
error && setError(error);
}, [error]);
const [isAccepting, setIsAccepting] = useState(false);
const { data, isLoading } = useApiData<OfferingData[]>(
'offeringList',
`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/offers/list`,
{ headers: { Authorization: `Bearer ${keycloak.token}` } }
);
useEffect(() => {
if (!data || data.length <= 0) return;
......@@ -62,7 +60,9 @@ const Offering = (): JSX.Element => {
status: '',
};
}
const offering = item.metadata.credential_configurations_supported[type];
return {
logo: getDetailedDisplay(offering.display, locale).logo.url,
id: item.requestId,
......@@ -78,7 +78,7 @@ const Offering = (): JSX.Element => {
head: ['', 'id', 'requestId', 'name', 'fields', 'status'],
body: tableBody.flat(2).filter(item => item.requestId && item.status),
});
}, [data]);
}, [data, locale]);
useEffect(() => {
if (!rowData) return;
......@@ -95,50 +95,41 @@ const Offering = (): JSX.Element => {
break;
case 'deny':
denyOffering(value)
.then(() => {
window.location.reload();
toast.success(t('deny-success'));
})
.catch(error => setError(error));
void handleDenyOffering(value);
break;
}
};
rowData.forEach((value, key) => {
handleAction(value, key).catch(error => setError(error));
});
Promise.all([...rowData.entries()].map(([key, value]) => handleAction(value, key))).catch(error => setError(error));
}, [rowData]);
const denyOffering = async (value: TableBody): Promise<void> => {
const handleDenyOffering = async (value: TableBody): Promise<void> => {
await genericFetch(`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/offers/${value?.requestId}/deny`, {
method: 'POST',
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
body: JSON.stringify({
keyId: '',
}),
});
headers: { Authorization: `Bearer ${keycloak.token}` },
body: JSON.stringify({ keyId: '' }),
})
.then(() => {
void queryClient.invalidateQueries({ queryKey: ['offeringList'] });
toast.success(t('deny-success'));
})
.catch(setError);
};
const handleCreateOnSubmit = (data: OfferingLinkData): void => {
console.log(data);
const offerLink = async (): Promise<void> => {
await genericFetch(`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/offers/create`, {
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
body: JSON.stringify({
credential_offer: data.offeringLink,
}),
headers: { Authorization: `Bearer ${keycloak.token}` },
body: JSON.stringify({ credential_offer: data.offeringLink }),
method: 'PUT',
});
};
offerLink()
.then(() => window.location.reload())
.then(() => {
void queryClient.invalidateQueries({ queryKey: ['offeringList'] });
toast.success(t('create-success'));
})
.catch(error => setError(error));
};
......@@ -146,23 +137,22 @@ const Offering = (): JSX.Element => {
const value = rowData?.get('accept');
const acceptOffering = async (): Promise<void> => {
setIsAccepting(true);
await genericFetch(`${process.env.API_URL_ACCOUNT_SERVICE}/credentials/offers/${value?.requestId}/accept`, {
method: 'POST',
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
body: JSON.stringify({
keyId: did,
}),
headers: { Authorization: `Bearer ${keycloak.token}` },
body: JSON.stringify({ keyId: did }),
});
};
acceptOffering()
.then(() => {
window.location.reload();
void queryClient.invalidateQueries({ queryKey: ['offeringList'] });
toast.success(t('accept-success'));
})
.catch(error => setError(error));
.catch(error => setError(error))
.finally(() => setIsAccepting(false));
};
return (
......@@ -176,7 +166,7 @@ const Offering = (): JSX.Element => {
<Table
data={tableData}
isLoading={isLoading}
isLoading={isLoading || isAccepting}
handleSelectRow={data => setRowData(data)}
showActions
filterActions={(data: TableBody) => data.status !== 'received'}
......
......@@ -8,35 +8,30 @@ import { AppContext } from '@/store/AppContextProvider';
import { faBan, faCirclePlus, faTrash } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { useTranslations } from 'next-intl';
import { useAuth } from 'oidc-react';
import { useContext, useEffect, useState } from 'react';
import { Button, Col, Container, Row } from 'react-bootstrap';
import css from './pairing-management.module.scss';
import DetailsModal from '@/components/details-modal/DetailsModal';
import { toast } from 'react-toastify';
import { useKeycloak } from '@react-keycloak/web';
import { useQueryClient } from '@tanstack/react-query';
const PairingManagement = (): JSX.Element => {
const t = useTranslations('SettingsPairingManagement');
const { userData } = useAuth();
const { data, error, isLoading } = useApiData<DevicesData[]>(
'devicesList',
`${process.env.API_URL_ACCOUNT_SERVICE}/devices/list`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
}
);
const { keycloak } = useKeycloak();
const { setError } = useContext(AppContext);
const queryClient = useQueryClient();
const [tableData, setTableData] = useState<TableData>();
const [showModal, setShowModal] = useState(false);
const [showSeeDetails, setShowSeeDetails] = useState(false);
const [rowData, setRowData] = useState<TableBodyMap>();
const { setError } = useContext(AppContext);
const [qrCode, setQrCode] = useState('');
useEffect(() => {
error && setError(error);
}, [error]);
const { data, isLoading } = useApiData<DevicesData[]>(
'devicesList',
`${process.env.API_URL_ACCOUNT_SERVICE}/devices/list`,
{ headers: { Authorization: `Bearer ${keycloak.token}` } }
);
useEffect(() => {
if (!data || data.length <= 0) return;
......@@ -69,45 +64,38 @@ const PairingManagement = (): JSX.Element => {
break;
case 'block':
await genericFetch(`${process.env.API_URL_ACCOUNT_SERVICE}/devices/block/${value.id}`, {
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
headers: { Authorization: `Bearer ${keycloak.token}` },
method: 'POST',
})
.then(() => {
void queryClient.invalidateQueries({ queryKey: ['devicesList'] });
toast.success(t('block-success'));
})
.catch(error => setError(error));
.catch(setError);
break;
case 'delete':
await genericFetch(`${process.env.API_URL_ACCOUNT_SERVICE}/devices/${value.id}`, {
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
headers: { Authorization: `Bearer ${keycloak.token}` },
method: 'DELETE',
})
.then(() => {
void queryClient.invalidateQueries({ queryKey: ['devicesList'] });
toast.success(t('delete-success'));
setTableData({
head: tableData!.head,
body: tableData!.body.filter(row => row.id !== value.id),
});
})
.catch(error => setError(error));
.catch(setError);
break;
}
};
rowData.forEach((value, key) => {
handleAction(value, key).catch(error => setError(error));
handleAction(value, key).catch(setError);
});
}, [rowData]);
const handleQrCodeClick = (): void => {
genericFetch<string>(`${process.env.API_URL_ACCOUNT_SERVICE}/devices/link`, {
headers: {
Authorization: `Bearer ${userData?.access_token}`,
Authorization: `Bearer ${keycloak.token}`,
},
})
.then(data => {
......
......@@ -4,9 +4,9 @@ import { RemoteComponent } from '@/RemoteComponent';
import LoadingSpinner from '@/components/loading-spinner/LoadingSpinner';
import { type Plugin as IPlugin } from '@/components/side-menu/WalletSideMenu';
import { AppContext } from '@/store/AppContextProvider';
import { useKeycloak } from '@react-keycloak/web';
import { useQueryClient } from '@tanstack/react-query';
import { useTranslations } from 'next-intl';
import { useAuth } from 'oidc-react';
import { useContext, useEffect, useState } from 'react';
interface PluginProps {
......@@ -20,7 +20,7 @@ const Plugin = ({ params }: PluginProps): JSX.Element => {
const pluginDiscoveryData = useQueryClient().getQueryData<IPlugin[]>(['pluginDiscovery']);
const t = useTranslations('Plugin');
const { setError } = useContext(AppContext);
const { userData } = useAuth();
const { keycloak } = useKeycloak();
const [pluginMetadata, setPluginMetadata] = useState<Record<string, string>>({});
useEffect(() => {
......@@ -47,7 +47,7 @@ const Plugin = ({ params }: PluginProps): JSX.Element => {
<div>{err.toString()}</div>
) : (
<Component
token={userData?.access_token}
token={keycloak.token}
metadata={metadata}
error={(error: Error) => setError(error)}
/>
......
......@@ -3,15 +3,13 @@
import { Col, Container, Row } from 'react-bootstrap';
import css from './presentations.module.scss';
import Divider from '@/components/divider/Divider';
import { useContext, useEffect } from 'react';
import type { VerifiableCredentials, VerifiablePresentation } from '@/service/types';
import { useApiData } from '@/service/apiService';
import { AppContext } from '@/store/AppContextProvider';
import { useTranslations } from 'next-intl';
import { useAuth } from 'oidc-react';
import CredentialColumn from '@/components/credential-column/CredentialColumn';
import LoadingSpinner from '@/components/loading-spinner/LoadingSpinner';
import NoData from '@/components/no-data/NoData';
import { useKeycloak } from '@react-keycloak/web';
function mapCredentialToPresentation(credential: VerifiablePresentation): VerifiableCredentials[] {
const credentials: VerifiableCredentials[] = [];
......@@ -42,24 +40,14 @@ function mapCredentialToPresentation(credential: VerifiablePresentation): Verifi
}
const Presentations = (): JSX.Element => {
const { userData } = useAuth();
const { data, error, isLoading } = useApiData<VerifiablePresentation[]>(
const { keycloak } = useKeycloak();
const { data, isLoading } = useApiData<VerifiablePresentation[]>(
'presentationList',
`${process.env.API_URL_ACCOUNT_SERVICE}/presentations/list`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
method: 'POST',
}
{ headers: { Authorization: `Bearer ${keycloak.token}` }, method: 'POST' }
);
const { setError } = useContext(AppContext);
const t = useTranslations('PresentationsList');
useEffect(() => {
error && setError(error);
}, [error]);
return (
<Container
fluid
......
......@@ -4,38 +4,24 @@ import Divider from '@/components/divider/Divider';
import Table, { type TableBodyMap, type TableData } from '@/components/table/Table';
import { useApiData } from '@/service/apiService';
import type { PresentationDefinitionData } from '@/service/types';
import { AppContext } from '@/store/AppContextProvider';
import { useTranslations } from 'next-intl';
import { useAuth } from 'oidc-react';
import { useContext, useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { Button, Col, Container, Row } from 'react-bootstrap';
import css from './selection.module.scss';
import PresentationSelection from '@/components/presentation-selection/PresentationSelection';
import { useKeycloak } from '@react-keycloak/web';
const Selection = (): JSX.Element => {
const t = useTranslations('Presentation');
const { userData } = useAuth();
const {
data: definitionData,
error: definitionError,
isLoading: isLoadingDefinition,
} = useApiData<PresentationDefinitionData[]>(
const { keycloak } = useKeycloak();
const { data: definitionData, isLoading: isLoadingDefinition } = useApiData<PresentationDefinitionData[]>(
'presentationDefinitionList',
`${process.env.API_URL_ACCOUNT_SERVICE}/presentations/selection/all`,
{
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
}
{ headers: { Authorization: `Bearer ${keycloak.token}` } }
);
const { setError } = useContext(AppContext);
const [rowData, setRowData] = useState<TableBodyMap>();
const [tableData, setTableData] = useState<TableData>();
useEffect(() => {
definitionError && setError(definitionError);
}, [definitionError]);
useEffect(() => {
if (!definitionData || definitionData.length <= 0) return;
......
......@@ -7,25 +7,21 @@ import { useTranslations } from 'next-intl';
import { useContext, useEffect, useState } from 'react';
import { AppContext } from '@/store/AppContextProvider';
import { type DefaultConfig } from '@/service/types';
import { useAuth } from 'oidc-react';
import { useQueryClient } from '@tanstack/react-query';
import { toast } from 'react-toastify';
import { genericFetch, useApiData } from '@/service/apiService';
import { useKeycloak } from '@react-keycloak/web';
const Settings = (): JSX.Element => {
const t = useTranslations('Settings');
const { userData } = useAuth();
const { keycloak } = useKeycloak();
const queryClient = useQueryClient();
const data = queryClient.getQueryData<DefaultConfig>(['defaultConfig']);
const {
data: userInfo,
error: errorUserInfo,
isLoading: isLoadingUserInfo,
} = useApiData<any>('userInfoData', `${process.env.API_URL_ACCOUNT_SERVICE}/configurations/getUserInfo`, {
headers: {
Authorization: `Bearer ${userData?.access_token}`,
},
});
const { data: userInfo, isLoading: isLoadingUserInfo } = useApiData<any>(
'userInfoData',
`${process.env.API_URL_ACCOUNT_SERVICE}/configurations/getUserInfo`,
{ headers: { Authorization: `Bearer ${keycloak.token}` } }
);
const { setError } = useContext(AppContext);
const [formData, setFormData] = useState<DefaultConfig>({
historyLimit: 0,
......@@ -38,10 +34,6 @@ const Settings = (): JSX.Element => {
}
}, [data]);
useEffect(() => {
setError && setError(errorUserInfo as Error);
}, [errorUserInfo]);
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>): void => {
const { name, value } = e.target;
setFormData(prevData => ({
......@@ -79,7 +71,7 @@ const Settings = (): JSX.Element => {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${userData?.access_token}`,
Authorization: `Bearer ${keycloak.token}`,
},
body: JSON.stringify({
language: formData.language,
......@@ -92,7 +84,7 @@ const Settings = (): JSX.Element => {
.then(async () => {
if (hasErrors) return;
await queryClient.refetchQueries({ queryKey: ['defaultConfig'] });
await queryClient.invalidateQueries({ queryKey: ['defaultConfig'] });
toast.success(t('save-success'));
})
.catch(error => {
......