Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-17 00:35:08 +00:00
co-authored by renee-png
parent 0cb99f38bb
commit 63b07ec6c6
+45
View File
@@ -265,6 +265,51 @@ function UsersPage() {
);
}
function RateInput({
value,
onSave,
}: {
value: number | null;
onSave: (v: number | null) => void | Promise<void>;
}) {
const [text, setText] = useState(value != null ? String(value) : "");
useEffect(() => setText(value != null ? String(value) : ""), [value]);
const dirty = text !== (value != null ? String(value) : "");
const commit = () => {
if (!dirty) return;
if (text.trim() === "") return onSave(null);
const n = parseFloat(text);
if (Number.isNaN(n) || n < 0) {
toast.error("Invalid rate");
setText(value != null ? String(value) : "");
return;
}
onSave(n);
};
return (
<div className="flex items-center gap-1">
<span className="text-xs text-muted-foreground">$</span>
<Input
type="number"
step="0.01"
min="0"
value={text}
onChange={(e) => setText(e.target.value)}
onBlur={commit}
onKeyDown={(e) => {
if (e.key === "Enter") (e.target as HTMLInputElement).blur();
}}
placeholder="—"
className="h-8 w-24"
/>
<span className="text-xs text-muted-foreground">/hr</span>
</div>
);
}
function InviteDialog({ onCreated }: { onCreated: () => void }) {
const [email, setEmail] = useState("");
const [fullName, setFullName] = useState("");