project-portfolio 2.2.2 → 2.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -273,6 +273,7 @@ Each group renders values as outlined pills. Fields with no value for the curren
|
|
|
273
273
|
| `backPath` | `string` | No | `"/projects"` | Path for the back navigation link |
|
|
274
274
|
| `backLabel` | `string` | No | `"All Projects"` | Label for the back navigation link |
|
|
275
275
|
| `revalidate` | `number` | No | `86400` | Cache revalidation period in seconds (24 hours) |
|
|
276
|
+
| `noCache` | `boolean` | No | `false` | Bypasses the Next.js Data Cache and sets `cache: "no-store"`. Useful during development or for frequently updated projects. |
|
|
276
277
|
|
|
277
278
|
---
|
|
278
279
|
|
|
@@ -435,9 +436,12 @@ Use `variant="card"` to render the same baseball-card style used in `ProjectPort
|
|
|
435
436
|
| `basePath` | `string` | No | `"/projects"` | Base path for project detail links |
|
|
436
437
|
| `projectSlugs` | `string[]` | No | — | Explicit list of project slugs to show, in order. When provided, overrides `filters` entirely. e.g. `["jacob-javits", "tillamook-bay"]` |
|
|
437
438
|
| `maxItems` | `number` | No | `3` | Maximum number of projects to show |
|
|
439
|
+
| `title` | `string` | No | `"Similar Projects"` | Heading text for the section. e.g. `"Featured Projects"` |
|
|
440
|
+
| `subtitle` | `string` | No | `"More Work"` | Small uppercase label above the heading. e.g. `"Our Work"` |
|
|
438
441
|
| `variant` | `"list" \| "card"` | No | `"list"` | `"list"` uses the border-bottom separator style; `"card"` renders full baseball-card style matching `ProjectPortfolio` |
|
|
439
442
|
| `font` | `string` | No | System font stack | Font family string applied to all inline styles |
|
|
440
443
|
| `revalidate` | `number` | No | `86400` | Cache revalidation period in seconds (24 hours) |
|
|
444
|
+
| `noCache` | `boolean` | No | `false` | Bypasses the Next.js Data Cache and sets `cache: "no-store"`. Useful during development or for frequently updated projects. |
|
|
441
445
|
|
|
442
446
|
---
|
|
443
447
|
|
|
@@ -487,7 +491,7 @@ Pass `menuId` to show a specific curated set of projects instead of all projects
|
|
|
487
491
|
| `font` | `string` | No | System font stack | Font family string applied to all inline styles |
|
|
488
492
|
| `maxProjects` | `number` | No | `6` | Maximum number of projects to display |
|
|
489
493
|
| `revalidate` | `number` | No | `86400` | Cache revalidation period in seconds (24 hours) |
|
|
490
|
-
| `noCache` | `boolean` | No | `false` |
|
|
494
|
+
| `noCache` | `boolean` | No | `false` | Bypasses the Next.js Data Cache and sets `cache: "no-store"`. Useful during development or for frequently updated projects. |
|
|
491
495
|
|
|
492
496
|
---
|
|
493
497
|
|
package/dist/ProjectDetail.d.ts
CHANGED
|
@@ -15,6 +15,11 @@ export interface ProjectDetailProps {
|
|
|
15
15
|
* Defaults to 60.
|
|
16
16
|
*/
|
|
17
17
|
revalidate?: number;
|
|
18
|
+
/**
|
|
19
|
+
* When true, bypasses the Next.js Data Cache and always fetches fresh data.
|
|
20
|
+
* Sets fetch cache to "no-store". Useful during development or for frequently updated projects.
|
|
21
|
+
*/
|
|
22
|
+
noCache?: boolean;
|
|
18
23
|
}
|
|
19
|
-
export declare function ProjectDetail({ slug, clientSlug, apiBase, backPath, backLabel, revalidate, }: ProjectDetailProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
24
|
+
export declare function ProjectDetail({ slug, clientSlug, apiBase, backPath, backLabel, revalidate, noCache, }: ProjectDetailProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
20
25
|
//# sourceMappingURL=ProjectDetail.d.ts.map
|
|
@@ -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;
|
|
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;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAwED,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,UAAU,EACV,OAAO,EACP,QAAsB,EACtB,SAA0B,EAC1B,UAAe,EACf,OAAe,GAChB,EAAE,kBAAkB,oDAoQpB"}
|
package/dist/ProjectDetail.js
CHANGED
|
@@ -19,12 +19,13 @@ function dedupeByKey(arr) {
|
|
|
19
19
|
return true;
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
const fetchProjectDetail = cache(async (apiBase, clientSlug, slug, revalidate) => {
|
|
22
|
+
const fetchProjectDetail = cache(async (apiBase, clientSlug, slug, revalidate, noCache) => {
|
|
24
23
|
var _a, _b, _c, _d;
|
|
25
|
-
const fetchOpts =
|
|
26
|
-
? {
|
|
27
|
-
:
|
|
24
|
+
const fetchOpts = noCache
|
|
25
|
+
? { cache: "no-store" }
|
|
26
|
+
: revalidate > 0
|
|
27
|
+
? { next: { revalidate } }
|
|
28
|
+
: {};
|
|
28
29
|
try {
|
|
29
30
|
// Single call — /projects/{slug} returns the project AND client.custom_fields_schema
|
|
30
31
|
// with full options embedded. No need for a separate /fields call.
|
|
@@ -51,9 +52,9 @@ const fetchProjectDetail = cache(async (apiBase, clientSlug, slug, revalidate) =
|
|
|
51
52
|
}
|
|
52
53
|
});
|
|
53
54
|
// ─── Component ───────────────────────────────────────────────────────────────
|
|
54
|
-
export async function ProjectDetail({ slug, clientSlug, apiBase, backPath = "/projects", backLabel = "All Projects", revalidate = 60, }) {
|
|
55
|
+
export async function ProjectDetail({ slug, clientSlug, apiBase, backPath = "/projects", backLabel = "All Projects", revalidate = 60, noCache = false, }) {
|
|
55
56
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
56
|
-
const { project, schema, fieldOptionsMap } = await fetchProjectDetail(apiBase, clientSlug, slug, revalidate);
|
|
57
|
+
const { project, schema, fieldOptionsMap } = await fetchProjectDetail(apiBase, clientSlug, slug, revalidate, noCache);
|
|
57
58
|
if (!project) {
|
|
58
59
|
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." }) }));
|
|
59
60
|
}
|
|
@@ -20,6 +20,11 @@ export interface SimilarProjectsProps {
|
|
|
20
20
|
maxItems?: number;
|
|
21
21
|
/** Seconds to cache. Defaults to 60 */
|
|
22
22
|
revalidate?: number;
|
|
23
|
+
/**
|
|
24
|
+
* When true, bypasses the Next.js Data Cache and always fetches fresh data.
|
|
25
|
+
* Sets fetch cache to "no-store". Useful during development or for frequently updated projects.
|
|
26
|
+
*/
|
|
27
|
+
noCache?: boolean;
|
|
23
28
|
/**
|
|
24
29
|
* Visual layout for the project cards.
|
|
25
30
|
* - "list" (default) — image + text with border-bottom separator
|
|
@@ -32,6 +37,10 @@ export interface SimilarProjectsProps {
|
|
|
32
37
|
* e.g. projectSlugs={["jacob-javits", "tillamook-bay-community-college"]}
|
|
33
38
|
*/
|
|
34
39
|
projectSlugs?: string[];
|
|
40
|
+
/** Main heading for the section. Defaults to "Similar Projects" */
|
|
41
|
+
title?: string;
|
|
42
|
+
/** Small label above the heading. Defaults to "More Work" */
|
|
43
|
+
subtitle?: string;
|
|
35
44
|
}
|
|
36
|
-
export declare function SimilarProjects({ filters, excludeSlug, clientSlug, apiBase, basePath, maxItems, revalidate, variant, projectSlugs, }: SimilarProjectsProps): Promise<import("react/jsx-runtime").JSX.Element | null>;
|
|
45
|
+
export declare function SimilarProjects({ filters, excludeSlug, clientSlug, apiBase, basePath, maxItems, revalidate, noCache, variant, projectSlugs, title, subtitle, }: SimilarProjectsProps): Promise<import("react/jsx-runtime").JSX.Element | null>;
|
|
37
46
|
//# sourceMappingURL=SimilarProjects.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimilarProjects.d.ts","sourceRoot":"","sources":["../src/SimilarProjects.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"SimilarProjects.d.ts","sourceRoot":"","sources":["../src/SimilarProjects.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;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;CAClB;AAmED,wBAAsB,eAAe,CAAC,EACpC,OAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,QAAsB,EACtB,QAAY,EACZ,UAAe,EACf,OAAe,EACf,OAAgB,EAChB,YAAY,EACZ,KAA0B,EAC1B,QAAsB,GACvB,EAAE,oBAAoB,2DAiKtB"}
|
package/dist/SimilarProjects.js
CHANGED
|
@@ -18,10 +18,13 @@ function dedupeByKey(arr) {
|
|
|
18
18
|
return true;
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
const fetchSimilarData = cache(async (apiBase, clientSlug, revalidate) => {
|
|
21
|
+
const fetchSimilarData = cache(async (apiBase, clientSlug, revalidate, noCache) => {
|
|
23
22
|
var _a, _b, _c, _d;
|
|
24
|
-
const fetchOpts =
|
|
23
|
+
const fetchOpts = noCache
|
|
24
|
+
? { cache: "no-store" }
|
|
25
|
+
: revalidate > 0
|
|
26
|
+
? { next: { revalidate } }
|
|
27
|
+
: {};
|
|
25
28
|
const API_KEY = "pk_live_crmsuTIm7NNfb9uEWBCyv88F6kj2YQUR";
|
|
26
29
|
try {
|
|
27
30
|
// Single call — /projects returns projects AND client.custom_fields_schema with full options.
|
|
@@ -47,8 +50,8 @@ const fetchSimilarData = cache(async (apiBase, clientSlug, revalidate) => {
|
|
|
47
50
|
}
|
|
48
51
|
});
|
|
49
52
|
// ─── Component ────────────────────────────────────────────────────────────────
|
|
50
|
-
export async function SimilarProjects({ filters = {}, excludeSlug, clientSlug, apiBase, basePath = "/projects", maxItems = 3, revalidate = 60, variant = "list", projectSlugs, }) {
|
|
51
|
-
const { allProjects, schema, fieldOptionsMap } = await fetchSimilarData(apiBase, clientSlug, revalidate);
|
|
53
|
+
export async function SimilarProjects({ filters = {}, excludeSlug, clientSlug, apiBase, basePath = "/projects", maxItems = 3, revalidate = 60, noCache = false, variant = "list", projectSlugs, title = "Similar Projects", subtitle = "More Work", }) {
|
|
54
|
+
const { allProjects, schema, fieldOptionsMap } = await fetchSimilarData(apiBase, clientSlug, revalidate, noCache);
|
|
52
55
|
const badgeField = schema.find((f) => f.display_position === "badge_overlay");
|
|
53
56
|
const locationField = schema.find((f) => f.type === "location");
|
|
54
57
|
const font = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
@@ -78,7 +81,7 @@ export async function SimilarProjects({ filters = {}, excludeSlug, clientSlug, a
|
|
|
78
81
|
}
|
|
79
82
|
if (similar.length === 0)
|
|
80
83
|
return null;
|
|
81
|
-
const header = (_jsxs("div", { className: "chisel-similar-header", children: [_jsxs("div", { children: [_jsx("p", { style: { fontSize: "11px", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", color: "oklch(0.78 0.16 85)", margin: "0 0 6px 0" }, children:
|
|
84
|
+
const header = (_jsxs("div", { className: "chisel-similar-header", children: [_jsxs("div", { children: [_jsx("p", { style: { fontSize: "11px", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", color: "oklch(0.78 0.16 85)", margin: "0 0 6px 0" }, children: subtitle }), _jsx("h2", { style: { color: "#18181b", fontWeight: 700, fontSize: "clamp(20px, 4vw, 28px)", margin: 0, fontFamily: font }, children: title })] }), _jsxs("a", { href: basePath, style: { color: "#18181b", fontWeight: 600, fontSize: "15px", textDecoration: "none", display: "inline-flex", alignItems: "center", gap: "6px", fontFamily: font, flexShrink: 0 }, children: ["View All", _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "M9 18l6-6-6-6" }) })] })] }));
|
|
82
85
|
// Shared styles injected regardless of variant so .chisel-project-card-img is always defined
|
|
83
86
|
const sharedStyles = (_jsx("style", { children: `
|
|
84
87
|
.chisel-similar-header { display: flex; flex-direction: column; gap: 12px; margin-bottom: 2rem; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "project-portfolio",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.4",
|
|
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",
|