uhc-portal-components-react 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.9 - 2026-08-02
4
+
5
+ - Allow the SOSChain card picker to expose a host-owned card-import action for
6
+ scanning or entering a provider card identifier.
7
+
8
+ ## 0.1.8 - 2026-08-02
9
+
10
+ - Add the shared subject-first SOSChain card picker and workspace for Places,
11
+ IndividualProducts and emergency/civil-protection communications.
12
+ - Keep authorization host-owned: the component receives server-resolved cards
13
+ and capabilities and never treats a browser selection as authority.
14
+
3
15
  ## 0.1.7 - 2026-07-30
4
16
 
5
17
  - Add controlled, actor-neutral invitation-acceptance and subject-access
package/README.md CHANGED
@@ -59,6 +59,9 @@ The package deliberately exposes modules instead of a cloned application:
59
59
  - `SubjectAccessRequestPanel`: controlled QR, numeric-code or `did:web`
60
60
  resolver plus section selector. It deliberately has no scanner role: the
61
61
  same component is reusable by an individual member or a professional.
62
+ - `SoschainWorkspace`: subject-card picker and four-area workspace for Places,
63
+ devices/vehicles and read-only emergency communications. The host supplies
64
+ already-authorized cards and capabilities.
62
65
 
63
66
  Clinical label semantics stay in `gdc-common-utils-ts` / the SDK reader. Hosts
64
67
  pass human titles to `ClinicalSectionSummary`: local `CodeableConcept.text`
