project-portfolio 1.0.8 → 1.3.5
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/dist/GalleryCarousel.d.ts +6 -0
- package/dist/GalleryCarousel.d.ts.map +1 -0
- package/dist/GalleryCarousel.js +84 -0
- package/dist/ProjectCard.js +2 -2
- package/dist/ProjectDetail.d.ts +20 -0
- package/dist/ProjectDetail.d.ts.map +1 -0
- package/dist/ProjectDetail.js +136 -0
- package/dist/ProjectFilters.d.ts +11 -0
- package/dist/ProjectFilters.d.ts.map +1 -0
- package/dist/ProjectFilters.js +49 -0
- package/dist/ProjectPortfolio.d.ts.map +1 -1
- package/dist/ProjectPortfolio.js +12 -6
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GalleryCarousel.d.ts","sourceRoot":"","sources":["../src/GalleryCarousel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAIpC,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,YAAY,GACb,EAAE;IACD,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;CACrB,kDAwJA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
const font = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
5
|
+
export function GalleryCarousel({ images, projectTitle, }) {
|
|
6
|
+
const [current, setCurrent] = useState(0);
|
|
7
|
+
if (images.length === 0)
|
|
8
|
+
return null;
|
|
9
|
+
// caption may come back as `caption`, `description`, or `alt` depending on the API
|
|
10
|
+
const active = images[current];
|
|
11
|
+
const caption = active.caption || active.description || null;
|
|
12
|
+
const total = images.length;
|
|
13
|
+
function prev() {
|
|
14
|
+
setCurrent((c) => (c - 1 + total) % total);
|
|
15
|
+
}
|
|
16
|
+
function next() {
|
|
17
|
+
setCurrent((c) => (c + 1) % total);
|
|
18
|
+
}
|
|
19
|
+
return (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "12px", fontFamily: font }, children: [_jsxs("div", { style: { position: "relative", width: "100%", height: "520px", backgroundColor: "#f4f4f5", overflow: "hidden" }, children: [_jsx("img", { src: active.url, alt: active.alt || projectTitle, style: { width: "100%", height: "100%", objectFit: "cover", display: "block" } }), total > 1 && (_jsx("button", { onClick: prev, "aria-label": "Previous image", style: {
|
|
20
|
+
position: "absolute",
|
|
21
|
+
left: "16px",
|
|
22
|
+
top: "50%",
|
|
23
|
+
transform: "translateY(-50%)",
|
|
24
|
+
width: "40px",
|
|
25
|
+
height: "40px",
|
|
26
|
+
borderRadius: "50%",
|
|
27
|
+
backgroundColor: "rgba(255,255,255,0.92)",
|
|
28
|
+
border: "none",
|
|
29
|
+
cursor: "pointer",
|
|
30
|
+
display: "flex",
|
|
31
|
+
alignItems: "center",
|
|
32
|
+
justifyContent: "center",
|
|
33
|
+
boxShadow: "0 1px 4px rgba(0,0,0,0.18)",
|
|
34
|
+
}, children: _jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "#18181b", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "M15 18l-6-6 6-6" }) }) })), total > 1 && (_jsx("button", { onClick: next, "aria-label": "Next image", style: {
|
|
35
|
+
position: "absolute",
|
|
36
|
+
right: "16px",
|
|
37
|
+
top: "50%",
|
|
38
|
+
transform: "translateY(-50%)",
|
|
39
|
+
width: "40px",
|
|
40
|
+
height: "40px",
|
|
41
|
+
borderRadius: "50%",
|
|
42
|
+
backgroundColor: "rgba(255,255,255,0.92)",
|
|
43
|
+
border: "none",
|
|
44
|
+
cursor: "pointer",
|
|
45
|
+
display: "flex",
|
|
46
|
+
alignItems: "center",
|
|
47
|
+
justifyContent: "center",
|
|
48
|
+
boxShadow: "0 1px 4px rgba(0,0,0,0.18)",
|
|
49
|
+
}, children: _jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "#18181b", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "M9 18l6-6-6-6" }) }) })), total > 1 && (_jsxs("div", { style: {
|
|
50
|
+
position: "absolute",
|
|
51
|
+
bottom: "14px",
|
|
52
|
+
right: "14px",
|
|
53
|
+
backgroundColor: "rgba(0,0,0,0.65)",
|
|
54
|
+
color: "#fff",
|
|
55
|
+
fontSize: "13px",
|
|
56
|
+
fontWeight: 600,
|
|
57
|
+
padding: "4px 10px",
|
|
58
|
+
borderRadius: "9999px",
|
|
59
|
+
fontFamily: font,
|
|
60
|
+
}, children: [current + 1, " / ", total] }))] }), caption && (_jsx("p", { style: {
|
|
61
|
+
textAlign: "center",
|
|
62
|
+
fontSize: "14px",
|
|
63
|
+
fontStyle: "italic",
|
|
64
|
+
color: "#6b7280",
|
|
65
|
+
margin: 0,
|
|
66
|
+
padding: "0 1rem",
|
|
67
|
+
fontFamily: font,
|
|
68
|
+
}, children: caption })), total > 1 && (_jsx("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap" }, children: images.map((img, i) => {
|
|
69
|
+
var _a;
|
|
70
|
+
return (_jsx("button", { onClick: () => setCurrent(i), "aria-label": `View image ${i + 1}`, style: {
|
|
71
|
+
width: "72px",
|
|
72
|
+
height: "52px",
|
|
73
|
+
padding: 0,
|
|
74
|
+
border: i === current ? "2px solid #f18a00" : "2px solid transparent",
|
|
75
|
+
borderRadius: "2px",
|
|
76
|
+
overflow: "hidden",
|
|
77
|
+
cursor: "pointer",
|
|
78
|
+
flexShrink: 0,
|
|
79
|
+
backgroundColor: "#f4f4f5",
|
|
80
|
+
opacity: i === current ? 1 : 0.65,
|
|
81
|
+
transition: "opacity 0.15s, border-color 0.15s",
|
|
82
|
+
}, children: _jsx("img", { src: img.url, alt: img.alt || `Image ${i + 1}`, style: { width: "100%", height: "100%", objectFit: "cover", display: "block" } }) }, (_a = img.id) !== null && _a !== void 0 ? _a : i));
|
|
83
|
+
}) }))] }));
|
|
84
|
+
}
|
package/dist/ProjectCard.js
CHANGED
|
@@ -79,7 +79,7 @@ export function ProjectCard({ project, schema, priority, variant = "card", baseP
|
|
|
79
79
|
transition: "box-shadow 0.3s",
|
|
80
80
|
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
81
81
|
boxSizing: "border-box",
|
|
82
|
-
}, children: [_jsxs("div", { style: { position: "relative",
|
|
82
|
+
}, children: [_jsxs("div", { style: { position: "relative", width: "100%", height: "220px", overflow: "hidden", flexShrink: 0 }, children: [imageUrl ? (_jsx("img", { src: imageUrl, alt: project.title, loading: priority ? "eager" : "lazy", style: { width: "100%", height: "100%", objectFit: "cover" } })) : (_jsx("div", { style: { position: "absolute", inset: 0, backgroundColor: "#f4f4f5" } })), _jsx("div", { style: {
|
|
83
83
|
position: "absolute",
|
|
84
84
|
inset: 0,
|
|
85
85
|
background: "linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.25) 50%, transparent 100%)",
|
|
@@ -113,7 +113,7 @@ export function ProjectCard({ project, schema, priority, variant = "card", baseP
|
|
|
113
113
|
fontSize: "11px",
|
|
114
114
|
fontWeight: 600,
|
|
115
115
|
padding: "3px 10px",
|
|
116
|
-
}, children: badgeValue })), _jsx("h3", { style: {
|
|
116
|
+
}, children: badgeValue })), _jsx("h3", { style: { color: "#fff", fontWeight: 700, fontSize: "20px", lineHeight: 1.3, margin: 0, padding: 0, fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" }, children: project.title }), locationString && (_jsx("p", { style: { color: "rgba(255,255,255,0.8)", fontSize: "14px", margin: 0 }, children: locationString }))] })] }), _jsxs("div", { style: { display: "flex", flexDirection: "column", flex: 1, padding: "1.5rem" }, children: [(project.blurb || project.description) && (_jsx("p", { style: { fontSize: "14px", color: "#3f3f46", lineHeight: 1.6, margin: "0 0 16px 0" }, children: project.blurb || project.description })), tagFields.map((field) => {
|
|
117
117
|
const vals = parseMultiValue(project.custom_field_values[field.key]);
|
|
118
118
|
if (vals.length === 0)
|
|
119
119
|
return null;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface ProjectDetailProps {
|
|
2
|
+
/** The project slug to load */
|
|
3
|
+
slug: string;
|
|
4
|
+
/** The client slug identifying which client owns this project */
|
|
5
|
+
clientSlug: string;
|
|
6
|
+
/** Base URL of the projects API */
|
|
7
|
+
apiBase: string;
|
|
8
|
+
/** Base path for the "back" link. Defaults to "/projects" */
|
|
9
|
+
backPath?: string;
|
|
10
|
+
/** Label for the "back" link. Defaults to "All Projects" */
|
|
11
|
+
backLabel?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Seconds to cache via Next.js Data Cache on production deployments.
|
|
14
|
+
* React.cache() always deduplicates within a single render in all environments.
|
|
15
|
+
* Defaults to 60.
|
|
16
|
+
*/
|
|
17
|
+
revalidate?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function ProjectDetail({ slug, clientSlug, apiBase, backPath, backLabel, revalidate, }: ProjectDetailProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
20
|
+
//# sourceMappingURL=ProjectDetail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectDetail.d.ts","sourceRoot":"","sources":["../src/ProjectDetail.tsx"],"names":[],"mappings":"AAIA,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,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAkLD,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,UAAU,EACV,OAAO,EACP,QAAsB,EACtB,SAA0B,EAC1B,UAAe,GAChB,EAAE,kBAAkB,oDAgLpB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cache } from "react";
|
|
3
|
+
import { GalleryCarousel } from "./GalleryCarousel";
|
|
4
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
5
|
+
function parseMultiValue(raw) {
|
|
6
|
+
if (Array.isArray(raw))
|
|
7
|
+
return raw.map(String).map((s) => s.replace(/`/g, "").trim()).filter(Boolean);
|
|
8
|
+
if (typeof raw === "string")
|
|
9
|
+
return raw.replace(/`/g, "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
function dedupeByKey(arr) {
|
|
13
|
+
const seen = new Set();
|
|
14
|
+
return arr.filter((f) => {
|
|
15
|
+
if (seen.has(f.key))
|
|
16
|
+
return false;
|
|
17
|
+
seen.add(f.key);
|
|
18
|
+
return true;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
// ─── Data fetching ───────────────────────────────────────────────────────────
|
|
22
|
+
const fetchProjectDetail = cache(async (apiBase, clientSlug, slug, revalidate) => {
|
|
23
|
+
var _a, _b, _c, _d;
|
|
24
|
+
const fetchOpts = revalidate > 0
|
|
25
|
+
? { next: { revalidate } }
|
|
26
|
+
: {};
|
|
27
|
+
try {
|
|
28
|
+
const [projectRes, allProjectsRes] = await Promise.all([
|
|
29
|
+
fetch(`${apiBase}/api/v1/clients/${clientSlug}/projects/${slug}?api_key=pk_live_crmsuTIm7NNfb9uEWBCyv88F6kj2YQUR`, fetchOpts),
|
|
30
|
+
fetch(`${apiBase}/api/v1/clients/${clientSlug}/projects?api_key=pk_live_crmsuTIm7NNfb9uEWBCyv88F6kj2YQUR`, fetchOpts),
|
|
31
|
+
]);
|
|
32
|
+
// Per API docs, single project response is { client: {..., custom_fields_schema}, data: {...} }
|
|
33
|
+
const projectJson = projectRes.ok ? await projectRes.json() : null;
|
|
34
|
+
const project = (_a = projectJson === null || projectJson === void 0 ? void 0 : projectJson.data) !== null && _a !== void 0 ? _a : null;
|
|
35
|
+
const schema = dedupeByKey((_c = (_b = projectJson === null || projectJson === void 0 ? void 0 : projectJson.client) === null || _b === void 0 ? void 0 : _b.custom_fields_schema) !== null && _c !== void 0 ? _c : []);
|
|
36
|
+
// All projects response is { client: {...}, data: [...] }
|
|
37
|
+
const allProjectsJson = allProjectsRes.ok ? await allProjectsRes.json() : null;
|
|
38
|
+
const allProjects = (_d = allProjectsJson === null || allProjectsJson === void 0 ? void 0 : allProjectsJson.data) !== null && _d !== void 0 ? _d : [];
|
|
39
|
+
return { project, schema, allProjects };
|
|
40
|
+
}
|
|
41
|
+
catch (_e) {
|
|
42
|
+
return { project: null, schema: [], allProjects: [] };
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// ─── Similar Projects sub-component ─────────────────────────────────────────
|
|
46
|
+
function SimilarProjects({ allProjects, currentSlug, badgeValue, badgeField, locationField, basePath, font, }) {
|
|
47
|
+
const similar = allProjects
|
|
48
|
+
.filter((p) => {
|
|
49
|
+
var _a;
|
|
50
|
+
if (p.slug === currentSlug)
|
|
51
|
+
return false;
|
|
52
|
+
if (!badgeValue || !badgeField)
|
|
53
|
+
return true;
|
|
54
|
+
const val = (_a = parseMultiValue(p.custom_field_values[badgeField.key])[0]) !== null && _a !== void 0 ? _a : null;
|
|
55
|
+
return val === badgeValue;
|
|
56
|
+
})
|
|
57
|
+
.slice(0, 3);
|
|
58
|
+
if (similar.length === 0)
|
|
59
|
+
return null;
|
|
60
|
+
return (_jsxs("section", { style: { borderTop: "1px solid #e4e4e7", paddingTop: "3rem" }, children: [_jsxs("div", { style: { display: "flex", alignItems: "flex-end", justifyContent: "space-between", marginBottom: "2rem" }, children: [_jsxs("div", { children: [_jsx("p", { style: { fontSize: "11px", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", color: "#f18a00", margin: "0 0 6px 0" }, children: "More Work" }), _jsx("h2", { style: { color: "#18181b", fontWeight: 700, fontSize: "28px", margin: 0, fontFamily: font }, children: "Similar Projects" })] }), _jsxs("a", { href: basePath, style: { color: "#18181b", fontWeight: 600, fontSize: "15px", textDecoration: "none", display: "flex", alignItems: "center", gap: "6px", fontFamily: font }, 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" }) })] })] }), _jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "1.5rem" }, children: similar.map((p) => {
|
|
61
|
+
var _a, _b, _c, _d, _e;
|
|
62
|
+
const imgUrl = (_d = (_a = p.image_url) !== null && _a !== void 0 ? _a : (_c = (_b = p.media) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.url) !== null && _d !== void 0 ? _d : null;
|
|
63
|
+
const badge = badgeField
|
|
64
|
+
? ((_e = parseMultiValue(p.custom_field_values[badgeField.key])[0]) !== null && _e !== void 0 ? _e : null)
|
|
65
|
+
: null;
|
|
66
|
+
const loc = locationField
|
|
67
|
+
? p.custom_field_values[locationField.key]
|
|
68
|
+
: null;
|
|
69
|
+
const locStr = loc ? [loc.city, loc.state].filter(Boolean).join(", ") : null;
|
|
70
|
+
return (_jsxs("a", { href: `${basePath}/${p.slug}`, style: { textDecoration: "none", color: "inherit", display: "block", borderBottom: "1px solid #e4e4e7", fontFamily: font }, children: [_jsxs("div", { style: { position: "relative", width: "100%", height: "220px", overflow: "hidden", backgroundColor: "#f4f4f5", marginBottom: "1rem" }, children: [imgUrl && (_jsx("img", { src: imgUrl, alt: p.title, style: { width: "100%", height: "100%", objectFit: "cover", display: "block" } })), badge && (_jsx("span", { style: {
|
|
71
|
+
position: "absolute",
|
|
72
|
+
top: "12px",
|
|
73
|
+
left: "12px",
|
|
74
|
+
backgroundColor: "#f18a00",
|
|
75
|
+
color: "#fff",
|
|
76
|
+
fontSize: "10px",
|
|
77
|
+
fontWeight: 700,
|
|
78
|
+
textTransform: "uppercase",
|
|
79
|
+
letterSpacing: "0.1em",
|
|
80
|
+
padding: "4px 10px",
|
|
81
|
+
}, children: badge }))] }), _jsxs("div", { style: { paddingBottom: "1.25rem" }, children: [_jsx("h3", { style: { color: "#18181b", fontWeight: 700, fontSize: "17px", lineHeight: 1.3, margin: "0 0 8px 0", fontFamily: font }, children: p.title }), locStr && (_jsxs("p", { style: { display: "flex", alignItems: "center", gap: "5px", color: "#71717a", fontSize: "14px", margin: 0 }, children: [_jsxs("svg", { width: "13", height: "13", 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" })] }), locStr] }))] })] }, p.id));
|
|
82
|
+
}) })] }));
|
|
83
|
+
}
|
|
84
|
+
// ─── Component ───────────────────────────────────────────────────────────────
|
|
85
|
+
export async function ProjectDetail({ slug, clientSlug, apiBase, backPath = "/projects", backLabel = "All Projects", revalidate = 60, }) {
|
|
86
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
87
|
+
const { project, schema, allProjects } = await fetchProjectDetail(apiBase, clientSlug, slug, revalidate);
|
|
88
|
+
if (!project) {
|
|
89
|
+
return (_jsxs("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." }), _jsxs("a", { href: backPath, style: { color: "#f18a00", fontWeight: 600, fontSize: "14px", textDecoration: "none", marginTop: "1rem", display: "inline-block" }, children: ["\u2190 ", backLabel] })] }));
|
|
90
|
+
}
|
|
91
|
+
const imageUrl = (_d = (_a = project.image_url) !== null && _a !== void 0 ? _a : (_c = (_b = project.media) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.url) !== null && _d !== void 0 ? _d : null;
|
|
92
|
+
const galleryImages = project.image_url
|
|
93
|
+
? ((_e = project.media) !== null && _e !== void 0 ? _e : [])
|
|
94
|
+
: ((_g = (_f = project.media) === null || _f === void 0 ? void 0 : _f.slice(1)) !== null && _g !== void 0 ? _g : []);
|
|
95
|
+
const badgeField = schema.find((f) => f.display_position === "badge_overlay");
|
|
96
|
+
const locationField = schema.find((f) => f.type === "location");
|
|
97
|
+
const numericField = schema.find((f) => f.type === "number" && f.display_position !== "hidden");
|
|
98
|
+
const badgeValue = badgeField
|
|
99
|
+
? ((_h = parseMultiValue(project.custom_field_values[badgeField.key])[0]) !== null && _h !== void 0 ? _h : null)
|
|
100
|
+
: null;
|
|
101
|
+
const locationValue = locationField
|
|
102
|
+
? project.custom_field_values[locationField.key]
|
|
103
|
+
: null;
|
|
104
|
+
const locationString = locationValue
|
|
105
|
+
? [locationValue.city, locationValue.state].filter(Boolean).join(", ")
|
|
106
|
+
: null;
|
|
107
|
+
const rawCoverage = numericField ? project.custom_field_values[numericField.key] : null;
|
|
108
|
+
const coverageFormatted = (() => {
|
|
109
|
+
if (rawCoverage === null || rawCoverage === undefined)
|
|
110
|
+
return null;
|
|
111
|
+
const n = typeof rawCoverage === "number" ? rawCoverage : parseFloat(String(rawCoverage));
|
|
112
|
+
return isNaN(n) ? String(rawCoverage) : `${n.toLocaleString()} SF`;
|
|
113
|
+
})();
|
|
114
|
+
const completedValue = (() => {
|
|
115
|
+
var _a;
|
|
116
|
+
const entries = Object.entries(project.custom_field_values);
|
|
117
|
+
const preferred = entries.find(([key]) => /(completed|completion|year|date)/i.test(key));
|
|
118
|
+
const candidate = (_a = preferred === null || preferred === void 0 ? void 0 : preferred[1]) !== null && _a !== void 0 ? _a : null;
|
|
119
|
+
if (candidate === null || candidate === undefined)
|
|
120
|
+
return null;
|
|
121
|
+
if (typeof candidate === "number")
|
|
122
|
+
return String(candidate);
|
|
123
|
+
if (typeof candidate === "string")
|
|
124
|
+
return candidate.trim() || null;
|
|
125
|
+
return null;
|
|
126
|
+
})();
|
|
127
|
+
const font = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
128
|
+
return (_jsxs("main", { style: { minHeight: "100vh", backgroundColor: "#fff", fontFamily: font }, children: [_jsxs("section", { style: { position: "relative", width: "100%", height: "55vh", minHeight: "320px", maxHeight: "560px", 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%)" } }), _jsx("div", { style: { position: "absolute", top: "1.5rem", left: 0, right: 0, padding: "0 1.5rem" }, children: _jsxs("a", { href: backPath, style: { display: "inline-flex", alignItems: "center", gap: "6px", color: "rgba(255,255,255,0.7)", fontSize: "14px", textDecoration: "none", fontFamily: font }, children: [_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "M19 12H5M12 5l-7 7 7 7" }) }), backLabel] }) }), _jsxs("div", { style: { position: "absolute", bottom: 0, left: 0, right: 0, padding: "0 1.5rem 2.5rem", maxWidth: "900px" }, children: [(badgeValue || completedValue) && (_jsx("p", { style: { color: "#f18a00", fontSize: "11px", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", margin: "0 0 10px 0" }, children: [badgeValue, completedValue].filter(Boolean).join(" · ") })), _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] }))] })] }), _jsx("section", { style: { borderBottom: "1px solid #e4e4e7", backgroundColor: "#fff" }, children: _jsx("div", { style: { maxWidth: "1280px", margin: "0 auto", padding: "2rem 1.5rem", display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: "2rem", boxSizing: "border-box" }, children: [
|
|
129
|
+
{ label: "Location", value: locationString !== null && locationString !== void 0 ? locationString : "—" },
|
|
130
|
+
{ label: "Project Type", value: badgeValue !== null && badgeValue !== void 0 ? badgeValue : "—" },
|
|
131
|
+
{ label: "Sq. Footage", value: coverageFormatted !== null && coverageFormatted !== void 0 ? coverageFormatted : "—" },
|
|
132
|
+
{ label: "Completed", value: completedValue !== null && completedValue !== void 0 ? completedValue : "—" },
|
|
133
|
+
].map(({ label, value }) => (_jsxs("div", { children: [_jsx("p", { style: { fontSize: "10px", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.1em", color: "#a1a1aa", margin: "0 0 6px 0" }, children: label }), _jsx("p", { style: { color: "#18181b", fontWeight: 600, fontSize: "15px", margin: 0 }, children: value })] }, label))) }) }), _jsxs("article", { style: { maxWidth: "1280px", margin: "0 auto", padding: "3rem 1.5rem", boxSizing: "border-box", display: "flex", flexDirection: "column", gap: "2.5rem" }, children: [(project.blurb || project.description) && (_jsxs("section", { style: { maxWidth: "720px" }, children: [_jsx("h2", { style: { color: "#18181b", fontWeight: 700, fontSize: "22px", margin: "0 0 16px 0", fontFamily: font }, children: "Project Overview" }), project.blurb && (_jsx("p", { style: { color: "#3f3f46", fontSize: "16px", lineHeight: 1.7, margin: "0 0 16px 0" }, children: project.blurb })), project.description && project.description !== project.blurb && (_jsx("p", { style: { color: "#3f3f46", fontSize: "16px", lineHeight: 1.7, margin: 0 }, children: project.description }))] })), _jsxs("section", { children: [_jsx("h2", { style: { color: "#18181b", fontWeight: 700, fontSize: "22px", margin: "0 0 1.5rem 0", fontFamily: font }, children: "Project Gallery" }), galleryImages.length > 0 ? (_jsx(GalleryCarousel, { images: galleryImages, projectTitle: project.title })) : (
|
|
134
|
+
/* Placeholder */
|
|
135
|
+
_jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "12px" }, 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))) }))] }), _jsx(SimilarProjects, { allProjects: allProjects, currentSlug: slug, badgeValue: badgeValue, badgeField: badgeField !== null && badgeField !== void 0 ? badgeField : null, locationField: locationField !== null && locationField !== void 0 ? locationField : null, basePath: backPath, font: font })] })] }));
|
|
136
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CustomFieldSchema } from "./types";
|
|
2
|
+
interface ProjectFiltersProps {
|
|
3
|
+
fields: CustomFieldSchema[];
|
|
4
|
+
filters: Record<string, string>;
|
|
5
|
+
onFilterChange: (key: string, value: string) => void;
|
|
6
|
+
onClearFilters: () => void;
|
|
7
|
+
hasActiveFilters: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function ProjectFilters({ fields, filters, onFilterChange, onClearFilters, hasActiveFilters, }: ProjectFiltersProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=ProjectFilters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectFilters.d.ts","sourceRoot":"","sources":["../src/ProjectFilters.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAEhD,UAAU,mBAAmB;IAC3B,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpD,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,OAAO,EACP,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,EAAE,mBAAmB,2CA8FrB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function ProjectFilters({ fields, filters, onFilterChange, onClearFilters, hasActiveFilters, }) {
|
|
3
|
+
const deduped = fields.filter((f, i, arr) => arr.findIndex((x) => x.key === f.key) === i);
|
|
4
|
+
return (_jsxs("div", { style: {
|
|
5
|
+
marginBottom: "2rem",
|
|
6
|
+
paddingBottom: "2rem",
|
|
7
|
+
borderBottom: "1px solid #e4e4e7",
|
|
8
|
+
display: "flex",
|
|
9
|
+
flexWrap: "wrap",
|
|
10
|
+
alignItems: "flex-end",
|
|
11
|
+
gap: "1rem",
|
|
12
|
+
}, children: [deduped.map((field, fieldIndex) => {
|
|
13
|
+
if (field.type === "select" || field.type === "multi-select") {
|
|
14
|
+
return (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [_jsx("label", { style: { fontSize: "13px", fontWeight: 500, color: "#71717a" }, children: field.name }), _jsxs("select", { value: filters[field.key] || "all", onChange: (e) => onFilterChange(field.key, e.target.value === "all" ? "" : e.target.value), style: {
|
|
15
|
+
width: "180px",
|
|
16
|
+
padding: "8px 12px",
|
|
17
|
+
border: "1px solid #e4e4e7",
|
|
18
|
+
borderRadius: "6px",
|
|
19
|
+
fontSize: "14px",
|
|
20
|
+
backgroundColor: "#fff",
|
|
21
|
+
color: "#18181b",
|
|
22
|
+
outline: "none",
|
|
23
|
+
cursor: "pointer",
|
|
24
|
+
}, children: [_jsxs("option", { value: "all", children: ["All ", field.name] }), [...new Set(field.options)].map((option, i) => (_jsx("option", { value: option, children: option }, `${field.key}-opt-${i}`)))] })] }, `filter-${fieldIndex}-${field.key}`));
|
|
25
|
+
}
|
|
26
|
+
if (field.type === "text" || field.type === "location") {
|
|
27
|
+
return (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [_jsx("label", { style: { fontSize: "13px", fontWeight: 500, color: "#71717a" }, children: field.name }), _jsx("input", { type: "text", placeholder: `Search ${field.name.toLowerCase()}...`, value: filters[field.key] || "", onChange: (e) => onFilterChange(field.key, e.target.value), style: {
|
|
28
|
+
width: "180px",
|
|
29
|
+
padding: "8px 12px",
|
|
30
|
+
border: "1px solid #e4e4e7",
|
|
31
|
+
borderRadius: "6px",
|
|
32
|
+
fontSize: "14px",
|
|
33
|
+
color: "#18181b",
|
|
34
|
+
outline: "none",
|
|
35
|
+
} })] }, `filter-${fieldIndex}-${field.key}`));
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}), hasActiveFilters && (_jsx("button", { onClick: onClearFilters, style: {
|
|
39
|
+
display: "flex",
|
|
40
|
+
alignItems: "center",
|
|
41
|
+
gap: "4px",
|
|
42
|
+
padding: "8px 12px",
|
|
43
|
+
background: "none",
|
|
44
|
+
border: "none",
|
|
45
|
+
fontSize: "14px",
|
|
46
|
+
color: "#71717a",
|
|
47
|
+
cursor: "pointer",
|
|
48
|
+
}, children: "\u00D7 Clear filters" }))] }));
|
|
49
|
+
}
|
|
@@ -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,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAuED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,OAAO,EACP,QAAsB,EACtB,UAAe,GAChB,EAAE,qBAAqB,
|
|
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,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAuED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,OAAO,EACP,QAAsB,EACtB,UAAe,GAChB,EAAE,qBAAqB,oDAwCvB"}
|
package/dist/ProjectPortfolio.js
CHANGED
|
@@ -14,8 +14,8 @@ const fetchPortfolioData = cache(async (apiBase, clientSlug, revalidate) => {
|
|
|
14
14
|
// Either way React.cache() above ensures no duplicate fetches within one render.
|
|
15
15
|
const fetchOpts = { next: { revalidate } };
|
|
16
16
|
const [clientRes, projectsRes] = await Promise.all([
|
|
17
|
-
fetch(`${apiBase}/api/v1/clients/${clientSlug}`, fetchOpts),
|
|
18
|
-
fetch(`${apiBase}/api/v1/clients/${clientSlug}/projects`, fetchOpts),
|
|
17
|
+
fetch(`${apiBase}/api/v1/clients/${clientSlug}?api_key=pk_live_crmsuTIm7NNfb9uEWBCyv88F6kj2YQUR`, fetchOpts),
|
|
18
|
+
fetch(`${apiBase}/api/v1/clients/${clientSlug}/projects?api_key=pk_live_crmsuTIm7NNfb9uEWBCyv88F6kj2YQUR`, fetchOpts),
|
|
19
19
|
]);
|
|
20
20
|
const clientJson = clientRes.ok
|
|
21
21
|
? await clientRes.json()
|
|
@@ -59,8 +59,14 @@ export async function ProjectPortfolio({ clientSlug, apiBase, basePath = "/proje
|
|
|
59
59
|
return (_jsx("div", { style: { textAlign: "center", padding: "4rem 0" }, children: _jsx("p", { style: { color: "#71717a" }, children: "No projects found." }) }));
|
|
60
60
|
}
|
|
61
61
|
return (_jsx("div", { style: {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
width: "100%",
|
|
63
|
+
maxWidth: "1280px",
|
|
64
|
+
margin: "0 auto",
|
|
65
|
+
padding: "2rem 1.5rem",
|
|
66
|
+
boxSizing: "border-box",
|
|
67
|
+
}, children: _jsx("div", { style: {
|
|
68
|
+
display: "grid",
|
|
69
|
+
gridTemplateColumns: "repeat(3, 1fr)",
|
|
70
|
+
gap: "2rem",
|
|
71
|
+
}, children: projects.map((project, index) => (_jsx(ProjectCard, { project: project, schema: schema, basePath: basePath, priority: index === 0 }, project.id))) }) }));
|
|
66
72
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { ProjectPortfolio } from "./ProjectPortfolio";
|
|
2
2
|
export type { ProjectPortfolioProps } from "./ProjectPortfolio";
|
|
3
|
-
export {
|
|
3
|
+
export { ProjectDetail } from "./ProjectDetail";
|
|
4
|
+
export type { ProjectDetailProps } from "./ProjectDetail";
|
|
5
|
+
export { GalleryCarousel } from "./GalleryCarousel";
|
|
4
6
|
export { ProjectCard } from "./ProjectCard";
|
|
5
7
|
export type { CardVariant } from "./ProjectCard";
|
|
6
8
|
export type { Project, CustomFieldSchema, CustomFieldValue, LocationValue, Media, } from "./types";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,KAAK,GACN,MAAM,SAAS,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/types.d.ts
CHANGED
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,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,CAAA;IACjB,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,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;CACnB;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,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,CAAA;IACjB,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;CACnB;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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "project-portfolio",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.5",
|
|
4
4
|
"description": "Self-contained project portfolio component for Next.js App Router. Drop in one component, pass a clientSlug and apiBase, done.",
|
|
5
5
|
"keywords": ["nextjs", "react", "portfolio", "projects"],
|
|
6
6
|
"license": "MIT",
|