refactoring, linting, formatting
This commit is contained in:
213
src/components/PageWorkspace/PageCard.tsx
Normal file
213
src/components/PageWorkspace/PageCard.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
import React from "react";
|
||||
import type { PageRef } from "../../pdf/pdfTypes";
|
||||
import DropIndicator from "./DropIndicator";
|
||||
|
||||
interface PageCardProps {
|
||||
page: PageRef;
|
||||
visualIndex: number;
|
||||
thumbnail?: string;
|
||||
selected: boolean;
|
||||
isDraggingCard: boolean;
|
||||
isBusy: boolean;
|
||||
isCopyDragging: boolean;
|
||||
showLeftLine: boolean;
|
||||
showRightLine: boolean;
|
||||
dropIndicatorColor: string;
|
||||
onDragStart: React.DragEventHandler<HTMLDivElement>;
|
||||
onDragEnd: React.DragEventHandler<HTMLDivElement>;
|
||||
onDragOver: React.DragEventHandler<HTMLDivElement>;
|
||||
onOpenPreview: () => void;
|
||||
onToggleSelect: React.MouseEventHandler<HTMLButtonElement>;
|
||||
onRotateClockwise: () => void;
|
||||
onRotateCounterclockwise: () => void;
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
const pageActionButtonStyle: React.CSSProperties = {
|
||||
border: "none",
|
||||
borderRadius: "999px",
|
||||
padding: "0.15rem 0.4rem",
|
||||
fontSize: "0.75rem",
|
||||
cursor: "pointer",
|
||||
};
|
||||
|
||||
const PageCard: React.FC<PageCardProps> = ({
|
||||
page,
|
||||
visualIndex,
|
||||
thumbnail,
|
||||
selected,
|
||||
isDraggingCard,
|
||||
isBusy,
|
||||
isCopyDragging,
|
||||
showLeftLine,
|
||||
showRightLine,
|
||||
dropIndicatorColor,
|
||||
onDragStart,
|
||||
onDragEnd,
|
||||
onDragOver,
|
||||
onOpenPreview,
|
||||
onToggleSelect,
|
||||
onRotateClockwise,
|
||||
onRotateCounterclockwise,
|
||||
onDelete,
|
||||
}) => {
|
||||
const background = isDraggingCard
|
||||
? isCopyDragging
|
||||
? "#dcfce7"
|
||||
: "#dbeafe"
|
||||
: selected
|
||||
? "#eff6ff"
|
||||
: "#f9fafb";
|
||||
|
||||
return (
|
||||
<div
|
||||
draggable
|
||||
onDragStart={onDragStart}
|
||||
onDragEnd={onDragEnd}
|
||||
onDragOver={onDragOver}
|
||||
onClick={onOpenPreview}
|
||||
style={{
|
||||
position: "relative",
|
||||
width: "162px",
|
||||
padding: "0.4rem",
|
||||
borderRadius: "0.5rem",
|
||||
border: "1px solid #e5e7eb",
|
||||
background,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: "0.25rem",
|
||||
cursor: isBusy ? "default" : isCopyDragging ? "copy" : "grab",
|
||||
opacity: isBusy ? 0.7 : 1,
|
||||
}}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onToggleSelect}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "4px",
|
||||
left: "4px",
|
||||
width: "20px",
|
||||
height: "20px",
|
||||
borderRadius: "0.4rem",
|
||||
border: "1px solid #9ca3af",
|
||||
background: selected ? "#2563eb" : "rgba(255,255,255,0.9)",
|
||||
color: selected ? "white" : "transparent",
|
||||
fontSize: "0.8rem",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: 0,
|
||||
cursor: "pointer",
|
||||
}}
|
||||
title="Select page"
|
||||
>
|
||||
✓
|
||||
</button>
|
||||
|
||||
{showLeftLine && <DropIndicator side="left" color={dropIndicatorColor} />}
|
||||
{showRightLine && (
|
||||
<DropIndicator side="right" color={dropIndicatorColor} />
|
||||
)}
|
||||
|
||||
<div
|
||||
style={{
|
||||
width: "110px",
|
||||
height: "90px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
{thumbnail ? (
|
||||
<img
|
||||
src={thumbnail}
|
||||
alt={`Page ${page.sourcePageIndex + 1}`}
|
||||
style={{
|
||||
maxWidth: "100%",
|
||||
maxHeight: "100%",
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
objectFit: "contain",
|
||||
borderRadius: "0.25rem",
|
||||
border: "1px solid #e5e7eb",
|
||||
background: "white",
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
width: "60px",
|
||||
height: "80px",
|
||||
borderRadius: "0.25rem",
|
||||
border: "1px dashed #d1d5db",
|
||||
background: "#f3f4f6",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<span style={{ fontSize: "0.8rem" }}>
|
||||
Page {page.sourcePageIndex + 1}
|
||||
</span>
|
||||
<span style={{ fontSize: "0.7rem", color: "#6b7280" }}>
|
||||
Pos {visualIndex + 1} · Rot {page.rotation}°
|
||||
</span>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: "0.25rem",
|
||||
marginTop: "0.25rem",
|
||||
}}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onRotateClockwise();
|
||||
}}
|
||||
style={{
|
||||
...pageActionButtonStyle,
|
||||
background: "#e5e7eb",
|
||||
}}
|
||||
>
|
||||
↻ 90°
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onRotateCounterclockwise();
|
||||
}}
|
||||
style={{
|
||||
...pageActionButtonStyle,
|
||||
background: "#e5e7eb",
|
||||
}}
|
||||
>
|
||||
↺ 90°
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onDelete();
|
||||
}}
|
||||
style={{
|
||||
...pageActionButtonStyle,
|
||||
background: "#fecaca",
|
||||
color: "#b91c1c",
|
||||
}}
|
||||
title="Remove this page from the exported PDF"
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PageCard;
|
||||
Reference in New Issue
Block a user