edc_web_components/pages/
verifiable_credential_page.rs1use crate::components::ListVerifiableCredentials;
2use crate::contexts::use_edc_identity_hub_context;
3use crate::models::VerifiableCredential;
4use patternfly_yew::prelude::*;
5use yew::platform::spawn_local;
6use yew::prelude::*;
7use yew::suspense::use_future_with;
8
9#[derive(Clone, Debug, PartialEq, Properties)]
10pub struct VerifiableCredentialPageProps {
11 #[prop_or("My Wallet".to_string())]
12 pub title: String,
13 #[prop_or(None)]
14 pub tag_line: Option<String>,
15 #[prop_or("Request a Verifiable Credential".to_string())]
16 pub create_title: String,
17 pub on_new_verifiable_credential: Callback<()>,
18 pub onshow: Callback<String>,
19}
20
21#[component]
22pub fn VerifiableCredentialPage(props: &VerifiableCredentialPageProps) -> Html {
23 let refresh = use_state(|| 0usize);
24
25 let edc_identity_hub_context = use_edc_identity_hub_context();
26
27 let ondelete = use_callback(
28 (refresh.clone(), edc_identity_hub_context),
29 |verifiable_credential_id: String, (refresh, edc_identity_hub_context)| {
30 let refresh = refresh.clone();
31 let verifiable_credential_id = verifiable_credential_id.clone();
32 let edc_identity_hub_context = edc_identity_hub_context.clone();
33
34 spawn_local(async move {
35 let identity_hub_client = edc_identity_hub_context.get_client();
36
37 identity_hub_client
38 .delete_credential(
39 edc_identity_hub_context.participant_id(),
40 &verifiable_credential_id,
41 )
42 .await
43 .unwrap_or_default();
44
45 log::warn!(
46 "Deleted Verifiable Credential {} - {}",
47 verifiable_credential_id,
48 *refresh + 1
49 );
50 refresh.set(*refresh + 1);
51 });
52 },
53 );
54
55 let onclick = use_callback(
56 props.on_new_verifiable_credential.clone(),
57 |_, on_new_verifiable_credential| {
58 on_new_verifiable_credential.emit(());
59 },
60 );
61
62 let tag_line = props
63 .tag_line
64 .as_ref()
65 .map(|tag_line| html!(<p>{ tag_line }</p>))
66 .unwrap_or_default();
67
68 html!(
69 <Stack gutter=true>
70 <StackItem>
71 <Split gutter=true>
72 <SplitItem fill=true>
73 <Title level={Level::H3} size={Size::XXLarge}>{ &props.title }</Title>
74 { tag_line }
75 </SplitItem>
76 <SplitItem>
77 <Button icon={Icon::Plus} {onclick} variant={ButtonVariant::Primary}>
78 { &props.create_title }
79 </Button>
80 </SplitItem>
81 </Split>
82 </StackItem>
83 <StackItem>
84 <Suspense>
85 <VerifiableCredentialPageInner
86 {ondelete}
87 onshow={props.onshow.clone()}
88 force_refresh={*refresh}
89 />
90 </Suspense>
91 </StackItem>
92 </Stack>
93 )
94}
95
96#[derive(Clone, Debug, PartialEq, Properties)]
97pub struct VerifiableCredentialPageInnerProps {
98 pub ondelete: Callback<String>,
99 pub onshow: Callback<String>,
100 pub force_refresh: usize,
101}
102
103#[component]
104pub fn VerifiableCredentialPageInner(props: &VerifiableCredentialPageInnerProps) -> HtmlResult {
105 let edc_identity_hub_context = use_edc_identity_hub_context();
106
107 let verifiable_credential_items = use_future_with(
108 (edc_identity_hub_context, props.force_refresh),
109 |parameters| async move {
110 let (edc_identity_hub_context, _) = (*parameters).clone();
111 let identity_hub_client = edc_identity_hub_context.get_client();
112
113 identity_hub_client
114 .get_credentials(edc_identity_hub_context.participant_id())
115 .await
116 .unwrap_or_default()
117 .into_iter()
118 .map(VerifiableCredential::from)
119 .collect::<Vec<_>>()
120 },
121 )?;
122
123 let verifiable_credential_items = (*verifiable_credential_items).clone();
124
125 Ok(html!(
126 <ListVerifiableCredentials
127 verifiable_credential_items={verifiable_credential_items}
128 ondelete={props.ondelete.clone()}
129 onshow={props.onshow.clone()}
130 />
131 ))
132}