19 Commits

Author SHA1 Message Date
denshooter 91df78b533 Merge branch 'dev' into production
CI / CD / test-build (push) Failing after 5m39s
CI / CD / deploy-dev (push) Has been skipped
CI / CD / deploy-production (push) Has been skipped
2026-05-14 16:05:25 +02:00
denshooter c6e63e8250 Merge branch 'dev' into production
CI / CD / test-build (push) Successful in 10m21s
CI / CD / deploy-dev (push) Has been skipped
CI / CD / deploy-production (push) Successful in 24s
2026-05-14 02:06:15 +02:00
denshooter 4a8c86b320 Merge branch 'dev' into production
CI / CD / test-build (push) Successful in 10m19s
CI / CD / deploy-dev (push) Has been skipped
CI / CD / deploy-production (push) Successful in 26s
2026-04-23 23:33:52 +02:00
denshooter 0ca14230f2 Merge branch 'dev' into production 2026-04-23 23:11:02 +02:00
denshooter 2c88b284c1 Merge branch 'dev' into production 2026-04-23 23:06:31 +02:00
denshooter 890b8c79c7 Merge branch 'dev' into production 2026-04-23 22:40:22 +02:00
denshooter 3494b361d6 Merge branch 'dev' into production 2026-04-23 20:20:37 +02:00
denshooter c9153d2660 Merge branch 'dev' into production 2026-04-23 20:18:46 +02:00
denshooter 52586ef28a Merge branch 'dev' into production 2026-04-22 11:50:28 +02:00
denshooter a44a90c69d Merge branch 'dev' into production 2026-04-22 11:43:52 +02:00
denshooter 258143b362 Merge branch 'dev' into production 2026-04-19 15:47:39 +02:00
denshooter edd8dc58ab Merge branch 'dev' into production 2026-04-17 09:50:38 +02:00
denshooter f17f0031a1 Merge branch 'dev' into production 2026-04-16 14:39:54 +02:00
denshooter 4d5dc1f8f9 Merge branch 'dev' into production 2026-04-15 15:53:22 +02:00
denshooter 8397e5acf2 Merge dev into production 2026-04-09 18:02:37 +02:00
denshooter 5bcaade558 Merge dev into production 2026-04-09 17:23:29 +02:00
denshooter aee811309b fix: scroll to top on locale switch and remove dashes from hero text
- HeaderClient: track locale prop changes with useRef and call
  window.scrollTo on switch to reliably reset scroll position
- messages/en.json + de.json: replace em dash with comma and remove
  hyphens from Self-Hoster/Full-Stack in hero description

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 14:37:56 +01:00
denshooter 48a29cd872 fix: pass locale explicitly to Hero and force-dynamic on locale-sensitive API routes
- Hero.tsx: pass locale prop directly to getTranslations instead of
  relying on setRequestLocale async storage, which can be lost during
  Next.js RSC streaming
- book-reviews route: replace revalidate=300 with force-dynamic to
  prevent cached English responses being served to German locale requests
- content/page route: add runtime=nodejs and force-dynamic (was missing
  both, violating CLAUDE.md API route conventions)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 13:43:26 +01:00
denshooter c95fc3101b chore: merge branch 'dev' into 'production' (Release: Design Overhaul & Admin Redesign) 2026-03-08 13:18:26 +01:00
+7 -23
View File
@@ -268,7 +268,7 @@ describe("Accessibility: images have alt text", () => {
const content = readFile(file);
const rel = path.relative(SRC_ROOT, file);
const imgRegex = /<img\b[^>]*>/g;
const imgRegex = /<img\b[^>]*>/gs;
let match: RegExpExecArray | null;
while ((match = imgRegex.exec(content)) !== null) {
const tag = match[0];
@@ -406,19 +406,7 @@ describe("Convention: no raw hex colors in classNames", () => {
// ═══════════════════════════════════════════════════════════════════════════
describe("Convention: no emoji in app/ source code", () => {
function lineContainsEmoji(line: string): boolean {
for (let i = 0; i < line.length; i++) {
const code = line.codePointAt(i);
if (code === undefined) continue;
if (code >= 0x1F300 && code <= 0x1FAFF) return true;
if (code >= 0x2600 && code <= 0x27BF) return true;
if (code >= 0xFE00 && code <= 0xFE0F) return true;
if (code === 0x200D) return true;
if (code === 0x20E3) return true;
if (code > 0xFFFF) i++;
}
return false;
}
const EMOJI_REGEX = /[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{FE00}-\u{FE0F}\u{1F000}-\u{1F02F}\u{1F0A0}-\u{1F0FF}\u{1F100}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{1FA70}-\u{1FAFF}\u{1FC00}-\u{1FCFF}\u{1FD00}-\u{1FDFF}\u{1FE00}-\u{1FEFF}\u{200D}\u{20E3}\u{E0020}-\u{E007F}]/gu;
const EXCLUDED_DIRS = new Set(["components/admin", "components/modern", "editor"]);
const EXCLUDED_FILES = new Set([
@@ -445,17 +433,13 @@ describe("Convention: no emoji in app/ source code", () => {
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.trim().startsWith("//") || line.trim().startsWith("*")) continue;
if (lineContainsEmoji(line)) {
const emojiChars: string[] = [];
for (let j = 0; j < line.length; j++) {
const code = line.codePointAt(j);
if (code !== undefined && ((code >= 0x1F300 && code <= 0x1FAFF) || (code >= 0x2600 && code <= 0x27BF) || (code >= 0xFE00 && code <= 0xFE0F) || code === 0x200D || code === 0x20E3)) {
emojiChars.push(String.fromCodePoint(code));
if (code > 0xFFFF) j++;
if (EMOJI_REGEX.test(line)) {
const emoji = line.match(EMOJI_REGEX);
if (emoji) {
violations.push(`${rel}:${i + 1} — found emoji: ${emoji.join(", ")}`);
}
}
violations.push(`${rel}:${i + 1} — found emoji: ${emojiChars.join(", ")}`);
}
EMOJI_REGEX.lastIndex = 0;
}
}