ultisuite-client/components/drive/ultidraw-chrome.tsx
R3D347HR4Y 303b2b1074
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
wow
2026-06-11 01:22:40 +02:00

123 lines
3.8 KiB
TypeScript

"use client"
import type { ReactNode } from "react"
import Link from "next/link"
import { ArrowLeft, Globe, Lock, Users } from "lucide-react"
import { EditorAccountButton } from "@/components/drive/editor-account-button"
import { OfficeEditorInlineTitle } from "@/components/drive/office-editor-inline-title"
import { ShareDialog } from "@/components/drive/share-dialog"
import { CollabPresenceAvatars } from "@/components/drive/richtext/collab-presence-avatars"
import { Button } from "@/components/ui/button"
import type { DriveShare } from "@/lib/api/types"
import type { CollabPresenceUser } from "@/lib/drive/use-collab-presence"
import {
resolveShareButtonIcon,
type ShareButtonIcon,
} from "@/lib/drive/drive-share-button-state"
import type { UltidrawSaveStatus } from "@/lib/drive/ultidraw-types"
import { cn } from "@/lib/utils"
function ShareButtonIcon({ kind }: { kind: ShareButtonIcon }) {
if (kind === "globe") return <Globe className="h-4 w-4" aria-hidden />
if (kind === "users") return <Users className="h-4 w-4" aria-hidden />
return <Lock className="h-4 w-4" aria-hidden />
}
function saveStatusLabel(status: UltidrawSaveStatus): string {
switch (status) {
case "saving":
return "Enregistrement…"
case "saved":
return "Enregistré dans UltiDrive"
case "error":
return "Erreur d'enregistrement"
default:
return ""
}
}
export function UltidrawChrome({
backHref,
backLabel,
title,
showBack = true,
onRename,
renameDisabled = false,
shares = [],
onShareClick,
showShare = false,
showAccount = false,
saveStatus = "idle",
presenceUsers = [],
trailing,
}: {
backHref?: string
backLabel?: string
title: string
showBack?: boolean
onRename?: (next: string) => Promise<void>
renameDisabled?: boolean
shares?: DriveShare[]
onShareClick?: () => void
showShare?: boolean
showAccount?: boolean
saveStatus?: UltidrawSaveStatus
presenceUsers?: CollabPresenceUser[]
trailing?: ReactNode
}) {
const shareIcon = resolveShareButtonIcon(shares)
const statusLabel = saveStatusLabel(saveStatus)
return (
<>
<div className="flex h-12 shrink-0 items-center gap-2 border-b border-border px-3 ultidrive-editor-chrome">
{showBack && backHref ? (
<Button variant="ghost" size="sm" asChild className="shrink-0">
<Link href={backHref}>
<ArrowLeft className="mr-1 h-4 w-4" />
{backLabel ?? "Retour"}
</Link>
</Button>
) : null}
<div className="min-w-0 flex-1">
{onRename ? (
<OfficeEditorInlineTitle
value={title}
onRename={onRename}
disabled={renameDisabled}
/>
) : (
<span className="block truncate px-1.5 text-sm font-medium">{title}</span>
)}
</div>
<div className="flex shrink-0 items-center gap-3">
{presenceUsers.length > 0 ? <CollabPresenceAvatars users={presenceUsers} /> : null}
{statusLabel ? (
<span className="text-xs text-muted-foreground tabular-nums">{statusLabel}</span>
) : null}
{trailing}
{showShare ? (
<Button
type="button"
size="sm"
className={cn(
"gap-2 rounded-full border-0 px-4 shadow-none",
"bg-[#1967d2] text-white hover:bg-[#185abc] hover:text-white",
"dark:bg-[#e8eaed] dark:text-[#3c4043] dark:hover:bg-[#dadce0] dark:hover:text-[#202124]"
)}
onClick={onShareClick}
>
<ShareButtonIcon kind={shareIcon} />
Partager
</Button>
) : null}
{showAccount ? <EditorAccountButton /> : null}
</div>
</div>
{showShare ? <ShareDialog /> : null}
</>
)
}