import React, { useState, useRef, useEffect } from 'react'; import { XKeypad, XKeypadManager, createPasswordKeypad, createPinKeypad, createCardKeypad, type XKeypadOptions, type XKeypadResult, type KeyType, type ViewType, type NumberKeyRowCount } from '../../utils/xkeypad'; import './xkeypad-styles.css'; export const XkeypadPage: React.FC = () => { // State for keypad options const [keyType, setKeyType] = useState('qwertysmart'); const [viewType, setViewType] = useState('half'); const [numberKeyRowCount, setNumberKeyRowCount] = useState(3); const [autoKeyResize, setAutoKeyResize] = useState(false); const [isE2E, setIsE2E] = useState(false); const [onlyMobile, setOnlyMobile] = useState(false); const [hasPressEffect, setHasPressEffect] = useState(true); const [useModal, setUseModal] = useState(false); const [useOverlay, setUseOverlay] = useState(true); // 오버레이 기본 활성화 // State for results const [passwordResult, setPasswordResult] = useState(null); const [pinResult, setPinResult] = useState(null); const [cardResult, setCardResult] = useState(null); // State for scripts loaded const [scriptsLoaded, setScriptsLoaded] = useState(false); // Input refs const passwordInputRef = useRef(null); const pinInputRef = useRef(null); const cardNumberInputRef = useRef(null); // XKeypad instances const passwordKeypadRef = useRef(null); const pinKeypadRef = useRef(null); const cardKeypadRef = useRef(null); // RSA Keys const RSA_MODULUS = "C4F7B39E2E93DB19C016C7A0C1C05B028A1D57CB9B91E13F5B7353F8FB5AC6CE6BE31ABEB8E8F7AD18B90C08F4EBC011A6A8FCE614EA879ED5B96296B969CE92923BC9BAD6FD87F00E08F529F93010EA77E40937BDAC1C866E79ACE2F2822A3ECD982F90532D5301CF90D9BF89E953A0593AB6C5F31E99B690DD582FB85F85A9"; const RSA_EXPONENT = "10001"; // Load scripts and initialize manager useEffect(() => { const initializeKeypadManager = async () => { try { const manager = XKeypadManager.getInstance({ modulus: RSA_MODULUS, exponent: RSA_EXPONENT }); await manager.loadScripts(); setScriptsLoaded(true); } catch (error) { console.error('Failed to load XKeypad scripts:', error); } }; initializeKeypadManager(); return () => { // Cleanup on unmount if (passwordKeypadRef.current) { passwordKeypadRef.current.destroy(); } if (pinKeypadRef.current) { pinKeypadRef.current.destroy(); } if (cardKeypadRef.current) { cardKeypadRef.current.destroy(); } }; }, []); // Close all keypads const closeAllKeypads = () => { if (passwordKeypadRef.current) { passwordKeypadRef.current.close(); } if (pinKeypadRef.current) { pinKeypadRef.current.close(); } if (cardKeypadRef.current) { cardKeypadRef.current.close(); } }; // Handle password keypad const handlePasswordKeypad = async () => { if (!scriptsLoaded || !passwordInputRef.current) return; // Close other keypads if (pinKeypadRef.current) pinKeypadRef.current.close(); if (cardKeypadRef.current) cardKeypadRef.current.close(); // Create or get existing keypad if (!passwordKeypadRef.current) { passwordKeypadRef.current = createPasswordKeypad(passwordInputRef.current, { keyType: keyType, viewType: viewType, numberKeyRowCount: numberKeyRowCount, autoKeyResize: autoKeyResize, isE2E: isE2E, onlyMobile: onlyMobile, hasPressEffect: hasPressEffect, useModal: useModal, useOverlay: useOverlay, onInputChange: (newLength: number) => { console.log('Password input length:', newLength); }, onKeypadClose: () => { console.log('Password keypad closed'); } }, { modulus: RSA_MODULUS, exponent: RSA_EXPONENT }); } else { // Update options if they changed passwordKeypadRef.current = new XKeypad('password', { keyType: keyType, viewType: viewType, numberKeyRowCount: numberKeyRowCount, maxInputSize: 16, autoKeyResize: autoKeyResize, isE2E: isE2E, onlyMobile: onlyMobile, hasPressEffect: hasPressEffect, useModal: useModal, useOverlay: useOverlay, onInputChange: (newLength: number) => { console.log('Password input length:', newLength); }, onKeypadClose: () => { console.log('Password keypad closed'); } }, { modulus: RSA_MODULUS, exponent: RSA_EXPONENT }); } const result = await passwordKeypadRef.current.initialize(passwordInputRef.current); if (result === 0) { console.log('Password keypad initialized successfully'); } else if (result === -1) { alert('지원하지 않는 기기입니다.'); } }; // Handle PIN keypad const handlePinKeypad = async () => { if (!scriptsLoaded || !pinInputRef.current) return; // Close other keypads if (passwordKeypadRef.current) passwordKeypadRef.current.close(); if (cardKeypadRef.current) cardKeypadRef.current.close(); // Create or get existing keypad if (!pinKeypadRef.current) { pinKeypadRef.current = createPinKeypad(pinInputRef.current, { viewType: viewType, numberKeyRowCount: numberKeyRowCount, autoKeyResize: autoKeyResize, isE2E: isE2E, onlyMobile: onlyMobile, hasPressEffect: hasPressEffect, useModal: useModal, useOverlay: useOverlay, onInputChange: (newLength: number) => { console.log('PIN input length:', newLength); if (newLength === 6 && pinKeypadRef.current && pinKeypadRef.current.isOpen()) { pinKeypadRef.current.close(); } }, onKeypadClose: () => { console.log('PIN keypad closed'); } }, { modulus: RSA_MODULUS, exponent: RSA_EXPONENT }); } else { // Update options if they changed pinKeypadRef.current = new XKeypad('pin', { keyType: 'number', viewType: viewType, numberKeyRowCount: numberKeyRowCount, maxInputSize: 6, autoKeyResize: autoKeyResize, isE2E: isE2E, onlyMobile: onlyMobile, hasPressEffect: hasPressEffect, useModal: useModal, useOverlay: useOverlay, onInputChange: (newLength: number) => { console.log('PIN input length:', newLength); if (newLength === 6 && pinKeypadRef.current && pinKeypadRef.current.isOpen()) { pinKeypadRef.current.close(); } }, onKeypadClose: () => { console.log('PIN keypad closed'); } }, { modulus: RSA_MODULUS, exponent: RSA_EXPONENT }); } const result = await pinKeypadRef.current.initialize(pinInputRef.current); if (result === 0) { console.log('PIN keypad initialized successfully'); } }; // Handle card keypad const handleCardKeypad = async () => { if (!scriptsLoaded || !cardNumberInputRef.current) return; // Close other keypads if (passwordKeypadRef.current) passwordKeypadRef.current.close(); if (pinKeypadRef.current) pinKeypadRef.current.close(); // Create or get existing keypad if (!cardKeypadRef.current) { cardKeypadRef.current = createCardKeypad(cardNumberInputRef.current, { viewType: viewType, autoKeyResize: autoKeyResize, isE2E: isE2E, onlyMobile: onlyMobile, hasPressEffect: hasPressEffect, useModal: useModal, useOverlay: useOverlay, onInputChange: (newLength: number) => { console.log('Card number input length:', newLength); if (newLength === 16 && cardKeypadRef.current && cardKeypadRef.current.isOpen()) { cardKeypadRef.current.close(); } }, onKeypadClose: () => { console.log('Card keypad closed'); } }, { modulus: RSA_MODULUS, exponent: RSA_EXPONENT }); } else { // Update options if they changed cardKeypadRef.current = new XKeypad('card', { keyType: 'number', viewType: viewType, numberKeyRowCount: 4, maxInputSize: 16, autoKeyResize: autoKeyResize, isE2E: isE2E, onlyMobile: onlyMobile, hasPressEffect: hasPressEffect, useModal: useModal, useOverlay: useOverlay, onInputChange: (newLength: number) => { console.log('Card number input length:', newLength); if (newLength === 16 && cardKeypadRef.current && cardKeypadRef.current.isOpen()) { cardKeypadRef.current.close(); } }, onKeypadClose: () => { console.log('Card keypad closed'); } }, { modulus: RSA_MODULUS, exponent: RSA_EXPONENT }); } const result = await cardKeypadRef.current.initialize(cardNumberInputRef.current); if (result === 0) { console.log('Card keypad initialized successfully'); } }; // Handle submit functions const handlePasswordSubmit = () => { if (!passwordKeypadRef.current) return; const result = passwordKeypadRef.current.getValue(); if (result) { setPasswordResult(result); console.log('Password Result:', result); alert(`Password submitted:\n${JSON.stringify(result, null, 2)}`); } }; const handlePinSubmit = () => { if (!pinKeypadRef.current) return; const result = pinKeypadRef.current.getValue(); if (result) { setPinResult(result); console.log('PIN Result:', result); alert(`PIN submitted:\n${JSON.stringify(result, null, 2)}`); } }; const handleCardSubmit = () => { if (!cardKeypadRef.current) return; const result = cardKeypadRef.current.getValue(); if (result) { setCardResult(result); console.log('Card Result:', result); alert(`Card Number submitted:\n${JSON.stringify(result, null, 2)}`); } }; const clearAll = () => { if (passwordKeypadRef.current) { passwordKeypadRef.current.clear(); } if (pinKeypadRef.current) { pinKeypadRef.current.clear(); } if (cardKeypadRef.current) { cardKeypadRef.current.clear(); } if (passwordInputRef.current) passwordInputRef.current.value = ''; if (pinInputRef.current) pinInputRef.current.value = ''; if (cardNumberInputRef.current) cardNumberInputRef.current.value = ''; setPasswordResult(null); setPinResult(null); setCardResult(null); }; if (!scriptsLoaded) { return
Loading XKeypad scripts...
; } return (

XecureKeypad Demo (Direct JS Integration)

Keypad Options

Input Fields

{passwordResult && (
{JSON.stringify(passwordResult, null, 2)}
)}
{pinResult && (
{JSON.stringify(pinResult, null, 2)}
)}
{cardResult && (
{JSON.stringify(cardResult, null, 2)}
)}
); }; export default XkeypadPage;