Skip to content
This repository has been archived by the owner on Mar 14, 2024. It is now read-only.

Commit

Permalink
Add list credential functionality with frontend search
Browse files Browse the repository at this point in the history
  • Loading branch information
mattdean-digicatapult committed Mar 29, 2022
1 parent 9a2828c commit 2ac217e
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 9 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "veritable-authority",
"version": "0.1.2",
"version": "0.2.2",
"description": "Front-end for Veritable authority",
"author": "Digital Catapult (https://www.digicatapult.org.uk/)",
"license": "Apache-2.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,99 @@
/**
* This function is responsible for rendering the left content column of the screen.
* @returns The `ColumnLeftWrap` component returns a `div` element with a `div`
* element inside of it.
* This function is used to display issued credential records log
*/
import { useEffect, useState } from 'react'
import IssuedRecordItem from '../IssuedRecordItem'
import useGetIssueCredentialRecords from '../../../../interface/hooks/use-get-looped-issue-credential-records'

export default function ColumnLeftWrap({ origin }) {
const [dataRecords, setDataRecords] = useState([])
const [flyerIdSearch, setFlyerIdSearch] = useState('')
const [statusRecords, errorRecords, startGetRecordsHandler] =
useGetIssueCredentialRecords()
useEffect(() => {
const setStoreDataFn = (resData) => setDataRecords(resData)
const intervalIdFetch = startGetRecordsHandler(origin, setStoreDataFn)
if (statusRecords !== 'started') clearInterval(intervalIdFetch)
return function clear() {
return clearInterval(intervalIdFetch)
}
}, [origin, statusRecords, startGetRecordsHandler])

const inputNameHandler = (e) => {
setFlyerIdSearch(e.target.value)
}

const renderedRecords = dataRecords.filter((record) => {
const flyerId = record.cred_ex_record.cred_preview.attributes[0].value
return flyerId.indexOf(flyerIdSearch) !== -1
})

export default function ColumnLeftWrap() {
return (
<>
<div className="col-md-6">
<div className="container py-1">
<div className="row">
<div className="col-md-12">
<h5>Enter Flyer ID</h5>
<p className="small">View all certificates for a flyer ID</p>
<h5>Issued Licenses</h5>
<p className="small">Search for issued licenses by flyer ID</p>
<input
type="text"
value={flyerIdSearch}
onChange={inputNameHandler}
required
className="form-control"
id="name"
placeholder="GBR-RP-123456"
/>
<div className="container py-3">
<div className="accordion" id="accordion">
{renderedRecords.length === 0 && (
<p className="small">No credentials found</p>
)}

{renderedRecords.length > 0 && (
<>
<div className="card m-0 p-0"></div>
</>
)}

{renderedRecords.map((r, i) => (
<div key={r.cred_ex_record.cred_ex_id} className="card">
<IssuedRecordItem record={r} index={i} />
</div>
))}

{renderedRecords.length > 0 && (
<>
<div className="card m-0 p-0"></div>
</>
)}
</div>
</div>
</div>
</div>
</div>
</div>

<div
className={errorRecords ? 'd-block' : 'd-none'}
style={{
position: 'fixed',
width: '10%',
height: '10%',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0,0,0,0.5)',
zIndex: 100,
}}
>
<div className="text-light m-2 p-2">
{' '}
<small>{errorRecords}</small>{' '}
</div>
</div>
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/**
* This function renders a single issued credential record.
* @returns A card with the following: Header; Collapsible body;
* Table; Details link
*/
import ReactJson from 'react-json-view'

const lookupRecordType = new Map([['2', 'A2 Open Category']])

export default function IssuedRecordItem({ record, index }) {
return (
<>
<div className="card-header" id={`heading${index}`}>
<div className="mb-0">
<button
className="btn btn-link text-left w-100"
type="button"
data-toggle="collapse"
data-target={`#collapse${index}`}
aria-expanded="false"
aria-controls={`collapse${index}`}
>
<span>
<i className="fa fa-sort"></i>
&nbsp; Issued Credential #{index + 1}
</span>
</button>
</div>
</div>
<div
className="collapse"
id={`collapse${index}`}
aria-labelledby={`heading${index}`}
data-parent="#accordion"
>
<div className="card-body">
<div className="table-responsive">
<table className="table table-striped">
<tbody>
<tr>
<td>
<b>Flyer ID:</b>
</td>
<td>
{record.cred_ex_record.cred_preview.attributes[0].value}
</td>
</tr>
<tr>
<td>
<b>Type:</b>
</td>
<td>
{lookupRecordType.get(
record.cred_ex_record.cred_preview.attributes[1].value
)}
</td>
</tr>
<tr>
<td>
<b>Expiration Date:</b>
</td>
<td>
{record.cred_ex_record.cred_preview.attributes[2].value}
</td>
</tr>
<tr>
<td>
<b>Created At:</b>
</td>
<td>{record.cred_ex_record.created_at.replace('Z', '')}</td>
</tr>
<tr>
<td>
<b>Update At:</b>
</td>
<td>{record.cred_ex_record.updated_at.replace('Z', '')}</td>
</tr>
</tbody>
</table>
</div>

<a
href={`#details${index}`}
className="text-primary"
data-toggle="collapse"
>
Details
</a>
<div id={`details${index}`} className="my-2 collapse">
<div className="pre-scrollable bg-light" style={{ height: 200 }}>
<ReactJson
src={record}
style={{ fontSize: '0.75em' }}
name={'record'}
displayDataTypes={false}
displayObjectSize={false}
iconStyle={'square'}
indentWidth={2}
/>
</div>
</div>
</div>
</div>
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './IssuedRecordItem'
30 changes: 30 additions & 0 deletions src/interface/hooks/use-get-looped-issue-credential-records.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* This function returns continuously the issue credentials records
*/
import { useCallback, useState } from 'react'
import getLooped from '../api/helpers/get-looped'

export default function useGetIssueCredentialRecords() {
const path = '/issue-credential-2.0/records'
const transformData = (retrievedData) => retrievedData.results
const statusOptions = ['started', 'error', 'stopped']
const [status, setStatus] = useState(statusOptions[0])
const [error, setError] = useState(null)
const onStartFetch = useCallback((origin, setStoreData) => {
const params = {}
const intervalId = setInterval(() => {
/* From: https://codesandbox.io/s/useinterval-nylhv */
getLooped(
origin,
path,
params,
setStatus,
setError,
setStoreData,
transformData
)
}, 1000)
return intervalId
}, [])
return [status, error, onStartFetch]
}

0 comments on commit 2ac217e

Please sign in to comment.