"use client"; import { useState, useRef, useEffect } from "react"; import helpCommand from "../app/commands/help"; import socialsCommand from "../app/commands/socials"; import selfhostedCommand from "../app/commands/selfhosted"; import exitCommand from "../app/commands/exit"; import unknownCommand from "../app/commands/unknown"; import sourceCommand from "../app/commands/source"; const Terminal: React.FC = () => { const [input, setInput] = useState(""); const [output, setOutput] = useState([]); // eslint-disable-next-line @typescript-eslint/no-unused-vars const [history, setHistory] = useState([]); // eslint-disable-next-line @typescript-eslint/no-unused-vars const [historyIndex, setHistoryIndex] = useState(null); const [suggestion, setSuggestion] = useState(null); const [inputDisabled, setInputDisabled] = useState(false); // Disable input after exit const terminalEndRef = useRef(null); const inputRef = useRef(null); const commandsList = ["help", "socials", "exit", "selfhosted", "source"]; const handleInput = (e: React.FormEvent) => { e.preventDefault(); if (inputDisabled) return; // Prevent handling input if disabled if (input.trim() === "") { setOutput((prev) => [ ...prev,
 
, ]); setInput(""); return; } const normalizedInput = input.toLowerCase(); const commands: { [key: string]: (setInputDisabled: never, setOutput: never) => JSX.Element[] } = { help: helpCommand, socials: socialsCommand, exit: () => exitCommand(setInputDisabled, setOutput), // Pass control functions selfhosted: selfhostedCommand, source: sourceCommand, }; const commandOutput = commands[normalizedInput] || unknownCommand(normalizedInput); setOutput((prev) => [ ...prev,
$ {input}
, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ...commandOutput(), ]); setHistory((prev) => [...prev, input]); setHistoryIndex(null); setInput(""); setSuggestion(null); }; const handleInputChange = (value: string) => { setInput(value); const normalizedInput = value.toLowerCase(); const matchedCommand = commandsList.find((command) => command.startsWith(normalizedInput) ); setSuggestion(matchedCommand || null); }; useEffect(() => { terminalEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [output]); return (
inputRef.current?.focus()} >
{output.map((line, index) => (
{line}
))}
{!inputDisabled && ( // Hide the prompt if input is disabled $ )} {!inputDisabled && (
handleInputChange(e.target.value)} autoFocus disabled={inputDisabled} // Disable input when exited /> {suggestion && input.trim() !== suggestion && (
{input} {suggestion.slice(input.length)}
)}
)}
); }; const MOTD = () => { const socialsOutput = socialsCommand(false); const selfHostedOutput = selfhostedCommand(false); return ( <>
{` _____ _ _ _ `} {`\n | __ \\ (_|_) | | `} {`\n | |__) |___ _ __ _ __ _ _ ___ __| | _____ __`} {`\n | _ // _ \\| '_ \\| '_ \\| | |/ _ \\ / _\` |/ _ \\ \\ / /`} {`\n | | \\ \\ (_) | | | | | | | | | __/| (_| | __/\\ V / `} {`\n |_| \\_\\___/|_| |_|_| |_|_|_|\\___(_)__,_|\\___| \\_/ `}
Welcome to Ronnie's Development Terminal!
🎩 ABOUT THE DEV

Hi! I'm Ronnie—a developer passionate about blending code and design.

This site is my playground for testing and crafting innovative projects.

When I'm not tinkering here, I'm programming for NullDaily LLC, building open-source tools to empower creators and developers.

📡 SOCIALS
{socialsOutput.map((line, index) => (
{line}
))}
⚙️ SELF-HOSTED TOOLS
{selfHostedOutput.map((line, index) => (
{line}
))}

🌟 "Code, automate, and create with purpose. This isn't just development; it's an adventure." 🌟

Type 'help' to see what you can do. Let’s explore together!
); } export default Terminal;