Skip to content

Commit 076251e

Browse files
committed
fix(dashboard): guessTimezone via dayjs, fix twitter-image revalidate export
- Replace Intl-based timezone helper with dayjs.tz.guess(); remove lib/timezone.ts - Export revalidate locally in twitter-image.tsx (Next.js forbids re-exporting route config) - Status and query consumers use guessTimezone from lib/dayjs
1 parent c95c5d5 commit 076251e

11 files changed

Lines changed: 25 additions & 39 deletions

File tree

apps/dashboard/app/status/[slug]/_components/last-checked.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,5 @@ interface LastCheckedProps {
77
}
88

99
export function LastChecked({ timestamp }: LastCheckedProps) {
10-
return (
11-
<p className="text-muted-foreground text-xs">{fromNow(timestamp)}</p>
12-
);
10+
return <p className="text-muted-foreground text-xs">{fromNow(timestamp)}</p>;
1311
}

apps/dashboard/app/status/[slug]/_components/last-updated.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { ClockIcon } from "@phosphor-icons/react";
44
import { useRouter } from "next/navigation";
55
import { useCallback, useRef, useState } from "react";
66
import { useInterval } from "@/hooks/use-interval";
7+
import { guessTimezone } from "@/lib/dayjs";
78
import { formatDateTime, localDayjs } from "@/lib/time";
8-
import { getUserTimezone } from "@/lib/timezone";
99

1010
const REFRESH_INTERVAL_SEC = 60;
1111

@@ -14,7 +14,7 @@ interface LastUpdatedProps {
1414
}
1515

1616
export function LastUpdated({ timestamp }: LastUpdatedProps) {
17-
const tz = getUserTimezone();
17+
const tz = guessTimezone();
1818
const abbreviation = localDayjs().format("z");
1919
const router = useRouter();
2020
const [countdown, setCountdown] = useState(REFRESH_INTERVAL_SEC);

apps/dashboard/app/status/[slug]/not-found.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ export default function StatusNotFound() {
77
Status page not found
88
</h1>
99
<p className="mt-2 max-w-sm text-pretty text-muted-foreground text-sm">
10-
This organization doesn&apos;t have a public status page, or the URL
11-
is incorrect.
10+
This organization doesn&apos;t have a public status page, or the URL is
11+
incorrect.
1212
</p>
1313
<Link
1414
className="mt-6 font-medium text-foreground text-sm hover:underline"

apps/dashboard/app/status/[slug]/opengraph-image.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,9 +345,7 @@ export default async function OGImage({
345345
key={i}
346346
style={{
347347
flex: 1,
348-
backgroundColor: getBarColor(
349-
day.uptime_percentage
350-
),
348+
backgroundColor: getBarColor(day.uptime_percentage),
351349
borderRadius: "2px",
352350
}}
353351
/>
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
export { contentType, default, revalidate, size } from "./opengraph-image";
1+
/** Must be defined here; Next.js does not allow re-exporting `revalidate` from another file. Match `opengraph-image.tsx`. */
2+
export const revalidate = 60;
3+
export { contentType, default, size } from "./opengraph-image";

apps/dashboard/hooks/use-dynamic-query.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type {
1010
} from "@databuddy/shared/types/parameters";
1111
import { type UseQueryOptions, useQuery } from "@tanstack/react-query";
1212
import { useCallback, useMemo } from "react";
13-
import { getUserTimezone } from "@/lib/timezone";
13+
import { guessTimezone } from "@/lib/dayjs";
1414

1515
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3001";
1616

@@ -101,7 +101,7 @@ async function fetchDynamicQuery(
101101
queryData: DynamicQueryRequest | DynamicQueryRequest[],
102102
signal?: AbortSignal
103103
): Promise<DynamicQueryResponse | BatchQueryResponse> {
104-
const timezone = getUserTimezone();
104+
const timezone = guessTimezone();
105105

106106
// Support both old string API (websiteId) and new options object
107107
const options: FetchOptions =

apps/dashboard/lib/dayjs.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// biome-ignore lint/style/noExportedImports: extended singleton is the app-wide default
12
import dayjs from "dayjs";
23
import relativeTime from "dayjs/plugin/relativeTime";
34
import timezone from "dayjs/plugin/timezone";
@@ -7,4 +8,7 @@ dayjs.extend(utc);
78
dayjs.extend(timezone);
89
dayjs.extend(relativeTime);
910

11+
export function guessTimezone(): string {
12+
return dayjs.tz.guess() ?? "UTC";
13+
}
1014
export default dayjs;

apps/dashboard/lib/insight-api.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import type { Insight, HistoryInsightRow } from "@/lib/insight-types";
2-
import { getUserTimezone } from "@/lib/timezone";
1+
import { guessTimezone } from "@/lib/dayjs";
2+
import type { HistoryInsightRow, Insight } from "@/lib/insight-types";
33

44
const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3001";
55

@@ -34,7 +34,7 @@ export async function fetchInsightsAi(
3434
method: "POST",
3535
credentials: "include",
3636
headers: { "Content-Type": "application/json" },
37-
body: JSON.stringify({ organizationId, timezone: getUserTimezone() }),
37+
body: JSON.stringify({ organizationId, timezone: guessTimezone() }),
3838
signal: AbortSignal.timeout(90_000),
3939
});
4040

apps/dashboard/lib/time.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,15 @@
44
* Always import dayjs from this file instead of 'dayjs' directly
55
* to ensure consistent timezone handling across the application.
66
*/
7-
import dayjs from "@/lib/dayjs";
8-
import { getUserTimezone } from "./timezone";
7+
import dayjs, { guessTimezone } from "@/lib/dayjs";
98

10-
// Get the user's timezone
11-
const userTimezone = getUserTimezone();
9+
const localTz = guessTimezone();
1210

1311
/**
1412
* Parse a date string (UTC) and convert to user's local timezone
1513
*/
1614
export function toLocalTime(date: string | Date | dayjs.Dayjs): dayjs.Dayjs {
17-
return dayjs.utc(date).tz(userTimezone);
15+
return dayjs.utc(date).tz(localTz);
1816
}
1917

2018
/**
@@ -83,7 +81,7 @@ export function formatDateOnly(
8381
*/
8482
export function localDayjs(date?: string | Date | dayjs.Dayjs): dayjs.Dayjs {
8583
if (!date) {
86-
return dayjs().tz(userTimezone);
84+
return dayjs().tz(localTz);
8785
}
88-
return dayjs.utc(date).tz(userTimezone);
86+
return dayjs.utc(date).tz(localTz);
8987
}

apps/dashboard/lib/timezone.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)