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
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:
@@ -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)}
|
||||
|
||||
Reference in New Issue
Block a user