project-portfolio 2.0.0 → 2.1.0
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 +349 -94
- package/dist/GalleryCarousel.d.ts +3 -2
- package/dist/GalleryCarousel.d.ts.map +1 -1
- package/dist/GalleryCarousel.js +1 -1
- package/dist/ProjectDetail.js +1 -1
- package/dist/ProjectMenu.d.ts +11 -3
- package/dist/ProjectMenu.d.ts.map +1 -1
- package/dist/ProjectMenu.js +57 -30
- package/dist/ProjectMenuClient.d.ts +6 -1
- package/dist/ProjectMenuClient.d.ts.map +1 -1
- package/dist/ProjectMenuClient.js +167 -103
- package/dist/ProjectPortfolioClient.d.ts.map +1 -1
- package/dist/ProjectPortfolioClient.js +6 -1
- package/dist/SimilarProjects.d.ts +13 -1
- package/dist/SimilarProjects.d.ts.map +1 -1
- package/dist/SimilarProjects.js +70 -24
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GalleryCarousel.d.ts","sourceRoot":"","sources":["../src/GalleryCarousel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAIpC,
|
|
1
|
+
{"version":3,"file":"GalleryCarousel.d.ts","sourceRoot":"","sources":["../src/GalleryCarousel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAIpC,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,YAAY,GACb,EAAE,oBAAoB,kDAwJtB"}
|
package/dist/GalleryCarousel.js
CHANGED
|
@@ -65,7 +65,7 @@ export function GalleryCarousel({ images, projectTitle, }) {
|
|
|
65
65
|
margin: 0,
|
|
66
66
|
padding: "0 1rem",
|
|
67
67
|
fontFamily: font,
|
|
68
|
-
}, children: caption })), total > 1 && (_jsx("div", { style: { display: "flex", gap: "8px",
|
|
68
|
+
}, children: caption })), total > 1 && (_jsx("div", { style: { display: "flex", gap: "8px", overflowX: "auto", WebkitOverflowScrolling: "touch", paddingBottom: "4px" }, children: images.map((img, i) => {
|
|
69
69
|
var _a;
|
|
70
70
|
return (_jsx("button", { onClick: () => setCurrent(i), "aria-label": `View image ${i + 1}`, style: {
|
|
71
71
|
width: "72px",
|
package/dist/ProjectDetail.js
CHANGED
|
@@ -83,7 +83,7 @@ export async function ProjectDetail({ slug, clientSlug, apiBase, backPath = "/pr
|
|
|
83
83
|
return isNaN(n) ? String(raw) : String(Math.round(n));
|
|
84
84
|
})();
|
|
85
85
|
const font = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
86
|
-
return (_jsxs("main", { style: { minHeight: "100vh", backgroundColor: "#fff", fontFamily: font }, children: [_jsxs("section", { className: "chisel-hero-img", style: { position: "relative", width: "100%", overflow: "hidden" }, children: [imageUrl ? (_jsx("img", { src: imageUrl, alt: project.title, style: { width: "100%", height: "100%", objectFit: "cover", display: "block" } })) : (_jsx("div", { style: { position: "absolute", inset: 0, backgroundColor: "#27272a" } })), _jsx("div", { style: { position: "absolute", inset: 0, background: "linear-gradient(to top, rgba(0,0,0,0.82) 0%, rgba(0,0,0,0.38) 50%, rgba(0,0,0,0.12) 100%)" } }), _jsxs("div", { style: { position: "absolute", bottom: 0, left: 0, right: 0, padding: "0 1.5rem
|
|
86
|
+
return (_jsxs("main", { style: { minHeight: "100vh", backgroundColor: "#fff", fontFamily: font }, children: [_jsxs("section", { className: "chisel-hero-img", style: { position: "relative", width: "100%", overflow: "hidden" }, children: [imageUrl ? (_jsx("img", { src: imageUrl, alt: project.title, style: { width: "100%", height: "100%", objectFit: "cover", display: "block" } })) : (_jsx("div", { style: { position: "absolute", inset: 0, backgroundColor: "#27272a" } })), _jsx("div", { style: { position: "absolute", inset: 0, background: "linear-gradient(to top, rgba(0,0,0,0.82) 0%, rgba(0,0,0,0.38) 50%, rgba(0,0,0,0.12) 100%)" } }), _jsxs("div", { style: { position: "absolute", bottom: 0, left: 0, right: 0, padding: "0 1rem 1.5rem", maxWidth: "900px" }, children: [badgeValue && (_jsx("p", { style: { color: "#f18a00", fontSize: "11px", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", margin: "0 0 10px 0" }, children: badgeValue })), _jsx("h1", { style: { color: "#fff", fontWeight: 700, fontSize: "clamp(28px, 4vw, 52px)", lineHeight: 1.1, margin: "0 0 12px 0", fontFamily: font }, children: project.title }), locationString && (_jsxs("p", { style: { display: "flex", alignItems: "center", gap: "6px", color: "rgba(255,255,255,0.75)", fontSize: "15px", margin: 0 }, children: [_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { flexShrink: 0 }, children: [_jsx("path", { d: "M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" }), _jsx("circle", { cx: "12", cy: "10", r: "3" })] }), locationString] }))] })] }), _jsxs("section", { style: { borderBottom: "1px solid #e4e4e7", backgroundColor: "#fff" }, children: [_jsx("style", { children: `
|
|
87
87
|
.chisel-stats-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.25rem; }
|
|
88
88
|
@media (min-width: 768px) { .chisel-stats-grid { grid-template-columns: repeat(4, 1fr); gap: 2rem; } }
|
|
89
89
|
.chisel-gallery-placeholder { display: grid; grid-template-columns: 1fr; gap: 12px; }
|
package/dist/ProjectMenu.d.ts
CHANGED
|
@@ -4,6 +4,11 @@ export interface ProjectMenuProps {
|
|
|
4
4
|
clientSlug: string;
|
|
5
5
|
/** API base URL e.g. "https://nexus.chiselandco.com" */
|
|
6
6
|
apiBase: string;
|
|
7
|
+
/**
|
|
8
|
+
* Optional menu ID to fetch a specific curated menu instead of all projects.
|
|
9
|
+
* When provided, fetches from /api/v1/clients/{clientSlug}/menus/{menuId}
|
|
10
|
+
*/
|
|
11
|
+
menuId?: string;
|
|
7
12
|
/** Base path for project detail links. Defaults to "/projects" */
|
|
8
13
|
basePath?: string;
|
|
9
14
|
/** Path for the "View All" link. Defaults to basePath */
|
|
@@ -46,14 +51,17 @@ export interface ProjectMenuProps {
|
|
|
46
51
|
* import { revalidateTag } from "next/cache"
|
|
47
52
|
* revalidateTag("chisel-menu-my-client")
|
|
48
53
|
*/
|
|
49
|
-
export declare function createMenuHandler({ clientSlug, apiBase, revalidate, }: {
|
|
54
|
+
export declare function createMenuHandler({ clientSlug, apiBase, menuId, revalidate, }: {
|
|
50
55
|
clientSlug: string;
|
|
51
56
|
apiBase: string;
|
|
57
|
+
/** Optional menu ID to fetch a specific curated menu instead of all projects */
|
|
58
|
+
menuId?: string;
|
|
52
59
|
revalidate?: number;
|
|
53
60
|
}): (request: Request) => Promise<Response>;
|
|
54
|
-
export declare function fetchProjectMenuData({ apiBase, clientSlug, revalidate, noCache, }: {
|
|
61
|
+
export declare function fetchProjectMenuData({ apiBase, clientSlug, menuId, revalidate, noCache, }: {
|
|
55
62
|
apiBase: string;
|
|
56
63
|
clientSlug: string;
|
|
64
|
+
menuId?: string;
|
|
57
65
|
revalidate?: number;
|
|
58
66
|
noCache?: boolean;
|
|
59
67
|
}): Promise<{
|
|
@@ -67,5 +75,5 @@ export declare function fetchProjectMenuData({ apiBase, clientSlug, revalidate,
|
|
|
67
75
|
filterFieldName: string;
|
|
68
76
|
fieldOptionsMap: Record<string, Record<string, string>>;
|
|
69
77
|
}>;
|
|
70
|
-
export declare function ProjectMenu({ clientSlug, apiBase, basePath, viewAllPath, subtitle, font, maxProjects, revalidate, noCache, }: ProjectMenuProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
78
|
+
export declare function ProjectMenu({ clientSlug, apiBase, menuId, basePath, viewAllPath, subtitle, font, maxProjects, revalidate, noCache, }: ProjectMenuProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
71
79
|
//# sourceMappingURL=ProjectMenu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectMenu.d.ts","sourceRoot":"","sources":["../src/ProjectMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAKzD,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IACf,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,UAAU,EACV,OAAO,EACP,UAAkB,GACnB,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,aACoC,OAAO,
|
|
1
|
+
{"version":3,"file":"ProjectMenu.d.ts","sourceRoot":"","sources":["../src/ProjectMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAKzD,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,UAAU,EACV,OAAO,EACP,MAAM,EACN,UAAkB,GACnB,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,aACoC,OAAO,uBAsE3C;AAED,wBAAsB,oBAAoB,CAAC,EACzC,OAAO,EACP,UAAU,EACV,MAAM,EACN,UAAkB,EAClB,OAAe,GAChB,EAAE;IACD,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,GAAG,OAAO,CAAC;IACV,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,aAAa,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC9C,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACxD,CAAC,CAqBD;AA8DD,wBAAsB,WAAW,CAAC,EAChC,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAsB,EACtB,WAAW,EACX,QAAQ,EACR,IAA0E,EAC1E,WAAe,EACf,UAAkB,EAClB,OAAe,GAChB,EAAE,gBAAgB,oDAiClB"}
|
package/dist/ProjectMenu.js
CHANGED
|
@@ -26,27 +26,41 @@ const API_KEY = "pk_live_crmsuTIm7NNfb9uEWBCyv88F6kj2YQUR";
|
|
|
26
26
|
* import { revalidateTag } from "next/cache"
|
|
27
27
|
* revalidateTag("chisel-menu-my-client")
|
|
28
28
|
*/
|
|
29
|
-
export function createMenuHandler({ clientSlug, apiBase, revalidate = 86400, }) {
|
|
29
|
+
export function createMenuHandler({ clientSlug, apiBase, menuId, revalidate = 86400, }) {
|
|
30
30
|
return async function GET(request) {
|
|
31
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
31
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
32
32
|
const bypass = process.env.CHISEL_CACHE_BYPASS === "true" ||
|
|
33
33
|
new URL(request.url).searchParams.has("bust");
|
|
34
|
+
const cacheTag = menuId ? `chisel-menu-${clientSlug}-${menuId}` : `chisel-menu-${clientSlug}`;
|
|
34
35
|
const fetchOpts = bypass
|
|
35
36
|
? { cache: "no-store" }
|
|
36
|
-
: { next: { revalidate, tags: [
|
|
37
|
+
: { next: { revalidate, tags: [cacheTag] } };
|
|
37
38
|
try {
|
|
38
|
-
|
|
39
|
+
// Always fetch /projects for schema, and /fields for options
|
|
40
|
+
// If menuId is provided, also fetch the menu endpoint for curated projects
|
|
41
|
+
const fetches = [
|
|
39
42
|
fetch(`${apiBase}/api/v1/clients/${clientSlug}/projects?api_key=${API_KEY}`, fetchOpts),
|
|
40
43
|
fetch(`${apiBase}/api/v1/clients/${clientSlug}/fields?api_key=${API_KEY}`, fetchOpts),
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
];
|
|
45
|
+
if (menuId) {
|
|
46
|
+
fetches.push(fetch(`${apiBase}/api/v1/clients/${clientSlug}/menus/${menuId}?api_key=${API_KEY}`, fetchOpts));
|
|
47
|
+
}
|
|
48
|
+
const responses = await Promise.all(fetches);
|
|
49
|
+
const [projectsRes, fieldsRes] = responses;
|
|
50
|
+
const menuRes = menuId ? responses[2] : null;
|
|
51
|
+
const projectsJson = projectsRes.ok ? await projectsRes.json() : {};
|
|
52
|
+
const menuJson = menuRes && menuRes.ok ? await menuRes.json() : null;
|
|
53
|
+
// If menuId provided, use menu projects; otherwise use all projects
|
|
54
|
+
const projects = menuJson
|
|
55
|
+
? ((_b = (_a = menuJson.projects) !== null && _a !== void 0 ? _a : menuJson.data) !== null && _b !== void 0 ? _b : [])
|
|
56
|
+
: ((_c = projectsJson === null || projectsJson === void 0 ? void 0 : projectsJson.data) !== null && _c !== void 0 ? _c : []);
|
|
57
|
+
// Always get schema from /projects response
|
|
58
|
+
const schema = (_e = (_d = projectsJson === null || projectsJson === void 0 ? void 0 : projectsJson.client) === null || _d === void 0 ? void 0 : _d.custom_fields_schema) !== null && _e !== void 0 ? _e : [];
|
|
45
59
|
const fieldsJson = fieldsRes.ok ? await fieldsRes.json() : { fields: [] };
|
|
46
60
|
const fieldOptionsMap = {};
|
|
47
|
-
for (const field of ((
|
|
61
|
+
for (const field of ((_f = fieldsJson.fields) !== null && _f !== void 0 ? _f : [])) {
|
|
48
62
|
const map = {};
|
|
49
|
-
for (const opt of ((
|
|
63
|
+
for (const opt of ((_g = field.options) !== null && _g !== void 0 ? _g : [])) {
|
|
50
64
|
if (typeof opt === "object" && opt.id && opt.label) {
|
|
51
65
|
map[opt.id] = opt.label;
|
|
52
66
|
map[opt.label] = opt.label;
|
|
@@ -54,9 +68,9 @@ export function createMenuHandler({ clientSlug, apiBase, revalidate = 86400, })
|
|
|
54
68
|
}
|
|
55
69
|
fieldOptionsMap[field.key] = map;
|
|
56
70
|
}
|
|
57
|
-
const filterField = (
|
|
71
|
+
const filterField = (_h = schema.find((f) => f.is_filterable && (f.type === "select" || f.type === "multi-select"))) !== null && _h !== void 0 ? _h : null;
|
|
58
72
|
const filterOptions = filterField
|
|
59
|
-
? ((
|
|
73
|
+
? ((_j = filterField.options) !== null && _j !== void 0 ? _j : []).map((opt) => {
|
|
60
74
|
var _a, _b;
|
|
61
75
|
if (typeof opt === "string")
|
|
62
76
|
return { id: opt.toLowerCase().replace(/\s+/g, "-"), label: opt };
|
|
@@ -67,19 +81,19 @@ export function createMenuHandler({ clientSlug, apiBase, revalidate = 86400, })
|
|
|
67
81
|
projects,
|
|
68
82
|
schema,
|
|
69
83
|
filterOptions,
|
|
70
|
-
filterFieldKey: (
|
|
71
|
-
filterFieldName: (
|
|
84
|
+
filterFieldKey: (_k = filterField === null || filterField === void 0 ? void 0 : filterField.key) !== null && _k !== void 0 ? _k : null,
|
|
85
|
+
filterFieldName: (_l = filterField === null || filterField === void 0 ? void 0 : filterField.name) !== null && _l !== void 0 ? _l : "Project Type",
|
|
72
86
|
fieldOptionsMap,
|
|
73
87
|
});
|
|
74
88
|
}
|
|
75
|
-
catch (
|
|
89
|
+
catch (_m) {
|
|
76
90
|
return Response.json({ projects: [], schema: [], filterOptions: [], filterFieldKey: null, filterFieldName: "Project Type", fieldOptionsMap: {} }, { status: 500 });
|
|
77
91
|
}
|
|
78
92
|
};
|
|
79
93
|
}
|
|
80
|
-
export async function fetchProjectMenuData({ apiBase, clientSlug, revalidate = 86400, noCache = false, }) {
|
|
94
|
+
export async function fetchProjectMenuData({ apiBase, clientSlug, menuId, revalidate = 86400, noCache = false, }) {
|
|
81
95
|
var _a, _b, _c, _d;
|
|
82
|
-
const raw = await _fetchMenuData(apiBase, clientSlug, revalidate, noCache);
|
|
96
|
+
const raw = await _fetchMenuData(apiBase, clientSlug, menuId, revalidate, noCache);
|
|
83
97
|
const filterField = (_a = raw.schema.find((f) => f.is_filterable && (f.type === "select" || f.type === "multi-select"))) !== null && _a !== void 0 ? _a : null;
|
|
84
98
|
const filterOptions = filterField
|
|
85
99
|
? ((_b = filterField.options) !== null && _b !== void 0 ? _b : []).map((opt) => {
|
|
@@ -99,27 +113,40 @@ export async function fetchProjectMenuData({ apiBase, clientSlug, revalidate = 8
|
|
|
99
113
|
fieldOptionsMap: raw.fieldOptionsMap,
|
|
100
114
|
};
|
|
101
115
|
}
|
|
102
|
-
const _fetchMenuData = cache(async (apiBase, clientSlug, revalidate, noCache = false) => {
|
|
103
|
-
var _a, _b, _c, _d, _e;
|
|
116
|
+
const _fetchMenuData = cache(async (apiBase, clientSlug, menuId, revalidate, noCache = false) => {
|
|
117
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
104
118
|
const fetchOpts = noCache
|
|
105
119
|
? { cache: "no-store" }
|
|
106
120
|
: { next: { revalidate } };
|
|
107
121
|
try {
|
|
108
|
-
|
|
122
|
+
// Always fetch /projects for schema, and /fields for options
|
|
123
|
+
// If menuId is provided, also fetch the menu endpoint for curated projects
|
|
124
|
+
const fetches = [
|
|
109
125
|
fetch(`${apiBase}/api/v1/clients/${clientSlug}/projects?api_key=${API_KEY}`, fetchOpts),
|
|
110
126
|
fetch(`${apiBase}/api/v1/clients/${clientSlug}/fields?api_key=${API_KEY}`, fetchOpts),
|
|
111
|
-
]
|
|
112
|
-
if (
|
|
127
|
+
];
|
|
128
|
+
if (menuId) {
|
|
129
|
+
fetches.push(fetch(`${apiBase}/api/v1/clients/${clientSlug}/menus/${menuId}?api_key=${API_KEY}`, fetchOpts));
|
|
130
|
+
}
|
|
131
|
+
const responses = await Promise.all(fetches);
|
|
132
|
+
const [projectsRes, fieldsRes] = responses;
|
|
133
|
+
const menuRes = menuId ? responses[2] : null;
|
|
134
|
+
if (!projectsRes.ok)
|
|
113
135
|
return { projects: [], schema: [], fieldOptionsMap: {} };
|
|
114
|
-
const
|
|
115
|
-
const
|
|
116
|
-
|
|
136
|
+
const projectsJson = await projectsRes.json();
|
|
137
|
+
const menuJson = menuRes && menuRes.ok ? await menuRes.json() : null;
|
|
138
|
+
// If menuId provided, use menu projects; otherwise use all projects
|
|
139
|
+
const projects = menuJson
|
|
140
|
+
? ((_b = (_a = menuJson.projects) !== null && _a !== void 0 ? _a : menuJson.data) !== null && _b !== void 0 ? _b : [])
|
|
141
|
+
: ((_c = projectsJson === null || projectsJson === void 0 ? void 0 : projectsJson.data) !== null && _c !== void 0 ? _c : []);
|
|
142
|
+
// Always get schema from /projects response
|
|
143
|
+
const schema = (_e = (_d = projectsJson === null || projectsJson === void 0 ? void 0 : projectsJson.client) === null || _d === void 0 ? void 0 : _d.custom_fields_schema) !== null && _e !== void 0 ? _e : [];
|
|
117
144
|
// Build fieldOptionsMap: { fieldKey: { id: label, label: label } }
|
|
118
145
|
const fieldsJson = fieldsRes.ok ? await fieldsRes.json() : { fields: [] };
|
|
119
146
|
const fieldOptionsMap = {};
|
|
120
|
-
for (const field of ((
|
|
147
|
+
for (const field of ((_f = fieldsJson.fields) !== null && _f !== void 0 ? _f : [])) {
|
|
121
148
|
const map = {};
|
|
122
|
-
for (const opt of ((
|
|
149
|
+
for (const opt of ((_g = field.options) !== null && _g !== void 0 ? _g : [])) {
|
|
123
150
|
if (typeof opt === "object" && opt.id && opt.label) {
|
|
124
151
|
map[opt.id] = opt.label;
|
|
125
152
|
map[opt.label] = opt.label;
|
|
@@ -129,13 +156,13 @@ const _fetchMenuData = cache(async (apiBase, clientSlug, revalidate, noCache = f
|
|
|
129
156
|
}
|
|
130
157
|
return { projects, schema, fieldOptionsMap };
|
|
131
158
|
}
|
|
132
|
-
catch (
|
|
159
|
+
catch (_h) {
|
|
133
160
|
return { projects: [], schema: [], fieldOptionsMap: {} };
|
|
134
161
|
}
|
|
135
162
|
});
|
|
136
|
-
export async function ProjectMenu({ clientSlug, apiBase, basePath = "/projects", viewAllPath, subtitle, font = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", maxProjects = 6, revalidate = 86400, noCache = false, }) {
|
|
163
|
+
export async function ProjectMenu({ clientSlug, apiBase, menuId, basePath = "/projects", viewAllPath, subtitle, font = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", maxProjects = 6, revalidate = 86400, noCache = false, }) {
|
|
137
164
|
var _a, _b, _c, _d;
|
|
138
|
-
const { projects, schema, fieldOptionsMap } = await _fetchMenuData(apiBase, clientSlug, revalidate, noCache);
|
|
165
|
+
const { projects, schema, fieldOptionsMap } = await _fetchMenuData(apiBase, clientSlug, menuId, revalidate, noCache);
|
|
139
166
|
// Find the filterable select field (badge_overlay is our category field)
|
|
140
167
|
const filterField = (_a = schema.find((f) => f.is_filterable && (f.type === "select" || f.type === "multi-select"))) !== null && _a !== void 0 ? _a : null;
|
|
141
168
|
// Build filter option list from schema
|
|
@@ -14,6 +14,11 @@ export interface ProjectMenuClientProps {
|
|
|
14
14
|
*/
|
|
15
15
|
clientSlug?: string;
|
|
16
16
|
apiBase?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Optional menu ID to fetch a specific curated menu instead of all projects.
|
|
19
|
+
* When provided, fetches from /api/v1/clients/{clientSlug}/menus/{menuId}
|
|
20
|
+
*/
|
|
21
|
+
menuId?: string;
|
|
17
22
|
projects?: Project[];
|
|
18
23
|
schema?: CustomFieldSchema[];
|
|
19
24
|
filterOptions?: {
|
|
@@ -29,5 +34,5 @@ export interface ProjectMenuClientProps {
|
|
|
29
34
|
font?: string;
|
|
30
35
|
maxProjects?: number;
|
|
31
36
|
}
|
|
32
|
-
export declare function ProjectMenuClient({ dataUrl, clientSlug, apiBase, projects: projectsProp, schema: schemaProp, filterOptions: filterOptionsProp, filterFieldKey: filterFieldKeyProp, filterFieldName: filterFieldNameProp, fieldOptionsMap: fieldOptionsMapProp, subtitle, basePath, viewAllPath, font, maxProjects, }: ProjectMenuClientProps): import("react/jsx-runtime").JSX.Element;
|
|
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;
|
|
33
38
|
//# 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;
|
|
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;IAEf,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,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,2CAwfxB"}
|