import React, { useCallback, useEffect, useMemo, useState, type CSSProperties } from "react"; import data from "../../assets/data/2.0/data.json"; import styles from "./MachineSelector.module.css"; import Icon from "../icon"; import { Autocomplete, Box, Popper, TextField, InputAdornment } from "@mui/material"; import SelectMenu from "./SelectFactorioMenu"; import Tooltip from "../Tooltip"; import type { Recipe } from "../../../scripts/factorio-dump/helpers/recipes.helper"; import type { Machine } from "../../../scripts/factorio-dump/process-data.models"; import { useQualityScroller } from "../../hooks/useQualityScroller"; const recipeList = data.recipeGroup.flatMap((r) => r.subGroup.flatMap((s) => (s.children ?? []) as Recipe[])); const machines = data.machines as Machine[]; type MachineSelectorProps = { className?: string; style?: CSSProperties; onChange?: (selection: { machine: Machine | null; qualityLevel: number; recipe: Recipe | null }) => void; }; function MachineSelector({ style, className, onChange }: MachineSelectorProps) { const [machine, setMachine] = React.useState(null); const [recipe, setRecipe] = useState(null); const [anchorEl, setAnchorEl] = useState(null); const [showMenuRecipe, setShowMenuRecipe] = useState(false); const { scrollRef, activeQuality, setQualityName } = useQualityScroller("normal"); useEffect(() => { if (onChange) { onChange({ machine, qualityLevel: activeQuality.level, recipe }); } }, [machine, activeQuality, recipe]); const machineOptions = useMemo(() => { if (recipe == null) return []; const categories = recipe.categories ?? []; return machines.filter((m) => m.crafting_categories.some((c) => categories.includes(c))); }, [recipe]); useEffect(() => { if (machineOptions.length === 1) setMachine(machineOptions[0]); if (machine && !machineOptions.includes(machine)) setMachine(null); }, [machineOptions, machine]); const onOpenRecipe = useCallback( (event: React.MouseEvent) => { setAnchorEl(anchorEl ? null : event.currentTarget); setShowMenuRecipe(!showMenuRecipe); }, [anchorEl, showMenuRecipe], ); const onSelectRecipe = useCallback((name: string) => { setRecipe(recipeList.find((r) => r.name === name) ?? null); setAnchorEl(null); setShowMenuRecipe(false); }, []); return (
{/* Recipe Trigger */}
{recipe == null ? (
Select recipe
) : (
)}
{ setMachine(newValue); }} disablePortal options={machineOptions} sx={{ width: 300 }} getOptionLabel={(option) => option.name} disabled={!recipe} renderInput={(params: any) => (
) : null, }} /> )} renderOption={(props: any, option: Machine) => { const { key, ...optionProps } = props; return ( {option.name} ); }} /> setShowMenuRecipe(false)} />
); } export default MachineSelector;