import { useState, type InputHTMLAttributes, type ReactNode, type Ref } from 'react'
import { useBlurBookingCodes } from '../../hooks/useBlurBookingCodes'
/**
* The "Blur booking codes" preference (blur_booking_codes) keeps confirmation
* codes unreadable to anyone looking at the screen until the user reaches for
* them. The pieces here carry it to every place that shows or edits a code, so
* a new surface gets the same look and the same way of revealing a code
* without reading the setting on its own.
*/
// The strength the code boxes in the bookings tabs and the day sheet use.
const BLUR_CLS = 'blur-[4px] select-none'
const joinCls = (...parts: (string | false | undefined)[]) => parts.filter(Boolean).join(' ')
type BookingCodeInputProps = Omit, 'type'> & {
ref?: Ref
}
/**
* The text field of a form that edits a booking code. While the preference is
* on, a filled field stays blurred until the pointer rests on it or it gets
* focus, so the code is still there to read and change the moment the user
* clicks, taps or tabs into it. An empty field keeps its placeholder readable.
*
* Only a class is added: the value, the handlers and the ref pass through
* untouched, so what gets saved is exactly what was typed, and there is no
* wrapper to upset the grid and flex rows the field sits in. It stays a text
* field on purpose; a password field would bring the browser's password
* manager and a different phone keyboard with it.
*/
export function BookingCodeInput({ className, ...props }: BookingCodeInputProps) {
const blur = useBlurBookingCodes()
const hidden = blur && props.value != null && props.value !== ''
return (
)
}
/**
* A booking code shown as text. With the preference off it renders the code
* and nothing around it, so the markup of the surface stays what it was.
*
* With the preference on, the code becomes a small toggle that lifts on hover
* and on click, Enter or Space, like the codes in the bookings list. Inside a
* row that is a button itself a second button is not allowed, so
* `interactive={false}` gives a plain blurred span there; the booking the row
* opens is where that code can be read.
*/
export function BlurredCode({ children, interactive = true, className }: {
children: ReactNode
interactive?: boolean
className?: string
}) {
const blur = useBlurBookingCodes()
const [revealed, setRevealed] = useState(false)
if (!blur) return <>{children}>
if (!interactive) return {children}
return (
)
}