fix(web): remove redundant prop-types and unblock lint pipeline
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 10s
Build & Deploy / 🧪 QA (push) Failing after 2m24s
Build & Deploy / 🏗️ Build (push) Failing after 3m40s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 3s

This commit is contained in:
2026-02-24 11:38:43 +01:00
parent 95a8b702fe
commit 6864903cff
205 changed files with 6570 additions and 1324 deletions

View File

@@ -1,26 +0,0 @@
import { getImgproxyUrl } from "./imgproxy";
/**
* Next.js Image Loader for imgproxy
*
* @param {Object} props - properties from Next.js Image component
* @param {string} props.src - The source image URL
* @param {number} props.width - The desired image width
* @param {number} props.quality - The desired image quality (ignored for now as imgproxy handles it)
*/
export default function imgproxyLoader({
src,
width,
_quality,
}: {
src: string;
width: number;
_quality?: number;
}) {
// We use the width provided by Next.js for responsive images
// Height is set to 0 to maintain aspect ratio
return getImgproxyUrl(src, {
width,
resizing_type: "fit",
});
}

View File

@@ -1,91 +0,0 @@
/**
* Generates an imgproxy URL for a given source image and options.
*
* Documentation: https://docs.imgproxy.net/usage/processing
*/
interface ImgproxyOptions {
width?: number;
height?: number;
resizing_type?: "fit" | "fill" | "fill-down" | "force" | "auto";
gravity?: string;
enlarge?: boolean;
extension?: string;
}
/**
* Encodes a string to Base64 (URL-safe)
*/
function encodeBase64(str: string): string {
if (typeof Buffer !== "undefined") {
return Buffer.from(str)
.toString("base64")
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "");
} else {
// Fallback for browser environment if Buffer is not available
return window
.btoa(str)
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "");
}
}
export function getImgproxyUrl(
src: string,
options: ImgproxyOptions = {},
): string {
const baseUrl =
process.env.NEXT_PUBLIC_IMGPROXY_URL || "https://img.infra.mintel.me";
// If no imgproxy URL is configured, return the source as is
if (!baseUrl) return src;
// Handle local paths or relative URLs
let absoluteSrc = src;
if (src.startsWith("/")) {
const baseUrlForSrc =
process.env.NEXT_PUBLIC_BASE_URL ||
(typeof window !== "undefined" ? window.location.origin : "");
if (baseUrlForSrc) {
absoluteSrc = `${baseUrlForSrc}${src}`;
}
}
// Development mapping: Map local domains to internal Docker hostnames
// so imgproxy can fetch images without SSL issues or external routing
// ONLY run this on server-side (node), not in browser
if (process.env.NODE_ENV === "development") {
if (absoluteSrc.includes("mintel.localhost")) {
absoluteSrc = absoluteSrc.replace(
/^https?:\/\/mintel\.localhost/,
"http://app:3000",
);
} else if (absoluteSrc.includes("cms.mintel.localhost")) {
absoluteSrc = absoluteSrc.replace(
/^https?:\/\/cms\.mintel\.localhost/,
"http://directus:8055",
);
}
}
const { width = 0, height = 0, enlarge = false, extension = "" } = options;
let quality = 80;
if (extension) quality = 90;
// Re-map imgproxy URL to our new parameter structure
// e.g. /process?url=...&w=...&h=...&q=...&format=...
const queryParams = new URLSearchParams({
url: absoluteSrc,
});
if (width > 0) queryParams.set("w", width.toString());
if (height > 0) queryParams.set("h", height.toString());
if (extension) queryParams.set("format", extension.replace(".", ""));
if (quality) queryParams.set("q", quality.toString());
return `${baseUrl}/process?${queryParams.toString()}`;
}

View File

@@ -1,62 +0,0 @@
import { getImgproxyUrl } from "./imgproxy";
/**
* Verification script for imgproxy URL generation
*/
function testImgproxyUrl() {
const testCases = [
{
src: "https://picsum.photos/800/800",
options: { width: 400, height: 300, resizing_type: "fill" as const },
description: "Remote URL with fill resizing",
},
{
src: "/images/avatar.jpg",
options: { width: 100, extension: "webp" },
description: "Local path with extension conversion",
},
{
src: "https://example.com/image.png",
options: { gravity: "no" },
description: "Remote URL with custom gravity",
},
];
console.log("🧪 Testing imgproxy URL generation...\n");
testCases.forEach((tc, i) => {
const url = getImgproxyUrl(tc.src, tc.options);
console.log(`Test Case ${i + 1}: ${tc.description}`);
console.log(`Source: ${tc.src}`);
console.log(`Result: ${url}`);
// Basic validation
if (url.startsWith("https://img.infra.mintel.me/unsafe/")) {
console.log("✅ Base URL and unsafe path correct");
} else {
console.log("❌ Base URL or unsafe path mismatch");
}
if (
tc.options.width &&
url.includes(
`rs:${tc.options.resizing_type || "fit"}:${tc.options.width}`,
)
) {
console.log("✅ Resizing options present");
}
console.log("-------------------\n");
});
}
// Mock environment for testing if not set
if (!process.env.NEXT_PUBLIC_IMGPROXY_URL) {
process.env.NEXT_PUBLIC_IMGPROXY_URL = "https://img.infra.mintel.me";
}
if (!process.env.NEXT_PUBLIC_BASE_URL) {
process.env.NEXT_PUBLIC_BASE_URL = "http://mintel.localhost";
}
testImgproxyUrl();