project-portfolio 2.1.0 → 2.2.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 +31 -1
- package/dist/ProjectCard.d.ts.map +1 -1
- package/dist/ProjectCard.js +15 -5
- package/dist/ProjectDetail.d.ts.map +1 -1
- package/dist/ProjectDetail.js +84 -36
- package/dist/ProjectMenu.d.ts.map +1 -1
- package/dist/ProjectMenu.js +6 -2
- package/dist/ProjectMenuClient.d.ts.map +1 -1
- package/dist/ProjectMenuClient.js +8 -3
- package/dist/ProjectPortfolio.js +1 -1
- package/dist/ProjectPortfolioClient.js +1 -1
- package/dist/SimilarProjects.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -216,7 +216,7 @@ export default function ProjectsPage() {
|
|
|
216
216
|
|
|
217
217
|
### `ProjectDetail`
|
|
218
218
|
|
|
219
|
-
A full server-rendered project detail page. Fetches a single project by slug and renders
|
|
219
|
+
A full server-rendered project detail page. Fetches a single project by slug and renders a hero image, a dynamic stats bar, a "Project Overview" section with description and specs sidebar, a photo gallery, and a back link.
|
|
220
220
|
|
|
221
221
|
```tsx
|
|
222
222
|
// app/projects/[slug]/page.tsx
|
|
@@ -235,6 +235,36 @@ export default async function ProjectPage({ params }: { params: { slug: string }
|
|
|
235
235
|
}
|
|
236
236
|
```
|
|
237
237
|
|
|
238
|
+
#### Stats bar
|
|
239
|
+
|
|
240
|
+
The stats bar below the hero is driven by an explicit ordered key list. Fields are shown in this order when present in the schema and populated on the project:
|
|
241
|
+
|
|
242
|
+
| Schema key | Label shown |
|
|
243
|
+
|---|---|
|
|
244
|
+
| `location` | Location |
|
|
245
|
+
| `type` (badge field) | field `name` from schema |
|
|
246
|
+
| `coverage` | Coverage |
|
|
247
|
+
| `year-completed` | Completed |
|
|
248
|
+
| `architect` | Architect |
|
|
249
|
+
| `general-contractor` | General Contractor |
|
|
250
|
+
|
|
251
|
+
If a field doesn't exist in the schema for a given client, or the project has no value for it, that stat is silently omitted. The column count adjusts automatically — 2 columns on mobile, 3 on tablet, up to 6 on desktop.
|
|
252
|
+
|
|
253
|
+
#### Project Overview specs sidebar
|
|
254
|
+
|
|
255
|
+
The "Project Overview" section renders the project description on the left and a specs sidebar on the right (amber accent border). The sidebar shows the following fields when populated, in this order:
|
|
256
|
+
|
|
257
|
+
| Schema key | Label shown |
|
|
258
|
+
|---|---|
|
|
259
|
+
| `systems-used` | Systems Used |
|
|
260
|
+
| `systems` | Track Systems |
|
|
261
|
+
| `series-used` | Series Used |
|
|
262
|
+
| `operation-type` | Operation Type |
|
|
263
|
+
| `finishes` | Finishes |
|
|
264
|
+
| `specifications` | Specifications |
|
|
265
|
+
|
|
266
|
+
Each group renders values as outlined pills. Fields with no value for the current project are omitted. Both the stats bar and the specs sidebar are fully schema-driven — if a key doesn't exist in a client's schema it is simply not shown, making `ProjectDetail` safe to reuse across clients with wildly different field configurations.
|
|
267
|
+
|
|
238
268
|
| Prop | Type | Required | Default | Description |
|
|
239
269
|
|---|---|---|---|---|
|
|
240
270
|
| `slug` | `string` | Yes | — | The project slug to load |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectCard.d.ts","sourceRoot":"","sources":["../src/ProjectCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAmC,MAAM,SAAS,CAAA;AAE1F,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,CAAA;AAE5C,UAAU,gBAAgB;IACxB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,2FAA2F;IAC3F,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAeD,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,MAAM,EACN,eAAoB,EACpB,QAAQ,EACR,OAAgB,EAChB,QAAsB,GACvB,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"ProjectCard.d.ts","sourceRoot":"","sources":["../src/ProjectCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAmC,MAAM,SAAS,CAAA;AAE1F,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,CAAA;AAE5C,UAAU,gBAAgB;IACxB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,2FAA2F;IAC3F,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAeD,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,MAAM,EACN,eAAoB,EACpB,QAAQ,EACR,OAAgB,EAChB,QAAsB,GACvB,EAAE,gBAAgB,2CAqQlB"}
|
package/dist/ProjectCard.js
CHANGED
|
@@ -19,8 +19,8 @@ export function ProjectCard({ project, schema, fieldOptionsMap = {}, priority, v
|
|
|
19
19
|
const tagFields = schema
|
|
20
20
|
.filter((f) => f.display_position === "tags" && f.type !== "number")
|
|
21
21
|
.filter((f, i, arr) => arr.findIndex((x) => x.key === f.key) === i);
|
|
22
|
-
//
|
|
23
|
-
const numericField = schema.find((f) => f.
|
|
22
|
+
// Coverage/sq ft field for footer stat — matched by key or name regardless of type
|
|
23
|
+
const numericField = schema.find((f) => /sq|sqft|square|coverage/i.test(f.key + f.name));
|
|
24
24
|
const locationField = schema.find((f) => f.type === "location");
|
|
25
25
|
const badgeValue = badgeField
|
|
26
26
|
? parseSingleValue(project.custom_field_values[badgeField.key])
|
|
@@ -38,8 +38,13 @@ export function ProjectCard({ project, schema, fieldOptionsMap = {}, priority, v
|
|
|
38
38
|
if (val === undefined || val === null || val === "")
|
|
39
39
|
return null;
|
|
40
40
|
const label = numericField.name.replace(/\s*\([^)]+\)/, "");
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
// Coverage is a pre-formatted string from the API (e.g. "186,446 SF") — render as-is.
|
|
42
|
+
// For numeric fields, format with commas.
|
|
43
|
+
const formatted = typeof val === "string"
|
|
44
|
+
? val
|
|
45
|
+
: typeof val === "number"
|
|
46
|
+
? Math.round(val).toLocaleString()
|
|
47
|
+
: String(val);
|
|
43
48
|
return { label, formatted };
|
|
44
49
|
})();
|
|
45
50
|
const compactTags = tagFields.flatMap((field) => parseMultiValue(project.custom_field_values[field.key]));
|
|
@@ -120,7 +125,12 @@ export function ProjectCard({ project, schema, fieldOptionsMap = {}, priority, v
|
|
|
120
125
|
if (vals.length === 0)
|
|
121
126
|
return null;
|
|
122
127
|
const optMap = (_a = fieldOptionsMap[field.key]) !== null && _a !== void 0 ? _a : {};
|
|
123
|
-
|
|
128
|
+
const hasOptions = Object.keys(optMap).length > 0;
|
|
129
|
+
// Filter out archived values — if optMap is populated and the value isn't in it, it's archived
|
|
130
|
+
const activeVals = hasOptions ? vals.filter((val) => optMap[val] !== undefined) : vals;
|
|
131
|
+
if (activeVals.length === 0)
|
|
132
|
+
return null;
|
|
133
|
+
return (_jsxs("div", { style: { marginBottom: "16px" }, children: [_jsx("p", { style: { fontSize: "10px", fontWeight: 600, letterSpacing: "0.1em", textTransform: "uppercase", color: "#a1a1aa", marginBottom: "8px" }, children: "Systems Used:" }), _jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: activeVals.map((val, i) => {
|
|
124
134
|
var _a, _b, _c, _d;
|
|
125
135
|
// Normalize: look up by id or label, always display the label
|
|
126
136
|
const label = (_a = optMap[val]) !== null && _a !== void 0 ? _a : val;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectDetail.d.ts","sourceRoot":"","sources":["../src/ProjectDetail.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAmDD,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,UAAU,EACV,OAAO,EACP,QAAsB,EACtB,SAA0B,EAC1B,UAAe,GAChB,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"ProjectDetail.d.ts","sourceRoot":"","sources":["../src/ProjectDetail.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAmDD,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,UAAU,EACV,OAAO,EACP,QAAsB,EACtB,SAA0B,EAC1B,UAAe,GAChB,EAAE,kBAAkB,oDAwPpB"}
|
package/dist/ProjectDetail.js
CHANGED
|
@@ -38,7 +38,7 @@ const fetchProjectDetail = cache(async (apiBase, clientSlug, slug, revalidate) =
|
|
|
38
38
|
});
|
|
39
39
|
// ─── Component ───────────────────────────────────────────────────────────────
|
|
40
40
|
export async function ProjectDetail({ slug, clientSlug, apiBase, backPath = "/projects", backLabel = "All Projects", revalidate = 60, }) {
|
|
41
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
41
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
42
42
|
const { project, schema } = await fetchProjectDetail(apiBase, clientSlug, slug, revalidate);
|
|
43
43
|
if (!project) {
|
|
44
44
|
return (_jsx("div", { style: { textAlign: "center", padding: "6rem 1.5rem", fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" }, children: _jsx("p", { style: { color: "#71717a", fontSize: "18px" }, children: "Project not found." }) }));
|
|
@@ -49,16 +49,8 @@ export async function ProjectDetail({ slug, clientSlug, apiBase, backPath = "/pr
|
|
|
49
49
|
: ((_g = (_f = project.media) === null || _f === void 0 ? void 0 : _f.slice(1)) !== null && _g !== void 0 ? _g : []);
|
|
50
50
|
const badgeField = schema.find((f) => f.display_position === "badge_overlay");
|
|
51
51
|
const locationField = schema.find((f) => f.type === "location");
|
|
52
|
-
// Year field: any number field whose key or name contains "year"
|
|
53
|
-
const yearField = schema.find((f) => f.type === "number" && f.display_position !== "hidden" &&
|
|
54
|
-
(/year/i.test(f.key) || /year/i.test(f.name)));
|
|
55
|
-
// Sq footage field: any field (text or number) whose key or name matches common area/coverage terms
|
|
56
|
-
// Falls back to the first non-year number field so it works regardless of client field naming
|
|
57
|
-
const sqftField = (_h = schema.find((f) => f.display_position !== "hidden" &&
|
|
58
|
-
(/coverage|sq.?ft|square.?foot|area|footage/i.test(f.key) || /coverage|sq.?ft|square.?foot|area|footage/i.test(f.name)))) !== null && _h !== void 0 ? _h : schema.find((f) => f.type === "number" && f.display_position !== "hidden" &&
|
|
59
|
-
!(/year/i.test(f.key) || /year/i.test(f.name)));
|
|
60
52
|
const badgeValue = badgeField
|
|
61
|
-
? ((
|
|
53
|
+
? ((_h = parseMultiValue(project.custom_field_values[badgeField.key])[0]) !== null && _h !== void 0 ? _h : null)
|
|
62
54
|
: null;
|
|
63
55
|
const locationValue = locationField
|
|
64
56
|
? project.custom_field_values[locationField.key]
|
|
@@ -66,36 +58,92 @@ export async function ProjectDetail({ slug, clientSlug, apiBase, backPath = "/pr
|
|
|
66
58
|
const locationString = locationValue
|
|
67
59
|
? [locationValue.city, locationValue.state].filter(Boolean).join(", ")
|
|
68
60
|
: null;
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
// Helper: format a raw field value to a display string
|
|
62
|
+
function formatFieldValue(field, raw) {
|
|
71
63
|
if (raw === null || raw === undefined || raw === "")
|
|
72
64
|
return null;
|
|
73
65
|
if (typeof raw === "string")
|
|
74
|
-
return raw;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (raw
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
66
|
+
return raw;
|
|
67
|
+
if (typeof raw === "number") {
|
|
68
|
+
if (/year/i.test(field.key + field.name))
|
|
69
|
+
return String(Math.round(raw));
|
|
70
|
+
return Math.round(raw).toLocaleString();
|
|
71
|
+
}
|
|
72
|
+
if (Array.isArray(raw)) {
|
|
73
|
+
const vals = raw.map(String).filter(Boolean);
|
|
74
|
+
return vals.length > 0 ? vals.join(", ") : null;
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
// ── Stats bar: explicit ordered list of fields to show ────────────────────
|
|
79
|
+
// Location and badge/type are handled first from their detected fields,
|
|
80
|
+
// then remaining stat bar fields are matched by key in the schema.
|
|
81
|
+
const STAT_BAR_KEYS = ["coverage", "year-completed", "architect", "general-contractor"];
|
|
82
|
+
const metadataStats = [];
|
|
83
|
+
if (locationString) {
|
|
84
|
+
metadataStats.push({ label: "Location", value: locationString });
|
|
85
|
+
}
|
|
86
|
+
if (badgeValue) {
|
|
87
|
+
metadataStats.push({ label: badgeField.name, value: badgeValue });
|
|
88
|
+
}
|
|
89
|
+
for (const key of STAT_BAR_KEYS) {
|
|
90
|
+
const field = schema.find((f) => f.key === key);
|
|
91
|
+
if (!field)
|
|
92
|
+
continue;
|
|
93
|
+
const raw = project.custom_field_values[field.key];
|
|
94
|
+
const formatted = formatFieldValue(field, raw);
|
|
95
|
+
// Use "Completed" as the label for year-completed
|
|
96
|
+
const label = key === "year-completed" ? "Completed" : field.name;
|
|
97
|
+
if (formatted)
|
|
98
|
+
metadataStats.push({ label, value: formatted });
|
|
99
|
+
}
|
|
100
|
+
// ── Specs sidebar: explicit ordered list of fields ────────────────────────
|
|
101
|
+
const SPEC_SIDEBAR_KEYS = [
|
|
102
|
+
"systems-used",
|
|
103
|
+
"systems",
|
|
104
|
+
"series-used",
|
|
105
|
+
"operation-type",
|
|
106
|
+
"finishes",
|
|
107
|
+
"specifications",
|
|
108
|
+
];
|
|
109
|
+
const specFields = SPEC_SIDEBAR_KEYS
|
|
110
|
+
.map((key) => schema.find((f) => f.key === key))
|
|
111
|
+
.filter((f) => f !== undefined);
|
|
85
112
|
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 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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
113
|
+
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] }))] })] }), metadataStats.length > 0 && (_jsxs("section", { style: { borderBottom: "1px solid #e4e4e7", backgroundColor: "#fff" }, children: [_jsx("style", { children: `
|
|
114
|
+
.chisel-stats-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; }
|
|
115
|
+
@media (min-width: 640px) { .chisel-stats-grid { grid-template-columns: repeat(3, 1fr); } }
|
|
116
|
+
@media (min-width: 1024px) { .chisel-stats-grid { grid-template-columns: repeat(${Math.min(metadataStats.length, 6)}, 1fr); } }
|
|
117
|
+
.chisel-stat-item { padding: 1.5rem 1.25rem; border-right: 1px solid #e4e4e7; border-bottom: 1px solid #e4e4e7; }
|
|
118
|
+
.chisel-stat-item:last-child { border-right: none; }
|
|
119
|
+
.chisel-gallery-placeholder { display: grid; grid-template-columns: 1fr; gap: 12px; }
|
|
120
|
+
@media (min-width: 640px) { .chisel-gallery-placeholder { grid-template-columns: repeat(3, 1fr); } }
|
|
121
|
+
.chisel-hero-img { height: 50vw; min-height: 220px; max-height: 560px; }
|
|
122
|
+
.chisel-overview-grid { display: grid; grid-template-columns: 1fr; gap: 2.5rem; }
|
|
123
|
+
@media (min-width: 1024px) { .chisel-overview-grid { grid-template-columns: 1fr 300px; gap: 4rem; align-items: start; } }
|
|
124
|
+
` }), _jsx("div", { style: { maxWidth: "1280px", margin: "0 auto", boxSizing: "border-box", padding: "0 0 0 0" }, className: "chisel-stats-grid", children: metadataStats.map(({ label, value }) => (_jsxs("div", { className: "chisel-stat-item", children: [_jsx("p", { style: { fontSize: "10px", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", color: "#a1a1aa", margin: "0 0 8px 0" }, children: label }), _jsx("p", { style: { color: "#18181b", fontWeight: 600, fontSize: "15px", margin: 0, lineHeight: 1.4 }, children: value })] }, label))) })] })), _jsxs("article", { style: { maxWidth: "1280px", margin: "0 auto", padding: "3rem 1.5rem", boxSizing: "border-box" }, children: [(project.blurb || project.description || specFields.length > 0) && (_jsxs("section", { style: { marginBottom: "3rem" }, children: [_jsx("div", { style: { borderBottom: "1px solid #e4e4e7", marginBottom: "2rem", paddingBottom: "1rem", display: "flex", alignItems: "baseline", justifyContent: "space-between" }, children: _jsx("h2", { style: { color: "#18181b", fontWeight: 700, fontSize: "20px", margin: 0, letterSpacing: "-0.01em", fontFamily: font }, children: "Project Overview" }) }), _jsxs("div", { className: "chisel-overview-grid", children: [_jsxs("div", { children: [project.blurb && (_jsx("p", { style: { color: "#3f3f46", fontSize: "16px", fontWeight: 400, lineHeight: 1.85, margin: "0 0 20px 0" }, children: project.blurb })), project.description && project.description !== project.blurb && (_jsx("p", { style: { color: "#3f3f46", fontSize: "16px", fontWeight: 400, lineHeight: 1.85, margin: 0 }, children: project.description }))] }), specFields.length > 0 && (_jsx("aside", { style: { borderLeft: "3px solid #f18a00", paddingLeft: "2rem" }, children: _jsx("div", { style: { display: "flex", flexDirection: "column", gap: "2rem" }, children: specFields.map((field) => {
|
|
125
|
+
const raw = project.custom_field_values[field.key];
|
|
126
|
+
const vals = Array.isArray(raw)
|
|
127
|
+
? raw.map(String).filter(Boolean)
|
|
128
|
+
: typeof raw === "string"
|
|
129
|
+
? [raw]
|
|
130
|
+
: raw !== null && raw !== undefined
|
|
131
|
+
? [String(raw)]
|
|
132
|
+
: [];
|
|
133
|
+
if (vals.length === 0)
|
|
134
|
+
return null;
|
|
135
|
+
return (_jsxs("div", { children: [_jsx("p", { style: { fontSize: "10px", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", color: "#a1a1aa", margin: "0 0 12px 0" }, children: field.name }), _jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: vals.map((val) => (_jsx("span", { style: {
|
|
136
|
+
display: "inline-block",
|
|
137
|
+
padding: "5px 14px",
|
|
138
|
+
backgroundColor: "#fafafa",
|
|
139
|
+
border: "1px solid #e4e4e7",
|
|
140
|
+
color: "#3f3f46",
|
|
141
|
+
fontSize: "13px",
|
|
142
|
+
fontWeight: 500,
|
|
143
|
+
borderRadius: "2px",
|
|
144
|
+
lineHeight: 1.5,
|
|
145
|
+
}, children: val }, val))) })] }, field.key));
|
|
146
|
+
}) }) }))] })] })), _jsxs("section", { children: [_jsx("div", { style: { borderBottom: "1px solid #e4e4e7", marginBottom: "2rem", paddingBottom: "1rem" }, children: _jsx("h2", { style: { color: "#18181b", fontWeight: 700, fontSize: "20px", margin: 0, letterSpacing: "-0.01em", fontFamily: font }, children: "Project Gallery" }) }), galleryImages.length > 0 ? (_jsx(GalleryCarousel, { images: galleryImages, projectTitle: project.title })) : (
|
|
99
147
|
/* Placeholder */
|
|
100
148
|
_jsx("div", { className: "chisel-gallery-placeholder", children: [0, 1, 2].map((i) => (_jsxs("div", { style: { aspectRatio: "4/3", borderRadius: "4px", backgroundColor: "#f9f9f9", border: "1px solid #e4e4e7", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: "8px" }, children: [_jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "#a1a1aa", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909M3.75 19.5h16.5" }) }), _jsx("p", { style: { color: "#a1a1aa", fontSize: "12px", margin: 0 }, children: "Photos coming soon" })] }, i))) }))] })] })] }));
|
|
101
149
|
}
|
|
@@ -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;;;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,
|
|
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,uBAwE3C;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;AAgED,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
|
@@ -51,9 +51,11 @@ export function createMenuHandler({ clientSlug, apiBase, menuId, revalidate = 86
|
|
|
51
51
|
const projectsJson = projectsRes.ok ? await projectsRes.json() : {};
|
|
52
52
|
const menuJson = menuRes && menuRes.ok ? await menuRes.json() : null;
|
|
53
53
|
// If menuId provided, use menu projects; otherwise use all projects
|
|
54
|
-
|
|
54
|
+
// Filter out archived (is_published === false) projects in both cases
|
|
55
|
+
const rawProjects = menuJson
|
|
55
56
|
? ((_b = (_a = menuJson.projects) !== null && _a !== void 0 ? _a : menuJson.data) !== null && _b !== void 0 ? _b : [])
|
|
56
57
|
: ((_c = projectsJson === null || projectsJson === void 0 ? void 0 : projectsJson.data) !== null && _c !== void 0 ? _c : []);
|
|
58
|
+
const projects = rawProjects.filter((p) => p.is_published !== false);
|
|
57
59
|
// Always get schema from /projects response
|
|
58
60
|
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 : [];
|
|
59
61
|
const fieldsJson = fieldsRes.ok ? await fieldsRes.json() : { fields: [] };
|
|
@@ -136,9 +138,11 @@ const _fetchMenuData = cache(async (apiBase, clientSlug, menuId, revalidate, noC
|
|
|
136
138
|
const projectsJson = await projectsRes.json();
|
|
137
139
|
const menuJson = menuRes && menuRes.ok ? await menuRes.json() : null;
|
|
138
140
|
// If menuId provided, use menu projects; otherwise use all projects
|
|
139
|
-
|
|
141
|
+
// Filter out archived (is_published === false) projects in both cases
|
|
142
|
+
const rawProjects = menuJson
|
|
140
143
|
? ((_b = (_a = menuJson.projects) !== null && _a !== void 0 ? _a : menuJson.data) !== null && _b !== void 0 ? _b : [])
|
|
141
144
|
: ((_c = projectsJson === null || projectsJson === void 0 ? void 0 : projectsJson.data) !== null && _c !== void 0 ? _c : []);
|
|
145
|
+
const projects = rawProjects.filter((p) => p.is_published !== false);
|
|
142
146
|
// Always get schema from /projects response
|
|
143
147
|
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 : [];
|
|
144
148
|
// Build fieldOptionsMap: { fieldKey: { id: label, label: label } }
|
|
@@ -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;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,
|
|
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,2CA4fxB"}
|
|
@@ -56,7 +56,7 @@ export function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, projec
|
|
|
56
56
|
]);
|
|
57
57
|
const menuJson = menuRes.ok ? await menuRes.json() : {};
|
|
58
58
|
const projectsJson = projectsRes.ok ? await projectsRes.json() : {};
|
|
59
|
-
const projects = (_h = (_g = menuJson === null || menuJson === void 0 ? void 0 : menuJson.projects) !== null && _g !== void 0 ? _g : menuJson === null || menuJson === void 0 ? void 0 : menuJson.data) !== null && _h !== void 0 ? _h : [];
|
|
59
|
+
const projects = ((_h = (_g = menuJson === null || menuJson === void 0 ? void 0 : menuJson.projects) !== null && _g !== void 0 ? _g : menuJson === null || menuJson === void 0 ? void 0 : menuJson.data) !== null && _h !== void 0 ? _h : []).filter((p) => p.is_published !== false);
|
|
60
60
|
// Get schema from menu response first, fallback to projects response
|
|
61
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
62
|
const fieldsJson = fieldsRes.ok ? await fieldsRes.json() : { fields: [] };
|
|
@@ -95,7 +95,7 @@ export function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, projec
|
|
|
95
95
|
fetch(`${apiBase}/api/v1/clients/${clientSlug}/fields?api_key=${API_KEY}`),
|
|
96
96
|
]);
|
|
97
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 : [];
|
|
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
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
100
|
const fieldsJson = fieldsRes.ok ? await fieldsRes.json() : { fields: [] };
|
|
101
101
|
const fieldOptionsMap = {};
|
|
@@ -348,7 +348,12 @@ export function ProjectMenuClient({ dataUrl, clientSlug, apiBase, menuId, projec
|
|
|
348
348
|
}, children: project.title }), badge && (_jsx("p", { style: { fontSize: "12px", color: "#71717a", margin: 0, fontFamily: font }, children: badge })), tags.length > 0 && (() => {
|
|
349
349
|
var _a;
|
|
350
350
|
const optMap = tagsField ? ((_a = fieldOptionsMap[tagsField.key]) !== null && _a !== void 0 ? _a : {}) : {};
|
|
351
|
-
const
|
|
351
|
+
const hasOptions = Object.keys(optMap).length > 0;
|
|
352
|
+
// Filter out archived values, then resolve to display labels
|
|
353
|
+
const activeTags = hasOptions ? tags.filter((t) => optMap[t] !== undefined) : tags;
|
|
354
|
+
const tagLabels = activeTags.map((t) => { var _a; return (_a = optMap[t]) !== null && _a !== void 0 ? _a : t; }).slice(0, 2);
|
|
355
|
+
if (tagLabels.length === 0)
|
|
356
|
+
return null;
|
|
352
357
|
return (_jsx("p", { style: { fontSize: "11px", color: ACCENT, margin: 0, fontFamily: font, lineHeight: 1.4 }, children: tagLabels.join(" · ") }));
|
|
353
358
|
})()] })] }, project.id));
|
|
354
359
|
}) }))] }), _jsx("div", { className: "chisel-menu-divider-v" }), _jsxs("div", { className: "chisel-menu-right", children: [filterOptions.length > 0 && (_jsxs(_Fragment, { children: [_jsx("p", { style: {
|
package/dist/ProjectPortfolio.js
CHANGED
|
@@ -49,7 +49,7 @@ const fetchPortfolioData = cache(async (apiBase, clientSlug, revalidate, filters
|
|
|
49
49
|
}
|
|
50
50
|
return {
|
|
51
51
|
clientName: (_f = (_e = json.client) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : "Projects",
|
|
52
|
-
projects: (_g = json.data) !== null && _g !== void 0 ? _g : [],
|
|
52
|
+
projects: ((_g = json.data) !== null && _g !== void 0 ? _g : []).filter((p) => p.is_published !== false),
|
|
53
53
|
schema,
|
|
54
54
|
fieldOptionsMap,
|
|
55
55
|
};
|
|
@@ -52,7 +52,7 @@ export function ProjectPortfolioClient({ clientSlug, apiBase, basePath = "/proje
|
|
|
52
52
|
fetch(`${apiBase}/api/v1/clients/${clientSlug}/fields?api_key=${API_KEY}`),
|
|
53
53
|
]);
|
|
54
54
|
const json = projectsRes.ok ? await projectsRes.json() : {};
|
|
55
|
-
const projects = (_a = json === null || json === void 0 ? void 0 : json.data) !== null && _a !== void 0 ? _a : [];
|
|
55
|
+
const projects = ((_a = json === null || json === void 0 ? void 0 : json.data) !== null && _a !== void 0 ? _a : []).filter((p) => p.is_published !== false);
|
|
56
56
|
// Deduplicate schema keys
|
|
57
57
|
const seen = new Set();
|
|
58
58
|
const schema = ((_c = (_b = json === null || json === void 0 ? void 0 : json.client) === null || _b === void 0 ? void 0 : _b.custom_fields_schema) !== null && _c !== void 0 ? _c : []).filter((f) => {
|
package/dist/SimilarProjects.js
CHANGED
|
@@ -29,7 +29,7 @@ const fetchSimilarData = cache(async (apiBase, clientSlug, revalidate) => {
|
|
|
29
29
|
fetch(`${apiBase}/api/v1/clients/${clientSlug}/fields?api_key=${API_KEY}`, fetchOpts),
|
|
30
30
|
]);
|
|
31
31
|
const json = res.ok ? await res.json() : null;
|
|
32
|
-
const allProjects = (_a = json === null || json === void 0 ? void 0 : json.data) !== null && _a !== void 0 ? _a : [];
|
|
32
|
+
const allProjects = ((_a = json === null || json === void 0 ? void 0 : json.data) !== null && _a !== void 0 ? _a : []).filter((p) => p.is_published !== false);
|
|
33
33
|
const schema = dedupeByKey((_c = (_b = json === null || json === void 0 ? void 0 : json.client) === null || _b === void 0 ? void 0 : _b.custom_fields_schema) !== null && _c !== void 0 ? _c : []);
|
|
34
34
|
const fieldsJson = fieldsRes.ok ? await fieldsRes.json() : { fields: [] };
|
|
35
35
|
const fieldOptionsMap = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "project-portfolio",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
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",
|