Coding examples
Real bits of code taken from my projects, with one-click copy.
Regex form validation
Validates contact form input client-side with a simple email regex plus a few human-friendly checks. Fields get inline styling and the user gets a clear message if anything is missing or invalid.
// Basic email validation
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
export function validateContactForm(form) {
const errors = {};
const fieldStatus = {};
const checks = {
name: (value) => {
const trimmed = value.trim();
if (!trimmed) return { valid: false, type: "missing", message: "Please enter your name." };
return { valid: true };
},
email: (value) => {
const trimmed = value.trim();
if (!trimmed) return { valid: false, type: "missing", message: "Please enter your email address." };
if (!emailPattern.test(trimmed)) {
return { valid: false, type: "invalid", message: "Please enter a valid email address." };
}
return { valid: true };
},
telephone: (value) => {
const trimmed = value.trim();
if (!trimmed) return { valid: false, type: "missing", message: "Please enter your telephone number." };
if (trimmed.replace(/\D/g, "").length < 10) {
return { valid: false, type: "invalid", message: "Please enter a valid telephone number." };
}
return { valid: true };
},
message: (value) => {
const trimmed = value.trim();
if (!trimmed) {
return {
valid: false,
type: "missing",
message: "Please enter a message.",
};
}
if (trimmed.length < 5) {
return {
valid: false,
type: "invalid",
message: "Message must be at least 5 characters.",
};
}
if (trimmed.length > 1000) {
return {
valid: false,
type: "invalid",
message: "Message must be 1000 characters or fewer.",
};
}
return { valid: true };
},
};
Object.entries(checks).forEach(([name, check]) => {
const field = form.elements[name];
if (!field) return;
const result = check(field.value);
fieldStatus[name] = result.valid ? "valid" : "invalid";
if (!result.valid) errors[name] = { label: name, type: result.type, message: result.message };
});
return { isValid: Object.keys(errors).length === 0, errors, fieldStatus };
}
Responsive service navigation (Sass)
Uses a Sass map plus an @each loop to generate themed navigation styles. The result is DRY, consistent and scalable.
// Sass loop that generates themed navigation dropdown styles
$services: (
"design": #00e5ff,
"dev": #ff6a00,
"seo": #ff2bd6,
);
@mixin mq($min) {
@media (min-width: $min) {
@content;
}
}
.services-nav {
display: none;
@include mq(992px) {
display: flex;
}
}
@each $name, $color in $services {
.nav-service--#{$name} {
position: relative;
color: #fff;
&:hover,
&:focus-visible {
background: $color;
}
&::after {
content: "";
position: absolute;
left: 50%;
top: 100%;
transform: translateX(-50%);
border: 10px solid transparent;
border-top-color: $color;
opacity: 0;
transition: opacity 0.15s ease;
}
&:hover::after,
&:focus-visible::after {
opacity: 1;
}
}
}
Layout-related tweaks (JavaScript)
A tiny utility that keeps layout in sync on wide screens and throttles work with requestAnimationFrame
so resize/scroll stays smooth.
// requestAnimationFrame-throttled layout syncing (wide screens only)
let raf = 0;
export function syncPanels(assignmentsEl, previewEl) {
const run = () => {
raf = 0;
if (window.matchMedia("(min-width: 992px)").matches) {
previewEl.style.minHeight = `${assignmentsEl.offsetHeight}px`;
} else {
previewEl.style.minHeight = "";
}
};
const schedule = () => {
if (raf) return;
raf = requestAnimationFrame(run);
};
window.addEventListener("resize", schedule);
window.addEventListener("scroll", schedule, { passive: true });
schedule();
}
Product filters hook (React/TypeScript)
A pure TypeScript React hook that memoizes the filtering logic and keeps all the domain rules (category, price range, stock status, text search and so on) in one place.
import { useMemo } from 'react'
import type { Product } from '../data/products'
export type ProductFilters = {
category: string
brand: string
size: string
gender: string
year: number | null
minPrice: number | null
maxPrice: number | null
inStockOnly: boolean
query: string
}
export function useProductFilters(
products: Product[],
{ category, brand, size, gender, year, minPrice, maxPrice, inStockOnly, query }: ProductFilters,
): Product[] {
return useMemo(() => {
const normalizedQuery = query.trim().toLowerCase()
return products.filter((product) => {
if (category !== 'All' && product.category !== category) return false
if (brand !== 'All' && product.brand !== brand) return false
if (size !== 'All' && product.size !== size) return false
if (gender !== 'All' && product.gender !== gender) return false
if (year !== null && product.year !== year) return false
if (inStockOnly && product.in_stock <= 0) return false
if (minPrice !== null && product.price_in_pounds < minPrice) return false
if (maxPrice !== null && product.price_in_pounds > maxPrice) return false
if (normalizedQuery) {
const name = `${product.brand} ${product.model}`.toLowerCase()
if (!name.includes(normalizedQuery)) return false
}
return true
})
}, [products, category, brand, size, gender, year, minPrice, maxPrice, inStockOnly, query])
}
SMTP mail config (PHP)
Sends a contact notification email using PHPMailer, reading SMTP configuration from environment variables.
<?php
use PHPMailer\PHPMailer\PHPMailer;
/**
* Send a contact email using SMTP settings from environment variables.
*/
function sendContactEmail(array $data): bool
{
$host = getenv('SMTP_HOST') ?: '';
$port = (int) (getenv('SMTP_PORT') ?: 587);
$username = getenv('SMTP_USER') ?: '';
$password = getenv('SMTP_PASS') ?: '';
if ($host === '' || $username === '' || $password === '') {
return false;
}
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $host;
$mail->Port = $port;
$mail->SMTPAuth = true;
$mail->Username = $username;
$mail->Password = $password;
$mail->SMTPSecure = getenv('SMTP_ENCRYPTION') ?: 'tls';
$mail->setFrom(getenv('SMTP_FROM') ?: $username, 'Portfolio contact form');
$mail->addAddress(getenv('SMTP_TO') ?: $username);
$mail->isHTML(false);
$mail->Subject = 'New portfolio contact form submission';
$mail->Body = implode("\n", [
"Name: {$data['name']}",
"Company: " . ($data['company'] ?: '(not provided)'),
"Email: {$data['email']}",
"Telephone: {$data['telephone']}",
"",
$data['message'],
]);
return $mail->send();
}
Server-side contact handler (PHP)
Validates request data and builds a structured error response so the front end can show which fields need attention.
<?php
// A server-side contact handler: validate → save to database → send email.
function validateContact(array $post): array
{
$errors = [];
$fieldStatus = [];
$name = trim($post['name'] ?? '');
$email = trim($post['email'] ?? '');
$telephone = trim($post['telephone'] ?? '');
$message = trim($post['message'] ?? '');
if ($name === '') {
$errors['name'] = ['type' => 'missing', 'message' => 'Please enter your name.'];
$fieldStatus['name'] = 'invalid';
} else {
$fieldStatus['name'] = 'valid';
}
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors['email'] = ['type' => 'invalid', 'message' => 'Please enter a valid email address.'];
$fieldStatus['email'] = 'invalid';
} else {
$fieldStatus['email'] = 'valid';
}
$digits = strlen(preg_replace('/\D+/', '', $telephone));
if ($digits < 10) {
$errors['telephone'] = ['type' => 'invalid', 'message' => 'Please enter a valid telephone number.'];
$fieldStatus['telephone'] = 'invalid';
} else {
$fieldStatus['telephone'] = 'valid';
}
if (mb_strlen($message) < 5 || mb_strlen($message) > 1000) {
$errors['message'] = ['type' => 'invalid', 'message' => 'Message must be between 5 and 1000 characters.'];
$fieldStatus['message'] = 'invalid';
} else {
$fieldStatus['message'] = 'valid';
}
return ['isValid' => empty($errors), 'errors' => $errors, 'fieldStatus' => $fieldStatus];
}