stlyes fixes

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-29 19:52:51 +00:00
parent c91175fdcb
commit 4f7ab9c606
155 changed files with 1576 additions and 2489 deletions

View File

@@ -39,11 +39,11 @@ interface ParsedArticle {
}
const imageStatusClassMap: Record<string, string> = {
generated: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-500/20 dark:text-emerald-200',
pending: 'bg-amber-100 text-amber-700 dark:bg-amber-500/20 dark:text-amber-200',
queued: 'bg-amber-100 text-amber-700 dark:bg-amber-500/20 dark:text-amber-200',
failed: 'bg-rose-100 text-rose-700 dark:bg-rose-500/20 dark:text-rose-200',
error: 'bg-rose-100 text-rose-700 dark:bg-rose-500/20 dark:text-rose-200',
generated: 'bg-purple-100 text-purple-700 dark:bg-purple-500/20 dark:text-purple-200',
pending: 'bg-warning-100 text-warning-700 dark:bg-warning-500/20 dark:text-warning-200',
queued: 'bg-warning-100 text-warning-700 dark:bg-warning-500/20 dark:text-warning-200',
failed: 'bg-error-100 text-error-700 dark:bg-error-500/20 dark:text-error-200',
error: 'bg-error-100 text-error-700 dark:bg-error-500/20 dark:text-error-200',
};
const serializeNodes = (nodes: Node[]): string =>
@@ -207,7 +207,7 @@ const getImageSrc = (image: ImageRecord | null): string | undefined => {
const ImageStatusPill = ({ status, className = '' }: { status?: string | null; className?: string }) => {
if (!status) return null;
const normalized = status.toLowerCase();
const classes = imageStatusClassMap[normalized] || 'bg-slate-100 text-slate-700 dark:bg-slate-700/70 dark:text-slate-200';
const classes = imageStatusClassMap[normalized] || 'bg-gray-100 text-gray-700 dark:bg-gray-700/70 dark:text-gray-200';
return (
<span className={`inline-flex items-center gap-1 rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-wide ${classes} ${className}`}>
{status}
@@ -225,16 +225,16 @@ const PromptPlaceholder = ({
minHeight?: number;
}) => (
<div
className="flex w-full items-center justify-center rounded-3xl bg-gradient-to-br from-slate-100 via-slate-50 to-white p-8 text-center dark:from-gray-800 dark:via-gray-900 dark:to-gray-950"
className="flex w-full items-center justify-center rounded-3xl bg-gradient-to-br from-gray-100 via-gray-50 to-white p-8 text-center dark:from-gray-800 dark:via-gray-900 dark:to-gray-950"
style={{ minHeight }}
>
<div className="max-w-xl space-y-3">
{label && (
<p className="text-[0.7rem] font-semibold uppercase tracking-[0.3em] text-slate-500 dark:text-slate-400">
<p className="text-[0.7rem] font-semibold uppercase tracking-[0.3em] text-gray-500 dark:text-gray-400">
{label}
</p>
)}
<p className="text-sm font-medium leading-relaxed text-slate-600 dark:text-slate-300 whitespace-pre-wrap">
<p className="text-sm font-medium leading-relaxed text-gray-600 dark:text-gray-300 whitespace-pre-wrap">
{prompt || 'Image prompt available, awaiting generation.'}
</p>
</div>
@@ -255,16 +255,16 @@ const FeaturedImageBlock = ({
}
return (
<div className="overflow-hidden rounded-3xl border border-slate-200/80 bg-white/80 shadow-lg shadow-slate-200/40 backdrop-blur-sm dark:border-gray-800/70 dark:bg-gray-900/70 dark:shadow-black/10">
<div className="overflow-hidden rounded-3xl border border-gray-200/80 bg-white/80 shadow-lg shadow-slate-200/40 backdrop-blur-sm dark:border-gray-800/70 dark:bg-gray-900/70 dark:shadow-black/10">
<div className="flex items-center justify-between px-8 pt-8">
<div className="text-xs font-semibold uppercase tracking-[0.35em] text-slate-500 dark:text-slate-400">
<div className="text-xs font-semibold uppercase tracking-[0.35em] text-gray-500 dark:text-gray-400">
Featured Visual
</div>
<ImageStatusPill status={image?.status} />
</div>
<div className="relative mt-6">
{loading && !imageSrc ? (
<div className="h-[420px] animate-pulse bg-slate-200/70 dark:bg-gray-800/60" />
<div className="h-[420px] animate-pulse bg-gray-200/70 dark:bg-gray-800/60" />
) : imageSrc ? (
<img
src={imageSrc}
@@ -276,13 +276,13 @@ const FeaturedImageBlock = ({
<PromptPlaceholder prompt={image?.prompt} minHeight={420} label="Featured Image Prompt" />
)}
{image?.caption && imageSrc && (
<div className="absolute bottom-5 left-5 rounded-full bg-white/80 px-4 py-2 text-xs font-medium text-slate-600 backdrop-blur-sm dark:bg-gray-950/70 dark:text-slate-300">
<div className="absolute bottom-5 left-5 rounded-full bg-white/80 px-4 py-2 text-xs font-medium text-gray-600 backdrop-blur-sm dark:bg-gray-950/70 dark:text-gray-300">
Caption aligned to hero section
</div>
)}
</div>
{image?.caption && (
<div className="border-t border-slate-200/70 bg-white/70 px-8 py-6 text-sm leading-relaxed text-slate-600 backdrop-blur-sm dark:border-gray-800/60 dark:bg-gray-900/70 dark:text-slate-300">
<div className="border-t border-gray-200/70 bg-white/70 px-8 py-6 text-sm leading-relaxed text-gray-600 backdrop-blur-sm dark:border-gray-800/60 dark:bg-gray-900/70 dark:text-gray-300">
{image.caption}
</div>
)}
@@ -304,10 +304,10 @@ const SectionImageBlock = ({
const imageSrc = getImageSrc(image);
return (
<figure className="overflow-hidden rounded-3xl border border-slate-200/70 bg-slate-50/70 shadow-inner shadow-slate-200/70 dark:border-gray-800/60 dark:bg-gray-900/40 dark:shadow-black/30">
<figure className="overflow-hidden rounded-3xl border border-gray-200/70 bg-gray-50/70 shadow-inner shadow-slate-200/70 dark:border-gray-800/60 dark:bg-gray-900/40 dark:shadow-black/30">
<div className="relative">
{loading && !image ? (
<div className="h-[260px] animate-pulse bg-slate-200/60 dark:bg-gray-800/60" />
<div className="h-[260px] animate-pulse bg-gray-200/60 dark:bg-gray-800/60" />
) : imageSrc ? (
<img
src={imageSrc}
@@ -323,8 +323,8 @@ const SectionImageBlock = ({
</div>
</div>
{image?.caption && (
<figcaption className="space-y-3 px-6 py-5 text-sm leading-relaxed text-slate-600 dark:text-slate-300">
<p className="font-semibold uppercase tracking-[0.25em] text-slate-400 dark:text-slate-500">
<figcaption className="space-y-3 px-6 py-5 text-sm leading-relaxed text-gray-600 dark:text-gray-300">
<p className="font-semibold uppercase tracking-[0.25em] text-gray-400 dark:text-gray-500">
Image Caption
</p>
<p className="font-medium whitespace-pre-wrap">{image.caption}</p>
@@ -335,8 +335,8 @@ const SectionImageBlock = ({
};
const IntroBlock = ({ html }: { html: string }) => (
<section className="overflow-hidden rounded-3xl border border-slate-200/80 bg-gradient-to-br from-white via-slate-50 to-white p-8 shadow-sm shadow-slate-200/60 dark:border-gray-800/70 dark:from-gray-900 dark:via-gray-950 dark:to-gray-900 dark:shadow-black/20">
<div className="text-xs font-semibold uppercase tracking-[0.35em] text-slate-500 dark:text-slate-400">
<section className="overflow-hidden rounded-3xl border border-gray-200/80 bg-gradient-to-br from-white via-gray-50 to-white p-8 shadow-sm shadow-slate-200/60 dark:border-gray-800/70 dark:from-gray-900 dark:via-gray-950 dark:to-gray-900 dark:shadow-black/20">
<div className="text-xs font-semibold uppercase tracking-[0.35em] text-gray-500 dark:text-gray-400">
Opening Narrative
</div>
<div className="content-html prose prose-lg mt-6 max-w-none text-gray-800 dark:prose-invert">
@@ -418,17 +418,17 @@ const ContentSectionBlock = ({
return (
<section id={section.id} className="group/section scroll-mt-24">
<div className="overflow-hidden rounded-3xl border border-slate-200/80 bg-white/90 shadow-lg shadow-slate-200/50 backdrop-blur-sm transition-transform duration-300 group-hover/section:-translate-y-1 dark:border-gray-800/70 dark:bg-gray-900/70 dark:shadow-black/20">
<div className="overflow-hidden rounded-3xl border border-gray-200/80 bg-white/90 shadow-lg shadow-slate-200/50 backdrop-blur-sm transition-transform duration-300 group-hover/section:-translate-y-1 dark:border-gray-800/70 dark:bg-gray-900/70 dark:shadow-black/20">
<div className="flex flex-col gap-6 p-8 sm:p-10">
<div className="flex items-center gap-4">
<span className="inline-flex h-10 w-10 items-center justify-center rounded-full bg-brand-500/10 text-sm font-semibold text-brand-600 dark:bg-brand-500/20 dark:text-brand-300">
{index + 1}
</span>
<div className="flex flex-col">
<span className="text-[0.7rem] font-semibold uppercase tracking-[0.35em] text-slate-400 dark:text-slate-500">
<span className="text-[0.7rem] font-semibold uppercase tracking-[0.35em] text-gray-400 dark:text-gray-500">
Section Spotlight
</span>
<h2 className="text-2xl font-bold text-slate-900 dark:text-white sm:text-3xl">
<h2 className="text-2xl font-bold text-gray-900 dark:text-white sm:text-3xl">
{headingLabel}
</h2>
</div>
@@ -541,7 +541,7 @@ const ArticleBody = ({ introHtml, sections, sectionImages, imagesLoading, rawHtm
if (!hasStructuredSections && !introHtml && rawHtml) {
return (
<div className="overflow-hidden rounded-3xl border border-slate-200/80 bg-white/90 p-8 shadow-lg shadow-slate-200/50 dark:border-gray-800/70 dark:bg-gray-900/70 dark:shadow-black/20">
<div className="overflow-hidden rounded-3xl border border-gray-200/80 bg-white/90 p-8 shadow-lg shadow-slate-200/50 dark:border-gray-800/70 dark:bg-gray-900/70 dark:shadow-black/20">
<div className="content-html prose prose-lg max-w-none text-gray-800 dark:prose-invert">
<div dangerouslySetInnerHTML={{ __html: rawHtml }} />
</div>
@@ -790,13 +790,13 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten
const getStatusColor = (status: string) => {
const statusLower = status.toLowerCase();
if (statusLower === 'generated' || statusLower === 'published' || statusLower === 'complete') {
return 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400';
return 'bg-success-100 text-success-800 dark:bg-success-900/30 dark:text-success-400';
}
if (statusLower === 'pending' || statusLower === 'draft') {
return 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400';
return 'bg-warning-100 text-warning-800 dark:bg-warning-900/30 dark:text-warning-400';
}
if (statusLower === 'failed' || statusLower === 'error') {
return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400';
return 'bg-error-100 text-error-800 dark:bg-error-900/30 dark:text-error-400';
}
return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300';
};
@@ -1036,7 +1036,7 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten
</button>
<button
onClick={() => navigate(`/writer/published?contentId=${content.id}&action=publish`)}
className="inline-flex items-center gap-2 px-4 py-2 bg-green-500 hover:bg-green-600 text-white rounded-lg font-medium transition-colors"
className="inline-flex items-center gap-2 px-4 py-2 bg-success-500 hover:bg-success-600 text-white rounded-lg font-medium transition-colors"
>
<BoltIcon className="w-4 h-4" />
Publish
@@ -1053,13 +1053,13 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten
<div className="flex items-center gap-4">
{content.has_image_prompts && (
<div className="flex items-center gap-2">
<CheckCircleIcon className="w-5 h-5 text-green-500" />
<CheckCircleIcon className="w-5 h-5 text-success-500" />
<span className="text-sm text-gray-700 dark:text-gray-300">Image Prompts Generated</span>
</div>
)}
{content.has_generated_images && (
<div className="flex items-center gap-2">
<CheckCircleIcon className="w-5 h-5 text-green-500" />
<CheckCircleIcon className="w-5 h-5 text-success-500" />
<span className="text-sm text-gray-700 dark:text-gray-300">Images Generated</span>
</div>
)}
@@ -1076,7 +1076,7 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten
{imagesError && (
<div className="px-8 pt-4">
<div className="rounded-2xl border border-rose-200 bg-rose-50/80 px-4 py-3 text-sm font-medium text-rose-700 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-300">
<div className="rounded-2xl border border-error-200 bg-error-50/80 px-4 py-3 text-sm font-medium text-error-700 dark:border-error-900/40 dark:bg-error-950/30 dark:text-error-300">
{imagesError}
</div>
</div>
@@ -1157,12 +1157,12 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten
}
.content-html table th,
.content-html table td {
border: 1px solid #e5e7eb;
border: 1px solid var(--color-gray-200);
padding: 0.875rem 1rem;
text-align: left;
}
.content-html table th {
background: #f9fafb;
background: var(--color-gray-50);
font-weight: 600;
}
.content-html img {
@@ -1174,14 +1174,14 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten
box-shadow: 0 20px 45px -25px rgba(15, 23, 42, 0.35);
}
.content-html a {
color: #2563eb;
color: var(--color-brand-600);
text-decoration: none;
border-bottom: 1px solid rgba(37, 99, 235, 0.3);
border-bottom: 1px solid color-mix(in oklch, var(--color-brand-600) 30%, transparent);
transition: color 0.2s ease, border-bottom-color 0.2s ease;
}
.content-html a:hover {
color: #1d4ed8;
border-bottom-color: rgba(37, 99, 235, 0.6);
color: var(--color-brand-700);
border-bottom-color: color-mix(in oklch, var(--color-brand-600) 60%, transparent);
}
.content-html code {
background: rgba(15, 23, 42, 0.06);
@@ -1213,12 +1213,12 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten
background: rgba(30, 41, 59, 0.65);
}
.dark .content-html a {
color: #93c5fd;
border-bottom-color: rgba(147, 197, 253, 0.4);
color: var(--color-brand-300);
border-bottom-color: color-mix(in oklch, var(--color-brand-300) 40%, transparent);
}
.dark .content-html a:hover {
color: #bfdbfe;
border-bottom-color: rgba(191, 219, 254, 0.6);
color: var(--color-brand-200);
border-bottom-color: color-mix(in oklch, var(--color-brand-200) 60%, transparent);
}
.dark .content-html code,
.dark .content-html pre {