Initial commit: CI Agent competitive-intelligence monitoring app

FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring,
source collection, LLM-based change analysis, enrichment, and account
security (Turnstile, escalating lockout, email verification).
This commit is contained in:
2026-08-05 10:48:20 -04:00
commit 1a4c80958f
365 changed files with 43541 additions and 0 deletions
@@ -0,0 +1,43 @@
"use client";
const LEVELS = [
{ label: "Weak", bar: "bg-red-500", text: "text-red-600" },
{ label: "Fair", bar: "bg-amber-500", text: "text-amber-600" },
{ label: "Good", bar: "bg-brand-500", text: "text-brand-600" },
{ label: "Strong", bar: "bg-green-500", text: "text-green-600" },
] as const;
/** A purely visual affordance - length/variety heuristics scored 0-4, shown
* as an animated bar. Doesn't gate submission or loosen the real policy
* (still enforced by the password field's own Zod schema). */
function scorePassword(password: string): number {
if (!password) return 0;
let score = 0;
if (password.length >= 10) score += 1;
if (password.length >= 14) score += 1;
if (/[^a-zA-Z0-9]/.test(password)) score += 1;
if (/[a-z]/.test(password) && /[A-Z]/.test(password)) score += 1;
return Math.min(score, 4);
}
export function PasswordStrengthMeter({ password }: { password: string }) {
const score = scorePassword(password);
if (!password) return null;
const level = LEVELS[Math.max(score - 1, 0)] ?? LEVELS[0];
const widthPercent = (score / 4) * 100;
return (
<div className="mt-2 animate-fade-in">
<div className="h-1.5 w-full overflow-hidden rounded-full bg-slate-100">
<div
className={`h-full rounded-full transition-[width,background-color] duration-300 ${level.bar}`}
style={{ width: `${widthPercent}%` }}
/>
</div>
<p key={level.label} className={`mt-1 animate-fade-in text-xs ${level.text}`}>
{level.label}
</p>
</div>
);
}