@@ -0,0 +1,72 @@
1
+ export type SoschainWorkspaceArea = 'overview' | 'places' | 'products' | 'communications';
2
+ export type SoschainCardSummary = Readonly<{
3
+ identifier: string;
4
+ displayName: string;
5
+ kindLabel: string;
6
+ selected?: boolean;
7
+ openHref: string;
8
+ }>;
9
+ export type SoschainAssociationSummary = Readonly<{
10
+ identifier: string;
11
+ name: string;
12
+ kindLabel: string;
13
+ detail: string;
14
+ statusLabel: string;
15
+ }>;
16
+ export type SoschainCommunicationSummary = Readonly<{
17
+ identifier: string;
18
+ sender: string;
19
+ categoryLabel: string;
20
+ subject: string;
21
+ body: string;
22
+ occurredAt: string;
23
+ placeLabel?: string;
24
+ }>;
25
+ export type SoschainWorkspaceCopy = Readonly<{
26
+ cardsTitle: string;
27
+ cardsDescription: string;
28
+ openCard: string;
29
+ selectedCard: string;
30
+ workspaceEyebrow: string;
31
+ noCardTitle: string;
32
+ noCardBody: string;
33
+ areas: Record<SoschainWorkspaceArea, string>;
34
+ overviewTitle: string;
35
+ overviewBody: string;
36
+ placesTitle: string;
37
+ placesBody: string;
38
+ productsTitle: string;
39
+ productsBody: string;
40
+ communicationsTitle: string;
41
+ communicationsBody: string;
42
+ addPlace: string;
43
+ addProduct: string;
44
+ emptyPlaces: string;
45
+ emptyProducts: string;
46
+ emptyCommunications: string;
47
+ readOnly: string;
48
+ importCard?: string;
49
+ }>;
50
+ export type SoschainWorkspaceProps = Readonly<{
51
+ copy: SoschainWorkspaceCopy;
52
+ cards: readonly SoschainCardSummary[];
53
+ selectedCard?: SoschainCardSummary;
54
+ activeArea: SoschainWorkspaceArea;
55
+ areaHrefs: Record<SoschainWorkspaceArea, string>;
56
+ places: readonly SoschainAssociationSummary[];
57
+ products: readonly SoschainAssociationSummary[];
58
+ communications: readonly SoschainCommunicationSummary[];
59
+ canManageAssociations: boolean;
60
+ addPlaceHref?: string;
61
+ addProductHref?: string;
62
+ importCardHref?: string;
63
+ }>;
64
+ /**
65
+ * Shared subject-first SOSChain workspace for personal and professional apps.
66
+ *
67
+ * The host supplies already-authorized cards, associations, capabilities and
68
+ * communications. This presentational component never derives authority from
69
+ * a selected role, card, tab or browser-controlled value.
70
+ */
71
+ export declare function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, canManageAssociations, addPlaceHref, addProductHref, importCardHref, }: SoschainWorkspaceProps): import("react").JSX.Element;
72
+ //# sourceMappingURL=SoschainWorkspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SoschainWorkspace.d.ts","sourceRoot":"","sources":["../src/SoschainWorkspace.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ function AssociationList({ items, empty }) {
3
+ if (items.length === 0)
4
+ return _jsx("p", { className: "uhcp-sos-empty", children: empty });
5
+ return (_jsx("ul", { className: "uhcp-sos-entity-list", children: items.map((item) => (_jsxs("li", { children: [_jsx("span", { className: "uhcp-sos-kind", children: item.kindLabel }), _jsx("strong", { children: item.name }), _jsx("span", { children: item.detail }), _jsx("small", { children: item.statusLabel })] }, item.identifier))) }));
6
+ }
7
+ /**
8
+ * Shared subject-first SOSChain workspace for personal and professional apps.
9
+ *
10
+ * The host supplies already-authorized cards, associations, capabilities and
11
+ * communications. This presentational component never derives authority from
12
+ * a selected role, card, tab or browser-controlled value.
13
+ */
14
+ export function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, canManageAssociations, addPlaceHref, addProductHref, importCardHref, }) {
15
+ if (!selectedCard) {
16
+ return (_jsxs("section", { className: "uhcp-sos-wrap", "aria-labelledby": "sos-card-picker-title", children: [_jsxs("header", { className: "uhcp-sos-heading", children: [_jsx("span", { children: copy.workspaceEyebrow }), _jsx("h1", { id: "sos-card-picker-title", children: copy.cardsTitle }), _jsx("p", { children: copy.cardsDescription }), importCardHref && copy.importCard ? _jsxs("a", { href: importCardHref, children: [copy.importCard, " \u2192"] }) : null] }), cards.length === 0 ? (_jsxs("div", { className: "uhcp-sos-empty-panel", children: [_jsx("h2", { children: copy.noCardTitle }), _jsx("p", { children: copy.noCardBody })] })) : (_jsx("ul", { className: "uhcp-sos-card-grid", children: cards.map((card) => (_jsx("li", { children: _jsxs("a", { href: card.openHref, children: [_jsx("span", { children: card.kindLabel }), _jsx("strong", { children: card.displayName }), _jsx("small", { children: card.identifier }), _jsxs("b", { children: [copy.openCard, " \u2192"] })] }) }, card.identifier))) }))] }));
17
+ }
18
+ const title = activeArea === 'places'
19
+ ? copy.placesTitle
20
+ : activeArea === 'products'
21
+ ? copy.productsTitle
22
+ : activeArea === 'communications'
23
+ ? copy.communicationsTitle
24
+ : copy.overviewTitle;
25
+ const body = activeArea === 'places'
26
+ ? copy.placesBody
27
+ : activeArea === 'products'
28
+ ? copy.productsBody
29
+ : activeArea === 'communications'
30
+ ? copy.communicationsBody
31
+ : copy.overviewBody;
32
+ return (_jsxs("section", { className: "uhcp-sos-wrap", children: [_jsxs("header", { className: "uhcp-sos-heading", children: [_jsx("span", { children: copy.selectedCard }), _jsx("h1", { children: selectedCard.displayName }), _jsxs("p", { children: [selectedCard.kindLabel, " \u00B7 ", selectedCard.identifier] })] }), _jsx("nav", { className: "uhcp-sos-tabs", "aria-label": copy.workspaceEyebrow, children: Object.keys(areaHrefs).map((area) => (_jsx("a", { href: areaHrefs[area], "aria-current": activeArea === area ? 'page' : undefined, children: copy.areas[area] }, area))) }), _jsxs("div", { className: "uhcp-sos-panel", children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { children: title }), _jsx("p", { children: body })] }), !canManageAssociations && activeArea !== 'communications' && (_jsx("span", { className: "uhcp-sos-readonly", children: copy.readOnly })), canManageAssociations && activeArea === 'places' && addPlaceHref && _jsx("a", { href: addPlaceHref, children: copy.addPlace }), canManageAssociations && activeArea === 'products' && addProductHref && _jsx("a", { href: addProductHref, children: copy.addProduct })] }), activeArea === 'overview' && (_jsxs("div", { className: "uhcp-sos-overview-grid", children: [_jsxs("article", { children: [_jsx("strong", { children: places.length }), _jsx("span", { children: copy.areas.places })] }), _jsxs("article", { children: [_jsx("strong", { children: products.length }), _jsx("span", { children: copy.areas.products })] }), _jsxs("article", { children: [_jsx("strong", { children: communications.length }), _jsx("span", { children: copy.areas.communications })] })] })), activeArea === 'places' && _jsx(AssociationList, { items: places, empty: copy.emptyPlaces }), activeArea === 'products' && _jsx(AssociationList, { items: products, empty: copy.emptyProducts }), activeArea === 'communications' && (communications.length === 0 ? _jsx("p", { className: "uhcp-sos-empty", children: copy.emptyCommunications }) : (_jsx("ol", { className: "uhcp-sos-timeline", children: communications.map((message) => (_jsxs("li", { children: [_jsxs("div", { children: [_jsx("span", { children: message.categoryLabel }), _jsx("time", { children: message.occurredAt })] }), _jsx("strong", { children: message.subject }), _jsx("p", { children: message.body }), _jsxs("small", { children: [message.sender, message.placeLabel ? ` · ${message.placeLabel}` : ''] })] }, message.identifier))) })))] })] }));
33
+ }
package/dist/index.d.ts CHANGED
@@ -9,4 +9,5 @@ export * from './ClinicalSectionSummary.js';
9
9
  export * from './IpsBundleSummary.js';
