@chiselandco/nexus 2.5.1 → 2.6.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 +39 -2
- package/dist/FilterSidebar.d.ts +1 -1
- package/dist/FilterSidebar.d.ts.map +1 -1
- package/dist/FilteredPortfolio.d.ts +8 -1
- package/dist/FilteredPortfolio.d.ts.map +1 -1
- package/dist/FilteredPortfolio.js +5 -2
- package/dist/GalleryCarousel.d.ts +1 -2
- package/dist/GalleryCarousel.d.ts.map +1 -1
- package/dist/ProjectCard.d.ts +1 -2
- package/dist/ProjectCard.d.ts.map +1 -1
- package/dist/ProjectDetail.d.ts +4 -2
- package/dist/ProjectDetail.d.ts.map +1 -1
- package/dist/ProjectDetail.js +8 -7
- package/dist/ProjectMenu.d.ts +1 -1
- package/dist/ProjectMenu.d.ts.map +1 -1
- package/dist/ProjectMenuClient.d.ts +1 -2
- package/dist/ProjectMenuClient.d.ts.map +1 -1
- package/dist/ProjectPortfolio.d.ts +8 -1
- package/dist/ProjectPortfolio.d.ts.map +1 -1
- package/dist/ProjectPortfolio.js +5 -2
- package/dist/ProjectPortfolioClient.d.ts +8 -2
- package/dist/ProjectPortfolioClient.d.ts.map +1 -1
- package/dist/ProjectPortfolioClient.js +7 -4
- package/dist/SimilarProjects.d.ts +8 -1
- package/dist/SimilarProjects.d.ts.map +1 -1
- package/dist/SimilarProjects.js +6 -2
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -16
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Self-contained project portfolio components for Next.js App Router. Pass a `clientSlug`, `apiBase`, and `apiKey` — each component fetches, caches, and renders everything it needs with no client-side waterfall requests.
|
|
4
4
|
|
|
5
|
-
**Version:** 2.
|
|
5
|
+
**Version:** 2.6.0
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -150,6 +150,7 @@ export default async function ProjectsPage({
|
|
|
150
150
|
| `font` | `string` | No | System font | Font family string |
|
|
151
151
|
| `noCache` | `boolean` | No | `false` | Sets `cache: "no-store"` — useful during development |
|
|
152
152
|
| `revalidate` | `number` | No | `86400` | Cache revalidation period in seconds |
|
|
153
|
+
| `side` | `"architectural" \| "speedrail"` | No | — | Filter projects by website side. When omitted all projects are shown. See [Filtering by side](#filtering-by-side). |
|
|
153
154
|
|
|
154
155
|
#### URL param format
|
|
155
156
|
|
|
@@ -247,7 +248,8 @@ Both the stats bar and specs sidebar are fully schema-driven — fields not pres
|
|
|
247
248
|
|
|
248
249
|
| Prop | Type | Required | Default | Description |
|
|
249
250
|
|---|---|---|---|---|
|
|
250
|
-
| `slug` | `string` | Yes | — | The project slug to load |
|
|
251
|
+
| `slug` | `string` | Yes* | — | The project slug to load |
|
|
252
|
+
| `projectSlug` | `string` | Yes* | — | Alias for `slug` — either one is accepted |
|
|
251
253
|
| `clientSlug` | `string` | Yes | — | The client slug that owns this project |
|
|
252
254
|
| `apiBase` | `string` | Yes | — | Base URL of the projects API |
|
|
253
255
|
| `apiKey` | `string` | Yes | — | Client API key — always pass via environment variable, never hardcode |
|
|
@@ -401,6 +403,7 @@ Use `variant="card"` to render baseball-card style instead of the default list s
|
|
|
401
403
|
| `font` | `string` | No | System font stack | Font family string |
|
|
402
404
|
| `revalidate` | `number` | No | `86400` | Cache revalidation period in seconds |
|
|
403
405
|
| `noCache` | `boolean` | No | `false` | Sets `cache: "no-store"` — useful during development |
|
|
406
|
+
| `side` | `"architectural" \| "speedrail"` | No | — | Filter projects by website side. When omitted all projects are shown. |
|
|
404
407
|
|
|
405
408
|
---
|
|
406
409
|
|
|
@@ -565,6 +568,7 @@ export default async function ProjectsPage({
|
|
|
565
568
|
| `searchParams` | `Record<string, string \| string[] \| undefined>` | No | `{}` | Filter params — pass Next.js `searchParams` directly |
|
|
566
569
|
| `revalidate` | `number` | No | `86400` | Cache revalidation period in seconds |
|
|
567
570
|
| `noCache` | `boolean` | No | `false` | Sets `cache: "no-store"` — useful during development |
|
|
571
|
+
| `side` | `"architectural" \| "speedrail"` | No | — | Filter projects by website side. When omitted all projects are shown. |
|
|
568
572
|
|
|
569
573
|
---
|
|
570
574
|
|
|
@@ -607,6 +611,39 @@ export default function ProjectsPage() {
|
|
|
607
611
|
| `filters` | `Record<string, string>` | No | `{}` | Active filters — filtering is instant, no API call on change |
|
|
608
612
|
| `columns` | `2 \| 3` | No | `3` | Number of grid columns |
|
|
609
613
|
| `font` | `string` | No | System font stack | Font family string |
|
|
614
|
+
| `side` | `"architectural" \| "speedrail"` | No | — | Filter projects by website side. When omitted all projects are shown. |
|
|
615
|
+
|
|
616
|
+
---
|
|
617
|
+
|
|
618
|
+
## Filtering by side
|
|
619
|
+
|
|
620
|
+
Every project returned by the API includes a `side` field: `"architectural"`, `"speedrail"`, or `"both"`. This reflects which section of the client's website a project belongs to.
|
|
621
|
+
|
|
622
|
+
The following components accept an optional `side` prop: `FilteredPortfolio`, `ProjectPortfolio`, `ProjectPortfolioClient`, and `SimilarProjects`.
|
|
623
|
+
|
|
624
|
+
```tsx
|
|
625
|
+
// Architectural side of the site — only shows architectural + both projects
|
|
626
|
+
<FilteredPortfolio
|
|
627
|
+
clientSlug="hollaender"
|
|
628
|
+
apiBase="https://your-api.com"
|
|
629
|
+
apiKey={process.env.HOLLAENDER_API_KEY!}
|
|
630
|
+
basePath="/architectural/projects"
|
|
631
|
+
searchParams={searchParams}
|
|
632
|
+
side="architectural"
|
|
633
|
+
/>
|
|
634
|
+
|
|
635
|
+
// Speed-Rail side of the site — only shows speedrail + both projects
|
|
636
|
+
<FilteredPortfolio
|
|
637
|
+
clientSlug="hollaender"
|
|
638
|
+
apiBase="https://your-api.com"
|
|
639
|
+
apiKey={process.env.HOLLAENDER_API_KEY!}
|
|
640
|
+
basePath="/speedrail/projects"
|
|
641
|
+
searchParams={searchParams}
|
|
642
|
+
side="speedrail"
|
|
643
|
+
/>
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
When `side` is omitted the component behaves exactly as before — all projects are shown. The client controls which value to pass based on the current route or context. No extra API calls are made — the filtering happens in memory after the standard fetch.
|
|
610
647
|
|
|
611
648
|
---
|
|
612
649
|
|
package/dist/FilterSidebar.d.ts
CHANGED
|
@@ -16,5 +16,5 @@ export interface FilterSidebarProps {
|
|
|
16
16
|
/** Label for the trigger link. Defaults to "Advanced Filters" */
|
|
17
17
|
triggerLabel?: string;
|
|
18
18
|
}
|
|
19
|
-
export declare function FilterSidebar({ schema, filterKeys, font, triggerLabel, }: FilterSidebarProps): import("react").JSX.Element | null;
|
|
19
|
+
export declare function FilterSidebar({ schema, filterKeys, font, triggerLabel, }: FilterSidebarProps): import("react/jsx-runtime").JSX.Element | null;
|
|
20
20
|
//# sourceMappingURL=FilterSidebar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterSidebar.d.ts","sourceRoot":"","sources":["../src/FilterSidebar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAEhD,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,UAAU,EACV,IAAI,EACJ,YAAiC,GAClC,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"FilterSidebar.d.ts","sourceRoot":"","sources":["../src/FilterSidebar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAEhD,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,UAAU,EACV,IAAI,EACJ,YAAiC,GAClC,EAAE,kBAAkB,kDAuXpB"}
|
|
@@ -19,6 +19,13 @@ export interface FilteredPortfolioProps {
|
|
|
19
19
|
revalidate?: number;
|
|
20
20
|
noCache?: boolean;
|
|
21
21
|
font?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Filter projects by website side.
|
|
24
|
+
* - "architectural" — shows projects with side "architectural" or "both"
|
|
25
|
+
* - "speedrail" — shows projects with side "speedrail" or "both"
|
|
26
|
+
* - omit — shows all projects regardless of side
|
|
27
|
+
*/
|
|
28
|
+
side?: "architectural" | "speedrail";
|
|
22
29
|
}
|
|
23
30
|
/**
|
|
24
31
|
* FilteredPortfolio — server component.
|
|
@@ -41,5 +48,5 @@ export interface FilteredPortfolioProps {
|
|
|
41
48
|
* )
|
|
42
49
|
* }
|
|
43
50
|
*/
|
|
44
|
-
export declare function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchParams, filterKeys, basePath, revalidate, noCache, font, }: FilteredPortfolioProps): Promise<import("react").JSX.Element>;
|
|
51
|
+
export declare function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchParams, filterKeys, basePath, revalidate, noCache, font, side, }: FilteredPortfolioProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
45
52
|
//# sourceMappingURL=FilteredPortfolio.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilteredPortfolio.d.ts","sourceRoot":"","sources":["../src/FilteredPortfolio.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IAC5D;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"FilteredPortfolio.d.ts","sourceRoot":"","sources":["../src/FilteredPortfolio.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IAC5D;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,IAAI,CAAC,EAAE,eAAe,GAAG,WAAW,CAAA;CACrC;AA8ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,UAAU,EACV,OAAO,EACP,MAAM,EACN,YAAiB,EACjB,UAAU,EACV,QAAsB,EACtB,UAAe,EACf,OAAe,EACf,IAAI,EACJ,IAAI,GACL,EAAE,sBAAsB,oDAkGxB"}
|
|
@@ -74,7 +74,7 @@ async function fetchSchema(apiBase, clientSlug, apiKey, fetchOpts) {
|
|
|
74
74
|
* )
|
|
75
75
|
* }
|
|
76
76
|
*/
|
|
77
|
-
export async function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchParams = {}, filterKeys, basePath = "/projects", revalidate = 60, noCache = false, font, }) {
|
|
77
|
+
export async function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchParams = {}, filterKeys, basePath = "/projects", revalidate = 60, noCache = false, font, side, }) {
|
|
78
78
|
const fetchOpts = noCache
|
|
79
79
|
? { cache: "no-store" }
|
|
80
80
|
: { next: { revalidate } };
|
|
@@ -95,6 +95,9 @@ export async function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchPar
|
|
|
95
95
|
fetchSchema(apiBase, clientSlug, apiKey, fetchOpts),
|
|
96
96
|
]);
|
|
97
97
|
const activeCount = Object.values(activeFilters).reduce((n, ids) => n + ids.length, 0);
|
|
98
|
+
const visible = side
|
|
99
|
+
? projects.filter((p) => p.side === side || p.side === "both")
|
|
100
|
+
: projects;
|
|
98
101
|
return (_jsxs(_Fragment, { children: [_jsx("style", { children: `
|
|
99
102
|
.nxs-fp-wrap {
|
|
100
103
|
width: 100%;
|
|
@@ -130,5 +133,5 @@ export async function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchPar
|
|
|
130
133
|
.chisel-project-card-img { height: 180px; }
|
|
131
134
|
@media (min-width: 640px) { .chisel-project-card-img { height: 200px; } }
|
|
132
135
|
@media (min-width: 1024px) { .chisel-project-card-img { height: 220px; } }
|
|
133
|
-
` }), _jsxs("div", { className: "nxs-fp-wrap", children: [_jsxs("div", { className: "nxs-fp-toolbar", children: [_jsxs("p", { className: "nxs-fp-count", children: ["Showing ", _jsx("strong", { children: projects.length }), total > projects.length ? ` of ${total}` : "", " project", projects.length !== 1 ? "s" : "", activeCount > 0 && ` (${activeCount} filter${activeCount !== 1 ? "s" : ""} active)`] }), _jsx(FilterSidebar, { schema: schema, filterKeys: filterKeys, font: font })] }), projects.length === 0 ? (_jsx("div", { style: { padding: "4rem 0", textAlign: "center" }, children: _jsx("p", { style: { color: "#71717a" }, children: "No projects match the selected filters." }) })) : (_jsx("div", { className: "nxs-fp-grid", children:
|
|
136
|
+
` }), _jsxs("div", { className: "nxs-fp-wrap", children: [_jsxs("div", { className: "nxs-fp-toolbar", children: [_jsxs("p", { className: "nxs-fp-count", children: ["Showing ", _jsx("strong", { children: projects.length }), total > projects.length ? ` of ${total}` : "", " project", projects.length !== 1 ? "s" : "", activeCount > 0 && ` (${activeCount} filter${activeCount !== 1 ? "s" : ""} active)`] }), _jsx(FilterSidebar, { schema: schema, filterKeys: filterKeys, font: font })] }), projects.length === 0 ? (_jsx("div", { style: { padding: "4rem 0", textAlign: "center" }, children: _jsx("p", { style: { color: "#71717a" }, children: "No projects match the selected filters." }) })) : (_jsx("div", { className: "nxs-fp-grid", children: visible.map((project, index) => (_jsx(ProjectCard, { project: project, schema: schema, fieldOptionsMap: fieldOptionsMap, basePath: basePath, priority: index === 0 }, project.id))) }))] })] }));
|
|
134
137
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import type { Media, CustomFieldSchema } from "./types";
|
|
3
2
|
export interface GalleryCarouselProps {
|
|
4
3
|
images: Media[];
|
|
@@ -11,5 +10,5 @@ export interface GalleryCarouselProps {
|
|
|
11
10
|
*/
|
|
12
11
|
schema?: CustomFieldSchema[];
|
|
13
12
|
}
|
|
14
|
-
export declare function GalleryCarousel({ images, projectTitle, schema }: GalleryCarouselProps):
|
|
13
|
+
export declare function GalleryCarousel({ images, projectTitle, schema }: GalleryCarouselProps): import("react/jsx-runtime").JSX.Element | null;
|
|
15
14
|
//# sourceMappingURL=GalleryCarousel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GalleryCarousel.d.ts","sourceRoot":"","sources":["../src/GalleryCarousel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GalleryCarousel.d.ts","sourceRoot":"","sources":["../src/GalleryCarousel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAe,MAAM,SAAS,CAAA;AASpE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAA;CAC7B;AA+ND,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,MAAW,EAAE,EAAE,oBAAoB,kDA2V1F"}
|
package/dist/ProjectCard.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import type { Project, CustomFieldSchema } from "./types";
|
|
3
2
|
export type CardVariant = "card" | "compact";
|
|
4
3
|
interface ProjectCardProps {
|
|
@@ -11,6 +10,6 @@ interface ProjectCardProps {
|
|
|
11
10
|
/** Base path for project detail links. Defaults to "/projects" */
|
|
12
11
|
basePath?: string;
|
|
13
12
|
}
|
|
14
|
-
export declare function ProjectCard({ project, schema, fieldOptionsMap, priority, variant, basePath, }: ProjectCardProps):
|
|
13
|
+
export declare function ProjectCard({ project, schema, fieldOptionsMap, priority, variant, basePath, }: ProjectCardProps): import("react/jsx-runtime").JSX.Element;
|
|
15
14
|
export {};
|
|
16
15
|
//# sourceMappingURL=ProjectCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectCard.d.ts","sourceRoot":"","sources":["../src/ProjectCard.tsx"],"names":[],"mappings":"
|
|
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,2CA2QlB"}
|
package/dist/ProjectDetail.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export interface ProjectDetailProps {
|
|
2
2
|
/** The project slug to load */
|
|
3
|
-
slug
|
|
3
|
+
slug?: string;
|
|
4
|
+
/** Alias for slug — either one is accepted */
|
|
5
|
+
projectSlug?: string;
|
|
4
6
|
/** The client slug identifying which client owns this project */
|
|
5
7
|
clientSlug: string;
|
|
6
8
|
/** Base URL of the projects API */
|
|
@@ -23,5 +25,5 @@ export interface ProjectDetailProps {
|
|
|
23
25
|
*/
|
|
24
26
|
noCache?: boolean;
|
|
25
27
|
}
|
|
26
|
-
export declare function ProjectDetail({ slug, clientSlug, apiBase, apiKey, backPath, backLabel, revalidate, noCache, }: ProjectDetailProps): Promise<import("react").JSX.Element>;
|
|
28
|
+
export declare function ProjectDetail({ slug: slugProp, projectSlug, clientSlug, apiBase, apiKey, backPath, backLabel, revalidate, noCache, }: ProjectDetailProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
27
29
|
//# sourceMappingURL=ProjectDetail.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectDetail.d.ts","sourceRoot":"","sources":["../src/ProjectDetail.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"ProjectDetail.d.ts","sourceRoot":"","sources":["../src/ProjectDetail.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAsFD,wBAAsB,aAAa,CAAC,EAClC,IAAI,EAAE,QAAQ,EACd,WAAW,EACX,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAsB,EACtB,SAA0B,EAC1B,UAAe,EACf,OAAe,GAChB,EAAE,kBAAkB,oDAiRpB"}
|
package/dist/ProjectDetail.js
CHANGED
|
@@ -69,23 +69,24 @@ async function fetchProjectDetail(apiBase, clientSlug, slug, apiKey, revalidate,
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
// ─── Component ───────────────────────────────────────────────────────────────
|
|
72
|
-
export async function ProjectDetail({ slug, clientSlug, apiBase, apiKey, backPath = "/projects", backLabel = "All Projects", revalidate = 60, noCache = false, }) {
|
|
73
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
72
|
+
export async function ProjectDetail({ slug: slugProp, projectSlug, clientSlug, apiBase, apiKey, backPath = "/projects", backLabel = "All Projects", revalidate = 60, noCache = false, }) {
|
|
73
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
74
|
+
const slug = (_a = slugProp !== null && slugProp !== void 0 ? slugProp : projectSlug) !== null && _a !== void 0 ? _a : "";
|
|
74
75
|
const { project, schema, fieldOptionsMap } = await fetchProjectDetail(apiBase, clientSlug, slug, apiKey, revalidate, noCache);
|
|
75
76
|
if (!project) {
|
|
76
77
|
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." }) }));
|
|
77
78
|
}
|
|
78
|
-
const imageUrl = (
|
|
79
|
+
const imageUrl = (_e = (_b = project.image_url) !== null && _b !== void 0 ? _b : (_d = (_c = project.media) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.url) !== null && _e !== void 0 ? _e : null;
|
|
79
80
|
// Always use all media items for the gallery — never exclude media[0] even if image_url is set,
|
|
80
81
|
// since media items carry custom_field_values (tags) that must be preserved.
|
|
81
|
-
const galleryImages = (
|
|
82
|
+
const galleryImages = (_f = project.media) !== null && _f !== void 0 ? _f : [];
|
|
82
83
|
const badgeField = schema.find((f) => f.display_position === "badge_overlay");
|
|
83
84
|
const locationField = schema.find((f) => f.type === "location");
|
|
84
85
|
const badgeRaw = badgeField
|
|
85
|
-
? ((
|
|
86
|
+
? ((_g = parseMultiValue(project.custom_field_values[badgeField.key])[0]) !== null && _g !== void 0 ? _g : null)
|
|
86
87
|
: null;
|
|
87
|
-
const badgeOptMap = badgeField ? ((
|
|
88
|
-
const badgeValue = badgeRaw ? ((
|
|
88
|
+
const badgeOptMap = badgeField ? ((_h = fieldOptionsMap[badgeField.key]) !== null && _h !== void 0 ? _h : {}) : {};
|
|
89
|
+
const badgeValue = badgeRaw ? ((_j = badgeOptMap[badgeRaw]) !== null && _j !== void 0 ? _j : badgeRaw) : null;
|
|
89
90
|
const locationValue = locationField
|
|
90
91
|
? project.custom_field_values[locationField.key]
|
|
91
92
|
: null;
|
package/dist/ProjectMenu.d.ts
CHANGED
|
@@ -80,5 +80,5 @@ export declare function fetchProjectMenuData({ apiBase, clientSlug, apiKey, menu
|
|
|
80
80
|
filterFieldName: string;
|
|
81
81
|
fieldOptionsMap: Record<string, Record<string, string>>;
|
|
82
82
|
}>;
|
|
83
|
-
export declare function ProjectMenu({ clientSlug, apiBase, apiKey, menuId, basePath, viewAllPath, subtitle, font, maxProjects, revalidate, noCache, }: ProjectMenuProps): Promise<import("react").JSX.Element>;
|
|
83
|
+
export declare function ProjectMenu({ clientSlug, apiBase, apiKey, menuId, basePath, viewAllPath, subtitle, font, maxProjects, revalidate, noCache, }: ProjectMenuProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
84
84
|
//# 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;AAGzD,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd;;;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,MAAM,EACN,UAAkB,GACnB,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,
|
|
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;AAGzD,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd;;;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,MAAM,EACN,UAAkB,GACnB,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,aACoC,OAAO,uBAmE3C;AAED,wBAAsB,oBAAoB,CAAC,EACzC,OAAO,EACP,UAAU,EACV,MAAM,EACN,MAAM,EACN,UAAkB,EAClB,OAAe,GAChB,EAAE;IACD,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,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;AAwDD,wBAAsB,WAAW,CAAC,EAChC,UAAU,EACV,OAAO,EACP,MAAM,EACN,MAAM,EACN,QAAsB,EACtB,WAAW,EACX,QAAQ,EACR,IAA0E,EAC1E,WAAe,EACf,UAAkB,EAClB,OAAe,GAChB,EAAE,gBAAgB,oDAiClB"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import type { Project, CustomFieldSchema } from "./types";
|
|
3
2
|
export interface ProjectMenuClientProps {
|
|
4
3
|
/**
|
|
@@ -43,5 +42,5 @@ export interface ProjectMenuClientProps {
|
|
|
43
42
|
font?: string;
|
|
44
43
|
maxProjects?: number;
|
|
45
44
|
}
|
|
46
|
-
export declare function ProjectMenuClient({ dataUrl, clientSlug, apiBase, apiKey, menuId, noCache, projects: projectsProp, schema: schemaProp, filterOptions: filterOptionsProp, filterFieldKey: filterFieldKeyProp, filterFieldName: filterFieldNameProp, fieldOptionsMap: fieldOptionsMapProp, subtitle, basePath, viewAllPath, font, maxProjects, }: ProjectMenuClientProps):
|
|
45
|
+
export declare function ProjectMenuClient({ dataUrl, clientSlug, apiBase, apiKey, 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;
|
|
47
46
|
//# sourceMappingURL=ProjectMenuClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectMenuClient.d.ts","sourceRoot":"","sources":["../src/ProjectMenuClient.tsx"],"names":[],"mappings":"
|
|
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,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;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;AAkBD,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,UAAU,EACV,OAAO,EACP,MAAM,EACN,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"}
|
|
@@ -24,6 +24,13 @@ export interface ProjectPortfolioProps {
|
|
|
24
24
|
* Useful for debugging — do not use in production.
|
|
25
25
|
*/
|
|
26
26
|
noCache?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Filter projects by website side.
|
|
29
|
+
* - "architectural" — shows projects with side "architectural" or "both"
|
|
30
|
+
* - "speedrail" — shows projects with side "speedrail" or "both"
|
|
31
|
+
* - omit — shows all projects regardless of side
|
|
32
|
+
*/
|
|
33
|
+
side?: "architectural" | "speedrail";
|
|
27
34
|
}
|
|
28
35
|
/**
|
|
29
36
|
* ProjectPortfolio — pure self-fetching card grid.
|
|
@@ -40,5 +47,5 @@ export interface ProjectPortfolioProps {
|
|
|
40
47
|
* apiBase="https://your-api.com"
|
|
41
48
|
* />
|
|
42
49
|
*/
|
|
43
|
-
export declare function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath, searchParams, revalidate, noCache, }: ProjectPortfolioProps): Promise<import("react").JSX.Element>;
|
|
50
|
+
export declare function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath, searchParams, revalidate, noCache, side, }: ProjectPortfolioProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
44
51
|
//# sourceMappingURL=ProjectPortfolio.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectPortfolio.d.ts","sourceRoot":"","sources":["../src/ProjectPortfolio.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IAC5D;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"ProjectPortfolio.d.ts","sourceRoot":"","sources":["../src/ProjectPortfolio.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IAC5D;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,eAAe,GAAG,WAAW,CAAA;CACrC;AA0ED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAsB,EACtB,YAAiB,EACjB,UAAe,EACf,OAAe,EACf,IAAI,GACL,EAAE,qBAAqB,oDAmIvB"}
|
package/dist/ProjectPortfolio.js
CHANGED
|
@@ -65,7 +65,7 @@ const fetchPortfolioData = cache(async (apiBase, clientSlug, apiKey, revalidate,
|
|
|
65
65
|
* apiBase="https://your-api.com"
|
|
66
66
|
* />
|
|
67
67
|
*/
|
|
68
|
-
export async function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath = "/projects", searchParams = {}, revalidate = 60, noCache = false, }) {
|
|
68
|
+
export async function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath = "/projects", searchParams = {}, revalidate = 60, noCache = false, side, }) {
|
|
69
69
|
// Parse filter[key]=value from searchParams into { key: value }
|
|
70
70
|
const filters = {};
|
|
71
71
|
Object.entries(searchParams).forEach(([key, val]) => {
|
|
@@ -77,6 +77,9 @@ export async function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath =
|
|
|
77
77
|
});
|
|
78
78
|
const filtersKey = JSON.stringify(filters);
|
|
79
79
|
const { projects, schema, fieldOptionsMap } = await fetchPortfolioData(apiBase, clientSlug, apiKey, revalidate, filtersKey, noCache);
|
|
80
|
+
const visible = side
|
|
81
|
+
? projects.filter((p) => p.side === side || p.side === "both")
|
|
82
|
+
: projects;
|
|
80
83
|
const hasFilters = Object.keys(filters).length > 0;
|
|
81
84
|
const activeFilterLabels = Object.entries(filters)
|
|
82
85
|
.map(([key, val]) => {
|
|
@@ -149,5 +152,5 @@ export async function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath =
|
|
|
149
152
|
height: 220px;
|
|
150
153
|
}
|
|
151
154
|
}
|
|
152
|
-
` }), _jsx("div", { className: "chisel-project-grid", children:
|
|
155
|
+
` }), _jsx("div", { className: "chisel-project-grid", children: visible.map((project, index) => (_jsx(ProjectCard, { project: project, schema: schema, fieldOptionsMap: fieldOptionsMap, basePath: basePath, priority: index === 0 }, project.id))) })] }));
|
|
153
156
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
export interface ProjectPortfolioClientProps {
|
|
3
2
|
/** Client slug identifying which client's projects to load */
|
|
4
3
|
clientSlug: string;
|
|
@@ -19,6 +18,13 @@ export interface ProjectPortfolioClientProps {
|
|
|
19
18
|
font?: string;
|
|
20
19
|
/** Max columns in the grid. 2 or 3. Defaults to 3 */
|
|
21
20
|
columns?: 2 | 3;
|
|
21
|
+
/**
|
|
22
|
+
* Filter projects by website side.
|
|
23
|
+
* - "architectural" — shows projects with side "architectural" or "both"
|
|
24
|
+
* - "speedrail" — shows projects with side "speedrail" or "both"
|
|
25
|
+
* - omit — shows all projects regardless of side
|
|
26
|
+
*/
|
|
27
|
+
side?: "architectural" | "speedrail";
|
|
22
28
|
}
|
|
23
|
-
export declare function ProjectPortfolioClient({ clientSlug, apiBase, apiKey, basePath, filters, font, columns, }: ProjectPortfolioClientProps):
|
|
29
|
+
export declare function ProjectPortfolioClient({ clientSlug, apiBase, apiKey, basePath, filters, font, columns, side, }: ProjectPortfolioClientProps): import("react/jsx-runtime").JSX.Element;
|
|
24
30
|
//# sourceMappingURL=ProjectPortfolioClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectPortfolioClient.d.ts","sourceRoot":"","sources":["../src/ProjectPortfolioClient.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProjectPortfolioClient.d.ts","sourceRoot":"","sources":["../src/ProjectPortfolioClient.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,2BAA2B;IAC1C,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qDAAqD;IACrD,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACf;;;;;OAKG;IACH,IAAI,CAAC,EAAE,eAAe,GAAG,WAAW,CAAA;CACrC;AAyDD,wBAAgB,sBAAsB,CAAC,EACrC,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAsB,EACtB,OAAY,EACZ,IAAmB,EACnB,OAAW,EACX,IAAI,GACL,EAAE,2BAA2B,2CAsJ7B"}
|
|
@@ -39,7 +39,7 @@ function matchesFilters(project, filters, schema, fieldOptionsMap) {
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
// ─── Component ───────────────────────────────────────────────────────────────
|
|
42
|
-
export function ProjectPortfolioClient({ clientSlug, apiBase, apiKey, basePath = "/projects", filters = {}, font = DEFAULT_FONT, columns = 3, }) {
|
|
42
|
+
export function ProjectPortfolioClient({ clientSlug, apiBase, apiKey, basePath = "/projects", filters = {}, font = DEFAULT_FONT, columns = 3, side, }) {
|
|
43
43
|
const [data, setData] = useState(null);
|
|
44
44
|
useEffect(() => {
|
|
45
45
|
const cacheKey = `${clientSlug}:${apiBase}:${apiKey}`;
|
|
@@ -90,11 +90,14 @@ export function ProjectPortfolioClient({ clientSlug, apiBase, apiKey, basePath =
|
|
|
90
90
|
const filteredProjects = useMemo(() => {
|
|
91
91
|
if (!data)
|
|
92
92
|
return [];
|
|
93
|
+
const bySide = side
|
|
94
|
+
? data.projects.filter((p) => p.side === side || p.side === "both")
|
|
95
|
+
: data.projects;
|
|
93
96
|
const hasActiveFilters = Object.values(filters).some(Boolean);
|
|
94
97
|
if (!hasActiveFilters)
|
|
95
|
-
return
|
|
96
|
-
return
|
|
97
|
-
}, [data, filters]);
|
|
98
|
+
return bySide;
|
|
99
|
+
return bySide.filter((p) => matchesFilters(p, filters, data.schema, data.fieldOptionsMap));
|
|
100
|
+
}, [data, filters, side]);
|
|
98
101
|
const gridCols = columns === 2
|
|
99
102
|
? "repeat(2, 1fr)"
|
|
100
103
|
: "repeat(3, 1fr)";
|
|
@@ -43,6 +43,13 @@ export interface SimilarProjectsProps {
|
|
|
43
43
|
title?: string;
|
|
44
44
|
/** Small label above the heading. Defaults to "More Work" */
|
|
45
45
|
subtitle?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Filter projects by website side.
|
|
48
|
+
* - "architectural" — shows projects with side "architectural" or "both"
|
|
49
|
+
* - "speedrail" — shows projects with side "speedrail" or "both"
|
|
50
|
+
* - omit — shows all projects regardless of side
|
|
51
|
+
*/
|
|
52
|
+
side?: "architectural" | "speedrail";
|
|
46
53
|
}
|
|
47
|
-
export declare function SimilarProjects({ filters, excludeSlug, clientSlug, apiBase, apiKey, basePath, maxItems, revalidate, noCache, variant, projectSlugs, title, subtitle, }: SimilarProjectsProps): Promise<import("react").JSX.Element | null>;
|
|
54
|
+
export declare function SimilarProjects({ filters, excludeSlug, clientSlug, apiBase, apiKey, basePath, maxItems, revalidate, noCache, variant, projectSlugs, title, subtitle, side, }: SimilarProjectsProps): Promise<import("react/jsx-runtime").JSX.Element | null>;
|
|
48
55
|
//# sourceMappingURL=SimilarProjects.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimilarProjects.d.ts","sourceRoot":"","sources":["../src/SimilarProjects.tsx"],"names":[],"mappings":"AAKA,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,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"SimilarProjects.d.ts","sourceRoot":"","sources":["../src/SimilarProjects.tsx"],"names":[],"mappings":"AAKA,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,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,eAAe,GAAG,WAAW,CAAA;CACrC;AA6DD,wBAAsB,eAAe,CAAC,EACpC,OAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAsB,EACtB,QAAY,EACZ,UAAe,EACf,OAAe,EACf,OAAgB,EAChB,YAAY,EACZ,KAA0B,EAC1B,QAAsB,EACtB,IAAI,GACL,EAAE,oBAAoB,2DAyKtB"}
|
package/dist/SimilarProjects.js
CHANGED
|
@@ -49,8 +49,12 @@ async function fetchSimilarData(apiBase, clientSlug, apiKey, revalidate, noCache
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
// ─── Component ────────────────────────────────────────────────────────────────
|
|
52
|
-
export async function SimilarProjects({ filters = {}, excludeSlug, clientSlug, apiBase, apiKey, basePath = "/projects", maxItems = 3, revalidate = 60, noCache = false, variant = "list", projectSlugs, title = "Similar Projects", subtitle = "More Work", }) {
|
|
53
|
-
const { allProjects, schema, fieldOptionsMap } = await fetchSimilarData(apiBase, clientSlug, apiKey, revalidate, noCache);
|
|
52
|
+
export async function SimilarProjects({ filters = {}, excludeSlug, clientSlug, apiBase, apiKey, basePath = "/projects", maxItems = 3, revalidate = 60, noCache = false, variant = "list", projectSlugs, title = "Similar Projects", subtitle = "More Work", side, }) {
|
|
53
|
+
const { allProjects: allProjectsRaw, schema, fieldOptionsMap } = await fetchSimilarData(apiBase, clientSlug, apiKey, revalidate, noCache);
|
|
54
|
+
// Apply side filter before any other filtering
|
|
55
|
+
const allProjects = side
|
|
56
|
+
? allProjectsRaw.filter((p) => p.side === side || p.side === "both")
|
|
57
|
+
: allProjectsRaw;
|
|
54
58
|
const badgeField = schema.find((f) => f.display_position === "badge_overlay");
|
|
55
59
|
const locationField = schema.find((f) => f.type === "location");
|
|
56
60
|
const font = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
package/dist/types.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ export interface Project {
|
|
|
39
39
|
image_url: string | null;
|
|
40
40
|
is_featured: boolean;
|
|
41
41
|
is_published?: boolean;
|
|
42
|
+
/** Which website side this project belongs to. Omitted = show on all sides. */
|
|
43
|
+
side?: "architectural" | "speedrail" | "both";
|
|
42
44
|
custom_field_values: Record<string, CustomFieldValue>;
|
|
43
45
|
created_at: string;
|
|
44
46
|
updated_at: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,GAAG,UAAU,CAAA;IAChE,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAA;CACpE;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;CAC/D;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,aAAa,GAAG,IAAI,CAAA;AAEhF,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACrD,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,KAAK,EAAE,CAAA;CACf"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,GAAG,UAAU,CAAA;IAChE,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAA;CACpE;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;CAC/D;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,aAAa,GAAG,IAAI,CAAA;AAEhF,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,eAAe,GAAG,WAAW,GAAG,MAAM,CAAA;IAC7C,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACrD,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,KAAK,EAAE,CAAA;CACf"}
|
package/package.json
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chiselandco/nexus",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Self-contained project portfolio components for Next.js App Router. Includes ProjectPortfolio, ProjectPortfolioClient, ProjectDetail, SimilarProjects, ProjectMenu, ProjectMenuClient, GalleryCarousel, FilterSidebar, and FilteredPortfolio. Pass a clientSlug and apiBase — done.",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"nextjs",
|
|
7
|
-
"react",
|
|
8
|
-
"portfolio",
|
|
9
|
-
"projects",
|
|
10
|
-
"megamenu",
|
|
11
|
-
"gallery",
|
|
12
|
-
"filtering",
|
|
13
|
-
"chiselandco",
|
|
14
|
-
"nexus"
|
|
15
|
-
],
|
|
5
|
+
"keywords": ["nextjs", "react", "portfolio", "projects", "megamenu", "gallery", "filtering", "chiselandco", "nexus"],
|
|
16
6
|
"license": "MIT",
|
|
17
7
|
"type": "module",
|
|
18
8
|
"main": "./dist/index.js",
|
|
@@ -24,9 +14,7 @@
|
|
|
24
14
|
"types": "./dist/index.d.ts"
|
|
25
15
|
}
|
|
26
16
|
},
|
|
27
|
-
"files": [
|
|
28
|
-
"dist"
|
|
29
|
-
],
|
|
17
|
+
"files": ["dist"],
|
|
30
18
|
"scripts": {
|
|
31
19
|
"build": "tsc",
|
|
32
20
|
"prepublishOnly": "npm run build"
|
|
@@ -37,7 +25,6 @@
|
|
|
37
25
|
"react-dom": ">=18.0.0"
|
|
38
26
|
},
|
|
39
27
|
"devDependencies": {
|
|
40
|
-
"@types/node": "^25.9.3",
|
|
41
28
|
"@types/react": "^18.0.0",
|
|
42
29
|
"@types/react-dom": "^18.0.0",
|
|
43
30
|
"next": "^15.0.0",
|