💂‍♂️ fixed lint and prittier

This commit is contained in:
RJ
2025-11-14 15:33:00 +02:00
parent 5e9093cf9c
commit 820a2b88d5
43 changed files with 5717 additions and 423 deletions

View File

@@ -17,7 +17,8 @@ export function BlogCard({ post, variant }: BlogCardProps) {
<article className="border border-slate-700 bg-slate-900 p-6 h-full cyber-glitch-hover">
<div className="border-l-2 pl-4 mb-4" style={{ borderColor: 'var(--neon-pink)' }}>
<span className="font-mono text-xs text-zinc-100 uppercase tracking-wider">
{post.frontmatter.category} <span style={{ color: 'var(--neon-cyan)' }}>//</span> {formatDate(post.frontmatter.date)}
{post.frontmatter.category} <span style={{ color: 'var(--neon-cyan)' }}>//</span>{' '}
{formatDate(post.frontmatter.date)}
</span>
</div>
<h3 className="font-mono text-xl font-bold text-zinc-100 uppercase mb-3">
@@ -27,8 +28,11 @@ export function BlogCard({ post, variant }: BlogCardProps) {
{post.frontmatter.description}
</p>
<div className="flex flex-wrap gap-2 mb-4">
{post.frontmatter.tags.map((tag) => (
<span key={tag} className="px-3 py-1 bg-zinc-800 border border-slate-700 text-cyan-400 font-mono text-xs uppercase">
{post.frontmatter.tags.map(tag => (
<span
key={tag}
className="px-3 py-1 bg-zinc-800 border border-slate-700 text-cyan-400 font-mono text-xs uppercase"
>
#{tag}
</span>
))}
@@ -68,8 +72,11 @@ export function BlogCard({ post, variant }: BlogCardProps) {
{post.frontmatter.description}
</p>
<div className="flex flex-wrap gap-2 mb-4">
{post.frontmatter.tags.map((tag) => (
<span key={tag} className="px-3 py-1 bg-zinc-800 border border-slate-700 text-cyan-400 font-mono text-xs uppercase">
{post.frontmatter.tags.map(tag => (
<span
key={tag}
className="px-3 py-1 bg-zinc-800 border border-slate-700 text-cyan-400 font-mono text-xs uppercase"
>
#{tag}
</span>
))}
@@ -99,7 +106,8 @@ export function BlogCard({ post, variant }: BlogCardProps) {
<div className="p-6">
<div className="border-l-2 pl-4 mb-4" style={{ borderColor: 'var(--neon-pink)' }}>
<span className="font-mono text-xs text-zinc-100 uppercase tracking-wider">
{post.frontmatter.category} <span style={{ color: 'var(--neon-cyan)' }}>//</span> {formatDate(post.frontmatter.date)}
{post.frontmatter.category} <span style={{ color: 'var(--neon-cyan)' }}>//</span>{' '}
{formatDate(post.frontmatter.date)}
</span>
</div>
<h3 className="font-mono text-xl font-bold text-zinc-100 uppercase mb-3">
@@ -109,8 +117,11 @@ export function BlogCard({ post, variant }: BlogCardProps) {
{post.frontmatter.description}
</p>
<div className="flex flex-wrap gap-2 mb-4">
{post.frontmatter.tags.map((tag) => (
<span key={tag} className="px-3 py-1 bg-zinc-800 border border-slate-700 text-cyan-400 font-mono text-xs uppercase">
{post.frontmatter.tags.map(tag => (
<span
key={tag}
className="px-3 py-1 bg-zinc-800 border border-slate-700 text-cyan-400 font-mono text-xs uppercase"
>
#{tag}
</span>
))}

View File

@@ -23,7 +23,9 @@ export function CodeBlock({ code, language, filename, showLineNumbers = true }:
<div className="flex items-center justify-between px-4 py-2 bg-[rgb(var(--bg-secondary))] dark:bg-zinc-950 border-b-2 border-[var(--neon-purple)] relative">
<div className="flex items-center gap-3">
{filename && (
<span className="text-[var(--neon-cyan)] font-mono text-sm uppercase">&gt;&gt; {filename}</span>
<span className="text-[var(--neon-cyan)] font-mono text-sm uppercase">
&gt;&gt; {filename}
</span>
)}
<span className="px-2 py-1 border border-[var(--neon-purple)] text-[var(--neon-purple)] text-xs font-mono uppercase">
[{language}]

View File

@@ -1,13 +1,13 @@
'use client';
'use client'
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import Image from 'next/image';
import Link from 'next/link';
import { CodeBlock } from './code-block';
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import Image from 'next/image'
import Link from 'next/link'
import { CodeBlock } from './code-block'
interface MarkdownRendererProps {
content: string;
content: string
}
export default function MarkdownRenderer({ content }: MarkdownRendererProps) {
@@ -16,48 +16,42 @@ export default function MarkdownRenderer({ content }: MarkdownRendererProps) {
remarkPlugins={[remarkGfm]}
components={{
h1: ({ children }) => {
const text = String(children);
const id = text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
return <h1 id={id}>{children}</h1>;
const text = String(children)
const id = text
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/(^-|-$)/g, '')
return <h1 id={id}>{children}</h1>
},
h2: ({ children }) => {
const text = String(children);
const id = text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
return <h2 id={id}>{children}</h2>;
const text = String(children)
const id = text
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/(^-|-$)/g, '')
return <h2 id={id}>{children}</h2>
},
h3: ({ children }) => {
const text = String(children);
const id = text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
return <h3 id={id}>{children}</h3>;
const text = String(children)
const id = text
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/(^-|-$)/g, '')
return <h3 id={id}>{children}</h3>
},
code: ({ inline, className, children, ...props }: any) => {
const match = /language-(\w+)/.exec(className || '');
const match = /language-(\w+)/.exec(className || '')
if (!inline && match) {
return (
<CodeBlock
code={String(children).replace(/\n$/, '')}
language={match[1]}
/>
);
return <CodeBlock code={String(children).replace(/\n$/, '')} language={match[1]} />
}
return (
<code {...props}>
{children}
</code>
);
return <code {...props}>{children}</code>
},
img: ({ src, alt }) => {
if (!src || typeof src !== 'string') return null;
const isExternal = src.startsWith('http://') || src.startsWith('https://');
if (!src || typeof src !== 'string') return null
const isExternal = src.startsWith('http://') || src.startsWith('https://')
if (isExternal) {
return (
<img
src={src}
alt={alt || ''}
className="w-full h-auto"
/>
);
return <img src={src} alt={alt || ''} className="w-full h-auto" />
}
return (
@@ -70,33 +64,25 @@ export default function MarkdownRenderer({ content }: MarkdownRendererProps) {
style={{ width: '100%', height: 'auto' }}
/>
</div>
);
)
},
a: ({ href, children }) => {
if (!href) return <>{children}</>;
const isExternal = href.startsWith('http://') || href.startsWith('https://');
if (!href) return <>{children}</>
const isExternal = href.startsWith('http://') || href.startsWith('https://')
if (isExternal) {
return (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
>
<a href={href} target="_blank" rel="noopener noreferrer">
{children}
</a>
);
)
}
return (
<Link href={href}>
{children}
</Link>
);
return <Link href={href}>{children}</Link>
},
}}
>
{content}
</ReactMarkdown>
);
)
}

View File

@@ -28,11 +28,17 @@ export function Navbar() {
}, [lastScrollY])
return (
<nav className={`border-b-4 border-slate-700 bg-slate-900 dark:bg-zinc-950 sticky top-0 z-50 ${isVisible ? 'navbar-visible' : 'navbar-hidden'}`}>
<nav
className={`border-b-4 border-slate-700 bg-slate-900 dark:bg-zinc-950 sticky top-0 z-50 ${isVisible ? 'navbar-visible' : 'navbar-hidden'}`}
>
<div className="max-w-7xl mx-auto px-6 py-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-8">
<Link href="/" className="font-mono text-sm uppercase tracking-wider transition-colors cursor-pointer" style={{ color: 'var(--neon-cyan)' }}>
<Link
href="/"
className="font-mono text-sm uppercase tracking-wider transition-colors cursor-pointer"
style={{ color: 'var(--neon-cyan)' }}
>
&lt; HOME
</Link>
<span className="font-mono text-sm text-zinc-100 dark:text-zinc-300 uppercase tracking-wider">
@@ -40,7 +46,10 @@ export function Navbar() {
</span>
</div>
<div className="flex items-center gap-6">
<Link href="/about" className="font-mono text-sm text-zinc-400 dark:text-zinc-500 uppercase tracking-wider hover:text-cyan-400 dark:hover:text-cyan-300 transition-colors cursor-pointer">
<Link
href="/about"
className="font-mono text-sm text-zinc-400 dark:text-zinc-500 uppercase tracking-wider hover:text-cyan-400 dark:hover:text-cyan-300 transition-colors cursor-pointer"
>
[ABOUT]
</Link>
<ThemeToggle />

View File

@@ -25,15 +25,13 @@ export function ReadingProgress() {
className="h-full bg-gradient-to-r from-[var(--neon-cyan)] via-[var(--neon-magenta)] to-[var(--neon-pink)] transition-all duration-150"
style={{
width: `${progress}%`,
boxShadow: progress > 0 ? '0 0 8px var(--neon-cyan)' : 'none'
boxShadow: progress > 0 ? '0 0 8px var(--neon-cyan)' : 'none',
}}
/>
</div>
<div className="fixed top-4 right-4 z-50 px-3 py-1.5 bg-[rgb(var(--bg-primary))] border-2 border-[var(--neon-cyan)] text-xs font-mono font-bold text-[var(--neon-cyan)] relative">
<span className="relative z-10">
[{Math.round(progress)}%]
</span>
<span className="relative z-10">[{Math.round(progress)}%]</span>
</div>
</>
)

View File

@@ -6,12 +6,14 @@ interface SearchBarProps {
export function SearchBar({ searchQuery, onSearchChange }: SearchBarProps) {
return (
<div className="flex-1 flex items-center border border-slate-700 bg-zinc-900 transition-all focus-within:border-[var(--neon-cyan)] focus-within:shadow-[0_0_6px_rgba(0,255,255,0.4),inset_0_0_6px_rgba(0,255,255,0.05)]">
<span className="pl-4 pr-2 font-mono text-lg" style={{ color: 'var(--neon-cyan)' }}>&gt;</span>
<span className="pl-4 pr-2 font-mono text-lg" style={{ color: 'var(--neon-cyan)' }}>
&gt;
</span>
<input
type="text"
placeholder="SEARCH POSTS..."
value={searchQuery}
onChange={(e) => onSearchChange(e.target.value)}
onChange={e => onSearchChange(e.target.value)}
className="flex-1 bg-transparent font-mono text-zinc-100 dark:text-zinc-100 px-2 py-3 focus:outline-none placeholder:text-zinc-600 uppercase text-sm"
/>
</div>

View File

@@ -9,12 +9,30 @@ export function SortDropdown({ sortBy, onSortChange }: SortDropdownProps) {
return (
<select
value={sortBy}
onChange={(e) => onSortChange(e.target.value as SortOption)}
onChange={e => onSortChange(e.target.value as SortOption)}
className="border-2 border-slate-700 bg-zinc-900 dark:bg-zinc-900 text-zinc-100 dark:text-zinc-100 font-mono px-6 py-3 uppercase text-sm cyber-focus-pink transition-all hover:border-cyan-400 cursor-pointer"
>
<option value="newest" className="bg-zinc-900 text-zinc-100" style={{ backgroundColor: '#18181b', color: '#f4f4f5' }}>NEWEST FIRST</option>
<option value="oldest" className="bg-zinc-900 text-zinc-100" style={{ backgroundColor: '#18181b', color: '#f4f4f5' }}>OLDEST FIRST</option>
<option value="title" className="bg-zinc-900 text-zinc-100" style={{ backgroundColor: '#18181b', color: '#f4f4f5' }}>BY TITLE</option>
<option
value="newest"
className="bg-zinc-900 text-zinc-100"
style={{ backgroundColor: '#18181b', color: '#f4f4f5' }}
>
NEWEST FIRST
</option>
<option
value="oldest"
className="bg-zinc-900 text-zinc-100"
style={{ backgroundColor: '#18181b', color: '#f4f4f5' }}
>
OLDEST FIRST
</option>
<option
value="title"
className="bg-zinc-900 text-zinc-100"
style={{ backgroundColor: '#18181b', color: '#f4f4f5' }}
>
BY TITLE
</option>
</select>
)
}

View File

@@ -48,7 +48,9 @@ export function StickyFooter({ url, title }: StickyFooterProps) {
${isVisible ? 'translate-y-0' : 'translate-y-full'}
`}
style={{
boxShadow: isVisible ? '0 -8px 30px rgba(155,90,142,0.5), inset 0 4px 20px rgba(155,90,142,0.1)' : 'none'
boxShadow: isVisible
? '0 -8px 30px rgba(155,90,142,0.5), inset 0 4px 20px rgba(155,90,142,0.1)'
: 'none',
}}
>
<div className="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-transparent via-[var(--neon-magenta)] to-transparent opacity-70" />
@@ -60,7 +62,10 @@ export function StickyFooter({ url, title }: StickyFooterProps) {
<div className="w-2 h-2 bg-[var(--neon-cyan)] shadow-[0_0_6px_rgba(90,139,149,1)]" />
<div className="w-2 h-2 bg-[var(--neon-pink)] shadow-[0_0_6px_rgba(155,90,110,1)]" />
</div>
<span className="text-[var(--neon-cyan)] font-mono text-xs uppercase tracking-wider" style={{ textShadow: '0 0 8px rgba(90,139,149,0.6)' }}>
<span
className="text-[var(--neon-cyan)] font-mono text-xs uppercase tracking-wider"
style={{ textShadow: '0 0 8px rgba(90,139,149,0.6)' }}
>
&gt;&gt; SHARE:
</span>
</div>
@@ -89,7 +94,9 @@ export function StickyFooter({ url, title }: StickyFooterProps) {
<button
onClick={handleCopyLink}
className="flex items-center gap-2 px-4 py-2 bg-black border-4 border-[var(--neon-pink)] text-[var(--neon-pink)] font-mono text-xs uppercase tracking-wider transition-all hover:shadow-[0_0_25px_rgba(155,90,110,0.8)] hover:bg-pink-900/20"
style={{ textShadow: copied ? '0 0 10px rgba(155,90,110,1)' : '0 0 8px rgba(155,90,110,0.6)' }}
style={{
textShadow: copied ? '0 0 10px rgba(155,90,110,1)' : '0 0 8px rgba(155,90,110,0.6)',
}}
>
{copied ? '[✓ COPIED]' : '[COPY]'}
</button>

View File

@@ -17,8 +17,8 @@ export function TableOfContents({ headings }: TOCProps) {
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
setActiveId(entry.target.id)
}
@@ -43,31 +43,45 @@ export function TableOfContents({ headings }: TOCProps) {
<div className="border-b border-[var(--neon-magenta)] pb-3 mb-4 relative">
<div className="flex gap-1.5 mb-2 justify-end">
<div className="w-3 h-3 border border-[var(--neon-cyan)]/40 hover:bg-[var(--neon-cyan)]/10 transition-colors cursor-pointer" title="Minimize" />
<div className="w-3 h-3 border border-[var(--neon-cyan)]/40 hover:bg-[var(--neon-cyan)]/10 transition-colors cursor-pointer" title="Maximize" />
<div className="w-3 h-3 border border-[var(--neon-pink)]/40 hover:bg-[var(--neon-pink)]/10 transition-colors cursor-pointer" title="Close" />
<div
className="w-3 h-3 border border-[var(--neon-cyan)]/40 hover:bg-[var(--neon-cyan)]/10 transition-colors cursor-pointer"
title="Minimize"
/>
<div
className="w-3 h-3 border border-[var(--neon-cyan)]/40 hover:bg-[var(--neon-cyan)]/10 transition-colors cursor-pointer"
title="Maximize"
/>
<div
className="w-3 h-3 border border-[var(--neon-pink)]/40 hover:bg-[var(--neon-pink)]/10 transition-colors cursor-pointer"
title="Close"
/>
</div>
<h3 className="text-xs font-mono font-bold text-[var(--neon-cyan)] uppercase tracking-wider" style={{ textShadow: '0 0 6px rgba(90,139,149,0.5)' }}>
<h3
className="text-xs font-mono font-bold text-[var(--neon-cyan)] uppercase tracking-wider"
style={{ textShadow: '0 0 6px rgba(90,139,149,0.5)' }}
>
&gt;&gt; NAVIGATION
</h3>
</div>
<nav className="space-y-1 relative">
{headings.map((heading) => (
{headings.map(heading => (
<a
key={heading.id}
href={`#${heading.id}`}
className={`
block text-sm font-mono py-2 border-l-2 transition-all duration-150
${heading.level === 2 ? 'pl-3' : 'pl-6'}
${activeId === heading.id
? 'text-[var(--neon-cyan)] border-[var(--neon-cyan)] bg-cyan-500/5 shadow-[0_0_8px_rgba(90,139,149,0.3)]'
: 'text-zinc-500 border-zinc-900 hover:border-[var(--neon-magenta)] hover:text-[var(--neon-magenta)] hover:bg-magenta-500/3 hover:shadow-[0_0_4px_rgba(155,90,142,0.2)]'
${
activeId === heading.id
? 'text-[var(--neon-cyan)] border-[var(--neon-cyan)] bg-cyan-500/5 shadow-[0_0_8px_rgba(90,139,149,0.3)]'
: 'text-zinc-500 border-zinc-900 hover:border-[var(--neon-magenta)] hover:text-[var(--neon-magenta)] hover:bg-magenta-500/3 hover:shadow-[0_0_4px_rgba(155,90,142,0.2)]'
}
`}
style={activeId === heading.id ? { textShadow: '0 0 4px rgba(90,139,149,0.5)' } : {}}
>
<span className="inline-block">{activeId === heading.id ? '▶ ' : '◆ '}</span>{heading.text}
<span className="inline-block">{activeId === heading.id ? '▶ ' : '◆ '}</span>
{heading.text}
</a>
))}
</nav>

View File

@@ -14,7 +14,7 @@ export function TagFilter({ allTags, selectedTags, onToggleTag, onClearTags }: T
FILTER BY TAG
</p>
<div className="flex flex-wrap gap-3">
{allTags.map((tag) => (
{allTags.map(tag => (
<button
key={tag}
onClick={() => onToggleTag(tag)}