"use client" import { useEffect, useRef, useState, useCallback } from "react" import { motion, AnimatePresence } from "motion/react" import { Terminal, ChevronDown, Loader2, ToggleLeft, ToggleRight } from "lucide-react" import { api } from "@/lib/eden" export const UPSCALER_TYPE_OPTIONS = [ { value: "none", label: "None" }, { value: "fsr", label: "AMD FSR" }, { value: "dlss", label: "NVIDIA DLSS" }, { value: "xess", label: "Intel XeSS" }, { value: "lsfg", label: "Lossless Scaling FG" }, { value: "other", label: "Other" }, ] as const export const FRAME_GEN_OPTIONS = [ { value: "none", label: "None" }, { value: "fsr_fg", label: "FSR Frame Generation" }, { value: "dlss_fg", label: "DLSS Frame Generation" }, { value: "lsfg", label: "Lossless Scaling FG" }, { value: "other", label: "Other" }, ] as const export interface EnvironmentData { protonVersion?: string osVersion?: string upscalerType?: string upscalerVersion?: string frameGenMethod?: string launchOptions?: string estimatedBatteryMin?: number customSystem?: boolean } interface EnvironmentStepProps { value: EnvironmentData onChange: (value: EnvironmentData) => void } function AutocompleteInput({ label, placeholder, value, onChange, field, }: { label: string placeholder: string value: string onChange: (val: string) => void field: "protonVersion" | "osVersion" }) { const [suggestions, setSuggestions] = useState([]) const [loading, setLoading] = useState(false) const [open, setOpen] = useState(false) const [localValue, setLocalValue] = useState("") const [isFocused, setIsFocused] = useState(false) const containerRef = useRef(null) const inputValue = isFocused ? localValue : (value ?? "") useEffect(() => { function handleClickOutside(e: MouseEvent) { if (containerRef.current && !containerRef.current.contains(e.target as Node)) { setOpen(false) } } document.addEventListener("mousedown", handleClickOutside) return () => document.removeEventListener("mousedown", handleClickOutside) }, []) const fetchSuggestions = useCallback( async (query: string) => { try { setLoading(true) const res = await api.performance.autocomplete.get({ query: { field } }) if (!res.error && res.data?.data) { const data = res.data.data const filtered = query ? data.filter((s) => s.toLowerCase().includes(query.toLowerCase())) : data setSuggestions(filtered.slice(0, 8)) } } catch { setSuggestions([]) } finally { setLoading(false) } }, [field] ) const handleFocus = () => { setLocalValue(value ?? "") setIsFocused(true) setOpen(true) fetchSuggestions(value ?? "") } const handleChange = (val: string) => { setLocalValue(val) onChange(val) fetchSuggestions(val) setOpen(true) } const handleSelect = (val: string) => { setLocalValue(val) onChange(val) setOpen(false) } return (
handleChange(e.target.value)} onFocus={handleFocus} onBlur={() => setIsFocused(false)} placeholder={placeholder} className="w-full px-4 py-3 rounded-lg border border-border bg-text/5 text-text text-sm placeholder:text-text/40 outline-none focus:border-primary focus:ring-2 focus:ring-primary/50 transition-colors" /> {loading && ( )} {open && suggestions.length > 0 && ( {suggestions.map((s) => ( ))} )}
) } export function EnvironmentStep({ value, onChange }: EnvironmentStepProps) { const update = (field: keyof EnvironmentData, val: string) => { onChange({ ...value, [field]: val }) } return (

Environment

Describe the software environment used during testing.

update("protonVersion", val)} field="protonVersion" /> update("osVersion", val)} field="osVersion" />
{value.upscalerType && value.upscalerType !== "none" && (
update("upscalerVersion", e.target.value)} placeholder="e.g. 3.1" className="w-full px-4 py-3 rounded-lg border border-border bg-text/5 text-text text-sm placeholder:text-text/40 outline-none focus:border-primary focus:ring-2 focus:ring-primary/50 transition-colors" />
)}