Spaces:
Sleeping
Sleeping
File size: 6,841 Bytes
9747d8e 0ced925 9747d8e 0ced925 9747d8e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | "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>
);
}
|