Initial commit: Dockerized, Postgres, CI/CD pipeline
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 3m36s
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 3m36s
This commit is contained in:
96
src/components/DateRangePicker.tsx
Normal file
96
src/components/DateRangePicker.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import React, { useRef } from 'react';
|
||||
import { Calendar } from 'lucide-react';
|
||||
import type { DateRange } from '../types';
|
||||
|
||||
interface DateRangePickerProps {
|
||||
dateRange: DateRange;
|
||||
onChange: (range: DateRange) => void;
|
||||
}
|
||||
|
||||
const DateRangePicker: React.FC<DateRangePickerProps> = ({ dateRange, onChange }) => {
|
||||
const startRef = useRef<HTMLInputElement>(null);
|
||||
const endRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const formatDateForInput = (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 formatShortDate = (date: Date) => {
|
||||
return date.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit', year: '2-digit' });
|
||||
};
|
||||
|
||||
const parseLocalDate = (value: string) => {
|
||||
if (!value) return null;
|
||||
const [year, month, day] = value.split('-');
|
||||
return new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
|
||||
};
|
||||
|
||||
const handleStartChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const newStart = parseLocalDate(e.target.value);
|
||||
if (newStart && !isNaN(newStart.getTime())) {
|
||||
onChange({ ...dateRange, start: newStart });
|
||||
}
|
||||
};
|
||||
|
||||
const handleEndChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const newEnd = parseLocalDate(e.target.value);
|
||||
if (newEnd && !isNaN(newEnd.getTime())) {
|
||||
newEnd.setHours(23, 59, 59, 999);
|
||||
onChange({ ...dateRange, end: newEnd });
|
||||
}
|
||||
};
|
||||
|
||||
const openPicker = (ref: React.RefObject<HTMLInputElement>) => {
|
||||
if (ref.current) {
|
||||
try {
|
||||
if ('showPicker' in HTMLInputElement.prototype) {
|
||||
ref.current.showPicker();
|
||||
} else {
|
||||
ref.current.focus();
|
||||
}
|
||||
} catch (e) {
|
||||
ref.current.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2 bg-dark-card border border-dark-border px-3 py-2 rounded-xl shadow-sm hover:border-brand-primary transition-colors">
|
||||
<Calendar size={16} className="text-dark-muted shrink-0" />
|
||||
<div className="flex items-center gap-2 text-sm font-medium text-dark-text">
|
||||
<div
|
||||
className="relative cursor-pointer hover:text-brand-primary transition-colors"
|
||||
onClick={() => openPicker(startRef)}
|
||||
>
|
||||
{formatShortDate(dateRange.start)}
|
||||
<input
|
||||
ref={startRef}
|
||||
type="date"
|
||||
value={formatDateForInput(dateRange.start)}
|
||||
onChange={handleStartChange}
|
||||
className="absolute opacity-0 w-0 h-0 overflow-hidden"
|
||||
/>
|
||||
</div>
|
||||
<span className="text-dark-muted font-normal text-xs">até</span>
|
||||
<div
|
||||
className="relative cursor-pointer hover:text-brand-primary transition-colors"
|
||||
onClick={() => openPicker(endRef)}
|
||||
>
|
||||
{formatShortDate(dateRange.end)}
|
||||
<input
|
||||
ref={endRef}
|
||||
type="date"
|
||||
value={formatDateForInput(dateRange.end)}
|
||||
onChange={handleEndChange}
|
||||
className="absolute opacity-0 w-0 h-0 overflow-hidden"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DateRangePicker;
|
||||
Reference in New Issue
Block a user