2026-02-27 21:12:23 +08:00
|
|
|
|
import type { DeckStore } from './hooks/deckStore';
|
|
|
|
|
|
|
|
|
|
|
|
export interface PrintPreviewHeaderProps {
|
|
|
|
|
|
store: DeckStore;
|
|
|
|
|
|
pageCount: number;
|
|
|
|
|
|
onExport: () => void;
|
|
|
|
|
|
onClose: () => void;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function PrintPreviewHeader(props: PrintPreviewHeaderProps) {
|
|
|
|
|
|
const { store } = props;
|
|
|
|
|
|
const orientation = () => store.state.printOrientation;
|
2026-03-13 17:26:00 +08:00
|
|
|
|
const frontOddPageOffsetX = () => store.state.printFrontOddPageOffsetX;
|
|
|
|
|
|
const frontOddPageOffsetY = () => store.state.printFrontOddPageOffsetY;
|
|
|
|
|
|
const doubleSided = () => store.state.printDoubleSided;
|
2026-02-27 21:12:23 +08:00
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div class="fixed top-0 left-0 right-0 z-50 bg-white shadow-lg rounded-lg mx-4 mt-4 px-4 py-3 flex items-center justify-between gap-4">
|
|
|
|
|
|
<div class="flex items-center gap-4">
|
|
|
|
|
|
<h2 class="text-base font-bold mt-0 mb-0">打印预览</h2>
|
|
|
|
|
|
<p class="text-xs text-gray-500 mb-0">共 {props.pageCount} 页,{store.state.cards.length} 张卡牌</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="flex items-center gap-4">
|
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
|
<label class="text-sm text-gray-600">方向:</label>
|
|
|
|
|
|
<div class="flex gap-1">
|
|
|
|
|
|
<button
|
|
|
|
|
|
onClick={() => store.actions.setPrintOrientation('portrait')}
|
|
|
|
|
|
class={`px-3 py-1 rounded text-sm font-medium cursor-pointer border ${
|
|
|
|
|
|
orientation() === 'portrait'
|
|
|
|
|
|
? 'bg-blue-600 text-white border-blue-600'
|
|
|
|
|
|
: 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'
|
|
|
|
|
|
}`}
|
|
|
|
|
|
>
|
|
|
|
|
|
竖向
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button
|
|
|
|
|
|
onClick={() => store.actions.setPrintOrientation('landscape')}
|
|
|
|
|
|
class={`px-3 py-1 rounded text-sm font-medium cursor-pointer border ${
|
|
|
|
|
|
orientation() === 'landscape'
|
|
|
|
|
|
? 'bg-blue-600 text-white border-blue-600'
|
|
|
|
|
|
: 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'
|
|
|
|
|
|
}`}
|
|
|
|
|
|
>
|
|
|
|
|
|
横向
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-03-13 17:26:00 +08:00
|
|
|
|
|
2026-02-27 21:12:23 +08:00
|
|
|
|
<div class="flex items-center gap-2">
|
2026-03-13 17:26:00 +08:00
|
|
|
|
<label class="flex items-center gap-1 cursor-pointer">
|
|
|
|
|
|
<input
|
|
|
|
|
|
type="checkbox"
|
|
|
|
|
|
checked={doubleSided()}
|
|
|
|
|
|
onChange={(e) => store.actions.setPrintDoubleSided(e.target.checked)}
|
|
|
|
|
|
class="cursor-pointer"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<span class="text-sm text-gray-600">双面打印</span>
|
|
|
|
|
|
</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
|
<label class="text-sm text-gray-600">正面奇数页偏移:</label>
|
2026-02-27 21:12:23 +08:00
|
|
|
|
<div class="flex items-center gap-1">
|
|
|
|
|
|
<span class="text-xs text-gray-500">X:</span>
|
|
|
|
|
|
<input
|
|
|
|
|
|
type="number"
|
2026-03-13 17:26:00 +08:00
|
|
|
|
value={frontOddPageOffsetX()}
|
|
|
|
|
|
onChange={(e) => store.actions.setPrintFrontOddPageOffsetX(Number(e.target.value))}
|
2026-02-27 21:12:23 +08:00
|
|
|
|
class="w-16 px-2 py-1 border border-gray-300 rounded text-sm"
|
|
|
|
|
|
step="0.1"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<span class="text-xs text-gray-500 ml-1">mm</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="flex items-center gap-1">
|
|
|
|
|
|
<span class="text-xs text-gray-500">Y:</span>
|
|
|
|
|
|
<input
|
|
|
|
|
|
type="number"
|
2026-03-13 17:26:00 +08:00
|
|
|
|
value={frontOddPageOffsetY()}
|
|
|
|
|
|
onChange={(e) => store.actions.setPrintFrontOddPageOffsetY(Number(e.target.value))}
|
2026-02-27 21:12:23 +08:00
|
|
|
|
class="w-16 px-2 py-1 border border-gray-300 rounded text-sm"
|
|
|
|
|
|
step="0.1"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<span class="text-xs text-gray-500 ml-1">mm</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="flex gap-2">
|
|
|
|
|
|
<button
|
|
|
|
|
|
onClick={props.onExport}
|
|
|
|
|
|
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-1.5 rounded text-sm font-medium cursor-pointer flex items-center gap-2"
|
|
|
|
|
|
>
|
|
|
|
|
|
<span>📥</span>
|
|
|
|
|
|
<span>导出 PDF</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button
|
|
|
|
|
|
onClick={props.onClose}
|
|
|
|
|
|
class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-1.5 rounded text-sm font-medium cursor-pointer"
|
|
|
|
|
|
>
|
|
|
|
|
|
关闭
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|