mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-20 05:56:53 +00:00
0dd07befa7
The Plan tab was the last trip tab still in the old design. It now reads like Bookings, Costs, Lists, Files and Collab, without losing a function: - Day plan: each day is a card with a head band (day tile with weather, stay and rental pills, a "+" menu for place, stay, transport, transit and note), rows with "..." menus, white badges and a white route bar. - Places column: add, search and filters in three rows, a show dropdown, category and rating filters, and a selection bar at the foot. - Place inspector, day details and the stay editor on the shared dialog frame; the place form in the editor look with the name in the head band. - Clicking a booking or transport anywhere on the plan opens the booking detail popup first; Edit leads to the editor. The popup is one host shared with the Bookings and Transports tabs. - Files and Collab dialogs, notes, polls, links and chat moved to the same frame; shared DialogShell and dialogParts hold the building blocks. - The map hover card shows the place photo and follows the theme. Every new and reworded string is translated into all locales, and a few older English leftovers (help center, cost split, import hints) with them. Phone screens keep their own look.
46 lines
1.7 KiB
TypeScript
46 lines
1.7 KiB
TypeScript
import { useState, useEffect, useRef } from 'react'
|
|
import { Tooltip } from '../shared/Tooltip'
|
|
|
|
interface EditableCatNameProps {
|
|
name: string
|
|
onRename: (newName: string) => void
|
|
/** The tooltip on the name, e.g. "Rename". */
|
|
renameLabel?: string
|
|
}
|
|
|
|
export function EditableCatName({ name, onRename, renameLabel = 'Click to rename' }: EditableCatNameProps) {
|
|
const [editing, setEditing] = useState(false)
|
|
const [value, setValue] = useState(name)
|
|
const inputRef = useRef(null)
|
|
|
|
useEffect(() => { if (editing && inputRef.current) { inputRef.current.focus(); inputRef.current.select() } }, [editing])
|
|
|
|
const save = () => {
|
|
setEditing(false)
|
|
if (value.trim() && value.trim() !== name) onRename(value.trim())
|
|
else setValue(name)
|
|
}
|
|
|
|
if (editing) {
|
|
return <input ref={inputRef} value={value} onChange={e => setValue(e.target.value)}
|
|
onBlur={save}
|
|
onKeyDown={e => {
|
|
if (e.key === 'Enter') save()
|
|
// Escape only drops the rename; the dialog around it stays open.
|
|
if (e.key === 'Escape') { e.preventDefault(); setValue(name); setEditing(false) }
|
|
}}
|
|
className="min-w-0 flex-1 rounded-[8px] border border-edge bg-surface-input px-2 py-0.5 font-semibold text-content outline-none focus:ring-2 focus:ring-[color:var(--text-primary)]"
|
|
style={{ fontSize: 'calc(13px * var(--fs-scale-body, 1))' }} />
|
|
}
|
|
|
|
return (
|
|
<Tooltip label={renameLabel}>
|
|
<button type="button" onClick={() => { setValue(name); setEditing(true) }}
|
|
className="min-w-0 flex-1 truncate py-0.5 text-left font-semibold text-content hover:underline hover:decoration-edge"
|
|
style={{ fontSize: 'calc(13px * var(--fs-scale-body, 1))' }}>
|
|
{name}
|
|
</button>
|
|
</Tooltip>
|
|
)
|
|
}
|