feat(blog): complete blog experience overhaul
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 5s
Build & Deploy / 🧪 QA (push) Failing after 1m4s
Build & Deploy / 🏗️ Build (push) Failing after 3m51s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s

- Implemented minimalist vertical teaser list (MediumCard)
- Consolidated and refined 20 engineering-focused blog posts
- Rebuilt blog overview with narrow, centered layout (max-w-3xl)
- Introduced BlogCommandBar for integrated search and tag filtering
- Consolidated tags to 6-8 core technical categories
- Redesigned blog detail pages with industrial 'Technical Frame' layout
- Added SectionHeader component for consistent industrial titling
- Optimized vertical space by removing redundant PageHeaders
This commit is contained in:
2026-02-15 18:52:48 +01:00
parent c1295546a6
commit 386a07aa53
36 changed files with 4141 additions and 688 deletions

View File

@@ -1,16 +1,20 @@
'use client';
"use client";
import * as React from 'react';
import { useState, useRef } from 'react';
import * as React from "react";
import { useState, useRef } from "react";
interface SearchBarProps {
value?: string;
onChange?: (value: string) => void;
size?: 'small' | 'large';
size?: "small" | "large";
}
export const SearchBar: React.FC<SearchBarProps> = ({ value: propValue, onChange, size = 'small' }) => {
const [internalValue, setInternalValue] = useState('');
export const SearchBar: React.FC<SearchBarProps> = ({
value: propValue,
onChange,
size = "small",
}) => {
const [internalValue, setInternalValue] = useState("");
const inputRef = useRef<HTMLInputElement>(null);
const [isFocused, setIsFocused] = useState(false);
@@ -27,9 +31,9 @@ export const SearchBar: React.FC<SearchBarProps> = ({ value: propValue, onChange
const clearSearch = () => {
if (onChange) {
onChange('');
onChange("");
} else {
setInternalValue('');
setInternalValue("");
}
if (inputRef.current) {
inputRef.current.focus();
@@ -37,24 +41,24 @@ export const SearchBar: React.FC<SearchBarProps> = ({ value: propValue, onChange
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Escape') {
if (e.key === "Escape") {
clearSearch();
}
};
return (
<div className="relative w-full">
<div className="relative flex items-center">
<div className="relative w-full max-w-full">
<div className="relative flex items-center w-full">
<input
ref={inputRef}
type="text"
placeholder="Suchen..."
value={value}
className={`w-full px-8 py-4 font-bold text-slate-900 bg-white rounded-2xl border transition-all focus:outline-none placeholder:text-slate-300 ${
size === 'large' ? 'text-2xl md:text-4xl py-6 rounded-3xl' : 'text-lg'
} ${
isFocused ? 'border-slate-400' : 'border-slate-200'
}`}
className={`w-full max-w-full px-8 py-4 font-bold text-slate-900 bg-white rounded-2xl border transition-all focus:outline-none placeholder:text-slate-300 ${
size === "large"
? "text-2xl md:text-4xl py-6 rounded-3xl"
: "text-lg"
} ${isFocused ? "border-slate-400" : "border-slate-200"}`}
onChange={handleInput}
onKeyDown={handleKeyDown}
onFocus={() => setIsFocused(true)}