From e821b0e808d88b0e8fc8b540fb0fdaf35975819d Mon Sep 17 00:00:00 2001 From: Anton Bergman Date: Thu, 4 Jul 2024 15:37:44 +0800 Subject: [PATCH 1/7] feat: simpliy (?) issuance page --- generator/nextjs/template/package-lock.json | 25 ++ generator/nextjs/template/package.json | 1 + generator/nextjs/template/src/pages/_app.tsx | 13 +- .../src/pages/credential-issuance.tsx | 297 +++++++++--------- generator/nextjs/template/src/services/api.ts | 24 ++ 5 files changed, 199 insertions(+), 161 deletions(-) create mode 100644 generator/nextjs/template/src/services/api.ts diff --git a/generator/nextjs/template/package-lock.json b/generator/nextjs/template/package-lock.json index 81c2f94..b9f621c 100644 --- a/generator/nextjs/template/package-lock.json +++ b/generator/nextjs/template/package-lock.json @@ -15,6 +15,7 @@ "@affinidi-tdk/iota-browser": "^1.0.0", "@affinidi-tdk/iota-client": "^1.4.0", "@affinidi-tdk/iota-core": "^1.0.0", + "@tanstack/react-query": "^5.49.2", "next": "^14.2.4", "next-auth": "^4.24.3", "qrcode.react": "^3.1.0", @@ -2524,6 +2525,30 @@ "tslib": "^2.4.0" } }, + "node_modules/@tanstack/query-core": { + "version": "5.49.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.49.1.tgz", + "integrity": "sha512-JnC9ndmD1KKS01Rt/ovRUB1tmwO7zkyXAyIxN9mznuJrcNtOrkmOnQqdJF2ib9oHzc2VxHomnEG7xyfo54Npkw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.49.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.49.2.tgz", + "integrity": "sha512-6rfwXDK9BvmHISbNFuGd+wY3P44lyW7lWiA9vIFGT/T0P9aHD1VkjTvcM4SDAIbAQ9ygEZZoLt7dlU1o3NjMVA==", + "dependencies": { + "@tanstack/query-core": "5.49.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", diff --git a/generator/nextjs/template/package.json b/generator/nextjs/template/package.json index 2eaee0f..415bf5d 100644 --- a/generator/nextjs/template/package.json +++ b/generator/nextjs/template/package.json @@ -15,6 +15,7 @@ "@affinidi-tdk/iota-browser": "^1.0.0", "@affinidi-tdk/iota-client": "^1.4.0", "@affinidi-tdk/iota-core": "^1.0.0", + "@tanstack/react-query": "^5.49.2", "next": "^14.2.4", "next-auth": "^4.24.3", "qrcode.react": "^3.1.0", diff --git a/generator/nextjs/template/src/pages/_app.tsx b/generator/nextjs/template/src/pages/_app.tsx index 929f18f..7cd39f7 100644 --- a/generator/nextjs/template/src/pages/_app.tsx +++ b/generator/nextjs/template/src/pages/_app.tsx @@ -3,17 +3,22 @@ import type { AppProps } from "next/app"; import NavBar from "src/components/NavBar"; import "../styles/globals.css"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; export default function App({ Component, pageProps: { session, ...pageProps }, }: AppProps) { + const queryClient = new QueryClient(); + return ( - -
- -
+ + +
+ +
+
); } diff --git a/generator/nextjs/template/src/pages/credential-issuance.tsx b/generator/nextjs/template/src/pages/credential-issuance.tsx index 68976c8..2d09a8d 100644 --- a/generator/nextjs/template/src/pages/credential-issuance.tsx +++ b/generator/nextjs/template/src/pages/credential-issuance.tsx @@ -2,16 +2,22 @@ import { IssuanceConfigDtoCredentialSupportedInner, StartIssuanceInputClaimModeEnum, } from "@affinidi-tdk/credential-issuance-client"; +import { useQuery } from "@tanstack/react-query"; import { GetServerSideProps, InferGetServerSidePropsType } from "next"; import { useSession } from "next-auth/react"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import Message from "src/components/Message"; import Button from "src/components/core/Button"; -import Select, { SelectOption } from "src/components/core/Select"; -import DynamicForm, { FormSchema } from "src/components/issuance/DynamicForm"; +import Select from "src/components/core/Select"; +import DynamicForm from "src/components/issuance/DynamicForm"; import Offer from "src/components/issuance/Offer"; import { personalAccessTokenConfigured } from "src/lib/env"; import { MessagePayload, OfferPayload } from "src/types/types"; +import { + fetchCredentialSchema, + fetchCredentialTypes, + fetchIssuanceConfigurations, +} from "../services/api"; const claimModeOptions = [ { @@ -29,121 +35,68 @@ export const getServerSideProps = (async () => { export default function CredentialIssuance({ featureAvailable, }: InferGetServerSidePropsType) { - const [holderDid, setHolderDid] = useState(""); - const [configOptions, setConfigOptions] = useState([]); - const [selectedConfig, setSelectedConfig] = useState(""); - const [types, setTypes] = useState< - IssuanceConfigDtoCredentialSupportedInner[] - >([]); - const [typeOptions, setTypeOptions] = useState([]); - const [selectedType, setSelectedType] = useState(""); - const [formProperties, setFormProperties] = useState(); + const [formData, setFormData] = useState<{ + selectedConfigId: string; + selectedTypeId: string; + }>({ selectedConfigId: "", selectedTypeId: "" }); const [isFormDisabled, setIsFormDisabled] = useState(false); const [offer, setOffer] = useState(); const [message, setMessage] = useState(); const [claimMode, setClaimMode] = useState( - StartIssuanceInputClaimModeEnum.TxCode, + StartIssuanceInputClaimModeEnum.TxCode ); - // Prefill did from session + const { selectedConfigId, selectedTypeId } = formData; + + // Get did from session const { data: session } = useSession(); - useEffect(() => { - if (!session || !session.user) return; - setHolderDid(session.userId); - }, [session]); - useEffect(() => { - const initConfigurations = async () => { - try { - const response = await fetch("/api/issuance/configuration-options", { - method: "GET", + const configurations = useQuery({ + queryKey: ["configurations"], + queryFn: fetchIssuanceConfigurations, + enabled: !!featureAvailable, + }); + + const credentialTypes = useQuery({ + queryKey: ["types", selectedConfigId], + queryFn: ({ queryKey }) => fetchCredentialTypes(queryKey[1]), + enabled: !!selectedConfigId, + }); + + const schema = useQuery({ + queryKey: ["schema", selectedTypeId], + queryFn: () => { + const credentialType = credentialTypes.data?.find( + (type) => type.credentialTypeId === selectedTypeId + ); + if (!credentialType) { + setMessage({ + message: "Unable to fetch credential schema to build the form", + type: "error", }); - const configurations = await response.json(); - console.log(configurations); - setConfigOptions(configurations); - } catch (error) { - console.error("Error getting issuance configurations:", error); + return; } - }; - if (featureAvailable) { - initConfigurations(); - } - }, [featureAvailable]); - - async function handleConfigurationChange(value: string | number) { - const configId = value as string; - clearIssuance(); - setTypeOptions([]); - setTypes([]); - setSelectedConfig(configId); - if (!configId) { - return; - } - const response = await fetch( - "/api/issuance/credential-types?" + - new URLSearchParams({ issuanceConfigurationId: configId }), - { - method: "GET", - }, - ); - const credentialTypes = await response.json(); - console.log(credentialTypes); - const credentialTypeOptions = credentialTypes.map( - (type: IssuanceConfigDtoCredentialSupportedInner) => ({ - label: type.credentialTypeId, - value: type.credentialTypeId, - }), - ); - setTypes(credentialTypes); - setTypeOptions(credentialTypeOptions); - } - - async function handleCredentialTypeChange(value: string | number) { - clearIssuance(); - setSelectedType(value as string); - if (!value) { - return; - } - const credentialType = types.find( - (type) => type.credentialTypeId === value, - ); - if (!credentialType) { - setMessage({ - message: "Unable to fetch credential schema to build the form", - type: "error", - }); - return; - } - const response = await fetch(credentialType.jsonSchemaUrl, { - method: "GET", - }); - const schema = await response.json(); - console.log(schema); - setFormProperties(schema.properties.credentialSubject); - console.log(formProperties); - } + return fetchCredentialSchema(credentialType.jsonSchemaUrl); + }, + enabled: !!selectedTypeId, + }); - function handleClaimModeChange(value: string | number) { - setClaimMode(value as string); - } + console.log({ + selectedConfigId, + configurations: configurations.data, + credentialTypes: credentialTypes.data, + schema: schema.data, + }); const handleSubmit = async (credentialData: any) => { - console.log(credentialData); - if (!selectedType) { - setMessage({ - message: "Holder's DID and Credential Type ID are required", - type: "error", - }); - return; - } console.log("credentialData:", credentialData); setIsFormDisabled(true); const response = await fetch("/api/issuance/start", { method: "POST", body: JSON.stringify({ credentialData, - credentialTypeId: selectedType, + credentialTypeId: selectedTypeId, claimMode, }), headers: { @@ -170,80 +123,108 @@ export default function CredentialIssuance({ setOffer(undefined); setIsFormDisabled(false); setMessage(undefined); - setFormProperties(undefined); - setSelectedType(""); + setFormData({ selectedConfigId: "", selectedTypeId: "" }); } - return ( - <> -

Issue Credentials

- - {!featureAvailable && ( + const hasErrors = !featureAvailable || !session || !session.userId; + const renderErrors = () => { + if (!featureAvailable) { + return (
Feature not available. Please set your Personal Access Token in your environment secrets.
- )} + ); + } - {featureAvailable && !holderDid && ( + if (!session || !session.userId) { + return (
You must be logged in to issue credentials to your Affinidi Vault
- )} - - {featureAvailable && holderDid && ( - <> -
-

- Verified holder did (From Affinidi Login) -

-

{holderDid}

-
- - {offer && ( -
- - -
- )} + ); + } + }; - {!offer && configOptions.length === 0 && ( -
Loading configurations...
- )} + const renderVerifiedHolder = (userId: string) => { + return ( +
+

+ Verified holder did (From Affinidi Login) +

+

{userId}

+
+ ); + }; - {!offer && configOptions.length > 0 && ( - - {typeOptions.length === 0 && ( -
Loading credential types...
+ {configurations.isLoading &&
Loading configurations...
} + {!configurations.isLoading && ( + setClaimMode(val as string)} + /> + )} + {credentialTypes.isLoading && ( +
Loading credential types...
+ )} + {credentialTypes.data && credentialTypes.data.length > 0 && ( ({ - label: type.credentialTypeId, - value: type.credentialTypeId, - }) - )} + options={ + credentialTypes.data?.map( + (type: IssuanceConfigDtoCredentialSupportedInner) => ({ + label: type.credentialTypeId, + value: type.credentialTypeId, + }) + ) || [] + } value={selectedTypeId} disabled={isFormDisabled} onChange={(value) => diff --git a/generator/nextjs/template/src/services/api.ts b/generator/nextjs/template/src/services/api.ts deleted file mode 100644 index 9e39686..0000000 --- a/generator/nextjs/template/src/services/api.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { IssuanceConfigDtoCredentialSupportedInner } from "@affinidi-tdk/credential-issuance-client"; -import { SelectOption } from "src/components/core/Select"; - -export const fetchCredentialSchema = async (jsonSchemaUrl: string) => { - const response = await fetch(jsonSchemaUrl, { - method: "GET", - }); - const schema = await response.json(); - return schema; -}; - -export const fetchCredentialTypes = ( - issuanceConfigurationId: string -): Promise => - fetch( - "/api/issuance/credential-types?" + - new URLSearchParams({ issuanceConfigurationId }), - { method: "GET" } - ).then((res) => res.json()); - -export const fetchIssuanceConfigurations = (): Promise => - fetch("/api/issuance/configuration-options", { method: "GET" }).then((res) => - res.json() - ); diff --git a/package.json b/package.json index dcbeba3..e35a26b 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "install:affinidi-java-springboot": "cd samples/affinidi-java-springboot && sh mvnw install", "start": "concurrently -n w: \"npm:start:*(!template)\"", "start:template": "npm run --prefix generator/template dev -- -p 3000", - "start:affinidi-nextjs-nextauthjs": "npm run --prefix samples/affinidi-nextjs-nextauthjs dev -- -p 3001", + "start:affinidi-nextjs-nextauthjs": "npm run --prefix samples/affinidi-nextjs-nextauthjs dev -- -p 3000", "start:auth0-nextjs-nextauthjs": "npm run --prefix samples/auth0-nextjs-nextauthjs dev -- -p 3002", "start:affinidi-django-authlib": "python3 samples/affinidi-django-authlib/manage.py migrate && python3 samples/affinidi-django-authlib/manage.py runserver 8000", "start:auth0-django-authlib": "python3 samples/auth0-django-authlib/manage.py migrate && python3 samples/auth0-django-authlib/manage.py runserver 8001", diff --git a/samples/affinidi-nextjs-nextauthjs/package-lock.json b/samples/affinidi-nextjs-nextauthjs/package-lock.json index 136254a..1cc359f 100644 --- a/samples/affinidi-nextjs-nextauthjs/package-lock.json +++ b/samples/affinidi-nextjs-nextauthjs/package-lock.json @@ -15,6 +15,7 @@ "@affinidi-tdk/iota-browser": "^1.0.0", "@affinidi-tdk/iota-client": "^1.4.0", "@affinidi-tdk/iota-core": "^1.0.0", + "@tanstack/react-query": "^5.49.2", "next": "^14.2.4", "next-auth": "^4.24.3", "qrcode.react": "^3.1.0", @@ -2524,6 +2525,30 @@ "tslib": "^2.4.0" } }, + "node_modules/@tanstack/query-core": { + "version": "5.49.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.49.1.tgz", + "integrity": "sha512-JnC9ndmD1KKS01Rt/ovRUB1tmwO7zkyXAyIxN9mznuJrcNtOrkmOnQqdJF2ib9oHzc2VxHomnEG7xyfo54Npkw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.49.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.49.2.tgz", + "integrity": "sha512-6rfwXDK9BvmHISbNFuGd+wY3P44lyW7lWiA9vIFGT/T0P9aHD1VkjTvcM4SDAIbAQ9ygEZZoLt7dlU1o3NjMVA==", + "dependencies": { + "@tanstack/query-core": "5.49.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", diff --git a/samples/affinidi-nextjs-nextauthjs/package.json b/samples/affinidi-nextjs-nextauthjs/package.json index 182aa3c..238c480 100644 --- a/samples/affinidi-nextjs-nextauthjs/package.json +++ b/samples/affinidi-nextjs-nextauthjs/package.json @@ -15,6 +15,7 @@ "@affinidi-tdk/iota-browser": "^1.0.0", "@affinidi-tdk/iota-client": "^1.4.0", "@affinidi-tdk/iota-core": "^1.0.0", + "@tanstack/react-query": "^5.49.2", "next": "^14.2.4", "next-auth": "^4.24.3", "qrcode.react": "^3.1.0", diff --git a/samples/affinidi-nextjs-nextauthjs/src/pages/_app.tsx b/samples/affinidi-nextjs-nextauthjs/src/pages/_app.tsx index 929f18f..7cd39f7 100644 --- a/samples/affinidi-nextjs-nextauthjs/src/pages/_app.tsx +++ b/samples/affinidi-nextjs-nextauthjs/src/pages/_app.tsx @@ -3,17 +3,22 @@ import type { AppProps } from "next/app"; import NavBar from "src/components/NavBar"; import "../styles/globals.css"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; export default function App({ Component, pageProps: { session, ...pageProps }, }: AppProps) { + const queryClient = new QueryClient(); + return ( - -
- -
+ + +
+ +
+
); } diff --git a/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx b/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx index 68976c8..5d46cdb 100644 --- a/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx +++ b/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx @@ -2,13 +2,14 @@ import { IssuanceConfigDtoCredentialSupportedInner, StartIssuanceInputClaimModeEnum, } from "@affinidi-tdk/credential-issuance-client"; +import { useQuery } from "@tanstack/react-query"; import { GetServerSideProps, InferGetServerSidePropsType } from "next"; import { useSession } from "next-auth/react"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import Message from "src/components/Message"; import Button from "src/components/core/Button"; import Select, { SelectOption } from "src/components/core/Select"; -import DynamicForm, { FormSchema } from "src/components/issuance/DynamicForm"; +import DynamicForm from "src/components/issuance/DynamicForm"; import Offer from "src/components/issuance/Offer"; import { personalAccessTokenConfigured } from "src/lib/env"; import { MessagePayload, OfferPayload } from "src/types/types"; @@ -22,6 +23,28 @@ const claimModeOptions = [ }, ]; +const fetchCredentialSchema = async (jsonSchemaUrl: string) => { + const response = await fetch(jsonSchemaUrl, { + method: "GET", + }); + const schema = await response.json(); + return schema; +}; + +const fetchCredentialTypes = ( + issuanceConfigurationId: string +): Promise => + fetch( + "/api/issuance/credential-types?" + + new URLSearchParams({ issuanceConfigurationId }), + { method: "GET" } + ).then((res) => res.json()); + +const fetchIssuanceConfigurations = (): Promise => + fetch("/api/issuance/configuration-options", { method: "GET" }).then((res) => + res.json() + ); + export const getServerSideProps = (async () => { return { props: { featureAvailable: personalAccessTokenConfigured() } }; }) satisfies GetServerSideProps<{ featureAvailable: boolean }>; @@ -29,121 +52,68 @@ export const getServerSideProps = (async () => { export default function CredentialIssuance({ featureAvailable, }: InferGetServerSidePropsType) { - const [holderDid, setHolderDid] = useState(""); - const [configOptions, setConfigOptions] = useState([]); - const [selectedConfig, setSelectedConfig] = useState(""); - const [types, setTypes] = useState< - IssuanceConfigDtoCredentialSupportedInner[] - >([]); - const [typeOptions, setTypeOptions] = useState([]); - const [selectedType, setSelectedType] = useState(""); - const [formProperties, setFormProperties] = useState(); + const [formData, setFormData] = useState<{ + selectedConfigId: string; + selectedTypeId: string; + }>({ selectedConfigId: "", selectedTypeId: "" }); const [isFormDisabled, setIsFormDisabled] = useState(false); const [offer, setOffer] = useState(); const [message, setMessage] = useState(); const [claimMode, setClaimMode] = useState( - StartIssuanceInputClaimModeEnum.TxCode, + StartIssuanceInputClaimModeEnum.TxCode ); - // Prefill did from session + const { selectedConfigId, selectedTypeId } = formData; + + // Get did from session const { data: session } = useSession(); - useEffect(() => { - if (!session || !session.user) return; - setHolderDid(session.userId); - }, [session]); - useEffect(() => { - const initConfigurations = async () => { - try { - const response = await fetch("/api/issuance/configuration-options", { - method: "GET", - }); - const configurations = await response.json(); - console.log(configurations); - setConfigOptions(configurations); - } catch (error) { - console.error("Error getting issuance configurations:", error); - } - }; - if (featureAvailable) { - initConfigurations(); - } - }, [featureAvailable]); + const configurations = useQuery({ + queryKey: ["configurations"], + queryFn: fetchIssuanceConfigurations, + enabled: !!featureAvailable, + }); - async function handleConfigurationChange(value: string | number) { - const configId = value as string; - clearIssuance(); - setTypeOptions([]); - setTypes([]); - setSelectedConfig(configId); - if (!configId) { - return; - } - const response = await fetch( - "/api/issuance/credential-types?" + - new URLSearchParams({ issuanceConfigurationId: configId }), - { - method: "GET", - }, - ); - const credentialTypes = await response.json(); - console.log(credentialTypes); - const credentialTypeOptions = credentialTypes.map( - (type: IssuanceConfigDtoCredentialSupportedInner) => ({ - label: type.credentialTypeId, - value: type.credentialTypeId, - }), - ); - setTypes(credentialTypes); - setTypeOptions(credentialTypeOptions); - } + const credentialTypes = useQuery({ + queryKey: ["types", selectedConfigId], + queryFn: ({ queryKey }) => fetchCredentialTypes(queryKey[1]), + enabled: !!selectedConfigId, + }); - async function handleCredentialTypeChange(value: string | number) { - clearIssuance(); - setSelectedType(value as string); - if (!value) { - return; - } - const credentialType = types.find( - (type) => type.credentialTypeId === value, - ); - if (!credentialType) { - setMessage({ - message: "Unable to fetch credential schema to build the form", - type: "error", - }); - return; - } + const schema = useQuery({ + queryKey: ["schema", selectedTypeId], + queryFn: () => { + const credentialType = credentialTypes.data?.find( + (type) => type.credentialTypeId === selectedTypeId + ); + if (!credentialType) { + setMessage({ + message: "Unable to fetch credential schema to build the form", + type: "error", + }); + return; + } - const response = await fetch(credentialType.jsonSchemaUrl, { - method: "GET", - }); - const schema = await response.json(); - console.log(schema); - setFormProperties(schema.properties.credentialSubject); - console.log(formProperties); - } + return fetchCredentialSchema(credentialType.jsonSchemaUrl); + }, + enabled: !!selectedTypeId, + }); - function handleClaimModeChange(value: string | number) { - setClaimMode(value as string); - } + console.log({ + selectedConfigId, + configurations: configurations.data, + credentialTypes: credentialTypes.data, + schema: schema.data, + }); const handleSubmit = async (credentialData: any) => { - console.log(credentialData); - if (!selectedType) { - setMessage({ - message: "Holder's DID and Credential Type ID are required", - type: "error", - }); - return; - } console.log("credentialData:", credentialData); setIsFormDisabled(true); const response = await fetch("/api/issuance/start", { method: "POST", body: JSON.stringify({ credentialData, - credentialTypeId: selectedType, + credentialTypeId: selectedTypeId, claimMode, }), headers: { @@ -170,80 +140,110 @@ export default function CredentialIssuance({ setOffer(undefined); setIsFormDisabled(false); setMessage(undefined); - setFormProperties(undefined); - setSelectedType(""); + setFormData({ selectedConfigId: "", selectedTypeId: "" }); } - return ( - <> -

Issue Credentials

- - {!featureAvailable && ( + const hasErrors = !featureAvailable || !session || !session.userId; + const renderErrors = () => { + if (!featureAvailable) { + return (
Feature not available. Please set your Personal Access Token in your environment secrets.
- )} + ); + } - {featureAvailable && !holderDid && ( + if (!session || !session.userId) { + return (
You must be logged in to issue credentials to your Affinidi Vault
- )} - - {featureAvailable && holderDid && ( - <> -
-

- Verified holder did (From Affinidi Login) -

-

{holderDid}

-
- - {offer && ( -
- - -
- )} + ); + } + }; - {!offer && configOptions.length === 0 && ( -
Loading configurations...
- )} + const renderVerifiedHolder = (userId: string) => { + return ( +
+

+ Verified holder did (From Affinidi Login) +

+

{userId}

+
+ ); + }; - {!offer && configOptions.length > 0 && ( - - {typeOptions.length === 0 && ( -
Loading credential types...
+ {configurations.isLoading &&
Loading configurations...
} + {!configurations.isLoading && ( + setClaimMode(val as string)} + /> )} - {typeOptions.length > 0 && ( + {credentialTypes.isLoading && ( +
Loading credential types...
+ )} + {!credentialTypes.isLoading && ( - )} + const renderOffer = (offerTorender: OfferPayload) => { + return ( +
+ + +
+ ); + }; - {!offer && selectedConfig && ( + return ( + <> +

Issue Credentials

+ {renderErrors()} + {!hasErrors && ( +
+ {renderVerifiedHolder(session.userId)} + {offer ? ( + renderOffer(offer) + ) : (
- + setFormData({ + ...formData, + selectedConfigId: value as string, + }) + } + /> + )} + {selectedConfigId && ( + ({ + label: type.credentialTypeId, + value: type.credentialTypeId, + }) + ) || [] + } + value={selectedTypeId} disabled={isFormDisabled} - onChange={handleCredentialTypeChange} + onChange={(value) => + setFormData({ + ...formData, + selectedTypeId: value as string, + }) + } /> )} {message && ( @@ -251,21 +251,23 @@ export default function CredentialIssuance({
)} - {formProperties && claimMode && ( + {schema.data?.properties.credentialSubject && (

Credential data

)}
)} - + )} ); From cb9047dc809f2fd1db48e6f15f3dcbdff2440d5e Mon Sep 17 00:00:00 2001 From: Anton Bergman Date: Thu, 4 Jul 2024 16:35:32 +0800 Subject: [PATCH 3/7] fix: loading states --- .../src/pages/credential-issuance.tsx | 20 +++++++------------ .../src/pages/credential-issuance.tsx | 20 +++++++------------ .../src/pages/credential-issuance.tsx | 20 +++++++------------ 3 files changed, 21 insertions(+), 39 deletions(-) diff --git a/generator/nextjs/template/src/pages/credential-issuance.tsx b/generator/nextjs/template/src/pages/credential-issuance.tsx index 5d46cdb..2aa163e 100644 --- a/generator/nextjs/template/src/pages/credential-issuance.tsx +++ b/generator/nextjs/template/src/pages/credential-issuance.tsx @@ -33,12 +33,13 @@ const fetchCredentialSchema = async (jsonSchemaUrl: string) => { const fetchCredentialTypes = ( issuanceConfigurationId: string -): Promise => - fetch( +): Promise => { + return fetch( "/api/issuance/credential-types?" + new URLSearchParams({ issuanceConfigurationId }), { method: "GET" } ).then((res) => res.json()); +}; const fetchIssuanceConfigurations = (): Promise => fetch("/api/issuance/configuration-options", { method: "GET" }).then((res) => @@ -99,13 +100,6 @@ export default function CredentialIssuance({ enabled: !!selectedTypeId, }); - console.log({ - selectedConfigId, - configurations: configurations.data, - credentialTypes: credentialTypes.data, - schema: schema.data, - }); - const handleSubmit = async (credentialData: any) => { console.log("credentialData:", credentialData); setIsFormDisabled(true); @@ -196,8 +190,8 @@ export default function CredentialIssuance({ renderOffer(offer) ) : (
- {configurations.isLoading &&
Loading configurations...
} - {!configurations.isLoading && ( + {configurations.isPending &&
Loading configurations...
} + {!configurations.isPending && ( { const fetchCredentialTypes = ( issuanceConfigurationId: string -): Promise => - fetch( +): Promise => { + return fetch( "/api/issuance/credential-types?" + new URLSearchParams({ issuanceConfigurationId }), { method: "GET" } ).then((res) => res.json()); +}; const fetchIssuanceConfigurations = (): Promise => fetch("/api/issuance/configuration-options", { method: "GET" }).then((res) => @@ -99,13 +100,6 @@ export default function CredentialIssuance({ enabled: !!selectedTypeId, }); - console.log({ - selectedConfigId, - configurations: configurations.data, - credentialTypes: credentialTypes.data, - schema: schema.data, - }); - const handleSubmit = async (credentialData: any) => { console.log("credentialData:", credentialData); setIsFormDisabled(true); @@ -196,8 +190,8 @@ export default function CredentialIssuance({ renderOffer(offer) ) : (
- {configurations.isLoading &&
Loading configurations...
} - {!configurations.isLoading && ( + {configurations.isPending &&
Loading configurations...
} + {!configurations.isPending && ( { const fetchCredentialTypes = ( issuanceConfigurationId: string -): Promise => - fetch( +): Promise => { + return fetch( "/api/issuance/credential-types?" + new URLSearchParams({ issuanceConfigurationId }), { method: "GET" } ).then((res) => res.json()); +}; const fetchIssuanceConfigurations = (): Promise => fetch("/api/issuance/configuration-options", { method: "GET" }).then((res) => @@ -99,13 +100,6 @@ export default function CredentialIssuance({ enabled: !!selectedTypeId, }); - console.log({ - selectedConfigId, - configurations: configurations.data, - credentialTypes: credentialTypes.data, - schema: schema.data, - }); - const handleSubmit = async (credentialData: any) => { console.log("credentialData:", credentialData); setIsFormDisabled(true); @@ -196,8 +190,8 @@ export default function CredentialIssuance({ renderOffer(offer) ) : (
- {configurations.isLoading &&
Loading configurations...
} - {!configurations.isLoading && ( + {configurations.isPending &&
Loading configurations...
} + {!configurations.isPending && ( Date: Thu, 4 Jul 2024 17:20:38 +0800 Subject: [PATCH 4/7] feat: update iota page --- .../src/components/iota/IotaClientPage.tsx | 227 +++++++++--------- .../src/pages/credential-issuance.tsx | 4 +- .../src/components/iota/IotaClientPage.tsx | 227 +++++++++--------- .../src/pages/credential-issuance.tsx | 4 +- .../src/components/iota/IotaClientPage.tsx | 227 +++++++++--------- .../src/pages/credential-issuance.tsx | 4 +- 6 files changed, 333 insertions(+), 360 deletions(-) diff --git a/generator/nextjs/template/src/components/iota/IotaClientPage.tsx b/generator/nextjs/template/src/components/iota/IotaClientPage.tsx index a0376da..df9b809 100644 --- a/generator/nextjs/template/src/components/iota/IotaClientPage.tsx +++ b/generator/nextjs/template/src/components/iota/IotaClientPage.tsx @@ -6,8 +6,9 @@ import { OpenMode, Session, } from "@affinidi-tdk/iota-browser"; +import { useQuery } from "@tanstack/react-query"; import { useSession } from "next-auth/react"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import Button from "../core/Button"; import Select, { SelectOption } from "../core/Select"; @@ -29,103 +30,86 @@ type DataRequests = { }; }; +const fetchIotaConfigurations = (): Promise => + fetch("/api/iota/configuration-options", { method: "GET" }).then((res) => + res.json() + ); + +const getQueryOptions = async (configurationId: string) => { + const response = await fetch( + "/api/iota/query-options?" + + new URLSearchParams({ + iotaConfigurationId: configurationId, + }), + { + method: "GET", + } + ); + return (await response.json()) as SelectOption[]; +}; + +const getIotaCredentials = async (configurationId: string) => { + const response = await fetch( + "/api/iota/start?" + + new URLSearchParams({ + iotaConfigurationId: configurationId, + }), + { + method: "GET", + } + ); + return (await response.json()) as IotaCredentials; +}; + export default function IotaSessionMultipleRequestsPage({ featureAvailable, }: { featureAvailable: boolean; }) { - const [holderDid, setHolderDid] = useState(""); - const [configOptions, setConfigOptions] = useState([]); - const [selectedConfig, setSelectedConfig] = useState(""); - const [iotaSession, setIotaSession] = useState(); - const [iotaIsInitializing, setIotaIsInitializing] = useState(false); - const [queryOptions, setQueryOptions] = useState([]); + const [selectedConfigId, setSelectedConfigId] = useState(""); const [selectedQuery, setSelectedQuery] = useState(""); const [openMode, setOpenMode] = useState(OpenMode.Popup); const [dataRequests, setDataRequests] = useState({}); const [isFormDisabled, setIsFormDisabled] = useState(false); - // Prefill did from session + // Get did from session const { data: session } = useSession(); - useEffect(() => { - if (!session || !session.user) return; - setHolderDid(session.userId); - }, [session]); - useEffect(() => { - const initConfigurations = async () => { - try { - const response = await fetch("/api/iota/configuration-options", { - method: "GET", - }); - const configurations = await response.json(); - setConfigOptions(configurations); - } catch (error) { - console.error("Error getting Iota configurations:", error); - } - }; - if (featureAvailable) { - initConfigurations(); - } - }, [featureAvailable]); + const configurations = useQuery({ + queryKey: ["configurations"], + queryFn: fetchIotaConfigurations, + enabled: !!featureAvailable, + }); - async function handleConfigurationChange(value: string | number) { - const configId = value as string; - clearSession(); - setSelectedConfig(configId); - if (!configId) { - return; - } - try { - setIotaIsInitializing(true); - getQueryOptions(configId); - const credentials = await getIotaCredentials(configId); + const iotaSession = useQuery({ + queryKey: ["iotaSession", selectedConfigId], + queryFn: async ({ queryKey }) => { + const credentials = await getIotaCredentials(queryKey[1]); const iotaSession = new Session({ credentials }); await iotaSession.initialize(); - setIotaSession(iotaSession); - } catch (error) { - if (error instanceof IotaError) { - console.log(error.code); - } - } finally { - setIotaIsInitializing(false); - } - } + return iotaSession; + }, + enabled: !!selectedConfigId, + }); - async function getQueryOptions(configurationId: string) { - const response = await fetch( - "/api/iota/query-options?" + - new URLSearchParams({ - iotaConfigurationId: configurationId, - }), - { - method: "GET", - }, - ); - const options = (await response.json()) as SelectOption[]; - setQueryOptions(options); - } + const queryOptions = useQuery({ + queryKey: ["configurations", selectedConfigId], + queryFn: ({ queryKey }) => getQueryOptions(queryKey[1]), + enabled: !!selectedConfigId, + }); - async function getIotaCredentials(configurationId: string) { - const response = await fetch( - "/api/iota/start?" + - new URLSearchParams({ - iotaConfigurationId: configurationId, - }), - { - method: "GET", - }, - ); - return (await response.json()) as IotaCredentials; + async function handleConfigurationChange(value: string | number) { + clearSession(); + setSelectedConfigId(value as string); } async function handleTDKShare(queryId: string) { - if (!iotaSession) { + if (!iotaSession.data) { throw new Error("Iota session not initialized"); } try { setIsFormDisabled(true); - const request = await iotaSession.prepareRequest({ queryId }); + const request = await iotaSession.data.prepareRequest({ queryId }); setIsFormDisabled(false); addNewDataRequest(request); request.openVault({ mode: openMode }); @@ -133,7 +117,7 @@ export default function IotaSessionMultipleRequestsPage({ updateDataRequestWithResponse(response); } catch (error) { if (error instanceof IotaError) { - updateDataRequestWithError(error) + updateDataRequestWithError(error); console.log(error.code); } } @@ -168,63 +152,66 @@ export default function IotaSessionMultipleRequestsPage({ } }; - async function handleOpenModeChange(value: string | number) { - setOpenMode(value as number); - } - - async function handleQueryChange(value: string | number) { - setSelectedQuery(value as string); - } - async function clearSession() { - setIotaSession(undefined); - setQueryOptions([]); setSelectedQuery(""); setIsFormDisabled(false); } - return ( - <> -

Receive Credentials

+ const renderVerifiedHolder = (userId: string) => { + return ( +
+

+ Verified holder did (From Affinidi Login) +

+

{userId}

+
+ ); + }; - {!featureAvailable && ( + const hasErrors = !featureAvailable || !session || !session.userId; + const renderErrors = () => { + if (!featureAvailable) { + return (
Feature not available. Please set your Personal Access Token in your environment secrets.
- )} + ); + } - {featureAvailable && !holderDid && ( + if (!session || !session.userId) { + return (
- You must be logged in to share credentials from your Affinidi Vault + You must be logged in to issue credentials to your Affinidi Vault
- )} + ); + } + }; - {featureAvailable && holderDid && ( + return ( + <> +

Receive Credentials

+ + {renderErrors()} + {!hasErrors && ( <> -
-

- Verified holder did (From Affinidi Login) -

-

{holderDid}

-
+ {renderVerifiedHolder(session.userId)} - {configOptions.length === 0 && ( + {configurations.isPending && (
Loading configurations...
)} - - {configOptions.length > 0 && ( + {!configurations.isPending && ( setOpenMode(val as number)} /> - {queryOptions.length === 0 && ( + {queryOptions.isPending && (
Loading queries...
)} - {queryOptions.length > 0 && ( + {!queryOptions.isPending && ( => + fetch("/api/iota/configuration-options", { method: "GET" }).then((res) => + res.json() + ); + +const getQueryOptions = async (configurationId: string) => { + const response = await fetch( + "/api/iota/query-options?" + + new URLSearchParams({ + iotaConfigurationId: configurationId, + }), + { + method: "GET", + } + ); + return (await response.json()) as SelectOption[]; +}; + +const getIotaCredentials = async (configurationId: string) => { + const response = await fetch( + "/api/iota/start?" + + new URLSearchParams({ + iotaConfigurationId: configurationId, + }), + { + method: "GET", + } + ); + return (await response.json()) as IotaCredentials; +}; + export default function IotaSessionMultipleRequestsPage({ featureAvailable, }: { featureAvailable: boolean; }) { - const [holderDid, setHolderDid] = useState(""); - const [configOptions, setConfigOptions] = useState([]); - const [selectedConfig, setSelectedConfig] = useState(""); - const [iotaSession, setIotaSession] = useState(); - const [iotaIsInitializing, setIotaIsInitializing] = useState(false); - const [queryOptions, setQueryOptions] = useState([]); + const [selectedConfigId, setSelectedConfigId] = useState(""); const [selectedQuery, setSelectedQuery] = useState(""); const [openMode, setOpenMode] = useState(OpenMode.Popup); const [dataRequests, setDataRequests] = useState({}); const [isFormDisabled, setIsFormDisabled] = useState(false); - // Prefill did from session + // Get did from session const { data: session } = useSession(); - useEffect(() => { - if (!session || !session.user) return; - setHolderDid(session.userId); - }, [session]); - useEffect(() => { - const initConfigurations = async () => { - try { - const response = await fetch("/api/iota/configuration-options", { - method: "GET", - }); - const configurations = await response.json(); - setConfigOptions(configurations); - } catch (error) { - console.error("Error getting Iota configurations:", error); - } - }; - if (featureAvailable) { - initConfigurations(); - } - }, [featureAvailable]); + const configurations = useQuery({ + queryKey: ["configurations"], + queryFn: fetchIotaConfigurations, + enabled: !!featureAvailable, + }); - async function handleConfigurationChange(value: string | number) { - const configId = value as string; - clearSession(); - setSelectedConfig(configId); - if (!configId) { - return; - } - try { - setIotaIsInitializing(true); - getQueryOptions(configId); - const credentials = await getIotaCredentials(configId); + const iotaSession = useQuery({ + queryKey: ["iotaSession", selectedConfigId], + queryFn: async ({ queryKey }) => { + const credentials = await getIotaCredentials(queryKey[1]); const iotaSession = new Session({ credentials }); await iotaSession.initialize(); - setIotaSession(iotaSession); - } catch (error) { - if (error instanceof IotaError) { - console.log(error.code); - } - } finally { - setIotaIsInitializing(false); - } - } + return iotaSession; + }, + enabled: !!selectedConfigId, + }); - async function getQueryOptions(configurationId: string) { - const response = await fetch( - "/api/iota/query-options?" + - new URLSearchParams({ - iotaConfigurationId: configurationId, - }), - { - method: "GET", - }, - ); - const options = (await response.json()) as SelectOption[]; - setQueryOptions(options); - } + const queryOptions = useQuery({ + queryKey: ["configurations", selectedConfigId], + queryFn: ({ queryKey }) => getQueryOptions(queryKey[1]), + enabled: !!selectedConfigId, + }); - async function getIotaCredentials(configurationId: string) { - const response = await fetch( - "/api/iota/start?" + - new URLSearchParams({ - iotaConfigurationId: configurationId, - }), - { - method: "GET", - }, - ); - return (await response.json()) as IotaCredentials; + async function handleConfigurationChange(value: string | number) { + clearSession(); + setSelectedConfigId(value as string); } async function handleTDKShare(queryId: string) { - if (!iotaSession) { + if (!iotaSession.data) { throw new Error("Iota session not initialized"); } try { setIsFormDisabled(true); - const request = await iotaSession.prepareRequest({ queryId }); + const request = await iotaSession.data.prepareRequest({ queryId }); setIsFormDisabled(false); addNewDataRequest(request); request.openVault({ mode: openMode }); @@ -133,7 +117,7 @@ export default function IotaSessionMultipleRequestsPage({ updateDataRequestWithResponse(response); } catch (error) { if (error instanceof IotaError) { - updateDataRequestWithError(error) + updateDataRequestWithError(error); console.log(error.code); } } @@ -168,63 +152,66 @@ export default function IotaSessionMultipleRequestsPage({ } }; - async function handleOpenModeChange(value: string | number) { - setOpenMode(value as number); - } - - async function handleQueryChange(value: string | number) { - setSelectedQuery(value as string); - } - async function clearSession() { - setIotaSession(undefined); - setQueryOptions([]); setSelectedQuery(""); setIsFormDisabled(false); } - return ( - <> -

Receive Credentials

+ const renderVerifiedHolder = (userId: string) => { + return ( +
+

+ Verified holder did (From Affinidi Login) +

+

{userId}

+
+ ); + }; - {!featureAvailable && ( + const hasErrors = !featureAvailable || !session || !session.userId; + const renderErrors = () => { + if (!featureAvailable) { + return (
Feature not available. Please set your Personal Access Token in your environment secrets.
- )} + ); + } - {featureAvailable && !holderDid && ( + if (!session || !session.userId) { + return (
- You must be logged in to share credentials from your Affinidi Vault + You must be logged in to issue credentials to your Affinidi Vault
- )} + ); + } + }; - {featureAvailable && holderDid && ( + return ( + <> +

Receive Credentials

+ + {renderErrors()} + {!hasErrors && ( <> -
-

- Verified holder did (From Affinidi Login) -

-

{holderDid}

-
+ {renderVerifiedHolder(session.userId)} - {configOptions.length === 0 && ( + {configurations.isPending && (
Loading configurations...
)} - - {configOptions.length > 0 && ( + {!configurations.isPending && ( setOpenMode(val as number)} /> - {queryOptions.length === 0 && ( + {queryOptions.isPending && (
Loading queries...
)} - {queryOptions.length > 0 && ( + {!queryOptions.isPending && ( => + fetch("/api/iota/configuration-options", { method: "GET" }).then((res) => + res.json() + ); + +const getQueryOptions = async (configurationId: string) => { + const response = await fetch( + "/api/iota/query-options?" + + new URLSearchParams({ + iotaConfigurationId: configurationId, + }), + { + method: "GET", + } + ); + return (await response.json()) as SelectOption[]; +}; + +const getIotaCredentials = async (configurationId: string) => { + const response = await fetch( + "/api/iota/start?" + + new URLSearchParams({ + iotaConfigurationId: configurationId, + }), + { + method: "GET", + } + ); + return (await response.json()) as IotaCredentials; +}; + export default function IotaSessionMultipleRequestsPage({ featureAvailable, }: { featureAvailable: boolean; }) { - const [holderDid, setHolderDid] = useState(""); - const [configOptions, setConfigOptions] = useState([]); - const [selectedConfig, setSelectedConfig] = useState(""); - const [iotaSession, setIotaSession] = useState(); - const [iotaIsInitializing, setIotaIsInitializing] = useState(false); - const [queryOptions, setQueryOptions] = useState([]); + const [selectedConfigId, setSelectedConfigId] = useState(""); const [selectedQuery, setSelectedQuery] = useState(""); const [openMode, setOpenMode] = useState(OpenMode.Popup); const [dataRequests, setDataRequests] = useState({}); const [isFormDisabled, setIsFormDisabled] = useState(false); - // Prefill did from session + // Get did from session const { data: session } = useSession(); - useEffect(() => { - if (!session || !session.user) return; - setHolderDid(session.userId); - }, [session]); - useEffect(() => { - const initConfigurations = async () => { - try { - const response = await fetch("/api/iota/configuration-options", { - method: "GET", - }); - const configurations = await response.json(); - setConfigOptions(configurations); - } catch (error) { - console.error("Error getting Iota configurations:", error); - } - }; - if (featureAvailable) { - initConfigurations(); - } - }, [featureAvailable]); + const configurations = useQuery({ + queryKey: ["configurations"], + queryFn: fetchIotaConfigurations, + enabled: !!featureAvailable, + }); - async function handleConfigurationChange(value: string | number) { - const configId = value as string; - clearSession(); - setSelectedConfig(configId); - if (!configId) { - return; - } - try { - setIotaIsInitializing(true); - getQueryOptions(configId); - const credentials = await getIotaCredentials(configId); + const iotaSession = useQuery({ + queryKey: ["iotaSession", selectedConfigId], + queryFn: async ({ queryKey }) => { + const credentials = await getIotaCredentials(queryKey[1]); const iotaSession = new Session({ credentials }); await iotaSession.initialize(); - setIotaSession(iotaSession); - } catch (error) { - if (error instanceof IotaError) { - console.log(error.code); - } - } finally { - setIotaIsInitializing(false); - } - } + return iotaSession; + }, + enabled: !!selectedConfigId, + }); - async function getQueryOptions(configurationId: string) { - const response = await fetch( - "/api/iota/query-options?" + - new URLSearchParams({ - iotaConfigurationId: configurationId, - }), - { - method: "GET", - }, - ); - const options = (await response.json()) as SelectOption[]; - setQueryOptions(options); - } + const queryOptions = useQuery({ + queryKey: ["configurations", selectedConfigId], + queryFn: ({ queryKey }) => getQueryOptions(queryKey[1]), + enabled: !!selectedConfigId, + }); - async function getIotaCredentials(configurationId: string) { - const response = await fetch( - "/api/iota/start?" + - new URLSearchParams({ - iotaConfigurationId: configurationId, - }), - { - method: "GET", - }, - ); - return (await response.json()) as IotaCredentials; + async function handleConfigurationChange(value: string | number) { + clearSession(); + setSelectedConfigId(value as string); } async function handleTDKShare(queryId: string) { - if (!iotaSession) { + if (!iotaSession.data) { throw new Error("Iota session not initialized"); } try { setIsFormDisabled(true); - const request = await iotaSession.prepareRequest({ queryId }); + const request = await iotaSession.data.prepareRequest({ queryId }); setIsFormDisabled(false); addNewDataRequest(request); request.openVault({ mode: openMode }); @@ -133,7 +117,7 @@ export default function IotaSessionMultipleRequestsPage({ updateDataRequestWithResponse(response); } catch (error) { if (error instanceof IotaError) { - updateDataRequestWithError(error) + updateDataRequestWithError(error); console.log(error.code); } } @@ -168,63 +152,66 @@ export default function IotaSessionMultipleRequestsPage({ } }; - async function handleOpenModeChange(value: string | number) { - setOpenMode(value as number); - } - - async function handleQueryChange(value: string | number) { - setSelectedQuery(value as string); - } - async function clearSession() { - setIotaSession(undefined); - setQueryOptions([]); setSelectedQuery(""); setIsFormDisabled(false); } - return ( - <> -

Receive Credentials

+ const renderVerifiedHolder = (userId: string) => { + return ( +
+

+ Verified holder did (From Affinidi Login) +

+

{userId}

+
+ ); + }; - {!featureAvailable && ( + const hasErrors = !featureAvailable || !session || !session.userId; + const renderErrors = () => { + if (!featureAvailable) { + return (
Feature not available. Please set your Personal Access Token in your environment secrets.
- )} + ); + } - {featureAvailable && !holderDid && ( + if (!session || !session.userId) { + return (
- You must be logged in to share credentials from your Affinidi Vault + You must be logged in to issue credentials to your Affinidi Vault
- )} + ); + } + }; - {featureAvailable && holderDid && ( + return ( + <> +

Receive Credentials

+ + {renderErrors()} + {!hasErrors && ( <> -
-

- Verified holder did (From Affinidi Login) -

-

{holderDid}

-
+ {renderVerifiedHolder(session.userId)} - {configOptions.length === 0 && ( + {configurations.isPending && (
Loading configurations...
)} - - {configOptions.length > 0 && ( + {!configurations.isPending && ( setOpenMode(val as number)} /> - {queryOptions.length === 0 && ( + {queryOptions.isPending && (
Loading queries...
)} - {queryOptions.length > 0 && ( + {!queryOptions.isPending && ( Date: Fri, 5 Jul 2024 10:29:18 +0800 Subject: [PATCH 5/7] feat: add states for when no configs/queries/types. Make better use of isFetching and isSuccess --- .../src/components/iota/IotaClientPage.tsx | 183 ++++++++++-------- .../src/pages/credential-issuance.tsx | 79 +++++--- .../src/components/iota/IotaClientPage.tsx | 183 ++++++++++-------- .../src/pages/credential-issuance.tsx | 79 +++++--- .../src/components/iota/IotaClientPage.tsx | 183 ++++++++++-------- .../src/pages/credential-issuance.tsx | 79 +++++--- 6 files changed, 462 insertions(+), 324 deletions(-) diff --git a/generator/nextjs/template/src/components/iota/IotaClientPage.tsx b/generator/nextjs/template/src/components/iota/IotaClientPage.tsx index df9b809..5451aec 100644 --- a/generator/nextjs/template/src/components/iota/IotaClientPage.tsx +++ b/generator/nextjs/template/src/components/iota/IotaClientPage.tsx @@ -30,7 +30,7 @@ type DataRequests = { }; }; -const fetchIotaConfigurations = (): Promise => +const fetchIotaConfigurations = (): Promise => fetch("/api/iota/configuration-options", { method: "GET" }).then((res) => res.json() ); @@ -75,13 +75,13 @@ export default function IotaSessionMultipleRequestsPage({ // Get did from session const { data: session } = useSession(); - const configurations = useQuery({ + const configurationsQuery = useQuery({ queryKey: ["configurations"], queryFn: fetchIotaConfigurations, enabled: !!featureAvailable, }); - const iotaSession = useQuery({ + const iotaSessionQuery = useQuery({ queryKey: ["iotaSession", selectedConfigId], queryFn: async ({ queryKey }) => { const credentials = await getIotaCredentials(queryKey[1]); @@ -92,7 +92,7 @@ export default function IotaSessionMultipleRequestsPage({ enabled: !!selectedConfigId, }); - const queryOptions = useQuery({ + const iotaQueryOptionsQuery = useQuery({ queryKey: ["configurations", selectedConfigId], queryFn: ({ queryKey }) => getQueryOptions(queryKey[1]), enabled: !!selectedConfigId, @@ -104,12 +104,12 @@ export default function IotaSessionMultipleRequestsPage({ } async function handleTDKShare(queryId: string) { - if (!iotaSession.data) { + if (!iotaSessionQuery.data) { throw new Error("Iota session not initialized"); } try { setIsFormDisabled(true); - const request = await iotaSession.data.prepareRequest({ queryId }); + const request = await iotaSessionQuery.data.prepareRequest({ queryId }); setIsFormDisabled(false); addNewDataRequest(request); request.openVault({ mode: openMode }); @@ -197,95 +197,114 @@ export default function IotaSessionMultipleRequestsPage({ <> {renderVerifiedHolder(session.userId)} - {configurations.isPending && ( + {configurationsQuery.isPending && (
Loading configurations...
)} - {!configurations.isPending && ( + {configurationsQuery.isSuccess && + configurationsQuery.data.length === 0 && ( +
+ You don't have any configurations. Go to the{" "} + + Affinidi Portal + {" "} + to create one. +
+ )} + {configurationsQuery.isSuccess && + configurationsQuery.data.length > 0 && ( + setOpenMode(val as number)} /> )} - {selectedConfigId && ( -
+ {iotaQueryOptionsQuery.isFetching && ( +
Loading queries...
+ )} + {iotaQueryOptionsQuery.isSuccess && + iotaQueryOptionsQuery.data.length === 0 && ( +
+ You don't have any queries. Go to the{" "} + + Affinidi Portal + {" "} + to create one. +
+ )} + {iotaQueryOptionsQuery.isSuccess && + iotaQueryOptionsQuery.data.length > 0 && ( setSelectedQuery(val as string)} - /> - )} - - {!iotaSession.isPending && selectedQuery && ( - - )} + {iotaSessionQuery.isSuccess && selectedQuery && ( + + )} - {iotaSession.isPending && ( -
- Initializing session with Affinidi Iota Framework... -
- )} - {iotaSession.isError &&
Failed to initialize Iota
} + {iotaSessionQuery.isFetching && ( +
+ Initializing session with Affinidi Iota Framework... +
+ )} + {iotaSessionQuery.isError &&
Failed to initialize Iota
} - {Object.keys(dataRequests).length > 0 && ( -
- - - - - - - - - {Object.keys(dataRequests).map((id: string) => ( - - - - - ))} - -
Request IDResult
{id} -
-                              {dataRequests[id].result instanceof IotaError && (
-                                

Error received:

- )} - {!( - dataRequests[id].result instanceof IotaError - ) &&

Response received:

} - {JSON.stringify( - dataRequests[id].result, - undefined, - 2 - )} -
-
-
- )} + {Object.keys(dataRequests).length > 0 && ( +
+ + + + + + + + + {Object.keys(dataRequests).map((id: string) => ( + + + + + ))} + +
Request IDResult
{id} +
+                          {dataRequests[id].result instanceof IotaError && (
+                            

Error received:

+ )} + {!(dataRequests[id].result instanceof IotaError) && ( +

Response received:

+ )} + {JSON.stringify( + dataRequests[id].result, + undefined, + 2 + )} +
+
)} diff --git a/generator/nextjs/template/src/pages/credential-issuance.tsx b/generator/nextjs/template/src/pages/credential-issuance.tsx index dc3685e..b0723cd 100644 --- a/generator/nextjs/template/src/pages/credential-issuance.tsx +++ b/generator/nextjs/template/src/pages/credential-issuance.tsx @@ -33,7 +33,7 @@ const fetchCredentialSchema = async (jsonSchemaUrl: string) => { const fetchCredentialTypes = ( issuanceConfigurationId: string -): Promise => { +): Promise => { return fetch( "/api/issuance/credential-types?" + new URLSearchParams({ issuanceConfigurationId }), @@ -41,7 +41,7 @@ const fetchCredentialTypes = ( ).then((res) => res.json()); }; -const fetchIssuanceConfigurations = (): Promise => +const fetchIssuanceConfigurations = (): Promise => fetch("/api/issuance/configuration-options", { method: "GET" }).then((res) => res.json() ); @@ -69,22 +69,22 @@ export default function CredentialIssuance({ // Get did from session const { data: session } = useSession(); - const configurations = useQuery({ + const configurationsQuery = useQuery({ queryKey: ["configurations"], queryFn: fetchIssuanceConfigurations, enabled: !!featureAvailable, }); - const credentialTypes = useQuery({ + const credentialTypesQuery = useQuery({ queryKey: ["types", selectedConfigId], queryFn: ({ queryKey }) => fetchCredentialTypes(queryKey[1]), enabled: !!selectedConfigId, }); - const schema = useQuery({ + const schemaQuery = useQuery({ queryKey: ["schema", selectedTypeId], queryFn: () => { - const credentialType = credentialTypes.data?.find( + const credentialType = credentialTypesQuery.data?.find( (type) => type.credentialTypeId === selectedTypeId ); if (!credentialType) { @@ -190,23 +190,37 @@ export default function CredentialIssuance({ renderOffer(offer) ) : (
- {configurations.isPending && ( + {configurationsQuery.isPending && (
Loading configurations...
)} - {!configurations.isPending && ( - + setFormData({ + ...formData, + selectedConfigId: value as string, + }) + } + /> + )} {selectedConfigId && ( ({ label: type.credentialTypeId, value: type.credentialTypeId, @@ -247,13 +274,13 @@ export default function CredentialIssuance({
)} - {schema.data?.properties.credentialSubject && ( + {schemaQuery.data?.properties.credentialSubject && (

Credential data

=> +const fetchIotaConfigurations = (): Promise => fetch("/api/iota/configuration-options", { method: "GET" }).then((res) => res.json() ); @@ -75,13 +75,13 @@ export default function IotaSessionMultipleRequestsPage({ // Get did from session const { data: session } = useSession(); - const configurations = useQuery({ + const configurationsQuery = useQuery({ queryKey: ["configurations"], queryFn: fetchIotaConfigurations, enabled: !!featureAvailable, }); - const iotaSession = useQuery({ + const iotaSessionQuery = useQuery({ queryKey: ["iotaSession", selectedConfigId], queryFn: async ({ queryKey }) => { const credentials = await getIotaCredentials(queryKey[1]); @@ -92,7 +92,7 @@ export default function IotaSessionMultipleRequestsPage({ enabled: !!selectedConfigId, }); - const queryOptions = useQuery({ + const iotaQueryOptionsQuery = useQuery({ queryKey: ["configurations", selectedConfigId], queryFn: ({ queryKey }) => getQueryOptions(queryKey[1]), enabled: !!selectedConfigId, @@ -104,12 +104,12 @@ export default function IotaSessionMultipleRequestsPage({ } async function handleTDKShare(queryId: string) { - if (!iotaSession.data) { + if (!iotaSessionQuery.data) { throw new Error("Iota session not initialized"); } try { setIsFormDisabled(true); - const request = await iotaSession.data.prepareRequest({ queryId }); + const request = await iotaSessionQuery.data.prepareRequest({ queryId }); setIsFormDisabled(false); addNewDataRequest(request); request.openVault({ mode: openMode }); @@ -197,95 +197,114 @@ export default function IotaSessionMultipleRequestsPage({ <> {renderVerifiedHolder(session.userId)} - {configurations.isPending && ( + {configurationsQuery.isPending && (
Loading configurations...
)} - {!configurations.isPending && ( + {configurationsQuery.isSuccess && + configurationsQuery.data.length === 0 && ( +
+ You don't have any configurations. Go to the{" "} + + Affinidi Portal + {" "} + to create one. +
+ )} + {configurationsQuery.isSuccess && + configurationsQuery.data.length > 0 && ( + setOpenMode(val as number)} /> )} - {selectedConfigId && ( -
+ {iotaQueryOptionsQuery.isFetching && ( +
Loading queries...
+ )} + {iotaQueryOptionsQuery.isSuccess && + iotaQueryOptionsQuery.data.length === 0 && ( +
+ You don't have any queries. Go to the{" "} + + Affinidi Portal + {" "} + to create one. +
+ )} + {iotaQueryOptionsQuery.isSuccess && + iotaQueryOptionsQuery.data.length > 0 && ( setSelectedQuery(val as string)} - /> - )} - - {!iotaSession.isPending && selectedQuery && ( - - )} + {iotaSessionQuery.isSuccess && selectedQuery && ( + + )} - {iotaSession.isPending && ( -
- Initializing session with Affinidi Iota Framework... -
- )} - {iotaSession.isError &&
Failed to initialize Iota
} + {iotaSessionQuery.isFetching && ( +
+ Initializing session with Affinidi Iota Framework... +
+ )} + {iotaSessionQuery.isError &&
Failed to initialize Iota
} - {Object.keys(dataRequests).length > 0 && ( -
- - - - - - - - - {Object.keys(dataRequests).map((id: string) => ( - - - - - ))} - -
Request IDResult
{id} -
-                              {dataRequests[id].result instanceof IotaError && (
-                                

Error received:

- )} - {!( - dataRequests[id].result instanceof IotaError - ) &&

Response received:

} - {JSON.stringify( - dataRequests[id].result, - undefined, - 2 - )} -
-
-
- )} + {Object.keys(dataRequests).length > 0 && ( +
+ + + + + + + + + {Object.keys(dataRequests).map((id: string) => ( + + + + + ))} + +
Request IDResult
{id} +
+                          {dataRequests[id].result instanceof IotaError && (
+                            

Error received:

+ )} + {!(dataRequests[id].result instanceof IotaError) && ( +

Response received:

+ )} + {JSON.stringify( + dataRequests[id].result, + undefined, + 2 + )} +
+
)} diff --git a/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx b/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx index dc3685e..b0723cd 100644 --- a/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx +++ b/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx @@ -33,7 +33,7 @@ const fetchCredentialSchema = async (jsonSchemaUrl: string) => { const fetchCredentialTypes = ( issuanceConfigurationId: string -): Promise => { +): Promise => { return fetch( "/api/issuance/credential-types?" + new URLSearchParams({ issuanceConfigurationId }), @@ -41,7 +41,7 @@ const fetchCredentialTypes = ( ).then((res) => res.json()); }; -const fetchIssuanceConfigurations = (): Promise => +const fetchIssuanceConfigurations = (): Promise => fetch("/api/issuance/configuration-options", { method: "GET" }).then((res) => res.json() ); @@ -69,22 +69,22 @@ export default function CredentialIssuance({ // Get did from session const { data: session } = useSession(); - const configurations = useQuery({ + const configurationsQuery = useQuery({ queryKey: ["configurations"], queryFn: fetchIssuanceConfigurations, enabled: !!featureAvailable, }); - const credentialTypes = useQuery({ + const credentialTypesQuery = useQuery({ queryKey: ["types", selectedConfigId], queryFn: ({ queryKey }) => fetchCredentialTypes(queryKey[1]), enabled: !!selectedConfigId, }); - const schema = useQuery({ + const schemaQuery = useQuery({ queryKey: ["schema", selectedTypeId], queryFn: () => { - const credentialType = credentialTypes.data?.find( + const credentialType = credentialTypesQuery.data?.find( (type) => type.credentialTypeId === selectedTypeId ); if (!credentialType) { @@ -190,23 +190,37 @@ export default function CredentialIssuance({ renderOffer(offer) ) : (
- {configurations.isPending && ( + {configurationsQuery.isPending && (
Loading configurations...
)} - {!configurations.isPending && ( - + setFormData({ + ...formData, + selectedConfigId: value as string, + }) + } + /> + )} {selectedConfigId && ( ({ label: type.credentialTypeId, value: type.credentialTypeId, @@ -247,13 +274,13 @@ export default function CredentialIssuance({
)} - {schema.data?.properties.credentialSubject && ( + {schemaQuery.data?.properties.credentialSubject && (

Credential data

=> +const fetchIotaConfigurations = (): Promise => fetch("/api/iota/configuration-options", { method: "GET" }).then((res) => res.json() ); @@ -75,13 +75,13 @@ export default function IotaSessionMultipleRequestsPage({ // Get did from session const { data: session } = useSession(); - const configurations = useQuery({ + const configurationsQuery = useQuery({ queryKey: ["configurations"], queryFn: fetchIotaConfigurations, enabled: !!featureAvailable, }); - const iotaSession = useQuery({ + const iotaSessionQuery = useQuery({ queryKey: ["iotaSession", selectedConfigId], queryFn: async ({ queryKey }) => { const credentials = await getIotaCredentials(queryKey[1]); @@ -92,7 +92,7 @@ export default function IotaSessionMultipleRequestsPage({ enabled: !!selectedConfigId, }); - const queryOptions = useQuery({ + const iotaQueryOptionsQuery = useQuery({ queryKey: ["configurations", selectedConfigId], queryFn: ({ queryKey }) => getQueryOptions(queryKey[1]), enabled: !!selectedConfigId, @@ -104,12 +104,12 @@ export default function IotaSessionMultipleRequestsPage({ } async function handleTDKShare(queryId: string) { - if (!iotaSession.data) { + if (!iotaSessionQuery.data) { throw new Error("Iota session not initialized"); } try { setIsFormDisabled(true); - const request = await iotaSession.data.prepareRequest({ queryId }); + const request = await iotaSessionQuery.data.prepareRequest({ queryId }); setIsFormDisabled(false); addNewDataRequest(request); request.openVault({ mode: openMode }); @@ -197,95 +197,114 @@ export default function IotaSessionMultipleRequestsPage({ <> {renderVerifiedHolder(session.userId)} - {configurations.isPending && ( + {configurationsQuery.isPending && (
Loading configurations...
)} - {!configurations.isPending && ( + {configurationsQuery.isSuccess && + configurationsQuery.data.length === 0 && ( +
+ You don't have any configurations. Go to the{" "} + + Affinidi Portal + {" "} + to create one. +
+ )} + {configurationsQuery.isSuccess && + configurationsQuery.data.length > 0 && ( + setOpenMode(val as number)} /> )} - {selectedConfigId && ( -
+ {iotaQueryOptionsQuery.isFetching && ( +
Loading queries...
+ )} + {iotaQueryOptionsQuery.isSuccess && + iotaQueryOptionsQuery.data.length === 0 && ( +
+ You don't have any queries. Go to the{" "} + + Affinidi Portal + {" "} + to create one. +
+ )} + {iotaQueryOptionsQuery.isSuccess && + iotaQueryOptionsQuery.data.length > 0 && ( setSelectedQuery(val as string)} - /> - )} - - {!iotaSession.isPending && selectedQuery && ( - - )} + {iotaSessionQuery.isSuccess && selectedQuery && ( + + )} - {iotaSession.isPending && ( -
- Initializing session with Affinidi Iota Framework... -
- )} - {iotaSession.isError &&
Failed to initialize Iota
} + {iotaSessionQuery.isFetching && ( +
+ Initializing session with Affinidi Iota Framework... +
+ )} + {iotaSessionQuery.isError &&
Failed to initialize Iota
} - {Object.keys(dataRequests).length > 0 && ( -
- - - - - - - - - {Object.keys(dataRequests).map((id: string) => ( - - - - - ))} - -
Request IDResult
{id} -
-                              {dataRequests[id].result instanceof IotaError && (
-                                

Error received:

- )} - {!( - dataRequests[id].result instanceof IotaError - ) &&

Response received:

} - {JSON.stringify( - dataRequests[id].result, - undefined, - 2 - )} -
-
-
- )} + {Object.keys(dataRequests).length > 0 && ( +
+ + + + + + + + + {Object.keys(dataRequests).map((id: string) => ( + + + + + ))} + +
Request IDResult
{id} +
+                          {dataRequests[id].result instanceof IotaError && (
+                            

Error received:

+ )} + {!(dataRequests[id].result instanceof IotaError) && ( +

Response received:

+ )} + {JSON.stringify( + dataRequests[id].result, + undefined, + 2 + )} +
+
)} diff --git a/samples/auth0-nextjs-nextauthjs/src/pages/credential-issuance.tsx b/samples/auth0-nextjs-nextauthjs/src/pages/credential-issuance.tsx index dc3685e..b0723cd 100644 --- a/samples/auth0-nextjs-nextauthjs/src/pages/credential-issuance.tsx +++ b/samples/auth0-nextjs-nextauthjs/src/pages/credential-issuance.tsx @@ -33,7 +33,7 @@ const fetchCredentialSchema = async (jsonSchemaUrl: string) => { const fetchCredentialTypes = ( issuanceConfigurationId: string -): Promise => { +): Promise => { return fetch( "/api/issuance/credential-types?" + new URLSearchParams({ issuanceConfigurationId }), @@ -41,7 +41,7 @@ const fetchCredentialTypes = ( ).then((res) => res.json()); }; -const fetchIssuanceConfigurations = (): Promise => +const fetchIssuanceConfigurations = (): Promise => fetch("/api/issuance/configuration-options", { method: "GET" }).then((res) => res.json() ); @@ -69,22 +69,22 @@ export default function CredentialIssuance({ // Get did from session const { data: session } = useSession(); - const configurations = useQuery({ + const configurationsQuery = useQuery({ queryKey: ["configurations"], queryFn: fetchIssuanceConfigurations, enabled: !!featureAvailable, }); - const credentialTypes = useQuery({ + const credentialTypesQuery = useQuery({ queryKey: ["types", selectedConfigId], queryFn: ({ queryKey }) => fetchCredentialTypes(queryKey[1]), enabled: !!selectedConfigId, }); - const schema = useQuery({ + const schemaQuery = useQuery({ queryKey: ["schema", selectedTypeId], queryFn: () => { - const credentialType = credentialTypes.data?.find( + const credentialType = credentialTypesQuery.data?.find( (type) => type.credentialTypeId === selectedTypeId ); if (!credentialType) { @@ -190,23 +190,37 @@ export default function CredentialIssuance({ renderOffer(offer) ) : (
- {configurations.isPending && ( + {configurationsQuery.isPending && (
Loading configurations...
)} - {!configurations.isPending && ( - + setFormData({ + ...formData, + selectedConfigId: value as string, + }) + } + /> + )} {selectedConfigId && ( ({ label: type.credentialTypeId, value: type.credentialTypeId, @@ -247,13 +274,13 @@ export default function CredentialIssuance({
)} - {schema.data?.properties.credentialSubject && ( + {schemaQuery.data?.properties.credentialSubject && (

Credential data

Date: Fri, 5 Jul 2024 15:56:47 +0800 Subject: [PATCH 6/7] fix: rename query keys --- .../nextjs/template/src/components/iota/IotaClientPage.tsx | 4 ++-- generator/nextjs/template/src/pages/credential-issuance.tsx | 2 +- .../src/components/iota/IotaClientPage.tsx | 4 ++-- .../src/pages/credential-issuance.tsx | 2 +- .../src/components/iota/IotaClientPage.tsx | 4 ++-- .../auth0-nextjs-nextauthjs/src/pages/credential-issuance.tsx | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/generator/nextjs/template/src/components/iota/IotaClientPage.tsx b/generator/nextjs/template/src/components/iota/IotaClientPage.tsx index 5451aec..a31c421 100644 --- a/generator/nextjs/template/src/components/iota/IotaClientPage.tsx +++ b/generator/nextjs/template/src/components/iota/IotaClientPage.tsx @@ -76,7 +76,7 @@ export default function IotaSessionMultipleRequestsPage({ const { data: session } = useSession(); const configurationsQuery = useQuery({ - queryKey: ["configurations"], + queryKey: ["iotaConfigurations"], queryFn: fetchIotaConfigurations, enabled: !!featureAvailable, }); @@ -93,7 +93,7 @@ export default function IotaSessionMultipleRequestsPage({ }); const iotaQueryOptionsQuery = useQuery({ - queryKey: ["configurations", selectedConfigId], + queryKey: ["queryOptions", selectedConfigId], queryFn: ({ queryKey }) => getQueryOptions(queryKey[1]), enabled: !!selectedConfigId, }); diff --git a/generator/nextjs/template/src/pages/credential-issuance.tsx b/generator/nextjs/template/src/pages/credential-issuance.tsx index b0723cd..a5752c7 100644 --- a/generator/nextjs/template/src/pages/credential-issuance.tsx +++ b/generator/nextjs/template/src/pages/credential-issuance.tsx @@ -70,7 +70,7 @@ export default function CredentialIssuance({ const { data: session } = useSession(); const configurationsQuery = useQuery({ - queryKey: ["configurations"], + queryKey: ["issuanceConfigurations"], queryFn: fetchIssuanceConfigurations, enabled: !!featureAvailable, }); diff --git a/samples/affinidi-nextjs-nextauthjs/src/components/iota/IotaClientPage.tsx b/samples/affinidi-nextjs-nextauthjs/src/components/iota/IotaClientPage.tsx index 5451aec..a31c421 100644 --- a/samples/affinidi-nextjs-nextauthjs/src/components/iota/IotaClientPage.tsx +++ b/samples/affinidi-nextjs-nextauthjs/src/components/iota/IotaClientPage.tsx @@ -76,7 +76,7 @@ export default function IotaSessionMultipleRequestsPage({ const { data: session } = useSession(); const configurationsQuery = useQuery({ - queryKey: ["configurations"], + queryKey: ["iotaConfigurations"], queryFn: fetchIotaConfigurations, enabled: !!featureAvailable, }); @@ -93,7 +93,7 @@ export default function IotaSessionMultipleRequestsPage({ }); const iotaQueryOptionsQuery = useQuery({ - queryKey: ["configurations", selectedConfigId], + queryKey: ["queryOptions", selectedConfigId], queryFn: ({ queryKey }) => getQueryOptions(queryKey[1]), enabled: !!selectedConfigId, }); diff --git a/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx b/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx index b0723cd..a5752c7 100644 --- a/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx +++ b/samples/affinidi-nextjs-nextauthjs/src/pages/credential-issuance.tsx @@ -70,7 +70,7 @@ export default function CredentialIssuance({ const { data: session } = useSession(); const configurationsQuery = useQuery({ - queryKey: ["configurations"], + queryKey: ["issuanceConfigurations"], queryFn: fetchIssuanceConfigurations, enabled: !!featureAvailable, }); diff --git a/samples/auth0-nextjs-nextauthjs/src/components/iota/IotaClientPage.tsx b/samples/auth0-nextjs-nextauthjs/src/components/iota/IotaClientPage.tsx index 5451aec..a31c421 100644 --- a/samples/auth0-nextjs-nextauthjs/src/components/iota/IotaClientPage.tsx +++ b/samples/auth0-nextjs-nextauthjs/src/components/iota/IotaClientPage.tsx @@ -76,7 +76,7 @@ export default function IotaSessionMultipleRequestsPage({ const { data: session } = useSession(); const configurationsQuery = useQuery({ - queryKey: ["configurations"], + queryKey: ["iotaConfigurations"], queryFn: fetchIotaConfigurations, enabled: !!featureAvailable, }); @@ -93,7 +93,7 @@ export default function IotaSessionMultipleRequestsPage({ }); const iotaQueryOptionsQuery = useQuery({ - queryKey: ["configurations", selectedConfigId], + queryKey: ["queryOptions", selectedConfigId], queryFn: ({ queryKey }) => getQueryOptions(queryKey[1]), enabled: !!selectedConfigId, }); diff --git a/samples/auth0-nextjs-nextauthjs/src/pages/credential-issuance.tsx b/samples/auth0-nextjs-nextauthjs/src/pages/credential-issuance.tsx index b0723cd..a5752c7 100644 --- a/samples/auth0-nextjs-nextauthjs/src/pages/credential-issuance.tsx +++ b/samples/auth0-nextjs-nextauthjs/src/pages/credential-issuance.tsx @@ -70,7 +70,7 @@ export default function CredentialIssuance({ const { data: session } = useSession(); const configurationsQuery = useQuery({ - queryKey: ["configurations"], + queryKey: ["issuanceConfigurations"], queryFn: fetchIssuanceConfigurations, enabled: !!featureAvailable, }); From 8ba45f8959ba498f162db70ca0c786d1b9cc01b8 Mon Sep 17 00:00:00 2001 From: Anton Bergman Date: Fri, 5 Jul 2024 16:22:03 +0800 Subject: [PATCH 7/7] fix: revert port change --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e35a26b..dcbeba3 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "install:affinidi-java-springboot": "cd samples/affinidi-java-springboot && sh mvnw install", "start": "concurrently -n w: \"npm:start:*(!template)\"", "start:template": "npm run --prefix generator/template dev -- -p 3000", - "start:affinidi-nextjs-nextauthjs": "npm run --prefix samples/affinidi-nextjs-nextauthjs dev -- -p 3000", + "start:affinidi-nextjs-nextauthjs": "npm run --prefix samples/affinidi-nextjs-nextauthjs dev -- -p 3001", "start:auth0-nextjs-nextauthjs": "npm run --prefix samples/auth0-nextjs-nextauthjs dev -- -p 3002", "start:affinidi-django-authlib": "python3 samples/affinidi-django-authlib/manage.py migrate && python3 samples/affinidi-django-authlib/manage.py runserver 8000", "start:auth0-django-authlib": "python3 samples/auth0-django-authlib/manage.py migrate && python3 samples/auth0-django-authlib/manage.py runserver 8001",