volleyball-dev-frontend/src/components/IbanInput.tsx
2025-04-20 20:32:34 +02:00

60 lines
1.7 KiB
TypeScript

import { useState } from "react";
import { Input } from "@/components/ui/input";
const IbanInput = ({ onValidIban }: { onValidIban?: (iban: string) => void }) => {
const [iban, setIban] = useState("");
const [error, setError] = useState("");
const formatIban = (value: string) => {
const alphanumeric = value.replace(/[^a-zA-Z0-9]/g, "").toUpperCase();
const formatted = alphanumeric.replace(/(.{4})/g, "$1 ").trim();
return formatted;
};
const validateIban = (rawIban: string) => {
// IBAN Validierung nach Mod-97-10 Regel
const rearranged = rawIban.slice(4) + rawIban.slice(0, 4);
const converted = rearranged.replace(/[A-Z]/g, (char) => (char.charCodeAt(0) - 55).toString());
const mod97 = BigInt(converted) % 97n;
return mod97 === 1n;
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const input = e.target.value;
if (input.length <= 27) {
setIban(formatIban(input));
setError(""); // Fehler zurücksetzen während der Eingabe
}
};
const handleBlur = () => {
const rawIban = iban.replace(/\s/g, ""); // Leerzeichen entfernen
if (rawIban.length >= 15) { // Minimum Länge einer IBAN
if (!validateIban(rawIban)) {
setError("Ungültige IBAN");
} else {
setError("");
if (onValidIban) {
onValidIban(rawIban);
}
}
}
};
return (
<div className="flex flex-col space-y-1">
<Input
placeholder="IBAN"
value={iban}
onChange={handleChange}
onBlur={handleBlur}
maxLength={27}
required
/>
{error && <span className="text-sm text-red-500">{error}</span>}
</div>
);
};
export default IbanInput;