project-portfolio 2.2.1 → 2.2.2
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/README.md
CHANGED
|
@@ -586,6 +586,7 @@ With a curated menu:
|
|
|
586
586
|
| `clientSlug` | `string` | No* | — | Client slug for direct fetch mode |
|
|
587
587
|
| `apiBase` | `string` | No* | — | API base URL for direct fetch mode |
|
|
588
588
|
| `menuId` | `string` | No | — | Slug of a curated menu. Fetches from `/menus/{slug}` for projects. Filters are always shown regardless. |
|
|
589
|
+
| `noCache` | `boolean` | No | `false` | Bypasses the module-level data cache and sets `cache: "no-store"` on all fetch calls. Useful during development or when projects update frequently. |
|
|
589
590
|
| `basePath` | `string` | Yes | — | Base path for project detail links |
|
|
590
591
|
| `viewAllPath` | `string` | Yes | — | Path for the "View All Projects" link |
|
|
591
592
|
| `subtitle` | `string` | No | — | Description shown above the project cards (hidden on mobile) |
|
|
@@ -15,10 +15,16 @@ export interface ProjectMenuClientProps {
|
|
|
15
15
|
clientSlug?: string;
|
|
16
16
|
apiBase?: string;
|
|
17
17
|
/**
|
|
18
|
-
* Optional menu
|
|
19
|
-
* When provided, fetches from /api/v1/clients/{clientSlug}/menus/{
|
|
18
|
+
* Optional menu slug to fetch a specific curated menu instead of all projects.
|
|
19
|
+
* When provided, fetches from /api/v1/clients/{clientSlug}/menus/{slug}
|
|
20
20
|
*/
|
|
21
21
|
menuId?: string;
|
|
22
|
+
/**
|
|
23
|
+
* When true, bypasses the module-level data cache and always fetches fresh data.
|
|
24
|
+
* Also sets fetch cache to "no-store" on all underlying requests.
|
|
25
|
+
* Useful during development or when projects update frequently.
|
|
26
|
+
*/
|
|
27
|
+
noCache?: boolean;
|
|
22
28
|
projects?: Project[];
|
|
23
29
|
schema?: CustomFieldSchema[];
|
|
24
30
|
filterOptions?: {
|
|
@@ -34,5 +40,5 @@ export interface ProjectMenuClientProps {
|
|
|
34
40
|
font?: string;
|
|
35
41
|
maxProjects?: number;
|
|
36
42
|
}
|
|
37
|
-
export declare function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, projects: projectsProp, schema: schemaProp, filterOptions: filterOptionsProp, filterFieldKey: filterFieldKeyProp, filterFieldName: filterFieldNameProp, fieldOptionsMap: fieldOptionsMapProp, subtitle, basePath, viewAllPath, font, maxProjects, }: ProjectMenuClientProps): import("react/jsx-runtime").JSX.Element;
|
|
43
|
+
export declare function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, noCache, projects: projectsProp, schema: schemaProp, filterOptions: filterOptionsProp, filterFieldKey: filterFieldKeyProp, filterFieldName: filterFieldNameProp, fieldOptionsMap: fieldOptionsMapProp, subtitle, basePath, viewAllPath, font, maxProjects, }: ProjectMenuClientProps): import("react/jsx-runtime").JSX.Element;
|
|
38
44
|
//# sourceMappingURL=ProjectMenuClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectMenuClient.d.ts","sourceRoot":"","sources":["../src/ProjectMenuClient.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAoB,MAAM,SAAS,CAAA;AAa3E,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"ProjectMenuClient.d.ts","sourceRoot":"","sources":["../src/ProjectMenuClient.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAoB,MAAM,SAAS,CAAA;AAa3E,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;IACpB,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC5B,aAAa,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC/C,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAmBD,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,UAAU,EACV,OAAO,EACP,MAAM,EACN,OAAe,EACf,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,iBAAiB,EAChC,cAAc,EAAE,kBAAkB,EAClC,eAAe,EAAE,mBAAoC,EACrD,eAAe,EAAE,mBAAwB,EACzC,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,IAAmB,EACnB,WAAe,GAChB,EAAE,sBAAsB,2CAqfxB"}
|
|
@@ -17,25 +17,27 @@ const ACCENT = "oklch(0.78 0.16 85)";
|
|
|
17
17
|
const API_KEY = "pk_live_crmsuTIm7NNfb9uEWBCyv88F6kj2YQUR";
|
|
18
18
|
const DEFAULT_FONT = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
19
19
|
const menuDataCache = new Map();
|
|
20
|
-
export function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, projects: projectsProp, schema: schemaProp, filterOptions: filterOptionsProp, filterFieldKey: filterFieldKeyProp, filterFieldName: filterFieldNameProp = "Project Type", fieldOptionsMap: fieldOptionsMapProp = {}, subtitle, basePath, viewAllPath, font = DEFAULT_FONT, maxProjects = 6, }) {
|
|
20
|
+
export function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, noCache = false, projects: projectsProp, schema: schemaProp, filterOptions: filterOptionsProp, filterFieldKey: filterFieldKeyProp, filterFieldName: filterFieldNameProp = "Project Type", fieldOptionsMap: fieldOptionsMapProp = {}, subtitle, basePath, viewAllPath, font = DEFAULT_FONT, maxProjects = 6, }) {
|
|
21
21
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
22
22
|
const [filtersOpen, setFiltersOpen] = useState(false);
|
|
23
23
|
const [hoveredCard, setHoveredCard] = useState(null);
|
|
24
24
|
const [fetched, setFetched] = useState(null);
|
|
25
25
|
// Self-fetch mode: fires when dataUrl OR (clientSlug + apiBase) are provided.
|
|
26
26
|
// Uses a module-level Promise cache so repeated mounts never re-hit the API.
|
|
27
|
+
// Pass noCache=true to bypass the module cache and always fetch fresh data.
|
|
27
28
|
useEffect(() => {
|
|
28
29
|
const hasDataUrl = !!dataUrl;
|
|
29
30
|
const hasDirectFetch = !!(clientSlug && apiBase);
|
|
30
31
|
if (!hasDataUrl && !hasDirectFetch)
|
|
31
32
|
return;
|
|
32
33
|
let cancelled = false;
|
|
34
|
+
const fetchOpts = noCache ? { cache: "no-store" } : {};
|
|
33
35
|
const cacheKey = dataUrl !== null && dataUrl !== void 0 ? dataUrl : `${clientSlug}:${apiBase}:${menuId !== null && menuId !== void 0 ? menuId : "all"}`;
|
|
34
36
|
async function fetchAndCache() {
|
|
35
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x
|
|
37
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
|
|
36
38
|
// dataUrl mode: fetch from local API route (server-cached, no API key exposed)
|
|
37
39
|
if (dataUrl) {
|
|
38
|
-
const res = await fetch(dataUrl);
|
|
40
|
+
const res = await fetch(dataUrl, fetchOpts);
|
|
39
41
|
const json = res.ok ? await res.json() : {};
|
|
40
42
|
return {
|
|
41
43
|
projects: (_a = json.projects) !== null && _a !== void 0 ? _a : [],
|
|
@@ -46,24 +48,20 @@ export function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, projec
|
|
|
46
48
|
fieldOptionsMap: (_f = json.fieldOptionsMap) !== null && _f !== void 0 ? _f : {},
|
|
47
49
|
};
|
|
48
50
|
}
|
|
49
|
-
// Menu endpoint mode:
|
|
50
|
-
// Also fetch /projects to get schema for filters (menu endpoint may not return it)
|
|
51
|
+
// Menu endpoint mode: /menus/{slug} for projects, /projects for schema+options.
|
|
51
52
|
if (menuId) {
|
|
52
|
-
const [menuRes, projectsRes
|
|
53
|
-
fetch(`${apiBase}/api/v1/clients/${clientSlug}/menus/${menuId}?api_key=${API_KEY}
|
|
54
|
-
fetch(`${apiBase}/api/v1/clients/${clientSlug}/projects?api_key=${API_KEY}
|
|
55
|
-
fetch(`${apiBase}/api/v1/clients/${clientSlug}/fields?api_key=${API_KEY}`),
|
|
53
|
+
const [menuRes, projectsRes] = await Promise.all([
|
|
54
|
+
fetch(`${apiBase}/api/v1/clients/${clientSlug}/menus/${menuId}?api_key=${API_KEY}`, fetchOpts),
|
|
55
|
+
fetch(`${apiBase}/api/v1/clients/${clientSlug}/projects?api_key=${API_KEY}`, fetchOpts),
|
|
56
56
|
]);
|
|
57
57
|
const menuJson = menuRes.ok ? await menuRes.json() : {};
|
|
58
58
|
const projectsJson = projectsRes.ok ? await projectsRes.json() : {};
|
|
59
|
-
const projects = ((
|
|
60
|
-
|
|
61
|
-
const schema = (_o = (_l = (_k = (_j = menuJson === null || menuJson === void 0 ? void 0 : menuJson.client) === null || _j === void 0 ? void 0 : _j.custom_fields_schema) !== null && _k !== void 0 ? _k : menuJson === null || menuJson === void 0 ? void 0 : menuJson.schema) !== null && _l !== void 0 ? _l : (_m = projectsJson === null || projectsJson === void 0 ? void 0 : projectsJson.client) === null || _m === void 0 ? void 0 : _m.custom_fields_schema) !== null && _o !== void 0 ? _o : [];
|
|
62
|
-
const fieldsJson = fieldsRes.ok ? await fieldsRes.json() : { fields: [] };
|
|
59
|
+
const projects = ((_g = menuJson === null || menuJson === void 0 ? void 0 : menuJson.projects) !== null && _g !== void 0 ? _g : []).filter((p) => p.is_published !== false);
|
|
60
|
+
const schema = (_j = (_h = projectsJson === null || projectsJson === void 0 ? void 0 : projectsJson.client) === null || _h === void 0 ? void 0 : _h.custom_fields_schema) !== null && _j !== void 0 ? _j : [];
|
|
63
61
|
const fieldOptionsMap = {};
|
|
64
|
-
for (const field of
|
|
62
|
+
for (const field of schema) {
|
|
65
63
|
const map = {};
|
|
66
|
-
for (const opt of ((
|
|
64
|
+
for (const opt of ((_k = field.options) !== null && _k !== void 0 ? _k : [])) {
|
|
67
65
|
if (typeof opt === "object" && opt.id && opt.label) {
|
|
68
66
|
map[opt.id] = opt.label;
|
|
69
67
|
map[opt.label] = opt.label;
|
|
@@ -71,9 +69,9 @@ export function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, projec
|
|
|
71
69
|
}
|
|
72
70
|
fieldOptionsMap[field.key] = map;
|
|
73
71
|
}
|
|
74
|
-
const filterField = (
|
|
72
|
+
const filterField = (_l = schema.find((f) => f.is_filterable && (f.type === "select" || f.type === "multi-select"))) !== null && _l !== void 0 ? _l : null;
|
|
75
73
|
const filterOptions = filterField
|
|
76
|
-
? ((
|
|
74
|
+
? ((_m = filterField.options) !== null && _m !== void 0 ? _m : []).map((opt) => {
|
|
77
75
|
var _a, _b;
|
|
78
76
|
if (typeof opt === "string")
|
|
79
77
|
return { id: opt.toLowerCase().replace(/\s+/g, "-"), label: opt };
|
|
@@ -84,24 +82,20 @@ export function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, projec
|
|
|
84
82
|
projects,
|
|
85
83
|
schema,
|
|
86
84
|
filterOptions,
|
|
87
|
-
filterFieldKey: (
|
|
88
|
-
filterFieldName: (
|
|
85
|
+
filterFieldKey: (_o = filterField === null || filterField === void 0 ? void 0 : filterField.key) !== null && _o !== void 0 ? _o : null,
|
|
86
|
+
filterFieldName: (_p = filterField === null || filterField === void 0 ? void 0 : filterField.name) !== null && _p !== void 0 ? _p : "Project Type",
|
|
89
87
|
fieldOptionsMap,
|
|
90
88
|
};
|
|
91
89
|
}
|
|
92
|
-
// Direct fetch mode
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
]
|
|
97
|
-
const json = projectsRes.ok ? await projectsRes.json() : {};
|
|
98
|
-
const projects = ((_v = json === null || json === void 0 ? void 0 : json.data) !== null && _v !== void 0 ? _v : []).filter((p) => p.is_published !== false);
|
|
99
|
-
const schema = (_x = (_w = json === null || json === void 0 ? void 0 : json.client) === null || _w === void 0 ? void 0 : _w.custom_fields_schema) !== null && _x !== void 0 ? _x : [];
|
|
100
|
-
const fieldsJson = fieldsRes.ok ? await fieldsRes.json() : { fields: [] };
|
|
90
|
+
// Direct fetch mode — single call, /projects returns everything.
|
|
91
|
+
const res = await fetch(`${apiBase}/api/v1/clients/${clientSlug}/projects?api_key=${API_KEY}`, fetchOpts);
|
|
92
|
+
const json = res.ok ? await res.json() : {};
|
|
93
|
+
const projects = ((_q = json === null || json === void 0 ? void 0 : json.data) !== null && _q !== void 0 ? _q : []).filter((p) => p.is_published !== false);
|
|
94
|
+
const schema = (_s = (_r = json === null || json === void 0 ? void 0 : json.client) === null || _r === void 0 ? void 0 : _r.custom_fields_schema) !== null && _s !== void 0 ? _s : [];
|
|
101
95
|
const fieldOptionsMap = {};
|
|
102
|
-
for (const field of
|
|
96
|
+
for (const field of schema) {
|
|
103
97
|
const map = {};
|
|
104
|
-
for (const opt of ((
|
|
98
|
+
for (const opt of ((_t = field.options) !== null && _t !== void 0 ? _t : [])) {
|
|
105
99
|
if (typeof opt === "object" && opt.id && opt.label) {
|
|
106
100
|
map[opt.id] = opt.label;
|
|
107
101
|
map[opt.label] = opt.label;
|
|
@@ -109,9 +103,9 @@ export function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, projec
|
|
|
109
103
|
}
|
|
110
104
|
fieldOptionsMap[field.key] = map;
|
|
111
105
|
}
|
|
112
|
-
const filterField = (
|
|
106
|
+
const filterField = (_u = schema.find((f) => f.is_filterable && (f.type === "select" || f.type === "multi-select"))) !== null && _u !== void 0 ? _u : null;
|
|
113
107
|
const filterOptions = filterField
|
|
114
|
-
? ((
|
|
108
|
+
? ((_v = filterField.options) !== null && _v !== void 0 ? _v : []).map((opt) => {
|
|
115
109
|
var _a, _b;
|
|
116
110
|
if (typeof opt === "string")
|
|
117
111
|
return { id: opt.toLowerCase().replace(/\s+/g, "-"), label: opt };
|
|
@@ -122,23 +116,26 @@ export function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, projec
|
|
|
122
116
|
projects,
|
|
123
117
|
schema,
|
|
124
118
|
filterOptions,
|
|
125
|
-
filterFieldKey: (
|
|
126
|
-
filterFieldName: (
|
|
119
|
+
filterFieldKey: (_w = filterField === null || filterField === void 0 ? void 0 : filterField.key) !== null && _w !== void 0 ? _w : null,
|
|
120
|
+
filterFieldName: (_x = filterField === null || filterField === void 0 ? void 0 : filterField.name) !== null && _x !== void 0 ? _x : "Project Type",
|
|
127
121
|
fieldOptionsMap,
|
|
128
122
|
};
|
|
129
123
|
}
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
124
|
+
// When noCache=true, skip the module cache entirely and always fetch fresh.
|
|
125
|
+
// Otherwise store the Promise on first call and reuse it on every subsequent mount.
|
|
126
|
+
const getOrFetch = noCache
|
|
127
|
+
? fetchAndCache()
|
|
128
|
+
: (menuDataCache.has(cacheKey)
|
|
129
|
+
? menuDataCache.get(cacheKey)
|
|
130
|
+
: (() => { const p = fetchAndCache(); menuDataCache.set(cacheKey, p); return p; })());
|
|
131
|
+
getOrFetch.then((data) => {
|
|
135
132
|
if (!cancelled)
|
|
136
133
|
setFetched(data);
|
|
137
134
|
}).catch(() => {
|
|
138
135
|
// silently fail — render nothing
|
|
139
136
|
});
|
|
140
137
|
return () => { cancelled = true; };
|
|
141
|
-
}, [dataUrl, clientSlug, apiBase, menuId]);
|
|
138
|
+
}, [dataUrl, clientSlug, apiBase, menuId, noCache]);
|
|
142
139
|
// Resolve data: prefer self-fetched, fall back to props
|
|
143
140
|
const projects = (_b = (_a = fetched === null || fetched === void 0 ? void 0 : fetched.projects) !== null && _a !== void 0 ? _a : projectsProp) !== null && _b !== void 0 ? _b : [];
|
|
144
141
|
const schema = (_d = (_c = fetched === null || fetched === void 0 ? void 0 : fetched.schema) !== null && _c !== void 0 ? _c : schemaProp) !== null && _d !== void 0 ? _d : [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimilarProjects.d.ts","sourceRoot":"","sources":["../src/SimilarProjects.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB;AA0DD,wBAAsB,eAAe,CAAC,EACpC,OAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,QAAsB,EACtB,QAAY,EACZ,UAAe,EACf,OAAgB,EAChB,YAAY,GACb,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"SimilarProjects.d.ts","sourceRoot":"","sources":["../src/SimilarProjects.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB;AA0DD,wBAAsB,eAAe,CAAC,EACpC,OAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,QAAsB,EACtB,QAAY,EACZ,UAAe,EACf,OAAgB,EAChB,YAAY,GACb,EAAE,oBAAoB,2DAiKtB"}
|
package/dist/SimilarProjects.js
CHANGED
|
@@ -100,11 +100,13 @@ export async function SimilarProjects({ filters = {}, excludeSlug, clientSlug, a
|
|
|
100
100
|
}
|
|
101
101
|
// ── List variant (default) ────────────────────────────────────────────────────
|
|
102
102
|
return (_jsxs("section", { style: { borderTop: "1px solid #e4e4e7", maxWidth: "1280px", margin: "0 auto", padding: "3rem 1rem 2rem", boxSizing: "border-box", fontFamily: font }, children: [sharedStyles, header, _jsx("div", { className: "chisel-similar-grid", children: similar.map((p) => {
|
|
103
|
-
var _a, _b, _c, _d, _e;
|
|
103
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
104
104
|
const imgUrl = (_d = (_a = p.image_url) !== null && _a !== void 0 ? _a : (_c = (_b = p.media) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.url) !== null && _d !== void 0 ? _d : null;
|
|
105
|
-
const
|
|
105
|
+
const badgeRaw = badgeField
|
|
106
106
|
? ((_e = parseMultiValue(p.custom_field_values[badgeField.key])[0]) !== null && _e !== void 0 ? _e : null)
|
|
107
107
|
: null;
|
|
108
|
+
const badgeOptMap = badgeField ? ((_f = fieldOptionsMap[badgeField.key]) !== null && _f !== void 0 ? _f : {}) : {};
|
|
109
|
+
const badge = badgeRaw ? ((_g = badgeOptMap[badgeRaw]) !== null && _g !== void 0 ? _g : badgeRaw) : null;
|
|
108
110
|
const loc = locationField
|
|
109
111
|
? p.custom_field_values[locationField.key]
|
|
110
112
|
: null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "project-portfolio",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "Self-contained project portfolio components for Next.js App Router. Includes ProjectPortfolio, ProjectPortfolioClient (with built-in filtering), ProjectDetail, SimilarProjects, ProjectMenu, ProjectMenuClient, and GalleryCarousel. Pass a clientSlug and apiBase — done.",
|
|
5
5
|
"keywords": ["nextjs", "react", "portfolio", "projects", "megamenu", "gallery", "filtering"],
|
|
6
6
|
"license": "MIT",
|