Manager Dashboard: product reorder/bulk actions, preference sub-choices UI, expanded reports with DateInput component, waiter management updates, order detail improvements, Docker config and backend dockerignore added. Backend: table groups, auto-numbering, has_active_order flag, expanded reporting endpoints, waiter zone management, user schema updates, system router additions, table router fixes. Waiter PWA: TableDetailPage order/payment event improvements. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
80 lines
2.4 KiB
JavaScript
80 lines
2.4 KiB
JavaScript
/**
|
||
* DateInput / DateTimeInput
|
||
*
|
||
* Native date pickers display in the OS/browser locale (MM/DD/YYYY on en-US).
|
||
* These wrappers overlay the native input with a visible DD/MM/YYYY display
|
||
* while keeping the full native picker UX (click, keyboard, mobile wheel).
|
||
*
|
||
* Props mirror a plain <input>: value (YYYY-MM-DD or YYYY-MM-DDTHH:MM),
|
||
* onChange (receives the same synthetic event), className.
|
||
*/
|
||
import { useRef } from 'react'
|
||
|
||
function formatDateGR(value) {
|
||
// value is "YYYY-MM-DD"
|
||
if (!value) return ''
|
||
const [y, m, d] = value.split('-')
|
||
if (!y || !m || !d) return value
|
||
return `${d}/${m}/${y}`
|
||
}
|
||
|
||
function formatDateTimeGR(value) {
|
||
// value is "YYYY-MM-DDTHH:MM"
|
||
if (!value) return ''
|
||
const [datePart, timePart] = value.split('T')
|
||
if (!datePart) return value
|
||
const [y, m, d] = datePart.split('-')
|
||
if (!y || !m || !d) return value
|
||
return `${d}/${m}/${y}${timePart ? ' ' + timePart : ''}`
|
||
}
|
||
|
||
export function DateInput({ value, onChange, className = '', ...rest }) {
|
||
const ref = useRef(null)
|
||
|
||
return (
|
||
<div
|
||
className={`relative cursor-pointer ${className}`}
|
||
onClick={() => ref.current?.showPicker?.()}
|
||
>
|
||
{/* Visible display */}
|
||
<div className="absolute inset-0 flex items-center px-3 pointer-events-none z-10 bg-white rounded-lg text-sm text-gray-800">
|
||
{value ? formatDateGR(value) : <span className="text-gray-400">ΗΗ/ΜΜ/ΕΕΕΕ</span>}
|
||
</div>
|
||
{/* Native input — invisible but functional (provides the picker) */}
|
||
<input
|
||
ref={ref}
|
||
type="date"
|
||
value={value}
|
||
onChange={onChange}
|
||
className="opacity-0 w-full h-full absolute inset-0 cursor-pointer"
|
||
tabIndex={0}
|
||
{...rest}
|
||
/>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export function DateTimeInput({ value, onChange, className = '', ...rest }) {
|
||
const ref = useRef(null)
|
||
|
||
return (
|
||
<div
|
||
className={`relative cursor-pointer ${className}`}
|
||
onClick={() => ref.current?.showPicker?.()}
|
||
>
|
||
<div className="absolute inset-0 flex items-center px-3 pointer-events-none z-10 bg-white rounded-lg text-sm text-gray-800">
|
||
{value ? formatDateTimeGR(value) : <span className="text-gray-400">ΗΗ/ΜΜ/ΕΕΕΕ ΩΩ:ΛΛ</span>}
|
||
</div>
|
||
<input
|
||
ref={ref}
|
||
type="datetime-local"
|
||
value={value}
|
||
onChange={onChange}
|
||
className="opacity-0 w-full h-full absolute inset-0 cursor-pointer"
|
||
tabIndex={0}
|
||
{...rest}
|
||
/>
|
||
</div>
|
||
)
|
||
}
|