10
10
  export * from './InvitationAcceptancePanel.js';
11
11
  export * from './SubjectAccessRequestPanel.js';
12
+ export * from './SoschainWorkspace.js';
12
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA"}
package/dist/index.js CHANGED
@@ -9,3 +9,4 @@ export * from './ClinicalSectionSummary.js';
9
9
  export * from './IpsBundleSummary.js';
10
10
  export * from './InvitationAcceptancePanel.js';
11
11
  export * from './SubjectAccessRequestPanel.js';
12
+ export * from './SoschainWorkspace.js';
package/dist/styles.css CHANGED
@@ -264,3 +264,36 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
264
264
  @media (prefers-reduced-motion: reduce) {
265
265
  .uhcp-access-card { transition: none; }
266
266
  }
267
+ .uhcp-sos-wrap { margin: 0 auto; max-width: 1160px; padding: clamp(1.25rem, 4vw, 3rem); }
268
+ .uhcp-sos-heading > span, .uhcp-sos-kind { color: var(--uhcp-emerald); font-size: .75rem; font-weight: 900; letter-spacing: .12em; text-transform: uppercase; }
269
+ .uhcp-sos-heading h1 { font-size: clamp(2rem, 5vw, 3.75rem); letter-spacing: -.04em; margin: .45rem 0; }
270
+ .uhcp-sos-heading p, .uhcp-sos-panel header p { color: var(--uhcp-muted); line-height: 1.6; margin: 0; }
271
+ .uhcp-sos-card-grid, .uhcp-sos-entity-list { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); list-style: none; margin: 2rem 0 0; padding: 0; }
272
+ .uhcp-sos-card-grid a, .uhcp-sos-entity-list li { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: 1.5rem; color: var(--uhcp-text); display: grid; gap: .65rem; padding: 1.4rem; text-decoration: none; }
273
+ .uhcp-sos-card-grid a:hover { border-color: var(--uhcp-turquoise); transform: translateY(-2px); }
274
+ .uhcp-sos-card-grid a:focus-visible, .uhcp-sos-tabs a:focus-visible, .uhcp-sos-panel a:focus-visible { outline: 3px solid var(--uhcp-turquoise); outline-offset: 3px; }
275
+ .uhcp-sos-card-grid span, .uhcp-sos-card-grid small, .uhcp-sos-entity-list span, .uhcp-sos-entity-list small { color: var(--uhcp-muted); }
276
+ .uhcp-sos-card-grid b { color: var(--uhcp-turquoise); }
277
+ .uhcp-sos-tabs { display: flex; gap: .5rem; margin: 2rem 0 1rem; overflow-x: auto; padding: .25rem; }
278
+ .uhcp-sos-tabs a { border-radius: 999px; color: var(--uhcp-muted); font-weight: 800; padding: .75rem 1rem; text-decoration: none; white-space: nowrap; }
279
+ .uhcp-sos-tabs a[aria-current='page'] { background: linear-gradient(135deg, var(--uhcp-action-start), var(--uhcp-action-end)); color: #fff; }
280
+ .uhcp-sos-panel, .uhcp-sos-empty-panel { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: 2rem; padding: clamp(1.25rem, 4vw, 2.25rem); }
281
+ .uhcp-sos-panel > header { align-items: flex-start; display: flex; gap: 1rem; justify-content: space-between; }
282
+ .uhcp-sos-panel h2 { margin: 0 0 .35rem; }
283
+ .uhcp-sos-panel > header > a { background: linear-gradient(135deg, var(--uhcp-action-start), var(--uhcp-action-end)); border-radius: 999px; color: #fff; font-weight: 800; padding: .75rem 1rem; text-decoration: none; white-space: nowrap; }
284
+ .uhcp-sos-readonly { background: var(--uhcp-panel-muted); border-radius: 999px; color: var(--uhcp-muted); font-size: .75rem; font-weight: 800; padding: .55rem .75rem; white-space: nowrap; }
285
+ .uhcp-sos-overview-grid { display: grid; gap: 1rem; grid-template-columns: repeat(3, 1fr); margin-top: 2rem; }
286
+ .uhcp-sos-overview-grid article { background: var(--uhcp-panel-muted); border-radius: 1.25rem; display: grid; gap: .3rem; padding: 1.25rem; }
287
+ .uhcp-sos-overview-grid strong { color: var(--uhcp-turquoise); font-size: 2.25rem; }
288
+ .uhcp-sos-overview-grid span, .uhcp-sos-empty { color: var(--uhcp-muted); }
289
+ .uhcp-sos-timeline { display: grid; gap: 0; list-style: none; margin: 2rem 0 0; padding: 0; }
290
+ .uhcp-sos-timeline li { border-left: 2px solid var(--uhcp-border); padding: 0 0 1.75rem 1.5rem; position: relative; }
291
+ .uhcp-sos-timeline li::before { background: var(--uhcp-turquoise); border-radius: 50%; content: ''; height: .75rem; left: -.44rem; position: absolute; top: .2rem; width: .75rem; }
292
+ .uhcp-sos-timeline div { display: flex; gap: 1rem; justify-content: space-between; }
293
+ .uhcp-sos-timeline div span { color: var(--uhcp-emerald); font-size: .75rem; font-weight: 900; text-transform: uppercase; }
294
+ .uhcp-sos-timeline time, .uhcp-sos-timeline small { color: var(--uhcp-muted); font-size: .8rem; }
295
+ .uhcp-sos-timeline p { line-height: 1.55; }
296
+ @media (max-width: 620px) {
297
+ .uhcp-sos-overview-grid { grid-template-columns: 1fr; }
298
+ .uhcp-sos-panel > header { display: grid; }
299
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uhc-portal-components-react",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Brand-neutral React portal shell, account preferences and protected-profile UI for UHC and VetChain portals.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",