-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
157 lines (124 loc) · 4.58 KB
/
script.js
File metadata and controls
157 lines (124 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
document.addEventListener("DOMContentLoaded", () => {
const menuButton = document.querySelector(".menu-toggle");
const nav = document.querySelector("#site-nav");
if (menuButton && nav) {
menuButton.addEventListener("click", () => {
const isOpen = nav.classList.toggle("open");
menuButton.setAttribute("aria-expanded", String(isOpen));
});
nav.querySelectorAll("a").forEach((link) => {
link.addEventListener("click", () => {
nav.classList.remove("open");
menuButton.setAttribute("aria-expanded", "false");
});
});
}
const form = document.querySelector("#contactForm");
const status = document.querySelector("#formStatus");
if (form && status) {
form.addEventListener("submit", () => {
const button = form.querySelector("button[type='submit']");
if (button) {
button.disabled = true;
button.textContent = "Sending...";
}
status.textContent = "Sending your request. After it goes through, you can text photos to (208) 861-2302 for a faster estimate.";
status.className = "form-status";
});
}
initProjectGalleries();
});
async function initProjectGalleries() {
const gallery = document.querySelector("[data-project-gallery]");
const featured = document.querySelector("[data-featured-projects]");
if (!gallery && !featured) {
return;
}
try {
const response = await fetch("projects.json", { cache: "no-cache" });
if (!response.ok) {
throw new Error("Project manifest unavailable");
}
const projects = (await response.json()).filter((project) => {
return project && project.image && project.hidden !== true;
});
if (!projects.length) {
return;
}
if (gallery) {
renderProjectCards(gallery, projects);
}
if (featured) {
renderProjectCards(featured, pickWeeklyFeaturedProjects(projects, 3));
}
} catch (error) {
// Keep the static fallback cards if the manifest cannot be loaded.
console.warn(error);
}
}
function pickWeeklyFeaturedProjects(projects, count) {
const pool = projects.filter((project) => project.featured !== false);
if (pool.length <= count) {
return pool;
}
const now = new Date();
const startOfYear = new Date(now.getFullYear(), 0, 1);
const weekIndex = Math.floor((now - startOfYear) / (7 * 24 * 60 * 60 * 1000));
const selected = [];
for (let index = 0; index < count; index += 1) {
selected.push(pool[(weekIndex + index) % pool.length]);
}
return selected;
}
function renderProjectCards(container, projects) {
container.replaceChildren(...projects.map(createProjectCard));
}
function createProjectCard(project) {
const article = document.createElement("article");
article.className = "project-card";
const imageWrap = document.createElement("div");
imageWrap.className = "project-image-wrap";
const image = document.createElement("img");
image.src = project.image;
image.alt = project.alt || `${project.title || "Hands-On Idaho project"} in ${project.area || "the Treasure Valley"}`;
image.loading = "lazy";
image.addEventListener("error", () => {
imageWrap.classList.add("missing-image");
image.remove();
});
imageWrap.append(image);
const content = document.createElement("div");
content.className = "project-content";
const eyebrow = document.createElement("p");
eyebrow.className = "eyebrow";
eyebrow.textContent = [project.service, project.area].filter(Boolean).join(" • ");
const title = document.createElement("h2");
title.textContent = project.title || "Project Photo";
const description = document.createElement("p");
description.textContent = project.description || "Real Hands-On Idaho project photo from around the Treasure Valley.";
content.append(eyebrow, title, description);
if (Array.isArray(project.tags) && project.tags.length) {
const tags = document.createElement("div");
tags.className = "project-tags";
project.tags.slice(0, 4).forEach((tag) => {
const item = document.createElement("span");
item.className = "project-tag";
item.textContent = tag;
tags.append(item);
});
content.append(tags);
}
if (project.needsReview) {
const review = document.createElement("p");
review.className = "project-review-note";
review.textContent = "Photo details need final review.";
content.append(review);
}
const link = document.createElement("a");
link.className = "text-link";
link.href = "contact.html";
link.textContent = project.cta || "Request a project estimate";
content.append(link);
article.append(imageWrap, content);
return article;
}