Add components for Act management and integrate Electron setup

This commit is contained in:
natreex
2025-11-16 11:00:04 -05:00
parent e192b6dcc2
commit 8167948881
97 changed files with 25378 additions and 3 deletions

View File

@@ -0,0 +1,71 @@
import React, {ChangeEvent, KeyboardEvent, useRef, useState} from "react";
import AddActionButton from "@/components/form/AddActionButton";
interface InlineAddInputProps {
value: string;
setValue: (value: string) => void;
numericalValue?: number;
setNumericalValue?: (value: number) => void;
placeholder: string;
onAdd: () => Promise<void>;
showNumericalInput?: boolean;
}
export default function InlineAddInput(
{
value,
setValue,
numericalValue,
setNumericalValue,
placeholder,
onAdd,
showNumericalInput = false
}: InlineAddInputProps) {
const [isAdding, setIsAdding] = useState<boolean>(false);
const listItemRef = useRef<HTMLLIElement>(null);
async function handleAdd(): Promise<void> {
await onAdd();
setIsAdding(false);
}
return (
<li
ref={listItemRef}
onBlur={(e: React.FocusEvent<HTMLLIElement, Element>): void => {
if (!listItemRef.current?.contains(e.relatedTarget)) {
setIsAdding(false);
}
}}
className="relative flex items-center gap-1 h-[44px] px-3 bg-secondary/30 rounded-xl border-2 border-dashed border-secondary/50 hover:border-primary/60 hover:bg-secondary/50 cursor-pointer transition-colors duration-200"
>
{showNumericalInput && numericalValue !== undefined && setNumericalValue && (
<input
className={`bg-secondary/50 text-primary text-sm px-1.5 py-0.5 rounded border border-secondary/50 transition-all duration-200 !outline-none !ring-0 !shadow-none focus-visible:!outline-none focus-visible:!ring-0 focus-visible:!shadow-none ${isAdding ? 'w-10 opacity-100' : 'w-0 opacity-0 px-0 border-0'}`}
type="number"
value={numericalValue}
onChange={(e: ChangeEvent<HTMLInputElement>) => setNumericalValue(parseInt(e.target.value))}
tabIndex={isAdding ? 0 : -1}
/>
)}
<input
onFocus={(): void => setIsAdding(true)}
onKeyUp={async (e: KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
await handleAdd();
}
}}
className="flex-1 min-w-0 bg-transparent text-text-primary text-sm px-1 py-0.5 cursor-pointer focus:cursor-text placeholder:text-muted/60 transition-all duration-200 !outline-none !ring-0 !shadow-none focus-visible:!outline-none focus-visible:!ring-0 focus-visible:!shadow-none"
type="text"
onChange={(e: ChangeEvent<HTMLInputElement>) => setValue(e.target.value)}
value={value}
placeholder={placeholder}
/>
{isAdding && (
<div className="absolute right-1 opacity-100">
<AddActionButton callBackAction={handleAdd}/>
</div>
)}
</li>
);
}