Skip to content

Commit 25c7761

Browse files
committed
cleanup dayjs
1 parent 77be7ea commit 25c7761

File tree

9 files changed

+83
-62
lines changed

9 files changed

+83
-62
lines changed

apps/dashboard/app/(main)/websites/[id]/errors/_components/utils.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
import { format, isValid, parseISO } from 'date-fns';
1+
import dayjs from 'dayjs';
22

33
// Helper function to safely parse dates
44
export const safeDateParse = (dateString: string): Date => {
55
if (!dateString) {
66
return new Date();
77
}
88

9-
let date = parseISO(dateString);
10-
if (isValid(date)) {
11-
return date;
9+
let dayjsDate = dayjs(dateString);
10+
if (dayjsDate.isValid()) {
11+
return dayjsDate.toDate();
1212
}
1313

1414
const isoString = dateString.replace(' ', 'T');
15-
date = parseISO(isoString);
16-
if (isValid(date)) {
17-
return date;
15+
dayjsDate = dayjs(isoString);
16+
if (dayjsDate.isValid()) {
17+
return dayjsDate.toDate();
1818
}
1919

20-
date = new Date(dateString);
21-
if (isValid(date)) {
22-
return date;
20+
dayjsDate = dayjs(new Date(dateString));
21+
if (dayjsDate.isValid()) {
22+
return dayjsDate.toDate();
2323
}
2424

2525
console.warn('Failed to parse date:', dateString);
@@ -32,7 +32,7 @@ export const safeFormatDate = (
3232
): string => {
3333
try {
3434
const date = safeDateParse(dateString);
35-
return format(date, formatString);
35+
return dayjs(date).format(formatString);
3636
} catch (error) {
3737
console.warn('Failed to format date:', dateString, error);
3838
return dateString;

apps/dashboard/app/(main)/websites/[id]/funnels/page.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
22

33
import { FunnelIcon, TrendDownIcon } from '@phosphor-icons/react';
4-
import { format, subDays, subHours } from 'date-fns';
4+
import dayjs from 'dayjs';
55
import { useAtom } from 'jotai';
66
import { useParams } from 'next/navigation';
77
import { lazy, Suspense, useCallback, useMemo, useRef, useState } from 'react';
@@ -145,8 +145,10 @@ export default function FunnelsPage() {
145145
(range: (typeof quickRanges)[0]) => {
146146
const now = new Date();
147147
const start = range.hours
148-
? subHours(now, range.hours)
149-
: subDays(now, range.days || 7);
148+
? dayjs(now).subtract(range.hours, 'hour').toDate()
149+
: dayjs(now)
150+
.subtract(range.days || 7, 'day')
151+
.toDate();
150152
setDateRangeAction({ startDate: start, endDate: now });
151153
},
152154
[setDateRangeAction]
@@ -340,16 +342,18 @@ export default function FunnelsPage() {
340342
{quickRanges.map((range) => {
341343
const now = new Date();
342344
const start = range.hours
343-
? subHours(now, range.hours)
344-
: subDays(now, range.days || 7);
345+
? dayjs(now).subtract(range.hours, 'hour').toDate()
346+
: dayjs(now)
347+
.subtract(range.days || 7, 'day')
348+
.toDate();
345349
const dayPickerCurrentRange = dayPickerSelectedRange;
346350
const isActive =
347351
dayPickerCurrentRange?.from &&
348352
dayPickerCurrentRange?.to &&
349-
format(dayPickerCurrentRange.from, 'yyyy-MM-dd') ===
350-
format(start, 'yyyy-MM-dd') &&
351-
format(dayPickerCurrentRange.to, 'yyyy-MM-dd') ===
352-
format(now, 'yyyy-MM-dd');
353+
dayjs(dayPickerCurrentRange.from).format('YYYY-MM-DD') ===
354+
dayjs(start).format('YYYY-MM-DD') &&
355+
dayjs(dayPickerCurrentRange.to).format('YYYY-MM-DD') ===
356+
dayjs(now).format('YYYY-MM-DD');
353357

354358
return (
355359
<Button

apps/dashboard/app/(main)/websites/[id]/goals/page.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
22

33
import { TargetIcon } from '@phosphor-icons/react';
4-
import { format, subDays, subHours } from 'date-fns';
4+
import dayjs from 'dayjs';
55
import { useAtom } from 'jotai';
66
import { useParams } from 'next/navigation';
77
import {
@@ -142,8 +142,10 @@ export default function GoalsPage() {
142142
(range: (typeof quickRanges)[0]) => {
143143
const now = new Date();
144144
const start = range.hours
145-
? subHours(now, range.hours)
146-
: subDays(now, range.days || 7);
145+
? dayjs(now).subtract(range.hours, 'hour').toDate()
146+
: dayjs(now)
147+
.subtract(range.days || 7, 'day')
148+
.toDate();
147149
setDateRangeAction({ startDate: start, endDate: now });
148150
},
149151
[setDateRangeAction]
@@ -299,16 +301,18 @@ export default function GoalsPage() {
299301
{quickRanges.map((range) => {
300302
const now = new Date();
301303
const start = range.hours
302-
? subHours(now, range.hours)
303-
: subDays(now, range.days || 7);
304+
? dayjs(now).subtract(range.hours, 'hour').toDate()
305+
: dayjs(now)
306+
.subtract(range.days || 7, 'day')
307+
.toDate();
304308
const dayPickerCurrentRange = dayPickerSelectedRange;
305309
const isActive =
306310
dayPickerCurrentRange?.from &&
307311
dayPickerCurrentRange?.to &&
308-
format(dayPickerCurrentRange.from, 'yyyy-MM-dd') ===
309-
format(start, 'yyyy-MM-dd') &&
310-
format(dayPickerCurrentRange.to, 'yyyy-MM-dd') ===
311-
format(now, 'yyyy-MM-dd');
312+
dayjs(dayPickerCurrentRange.from).format('YYYY-MM-DD') ===
313+
dayjs(start).format('YYYY-MM-DD') &&
314+
dayjs(dayPickerCurrentRange.to).format('YYYY-MM-DD') ===
315+
dayjs(now).format('YYYY-MM-DD');
312316

313317
return (
314318
<Button

apps/dashboard/app/(main)/websites/[id]/page.tsx

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
'use client';
22

3-
import { filterOptions, type DynamicQueryFilter } from '@databuddy/shared';
3+
import { type DynamicQueryFilter, filterOptions } from '@databuddy/shared';
44
import { ArrowClockwiseIcon, WarningIcon, XIcon } from '@phosphor-icons/react';
55
import { useQueryClient } from '@tanstack/react-query';
6-
import { format, subDays, subHours } from 'date-fns';
6+
import dayjs from 'dayjs';
77
import { useAtom } from 'jotai';
88
import dynamic from 'next/dynamic';
99
import Link from 'next/link';
@@ -16,6 +16,7 @@ import { DateRangePicker } from '@/components/date-range-picker';
1616
import { Button } from '@/components/ui/button';
1717
import { Skeleton } from '@/components/ui/skeleton';
1818
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
19+
import { operatorOptions, useFilters } from '@/hooks/use-filters';
1920
import { useWebsite } from '@/hooks/use-websites';
2021
import { trpc } from '@/lib/trpc';
2122
import {
@@ -25,16 +26,15 @@ import {
2526
timeGranularityAtom,
2627
timezoneAtom,
2728
} from '@/stores/jotai/filterAtoms';
28-
import { operatorOptions, useFilters } from '@/hooks/use-filters';
29+
import {
30+
AddFilterForm,
31+
getOperatorShorthand,
32+
} from './_components/utils/add-filters';
2933
import type {
3034
FullTabProps,
3135
WebsiteDataTabProps,
3236
} from './_components/utils/types';
3337
import { EmptyState } from './_components/utils/ui-components';
34-
import {
35-
AddFilterForm,
36-
getOperatorShorthand,
37-
} from './_components/utils/add-filters';
3838

3939
type TabId =
4040
| 'overview'
@@ -130,8 +130,10 @@ function WebsiteDetailsPage() {
130130
(range: (typeof quickRanges)[0]) => {
131131
const now = new Date();
132132
const start = range.hours
133-
? subHours(now, range.hours)
134-
: subDays(now, range.days || 7);
133+
? dayjs(now).subtract(range.hours, 'hour').toDate()
134+
: dayjs(now)
135+
.subtract(range.days || 7, 'day')
136+
.toDate();
135137
setDateRangeAction({ startDate: start, endDate: now });
136138
},
137139
[setDateRangeAction]
@@ -336,16 +338,18 @@ function WebsiteDetailsPage() {
336338
{quickRanges.map((range) => {
337339
const now = new Date();
338340
const start = range.hours
339-
? subHours(now, range.hours)
340-
: subDays(now, range.days || 7);
341+
? dayjs(now).subtract(range.hours, 'hour').toDate()
342+
: dayjs(now)
343+
.subtract(range.days || 7, 'day')
344+
.toDate();
341345
const dayPickerCurrentRange = dayPickerSelectedRange;
342346
const isActive =
343347
dayPickerCurrentRange?.from &&
344348
dayPickerCurrentRange?.to &&
345-
format(dayPickerCurrentRange.from, 'yyyy-MM-dd') ===
346-
format(start, 'yyyy-MM-dd') &&
347-
format(dayPickerCurrentRange.to, 'yyyy-MM-dd') ===
348-
format(now, 'yyyy-MM-dd');
349+
dayjs(dayPickerCurrentRange.from).format('YYYY-MM-DD') ===
350+
dayjs(start).format('YYYY-MM-DD') &&
351+
dayjs(dayPickerCurrentRange.to).format('YYYY-MM-DD') ===
352+
dayjs(now).format('YYYY-MM-DD');
349353

350354
return (
351355
<Button

apps/dashboard/app/(main)/websites/[id]/revenue/_components/recent-transactions.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
22

33
import { CalendarIcon, CreditCardIcon } from '@phosphor-icons/react';
4-
import { format } from 'date-fns';
4+
import dayjs from 'dayjs';
55
import { Badge } from '@/components/ui/badge';
66
import { Skeleton } from '@/components/ui/skeleton';
77
import { formatCurrency } from '@/lib/formatters';
@@ -83,7 +83,7 @@ export function RecentTransactions({
8383

8484
const formatDate = (dateString: string) => {
8585
try {
86-
return format(new Date(dateString), 'MMM dd, yyyy HH:mm');
86+
return dayjs(new Date(dateString)).format('MMM dd, yyyy HH:mm');
8787
} catch {
8888
return dateString;
8989
}

apps/dashboard/components/date-range-picker.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
22

33
import { CalendarDotsIcon } from '@phosphor-icons/react';
4-
import { format } from 'date-fns';
4+
import dayjs from 'dayjs';
55
import { useCallback, useEffect, useState } from 'react';
66
import type { DateRange } from 'react-day-picker';
77
import { Button } from '@/components/ui/button';
@@ -71,19 +71,19 @@ export function DateRangePicker({
7171
}
7272

7373
if (appliedRange.from && !appliedRange.to) {
74-
return format(appliedRange.from, 'MMM d, yyyy');
74+
return dayjs(appliedRange.from).format('MMM D, YYYY');
7575
}
7676

7777
if (appliedRange.from && appliedRange.to) {
7878
if (appliedRange.from.getTime() === appliedRange.to.getTime()) {
79-
return format(appliedRange.from, 'MMM d, yyyy');
79+
return dayjs(appliedRange.from).format('MMM D, YYYY');
8080
}
8181

8282
if (appliedRange.from.getFullYear() !== appliedRange.to.getFullYear()) {
83-
return `${format(appliedRange.from, 'MMM d, yyyy')} - ${format(appliedRange.to, 'MMM d, yyyy')}`;
83+
return `${dayjs(appliedRange.from).format('MMM D, YYYY')} - ${dayjs(appliedRange.to).format('MMM D, YYYY')}`;
8484
}
8585

86-
return `${format(appliedRange.from, 'MMM d')} - ${format(appliedRange.to, 'MMM d, yyyy')}`;
86+
return `${dayjs(appliedRange.from).format('MMM D')} - ${dayjs(appliedRange.to).format('MMM D, YYYY')}`;
8787
}
8888

8989
return 'Select dates';
@@ -119,13 +119,13 @@ export function DateRangePicker({
119119
<div className="text-muted-foreground text-sm">
120120
{tempRange?.from && tempRange?.to ? (
121121
<span className="font-medium text-foreground">
122-
{format(tempRange.from, 'MMM d')} -{' '}
123-
{format(tempRange.to, 'MMM d, yyyy')}
122+
{dayjs(tempRange.from).format('MMM D')} -{' '}
123+
{dayjs(tempRange.to).format('MMM D, YYYY')}
124124
</span>
125125
) : tempRange?.from ? (
126126
<span>
127127
<span className="font-medium text-foreground">
128-
{format(tempRange.from, 'MMM d')}
128+
{dayjs(tempRange.from).format('MMM D')}
129129
</span>
130130
<span className="text-muted-foreground">
131131
{' '}

apps/dashboard/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"d3-geo": "^3.1.1",
4343
"d3-scale": "^4.0.2",
4444
"dagre": "^0.8.5",
45-
"date-fns": "^4.1.0",
45+
"dayjs": "catalog:",
4646
"drizzle-zod": "^0.8.2",
4747
"embla-carousel-react": "^8.6.0",
4848
"framer-motion": "catalog:",

apps/dashboard/stores/jotai/filterAtoms.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { differenceInDays, format, isValid, subDays } from 'date-fns';
1+
import dayjs from 'dayjs';
22
import { atom } from 'jotai';
33
// Consider adding nanoid for unique ID generation for complex filters
44
// import { nanoid } from 'nanoid';
@@ -9,7 +9,7 @@ export interface DateRangeState {
99
endDate: Date;
1010
}
1111

12-
const initialStartDate = subDays(new Date(), 30);
12+
const initialStartDate = dayjs().subtract(30, 'day').toDate();
1313
const initialEndDate = new Date();
1414

1515
export const dateRangeAtom = atom<DateRangeState>({
@@ -24,8 +24,12 @@ export const dateRangeAtom = atom<DateRangeState>({
2424
export const formattedDateRangeAtom = atom((get) => {
2525
const { startDate, endDate } = get(dateRangeAtom);
2626
return {
27-
startDate: isValid(startDate) ? format(startDate, 'yyyy-MM-dd') : '',
28-
endDate: isValid(endDate) ? format(endDate, 'yyyy-MM-dd') : '',
27+
startDate: dayjs(startDate).isValid()
28+
? dayjs(startDate).format('YYYY-MM-DD')
29+
: '',
30+
endDate: dayjs(endDate).isValid()
31+
? dayjs(endDate).format('YYYY-MM-DD')
32+
: '',
2933
};
3034
});
3135

@@ -42,7 +46,10 @@ export const setDateRangeAndAdjustGranularityAtom = atom(
4246
null,
4347
(_get, set, newRange: DateRangeState) => {
4448
set(dateRangeAtom, newRange);
45-
const diffDays = differenceInDays(newRange.endDate, newRange.startDate);
49+
const diffDays = dayjs(newRange.endDate).diff(
50+
dayjs(newRange.startDate),
51+
'day'
52+
);
4653
if (diffDays <= 2) {
4754
// If 2 days or less, set to hourly
4855
set(timeGranularityAtom, 'hourly');

apps/docs/app/(home)/layout.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ export default async function Layout({ children }: { children: ReactNode }) {
3333

3434
return (
3535
<HomeLayout {...baseOptions}>
36-
<div className="flex min-h-screen flex-col font-manrope">
36+
<div className="overflow-hidden">
3737
<Navbar stars={stars} />
38-
<main>{children}</main>
38+
<main className="flex min-h-screen flex-col font-manrope">
39+
{children}
40+
</main>
3941
</div>
4042
</HomeLayout>
4143
);

0 commit comments

Comments
 (0)