"use client"; import { ChoiceGroup } from "@/components/form/choice-group"; import { feederRange, rangeText } from "@/lib/hive/feeder-slots"; import type { CatalogPartType, HiveFrame, HiveOp, HivePart } from "@/lib/hive/types"; import { StateFieldControl } from "./state-field-control"; import type { FieldDraft } from "./state-field-control"; // „Futtertasche einsetzen“ in the box sheet: choose the position, then the fill // level. Choosing a position empties the frames it covers in the same batch. const POCKET_OPTIONS = [ { value: false, label: "Keine Futtertasche" }, { value: true, label: "Futtertasche einsetzen" }, ]; export interface FrameFeederChoice { wants: boolean; /** First slot of the new pocket. */ start: number; draft: FieldDraft; } function rangeAt(start: number, type: CatalogPartType) { return feederRange({ id: "", partTypeId: type.id, state: {}, slot: start }, type); } function coveredSlots(start: number, type: CatalogPartType): number[] { const range = rangeAt(start, type); if (!range) return []; return Array.from({ length: range.to - range.from + 1 }, (_, index) => range.from + index); } /** Frames of the box with the covered slots set to NONE (names of covered frames are dropped). */ function emptiedFrames(frames: HiveFrame[], covered: number[]): HiveFrame[] { return frames.map((frame) => (covered.includes(frame.slot) ? { slot: frame.slot, type: "NONE" } : frame)); } /** Ops for the chosen pocket: setFrames only if a covered frame is not empty yet, then addInsert. */ export function frameFeederOps( boxId: string, frames: HiveFrame[], type: CatalogPartType, start: number, pocket: HivePart, ): HiveOp[] { const covered = coveredSlots(start, type); const needsEmptying = frames.some((frame) => covered.includes(frame.slot) && frame.type !== "NONE"); const ops: HiveOp[] = []; if (needsEmptying) ops.push({ op: "setFrames", boxId, frames: emptiedFrames(frames, covered) }); ops.push({ op: "addInsert", hostId: boxId, part: { ...pocket, slot: start } }); return ops; } interface FrameFeederPickerProps { boxId: string; type: CatalogPartType; frames: HiveFrame[]; starts: number[]; choice: FrameFeederChoice; onChange: (choice: FrameFeederChoice) => void; } export function FrameFeederPicker({ boxId, type, frames, starts, choice, onChange }: FrameFeederPickerProps) { const groupId = `part-${boxId}-frame-feeder`; const covered = coveredSlots(choice.start, type); const losesFrames = frames.some((frame) => covered.includes(frame.slot) && frame.type !== "NONE"); const startOptions = starts.map((start) => { const range = rangeAt(start, type); const noun = range && range.from !== range.to ? "Plätze" : "Platz"; return { value: start, label: `${noun} ${range ? rangeText(range) : start}` }; }); return (
Futtertasche onChange({ ...choice, wants })} labelledBy={groupId} className="grid-cols-2" /> {choice.wants ? ( <> Position onChange({ ...choice, start })} labelledBy={`${groupId}-slot`} className="grid-cols-3" /> {losesFrames ? (

Rähmchen auf diesen Plätzen werden zu „leer“.

) : null} {type.stateSchema.map((field) => ( onChange({ ...choice, draft: { ...choice.draft, [field.key]: value } })} /> ))} ) : null}
); }