feat: dashboard v2, esm, upgrades (#211)
* esm * wip * wip * wip * wip * wip * wip * subscription notice * wip * wip * wip * fix envs * fix: update docker build * fix * esm/types * delete dashboard :D * add patches to dockerfiles * update packages + catalogs + ts * wip * remove native libs * ts * improvements * fix redirects and fetching session * try fix favicon * fixes * fix * order and resize reportds within a dashboard * improvements * wip * added userjot to dashboard * fix * add op * wip * different cache key * improve date picker * fix table * event details loading * redo onboarding completely * fix login * fix * fix * extend session, billing and improve bars * fix * reduce price on 10M
This commit is contained in:
committed by
GitHub
parent
436e81ecc9
commit
81a7e5d62e
88
apps/start/src/components/ui/input-date-time.tsx
Normal file
88
apps/start/src/components/ui/input-date-time.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
import { pushModal } from '@/modals';
|
||||
import { format, isValid, parseISO } from 'date-fns';
|
||||
import { CalendarIcon } from 'lucide-react';
|
||||
import { type InputHTMLAttributes, useEffect, useState } from 'react';
|
||||
import { WithLabel } from '../forms/input-with-label';
|
||||
import { Input } from './input';
|
||||
|
||||
export function InputDateTime({
|
||||
value,
|
||||
onChange,
|
||||
placeholder = 'Select date and time',
|
||||
label,
|
||||
...props
|
||||
}: {
|
||||
value: string | undefined;
|
||||
onChange: (value: string) => void;
|
||||
label: string;
|
||||
} & InputHTMLAttributes<HTMLInputElement>) {
|
||||
const [internalValue, setInternalValue] = useState(value ?? '');
|
||||
|
||||
useEffect(() => {
|
||||
if (value !== internalValue) {
|
||||
setInternalValue(value ?? '');
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
// Convert string to Date for modal
|
||||
const getDateFromValue = (dateString: string): Date => {
|
||||
if (!dateString) return new Date();
|
||||
|
||||
try {
|
||||
const date = parseISO(dateString);
|
||||
return isValid(date) ? date : new Date();
|
||||
} catch {
|
||||
return new Date();
|
||||
}
|
||||
};
|
||||
|
||||
// Format date for display
|
||||
const getDisplayValue = (dateString: string): string => {
|
||||
if (!dateString) return '';
|
||||
|
||||
try {
|
||||
const date = parseISO(dateString);
|
||||
return isValid(date) ? format(date, 'MM/dd/yyyy HH:mm') : dateString;
|
||||
} catch {
|
||||
return dateString;
|
||||
}
|
||||
};
|
||||
|
||||
const handleDateTimeSelect = () => {
|
||||
pushModal('DateTimePicker', {
|
||||
initialDate: getDateFromValue(value || ''),
|
||||
title: 'Select Date & Time',
|
||||
onChange: (selectedDate: Date) => {
|
||||
const isoString = selectedDate.toISOString();
|
||||
setInternalValue(isoString);
|
||||
onChange(isoString);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<WithLabel label={label}>
|
||||
<div
|
||||
className="relative w-full cursor-pointer"
|
||||
onClick={handleDateTimeSelect}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
handleDateTimeSelect();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
{...props}
|
||||
value={getDisplayValue(value || '')}
|
||||
placeholder={placeholder}
|
||||
readOnly
|
||||
className="cursor-pointer pr-10"
|
||||
size="default"
|
||||
/>
|
||||
<div className="absolute right-4 top-1/2 -translate-y-1/2 pointer-events-none">
|
||||
<CalendarIcon className="h-4 w-4 text-muted-foreground" />
|
||||
</div>
|
||||
</div>
|
||||
</WithLabel>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user