@use('App\Services\Date')
{{--
Date Picker Blade Component
A wrapper for the Vue DatePickerComponent with Flatpickr.
Features: Auto date format conversion, Today/Clear buttons, RTL support.
USAGE:
------
Single Date:
Date Range (shows 2 months by default):
Date Range with pre-populated values:
Time Only:
DateTime:
PROPS:
------
- mode: 'single' | 'range' | 'time' | 'datetime' (default: 'single')
- name: Input name for form submission (required)
- startName: Name for start date hidden input in range mode (default: 'start_date')
- endName: Name for end date hidden input in range mode (default: 'end_date')
- value: Initial value
- placeholder: Placeholder text (default: 'yyyy-mm-dd')
- inputId: Custom input ID
- inputClass: Additional CSS classes
- required: Boolean
- disabled: Boolean
- isInvalid: Boolean - show error state
- minDate: Minimum selectable date (ISO format)
- maxDate: Maximum selectable date (ISO format)
- lang: 'en' | 'ar' (default: current locale)
- format: Custom display format (flatpickr format)
- valueFormat: Server-side date format (default: Date::rawFormat('date'))
- time24hr: Use 24-hour time format
- enableSeconds: Show seconds in time picker
- showIcon: Show calendar icon button (default: true)
- showClear: Show clear button (default: true)
- showMonths: Number of months to display (default: 2 for range, 1 for others)
- defaultToday: Boolean - if true and no value provided, defaults to today's date
FEATURES:
---------
- Auto Date Formatting: Automatically converts dates from server format to display format
- Today Button: Quickly select today's date
- Clear Button: Clear the selected date
- RTL Support: Full Arabic language and RTL layout support
- 2-Month View: Range mode shows 2 months side-by-side by default
EXAMPLES:
---------
With Icon (default):
Without Icon:
With Custom Placeholder:
Date Range with 3 months visible:
With min/max date constraints:
--}}
@props([
'mode' => 'single',
'name',
'startName' => 'start_date',
'endName' => 'end_date',
'value' => '',
'placeholder' => 'yyyy-mm-dd',
'inputId' => null,
'inputClass' => 'h-45',
'required' => false,
'disabled' => false,
'isInvalid' => false,
'minDate' => null,
'maxDate' => null,
'lang' => null,
'format' => null,
'valueFormat' => null, // Defaults to Date::rawFormat('date') internally if not provided by JS component
'time24hr' => false,
'enableSeconds' => false,
'weekNumbers' => false,
'defaultHour' => 12,
'defaultMinute' => 0,
'showIcon' => true,
'showClear' => true,
'whiteIcon' => false,
'showMonths' => null,
'defaultToday' => false,
'defaultToCurrentTime' => false,
])
@php
$resolvedLang = $lang ?? app()->getLocale();
$componentId = $inputId ?? 'datepicker-' . Str::random(8);
$defaultPlaceholder = $resolvedLang === 'ar' ? 'يوم-شهر-سنة - مثال: 20-01-2026' : 'yyyy-mm-dd - e.g. 2026-01-20';
$finalPlaceholder = $placeholder === 'yyyy-mm-dd' ? $defaultPlaceholder : $placeholder;
// Auto-convert value from server format to display format
$formattedValue = $value;
if ($mode === 'range') {
// For range mode, handle array or string values
if (is_array($value) && count($value) === 2 && $value[0] && $value[1]) {
try {
$from = Date::format($value[0], 'date');
$to = Date::format($value[1], 'date');
$formattedValue = [$from, $to];
} catch (\Exception $e) {
$formattedValue = $value;
}
} elseif (is_string($value) && !empty($value)) {
// Handle "start to end" string format
$parts = explode(' to ', $value);
if (count($parts) === 2) {
try {
$from = Date::format(trim($parts[0]), 'date');
$to = Date::format(trim($parts[1]), 'date');
$formattedValue = [$from, $to];
} catch (\Exception $e) {
$formattedValue = $value;
}
}
}
} elseif ($mode === 'single' || $mode === 'datetime') {
// For single date mode
if (!empty($value) && is_string($value)) {
try {
$formattedValue = Date::format($value, 'date');
} catch (\Exception $e) {
$formattedValue = $value;
}
} elseif (empty($value) && $defaultToday) {
// Default to today's date if defaultToday is true and no value provided
$formattedValue = Date::now('date');
}
}
@endphp