Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.18.0
22
19 changes: 18 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Resolved `fetchPriority` prop warning in next/image
- Updated sendgridEmail to support@webdevpath.co

## Unreleased
## 1.5.0

### Added

Expand All @@ -155,6 +155,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added Oluwatobi to 'about us'
- Updated Satoshi's profile links
- Added Damilola to 'about us'
- Updated Next.js from v15.5.14 to v15.5.19 and other outdated dependencies
- Updated Damilola's profile image format from jpg to webp
- Updated Oluwatobi's profile
- Added `sizes` prop to images with `fill` to improve page performance
- Update supported Node.js version from 20.18.0 to 22

### Fixed

Expand Down Expand Up @@ -220,3 +225,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Removed unused props from Hero layout component
- Replace sendgrid with mailjet for sending contact email
- Replace mailto:hello@webdevpath.co button links with /contact
- Removed next-pwa implementation
- Removed redundant styledComponents configuration

## Unreleased

### Added

- Introduced SDD structure for Services Page

### Fixed

### Changed
7 changes: 6 additions & 1 deletion components/blog/AuthorBio/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ export default function AuthorBio({ user }) {
<h3>Author Bio</h3>
<div className={styles['flex-container']}>
<div className={styles['image-wrapper']}>
<Image src={user.profile_image} alt="Author's profile" fill />
<Image
src={user.profile_image}
alt="Author's profile"
fill
sizes='(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw'
/>
</div>
<div className={styles['split-container']}>
<p>{user.summary}</p>
Expand Down
7 changes: 6 additions & 1 deletion components/blog/PostContent/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ export default function PostContent({ post }) {
>{`${post.user.name}\u00A0\u00A0\u00A0${publishedDate}`}</p>
{post.cover_image && (
<div className={styles.imageWrapper}>
<Image src={post.cover_image} alt='Blog post cover' fill />
<Image
src={post.cover_image}
alt='Blog post cover'
fill
sizes='(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw'
/>
</div>
)}
<div className={styles.contentContainer}>
Expand Down
8 changes: 7 additions & 1 deletion components/containers/Card/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ export function Card({ card, cardType = 'default' }) {
<div className={`${styles.card} ${styles[`card--${cardType}`] || ''}`}>
{image && (
<div className={styles.imageWrapper}>
<Image className={styles.cardImage} src={image} alt={altTag} fill />
<Image
className={styles.cardImage}
src={image}
alt={altTag}
fill
sizes='(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw'
/>
</div>
)}

Expand Down
7 changes: 6 additions & 1 deletion components/containers/Member/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ export default function Member({
<div className={styles.card}>
{image && (
<div className={styles.imageWrapper}>
<Image src={image} alt={name} fill />
<Image
src={image}
alt={name}
fill
sizes='(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw'
/>
</div>
)}

Expand Down
8 changes: 7 additions & 1 deletion components/containers/TwoColumn/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ export default function TwoColumn({
{secondTextColumn ||
(image && (
<div className={styles.inner__image}>
<Image className={styles.img} src={image} alt={altTag} fill />
<Image
className={styles.img}
src={image}
alt={altTag}
fill
sizes='(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw'
/>
</div>
))}
</Container>
Expand Down
1 change: 1 addition & 0 deletions components/layout/Hero/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default function Hero({
alt={imgAlt}
fill
priority
sizes='(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw'
/>
<Container className={styles.headerContent}>
<div className={styles.headerContentUpper}>
Expand Down
21 changes: 5 additions & 16 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
const withPWA = require('next-pwa');

module.exports = withPWA({
pwa: {
dest: 'public',
register: true,
skipWaiting: true,
disable: process.env.NODE_ENV === 'development',
},
compiler: {
styledComponents: {
ssr: true,
cssProp: true,
},
},
/** @type {import('next').NextConfig} */
const nextConfig = {
i18n: {
locales: ['en'],
defaultLocale: 'en',
Expand All @@ -29,4 +16,6 @@ module.exports = withPWA({
},
],
},
});
};

module.exports = nextConfig;
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "web-dev-path",
"version": "1.4.0",
"version": "1.5.0",
"private": true,
"scripts": {
"dev": "yarn run open-browser-win && next dev -p 3010",
Expand All @@ -19,26 +19,26 @@
]
},
"dependencies": {
"@hookform/resolvers": "^5.2.2",
"@sendgrid/mail": "^8.1.5",
"@hookform/resolvers": "^5.4.0",
"@sendgrid/mail": "^8.1.6",
"html-entities": "^2.3.2",
"next": "^15.5.14",
"next-pwa": "^2.0.2",
"next": "15.5.19",
"node-mailjet": "^6.0.9",
"react": "19.1.0",
"react-dom": "19.1.0",
"react": "19.2.7",
"react-dom": "19.2.7",
"react-google-recaptcha": "^3.1.0",
"react-hook-form": "^7.35.0",
"sass": "^1.35.1",
"swiper": "^12.1.3",
"zod": "^4.3.6"
"react-hook-form": "^7.78.0",
"sass": "^1.100.0",
"swiper": "^12.2.0",
"zod": "^4.4.3"
},
"devDependencies": {
"husky": "^9.1.7",
"lint-staged": "^16.0.0",
"prettier": "^3.5.3",
"lint-staged": "^17.0.7",
"prettier": "^3.8.4",
"prettylint": "^2.0.0",
"webpack": "^5.88.1"
"webpack": "^5.107.2",
"yaml": "^2.9.0"
},
"license": "GPL-3.0",
"packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72"
Expand Down
Binary file removed public/images/damilola.jpg
Binary file not shown.
Binary file added public/images/damilola.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/images/oluwatobi.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
148 changes: 148 additions & 0 deletions specs/services-page/decisions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Services Page Decisions

## Source of Truth

### Decision

The Services Page specification folder is the primary source of truth for this initiative.

### Reason

Requirements, decisions, implementation references, and task tracking should remain centralized and easily discoverable.

### Implementation

Contributors should consult:

- specification.md
- decisions.md
- references.md
- tasks.md

before beginning implementation work.

GitHub Issues and Pull Requests should reference these documents whenever applicable.

## Branch Strategy

### Decision

All Services Page development will occur within the `services-dev` branch.

### Reason

The Services Page represents a large initiative involving multiple contributors.

Using a dedicated branch allows the team to:

- Reduce merge conflicts.
- Test functionality independently.
- Continue maintaining the production site through `main`.
- Deploy Services Page work to a dedicated Netlify staging environment.

---

## Hero Section Form

### Decision

Remove custom intake form fields from the Hero section.

### Reason

Calendly already collects the required information.

Maintaining both a custom form and Calendly introduces duplicate data entry and unnecessary friction.

### Implementation

Replace the form with a CTA that opens Calendly.

---

## Testimonials Section

### Decision

Do not implement the Testimonials section during the initial release.

### Reason

The organization does not currently have enough completed client projects to support testimonials.

### Future State

The section may be implemented after sufficient client feedback and case studies have been collected.

---

## Pricing Strategy

### Decision

Pricing will be one of the final sections implemented.

### Reason

The team requires additional time to conduct pricing research and validate assumptions before publishing pricing information.

The goal is to establish pricing that is:

- Affordable for small businesses.
- Competitive within the market.
- Sustainable for project delivery.
- Aligned with Web Dev Path's educational mission.

### Implementation

Pricing cards may be built after pricing research is completed and approved.

---

## Specification-Driven Development

### Decision

The Services Page will be developed using a lightweight Specification-Driven Development approach.

### Reason

The team wants to:

- Improve onboarding.
- Reduce ambiguity.
- Improve collaboration.
- Improve AI-assisted development workflows.
- Create experience with specification-based delivery practices.

### Implementation

The following documents act as the source of truth:

- specification.md
- decisions.md
- tasks.md

GitHub Issues and Pull Requests should reference these documents whenever applicable.

---

## Netlify Environment Strategy

### Decision

Services Page development will be validated through a dedicated Netlify staging environment connected to `services-dev`.

### Reason

This allows the team to:

- Test independently of production.
- Validate functionality before merging.
- Review large features incrementally.

### Implementation

Production remains connected to `main`.

Services staging remains connected to `services-dev`.
Loading