ultisuite-client/components/drive/richtext/docs-header-footer-dialogs.tsx
R3D347HR4Y 2a7c153748
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
wrap page
2026-06-10 12:48:27 +02:00

209 lines
6.7 KiB
TypeScript

"use client"
import { useState } from "react"
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Checkbox } from "@/components/ui/checkbox"
import type { DocPageNumberSettings, DocPageSetup } from "@/lib/drive/doc-page-setup"
import { cmToMm, mmToCm } from "@/lib/drive/doc-page-setup"
export function DocsHeaderFooterFormatDialog({
open,
onOpenChange,
pageSetup,
onApply,
}: {
open: boolean
onOpenChange: (open: boolean) => void
pageSetup: DocPageSetup | null
onApply: (patch: Partial<DocPageSetup>) => void
}) {
const headerCm = mmToCm(pageSetup?.headerMarginMm ?? pageSetup?.marginsMm.top ?? 20)
const footerCm = mmToCm(pageSetup?.footerMarginMm ?? pageSetup?.marginsMm.bottom ?? 20)
const [headerMarginCm, setHeaderMarginCm] = useState(headerCm)
const [footerMarginCm, setFooterMarginCm] = useState(footerCm)
const [differentFirst, setDifferentFirst] = useState(
pageSetup?.headerFooterDifferentFirstPage ?? false
)
const [differentOddEven, setDifferentOddEven] = useState(
pageSetup?.headerFooterDifferentOddEven ?? false
)
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-md">
<DialogHeader>
<DialogTitle>En-têtes et pieds de page</DialogTitle>
</DialogHeader>
<div className="space-y-4 py-2">
<div>
<p className="mb-2 text-sm font-medium">Marges</p>
<div className="grid grid-cols-2 gap-3">
<div className="space-y-1">
<Label className="text-xs text-muted-foreground">
En-tête (cm depuis le haut)
</Label>
<Input
type="number"
min={0}
step={0.1}
value={headerMarginCm}
onChange={(e) => setHeaderMarginCm(Number(e.target.value) || 0)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-muted-foreground">
Pied de page (cm depuis le bas)
</Label>
<Input
type="number"
min={0}
step={0.1}
value={footerMarginCm}
onChange={(e) => setFooterMarginCm(Number(e.target.value) || 0)}
/>
</div>
</div>
</div>
<div>
<p className="mb-2 text-sm font-medium">Mise en page</p>
<div className="space-y-2">
<label className="flex items-center gap-2 text-sm">
<Checkbox
checked={differentFirst}
onCheckedChange={(v) => setDifferentFirst(v === true)}
/>
Première page différente
</label>
<label className="flex items-center gap-2 text-sm">
<Checkbox
checked={differentOddEven}
onCheckedChange={(v) => setDifferentOddEven(v === true)}
/>
Différente pour les pages paires et impaires
</label>
</div>
</div>
</div>
<DialogFooter>
<Button type="button" variant="ghost" onClick={() => onOpenChange(false)}>
Annuler
</Button>
<Button
type="button"
onClick={() => {
onApply({
headerMarginMm: cmToMm(headerMarginCm),
footerMarginMm: cmToMm(footerMarginCm),
headerFooterDifferentFirstPage: differentFirst,
headerFooterDifferentOddEven: differentOddEven,
})
onOpenChange(false)
}}
>
Appliquer
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}
export function DocsPageNumbersDialog({
open,
onOpenChange,
settings,
onApply,
}: {
open: boolean
onOpenChange: (open: boolean) => void
settings: DocPageNumberSettings | null | undefined
onApply: (settings: DocPageNumberSettings) => void
}) {
const [placement, setPlacement] = useState<"header" | "footer">(
settings?.placement ?? "header"
)
const [startAt, setStartAt] = useState(settings?.startAt ?? 1)
const [showOnFirstPage, setShowOnFirstPage] = useState(settings?.showOnFirstPage ?? true)
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-md">
<DialogHeader>
<DialogTitle>Numéros de page</DialogTitle>
</DialogHeader>
<div className="space-y-4 py-2">
<div>
<p className="mb-2 text-sm font-medium">Position</p>
<div className="flex gap-4 text-sm">
<label className="flex items-center gap-2">
<input
type="radio"
name="page-num-placement"
checked={placement === "header"}
onChange={() => setPlacement("header")}
/>
En-tête
</label>
<label className="flex items-center gap-2">
<input
type="radio"
name="page-num-placement"
checked={placement === "footer"}
onChange={() => setPlacement("footer")}
/>
Pied de page
</label>
</div>
</div>
<label className="flex items-center gap-2 text-sm">
<Checkbox
checked={showOnFirstPage}
onCheckedChange={(v) => setShowOnFirstPage(v === true)}
/>
Afficher sur la première page
</label>
<div className="space-y-1">
<Label className="text-xs text-muted-foreground">Commencer à</Label>
<Input
type="number"
min={0}
value={startAt}
onChange={(e) => setStartAt(Number(e.target.value) || 0)}
className="w-24"
/>
</div>
</div>
<DialogFooter>
<Button type="button" variant="ghost" onClick={() => onOpenChange(false)}>
Annuler
</Button>
<Button
type="button"
onClick={() => {
onApply({
enabled: true,
placement,
align: "right",
startAt,
showOnFirstPage,
})
onOpenChange(false)
}}
>
Appliquer
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}