Skip to main content

edc_web_components/pages/
show_verifiable_credential.rs

1use crate::components::{DidLabel, Identifier};
2use crate::contexts::use_edc_identity_hub_context;
3use patternfly_yew::prelude::*;
4use yew::prelude::*;
5use yew::suspense::use_future_with;
6
7#[derive(Clone, Debug, PartialEq, Properties)]
8pub struct ShowVerifiableCredentialPageProps {
9  #[prop_or("Verifiable Credential".to_string())]
10  pub title: String,
11  #[prop_or(None)]
12  pub tag_line: Option<String>,
13  pub verifiable_credential_id: String,
14}
15
16#[component]
17pub fn ShowVerifiableCredentialPage(props: &ShowVerifiableCredentialPageProps) -> Html {
18  let tag_line = props
19    .tag_line
20    .as_ref()
21    .map(|tag_line| html!(<p>{ tag_line }</p>))
22    .unwrap_or_default();
23
24  html!(
25    <>
26      <Title level={Level::H2} size={Size::XXXLarge}>{ &props.title }</Title>
27      { tag_line }
28      <Suspense fallback={html! {<Bullseye><Spinner /></Bullseye>}}>
29        <ShowVerifiableCredentialPageInner
30          verifiable_credential_id={props.verifiable_credential_id.clone()}
31        />
32      </Suspense>
33    </>
34  )
35}
36
37#[component]
38pub fn ShowVerifiableCredentialPageInner(props: &ShowVerifiableCredentialPageProps) -> HtmlResult {
39  let edc_identity_hub_context = use_edc_identity_hub_context();
40
41  let verifiable_credential = use_future_with(
42    (
43      props.verifiable_credential_id.clone(),
44      edc_identity_hub_context.clone(),
45    ),
46    |properties| async move {
47      let (verifiable_credential_id, edc_identity_hub_context) = (*properties).clone();
48      edc_identity_hub_context
49        .get_client()
50        .get_credential(
51          edc_identity_hub_context.participant_id(),
52          &verifiable_credential_id,
53        )
54        .await
55        .ok()
56    },
57  )?;
58
59  let verifiable_credential = (*verifiable_credential).clone();
60
61  if let Some(verifiable_credential) = verifiable_credential {
62    let types = verifiable_credential
63      .verifiable_credential
64      .credential
65      .r#type
66      .iter()
67      .map(|type_name| {
68        html_nested!(
69          <FlexItem>
70            <Label label={type_name.to_string()} color={Color::Blue} />
71          </FlexItem>
72        )
73      });
74
75    let credential_subjects = verifiable_credential
76      .verifiable_credential
77      .credential
78      .credential_subject
79      .iter()
80      .map(|credential_subject| {
81        html!(
82          <CodeBlock>
83            <CodeBlockCode>
84              { serde_json::to_string_pretty(credential_subject).unwrap_or_default() }
85            </CodeBlockCode>
86          </CodeBlock>
87        )
88      });
89
90    Ok(html!(
91      <DescriptionList mode={[DescriptionListMode::Horizontal]}>
92        <DescriptionGroup term="Id">
93          <Identifier id={verifiable_credential.id.to_string()} />
94        </DescriptionGroup>
95        <DescriptionGroup term="Issuer">
96          <DidLabel did={verifiable_credential.issuer_id} />
97        </DescriptionGroup>
98        <DescriptionGroup term="Holder">
99          <DidLabel did={verifiable_credential.holder_id} />
100        </DescriptionGroup>
101        <DescriptionGroup term="Insurance Date">
102          { verifiable_credential.verifiable_credential.credential.issuance_date.format("%Y-%m-%d %H:%M:%S").to_string() }
103        </DescriptionGroup>
104        <DescriptionGroup term="Expiration Date">
105          { verifiable_credential.verifiable_credential.credential.expiration_date.format("%Y-%m-%d %H:%M:%S").to_string() }
106        </DescriptionGroup>
107        <DescriptionGroup term="Name">
108          <DidLabel did={verifiable_credential.verifiable_credential.credential.name} />
109        </DescriptionGroup>
110        <DescriptionGroup term="Description">
111          { verifiable_credential.verifiable_credential.credential.description.unwrap_or_default() }
112        </DescriptionGroup>
113        <DescriptionGroup term="Types">
114          <Flex>{ for types }</Flex>
115        </DescriptionGroup>
116        <DescriptionGroup term="Credential Subjects">{ for credential_subjects }</DescriptionGroup>
117      </DescriptionList>
118    ))
119  } else {
120    Ok(html!(
121      format!(
122      "Verifiable Credential with id {} not found.",
123      props.verifiable_credential_id
124    )
125    ))
126  }
127}