Phase 6: QA fixes for Lighthouse and navigation
- Map is a titled iframe (accessibility); drop @next/third-parties - "Services" nav toggle is a real button with aria-expanded (SEO crawlable-anchors, accessibility) - Hero images use default quality; page-header image is preloaded (LCP) - Mobile services submenu no longer clips its last item Mobile Lighthouse: / 94/100/100/100, /services/computer-repair 96/100/100/100, /areas/henderson 97/100/100/100, /contact 95/100/100/100 (performance/accessibility/best practices/SEO). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
4d901b351e
commit
275bce3b87
7 files changed
+23
-33
No files matched your search
Generated
-20
@@ -9,7 +9,6 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@next/env": "^16.2.10",
|
"@next/env": "^16.2.10",
|
||||||
"@next/third-parties": "^16.2.10",
|
|
||||||
"@radix-ui/react-accordion": "^1.2.3",
|
"@radix-ui/react-accordion": "^1.2.3",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
@@ -1304,19 +1303,6 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/third-parties": {
|
|
||||||
"version": "16.2.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/third-parties/-/third-parties-16.2.10.tgz",
|
|
||||||
"integrity": "sha512-H3yxCMLziM1JKXnjQv83WBH2cp1fB1vMxpC1/bBTpvvaesBEuRuprpzq5RI32atis0VhUZflgdpJdGNZIGpQaQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"third-party-capital": "1.0.20"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"next": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0-beta.0",
|
|
||||||
"react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||||
@@ -7298,12 +7284,6 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/third-party-capital": {
|
|
||||||
"version": "1.0.20",
|
|
||||||
"resolved": "https://registry.npmjs.org/third-party-capital/-/third-party-capital-1.0.20.tgz",
|
|
||||||
"integrity": "sha512-oB7yIimd8SuGptespDAZnNkzIz+NWaJCu2RMsbs4Wmp9zSDUM8Nhi3s2OOcqYuv3mN4hitXc8DVx+LyUmbUDiA==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/tinyglobby": {
|
"node_modules/tinyglobby": {
|
||||||
"version": "0.2.17",
|
"version": "0.2.17",
|
||||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@next/env": "^16.2.10",
|
"@next/env": "^16.2.10",
|
||||||
"@next/third-parties": "^16.2.10",
|
|
||||||
"@radix-ui/react-accordion": "^1.2.3",
|
"@radix-ui/react-accordion": "^1.2.3",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ export default function HeaderSm({ text }) {
|
|||||||
src={bgimage}
|
src={bgimage}
|
||||||
alt=""
|
alt=""
|
||||||
placeholder="blur"
|
placeholder="blur"
|
||||||
quality={100}
|
|
||||||
fill
|
fill
|
||||||
|
priority
|
||||||
sizes="100vw"
|
sizes="100vw"
|
||||||
style={{
|
style={{
|
||||||
objectFit: "cover",
|
objectFit: "cover",
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
import { GoogleMapsEmbed } from "@next/third-parties/google";
|
|
||||||
|
|
||||||
// This key is public by design; restrict it by HTTP referrer in Google Cloud Console.
|
// This key is public by design; restrict it by HTTP referrer in Google Cloud Console.
|
||||||
const MAPS_API_KEY = "AIzaSyDbgQY55TQY5CefsCUwKbc8RfoOUe8U5gY";
|
const MAPS_API_KEY = "AIzaSyDbgQY55TQY5CefsCUwKbc8RfoOUe8U5gY";
|
||||||
const PLACE_ID = "ChIJz0ZoDYhADW0R0TDgWoWMq0M";
|
const PLACE_ID = "ChIJz0ZoDYhADW0R0TDgWoWMq0M";
|
||||||
|
|
||||||
|
// Plain iframe so it can have an accessible title.
|
||||||
export default function MapEmbed({ height = "400px" }) {
|
export default function MapEmbed({ height = "400px" }) {
|
||||||
return (
|
return (
|
||||||
<GoogleMapsEmbed
|
<iframe
|
||||||
apiKey={MAPS_API_KEY}
|
title="Map showing Te Atatu Computers on Graham Avenue, Te Atatū Peninsula"
|
||||||
|
src={`https://www.google.com/maps/embed/v1/place?key=${MAPS_API_KEY}&q=place_id:${PLACE_ID}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height={height}
|
height={height}
|
||||||
mode="place"
|
style={{ border: 0 }}
|
||||||
q={`place_id:${PLACE_ID}`}
|
loading="lazy"
|
||||||
|
referrerPolicy="no-referrer-when-downgrade"
|
||||||
|
allowFullScreen
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -87,13 +87,15 @@ export default function Navbar() {
|
|||||||
data-state={isDropdownActive ? "open" : "close"}
|
data-state={isDropdownActive ? "open" : "close"}
|
||||||
className="flex items-center justify-center gap-1 [&[data-state=open]>svg]:rotate-180"
|
className="flex items-center justify-center gap-1 [&[data-state=open]>svg]:rotate-180"
|
||||||
>
|
>
|
||||||
<a
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-expanded={isDropdownActive}
|
||||||
className={`${styles.dropdownTitle}
|
className={`${styles.dropdownTitle}
|
||||||
${pathname === "/services" ? styles.active : ""}`}
|
${pathname.startsWith("/services") ? styles.active : ""}`}
|
||||||
onClick={handleDropdownToggle}
|
onClick={handleDropdownToggle}
|
||||||
>
|
>
|
||||||
Services
|
Services
|
||||||
</a>
|
</button>
|
||||||
<ChevronDownIcon className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
|
<ChevronDownIcon className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
|
||||||
</div>
|
</div>
|
||||||
<ul className={styles.dropdownMenu}>
|
<ul className={styles.dropdownMenu}>
|
||||||
|
|||||||
@@ -131,7 +131,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dropdownActive .dropdownMenu {
|
.dropdownActive .dropdownMenu {
|
||||||
max-height: 20em;
|
max-height: 30em;
|
||||||
transition: max-height 0.5s cubic-bezier(0.215, 0.61, 0.355, 1);
|
transition: max-height 0.5s cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,3 +219,11 @@
|
|||||||
.dropdown:not(.dropdownActive) .dropdownTitle {
|
.dropdown:not(.dropdownActive) .dropdownTitle {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdownTitle {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownTitle.active {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
@@ -120,7 +120,6 @@ export default function Home() {
|
|||||||
src={bgimage}
|
src={bgimage}
|
||||||
alt=""
|
alt=""
|
||||||
placeholder="blur"
|
placeholder="blur"
|
||||||
quality={100}
|
|
||||||
fill
|
fill
|
||||||
priority
|
priority
|
||||||
sizes="100vw"
|
sizes="100vw"
|
||||||
|
|||||||
Reference in new issue
Block a user