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:
@@ -0,0 +1,44 @@
|
||||
import { type InputHTMLAttributes, forwardRef } from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
interface FormFieldProps extends InputHTMLAttributes<HTMLInputElement> {
|
||||
label: string;
|
||||
error?: string;
|
||||
hint?: string;
|
||||
}
|
||||
|
||||
export const FormField = forwardRef<HTMLInputElement, FormFieldProps>(
|
||||
({ label, error, hint, id, className, ...props }, ref) => {
|
||||
const fieldId = id ?? props.name;
|
||||
return (
|
||||
<div>
|
||||
<label htmlFor={fieldId} className="block text-sm font-medium text-slate-700">
|
||||
{label}
|
||||
</label>
|
||||
<input
|
||||
ref={ref}
|
||||
id={fieldId}
|
||||
className={clsx(
|
||||
"focus-ring mt-1 block w-full rounded-md border border-slate-300 px-3 py-2 text-sm shadow-sm",
|
||||
error && "border-red-400",
|
||||
className,
|
||||
)}
|
||||
aria-invalid={error ? "true" : "false"}
|
||||
aria-describedby={error ? `${fieldId}-error` : hint ? `${fieldId}-hint` : undefined}
|
||||
{...props}
|
||||
/>
|
||||
{hint && !error && (
|
||||
<p id={`${fieldId}-hint`} className="mt-1 text-xs text-slate-500">
|
||||
{hint}
|
||||
</p>
|
||||
)}
|
||||
{error && (
|
||||
<p id={`${fieldId}-error`} className="mt-1 text-xs text-red-600" role="alert">
|
||||
{error}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
FormField.displayName = "FormField";
|
||||
Reference in New Issue
Block a user