@homepages/template-kit 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +182 -0
- package/README.md +71 -14
- package/dist/base.css +85 -0
- package/dist/browser.d.ts +26 -0
- package/dist/browser.js +55 -0
- package/dist/cli.js +1 -1
- package/dist/contracts/image-descriptor.d.ts +17 -0
- package/dist/contracts/markers.d.ts +20 -0
- package/dist/contracts/markers.js +21 -0
- package/dist/contracts/slot-catalog.d.ts +237 -0
- package/dist/contracts/slot-catalog.js +247 -0
- package/dist/contracts/transforms.d.ts +108 -0
- package/dist/contracts/transforms.js +117 -0
- package/dist/design-system/breakpoints.d.ts +5 -0
- package/dist/design-system/breakpoints.js +14 -0
- package/dist/design-system/theme.d.ts +307 -0
- package/dist/design-system/theme.js +95 -0
- package/dist/eslint/is-client-file.js +79 -0
- package/dist/eslint/rules/image-bare-needs-reason.js +38 -0
- package/dist/eslint/rules/no-client-directive-in-contract.js +26 -0
- package/dist/eslint/rules/no-client-runtime-in-server.js +99 -0
- package/dist/eslint/rules/no-css-import-from-render-path.js +23 -0
- package/dist/eslint/rules/no-hex.js +111 -0
- package/dist/eslint/rules/no-inline-style.js +23 -0
- package/dist/eslint/rules/no-nondeterminism.js +44 -0
- package/dist/eslint/rules/no-raw-element.js +32 -0
- package/dist/eslint/rules/props-from-schema.js +32 -0
- package/dist/eslint/rules/serializable-island-props.js +108 -0
- package/dist/eslint/rules/slot-marker-literal.js +33 -0
- package/dist/eslint.d.ts +4 -8
- package/dist/eslint.js +75 -11
- package/dist/fixtures/sample-property.d.ts +67 -0
- package/dist/fixtures/sample-property.js +707 -0
- package/dist/fixtures.d.ts +2 -0
- package/dist/fixtures.js +3 -0
- package/dist/index.d.ts +37 -13
- package/dist/index.js +34 -2
- package/dist/island-runtime.d.ts +30 -0
- package/dist/island-runtime.js +73 -0
- package/dist/islands/contract.d.ts +56 -0
- package/dist/islands/contract.js +71 -0
- package/dist/islands/marker.d.ts +16 -0
- package/dist/islands/marker.js +18 -0
- package/dist/package.js +5 -0
- package/dist/primitives/Image.d.ts +49 -0
- package/dist/primitives/Image.js +95 -0
- package/dist/primitives/Section.d.ts +22 -0
- package/dist/primitives/Section.js +26 -0
- package/dist/primitives/Slot.d.ts +50 -0
- package/dist/primitives/Slot.js +39 -0
- package/dist/primitives/SlotGroup.d.ts +38 -0
- package/dist/primitives/SlotGroup.js +24 -0
- package/dist/primitives/SlotItem.d.ts +43 -0
- package/dist/primitives/SlotItem.js +38 -0
- package/dist/primitives/index.d.ts +7 -0
- package/dist/primitives/picture-sources.d.ts +22 -0
- package/dist/primitives/picture-sources.js +52 -0
- package/dist/schema/fill-spec.d.ts +692 -0
- package/dist/schema/fill-spec.js +98 -0
- package/dist/schema/fixture-schema.d.ts +143 -0
- package/dist/schema/fixture-schema.js +113 -0
- package/dist/schema/index.d.ts +16 -0
- package/dist/schema/manifest.d.ts +527 -0
- package/dist/schema/manifest.js +73 -0
- package/dist/schema/property-facts.d.ts +44 -0
- package/dist/schema/resolve-variants.d.ts +11 -0
- package/dist/schema/resolve-variants.js +15 -0
- package/dist/schema/runtime-values.d.ts +45 -0
- package/dist/schema/section-nav.d.ts +7 -0
- package/dist/schema/section-props.d.ts +69 -0
- package/dist/schema/section-schema.d.ts +533 -0
- package/dist/schema/section-schema.js +72 -0
- package/dist/schema/slot-types.d.ts +117 -0
- package/dist/schema/slot-types.js +181 -0
- package/dist/schema/source.d.ts +13 -0
- package/dist/schema/source.js +12 -0
- package/dist/schema/synthesize-nullable.d.ts +18 -0
- package/dist/schema/synthesize-nullable.js +47 -0
- package/dist/styles.css +131 -9
- package/docs/INDEX.md +6 -4
- package/docs/eslint.md +90 -0
- package/docs/islands.md +150 -0
- package/docs/llms.txt +30 -3
- package/docs/primitives.md +214 -0
- package/docs/schema-system.md +240 -0
- package/docs/theme-and-css.md +179 -0
- package/package.json +30 -6
- package/tsconfig.base.json +16 -0
- package/tsconfig.json +2 -13
- package/dist/src-CrdHXijV.js +0 -23
|
@@ -0,0 +1,707 @@
|
|
|
1
|
+
//#region src/fixtures/sample-property.ts
|
|
2
|
+
const PHOTO_BASE = "https://example.invalid/photos/queensway";
|
|
3
|
+
const galleryPhotos = [
|
|
4
|
+
{
|
|
5
|
+
id: "ph_001",
|
|
6
|
+
url: `${PHOTO_BASE}/01-lobby.jpg`,
|
|
7
|
+
alt: "Lobby with terrazzo flooring and chandeliers.",
|
|
8
|
+
tags: {
|
|
9
|
+
room: "lobby",
|
|
10
|
+
category: "interior"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: "ph_002",
|
|
15
|
+
url: `${PHOTO_BASE}/02-gym-a.jpg`,
|
|
16
|
+
alt: "Gym with cardio equipment and floor-to-ceiling mirrors.",
|
|
17
|
+
tags: {
|
|
18
|
+
room: "gym",
|
|
19
|
+
category: "interior"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: "ph_003",
|
|
24
|
+
url: `${PHOTO_BASE}/03-gym-b.jpg`,
|
|
25
|
+
alt: "Gym free-weights area.",
|
|
26
|
+
tags: {
|
|
27
|
+
room: "gym",
|
|
28
|
+
category: "interior"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "ph_004",
|
|
33
|
+
url: `${PHOTO_BASE}/04-living-a.jpg`,
|
|
34
|
+
alt: "Living area with bay windows and original mouldings.",
|
|
35
|
+
tags: {
|
|
36
|
+
room: "living",
|
|
37
|
+
category: "interior"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "ph_005",
|
|
42
|
+
url: `${PHOTO_BASE}/05-living-b.jpg`,
|
|
43
|
+
alt: "Living area facing the fireplace.",
|
|
44
|
+
tags: {
|
|
45
|
+
room: "living",
|
|
46
|
+
category: "interior"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "ph_006",
|
|
51
|
+
url: `${PHOTO_BASE}/06-kitchen-a.jpg`,
|
|
52
|
+
alt: "Kitchen with quartz waterfall island.",
|
|
53
|
+
tags: {
|
|
54
|
+
room: "kitchen",
|
|
55
|
+
category: "interior"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "ph_007",
|
|
60
|
+
url: `${PHOTO_BASE}/07-kitchen-b.jpg`,
|
|
61
|
+
alt: "Kitchen breakfast nook by the window.",
|
|
62
|
+
tags: {
|
|
63
|
+
room: "kitchen",
|
|
64
|
+
category: "interior"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: "ph_008",
|
|
69
|
+
url: `${PHOTO_BASE}/08-dining.jpg`,
|
|
70
|
+
alt: "Dining area set for six.",
|
|
71
|
+
tags: {
|
|
72
|
+
room: "dining",
|
|
73
|
+
category: "interior"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: "ph_009",
|
|
78
|
+
url: `${PHOTO_BASE}/09-living-c.jpg`,
|
|
79
|
+
alt: "Living area with statement art wall.",
|
|
80
|
+
tags: {
|
|
81
|
+
room: "living",
|
|
82
|
+
category: "interior"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: "ph_010",
|
|
87
|
+
url: `${PHOTO_BASE}/10-living-d.jpg`,
|
|
88
|
+
alt: "Living area opening onto private terrace.",
|
|
89
|
+
tags: {
|
|
90
|
+
room: "living",
|
|
91
|
+
category: "interior"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "ph_011",
|
|
96
|
+
url: `${PHOTO_BASE}/11-living-e.jpg`,
|
|
97
|
+
alt: "Sunken living area with built-in shelving.",
|
|
98
|
+
tags: {
|
|
99
|
+
room: "living",
|
|
100
|
+
category: "interior"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: "ph_012",
|
|
105
|
+
url: `${PHOTO_BASE}/12-living-f.jpg`,
|
|
106
|
+
alt: "Living area corner with reading chair.",
|
|
107
|
+
tags: {
|
|
108
|
+
room: "living",
|
|
109
|
+
category: "interior"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "ph_013",
|
|
114
|
+
url: `${PHOTO_BASE}/13-master-bedroom.jpg`,
|
|
115
|
+
alt: "Primary bedroom with king bed and skylight.",
|
|
116
|
+
tags: {
|
|
117
|
+
room: "bedroom",
|
|
118
|
+
category: "interior"
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: "ph_014",
|
|
123
|
+
url: `${PHOTO_BASE}/14-master-bath-a.jpg`,
|
|
124
|
+
alt: "Spa-style primary bath with freestanding tub.",
|
|
125
|
+
tags: {
|
|
126
|
+
room: "bath",
|
|
127
|
+
category: "interior"
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: "ph_015",
|
|
132
|
+
url: `${PHOTO_BASE}/15-master-bath-b.jpg`,
|
|
133
|
+
alt: "Primary bath double vanity and shower.",
|
|
134
|
+
tags: {
|
|
135
|
+
room: "bath",
|
|
136
|
+
category: "interior"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: "ph_016",
|
|
141
|
+
url: `${PHOTO_BASE}/16-common-bath.jpg`,
|
|
142
|
+
alt: "Common bath with marble subway tile.",
|
|
143
|
+
tags: {
|
|
144
|
+
room: "bath",
|
|
145
|
+
category: "interior"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: "ph_017",
|
|
150
|
+
url: `${PHOTO_BASE}/17-entrance.jpg`,
|
|
151
|
+
alt: "Entrance foyer with original mosaic floor.",
|
|
152
|
+
tags: {
|
|
153
|
+
room: "entry",
|
|
154
|
+
category: "interior"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
id: "ph_018",
|
|
159
|
+
url: `${PHOTO_BASE}/18-patio.jpg`,
|
|
160
|
+
alt: "Patio with built-in seating and planters.",
|
|
161
|
+
tags: {
|
|
162
|
+
room: "patio",
|
|
163
|
+
category: "exterior"
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: "ph_019",
|
|
168
|
+
url: `${PHOTO_BASE}/19-outdoor-deck.jpg`,
|
|
169
|
+
alt: "Outdoor deck with sunset view.",
|
|
170
|
+
tags: {
|
|
171
|
+
room: "deck",
|
|
172
|
+
category: "exterior"
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
id: "ph_020",
|
|
177
|
+
url: `${PHOTO_BASE}/20-exterior-hero.jpg`,
|
|
178
|
+
alt: "Mansard victorian facade at golden hour.",
|
|
179
|
+
tags: {
|
|
180
|
+
room: "exterior-front",
|
|
181
|
+
category: "exterior"
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
];
|
|
185
|
+
const allPhotos = galleryPhotos;
|
|
186
|
+
const RUNG_WIDTHS = [
|
|
187
|
+
320,
|
|
188
|
+
640,
|
|
189
|
+
960,
|
|
190
|
+
1200,
|
|
191
|
+
1600,
|
|
192
|
+
2048
|
|
193
|
+
];
|
|
194
|
+
function mkResponsive(url, width, height) {
|
|
195
|
+
const widths = RUNG_WIDTHS.filter((w) => w <= width);
|
|
196
|
+
if (widths.length === 0) widths.push(width);
|
|
197
|
+
const ladder = (ext) => widths.map((w) => `${url}.${w}.${ext} ${w}w`).join(", ");
|
|
198
|
+
return {
|
|
199
|
+
sources: [
|
|
200
|
+
{
|
|
201
|
+
type: "image/avif",
|
|
202
|
+
srcset: ladder("avif")
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
type: "image/webp",
|
|
206
|
+
srcset: ladder("webp")
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
type: "image/jpeg",
|
|
210
|
+
srcset: ladder("jpg")
|
|
211
|
+
}
|
|
212
|
+
],
|
|
213
|
+
width,
|
|
214
|
+
height
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
const FP_BASE = "https://example.invalid/floorplans/queensway";
|
|
218
|
+
function fp(id, url, alt, floorLabel, position) {
|
|
219
|
+
return {
|
|
220
|
+
id,
|
|
221
|
+
url,
|
|
222
|
+
alt,
|
|
223
|
+
floor_label: floorLabel,
|
|
224
|
+
position,
|
|
225
|
+
responsive: mkResponsive(url, 1024, 1024)
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
const FLOORPLAN_3BR = (suffix) => [fp(`fp_3br_${suffix}_a`, `${FP_BASE}/3br-${suffix}-l1.png`, "3BR layout — main floor.", "Main Floor", 0), fp(`fp_3br_${suffix}_b`, `${FP_BASE}/3br-${suffix}-l2.png`, "3BR layout — upper floor.", "Upper Floor", 1)];
|
|
229
|
+
const FLOORPLAN_2BR = (suffix) => [fp(`fp_2br_${suffix}_a`, `${FP_BASE}/2br-${suffix}-l1.png`, "2BR layout.", null, 0)];
|
|
230
|
+
const FLOORPLAN_4BR = (suffix) => [
|
|
231
|
+
fp(`fp_4br_${suffix}_a`, `${FP_BASE}/4br-${suffix}-l1.png`, "4BR layout — main floor.", "Main Floor", 0),
|
|
232
|
+
fp(`fp_4br_${suffix}_b`, `${FP_BASE}/4br-${suffix}-l2.png`, "4BR layout — upper floor.", "Upper Floor", 1),
|
|
233
|
+
fp(`fp_4br_${suffix}_c`, `${FP_BASE}/4br-${suffix}-l3.png`, "4BR layout — penthouse.", "Penthouse", 2)
|
|
234
|
+
];
|
|
235
|
+
const FLOORPLAN_STUDIO = (suffix) => [fp(`fp_studio_${suffix}_a`, `${FP_BASE}/studio-${suffix}-l1.png`, "Studio layout.", null, 0)];
|
|
236
|
+
function unit(position, unitLabel, beds, baths, sqft, price, notes, description, features, floorPlans) {
|
|
237
|
+
return {
|
|
238
|
+
unit_id: `unit_${String(position + 1).padStart(2, "0")}`,
|
|
239
|
+
unit_label: unitLabel,
|
|
240
|
+
beds,
|
|
241
|
+
baths,
|
|
242
|
+
sqft,
|
|
243
|
+
price,
|
|
244
|
+
notes,
|
|
245
|
+
description,
|
|
246
|
+
features,
|
|
247
|
+
position,
|
|
248
|
+
floor_plans: floorPlans
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
const units = [
|
|
252
|
+
unit(0, "Unit 1", 3, 2.5, 3119, "210000", "Corner unit, southern exposure.", "A sun-filled corner residence with southern exposure across two walls of original bay windows. The open kitchen carries a quartz waterfall island into a living and dining room anchored by a working gas fireplace. The primary suite adds dual closets and a spa bath, with two further bedrooms off a quiet hall.", [
|
|
253
|
+
"Quartz waterfall island",
|
|
254
|
+
"Working gas fireplace",
|
|
255
|
+
"Primary spa bath",
|
|
256
|
+
"In-unit washer & dryer",
|
|
257
|
+
"Deeded garage parking",
|
|
258
|
+
"Central air"
|
|
259
|
+
], FLOORPLAN_3BR("1")),
|
|
260
|
+
unit(1, "Unit 2", 2, 2, 2450, "Reserved", "Bay-window living area.", "A bright two-bedroom with a bay-window living area that frames the tree-lined street. Engineered hardwood runs throughout an open layout, and the kitchen pairs integrated appliances with a breakfast bar. Both bedrooms sit on the quiet rear of the building, served by full and half baths.", [
|
|
261
|
+
"Bay-window living room",
|
|
262
|
+
"Engineered hardwood floors",
|
|
263
|
+
"Integrated appliances",
|
|
264
|
+
"Breakfast bar",
|
|
265
|
+
"Full + half bath",
|
|
266
|
+
"In-unit laundry"
|
|
267
|
+
], FLOORPLAN_2BR("2")),
|
|
268
|
+
unit(2, "Unit 3", 4, 3, 3800, "Sold", "Penthouse with private rooftop terrace.", "The building's signature penthouse, crowned by a private rooftop terrace with skyline views. Four bedrooms and three baths wrap a great room with eleven-foot ceilings and a chef's kitchen. A wet bar, walk-in pantry, and dedicated mudroom round out the top-floor plan.", [
|
|
269
|
+
"Private rooftop terrace",
|
|
270
|
+
"11-ft ceilings",
|
|
271
|
+
"Chef's kitchen",
|
|
272
|
+
"Wet bar",
|
|
273
|
+
"Walk-in pantry",
|
|
274
|
+
"Two-car parking"
|
|
275
|
+
], FLOORPLAN_4BR("3")),
|
|
276
|
+
unit(3, "Unit 4", 2, 1.5, 1850, "159000", "Garden-level with patio access.", "A garden-level two-bedroom opening directly onto a private brick patio. The layout keeps living and sleeping zones separate, with a renovated kitchen and a flexible nook that suits a home office. Extra storage and a half bath make it an easy turnkey home.", [
|
|
277
|
+
"Private brick patio",
|
|
278
|
+
"Home-office nook",
|
|
279
|
+
"Renovated kitchen",
|
|
280
|
+
"Extra storage",
|
|
281
|
+
"Half bath",
|
|
282
|
+
"Pet-friendly"
|
|
283
|
+
], FLOORPLAN_2BR("4")),
|
|
284
|
+
unit(4, "Unit 5", 3, 2.5, 3119, "210000", "Mirror of Unit 1, north-facing.", "A north-facing three-bedroom mirroring the corner plan, with even, glare-free light ideal for working from home. The kitchen island seats four and flows to a fireplace living room. The primary suite offers a walk-in closet and a double-vanity bath.", [
|
|
285
|
+
"Island seats four",
|
|
286
|
+
"Fireplace living room",
|
|
287
|
+
"Walk-in closet",
|
|
288
|
+
"Double-vanity bath",
|
|
289
|
+
"In-unit laundry",
|
|
290
|
+
"Central air"
|
|
291
|
+
], FLOORPLAN_3BR("5")),
|
|
292
|
+
unit(5, "Unit 6", 2, 2, 2450, "185000", "Bay-window living area.", "A classic two-bedroom with a bay-window sitting area and preserved crown moldings. The updated kitchen opens to the dining room, and both bedrooms enjoy generous closets. Hardwood floors, recessed lighting, and a renovated bath complete the unit.", [
|
|
293
|
+
"Bay-window sitting area",
|
|
294
|
+
"Original crown molding",
|
|
295
|
+
"Updated kitchen",
|
|
296
|
+
"Generous closets",
|
|
297
|
+
"Recessed lighting",
|
|
298
|
+
"Renovated bath"
|
|
299
|
+
], FLOORPLAN_2BR("6")),
|
|
300
|
+
unit(6, "Unit 7", 4, 3, 3800, "289000", "Skyline-view penthouse.", "A four-bedroom penthouse with skyline views from a wall of west-facing windows. The great room steps up to a dining area beneath a statement chandelier, and the kitchen features dual ovens and a butler's pantry. Three full baths serve the bedroom wing.", [
|
|
301
|
+
"West-facing skyline views",
|
|
302
|
+
"Dual ovens",
|
|
303
|
+
"Butler's pantry",
|
|
304
|
+
"Statement great room",
|
|
305
|
+
"Three full baths",
|
|
306
|
+
"Two-car parking"
|
|
307
|
+
], FLOORPLAN_4BR("7")),
|
|
308
|
+
unit(7, "Unit 8", 2, 1.5, 1850, "159000", "Quiet rear-facing layout.", "A quiet rear-facing two-bedroom set away from the street, prized for its calm and privacy. An efficient galley kitchen serves an open living and dining space, and both bedrooms back onto the landscaped courtyard. A full and half bath round out the plan.", [
|
|
309
|
+
"Courtyard-facing bedrooms",
|
|
310
|
+
"Galley kitchen",
|
|
311
|
+
"Open living/dining",
|
|
312
|
+
"Full + half bath",
|
|
313
|
+
"In-unit laundry",
|
|
314
|
+
"Extra closet space"
|
|
315
|
+
], FLOORPLAN_2BR("8")),
|
|
316
|
+
unit(8, "Unit 9", 0, 1, 720, "95000", "Studio with built-in murphy bed.", "A smartly designed studio with a built-in murphy bed that reclaims the floor by day. A compact kitchen with full-size appliances lines one wall, and a renovated three-quarter bath keeps the footprint efficient. Ideal as a pied-à-terre or first home.", [
|
|
317
|
+
"Built-in murphy bed",
|
|
318
|
+
"Full-size appliances",
|
|
319
|
+
"Renovated bath",
|
|
320
|
+
"Smart storage",
|
|
321
|
+
"Pied-à-terre ready"
|
|
322
|
+
], FLOORPLAN_STUDIO("9")),
|
|
323
|
+
unit(9, "Unit 10", 3, 2.5, 3050, "208000", "Original tin ceilings preserved.", "A three-bedroom that preserves the building's original pressed-tin ceilings alongside a fully modern kitchen. The living room centers on a restored mantel, and a sunroom off the primary bedroom makes a perfect reading retreat. Two and a half baths serve the floor.", [
|
|
324
|
+
"Original tin ceilings",
|
|
325
|
+
"Restored mantel",
|
|
326
|
+
"Primary sunroom",
|
|
327
|
+
"Modern kitchen",
|
|
328
|
+
"2.5 baths",
|
|
329
|
+
"In-unit laundry"
|
|
330
|
+
], FLOORPLAN_3BR("10")),
|
|
331
|
+
unit(10, "Unit 11", 2, 2, 2450, "185000", "Eat-in kitchen with breakfast nook.", "A welcoming two-bedroom built around an eat-in kitchen with a sunlit breakfast nook. The living room opens to a small balcony overlooking Centre Street, and both bedrooms offer custom closet systems. A renovated full bath and in-unit laundry complete the home.", [
|
|
332
|
+
"Eat-in kitchen",
|
|
333
|
+
"Breakfast nook",
|
|
334
|
+
"Centre Street balcony",
|
|
335
|
+
"Custom closets",
|
|
336
|
+
"Renovated bath",
|
|
337
|
+
"In-unit laundry"
|
|
338
|
+
], FLOORPLAN_2BR("11")),
|
|
339
|
+
unit(11, "Unit 12", 4, 3, 3800, "289000", "Top-floor with private balcony.", "A top-floor four-bedroom with a private balcony tucked under the mansard roofline. The vaulted great room draws light through skylights, and the kitchen anchors an open plan with a generous island. A flexible fourth bedroom works equally well as a media room.", [
|
|
340
|
+
"Private balcony",
|
|
341
|
+
"Vaulted great room",
|
|
342
|
+
"Skylights",
|
|
343
|
+
"Generous island",
|
|
344
|
+
"Flex media room",
|
|
345
|
+
"Two-car parking"
|
|
346
|
+
], FLOORPLAN_4BR("12"))
|
|
347
|
+
];
|
|
348
|
+
const samplePois = [
|
|
349
|
+
{
|
|
350
|
+
id: "poi_r1",
|
|
351
|
+
category: "restaurant",
|
|
352
|
+
name: "Rozafa Mediterranean Bistro",
|
|
353
|
+
distance: "0.2 mi",
|
|
354
|
+
lat: 42.3122,
|
|
355
|
+
lng: -71.1085,
|
|
356
|
+
url: "https://example.invalid/poi/rozafa"
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
id: "poi_r2",
|
|
360
|
+
category: "restaurant",
|
|
361
|
+
name: "Dotty's Kitchen & Raw Bar",
|
|
362
|
+
distance: "0.3 mi",
|
|
363
|
+
lat: 42.3088,
|
|
364
|
+
lng: -71.1132,
|
|
365
|
+
url: "https://example.invalid/poi/dottys"
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
id: "poi_r3",
|
|
369
|
+
category: "restaurant",
|
|
370
|
+
name: "Fuji at WoC",
|
|
371
|
+
distance: "0.4 mi",
|
|
372
|
+
lat: 42.3135,
|
|
373
|
+
lng: -71.1142,
|
|
374
|
+
url: "https://example.invalid/poi/fuji"
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
id: "poi_r4",
|
|
378
|
+
category: "restaurant",
|
|
379
|
+
name: "The Fours Restaurant Quincy",
|
|
380
|
+
distance: "0.5 mi",
|
|
381
|
+
lat: 42.306,
|
|
382
|
+
lng: -71.107,
|
|
383
|
+
url: "https://example.invalid/poi/the-fours"
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
id: "poi_p1",
|
|
387
|
+
category: "park",
|
|
388
|
+
name: "Jamaica Pond",
|
|
389
|
+
distance: "0.4 mi",
|
|
390
|
+
lat: 42.317,
|
|
391
|
+
lng: -71.119,
|
|
392
|
+
url: "https://example.invalid/poi/jamaica-pond"
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
id: "poi_p2",
|
|
396
|
+
category: "park",
|
|
397
|
+
name: "Arnold Arboretum",
|
|
398
|
+
distance: "0.9 mi",
|
|
399
|
+
lat: 42.299,
|
|
400
|
+
lng: -71.123,
|
|
401
|
+
url: "https://example.invalid/poi/arboretum"
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
id: "poi_p3",
|
|
405
|
+
category: "park",
|
|
406
|
+
name: "Olmsted Park",
|
|
407
|
+
distance: "0.7 mi",
|
|
408
|
+
lat: 42.321,
|
|
409
|
+
lng: -71.113,
|
|
410
|
+
url: "https://example.invalid/poi/olmsted"
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
id: "poi_p4",
|
|
414
|
+
category: "park",
|
|
415
|
+
name: "Franklin Park",
|
|
416
|
+
distance: "1.2 mi",
|
|
417
|
+
lat: 42.302,
|
|
418
|
+
lng: -71.089,
|
|
419
|
+
url: "https://example.invalid/poi/franklin-park"
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
id: "poi_t1",
|
|
423
|
+
category: "transit",
|
|
424
|
+
name: "Stony Brook (Orange Line)",
|
|
425
|
+
distance: "0.4 mi",
|
|
426
|
+
lat: 42.317,
|
|
427
|
+
lng: -71.1043,
|
|
428
|
+
url: "https://example.invalid/poi/stony-brook"
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
id: "poi_t2",
|
|
432
|
+
category: "transit",
|
|
433
|
+
name: "Forest Hills (Orange Line)",
|
|
434
|
+
distance: "1.0 mi",
|
|
435
|
+
lat: 42.3008,
|
|
436
|
+
lng: -71.1137,
|
|
437
|
+
url: "https://example.invalid/poi/forest-hills"
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
id: "poi_t3",
|
|
441
|
+
category: "transit",
|
|
442
|
+
name: "Route 39 bus stop",
|
|
443
|
+
distance: "0.1 mi",
|
|
444
|
+
lat: 42.3108,
|
|
445
|
+
lng: -71.1112,
|
|
446
|
+
url: "https://example.invalid/poi/bus-39"
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
id: "poi_t4",
|
|
450
|
+
category: "transit",
|
|
451
|
+
name: "Commuter Rail — Forest Hills",
|
|
452
|
+
distance: "1.0 mi",
|
|
453
|
+
lat: 42.3007,
|
|
454
|
+
lng: -71.114,
|
|
455
|
+
url: "https://example.invalid/poi/commuter-rail"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
id: "poi_s1",
|
|
459
|
+
category: "shopping",
|
|
460
|
+
name: "Centre Street Shops",
|
|
461
|
+
distance: "0.2 mi",
|
|
462
|
+
lat: 42.3125,
|
|
463
|
+
lng: -71.114,
|
|
464
|
+
url: "https://example.invalid/poi/centre-st"
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
id: "poi_s2",
|
|
468
|
+
category: "shopping",
|
|
469
|
+
name: "JP Licks Boutique Row",
|
|
470
|
+
distance: "0.3 mi",
|
|
471
|
+
lat: 42.314,
|
|
472
|
+
lng: -71.1118,
|
|
473
|
+
url: "https://example.invalid/poi/boutique-row"
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
id: "poi_s3",
|
|
477
|
+
category: "shopping",
|
|
478
|
+
name: "Whole Foods Jamaica Plain",
|
|
479
|
+
distance: "0.5 mi",
|
|
480
|
+
lat: 42.3219,
|
|
481
|
+
lng: -71.1098,
|
|
482
|
+
url: "https://example.invalid/poi/wholefoods"
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
id: "poi_s4",
|
|
486
|
+
category: "shopping",
|
|
487
|
+
name: "Forest Hills Farmers Market",
|
|
488
|
+
distance: "0.9 mi",
|
|
489
|
+
lat: 42.3009,
|
|
490
|
+
lng: -71.1131,
|
|
491
|
+
url: "https://example.invalid/poi/farmers-market"
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
id: "poi_c1",
|
|
495
|
+
category: "coffee",
|
|
496
|
+
name: "Canto 6 Bakery",
|
|
497
|
+
distance: "0.2 mi",
|
|
498
|
+
lat: 42.3133,
|
|
499
|
+
lng: -71.1126,
|
|
500
|
+
url: "https://example.invalid/poi/canto6"
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
id: "poi_c2",
|
|
504
|
+
category: "coffee",
|
|
505
|
+
name: "Ula Cafe",
|
|
506
|
+
distance: "0.5 mi",
|
|
507
|
+
lat: 42.305,
|
|
508
|
+
lng: -71.114,
|
|
509
|
+
url: "https://example.invalid/poi/ula"
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
id: "poi_c3",
|
|
513
|
+
category: "coffee",
|
|
514
|
+
name: "Tres Gatos Cafe",
|
|
515
|
+
distance: "0.3 mi",
|
|
516
|
+
lat: 42.3094,
|
|
517
|
+
lng: -71.1158,
|
|
518
|
+
url: "https://example.invalid/poi/tres-gatos"
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
id: "poi_c4",
|
|
522
|
+
category: "coffee",
|
|
523
|
+
name: "J.P. Licks",
|
|
524
|
+
distance: "0.4 mi",
|
|
525
|
+
lat: 42.317,
|
|
526
|
+
lng: -71.1186,
|
|
527
|
+
url: "https://example.invalid/poi/jp-licks"
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
id: "poi_f1",
|
|
531
|
+
category: "fitness",
|
|
532
|
+
name: "FitRec JP",
|
|
533
|
+
distance: "0.3 mi",
|
|
534
|
+
lat: 42.308,
|
|
535
|
+
lng: -71.1075,
|
|
536
|
+
url: "https://example.invalid/poi/fitrec"
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
id: "poi_f2",
|
|
540
|
+
category: "fitness",
|
|
541
|
+
name: "Forge Fitness",
|
|
542
|
+
distance: "0.6 mi",
|
|
543
|
+
lat: 42.316,
|
|
544
|
+
lng: -71.105,
|
|
545
|
+
url: "https://example.invalid/poi/forge"
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
id: "poi_f3",
|
|
549
|
+
category: "fitness",
|
|
550
|
+
name: "Beacon Yoga",
|
|
551
|
+
distance: "0.4 mi",
|
|
552
|
+
lat: 42.314,
|
|
553
|
+
lng: -71.1075,
|
|
554
|
+
url: "https://example.invalid/poi/beacon-yoga"
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
id: "poi_f4",
|
|
558
|
+
category: "fitness",
|
|
559
|
+
name: "JP CrossFit",
|
|
560
|
+
distance: "0.7 mi",
|
|
561
|
+
lat: 42.305,
|
|
562
|
+
lng: -71.118,
|
|
563
|
+
url: "https://example.invalid/poi/jp-crossfit"
|
|
564
|
+
}
|
|
565
|
+
];
|
|
566
|
+
const sampleContacts = [{
|
|
567
|
+
library_item_id: "li_donovan",
|
|
568
|
+
category: "contact",
|
|
569
|
+
type: "agent",
|
|
570
|
+
position: 0,
|
|
571
|
+
fields: {
|
|
572
|
+
display_name: "James Donovan",
|
|
573
|
+
title: "Listing Agent",
|
|
574
|
+
bio: "James Donovan is a 15-year veteran of the Boston real estate market, specializing in historic multi-family conversions in Jamaica Plain and the South End. He has closed over $400M in residential transactions and is known for white-glove attention to multi-unit listings.",
|
|
575
|
+
headshot_url: "https://example.invalid/contacts/james-donovan.jpg",
|
|
576
|
+
website_url: "https://homepages.io",
|
|
577
|
+
email: "info@homepages.io",
|
|
578
|
+
phone: "(603) 555-1068",
|
|
579
|
+
address: "3033 Fifth Ave, Suite 100, Boston, MA 92103",
|
|
580
|
+
socials: [
|
|
581
|
+
{
|
|
582
|
+
platform: "instagram",
|
|
583
|
+
url: "https://instagram.com/okanemarketing/"
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
platform: "linkedin",
|
|
587
|
+
url: "https://linkedin.com/company/okanemarketing/"
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
platform: "x",
|
|
591
|
+
url: "https://x.com/okanemarketing"
|
|
592
|
+
}
|
|
593
|
+
]
|
|
594
|
+
}
|
|
595
|
+
}];
|
|
596
|
+
const sampleAmenities = [
|
|
597
|
+
{
|
|
598
|
+
id: "parking",
|
|
599
|
+
label: "Parking",
|
|
600
|
+
icon: "square-parking",
|
|
601
|
+
description: "Great parking benefits in the neighborhood",
|
|
602
|
+
items: [
|
|
603
|
+
"4 spaces for visitors per tenant",
|
|
604
|
+
"Automatic parking door for entrance",
|
|
605
|
+
"Space for 2 vehicles",
|
|
606
|
+
"Curbside parking available"
|
|
607
|
+
]
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
id: "neighborhood",
|
|
611
|
+
label: "Neighborhood",
|
|
612
|
+
icon: "map-pinned",
|
|
613
|
+
description: "Friendly neighborhood with great venues",
|
|
614
|
+
items: [
|
|
615
|
+
"Walkable to Centre Street shops & cafés",
|
|
616
|
+
"Steps from Jamaica Pond",
|
|
617
|
+
"Near top-rated schools"
|
|
618
|
+
]
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
id: "outdoors",
|
|
622
|
+
label: "Outdoor & Parks",
|
|
623
|
+
icon: "trees",
|
|
624
|
+
description: "Parks and playgrounds nearby",
|
|
625
|
+
items: [
|
|
626
|
+
"Arnold Arboretum minutes away",
|
|
627
|
+
"Private rooftop terrace",
|
|
628
|
+
"Landscaped courtyard"
|
|
629
|
+
]
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
id: "finishes",
|
|
633
|
+
label: "Interior Finishes",
|
|
634
|
+
icon: "swatch-book",
|
|
635
|
+
description: "Premium finishes for a beautiful home",
|
|
636
|
+
items: [
|
|
637
|
+
"Quartz countertops",
|
|
638
|
+
"Engineered hardwood floors",
|
|
639
|
+
"Custom millwork & trim"
|
|
640
|
+
]
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
id: "appliances",
|
|
644
|
+
label: "Appliances",
|
|
645
|
+
icon: "refrigerator",
|
|
646
|
+
description: "Modern, energy-efficient appliances included.",
|
|
647
|
+
items: [
|
|
648
|
+
"Miele gas range",
|
|
649
|
+
"Integrated refrigerator",
|
|
650
|
+
"In-unit washer & dryer"
|
|
651
|
+
]
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
id: "transportation",
|
|
655
|
+
label: "Transportation",
|
|
656
|
+
icon: "train-front",
|
|
657
|
+
description: "Convenient access to public transit and main roads.",
|
|
658
|
+
items: [
|
|
659
|
+
"Orange Line a short walk away",
|
|
660
|
+
"Bus routes at the door",
|
|
661
|
+
"Quick access to Route 1 & I-93"
|
|
662
|
+
]
|
|
663
|
+
}
|
|
664
|
+
];
|
|
665
|
+
const sampleProperty = {
|
|
666
|
+
address: "101 Queensway, Jamaica Plain, MA 02130",
|
|
667
|
+
address_lines: ["101 Queensway", "Jamaica Plain, MA 02130"],
|
|
668
|
+
coordinates: {
|
|
669
|
+
lat: 42.31,
|
|
670
|
+
lng: -71.11
|
|
671
|
+
},
|
|
672
|
+
listing_intent: "for_sale",
|
|
673
|
+
status: "For Sale",
|
|
674
|
+
property_type: "multi_family",
|
|
675
|
+
year_built: 1885,
|
|
676
|
+
lot_size: "0.18 acres",
|
|
677
|
+
units,
|
|
678
|
+
contacts: [{
|
|
679
|
+
id: "primary",
|
|
680
|
+
primary: true,
|
|
681
|
+
name: sampleContacts[0].fields.display_name,
|
|
682
|
+
title: sampleContacts[0].fields.title,
|
|
683
|
+
bio: sampleContacts[0].fields.bio,
|
|
684
|
+
email: sampleContacts[0].fields.email,
|
|
685
|
+
phone: "(603) 555-1068",
|
|
686
|
+
address: sampleContacts[0].fields.address,
|
|
687
|
+
website_url: sampleContacts[0].fields.website_url,
|
|
688
|
+
avatar_upload_id: "upload_headshot_sample",
|
|
689
|
+
instagram_url: sampleContacts[0].fields.socials.find((s) => s.platform === "instagram")?.url ?? null,
|
|
690
|
+
linkedin_url: sampleContacts[0].fields.socials.find((s) => s.platform === "linkedin")?.url ?? null,
|
|
691
|
+
x_url: sampleContacts[0].fields.socials.find((s) => s.platform === "x")?.url ?? null,
|
|
692
|
+
facebook_url: sampleContacts[0].fields.socials.find((s) => s.platform === "facebook")?.url ?? null
|
|
693
|
+
}]
|
|
694
|
+
};
|
|
695
|
+
const sampleHeroSlots = {
|
|
696
|
+
headline: "A mansard victorian single-family home in the heart of Jamaica Plain",
|
|
697
|
+
hero_image: {
|
|
698
|
+
photo_id: galleryPhotos[19].id,
|
|
699
|
+
url: galleryPhotos[19].url,
|
|
700
|
+
alt: galleryPhotos[19].alt
|
|
701
|
+
},
|
|
702
|
+
brand_logo: null,
|
|
703
|
+
listing_status: "for_sale"
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
//#endregion
|
|
707
|
+
export { allPhotos, mkResponsive, sampleAmenities, sampleContacts, sampleHeroSlots, samplePois, sampleProperty };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { AmenityItem, ContactFixture, PhotoFixture, PoiFixture, allPhotos, mkResponsive, sampleAmenities, sampleContacts, sampleHeroSlots, samplePois, sampleProperty } from "./fixtures/sample-property.js";
|
|
2
|
+
export { type AmenityItem, type ContactFixture, type PhotoFixture, type PoiFixture, allPhotos, mkResponsive, sampleAmenities, sampleContacts, sampleHeroSlots, samplePois, sampleProperty };
|
package/dist/fixtures.js
ADDED