From 8aafc6b288ec9cdabf9e64fd70d987d080278f13 Mon Sep 17 00:00:00 2001 From: Jason Healy Date: Tue, 28 Jan 2020 13:09:34 +0000 Subject: [PATCH] feat: Respond to SDR request --- .../client/src/components/Avatar/Avatar.tsx | 11 ++ .../src/components/Credential/Credential.tsx | 2 +- .../client/src/components/Request/Request.tsx | 175 +++++++++++++++++- .../react-graphql/client/src/gql/mutations.ts | 6 + 4 files changed, 187 insertions(+), 7 deletions(-) create mode 100644 examples/react-graphql/client/src/components/Avatar/Avatar.tsx diff --git a/examples/react-graphql/client/src/components/Avatar/Avatar.tsx b/examples/react-graphql/client/src/components/Avatar/Avatar.tsx new file mode 100644 index 000000000..3e35033d0 --- /dev/null +++ b/examples/react-graphql/client/src/components/Avatar/Avatar.tsx @@ -0,0 +1,11 @@ +import React from 'react' +import { Box, Heading, Avatar } from 'rimble-ui' +import Page from '../../layout/Page' + +interface AvatarProps {} + +const Component: React.FC = () => { + return +} + +export default Component diff --git a/examples/react-graphql/client/src/components/Credential/Credential.tsx b/examples/react-graphql/client/src/components/Credential/Credential.tsx index 849cd3678..5cf52bfc3 100644 --- a/examples/react-graphql/client/src/components/Credential/Credential.tsx +++ b/examples/react-graphql/client/src/components/Credential/Credential.tsx @@ -20,7 +20,7 @@ const Component: React.FC = ({ onClick, detailMode, fields, jwt, iss, sub : { maxWidth: 350, style: { cursor: 'pointer' }, className: 'credential_hover' } return ( - + diff --git a/examples/react-graphql/client/src/components/Request/Request.tsx b/examples/react-graphql/client/src/components/Request/Request.tsx index 3a85da2af..2ca8b0f83 100644 --- a/examples/react-graphql/client/src/components/Request/Request.tsx +++ b/examples/react-graphql/client/src/components/Request/Request.tsx @@ -1,18 +1,142 @@ -import React from 'react' -import { Box, Heading, Avatar, Text } from 'rimble-ui' +import React, { useState, useContext, useEffect } from 'react' +import { Box, Heading, Avatar, Text, Radio, Button, Loader } from 'rimble-ui' import * as Types from '../../types' +import Credential from '../Credential/Credential' +import { AppContext } from '../../context/AppProvider' +import { useMutation } from 'react-apollo' +import * as mutations from '../../gql/mutations' +import * as queries from '../../gql/queries' + +const S = require('sugar/string') interface Props { sender: Types.Identity receiver: Types.Identity + threadId: string sdr: any } -const Component: React.FC = ({ sdr, sender, receiver }) => { +interface ValidationState { + [index: string]: { + required: boolean + jwt: string | null + } +} + +const Component: React.FC = ({ sdr, sender, receiver, threadId }) => { console.log(sdr, sender, receiver) + const [sending, updateSending] = useState(false) + const [selected, updateSelected] = useState({}) + const [formValid, setValid] = useState(true) + const [appState] = useContext(AppContext) + + const checkValidity = () => { + let valid = true + Object.keys(selected).map(key => { + if (selected[key].required && !selected[key].jwt) { + valid = false + } + }) + + setValid(valid) + } + + const [actionSendJwt] = useMutation(mutations.actionSendJwt, { + refetchQueries: [ + { + query: queries.allMessages, + variables: { activeDid: appState.defaultDid }, + }, + ], + onCompleted: response => { + if (response.actionSendJwt) { + updateSending(false) + window.toastProvider.addMessage('Response sent!', { variant: 'success' }) + } + }, + onError: response => { + window.toastProvider.addMessage('There was a problem sending your response', { variant: 'error' }) + }, + }) + const [actionSignVp] = useMutation(mutations.actionSignVp, { + onCompleted: response => { + if (response.actionSignVp) { + updateSending(true) + + actionSendJwt({ + variables: { + to: sender.did, + from: appState.defaultDid, + jwt: response.actionSignVp, + }, + }) + } + }, + }) + + const accept = () => { + if (formValid) { + const selectedVp = Object.keys(selected) + .map(key => selected[key].jwt) + .filter(item => item) + + const payload = { + variables: { + did: appState.defaultDid, + data: { + aud: sender.did, + tag: threadId, + vp: { + context: ['https://www.w3.org/2018/credentials/v1'], + type: ['VerifiableCredential'], + verifiableCredential: selectedVp, + }, + }, + }, + } + + actionSignVp(payload) + } + } + + const onSelectItem = (id: string | null, jwt: string | null, claimType: string) => { + const updatedSelection = { + ...selected, + [claimType]: { ...selected[claimType], jwt }, + } + + updateSelected(updatedSelection) + } + + useEffect(() => { + checkValidity() + }, [selected]) + + useEffect(() => { + let defaultSelected: ValidationState = {} + sdr.map((sdr: any) => { + if (sdr && sdr.essential) { + if (sdr.vc.length) { + defaultSelected[sdr.claimType] = { + required: true, + jwt: sdr.vc[0].jwt, + } + } else { + defaultSelected[sdr.claimType] = { + required: true, + jwt: null, + } + setValid(false) + } + } + }) + updateSelected(defaultSelected) + + console.log(defaultSelected) + }, []) return ( - + = ({ sdr, sender, receiver }) => { display={'flex'} flex={1} py={4} - bg={'#252731'} > {sender.shortId} - + Share your data with {sender.shortId} + {sdr.map((requestItem: any) => { + console.log(requestItem) + return ( + onSelectItem(requestItem.id, requestItem.jwt, requestItem.claimType)} + > + + {S.String.titleize(requestItem.claimType)} + + + {requestItem.reason} + + + {requestItem.vc.map((credential: any) => { + return + })} + {requestItem.vc.length === 0 && ( + + Cannot find a credential for {S.String.titleize(requestItem.claimType)} + + )} + + + ) + })} + + {sending ? ( + + ) : ( + <> + + + Later + + )} + ) } diff --git a/examples/react-graphql/client/src/gql/mutations.ts b/examples/react-graphql/client/src/gql/mutations.ts index d7d71dea8..98cde73aa 100644 --- a/examples/react-graphql/client/src/gql/mutations.ts +++ b/examples/react-graphql/client/src/gql/mutations.ts @@ -12,6 +12,12 @@ export const actionSignVc = gql` } ` +export const actionSignVp = gql` + mutation signVp($did: String!, $data: VerifiablePresentationInput!) { + actionSignVp(did: $did, data: $data) + } +` + export const actionSignSDR = gql` mutation signSDR($did: String!, $data: SDRInput!) { actionSignSDR(did: $did, data: $data)