feat(dashboard): Upgrade to the dateTime filter UI (#2864)

UI/UX improvement to the date/time picker:

- You can now choose a custom duration
- Adds a new DateTimePicker.tsx component, using a new shadcn
Calendar.tsx component
- Clear UI separation between the 2 actions, choosing a duration or
choosing date range
- Adds new quick select options for picking a date range quickly


https://github.com/user-attachments/assets/6b59b49d-2a56-4354-ad72-d8426437e56e

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Eric Allam <ericallam@users.noreply.github.com>
This commit is contained in:
James Ritchie
2026-01-12 13:01:17 +00:00
committed by GitHub
parent 2c30c2defb
commit 768206c91b
6 changed files with 980 additions and 290 deletions
@@ -0,0 +1,126 @@
"use client";
import * as React from "react";
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/20/solid";
import { format } from "date-fns";
import { DayPicker, useDayPicker } from "react-day-picker";
import { cn } from "~/utils/cn";
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
const navButtonClass =
"size-7 rounded-[3px] bg-secondary border border-charcoal-600 text-text-bright hover:bg-charcoal-600 hover:border-charcoal-550 transition inline-flex items-center justify-center";
function CustomMonthCaption({ calendarMonth }: { calendarMonth: { date: Date } }) {
const { goToMonth, nextMonth, previousMonth } = useDayPicker();
return (
<div className="flex w-full items-center justify-between px-1">
<button
type="button"
className={navButtonClass}
disabled={!previousMonth}
onClick={() => previousMonth && goToMonth(previousMonth)}
aria-label="Go to previous month"
>
<ChevronLeftIcon className="size-4" />
</button>
<div className="flex items-center gap-2">
<select
className="rounded border border-charcoal-600 bg-charcoal-750 px-2 py-1 text-sm text-text-bright focus:border-charcoal-500 focus:outline-none"
value={calendarMonth.date.getMonth()}
onChange={(e) => {
const newDate = new Date(calendarMonth.date);
newDate.setMonth(parseInt(e.target.value));
goToMonth(newDate);
}}
>
{Array.from({ length: 12 }, (_, i) => (
<option key={i} value={i}>
{format(new Date(2000, i), "MMM")}
</option>
))}
</select>
<select
className="rounded border border-charcoal-600 bg-charcoal-750 px-2 py-1 text-sm text-text-bright focus:border-charcoal-500 focus:outline-none"
value={calendarMonth.date.getFullYear()}
onChange={(e) => {
const newDate = new Date(calendarMonth.date);
newDate.setFullYear(parseInt(e.target.value));
goToMonth(newDate);
}}
>
{Array.from({ length: 100 }, (_, i) => {
const year = new Date().getFullYear() - 50 + i;
return (
<option key={year} value={year}>
{year}
</option>
);
})}
</select>
</div>
<button
type="button"
className={navButtonClass}
disabled={!nextMonth}
onClick={() => nextMonth && goToMonth(nextMonth)}
aria-label="Go to next month"
>
<ChevronRightIcon className="size-4" />
</button>
</div>
);
}
export function Calendar({
className,
classNames,
showOutsideDays = true,
...props
}: CalendarProps) {
return (
<DayPicker
showOutsideDays={showOutsideDays}
weekStartsOn={1}
className={cn("p-3", className)}
classNames={{
months: "flex flex-col sm:flex-row gap-2",
month: "flex flex-col gap-4",
month_caption: "flex justify-center pt-1 relative items-center w-full",
caption_label: "sr-only",
nav: "hidden",
month_grid: "w-full border-collapse",
weekdays: "flex",
weekday: "text-text-dimmed rounded-md w-8 font-normal text-[0.8rem]",
week: "flex w-full mt-2",
day: "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-charcoal-700 [&:has([aria-selected].day-outside)]:bg-charcoal-700/50 [&:has([aria-selected].day-range-end)]:rounded-r-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md",
day_button: cn(
"size-8 p-0 font-normal text-text-bright rounded-md",
"hover:bg-charcoal-700 hover:text-text-bright",
"focus:bg-charcoal-700 focus:text-text-bright focus:outline-none",
"aria-selected:opacity-100"
),
range_start: "day-range-start rounded-l-md",
range_end: "day-range-end rounded-r-md",
selected:
"bg-indigo-600 text-text-bright hover:bg-indigo-600 hover:text-text-bright focus:bg-indigo-600 focus:text-text-bright rounded-md",
today: "bg-charcoal-700 text-text-bright rounded-md",
outside:
"day-outside text-text-dimmed opacity-50 aria-selected:bg-charcoal-700/50 aria-selected:text-text-dimmed aria-selected:opacity-30",
disabled: "text-text-dimmed opacity-50",
range_middle: "aria-selected:bg-charcoal-700 aria-selected:text-text-bright",
hidden: "invisible",
dropdowns: "flex gap-2 items-center justify-center",
dropdown:
"bg-charcoal-750 border border-charcoal-600 rounded px-2 py-1 text-sm text-text-bright focus:outline-none focus:border-charcoal-500",
...classNames,
}}
components={{
MonthCaption: CustomMonthCaption,
}}
{...props}
/>
);
}
Calendar.displayName = "Calendar";
@@ -1,9 +1,11 @@
import { BellAlertIcon, XMarkIcon } from "@heroicons/react/20/solid";
import { CalendarDateTime, createCalendar } from "@internationalized/date";
import { useDateField, useDateSegment } from "@react-aria/datepicker";
import type { DateFieldState, DateSegment } from "@react-stately/datepicker";
import { useDateFieldState } from "@react-stately/datepicker";
import { Granularity } from "@react-types/datepicker";
import {
useDateFieldState,
type DateFieldState,
type DateSegment,
} from "@react-stately/datepicker";
import { type Granularity } from "@react-types/datepicker";
import { useEffect, useRef, useState } from "react";
import { cn } from "~/utils/cn";
import { Button } from "./Buttons";
@@ -0,0 +1,145 @@
"use client";
import * as React from "react";
import { ChevronUpDownIcon } from "@heroicons/react/20/solid";
import { format } from "date-fns";
import { Calendar } from "./Calendar";
import { Popover, PopoverContent, PopoverTrigger } from "./Popover";
import { Button } from "./Buttons";
import { cn } from "~/utils/cn";
import { SimpleTooltip } from "./Tooltip";
import { XIcon } from "lucide-react";
type DateTimePickerProps = {
label: string;
value?: Date;
onChange?: (date: Date | undefined) => void;
showSeconds?: boolean;
showNowButton?: boolean;
showClearButton?: boolean;
showInlineLabel?: boolean;
className?: string;
};
export function DateTimePicker({
label,
value,
onChange,
showSeconds = true,
showNowButton = false,
showClearButton = false,
showInlineLabel = false,
className,
}: DateTimePickerProps) {
const [open, setOpen] = React.useState(false);
// Extract time parts from value
const hours = value ? value.getHours().toString().padStart(2, "0") : "";
const minutes = value ? value.getMinutes().toString().padStart(2, "0") : "";
const seconds = value ? value.getSeconds().toString().padStart(2, "0") : "";
const timeValue = showSeconds ? `${hours}:${minutes}:${seconds}` : `${hours}:${minutes}`;
const handleDateSelect = (date: Date | undefined) => {
if (date) {
// Preserve the time from the current value if it exists
if (value) {
date.setHours(value.getHours());
date.setMinutes(value.getMinutes());
date.setSeconds(value.getSeconds());
}
onChange?.(date);
} else {
onChange?.(undefined);
}
setOpen(false);
};
const handleTimeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const timeString = e.target.value;
if (!timeString) return;
const [h, m, s] = timeString.split(":").map(Number);
const newDate = value ? new Date(value) : new Date();
newDate.setHours(h || 0);
newDate.setMinutes(m || 0);
newDate.setSeconds(s || 0);
onChange?.(newDate);
};
const handleNowClick = () => {
onChange?.(new Date());
};
const handleClearClick = () => {
onChange?.(undefined);
};
return (
<div className={cn("flex items-center gap-2", className)}>
{showInlineLabel && (
<span className="w-6 shrink-0 text-right text-xxs text-charcoal-500">{label}</span>
)}
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<button
type="button"
className={cn(
"flex h-[1.8rem] w-full items-center justify-between gap-2 whitespace-nowrap rounded border border-charcoal-650 bg-charcoal-750 px-2 text-xs tabular-nums transition hover:border-charcoal-600",
value ? "text-text-bright" : "text-text-dimmed"
)}
>
{value ? format(value, "yyyy/MM/dd") : "Select date"}
<ChevronUpDownIcon className="size-3.5 text-text-dimmed" />
</button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
selected={value}
onSelect={handleDateSelect}
captionLayout="dropdown"
/>
</PopoverContent>
</Popover>
<input
type="time"
step={showSeconds ? "1" : "60"}
value={value ? timeValue : ""}
onChange={handleTimeChange}
className={cn(
"h-[1.8rem] rounded border border-charcoal-650 bg-charcoal-750 px-2 text-xs tabular-nums transition hover:border-charcoal-600",
value ? "text-text-bright" : "text-text-dimmed",
"focus:border-charcoal-500 focus:outline-none",
"[&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none"
)}
aria-label={`${label} time`}
/>
{showNowButton && (
<Button
type="button"
variant="secondary/small"
className="h-[1.8rem]"
onClick={handleNowClick}
>
Now
</Button>
)}
{showClearButton && (
<SimpleTooltip
button={
<button
type="button"
className="flex h-[1.8rem] items-center justify-center px-1 text-text-dimmed transition hover:text-text-bright"
onClick={handleClearClick}
>
<XIcon className="size-3.5" />
</button>
}
content="Clear"
disableHoverableContent
asChild
/>
)}
</div>
);
}
@@ -1,16 +1,33 @@
import * as Ariakit from "@ariakit/react";
import type { RuntimeEnvironment } from "@trigger.dev/database";
import {
startOfDay,
endOfDay,
startOfWeek,
endOfWeek,
startOfMonth,
endOfMonth,
startOfYear,
subDays,
subWeeks,
subMonths,
previousSaturday,
isSaturday,
isSunday,
} from "date-fns";
import parse from "parse-duration";
import type { ReactNode } from "react";
import { startTransition, useCallback, useState } from "react";
import { startTransition, useCallback, useEffect, useState, type ReactNode } from "react";
import { AppliedFilter } from "~/components/primitives/AppliedFilter";
import { DateField } from "~/components/primitives/DateField";
import { DateTimePicker } from "~/components/primitives/DateTimePicker";
import { DateTime } from "~/components/primitives/DateTime";
import { Label } from "~/components/primitives/Label";
import { RadioButtonCircle } from "~/components/primitives/RadioButton";
import { ComboboxProvider, SelectPopover, SelectProvider } from "~/components/primitives/Select";
import { useSearchParams } from "~/hooks/useSearchParam";
import { cn } from "~/utils/cn";
import { Button } from "../../primitives/Buttons";
import { filterIcon } from "./RunFilters";
import { Paragraph } from "~/components/primitives/Paragraph";
export type DisplayableEnvironment = Pick<RuntimeEnvironment, "type" | "id"> & {
userName?: string;
@@ -90,13 +107,28 @@ const timePeriods = [
value: "30d",
},
{
label: "1 year",
value: "365d",
label: "90 days",
value: "90d",
},
];
const defaultPeriod = "7d";
const defaultPeriodMs = parse(defaultPeriod);
const timeUnits = [
{ label: "minutes", value: "m", singular: "minute", shortLabel: "mins" },
{ label: "hours", value: "h", singular: "hour", shortLabel: "hours" },
{ label: "days", value: "d", singular: "day", shortLabel: "days" },
];
// Parse a period string (e.g., "90m", "2h", "7d") into value and unit
function parsePeriodString(period: string): { value: number; unit: string } | null {
const match = period.match(/^(\d+)([mhd])$/);
if (match) {
return { value: parseInt(match[1], 10), unit: match[2] };
}
return null;
}
const DEFAULT_PERIOD = "7d";
const defaultPeriodMs = parse(DEFAULT_PERIOD);
if (!defaultPeriodMs) {
throw new Error("Invalid default period");
}
@@ -107,10 +139,12 @@ export const timeFilters = ({
period,
from,
to,
defaultPeriod = DEFAULT_PERIOD,
}: {
period?: string;
from?: string | number;
to?: string | number;
defaultPeriod?: string;
}): {
period?: string;
from?: Date;
@@ -166,18 +200,40 @@ export function timeFilterRenderValues({
from,
to,
period,
defaultPeriod = DEFAULT_PERIOD,
}: {
from?: Date;
to?: Date;
period?: string;
defaultPeriod?: string;
}) {
const rangeType: TimeRangeType = from && to ? "range" : from ? "from" : to ? "to" : "period";
let valueLabel: ReactNode;
switch (rangeType) {
case "period":
valueLabel = timePeriods.find((t) => t.value === period)?.label ?? period ?? defaultPeriod;
case "period": {
// First check if it's a preset period
const preset = timePeriods.find((t) => t.value === period);
if (preset) {
valueLabel = preset.label;
} else if (period) {
// Parse custom period and format nicely (e.g., "90m" -> "90 mins")
const parsed = parsePeriodString(period);
if (parsed) {
const unit = timeUnits.find((u) => u.value === parsed.unit);
if (unit) {
valueLabel = `${parsed.value} ${parsed.value === 1 ? unit.singular : unit.label}`;
} else {
valueLabel = period;
}
} else {
valueLabel = period;
}
} else {
valueLabel = defaultPeriod;
}
break;
}
case "range":
valueLabel = (
<span>
@@ -237,38 +293,87 @@ export function TimeFilter() {
);
}
// Get initial custom duration state from a period string
function getInitialCustomDuration(period?: string): { value: string; unit: string } {
if (period) {
const parsed = parsePeriodString(period);
if (parsed) {
return { value: parsed.value.toString(), unit: parsed.unit };
}
}
return { value: "", unit: "m" };
}
export function TimeDropdown({
trigger,
period,
from,
to,
defaultPeriod = DEFAULT_PERIOD,
}: {
trigger: ReactNode;
period?: string;
from?: Date;
to?: Date;
defaultPeriod?: string;
}) {
const [open, setOpen] = useState<boolean | undefined>();
const { replace } = useSearchParams();
const [fromValue, setFromValue] = useState(from);
const [toValue, setToValue] = useState(to);
const apply = useCallback(() => {
replace({
period: undefined,
cursor: undefined,
direction: undefined,
from: fromValue?.getTime().toString(),
to: toValue?.getTime().toString(),
});
// Section selection state: "duration" or "dateRange"
type SectionType = "duration" | "dateRange";
const initialSection: SectionType = from || to ? "dateRange" : "duration";
const [activeSection, setActiveSection] = useState<SectionType>(initialSection);
const [validationError, setValidationError] = useState<string | null>(null);
const [selectedQuickDate, setSelectedQuickDate] = useState<string | null>(null);
setOpen(false);
}, [fromValue, toValue, replace]);
// Selection state: preset value or "custom"
const initialCustom = getInitialCustomDuration(period);
const isInitialCustom =
period && !timePeriods.some((p) => p.value === period) && initialCustom.value !== "";
const [selectedPeriod, setSelectedPeriod] = useState<string>(
isInitialCustom ? "custom" : period ?? defaultPeriod
);
// Custom duration state
const [customValue, setCustomValue] = useState(initialCustom.value);
const [customUnit, setCustomUnit] = useState(initialCustom.unit);
// Sync state when props change
useEffect(() => {
const parsed = getInitialCustomDuration(period);
setCustomValue(parsed.value);
setCustomUnit(parsed.unit);
const isCustom = period && !timePeriods.some((p) => p.value === period) && parsed.value !== "";
setSelectedPeriod(isCustom ? "custom" : period ?? defaultPeriod);
setActiveSection(from || to ? "dateRange" : "duration");
}, [period, from, to, defaultPeriod]);
const isCustomDurationValid = (() => {
const value = parseInt(customValue, 10);
return !isNaN(value) && value > 0;
})();
const applySelection = useCallback(() => {
setValidationError(null);
if (activeSection === "duration") {
// Validate custom duration
if (selectedPeriod === "custom" && !isCustomDurationValid) {
setValidationError("Please enter a valid custom duration");
return;
}
let periodToApply = selectedPeriod;
if (selectedPeriod === "custom") {
periodToApply = `${customValue}${customUnit}`;
}
const handlePeriodClick = useCallback(
(period: string) => {
replace({
period,
period: periodToApply,
cursor: undefined,
direction: undefined,
from: undefined,
@@ -277,11 +382,39 @@ export function TimeDropdown({
setFromValue(undefined);
setToValue(undefined);
setOpen(false);
} else {
// Validate date range
if (!fromValue && !toValue) {
setValidationError("Please specify at least one date");
return;
}
if (fromValue && toValue && fromValue > toValue) {
setValidationError("From date must be before To date");
return;
}
replace({
period: undefined,
cursor: undefined,
direction: undefined,
from: fromValue?.getTime().toString(),
to: toValue?.getTime().toString(),
});
setOpen(false);
},
[replace]
);
}
}, [
activeSection,
selectedPeriod,
isCustomDurationValid,
customValue,
customUnit,
fromValue,
toValue,
replace,
]);
return (
<SelectProvider virtualFocus={true} open={open} setOpen={setOpen}>
@@ -292,92 +425,340 @@ export function TimeDropdown({
return true;
}}
>
<div className="flex flex-col gap-6 p-3">
<div className="flex flex-col gap-1">
<Label>Runs created in the last</Label>
<div className="grid grid-cols-4 gap-2">
{timePeriods.map((p) => (
<Button
key={p.value}
variant="secondary/small"
className={
p.value === period
? "border-indigo-500 group-hover/button:border-indigo-500"
: undefined
}
onClick={(e) => {
e.preventDefault();
handlePeriodClick(p.value);
}}
fullWidth
type="button"
<div className="flex flex-col gap-4 p-3">
{/* Duration section */}
<div
onClick={() => {
setActiveSection("duration");
setValidationError(null);
setSelectedQuickDate(null);
}}
className="flex cursor-pointer gap-3 rounded-md pb-3"
>
<RadioButtonCircle checked={activeSection === "duration"} />
<div className="flex flex-1 flex-col gap-1">
<Label
className={cn(
"mb-2 transition-colors",
activeSection === "duration" && "text-indigo-500"
)}
>
Runs created in the last
</Label>
<div className="grid grid-cols-4 gap-2">
{/* Custom duration row */}
<div
className={cn(
"col-span-4 flex h-[1.8rem] w-full items-center gap-2 rounded border bg-charcoal-750 py-0.5 pl-0 pr-2 transition-colors",
activeSection === "duration" && selectedPeriod === "custom"
? "border-indigo-500 "
: "border-charcoal-650 hover:border-charcoal-600",
validationError &&
activeSection === "duration" &&
selectedPeriod === "custom" &&
"border-error"
)}
onClick={(e) => e.stopPropagation()}
>
{p.label}
</Button>
))}
<input
type="number"
min="1"
step="1"
placeholder="Custom"
value={customValue}
autoFocus
onChange={(e) => {
setCustomValue(e.target.value);
setSelectedPeriod("custom");
setActiveSection("duration");
setValidationError(null);
}}
onFocus={() => {
setSelectedPeriod("custom");
setActiveSection("duration");
setValidationError(null);
}}
className="h-full w-full translate-y-px border-none bg-transparent py-0 pl-2 pr-0 text-xs leading-none text-text-bright outline-none placeholder:text-text-dimmed focus:outline-none focus:ring-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
/>
<div className="flex items-center gap-2">
{timeUnits.map((unit) => (
<button
key={unit.value}
type="button"
onClick={(e) => {
e.stopPropagation();
setCustomUnit(unit.value);
setSelectedPeriod("custom");
setActiveSection("duration");
setValidationError(null);
}}
className={cn(
"text-xs transition-colors",
customUnit === unit.value
? "text-indigo-500"
: "text-text-dimmed hover:text-text-bright"
)}
>
{unit.shortLabel}
</button>
))}
</div>
</div>
{timePeriods.map((p) => {
const parsed = parsePeriodString(p.value);
return (
<Button
key={p.value}
variant="secondary/small"
className={
activeSection === "duration" && p.value === selectedPeriod
? "border-indigo-500 group-hover/button:border-indigo-500"
: undefined
}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
setActiveSection("duration");
setSelectedPeriod(p.value);
if (parsed) {
setCustomValue(parsed.value.toString());
setCustomUnit(parsed.unit);
}
setValidationError(null);
}}
fullWidth
type="button"
>
{p.label}
</Button>
);
})}
</div>
{validationError && activeSection === "duration" && selectedPeriod === "custom" && (
<p className="mt-1 text-xs text-error">{validationError}</p>
)}
</div>
</div>
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-1">
<Label>
From <span className="text-text-dimmed">(local time)</span>
</Label>
<DateField
label="From time"
defaultValue={fromValue}
onValueChange={setFromValue}
granularity="second"
showNowButton
showClearButton
variant="small"
/>
</div>
<div className="flex flex-col gap-1">
<Label>
To <span className="text-text-dimmed">(local time)</span>
</Label>
<DateField
label="To time"
defaultValue={toValue}
onValueChange={setToValue}
granularity="second"
showNowButton
showClearButton
variant="small"
/>
</div>
<div className="flex justify-between gap-1 border-t border-grid-bright pt-3">
<Button
variant="tertiary/small"
onClick={(e) => {
e.preventDefault();
setFromValue(from);
setToValue(to);
setOpen(false);
}}
type="button"
{/* Date range section */}
<div
onClick={() => {
setActiveSection("dateRange");
setValidationError(null);
}}
className="flex cursor-pointer gap-3"
>
<RadioButtonCircle checked={activeSection === "dateRange"} />
<div className="flex flex-1 flex-col">
<Label
className={cn(
"mb-3 transition-colors",
activeSection === "dateRange" && "text-indigo-500"
)}
>
Cancel
</Button>
<Button
variant="secondary/small"
shortcut={{
modifiers: ["mod"],
key: "Enter",
enabledOnInputElements: true,
}}
disabled={!fromValue && !toValue}
onClick={(e) => {
e.preventDefault();
apply();
}}
type="button"
>
Apply
</Button>
Or specify exact time range{" "}
<span
className={cn(
"transition-colors",
activeSection === "dateRange" ? "text-indigo-500" : "text-text-dimmed"
)}
>
(in local time)
</span>
</Label>
<div className="-ml-8 mb-2" onClick={(e) => e.stopPropagation()}>
<DateTimePicker
label="From"
value={fromValue}
onChange={(value) => {
setFromValue(value);
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate(null);
}}
showSeconds
showNowButton
showClearButton
showInlineLabel
/>
</div>
<div onClick={(e) => e.stopPropagation()} className="-ml-8">
<DateTimePicker
label="To"
value={toValue}
onChange={(value) => {
setToValue(value);
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate(null);
}}
showSeconds
showNowButton
showClearButton
showInlineLabel
/>
</div>
{/* Quick select date ranges */}
<div className="mt-2 grid grid-cols-3 gap-2" onClick={(e) => e.stopPropagation()}>
<QuickDateButton
label="Yesterday"
isActive={selectedQuickDate === "yesterday"}
onClick={() => {
const yesterday = subDays(new Date(), 1);
setFromValue(startOfDay(yesterday));
setToValue(endOfDay(yesterday));
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate("yesterday");
}}
/>
<QuickDateButton
label="Today"
isActive={selectedQuickDate === "today"}
onClick={() => {
const today = new Date();
setFromValue(startOfDay(today));
setToValue(today);
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate("today");
}}
/>
<QuickDateButton
label="This week"
isActive={selectedQuickDate === "thisWeek"}
onClick={() => {
const now = new Date();
setFromValue(startOfWeek(now, { weekStartsOn: 1 }));
setToValue(now);
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate("thisWeek");
}}
/>
<QuickDateButton
label="Last weekend"
isActive={selectedQuickDate === "lastWeekend"}
onClick={() => {
const now = new Date();
let saturday: Date;
if (isSaturday(now)) {
saturday = subDays(now, 7);
} else if (isSunday(now)) {
saturday = subDays(now, 8);
} else {
saturday = previousSaturday(now);
}
const sunday = endOfDay(subDays(saturday, -1));
setFromValue(startOfDay(saturday));
setToValue(sunday);
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate("lastWeekend");
}}
/>
<QuickDateButton
label="Last week"
isActive={selectedQuickDate === "lastWeek"}
onClick={() => {
const lastWeek = subWeeks(new Date(), 1);
setFromValue(startOfWeek(lastWeek, { weekStartsOn: 1 }));
setToValue(endOfWeek(lastWeek, { weekStartsOn: 1 }));
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate("lastWeek");
}}
/>
<QuickDateButton
label="Last weekdays"
isActive={selectedQuickDate === "lastWeekdays"}
onClick={() => {
const lastWeek = subWeeks(new Date(), 1);
const monday = startOfWeek(lastWeek, { weekStartsOn: 1 });
const friday = endOfDay(subDays(monday, -4)); // Monday + 4 days = Friday
setFromValue(startOfDay(monday));
setToValue(friday);
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate("lastWeekdays");
}}
/>
<QuickDateButton
label="Last month"
isActive={selectedQuickDate === "lastMonth"}
onClick={() => {
const lastMonth = subMonths(new Date(), 1);
setFromValue(startOfMonth(lastMonth));
setToValue(endOfMonth(lastMonth));
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate("lastMonth");
}}
/>
<QuickDateButton
label="This month"
isActive={selectedQuickDate === "thisMonth"}
onClick={() => {
const now = new Date();
setFromValue(startOfMonth(now));
setToValue(now);
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate("thisMonth");
}}
/>
<QuickDateButton
label="Year to date"
isActive={selectedQuickDate === "yearToDate"}
onClick={() => {
const now = new Date();
setFromValue(startOfYear(now));
setToValue(now);
setActiveSection("dateRange");
setValidationError(null);
setSelectedQuickDate("yearToDate");
}}
/>
</div>
{validationError && activeSection === "dateRange" && (
<Paragraph variant="extra-small" className="mt-2 text-error">
{validationError}
</Paragraph>
)}
</div>
</div>
{/* Action buttons */}
<div className="flex justify-between gap-1 border-t border-grid-bright px-0 pt-3">
<Button
variant="tertiary/small"
onClick={(e) => {
e.preventDefault();
setFromValue(from);
setToValue(to);
setValidationError(null);
setOpen(false);
}}
type="button"
>
Cancel
</Button>
<Button
variant="primary/small"
shortcut={{
modifiers: ["mod"],
key: "Enter",
enabledOnInputElements: true,
}}
onClick={(e) => {
e.preventDefault();
applySelection();
}}
type="button"
>
Apply
</Button>
</div>
</div>
</SelectPopover>
</SelectProvider>
@@ -407,3 +788,25 @@ export function dateFromString(value: string | undefined | null): Date | undefin
return new Date(value);
}
function QuickDateButton({
label,
onClick,
isActive,
}: {
label: string;
onClick: () => void;
isActive?: boolean;
}) {
return (
<Button
type="button"
variant="secondary/small"
onClick={onClick}
fullWidth
className={isActive ? "border-indigo-500 group-hover/button:border-indigo-500" : undefined}
>
{label}
</Button>
);
}
+2
View File
@@ -139,6 +139,7 @@
"cronstrue": "^2.21.0",
"cross-env": "^7.0.3",
"cuid": "^2.1.8",
"date-fns": "^4.1.0",
"dompurify": "^3.2.6",
"dotenv": "^16.4.5",
"effect": "^3.11.7",
@@ -180,6 +181,7 @@
"react": "^18.2.0",
"react-aria": "^3.31.1",
"react-collapse": "^5.1.1",
"react-day-picker": "^9.13.0",
"react-dom": "^18.2.0",
"react-hotkeys-hook": "^4.4.1",
"react-popper": "^2.3.0",
+194 -182
View File
@@ -431,31 +431,31 @@ importers:
version: 3.7.1(react@18.2.0)
'@remix-run/express':
specifier: 2.1.0
version: 2.1.0(express@4.20.0)(typescript@5.5.4)
version: 2.1.0(express@4.20.0)(typescript@5.9.3)
'@remix-run/node':
specifier: 2.1.0
version: 2.1.0(typescript@5.5.4)
version: 2.1.0(typescript@5.9.3)
'@remix-run/react':
specifier: 2.1.0
version: 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4)
version: 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3)
'@remix-run/router':
specifier: ^1.15.3
version: 1.15.3
'@remix-run/serve':
specifier: 2.1.0
version: 2.1.0(typescript@5.5.4)
version: 2.1.0(typescript@5.9.3)
'@remix-run/server-runtime':
specifier: 2.1.0
version: 2.1.0(typescript@5.5.4)
version: 2.1.0(typescript@5.9.3)
'@remix-run/v1-meta':
specifier: ^0.1.3
version: 0.1.3(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
version: 0.1.3(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))
'@s2-dev/streamstore':
specifier: ^0.17.2
version: 0.17.3(typescript@5.5.4)
version: 0.17.3(typescript@5.9.3)
'@sentry/remix':
specifier: 9.46.0
version: 9.46.0(patch_hash=146126b032581925294aaed63ab53ce3f5e0356a755f1763d7a9a76b9846943b)(@remix-run/node@2.1.0(typescript@5.5.4))(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(encoding@0.1.13)(react@18.2.0)
version: 9.46.0(patch_hash=146126b032581925294aaed63ab53ce3f5e0356a755f1763d7a9a76b9846943b)(@remix-run/node@2.1.0(typescript@5.9.3))(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(encoding@0.1.13)(react@18.2.0)
'@slack/web-api':
specifier: 7.9.1
version: 7.9.1
@@ -524,7 +524,7 @@ importers:
version: 1.0.18
class-variance-authority:
specifier: ^0.5.2
version: 0.5.2(typescript@5.5.4)
version: 0.5.2(typescript@5.9.3)
clsx:
specifier: ^1.2.1
version: 1.2.1
@@ -546,6 +546,9 @@ importers:
cuid:
specifier: ^2.1.8
version: 2.1.8
date-fns:
specifier: ^4.1.0
version: 4.1.0
dompurify:
specifier: ^3.2.6
version: 3.2.6
@@ -572,7 +575,7 @@ importers:
version: 10.12.11(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
graphile-worker:
specifier: 0.16.6
version: 0.16.6(patch_hash=798129c99ed02177430fc90a1fdef800ec94e5fd1d491b931297dc52f4c98ab1)(typescript@5.5.4)
version: 0.16.6(patch_hash=798129c99ed02177430fc90a1fdef800ec94e5fd1d491b931297dc52f4c98ab1)(typescript@5.9.3)
humanize-duration:
specifier: ^3.27.3
version: 3.27.3
@@ -669,6 +672,9 @@ importers:
react-collapse:
specifier: ^5.1.1
version: 5.1.1(react@18.2.0)
react-day-picker:
specifier: ^9.13.0
version: 9.13.0(react@18.2.0)
react-dom:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
@@ -698,22 +704,22 @@ importers:
version: 2.0.1
remix-auth:
specifier: ^3.6.0
version: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
version: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))
remix-auth-email-link:
specifier: 2.0.2
version: 2.0.2(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
version: 2.0.2(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)))
remix-auth-github:
specifier: ^1.6.0
version: 1.6.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
version: 1.6.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)))
remix-auth-google:
specifier: ^2.0.0
version: 2.0.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
version: 2.0.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)))
remix-typedjson:
specifier: 0.3.1
version: 0.3.1(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(react@18.2.0)
version: 0.3.1(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(react@18.2.0)
remix-utils:
specifier: ^7.7.0
version: 7.7.0(@remix-run/node@2.1.0(typescript@5.5.4))(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/router@1.15.3)(crypto-js@4.2.0)(intl-parse-accept-language@1.0.0)(react@18.2.0)(zod@3.25.76)
version: 7.7.0(@remix-run/node@2.1.0(typescript@5.9.3))(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/router@1.15.3)(crypto-js@4.2.0)(intl-parse-accept-language@1.0.0)(react@18.2.0)(zod@3.25.76)
seedrandom:
specifier: ^3.0.5
version: 3.0.5
@@ -798,13 +804,13 @@ importers:
version: link:../../internal-packages/testcontainers
'@remix-run/dev':
specifier: 2.1.0
version: 2.1.0(@remix-run/serve@2.1.0(typescript@5.5.4))(@types/node@22.13.9)(bufferutil@4.0.9)(encoding@0.1.13)(lightningcss@1.29.2)(terser@5.44.1)(typescript@5.5.4)
version: 2.1.0(@remix-run/serve@2.1.0(typescript@5.9.3))(@types/node@22.13.9)(bufferutil@4.0.9)(encoding@0.1.13)(lightningcss@1.29.2)(terser@5.44.1)(typescript@5.9.3)
'@remix-run/eslint-config':
specifier: 2.1.0
version: 2.1.0(eslint@8.31.0)(react@18.2.0)(typescript@5.5.4)
version: 2.1.0(eslint@8.31.0)(react@18.2.0)(typescript@5.9.3)
'@remix-run/testing':
specifier: ^2.1.0
version: 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4)
version: 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3)
'@sentry/cli':
specifier: 2.50.2
version: 2.50.2(encoding@0.1.13)
@@ -903,10 +909,10 @@ importers:
version: 8.5.4
'@typescript-eslint/eslint-plugin':
specifier: ^5.59.6
version: 5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint@8.31.0)(typescript@5.5.4)
version: 5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint@8.31.0)(typescript@5.9.3)
'@typescript-eslint/parser':
specifier: ^5.59.6
version: 5.59.6(eslint@8.31.0)(typescript@5.5.4)
version: 5.59.6(eslint@8.31.0)(typescript@5.9.3)
autoevals:
specifier: ^0.0.130
version: 0.0.130(encoding@0.1.13)(ws@8.12.0(bufferutil@4.0.9))
@@ -933,7 +939,7 @@ importers:
version: 8.6.0(eslint@8.31.0)
eslint-plugin-import:
specifier: ^2.29.1
version: 2.29.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0)
version: 2.29.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0)
eslint-plugin-react-hooks:
specifier: ^4.6.2
version: 4.6.2(eslint@8.31.0)
@@ -951,7 +957,7 @@ importers:
version: 16.0.1(postcss@8.5.6)
postcss-loader:
specifier: ^8.1.1
version: 8.1.1(postcss@8.5.6)(typescript@5.5.4)(webpack@5.102.1(@swc/core@1.3.26)(esbuild@0.15.18))
version: 8.1.1(postcss@8.5.6)(typescript@5.9.3)(webpack@5.102.1(@swc/core@1.3.26)(esbuild@0.15.18))
prettier:
specifier: ^2.8.8
version: 2.8.8
@@ -984,7 +990,7 @@ importers:
version: 4.20.6
vite-tsconfig-paths:
specifier: ^4.0.5
version: 4.0.5(typescript@5.5.4)
version: 4.0.5(typescript@5.9.3)
docs: {}
@@ -1072,7 +1078,7 @@ importers:
version: 18.3.1
react-email:
specifier: ^2.1.1
version: 2.1.2(@opentelemetry/api@1.9.0)(@swc/helpers@0.5.15)(bufferutil@4.0.9)(eslint@8.31.0)
version: 2.1.2(@opentelemetry/api@1.9.0)(@swc/helpers@0.5.15)(eslint@8.31.0)
resend:
specifier: ^3.2.0
version: 3.2.0
@@ -1673,7 +1679,7 @@ importers:
version: 1.36.0
'@s2-dev/streamstore':
specifier: 0.17.3
version: 0.17.3(typescript@5.5.4)
version: 0.17.3(typescript@5.9.3)
dequal:
specifier: ^2.0.3
version: 2.0.3
@@ -1749,7 +1755,7 @@ importers:
version: 4.0.14
ai:
specifier: ^3.4.33
version: 3.4.33(openai@4.97.0(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9))(zod@3.25.76))(react@19.1.0)(sswr@2.1.0(svelte@5.43.6))(svelte@5.43.6)(vue@3.5.24(typescript@5.5.4))(zod@3.25.76)
version: 3.4.33(openai@4.97.0(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9))(zod@3.25.76))(react@19.1.0)(sswr@2.1.0(svelte@5.43.6))(svelte@5.43.6)(vue@3.5.24(typescript@5.9.3))(zod@3.25.76)
defu:
specifier: ^6.1.4
version: 6.1.4
@@ -1761,7 +1767,7 @@ importers:
version: 3.0.2
ts-essentials:
specifier: 10.0.1
version: 10.0.1(typescript@5.5.4)
version: 10.0.1(typescript@5.9.3)
tshy:
specifier: ^3.0.2
version: 3.0.2
@@ -4077,6 +4083,9 @@ packages:
peerDependencies:
'@bufbuild/protobuf': ^2.2.0
'@date-fns/tz@1.4.1':
resolution: {integrity: sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==}
'@depot/cli-darwin-arm64@0.0.1-cli.2.80.0':
resolution: {integrity: sha512-H7tQ0zWXVmdYXGFvt3d/v5fmquMlMM1I9JC8C2yiBZ9En9a20hzSbKoiym92RtcfqjKQFvhXL0DT6vQmJ8bgQA==}
engines: {node: '>=14'}
@@ -12559,6 +12568,9 @@ packages:
dataloader@1.4.0:
resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==}
date-fns-jalali@4.1.0-0:
resolution: {integrity: sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==}
date-fns@4.1.0:
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
@@ -17371,6 +17383,12 @@ packages:
peerDependencies:
react: '>=16.3.0'
react-day-picker@9.13.0:
resolution: {integrity: sha512-euzj5Hlq+lOHqI53NiuNhCP8HWgsPf/bBAVijR50hNaY1XwjKjShAnIe8jm8RD2W9IJUvihDIZ+KrmqfFzNhFQ==}
engines: {node: '>=18'}
peerDependencies:
react: '>=16.8.0'
react-dom@18.2.0:
resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
peerDependencies:
@@ -20199,13 +20217,13 @@ snapshots:
zod: 3.25.76
zod-to-json-schema: 3.24.6(zod@3.25.76)
'@ai-sdk/vue@0.0.59(vue@3.5.24(typescript@5.5.4))(zod@3.25.76)':
'@ai-sdk/vue@0.0.59(vue@3.5.24(typescript@5.9.3))(zod@3.25.76)':
dependencies:
'@ai-sdk/provider-utils': 1.0.22(zod@3.25.76)
'@ai-sdk/ui-utils': 0.0.50(zod@3.25.76)
swrv: 1.0.4(vue@3.5.24(typescript@5.5.4))
swrv: 1.0.4(vue@3.5.24(typescript@5.9.3))
optionalDependencies:
vue: 3.5.24(typescript@5.5.4)
vue: 3.5.24(typescript@5.9.3)
transitivePeerDependencies:
- zod
@@ -22826,6 +22844,8 @@ snapshots:
dependencies:
'@bufbuild/protobuf': 2.2.5
'@date-fns/tz@1.4.1': {}
'@depot/cli-darwin-arm64@0.0.1-cli.2.80.0':
optional: true
@@ -28649,7 +28669,7 @@ snapshots:
transitivePeerDependencies:
- encoding
'@remix-run/dev@2.1.0(@remix-run/serve@2.1.0(typescript@5.5.4))(@types/node@22.13.9)(bufferutil@4.0.9)(encoding@0.1.13)(lightningcss@1.29.2)(terser@5.44.1)(typescript@5.5.4)':
'@remix-run/dev@2.1.0(@remix-run/serve@2.1.0(typescript@5.9.3))(@types/node@22.13.9)(bufferutil@4.0.9)(encoding@0.1.13)(lightningcss@1.29.2)(terser@5.44.1)(typescript@5.9.3)':
dependencies:
'@babel/core': 7.22.17
'@babel/generator': 7.24.7
@@ -28660,7 +28680,7 @@ snapshots:
'@babel/traverse': 7.24.7
'@mdx-js/mdx': 2.3.0
'@npmcli/package-json': 4.0.1
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
'@types/mdx': 2.0.5
'@vanilla-extract/integration': 6.2.1(@types/node@22.13.9)(lightningcss@1.29.2)(terser@5.44.1)
arg: 5.0.2
@@ -28700,8 +28720,8 @@ snapshots:
tsconfig-paths: 4.2.0
ws: 7.5.9(bufferutil@4.0.9)
optionalDependencies:
'@remix-run/serve': 2.1.0(typescript@5.5.4)
typescript: 5.5.4
'@remix-run/serve': 2.1.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- '@types/node'
- bluebird
@@ -28717,43 +28737,43 @@ snapshots:
- ts-node
- utf-8-validate
'@remix-run/eslint-config@2.1.0(eslint@8.31.0)(react@18.2.0)(typescript@5.5.4)':
'@remix-run/eslint-config@2.1.0(eslint@8.31.0)(react@18.2.0)(typescript@5.9.3)':
dependencies:
'@babel/core': 7.22.17
'@babel/eslint-parser': 7.21.8(@babel/core@7.22.17)(eslint@8.31.0)
'@babel/preset-react': 7.18.6(@babel/core@7.22.17)
'@rushstack/eslint-patch': 1.2.0
'@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/parser': 5.59.6(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint@8.31.0)(typescript@5.9.3)
'@typescript-eslint/parser': 5.59.6(eslint@8.31.0)(typescript@5.9.3)
eslint: 8.31.0
eslint-import-resolver-node: 0.3.7
eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.31.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0)
eslint-plugin-jest: 26.9.0(@typescript-eslint/eslint-plugin@5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint@8.31.0)(typescript@5.5.4))(eslint@8.31.0)(typescript@5.5.4)
eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.31.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0)
eslint-plugin-jest: 26.9.0(@typescript-eslint/eslint-plugin@5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint@8.31.0)(typescript@5.9.3))(eslint@8.31.0)(typescript@5.9.3)
eslint-plugin-jest-dom: 4.0.3(eslint@8.31.0)
eslint-plugin-jsx-a11y: 6.7.1(eslint@8.31.0)
eslint-plugin-node: 11.1.0(eslint@8.31.0)
eslint-plugin-react: 7.32.2(eslint@8.31.0)
eslint-plugin-react-hooks: 4.6.2(eslint@8.31.0)
eslint-plugin-testing-library: 5.11.0(eslint@8.31.0)(typescript@5.5.4)
eslint-plugin-testing-library: 5.11.0(eslint@8.31.0)(typescript@5.9.3)
react: 18.2.0
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
transitivePeerDependencies:
- eslint-import-resolver-webpack
- jest
- supports-color
'@remix-run/express@2.1.0(express@4.20.0)(typescript@5.5.4)':
'@remix-run/express@2.1.0(express@4.20.0)(typescript@5.9.3)':
dependencies:
'@remix-run/node': 2.1.0(typescript@5.5.4)
'@remix-run/node': 2.1.0(typescript@5.9.3)
express: 4.20.0
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
'@remix-run/node@2.1.0(typescript@5.5.4)':
'@remix-run/node@2.1.0(typescript@5.9.3)':
dependencies:
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
'@remix-run/web-fetch': 4.4.1
'@remix-run/web-file': 3.1.0
'@remix-run/web-stream': 1.1.0
@@ -28762,26 +28782,26 @@ snapshots:
source-map-support: 0.5.21
stream-slice: 0.1.2
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
'@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4)':
'@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3)':
dependencies:
'@remix-run/router': 1.10.0
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
react-router-dom: 6.17.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
'@remix-run/router@1.10.0': {}
'@remix-run/router@1.15.3': {}
'@remix-run/serve@2.1.0(typescript@5.5.4)':
'@remix-run/serve@2.1.0(typescript@5.9.3)':
dependencies:
'@remix-run/express': 2.1.0(express@4.20.0)(typescript@5.5.4)
'@remix-run/node': 2.1.0(typescript@5.5.4)
'@remix-run/express': 2.1.0(express@4.20.0)(typescript@5.9.3)
'@remix-run/node': 2.1.0(typescript@5.9.3)
chokidar: 3.6.0
compression: 1.7.4
express: 4.20.0
@@ -28792,7 +28812,7 @@ snapshots:
- supports-color
- typescript
'@remix-run/server-runtime@2.1.0(typescript@5.5.4)':
'@remix-run/server-runtime@2.1.0(typescript@5.9.3)':
dependencies:
'@remix-run/router': 1.10.0
'@types/cookie': 0.4.1
@@ -28801,24 +28821,24 @@ snapshots:
set-cookie-parser: 2.6.0
source-map: 0.7.4
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
'@remix-run/testing@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4)':
'@remix-run/testing@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3)':
dependencies:
'@remix-run/node': 2.1.0(typescript@5.5.4)
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4)
'@remix-run/node': 2.1.0(typescript@5.9.3)
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3)
'@remix-run/router': 1.10.0
react: 18.2.0
react-router-dom: 6.17.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
transitivePeerDependencies:
- react-dom
'@remix-run/v1-meta@0.1.3(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))':
'@remix-run/v1-meta@0.1.3(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))':
dependencies:
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4)
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3)
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
'@remix-run/web-blob@3.1.0':
dependencies:
@@ -28913,10 +28933,10 @@ snapshots:
'@rushstack/eslint-patch@1.2.0': {}
'@s2-dev/streamstore@0.17.3(typescript@5.5.4)':
'@s2-dev/streamstore@0.17.3(typescript@5.9.3)':
dependencies:
'@protobuf-ts/runtime': 2.11.1
typescript: 5.5.4
typescript: 5.9.3
'@s2-dev/streamstore@0.17.6':
dependencies:
@@ -29070,15 +29090,15 @@ snapshots:
hoist-non-react-statics: 3.3.2
react: 18.2.0
'@sentry/remix@9.46.0(patch_hash=146126b032581925294aaed63ab53ce3f5e0356a755f1763d7a9a76b9846943b)(@remix-run/node@2.1.0(typescript@5.5.4))(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(encoding@0.1.13)(react@18.2.0)':
'@sentry/remix@9.46.0(patch_hash=146126b032581925294aaed63ab53ce3f5e0356a755f1763d7a9a76b9846943b)(@remix-run/node@2.1.0(typescript@5.9.3))(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(encoding@0.1.13)(react@18.2.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.36.0
'@remix-run/node': 2.1.0(typescript@5.5.4)
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4)
'@remix-run/node': 2.1.0(typescript@5.9.3)
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3)
'@remix-run/router': 1.15.3
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
'@sentry/cli': 2.50.2(encoding@0.1.13)
'@sentry/core': 9.46.0
'@sentry/node': 9.46.0
@@ -30970,34 +30990,34 @@ snapshots:
'@types/node': 20.14.14
optional: true
'@typescript-eslint/eslint-plugin@5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint@8.31.0)(typescript@5.5.4)':
'@typescript-eslint/eslint-plugin@5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint@8.31.0)(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.5.1
'@typescript-eslint/parser': 5.59.6(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/parser': 5.59.6(eslint@8.31.0)(typescript@5.9.3)
'@typescript-eslint/scope-manager': 5.59.6
'@typescript-eslint/type-utils': 5.59.6(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/utils': 5.59.6(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/type-utils': 5.59.6(eslint@8.31.0)(typescript@5.9.3)
'@typescript-eslint/utils': 5.59.6(eslint@8.31.0)(typescript@5.9.3)
debug: 4.3.4
eslint: 8.31.0
grapheme-splitter: 1.0.4
ignore: 5.2.4
natural-compare-lite: 1.4.0
semver: 7.6.3
tsutils: 3.21.0(typescript@5.5.4)
tsutils: 3.21.0(typescript@5.9.3)
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4)':
'@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/scope-manager': 5.59.6
'@typescript-eslint/types': 5.59.6
'@typescript-eslint/typescript-estree': 5.59.6(typescript@5.5.4)
'@typescript-eslint/typescript-estree': 5.59.6(typescript@5.9.3)
debug: 4.4.0
eslint: 8.31.0
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@@ -31006,21 +31026,21 @@ snapshots:
'@typescript-eslint/types': 5.59.6
'@typescript-eslint/visitor-keys': 5.59.6
'@typescript-eslint/type-utils@5.59.6(eslint@8.31.0)(typescript@5.5.4)':
'@typescript-eslint/type-utils@5.59.6(eslint@8.31.0)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/typescript-estree': 5.59.6(typescript@5.5.4)
'@typescript-eslint/utils': 5.59.6(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/typescript-estree': 5.59.6(typescript@5.9.3)
'@typescript-eslint/utils': 5.59.6(eslint@8.31.0)(typescript@5.9.3)
debug: 4.4.1(supports-color@10.0.0)
eslint: 8.31.0
tsutils: 3.21.0(typescript@5.5.4)
tsutils: 3.21.0(typescript@5.9.3)
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/types@5.59.6': {}
'@typescript-eslint/typescript-estree@5.59.6(typescript@5.5.4)':
'@typescript-eslint/typescript-estree@5.59.6(typescript@5.9.3)':
dependencies:
'@typescript-eslint/types': 5.59.6
'@typescript-eslint/visitor-keys': 5.59.6
@@ -31028,20 +31048,20 @@ snapshots:
globby: 11.1.0
is-glob: 4.0.3
semver: 7.7.2
tsutils: 3.21.0(typescript@5.5.4)
tsutils: 3.21.0(typescript@5.9.3)
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@5.59.6(eslint@8.31.0)(typescript@5.5.4)':
'@typescript-eslint/utils@5.59.6(eslint@8.31.0)(typescript@5.9.3)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.31.0)
'@types/json-schema': 7.0.13
'@types/semver': 7.5.1
'@typescript-eslint/scope-manager': 5.59.6
'@typescript-eslint/types': 5.59.6
'@typescript-eslint/typescript-estree': 5.59.6(typescript@5.5.4)
'@typescript-eslint/typescript-estree': 5.59.6(typescript@5.9.3)
eslint: 8.31.0
eslint-scope: 5.1.1
semver: 7.7.2
@@ -31308,11 +31328,11 @@ snapshots:
'@vue/shared': 3.5.24
csstype: 3.2.0
'@vue/server-renderer@3.5.24(vue@3.5.24(typescript@5.5.4))':
'@vue/server-renderer@3.5.24(vue@3.5.24(typescript@5.9.3))':
dependencies:
'@vue/compiler-ssr': 3.5.24
'@vue/shared': 3.5.24
vue: 3.5.24(typescript@5.5.4)
vue: 3.5.24(typescript@5.9.3)
'@vue/shared@3.5.24': {}
@@ -31599,7 +31619,7 @@ snapshots:
ahocorasick@1.0.2: {}
ai@3.4.33(openai@4.97.0(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9))(zod@3.25.76))(react@19.1.0)(sswr@2.1.0(svelte@5.43.6))(svelte@5.43.6)(vue@3.5.24(typescript@5.5.4))(zod@3.25.76):
ai@3.4.33(openai@4.97.0(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9))(zod@3.25.76))(react@19.1.0)(sswr@2.1.0(svelte@5.43.6))(svelte@5.43.6)(vue@3.5.24(typescript@5.9.3))(zod@3.25.76):
dependencies:
'@ai-sdk/provider': 0.0.26
'@ai-sdk/provider-utils': 1.0.22(zod@3.25.76)
@@ -31607,7 +31627,7 @@ snapshots:
'@ai-sdk/solid': 0.0.54(zod@3.25.76)
'@ai-sdk/svelte': 0.0.57(svelte@5.43.6)(zod@3.25.76)
'@ai-sdk/ui-utils': 0.0.50(zod@3.25.76)
'@ai-sdk/vue': 0.0.59(vue@3.5.24(typescript@5.5.4))(zod@3.25.76)
'@ai-sdk/vue': 0.0.59(vue@3.5.24(typescript@5.9.3))(zod@3.25.76)
'@opentelemetry/api': 1.9.0
eventsource-parser: 1.1.2
json-schema: 0.4.0
@@ -32435,9 +32455,9 @@ snapshots:
cjs-module-lexer@1.2.3: {}
class-variance-authority@0.5.2(typescript@5.5.4):
class-variance-authority@0.5.2(typescript@5.9.3):
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
class-variance-authority@0.7.0:
dependencies:
@@ -32689,15 +32709,6 @@ snapshots:
dependencies:
layout-base: 2.0.1
cosmiconfig@8.3.6(typescript@5.5.4):
dependencies:
import-fresh: 3.3.0
js-yaml: 4.1.1
parse-json: 5.2.0
path-type: 4.0.0
optionalDependencies:
typescript: 5.5.4
cosmiconfig@8.3.6(typescript@5.9.3):
dependencies:
import-fresh: 3.3.0
@@ -32707,14 +32718,14 @@ snapshots:
optionalDependencies:
typescript: 5.9.3
cosmiconfig@9.0.0(typescript@5.5.4):
cosmiconfig@9.0.0(typescript@5.9.3):
dependencies:
env-paths: 2.2.1
import-fresh: 3.3.0
js-yaml: 4.1.1
parse-json: 5.2.0
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
cp-file@10.0.0:
dependencies:
@@ -33060,6 +33071,8 @@ snapshots:
dataloader@1.4.0: {}
date-fns-jalali@4.1.0-0: {}
date-fns@4.1.0: {}
dayjs@1.11.18: {}
@@ -33911,13 +33924,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.31.0):
eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.31.0):
dependencies:
debug: 4.4.1(supports-color@10.0.0)
enhanced-resolve: 5.15.0
eslint: 8.31.0
eslint-module-utils: 2.7.4(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0)
eslint-module-utils: 2.7.4(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0)
get-tsconfig: 4.7.2
globby: 13.2.2
is-core-module: 2.14.0
@@ -33929,25 +33942,25 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-module-utils@2.7.4(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0):
eslint-module-utils@2.7.4(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 5.59.6(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/parser': 5.59.6(eslint@8.31.0)(typescript@5.9.3)
eslint: 8.31.0
eslint-import-resolver-node: 0.3.7
eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.31.0)
eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.31.0)
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.8.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0):
eslint-module-utils@2.8.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 5.59.6(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/parser': 5.59.6(eslint@8.31.0)(typescript@5.9.3)
eslint: 8.31.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.31.0)
eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.31.0)
transitivePeerDependencies:
- supports-color
@@ -33957,7 +33970,7 @@ snapshots:
eslint-utils: 2.1.0
regexpp: 3.2.0
eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0):
eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0):
dependencies:
array-includes: 3.1.8
array.prototype.findlastindex: 1.2.5
@@ -33967,7 +33980,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.31.0
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0)
eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0)
hasown: 2.0.2
is-core-module: 2.14.0
is-glob: 4.0.3
@@ -33978,7 +33991,7 @@ snapshots:
semver: 6.3.1
tsconfig-paths: 3.15.0
optionalDependencies:
'@typescript-eslint/parser': 5.59.6(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/parser': 5.59.6(eslint@8.31.0)(typescript@5.9.3)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
@@ -33991,12 +34004,12 @@ snapshots:
eslint: 8.31.0
requireindex: 1.2.0
eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint@8.31.0)(typescript@5.5.4))(eslint@8.31.0)(typescript@5.5.4):
eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint@8.31.0)(typescript@5.9.3))(eslint@8.31.0)(typescript@5.9.3):
dependencies:
'@typescript-eslint/utils': 5.59.6(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/utils': 5.59.6(eslint@8.31.0)(typescript@5.9.3)
eslint: 8.31.0
optionalDependencies:
'@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.5.4))(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.59.6(eslint@8.31.0)(typescript@5.9.3))(eslint@8.31.0)(typescript@5.9.3)
transitivePeerDependencies:
- supports-color
- typescript
@@ -34054,9 +34067,9 @@ snapshots:
semver: 6.3.1
string.prototype.matchall: 4.0.8
eslint-plugin-testing-library@5.11.0(eslint@8.31.0)(typescript@5.5.4):
eslint-plugin-testing-library@5.11.0(eslint@8.31.0)(typescript@5.9.3):
dependencies:
'@typescript-eslint/utils': 5.59.6(eslint@8.31.0)(typescript@5.5.4)
'@typescript-eslint/utils': 5.59.6(eslint@8.31.0)(typescript@5.9.3)
eslint: 8.31.0
transitivePeerDependencies:
- supports-color
@@ -34984,22 +34997,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
graphile-worker@0.16.6(patch_hash=798129c99ed02177430fc90a1fdef800ec94e5fd1d491b931297dc52f4c98ab1)(typescript@5.5.4):
dependencies:
'@graphile/logger': 0.2.0
'@types/debug': 4.1.12
'@types/pg': 8.11.6
cosmiconfig: 8.3.6(typescript@5.5.4)
graphile-config: 0.0.1-beta.8
json5: 2.2.3
pg: 8.11.5
tslib: 2.6.2
yargs: 17.7.2
transitivePeerDependencies:
- pg-native
- supports-color
- typescript
graphile-worker@0.16.6(patch_hash=798129c99ed02177430fc90a1fdef800ec94e5fd1d491b931297dc52f4c98ab1)(typescript@5.9.3):
dependencies:
'@graphile/logger': 0.2.0
@@ -38218,9 +38215,9 @@ snapshots:
tsx: 4.17.0
yaml: 2.7.1
postcss-loader@8.1.1(postcss@8.5.6)(typescript@5.5.4)(webpack@5.102.1(@swc/core@1.3.26)(esbuild@0.15.18)):
postcss-loader@8.1.1(postcss@8.5.6)(typescript@5.9.3)(webpack@5.102.1(@swc/core@1.3.26)(esbuild@0.15.18)):
dependencies:
cosmiconfig: 9.0.0(typescript@5.5.4)
cosmiconfig: 9.0.0(typescript@5.9.3)
jiti: 1.21.0
postcss: 8.5.6
semver: 7.6.3
@@ -38805,6 +38802,13 @@ snapshots:
dependencies:
react: 18.2.0
react-day-picker@9.13.0(react@18.2.0):
dependencies:
'@date-fns/tz': 1.4.1
date-fns: 4.1.0
date-fns-jalali: 4.1.0-0
react: 18.2.0
react-dom@18.2.0(react@18.2.0):
dependencies:
loose-envify: 1.4.0
@@ -38832,7 +38836,7 @@ snapshots:
react: 19.1.0
scheduler: 0.26.0
react-email@2.1.2(@opentelemetry/api@1.9.0)(@swc/helpers@0.5.15)(bufferutil@4.0.9)(eslint@8.31.0):
react-email@2.1.2(@opentelemetry/api@1.9.0)(@swc/helpers@0.5.15)(eslint@8.31.0):
dependencies:
'@babel/parser': 7.24.1
'@radix-ui/colors': 1.0.1
@@ -38869,8 +38873,8 @@ snapshots:
react: 18.3.1
react-dom: 18.2.0(react@18.3.1)
shelljs: 0.8.5
socket.io: 4.7.3(bufferutil@4.0.9)
socket.io-client: 4.7.3(bufferutil@4.0.9)
socket.io: 4.7.3
socket.io-client: 4.7.3
sonner: 1.3.1(react-dom@18.2.0(react@18.3.1))(react@18.3.1)
source-map-js: 1.0.2
stacktrace-parser: 0.1.10
@@ -39393,54 +39397,54 @@ snapshots:
mdast-util-to-markdown: 2.1.2
unified: 11.0.5
remix-auth-email-link@2.0.2(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))):
remix-auth-email-link@2.0.2(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))):
dependencies:
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
crypto-js: 4.1.1
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))
remix-auth-github@1.6.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))):
remix-auth-github@1.6.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))):
dependencies:
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
remix-auth-oauth2: 1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))
remix-auth-oauth2: 1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)))
transitivePeerDependencies:
- supports-color
remix-auth-google@2.0.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))):
remix-auth-google@2.0.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))):
dependencies:
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
remix-auth-oauth2: 1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))
remix-auth-oauth2: 1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)))
transitivePeerDependencies:
- supports-color
remix-auth-oauth2@1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))):
remix-auth-oauth2@1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))):
dependencies:
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
debug: 4.4.1(supports-color@10.0.0)
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))
transitivePeerDependencies:
- supports-color
remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)):
remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)):
dependencies:
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4)
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3)
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
uuid: 8.3.2
remix-typedjson@0.3.1(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(react@18.2.0):
remix-typedjson@0.3.1(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(react@18.2.0):
dependencies:
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4)
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3)
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
react: 18.2.0
remix-utils@7.7.0(@remix-run/node@2.1.0(typescript@5.5.4))(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/router@1.15.3)(crypto-js@4.2.0)(intl-parse-accept-language@1.0.0)(react@18.2.0)(zod@3.25.76):
remix-utils@7.7.0(@remix-run/node@2.1.0(typescript@5.9.3))(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/router@1.15.3)(crypto-js@4.2.0)(intl-parse-accept-language@1.0.0)(react@18.2.0)(zod@3.25.76):
dependencies:
type-fest: 4.33.0
optionalDependencies:
'@remix-run/node': 2.1.0(typescript@5.5.4)
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4)
'@remix-run/node': 2.1.0(typescript@5.9.3)
'@remix-run/react': 2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3)
'@remix-run/router': 1.15.3
crypto-js: 4.2.0
intl-parse-accept-language: 1.0.0
@@ -40015,7 +40019,7 @@ snapshots:
- supports-color
- utf-8-validate
socket.io-client@4.7.3(bufferutil@4.0.9):
socket.io-client@4.7.3:
dependencies:
'@socket.io/component-emitter': 3.1.0
debug: 4.3.7(supports-color@10.0.0)
@@ -40044,7 +40048,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
socket.io@4.7.3(bufferutil@4.0.9):
socket.io@4.7.3:
dependencies:
accepts: 1.3.8
base64id: 2.0.0
@@ -40539,9 +40543,9 @@ snapshots:
swrev@4.0.0: {}
swrv@1.0.4(vue@3.5.24(typescript@5.5.4)):
swrv@1.0.4(vue@3.5.24(typescript@5.9.3)):
dependencies:
vue: 3.5.24(typescript@5.5.4)
vue: 3.5.24(typescript@5.9.3)
sync-content@2.0.1:
dependencies:
@@ -40978,10 +40982,6 @@ snapshots:
ts-easing@0.2.0: {}
ts-essentials@10.0.1(typescript@5.5.4):
optionalDependencies:
typescript: 5.5.4
ts-essentials@10.0.1(typescript@5.9.3):
optionalDependencies:
typescript: 5.9.3
@@ -41012,6 +41012,10 @@ snapshots:
optionalDependencies:
typescript: 5.5.4
tsconfck@2.1.2(typescript@5.9.3):
optionalDependencies:
typescript: 5.9.3
tsconfck@3.1.3(typescript@5.9.3):
optionalDependencies:
typescript: 5.9.3
@@ -41088,10 +41092,10 @@ snapshots:
- tsx
- yaml
tsutils@3.21.0(typescript@5.5.4):
tsutils@3.21.0(typescript@5.9.3):
dependencies:
tslib: 1.14.1
typescript: 5.5.4
typescript: 5.9.3
tsx@3.12.2:
dependencies:
@@ -41253,8 +41257,7 @@ snapshots:
typescript@5.5.4: {}
typescript@5.9.3:
optional: true
typescript@5.9.3: {}
ufo@1.5.4: {}
@@ -41655,6 +41658,15 @@ snapshots:
- supports-color
- typescript
vite-tsconfig-paths@4.0.5(typescript@5.9.3):
dependencies:
debug: 4.3.7(supports-color@10.0.0)
globrex: 0.1.2
tsconfck: 2.1.2(typescript@5.9.3)
transitivePeerDependencies:
- supports-color
- typescript
vite@4.4.9(@types/node@22.13.9)(lightningcss@1.29.2)(terser@5.44.1):
dependencies:
esbuild: 0.18.11
@@ -41731,15 +41743,15 @@ snapshots:
vscode-uri@3.0.8: {}
vue@3.5.24(typescript@5.5.4):
vue@3.5.24(typescript@5.9.3):
dependencies:
'@vue/compiler-dom': 3.5.24
'@vue/compiler-sfc': 3.5.24
'@vue/runtime-dom': 3.5.24
'@vue/server-renderer': 3.5.24(vue@3.5.24(typescript@5.5.4))
'@vue/server-renderer': 3.5.24(vue@3.5.24(typescript@5.9.3))
'@vue/shared': 3.5.24
optionalDependencies:
typescript: 5.5.4
typescript: 5.9.3
w3c-keyname@2.2.8: {}