diff --git a/.changeset/upset-mugs-appear.md b/.changeset/upset-mugs-appear.md new file mode 100644 index 0000000000..edacfd5c33 --- /dev/null +++ b/.changeset/upset-mugs-appear.md @@ -0,0 +1,6 @@ +--- +'@learncard/vc-templates-plugin': patch +'@learncard/react': patch +--- + +Properly handle Obv3 alignments field diff --git a/packages/plugins/vc-templates/src/templates.ts b/packages/plugins/vc-templates/src/templates.ts index 2294d38e26..4ebdf86077 100644 --- a/packages/plugins/vc-templates/src/templates.ts +++ b/packages/plugins/vc-templates/src/templates.ts @@ -118,6 +118,7 @@ export const VC_TEMPLATES: { display, familyTitles, skills, + alignments, groupID = '', } = {}, crypto @@ -146,6 +147,7 @@ export const VC_TEMPLATES: { criteria: { narrative: achievementNarrative, }, + ...(alignments && alignments.length ? { alignments } : {}), }, }, display, @@ -172,6 +174,7 @@ export const VC_TEMPLATES: { address, attachments, skills, + alignments, display, familyTitles, boostID, @@ -204,16 +207,17 @@ export const VC_TEMPLATES: { criteria: { narrative: achievementNarrative, }, + ...(alignments && alignments.length ? { alignments } : {}), }, }, ...(address ? { - address: { - type: ['Address'], - ...address, - ...(address.geo ? { geo: { type: ['GeoCoordinates'], ...address.geo } } : {}), - }, - } + address: { + type: ['Address'], + ...address, + ...(address.geo ? { geo: { type: ['GeoCoordinates'], ...address.geo } } : {}), + }, + } : {}), display, familyTitles, diff --git a/packages/plugins/vc-templates/src/types.ts b/packages/plugins/vc-templates/src/types.ts index 6106b5af04..634e6fad0b 100644 --- a/packages/plugins/vc-templates/src/types.ts +++ b/packages/plugins/vc-templates/src/types.ts @@ -1,4 +1,4 @@ -import { UnsignedVC, VC, UnsignedVP } from '@learncard/types'; +import { UnsignedVC, VC, UnsignedVP, Alignment } from '@learncard/types'; import { DiscriminatedUnionize } from './type.helpers'; import { Plugin } from '@learncard/core'; @@ -90,6 +90,8 @@ export type BoostTemplate = { achievementImage?: string; attachments?: BoostAttachment[]; skills?: BoostSkills[]; + /** OBv3 alignment targets associated with the achievement */ + alignments?: Alignment[]; display?: BoostDisplay; familyTitles?: BoostFamilyTitles; boostID?: BoostID; diff --git a/packages/react-learn-card/src/components/CertificateDisplayCard/AlignmentRow.tsx b/packages/react-learn-card/src/components/CertificateDisplayCard/AlignmentRow.tsx index a40c5eacd3..e6eed8d327 100644 --- a/packages/react-learn-card/src/components/CertificateDisplayCard/AlignmentRow.tsx +++ b/packages/react-learn-card/src/components/CertificateDisplayCard/AlignmentRow.tsx @@ -1,24 +1,20 @@ import React from 'react'; import CaretRightFilled from '../../assets/images/CaretRightFilled.svg'; -type AlignmentsRowProps = { - url?: string - name?: string - framework?: string +type AlignmentRowProps = { + url?: string; + name?: string; + framework?: string; }; -const AlignmentRow:React.FC = ({ - url, - name, - framework - }) => { +const AlignmentRow: React.FC = ({ url, name, framework }) => { return (
-

{framework}

- {/* this might need to change to a link depends on how it comes back after the api call */} - +

{framework}

+ {/* this might need to change to a link depends on how it comes back after the api call */} +
); }; diff --git a/packages/react-learn-card/src/components/CertificateDisplayCard/AlignmentsBox.tsx b/packages/react-learn-card/src/components/CertificateDisplayCard/AlignmentsBox.tsx index a6510e6d5c..18a8dc188a 100644 --- a/packages/react-learn-card/src/components/CertificateDisplayCard/AlignmentsBox.tsx +++ b/packages/react-learn-card/src/components/CertificateDisplayCard/AlignmentsBox.tsx @@ -8,14 +8,14 @@ type Alignment = { targetUrl: string; targetName: string; targetFramework: string; -} +}; type AlignmentsBoxProps = { alignment: Alignment | Alignment[]; - style: 'Certificate' | 'boost'; + style: 'Certificate' | 'boost'; }; -const AlignmentsBox:React.FC = ({ alignment, style }) => { +const AlignmentsBox: React.FC = ({ alignment, style }) => { const [showInfo, setShowInfo] = useState(false); const alignmentText = ` Alignments in your Open Badge credential link your achievement to established frameworks, standards, or competencies. @@ -42,17 +42,20 @@ const AlignmentsBox:React.FC = ({ alignment, style }) => { return (
-

Alignments

+

+ Alignments +

- {showInfo && ( - setShowInfo(false)} - /> - )} + {showInfo && setShowInfo(false)} />} {alignments}
); diff --git a/packages/react-learn-card/src/components/CertificateDisplayCard/CertificateBackFace.tsx b/packages/react-learn-card/src/components/CertificateDisplayCard/CertificateBackFace.tsx index f3e91b147a..680d895148 100644 --- a/packages/react-learn-card/src/components/CertificateDisplayCard/CertificateBackFace.tsx +++ b/packages/react-learn-card/src/components/CertificateDisplayCard/CertificateBackFace.tsx @@ -50,7 +50,7 @@ export const CertificateBackFace: React.FC = ({ const { description } = credentialSubject?.achievement ?? {}; const criteria = credentialSubject?.achievement?.criteria?.narrative; - const alignment = credentialSubject?.achievement?.alignment; + const alignments = credentialSubject?.achievement?.alignments; const credentialDarkColor = getCategoryDarkColor(categoryType); @@ -115,7 +115,7 @@ export const CertificateBackFace: React.FC = ({ /> )} - {alignment && } + {alignments && } {verificationItems && verificationItems.length > 0 && ( diff --git a/packages/react-learn-card/src/components/CertificateDisplayCard/CertificateDisplayCard.stories.tsx b/packages/react-learn-card/src/components/CertificateDisplayCard/CertificateDisplayCard.stories.tsx index 98a6aea4e8..2a6d65149e 100644 --- a/packages/react-learn-card/src/components/CertificateDisplayCard/CertificateDisplayCard.stories.tsx +++ b/packages/react-learn-card/src/components/CertificateDisplayCard/CertificateDisplayCard.stories.tsx @@ -1,6 +1,8 @@ import React from 'react'; import { Story, Meta } from '@storybook/react'; import CertificateDisplayCard from './CertificateDisplayCard'; +import { AllFieldsCredential } from '../../helpers/test.helpers'; +import { TestVerificationItems } from '../../helpers/test.helpers'; export default { title: 'CertificateDisplayCard', @@ -12,4 +14,16 @@ export default { const Template: Story = args => ; export const CertificateDisplayCardTest = Template.bind({}); -CertificateDisplayCardTest.args = {}; +CertificateDisplayCardTest.args = { + credential: AllFieldsCredential, + verificationItems: [ + TestVerificationItems.SUCCESS.PROOF, + TestVerificationItems.SUCCESS.NO_EXPIRATION, + TestVerificationItems.SUCCESS.NOT_EXPIRED, + TestVerificationItems.FAILED.EXPIRED, + TestVerificationItems.FAILED.CONTEXT, + TestVerificationItems.FAILED.SIGNATURE, + TestVerificationItems.FAILED.PROOF_TYPE, + TestVerificationItems.FAILED.APPLICABLE_PROOF, + ], +}; diff --git a/packages/react-learn-card/src/components/MeritBadgeDisplayCard/AlignmentRow.tsx b/packages/react-learn-card/src/components/MeritBadgeDisplayCard/AlignmentRow.tsx index a40c5eacd3..e6037b8277 100644 --- a/packages/react-learn-card/src/components/MeritBadgeDisplayCard/AlignmentRow.tsx +++ b/packages/react-learn-card/src/components/MeritBadgeDisplayCard/AlignmentRow.tsx @@ -2,23 +2,19 @@ import React from 'react'; import CaretRightFilled from '../../assets/images/CaretRightFilled.svg'; type AlignmentsRowProps = { - url?: string - name?: string - framework?: string + url?: string; + name?: string; + framework?: string; }; -const AlignmentRow:React.FC = ({ - url, - name, - framework - }) => { +const AlignmentRow: React.FC = ({ url, name, framework }) => { return (
-

{framework}

- {/* this might need to change to a link depends on how it comes back after the api call */} - +

{framework}

+ {/* this might need to change to a link depends on how it comes back after the api call */} +
); }; diff --git a/packages/react-learn-card/src/components/MeritBadgeDisplayCard/AlignmentsBox.tsx b/packages/react-learn-card/src/components/MeritBadgeDisplayCard/AlignmentsBox.tsx index a9a9513261..745043a4c6 100644 --- a/packages/react-learn-card/src/components/MeritBadgeDisplayCard/AlignmentsBox.tsx +++ b/packages/react-learn-card/src/components/MeritBadgeDisplayCard/AlignmentsBox.tsx @@ -24,20 +24,20 @@ const AlignmentsBox: React.FC = ({ alignment, style }) => { const alignments = Array.isArray(alignment) ? alignment.map((object, index) => ( - - )) + + )) : alignment && ( - - ); + + ); return (
diff --git a/packages/react-learn-card/src/components/MeritBadgeDisplayCard/MeritBadgeBackFace.tsx b/packages/react-learn-card/src/components/MeritBadgeDisplayCard/MeritBadgeBackFace.tsx index 84e35f96ab..ce7556261a 100644 --- a/packages/react-learn-card/src/components/MeritBadgeDisplayCard/MeritBadgeBackFace.tsx +++ b/packages/react-learn-card/src/components/MeritBadgeDisplayCard/MeritBadgeBackFace.tsx @@ -50,7 +50,7 @@ export const MeritBadgeBackFace: React.FC = ({ const { description } = credentialSubject?.achievement ?? {}; const criteria = credentialSubject?.achievement?.criteria?.narrative; - const alignment = credentialSubject?.achievement?.alignment; + const alignments = credentialSubject?.achievement?.alignments; const credentialDarkColor = getCategoryDarkColor(categoryType); @@ -115,7 +115,7 @@ export const MeritBadgeBackFace: React.FC = ({ /> )} - {alignment && } + {alignments && } {verificationItems && verificationItems.length > 0 && ( diff --git a/packages/react-learn-card/src/components/VCDisplayCard2/VC2BackFace.tsx b/packages/react-learn-card/src/components/VCDisplayCard2/VC2BackFace.tsx index 5156a964b8..86b329d024 100644 --- a/packages/react-learn-card/src/components/VCDisplayCard2/VC2BackFace.tsx +++ b/packages/react-learn-card/src/components/VCDisplayCard2/VC2BackFace.tsx @@ -75,7 +75,7 @@ const VC2BackFace: React.FC = ({ : undefined; const criteria = achievement?.criteria?.narrative; const description = achievement?.description; - const alignment = achievement?.alignment; + const alignments = achievement?.alignments; /* const tags = credential.credentialSubject.achievement?.tag; @@ -164,7 +164,7 @@ const VC2BackFace: React.FC = ({ )} {/* {credential.notes && } */} - {alignment && } + {alignments && } {verificationItems && verificationItems.length > 0 && ( diff --git a/packages/react-learn-card/src/components/svgs/ThreeDotVertical.tsx b/packages/react-learn-card/src/components/svgs/ThreeDotVertical.tsx index 30fb517ca1..b0db5c77dd 100644 --- a/packages/react-learn-card/src/components/svgs/ThreeDotVertical.tsx +++ b/packages/react-learn-card/src/components/svgs/ThreeDotVertical.tsx @@ -14,25 +14,25 @@ export const ThreeDotVertical = ({ className }: { className?: string }) => { d="M8.4375 10C8.4375 10.8629 9.13706 11.5625 10 11.5625C10.8629 11.5625 11.5625 10.8629 11.5625 10C11.5625 9.13706 10.8629 8.4375 10 8.4375C9.13706 8.4375 8.4375 9.13705 8.4375 10Z" fill="#6F7590" stroke="#6F7590" - stroke-width="2" - stroke-linecap="round" - stroke-linejoin="round" + strokeWidth="2" + strokeLinecap="round" + strokeLinejoin="round" /> ); diff --git a/packages/react-learn-card/src/helpers/test.helpers.ts b/packages/react-learn-card/src/helpers/test.helpers.ts index 9e591e5f0a..18d176d83e 100644 --- a/packages/react-learn-card/src/helpers/test.helpers.ts +++ b/packages/react-learn-card/src/helpers/test.helpers.ts @@ -103,6 +103,26 @@ export const AllFieldsCredential = { narrative: 'You really know your crednetials! Pretty rad. Being able to find and handle all of these fields is incredible! This narrative is going to be pretty long so that we can see if you can handle long blocks of text too. This should probably be truncated off by now or something.', }, + alignments: [ + { + type: 'Alignment', + targetType: 'Competency', + targetName: 'Teamwork', + targetDescription: 'Teamwork is the ability to work well with others', + targetFramework: '21st Century Skills', + targetUrl: 'https://example.com/alignments/21st-century-skills/teamwork', + targetCode: '123', + }, + { + type: ['Alignment'], + targetType: 'Competency', + targetName: 'Quick Thinker', + targetDescription: 'Quick Thinker is the ability to think quickly', + targetFramework: '21st Century Skills', + targetUrl: 'https://example.com/alignments/21st-century-skills/quick-thinker', + targetCode: '456', + }, + ], }, }, proof: {