Skip to content

Commit 364dd0c

Browse files
Release: Netlify_2025-12-31.02 (#41)
* improve SEO * add alt text * contact form improvement * add test coverage * address sonarqube issues and improve mobile behaviour in the the contact fallback dialog
1 parent 749b2ed commit 364dd0c

17 files changed

+666
-123
lines changed

.github/workflows/ensure-dev-to-main.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ jobs:
1111
steps:
1212
- name: Verify source is dev
1313
if: github.head_ref != 'dev'
14+
env:
15+
HEAD_REF: ${{ github.head_ref }}
1416
run: |
15-
echo "STOP: You are trying to merge '${{ github.head_ref }}' directly into main."
17+
echo "STOP: You are trying to merge '${HEAD_REF}' directly into main."
1618
echo "All code must go through the 'dev' branch first."
1719
exit 1

.github/workflows/github-pages-deploy.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ on:
55
branches:
66
- dev
77

8-
permissions:
9-
contents: read
10-
pages: write
11-
id-token: write
12-
138
concurrency:
149
group: pages
1510
cancel-in-progress: false
@@ -21,6 +16,8 @@ jobs:
2116
build:
2217
runs-on: ubuntu-latest
2318
needs: [test]
19+
permissions:
20+
contents: read
2421
steps:
2522
- name: Checkout
2623
uses: actions/checkout@v4
@@ -53,6 +50,9 @@ jobs:
5350
url: ${{ steps.deployment.outputs.page_url }}
5451
runs-on: ubuntu-latest
5552
needs: build
53+
permissions:
54+
pages: write
55+
id-token: write
5656
steps:
5757
- name: Deploy to GitHub Pages
5858
id: deployment

README.md

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,62 @@
55
[![Tests](https://github.com/fernandotonacoder/chrisert/actions/workflows/test.yml/badge.svg)](https://github.com/fernandotonacoder/chrisert/actions/workflows/test.yml)
66
[![Lint](https://github.com/fernandotonacoder/chrisert/actions/workflows/lint.yml/badge.svg)](https://github.com/fernandotonacoder/chrisert/actions/workflows/lint.yml)
77

8-
A business website for a fully-working construction services company.
8+
<table>
9+
<tr>
10+
<td rowspan="3">
11+
<a href="https://sonarcloud.io/summary/new_code?id=fernandotonacoder_chrisert">
12+
<img src="https://sonarcloud.io/images/project_badges/sonarcloud-light.svg" alt="SonarQube Cloud" />
13+
</a>
14+
</td>
15+
<td>
16+
<a href="https://sonarcloud.io/summary/new_code?id=fernandotonacoder_chrisert">
17+
<img src="https://sonarcloud.io/api/project_badges/measure?project=fernandotonacoder_chrisert&metric=alert_status" alt="Quality Gate Status" />
18+
</a>
19+
</td>
20+
</tr>
21+
<tr>
22+
<td>
23+
<a href="https://sonarcloud.io/summary/new_code?id=fernandotonacoder_chrisert">
24+
<img src="https://sonarcloud.io/api/project_badges/measure?project=fernandotonacoder_chrisert&metric=security_rating" alt="Security Rating" />
25+
</a>
26+
</td>
27+
</tr>
28+
<tr>
29+
<td>
30+
<a href="https://sonarcloud.io/summary/new_code?id=fernandotonacoder_chrisert">
31+
<img src="https://sonarcloud.io/api/project_badges/measure?project=fernandotonacoder_chrisert&metric=sqale_rating" alt="Maintainability Rating" />
32+
</a>
33+
</td>
34+
</tr>
35+
</table>
36+
37+
A high-performance web platform for a construction firm specializing in ETICS insulation. Built to bridge modern frontend development with real-world business needs, focusing on SEO and lead generation.
938

1039
## 📋 About
1140

12-
Currently working on a side project that will serve as the official website for a construction services company that specializes in applying ETICS (External Thermal Insulation Composite Systems) to both commercial and residential properties, providing thermal and acoustic insulation solutions for their clients.
41+
Currently working on a side project that will serve as the official website for a construction services company that specializes in applying ETICS (External Thermal Insulation Composite Systems) to both commercial and residential properties, providing thermal and acoustic insulation solutions for their clients.
1342

1443
Built with React and JavaScript, styled using Tailwind CSS and Shadcn UI components. The project follows a professional development workflow with GitHub Pages as a staging/test environment and Netlify for production deployment. Unit and component testing is handled with Vitest to ensure code reliability.
1544

16-
This is a frontend-focused website that leverages Netlify Forms for contact handling, eliminating the need for a complex backend infrastructure since there's no heavy business logic or database requirements involved.
45+
This is a frontend-focused website that leverages Netlify Forms for contact handling, eliminating the need for a complex backend infrastructure since there's no heavy business logic or database requirements involved.
1746

18-
Optimized for performance and SEO to maximize the company's online visibility. Fully responsive design ensuring a seamless experience across all devices.
47+
Optimized for performance and SEO to maximize the company's online visibility. Fully responsive design ensuring a seamless experience across all devices.
1948

20-
A hands-on project bridging web development skills with real business needs.
49+
A hands-on project bridging web development skills with real business needs.
2150

2251
## 🚀 Tech Stack
2352

24-
| Category | Technology |
25-
|----------|------------|
26-
| Framework | React |
27-
| Language | JavaScript |
28-
| Styling | Tailwind CSS |
29-
| UI Components | Shadcn UI |
30-
| Testing | Vitest |
31-
| Staging | GitHub Pages |
32-
| Production | Netlify |
33-
| Forms | Netlify Forms |
53+
| Category | Technology |
54+
| ------------- | --------------------------------------------------------------------------------------- |
55+
| Framework | React |
56+
| Language | JavaScript |
57+
| Styling | Tailwind CSS |
58+
| UI Components | Shadcn UI |
59+
| Testing | Vitest |
60+
| Code Quality | [SonarQube Cloud](https://sonarcloud.io/summary/new_code?id=fernandotonacoder_chrisert) |
61+
| Staging | GitHub Pages |
62+
| Production | Netlify |
63+
| Forms | Netlify Forms |
3464

3565
## 🛠️ Getting Started
3666

@@ -81,10 +111,10 @@ npm run preview
81111

82112
## 🔄 CI/CD Pipeline
83113

84-
| Branch | Environment | Checks |
85-
|--------|-------------|--------|
86-
| `dev` | GitHub Pages (Staging) | Tests, Lint, Build |
87-
| `main` | Netlify (Production) | Tests, Lint, Security Audit, Build |
114+
| Branch | Environment | Checks |
115+
| ------ | ---------------------- | ---------------------------------- |
116+
| `dev` | GitHub Pages (Staging) | Tests, Lint, Build |
117+
| `main` | Netlify (Production) | Tests, Lint, Security Audit, Build |
88118

89119
- **Branch Protection:** Both `main` and `dev` are protected with linear history required; all changes must go through PRs
90120
- **Automated Testing:** Vitest runs on every PR to `dev` and `main`
@@ -100,10 +130,10 @@ chrisert/
100130
│ ├── components/ # Reusable UI components
101131
│ ├── pages/ # Page components
102132
│ ├── assets/ # Images, fonts, etc.
103-
│ └── ...
133+
│ └── ...
104134
├── public/ # Static assets
105135
├── tests/ # Test setup
106-
└── ...
136+
└── ...
107137
```
108138

109139
## ✨ Features
@@ -118,13 +148,14 @@ chrisert/
118148

119149
The **source code** of this project is licensed under the [MIT License](LICENSE).
120150

121-
**Note:** All branding, logos, images, and business-specific content are proprietary and belong to the client. Feel free to use this codebase as a learning resource or as inspiration for your own projects!
151+
**Note:** All branding, logos, images, and business-specific content are proprietary and belong to the client. Feel free to use this codebase as a learning resource or as inspiration for your own projects!
122152

123153
## 👤 Author
124154

125155
**Fernando Tona**
156+
126157
- GitHub: [@fernandotonacoder](https://github.com/fernandotonacoder)
127158

128159
---
129160

130-
*Built with ❤️ for real-world business needs*
161+
_Built with ❤️ for real-world business needs_

index.html

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,25 @@
33
<head>
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6-
7-
<!-- Geo-targeting for Portugal -->
6+
7+
<link rel="canonical" href="https://chrisert.pt/" />
8+
89
<link rel="alternate" hreflang="pt-PT" href="https://chrisert.pt/" />
910
<link rel="alternate" hreflang="x-default" href="https://chrisert.pt/" />
1011
<meta name="geo.region" content="PT" />
1112
<meta name="geo.placename" content="Águeda, Portugal" />
12-
13+
1314
<meta
1415
name="description"
15-
content="Chrisert - Especialistas em sistemas ETICS (Capoto), isolamento térmico, remodelações e acabamentos de alta qualidade em Portugal continental."
16+
content="Chrisert - Especialistas em ETICS (Capoto), isolamento térmico de fachadas, limpeza de telhados e pintura exterior em Águeda e Portugal continental."
1617
/>
1718
<meta name="author" content="Chrisert" />
1819
<meta
1920
name="keywords"
20-
content="ETICS, Capoto, isolamento térmico, remodelações, acabamentos, construção, eficiência energética, Portugal continental, Águeda"
21+
content="ETICS, Capoto, isolamento térmico, pintura de fachadas, limpeza de telhados, renovação de fachadas, eficiência energética, Águeda, Aveiro, Portugal"
2122
/>
2223
<title>Chrisert - Especialistas em ETICS e Isolamento Térmico</title>
2324

24-
<!-- Open Graph / Facebook -->
2525
<meta property="og:type" content="website" />
2626
<meta property="og:url" content="https://chrisert.pt/" />
2727
<meta
@@ -30,14 +30,13 @@
3030
/>
3131
<meta
3232
property="og:description"
33-
content="Especialistas em sistemas ETICS (Capoto), isolamento térmico, remodelações e acabamentos de alta qualidade em Portugal continental."
33+
content="Especialistas em ETICS (Capoto), isolamento térmico de fachadas, limpeza de telhados e pintura exterior."
3434
/>
3535
<meta
3636
property="og:image"
37-
content="https://raw.githubusercontent.com/fernandotonacoder/chrisert/main/public/chrisert-logo-with-footer-and-border-no-bg.png"
37+
content="https://chrisert.pt/chrisert-logo-with-footer-and-border-no-bg.png"
3838
/>
3939

40-
<!-- Twitter -->
4140
<meta name="twitter:card" content="summary_large_image" />
4241
<meta name="twitter:url" content="https://chrisert.pt/" />
4342
<meta
@@ -46,18 +45,44 @@
4645
/>
4746
<meta
4847
name="twitter:description"
49-
content="Especialistas em sistemas ETICS (Capoto), isolamento térmico, remodelações e acabamentos de alta qualidade em Portugal continental."
48+
content="Especialistas em ETICS (Capoto), isolamento térmico de fachadas, limpeza de telhados e pintura exterior."
5049
/>
5150
<meta
5251
name="twitter:image"
53-
content="https://raw.githubusercontent.com/fernandotonacoder/chrisert/main/public/chrisert-logo-with-footer-and-border-no-bg.png"
52+
content="https://chrisert.pt/chrisert-logo-with-footer-and-border-no-bg.png"
5453
/>
5554

5655
<link
5756
rel="icon"
5857
type="image/png"
5958
href="/chrisert-logo-with-footer-and-border-no-bg.png"
6059
/>
60+
61+
<script type="application/ld+json">
62+
{
63+
"@context": "https://schema.org",
64+
"@type": "LocalBusiness",
65+
"name": "Chrisert - Especialistas em ETICS e Isolamento Térmico",
66+
"image": "https://chrisert.pt/chrisert-logo-with-footer-and-border-no-bg.png",
67+
"url": "https://chrisert.pt/",
68+
"telephone": "+351932741391",
69+
"priceRange": "$$",
70+
"address": {
71+
"@type": "PostalAddress",
72+
"streetAddress": "Rua Subida da Catraia, nº 323 R/C Esquerdo",
73+
"addressLocality": "Águeda",
74+
"addressRegion": "Aveiro",
75+
"postalCode": "3750-308",
76+
"addressCountry": "PT"
77+
},
78+
"geo": {
79+
"@type": "GeoCoordinates",
80+
"latitude": 40.5744,
81+
"longitude": -8.4447
82+
},
83+
"description": "Especialistas em ETICS (Capoto), isolamento térmico de fachadas, limpeza de telhados e pintura exterior em Águeda e Portugal continental."
84+
}
85+
</script>
6186
</head>
6287
<body>
6388
<!-- Netlify forms - hidden form for Netlify to detect (required for SPAs) -->
@@ -69,11 +94,11 @@
6994
>
7095
<input type="hidden" name="form-name" value="contacto" />
7196
<input name="bot-field" />
72-
<input type="text" name="name" />
97+
<input type="text" name="nome" />
7398
<input type="email" name="email" />
74-
<input type="tel" name="phone" />
75-
<input type="text" name="subject" />
76-
<textarea name="message"></textarea>
99+
<input type="tel" name="telefone" />
100+
<input type="text" name="assunto" />
101+
<textarea name="mensagem"></textarea>
77102
</form>
78103
<div id="root"></div>
79104
<script type="module" src="/src/main.jsx"></script>

package-lock.json

Lines changed: 39 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"embla-carousel-react": "^8.6.0",
2727
"lucide-react": "^0.555.0",
2828
"media-chrome": "^4.16.1",
29+
"prop-types": "^15.8.1",
2930
"react": "^19.2.0",
3031
"react-dom": "^19.2.0",
3132
"react-fast-marquee": "^1.6.5",

src/components/SEO.jsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import PropTypes from "prop-types";
2+
13
const SEO = ({
24
title,
35
description,
@@ -49,4 +51,13 @@ const SEO = ({
4951
);
5052
};
5153

54+
SEO.propTypes = {
55+
title: PropTypes.string,
56+
description: PropTypes.string,
57+
keywords: PropTypes.string,
58+
canonical: PropTypes.string,
59+
ogImage: PropTypes.string,
60+
ogType: PropTypes.string,
61+
};
62+
5263
export default SEO;

0 commit comments

Comments
 (0)