Merge branch 't3code/company-overview-loading-cache'

This commit is contained in:
2026-03-13 19:05:25 -04:00
18 changed files with 1571 additions and 158 deletions

View File

@@ -0,0 +1,141 @@
import { Panel } from '@/components/ui/panel';
function SkeletonLine(props: { className: string }) {
return (
<div
aria-hidden="true"
className={`rounded-full bg-[color:var(--panel-soft)] motion-safe:animate-pulse ${props.className}`}
/>
);
}
function SkeletonCard(props: {
title?: string;
subtitle?: string;
children: React.ReactNode;
className?: string;
}) {
return (
<Panel title={props.title} subtitle={props.subtitle} className={props.className}>
{props.children}
</Panel>
);
}
export function CompanyAnalysisSkeleton() {
return (
<div className="space-y-6" data-testid="analysis-overview-skeleton" aria-live="polite" aria-busy="true">
<span className="sr-only">Loading company overview</span>
<section className="grid gap-6 xl:grid-cols-[minmax(320px,1fr)_minmax(0,2fr)]">
<Panel className="h-full pt-2">
<div className="space-y-5">
<div className="space-y-3">
<SkeletonLine className="h-8 w-3/4" />
<SkeletonLine className="h-3 w-1/2" />
</div>
<div className="border-t border-[color:var(--line-weak)] py-4">
<div className="space-y-3">
<SkeletonLine className="h-3 w-28" />
<SkeletonLine className="h-4 w-full" />
<SkeletonLine className="h-4 w-[92%]" />
<SkeletonLine className="h-4 w-[84%]" />
<SkeletonLine className="h-4 w-[66%]" />
</div>
</div>
</div>
</Panel>
<SkeletonCard title="Price chart" className="pt-2">
<div className="space-y-4">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-3">
{Array.from({ length: 3 }, (_, index) => (
<div key={index} className="border-b border-[color:var(--line-weak)] px-4 py-4 sm:border-b-0 sm:border-r last:border-r-0">
<SkeletonLine className="h-3 w-24" />
<SkeletonLine className="mt-3 h-7 w-28" />
<SkeletonLine className="mt-3 h-3 w-20" />
</div>
))}
</div>
<div className="rounded-xl border border-[color:var(--line-weak)] bg-[color:var(--panel-soft)] p-4">
<SkeletonLine className="h-[288px] w-full rounded-xl" />
</div>
</div>
</SkeletonCard>
</section>
<section className="grid gap-6 xl:grid-cols-2">
<SkeletonCard title="Company profile facts" className="pt-2">
<div className="space-y-3">
{Array.from({ length: 4 }, (_, index) => (
<div key={index} className="grid grid-cols-[18%_32%_18%_32%] gap-3 border-t border-[color:var(--line-weak)] py-2">
<SkeletonLine className="h-3 w-16" />
<SkeletonLine className="h-4 w-20" />
<SkeletonLine className="h-3 w-16" />
<SkeletonLine className="h-4 w-24" />
</div>
))}
</div>
</SkeletonCard>
<SkeletonCard title="Valuation" className="pt-2">
<div className="space-y-3">
{Array.from({ length: 4 }, (_, index) => (
<div key={index} className="grid grid-cols-[18%_32%_18%_32%] gap-3 border-t border-[color:var(--line-weak)] py-2">
<SkeletonLine className="h-3 w-20" />
<SkeletonLine className="h-4 w-24" />
<SkeletonLine className="h-3 w-20" />
<SkeletonLine className="h-4 w-20" />
</div>
))}
</div>
</SkeletonCard>
</section>
<SkeletonCard title="Bull vs Bear" subtitle="The highest-level reasons investors may lean in or lean out right now." className="pt-2">
<div className="grid gap-4 lg:grid-cols-2">
{Array.from({ length: 2 }, (_, index) => (
<section key={index} className="border-t border-[color:var(--line-weak)] pt-5">
<SkeletonLine className="h-6 w-28" />
<div className="mt-4 space-y-3">
{Array.from({ length: 3 }, (_, bulletIndex) => (
<div key={bulletIndex} className="border-t border-[color:var(--line-weak)] pt-3">
<SkeletonLine className="h-4 w-full" />
</div>
))}
</div>
</section>
))}
</div>
</SkeletonCard>
<section className="grid gap-6 xl:grid-cols-[minmax(280px,0.72fr)_minmax(0,1.28fr)]">
<SkeletonCard title="Past 7 Days" className="pt-2">
<div className="space-y-3">
<SkeletonLine className="h-4 w-full" />
<SkeletonLine className="h-4 w-[88%]" />
<div className="space-y-2 pt-2">
{Array.from({ length: 3 }, (_, index) => (
<SkeletonLine key={index} className="h-4 w-full" />
))}
</div>
</div>
</SkeletonCard>
<SkeletonCard title="Recent Developments" subtitle="SEC-first event cards sourced from filings and attached analysis." className="pt-2">
<div className="grid gap-3 md:grid-cols-2">
{Array.from({ length: 4 }, (_, index) => (
<article key={index} className="border-t border-[color:var(--line-weak)] pt-4">
<SkeletonLine className="h-3 w-28" />
<SkeletonLine className="mt-3 h-5 w-3/4" />
<SkeletonLine className="mt-3 h-4 w-full" />
<SkeletonLine className="mt-2 h-4 w-[90%]" />
<SkeletonLine className="mt-4 h-3 w-24" />
</article>
))}
</div>
</SkeletonCard>
</section>
</div>
);
}