({ isOpen, onClose, t, categories, newBankLabel, setNewBankLabel, newBankKey, setNewBankKey, newBankCategory, setNewBankCategory, onConfirm, language, isDarkMode })
| 555 | * 核心组件:添加词库模态框 |
| 556 | */ |
| 557 | export const AddBankModal = ({ isOpen, onClose, t, categories, newBankLabel, setNewBankLabel, newBankKey, setNewBankKey, newBankCategory, setNewBankCategory, onConfirm, language, isDarkMode }) => { |
| 558 | if (!isOpen) return null; |
| 559 | |
| 560 | return ( |
| 561 | <div |
| 562 | className="fixed inset-0 z-[120] bg-black/40 backdrop-blur-sm flex items-center justify-center p-4 animate-fade-in" |
| 563 | onClick={onClose} |
| 564 | > |
| 565 | <div |
| 566 | className={`w-full max-w-md rounded-2xl shadow-2xl overflow-hidden border animate-scale-up ${isDarkMode ? 'bg-[#242120] border-white/5' : 'bg-white border-gray-100'}`} |
| 567 | onClick={(e) => e.stopPropagation()} |
| 568 | > |
| 569 | <div className={`p-4 border-b flex justify-between items-center ${isDarkMode ? 'bg-black/20 border-white/5' : 'bg-gray-50 border-gray-100'}`}> |
| 570 | <h3 className={`font-bold flex items-center gap-2 ${isDarkMode ? 'text-gray-300' : 'text-gray-800'}`}> |
| 571 | <span className="w-2 h-2 rounded-full bg-orange-500"></span> |
| 572 | {t('add_bank_title')} |
| 573 | </h3> |
| 574 | <button onClick={onClose} className={`p-1 rounded transition-colors ${isDarkMode ? 'hover:bg-white/10 text-gray-500' : 'hover:bg-gray-200 text-gray-500'}`}> |
| 575 | <X size={18}/> |
| 576 | </button> |
| 577 | </div> |
| 578 | |
| 579 | <div className="p-6 space-y-4"> |
| 580 | <div> |
| 581 | <label className={`block text-xs mb-1.5 font-bold uppercase tracking-wide ${isDarkMode ? 'text-gray-600' : 'text-gray-500'}`}>{t('label_name')}</label> |
| 582 | <input |
| 583 | autoFocus |
| 584 | type="text" |
| 585 | className={`w-full text-sm rounded-xl px-4 py-3 focus:ring-2 focus:ring-orange-200 focus:border-orange-500 outline-none transition-all ${isDarkMode ? 'bg-white/5 border border-white/10 text-gray-200' : 'border border-gray-200 bg-gray-50/50 text-gray-700'}`} |
| 586 | placeholder={t('label_placeholder')} |
| 587 | value={newBankLabel} |
| 588 | onChange={e => setNewBankLabel(e.target.value)} |
| 589 | /> |
| 590 | </div> |
| 591 | <div> |
| 592 | <label className={`block text-xs mb-1.5 font-bold uppercase tracking-wide ${isDarkMode ? 'text-gray-600' : 'text-gray-500'}`}>{t('id_name')}</label> |
| 593 | <input |
| 594 | type="text" |
| 595 | className={`w-full text-sm rounded-xl px-4 py-3 font-mono focus:ring-2 focus:ring-orange-200 focus:border-orange-500 outline-none transition-all ${isDarkMode ? 'bg-white/5 border border-white/10 text-gray-200' : 'border border-gray-200 bg-gray-50/50 text-gray-700'}`} |
| 596 | placeholder={t('id_placeholder')} |
| 597 | value={newBankKey} |
| 598 | onChange={e => setNewBankKey(e.target.value)} |
| 599 | /> |
| 600 | </div> |
| 601 | <div> |
| 602 | <label className={`block text-xs mb-1.5 font-bold uppercase tracking-wide ${isDarkMode ? 'text-gray-600' : 'text-gray-500'}`}>{t('category_label')}</label> |
| 603 | <select |
| 604 | value={newBankCategory} |
| 605 | onChange={e => setNewBankCategory(e.target.value)} |
| 606 | className={`w-full text-sm border rounded-xl px-4 py-3 focus:ring-2 focus:ring-orange-200 focus:border-orange-500 outline-none transition-all appearance-none ${isDarkMode ? 'bg-[#2A2726] border-white/10 text-gray-300' : 'border-gray-200 bg-gray-50/50 text-gray-700'}`} |
| 607 | > |
| 608 | {Object.values(categories).map(cat => ( |
| 609 | <option key={cat.id} value={cat.id}>{getLocalized(cat.label, language)}</option> |
| 610 | ))} |
| 611 | </select> |
| 612 | </div> |
| 613 | |
| 614 | <div className="pt-4 flex gap-3"> |
nothing calls this directly
no test coverage detected