chore: overhaul infrastructure and integrate @mintel packages
Some checks failed
🧪 CI (QA) / 🧪 Quality Assurance (push) Failing after 1m3s

- Restructure to pnpm monorepo (site moved to apps/web)
- Integrate @mintel/tsconfig, @mintel/eslint-config, @mintel/husky-config
- Implement Docker service architecture (Varnish, Directus, Gatekeeper)
- Setup environment-aware Gitea Actions deployment
This commit is contained in:
2026-02-05 14:18:51 +01:00
parent 190720ad92
commit 103d71851c
1029 changed files with 13242 additions and 27898 deletions

View File

@@ -0,0 +1,208 @@
import React from 'react';
import Prism from 'prismjs';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-jsx';
import 'prismjs/components/prism-tsx';
import 'prismjs/components/prism-docker';
import 'prismjs/components/prism-yaml';
import 'prismjs/components/prism-json';
import 'prismjs/components/prism-markup';
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-sql';
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-markdown';
interface BlockquoteProps {
children: React.ReactNode;
className?: string;
}
export const Blockquote: React.FC<BlockquoteProps> = ({ children, className = '' }) => (
<blockquote className={`border-l-4 border-slate-900 pl-6 italic text-slate-700 my-8 text-xl md:text-2xl font-serif ${className}`}>
{children}
</blockquote>
);
interface CodeBlockProps {
code?: string;
children?: React.ReactNode;
language?: string;
showLineNumbers?: boolean;
className?: string;
}
// Language mapping for Prism.js
const prismLanguageMap: Record<string, string> = {
py: 'python',
ts: 'typescript',
tsx: 'tsx',
js: 'javascript',
jsx: 'jsx',
dockerfile: 'docker',
docker: 'docker',
yml: 'yaml',
yaml: 'yaml',
json: 'json',
html: 'markup',
css: 'css',
sql: 'sql',
sh: 'bash',
bash: 'bash',
md: 'markdown',
astro: 'markup', // Fallback for Astro
};
// Highlight code using Prism.js
const highlightCode = (code: string, language: string): { html: string; prismLanguage: string } => {
const prismLanguage = prismLanguageMap[language] || language || 'markup';
try {
const highlighted = Prism.highlight(
code.trim(),
Prism.languages[prismLanguage] || Prism.languages.markup,
prismLanguage,
);
return { html: highlighted, prismLanguage };
} catch (error) {
console.warn('Prism highlighting failed:', error);
return { html: code.trim(), prismLanguage: 'text' };
}
};
export const CodeBlock: React.FC<CodeBlockProps> = ({
code,
children,
language = 'text',
showLineNumbers = false,
className = ''
}) => {
const codeContent = code || (typeof children === 'string' ? children : String(children || '')).trim();
const { html: highlightedCode, prismLanguage } = language !== 'text' ? highlightCode(codeContent, language) : { html: codeContent, prismLanguage: 'text' };
const lines = codeContent.split('\n');
return (
<>
<style dangerouslySetInnerHTML={{ __html: syntaxHighlightingStyles }} />
<div className="relative my-6">
{language !== 'text' && (
<div className="absolute top-3 right-3 text-[10px] font-bold uppercase tracking-widest bg-white text-slate-500 px-2 py-1 rounded-md z-10 border border-slate-100 shadow-sm">
{language}
</div>
)}
<pre
className={`m-0 p-6 overflow-x-auto overflow-y-auto text-[13px] leading-[1.65] font-mono text-slate-800 hide-scrollbar border border-slate-200 bg-white rounded-2xl ${className} ${showLineNumbers ? 'pl-12' : ''}`}
style={{ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", maxHeight: "22rem" }}
>
{showLineNumbers ? (
<div className="relative">
<div className="absolute left-0 top-0 bottom-0 w-8 text-right text-slate-600 select-none pr-3 border-r border-slate-700">
{lines.map((_, i) => (
<div key={i} className="leading-relaxed">{i + 1}</div>
))}
</div>
<div className="pl-10">
<code className={`language-${prismLanguage}`} dangerouslySetInnerHTML={{ __html: highlightedCode }} />
</div>
</div>
) : (
<code className={`language-${prismLanguage}`} dangerouslySetInnerHTML={{ __html: highlightedCode }} />
)}
</pre>
</div>
</>
);
};
export const InlineCode: React.FC<{ children: React.ReactNode; className?: string }> = ({ children, className = '' }) => (
<code className={`bg-white text-slate-800 px-1.5 py-0.5 rounded-md font-mono text-[0.9em] border border-slate-200 ${className}`}>
{children}
</code>
);
// Prism.js syntax highlighting styles (matching FileExample.astro)
const syntaxHighlightingStyles = `
code[class*='language-'],
pre[class*='language-'],
pre:has(code[class*='language-']) {
color: #0f172a;
background: transparent;
text-shadow: none;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
font-size: 0.8125rem;
line-height: 1.65;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
tab-size: 2;
hyphens: none;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: #64748b;
font-style: italic;
}
.token.punctuation {
color: #94a3b8;
}
.token.operator {
color: #64748b;
}
.token.property,
.token.tag,
.token.constant,
.token.symbol,
.token.deleted {
color: #c2410c;
}
.token.boolean,
.token.number {
color: #a16207;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #059669;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #475569;
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #7c3aed;
font-weight: 500;
}
.token.function,
.token.class-name {
color: #2563eb;
}
.token.regex,
.token.important,
.token.variable {
color: #db2777;
}
`;