edc_web_components/pages/
show_verifiable_credential.rs1use 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}