Final working solution: shadcn date picker with timezone fix
- Implemented shadcn/ui date picker with Czech localization - Added month/year dropdown navigation for easy date selection - Fixed critical timezone bug causing "No valid days found" error - Changed from toISOString() to local date formatting - Dates now correctly sent as 2025-01-01 instead of 2024-12-31 - Calendar auto-closes after date selection - All features tested and working: - Journey calculation with correct date ranges - "Vyplnit na web" button visible and functional - Excel export working - Backend successfully processes January 2025 data 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { DatePicker } from '@/components/ui/date-picker'
|
||||
import { Calculator, Download } from 'lucide-react'
|
||||
|
||||
interface JourneyFormProps {
|
||||
@@ -18,8 +19,8 @@ export default function JourneyForm({ onDataCalculated, setLoading, onFormDataCh
|
||||
const [formData, setFormData] = useState({
|
||||
username: '',
|
||||
password: '',
|
||||
startDate: new Date().toISOString().slice(0, 10),
|
||||
endDate: new Date().toISOString().slice(0, 10),
|
||||
startDate: new Date(),
|
||||
endDate: new Date(),
|
||||
startKm: '',
|
||||
endKm: '',
|
||||
vehicleRegistration: '4SH1148',
|
||||
@@ -31,9 +32,24 @@ export default function JourneyForm({ onDataCalculated, setLoading, onFormDataCh
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
setError('')
|
||||
|
||||
// Validate date range
|
||||
if (formData.startDate > formData.endDate) {
|
||||
setError('Datum od musí být před nebo stejný jako Datum do')
|
||||
return
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
// Format dates as YYYY-MM-DD in local timezone
|
||||
const formatLocalDate = (date: Date) => {
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
|
||||
const response = await fetch(`${API_URL}/api/calculate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -42,8 +58,8 @@ export default function JourneyForm({ onDataCalculated, setLoading, onFormDataCh
|
||||
body: JSON.stringify({
|
||||
username: formData.username,
|
||||
password: formData.password,
|
||||
start_date: formData.startDate,
|
||||
end_date: formData.endDate,
|
||||
start_date: formatLocalDate(formData.startDate),
|
||||
end_date: formatLocalDate(formData.endDate),
|
||||
start_km: parseInt(formData.startKm),
|
||||
end_km: parseInt(formData.endKm),
|
||||
vehicle_registration: formData.vehicleRegistration,
|
||||
@@ -71,6 +87,14 @@ export default function JourneyForm({ onDataCalculated, setLoading, onFormDataCh
|
||||
const handleExport = async () => {
|
||||
setLoading(true)
|
||||
try {
|
||||
// Format dates as YYYY-MM-DD in local timezone
|
||||
const formatLocalDate = (date: Date) => {
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
|
||||
const response = await fetch(`${API_URL}/api/export/excel`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -79,8 +103,8 @@ export default function JourneyForm({ onDataCalculated, setLoading, onFormDataCh
|
||||
body: JSON.stringify({
|
||||
username: formData.username,
|
||||
password: formData.password,
|
||||
start_date: formData.startDate,
|
||||
end_date: formData.endDate,
|
||||
start_date: formatLocalDate(formData.startDate),
|
||||
end_date: formatLocalDate(formData.endDate),
|
||||
start_km: parseInt(formData.startKm),
|
||||
end_km: parseInt(formData.endKm),
|
||||
vehicle_registration: formData.vehicleRegistration,
|
||||
@@ -94,7 +118,7 @@ export default function JourneyForm({ onDataCalculated, setLoading, onFormDataCh
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = `journeybook_${formData.startDate}_${formData.endDate}.xlsx`
|
||||
a.download = `journeybook_${formData.startDate.toISOString().slice(0, 10)}_${formData.endDate.toISOString().slice(0, 10)}.xlsx`
|
||||
a.click()
|
||||
} catch (err: any) {
|
||||
setError(err.message)
|
||||
@@ -138,23 +162,19 @@ export default function JourneyForm({ onDataCalculated, setLoading, onFormDataCh
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="startDate">Datum od</Label>
|
||||
<Input
|
||||
id="startDate"
|
||||
type="date"
|
||||
required
|
||||
<DatePicker
|
||||
value={formData.startDate}
|
||||
onChange={(e) => setFormData({ ...formData, startDate: e.target.value })}
|
||||
onChange={(date) => date && setFormData({ ...formData, startDate: date })}
|
||||
placeholder="Vyberte datum od"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="endDate">Datum do</Label>
|
||||
<Input
|
||||
id="endDate"
|
||||
type="date"
|
||||
required
|
||||
<DatePicker
|
||||
value={formData.endDate}
|
||||
onChange={(e) => setFormData({ ...formData, endDate: e.target.value })}
|
||||
onChange={(date) => date && setFormData({ ...formData, endDate: date })}
|
||||
placeholder="Vyberte datum do"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user