Thanks for pushing me in the right direction. I was able to make it work with plain solid-client
and solid-ui-react
. Also @inrupt/vocab-common-rdf
is a very useful package!
Maybe it is helpful for someone else:
App.js component
import React, { useEffect, useState } from 'react'
import {
LoginButton,
LogoutButton,
CombinedDataProvider,
Text,
Image
} from '@inrupt/solid-ui-react'
import {
getSolidDataset,
getThing,
getUrl,
getUrlAll,
getStringNoLocale
} from '@inrupt/solid-client'
import { FOAF, VCARD, RDF } from '@inrupt/vocab-common-rdf'
import { handleIncomingRedirect, fetch } from '@inrupt/solid-client-authn-browser'
import _ from 'lodash'
import Emails from './Emails'
const App = () => {
const [idp] = useState('https://broker.pod.inrupt.com')
const [currentUrl] = useState("http://localhost:8080")
const [auth, setAuth] = useState(false)
const [profile, setProfile] = useState(false)
const [dataset, setDataset] = useState(false)
const logout = () => {
setAuth(false)
}
useEffect(() => {
handleIncomingRedirect({
restorePreviousSession: true
}).then(async info => {
setAuth(info)
console.log(`Logged in with WebID [${info.webId}]`)
})
}, [])
useEffect(async () => {
if (!auth.webId) {
return
}
setDataset(
await getSolidDataset(
auth.webId,
{ fetch: fetch }
)
)
}, [auth.webId])
useEffect(() => {
if (!auth.webId || !dataset) {
setProfile(false)
return
}
setProfile(
getThing(dataset, auth.webId)
)
}, [auth.webId, dataset])
const renderEmails = () => {
if (!profile) {
return
}
const emailAddressUrls = getUrlAll(profile, VCARD.hasEmail)
const emailAddressThings = emailAddressUrls.map(url => getThing(dataset, url))
const workEmailAddressThing = emailAddressThings.find(thing => getUrl(thing, RDF.type) === VCARD.Work)
const workEmailAddress = getUrl(workEmailAddressThing, VCARD.value)
const homeEmailAddressThing = emailAddressThings.find(thing => getUrl(thing, RDF.type) === VCARD.Home)
const homeEmailAddress = getUrl(homeEmailAddressThing, VCARD.value)
return (
<>
Work: {workEmailAddress}<br />
Home: {homeEmailAddress}<br />
</>
)
}
const renderInfo = () => profile &&
<div>
<strong>Using solid-client</strong><br />
FOAF.name: {getStringNoLocale(profile, FOAF.name)}<br />
VCARD.fn: {getStringNoLocale(profile, VCARD.fn)}<br />
VCARD.role: {getStringNoLocale(profile, VCARD.role)}<br />
VCARD.organization_name: {getStringNoLocale(profile, VCARD.organization_name)}<br />
VCARD.hasPhoto:<br />
<img src={getUrl(profile, VCARD.hasPhoto)}/><br />
{renderEmails()}
</div>
return (
<div>
<LoginButton
authOptions={{ clientName: 'test' }}
oidcIssuer={idp}
redirectUrl={currentUrl}
onError={console.error}
></LoginButton>
<LogoutButton
onLogout={logout}
></LogoutButton>
{auth.isLoggedIn ? 'yes' : 'no'}<br />
{renderInfo()}
<strong>Using solid-ui-react</strong><br />
<CombinedDataProvider
datasetUrl={auth.webId}
thingUrl={auth.webId}
>
FOAF.name: <Text property={FOAF.name} /><br />
VCARD.fn: <Text property={VCARD.fn} /><br />
VCARD.role: <Text property={VCARD.role} /><br />
VCARD.organization_name: <Text property={VCARD.organization_name} /><br />
VCARD.photo:<br /><Image property={VCARD.hasPhoto} width={480} /><br />
<Emails></Emails>
</CombinedDataProvider>
</div>
)
}
export default App
emails.js component
import { getThing, getUrl, getUrlAll } from '@inrupt/solid-client'
import { DatasetContext, useThing, CombinedDataProvider, Value } from '@inrupt/solid-ui-react'
import React, { useContext } from 'react'
import { RDF, VCARD } from '@inrupt/vocab-common-rdf'
const emails = () => {
const { solidDataset } = useContext(DatasetContext)
const { thing } = useThing()
const contactDetailUrls = getUrlAll(thing, VCARD.hasEmail)
const contactDetailThings = contactDetailUrls.map((url) => ({
solidDataset,
thing: getThing(solidDataset, url)
}));
const getLabel = (thing, type) => {
switch(getUrl(thing, type)) {
case VCARD.Work:
return 'Work'
case VCARD.Home:
return 'Home'
default:
return
}
}
return contactDetailThings.map((contactDetailThing, index) =>
<React.Fragment key={index}>
<CombinedDataProvider
solidDataset={contactDetailThing.solidDataset}
thing={contactDetailThing.thing}
>
{getLabel(contactDetailThing.thing, RDF.type)}
<Value dataType="url" property={VCARD.value} />
</CombinedDataProvider><br/>
</React.Fragment>
)
}
export default emails