borndeveloper's picture
Highlight that PDC Intelligence is a prototype throughout the UI.
0ced925
Raw
History Blame Contribute Delete
6.84 kB
"use client";
import TooltipItem from "../common/TooltipItem";
interface Props {
predictionInput: any;
setPredictionInput: (v: any) => void;
filters: any;
handlePredict: () => void;
predicting: boolean;
}
export default function InputForm({
predictionInput,
setPredictionInput,
filters,
handlePredict,
predicting,
}: Props) {
const update = (key: string, value: string) =>
setPredictionInput({ ...predictionInput, [key]: value });
return (
<div className="bg-white rounded-xl border border-slate-200 shadow-sm overflow-hidden">
<div className="bg-slate-50 border-b border-slate-200 p-6">
<div className="flex items-center gap-2 mb-1 flex-wrap">
<h3 className="text-lg font-semibold text-slate-800">Target Finished Parameters</h3>
<span className="rounded-full bg-amber-100 border border-amber-300 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-amber-800">
Prototype Input
</span>
</div>
<p className="text-sm text-slate-500">
Enter finish specifications to explore greige construction options in this prototype.
Results are for evaluation feedback — not final production issuance.
</p>
</div>
<div className="p-6">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-5">
<SelectField
label="Weave"
value={predictionInput.weave}
onChange={(v: string) => update("weave", v)}
options={filters?.weaves || []}
required
tooltip="The interlacing pattern (Plain, Twill, Satin). Determines fabric texture."
/>
<SelectField
label="Blend"
value={predictionInput.blend}
onChange={(v: string) => update("blend", v)}
options={filters?.blends || []}
required
tooltip="Yarn composition. 100%CO = 100% Cotton."
/>
<SelectField
label="Dataset"
value={predictionInput.dataset}
onChange={(v: string) => update("dataset", v)}
options={["all", "working", "piece_dyed"]}
tooltip="Working = general catalog. Piece Dyed = dyed after weaving."
/>
<InputField
label="Warp Count"
value={predictionInput.warp_count}
onChange={(e: any) => update("warp_count", e.target.value)}
placeholder="e.g. 40"
tooltip="Yarn thickness (Ne). Raw value from swatch analysis."
type="number"
/>
<InputField
label="Weft Count"
value={predictionInput.weft_count}
onChange={(e: any) => update("weft_count", e.target.value)}
placeholder="e.g. 40"
tooltip="Weft yarn count (Ne). Used for GSM computation."
type="number"
/>
<InputField
label="Finish EPI"
value={predictionInput.finish_epi}
onChange={(e: any) => update("finish_epi", e.target.value)}
placeholder="e.g. 120"
tooltip="Ends per inch in finished fabric."
type="number"
/>
<InputField
label="Finish PPI"
value={predictionInput.finish_ppi}
onChange={(e: any) => update("finish_ppi", e.target.value)}
placeholder="e.g. 90"
tooltip="Picks per inch in finished fabric."
type="number"
/>
<InputField
label="Target GSM"
value={predictionInput.target_gsm}
onChange={(e: any) => update("target_gsm", e.target.value)}
placeholder="e.g. 120"
tooltip="Target fabric weight. Optional — GSM is also computed if counts + EPI/PPI provided."
type="number"
/>
</div>
<div className="mt-8 flex justify-end">
<button
onClick={handlePredict}
disabled={predicting || !predictionInput.weave || !predictionInput.blend || !predictionInput.finish_epi || !predictionInput.finish_ppi}
className="bg-indigo-600 hover:bg-indigo-700 disabled:opacity-50 disabled:cursor-not-allowed text-white px-6 py-2.5 rounded-lg font-medium shadow-sm transition-colors flex items-center gap-2"
>
{predicting ? (
<>
<svg className="animate-spin h-5 w-5" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" fill="none" />
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
</svg>
Analyzing...
</>
) : (
<>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<rect width="7" height="7" x="14" y="3" rx="1"></rect>
<path d="M10 21V8l-7 8"></path>
<path d="M10 13h12"></path>
</svg>
Generate Construction
</>
)}
</button>
</div>
</div>
</div>
);
}
function InputField({ label, type = "text", value, onChange, placeholder, tooltip }: any) {
return (
<div className="flex flex-col space-y-1.5">
<div className="text-sm font-medium text-slate-700 flex items-center">
{label}
{tooltip && <TooltipItem label={label} text={tooltip} />}
</div>
<input
type={type}
value={value}
onChange={onChange}
placeholder={placeholder}
className="px-3 py-2 border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent text-sm bg-white text-slate-900"
/>
</div>
);
}
function SelectField({ label, value, onChange, options, required, tooltip }: any) {
return (
<div className="flex flex-col space-y-1.5">
<div className="text-sm font-medium text-slate-700 flex items-center">
{label} {required && <span className="text-red-500 ml-1">*</span>}
{tooltip && <TooltipItem label={label} text={tooltip} />}
</div>
<select
value={value}
onChange={(e) => onChange(e.target.value)}
className="px-3 py-2 border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent text-sm bg-white text-slate-900"
>
<option value="">Select...</option>
{options?.map((opt: string) => (
<option key={opt} value={opt}>
{opt}
</option>
))}
</select>
</div>
);
}