cd75141037
P1 thiserror 类型化错误: 新增 core/src/error.rs QrError 枚举, 全链 String -> QrError, 包括 EmptyInput/InvalidVersion/DataTooLong/DecodeFail 等 8 种变体 P2 text_builder Tauri 统一: 新增 build_qr_text Tauri command, 删除前端 qrText.ts, 所有 mode 组件改为 invoke 调用 Rust 端构建文本 P3 QrConfig 颜色字段移除: 从 QrConfig/QrCode 移除 fg_color/bg_color, 改为 to_svg/to_image_bytes 参数传递 P4 前端 4 项合并: Context 拆分为 StateContext+DispatchContext (H10), 新建 useModeForm 通用 hook (M11), VCardMode grid-cols-2 网格布局 (M13), persistHistory/loadHistory 迁至 utils/storage.ts (L9) P5 算法优化: MaskedView 懒计算替代 8 次 Matrix 克隆 (H9), encoding_rs 精确 Kanji Shift JIS 映射 (H12) 验证: cargo check+clippy 通过, 81+24+7 全部测试通过
41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
import { useTranslation } from 'react-i18next';
|
|
import { useQrState, useQrDispatch } from '../store/qrContext';
|
|
import { MODES } from '../types';
|
|
|
|
const MODE_LABELS: Record<string, string> = {
|
|
text: 'mode.text',
|
|
url: 'mode.url',
|
|
wifi: 'mode.wifi',
|
|
vcard: 'mode.vcard',
|
|
email: 'mode.email',
|
|
phone: 'mode.phone',
|
|
sms: 'mode.sms',
|
|
};
|
|
|
|
export default function ModePanel() {
|
|
const { t } = useTranslation();
|
|
const state = useQrState();
|
|
const dispatch = useQrDispatch();
|
|
|
|
return (
|
|
<div className="w-48 border-r border-gray-200 dark:border-gray-800 p-3 flex flex-col gap-1 bg-white/60 dark:bg-gray-900/60 backdrop-blur-sm">
|
|
<div className="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2 px-2">
|
|
{t('app.encodingModes')}
|
|
</div>
|
|
{MODES.map((mode) => (
|
|
<button
|
|
key={mode}
|
|
onClick={() => dispatch({ type: 'SET_MODE', payload: mode })}
|
|
className={`px-3 py-2 rounded-lg text-left text-sm transition-all ${
|
|
state.mode === mode
|
|
? 'bg-gradient-to-r from-blue-500 to-cyan-500 text-white shadow-md shadow-blue-500/20'
|
|
: 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800'
|
|
}`}
|
|
>
|
|
{t(MODE_LABELS[mode])}
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|