Skip to content

Commit dc2ebe8

Browse files
committed
Merge branch 'main' into verceltypes
2 parents d453708 + 0d5bad0 commit dc2ebe8

File tree

14 files changed

+75
-30
lines changed

14 files changed

+75
-30
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
.venv
33
.tinyb
44
.tmp
5+
.tb_error*
6+
tinybird/fixtures
7+

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# Dev stack analytics template
2-
The dev stack analytics template is an open source utility built with love by Tinybird. Capture and analyze data from over a dozen common dev tools, from Vercel to Stripe to Auth0 and more, with just a few lines of code.
1+
# The Dev Stack Analytics Template
2+
The Dev Stack Analytics Template is an open source utility built with love by Tinybird. Capture and analyze data from over a dozen common dev tools, from Vercel to Stripe to Auth0 and more, with just a few lines of code.
33

44
![image](https://github.com/user-attachments/assets/32f24c18-a815-44f5-8a37-40e2d899e866)
55

TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ Fork the GitHub repository and deploy the data project to Tinybird.
66

77
## Set up the dashboard
88

9-
Deploy the dashboard to Vercel or use the hosted dashboard at https://dsat.tinybird.co/ using the Workspace admin [token](https://app.tinybird.co/tokens).
9+
Deploy the dashboard to Vercel or use the hosted dashboard at https://dsat.tinybird.app/ using the Workspace admin [token](https://app.tinybird.co/tokens).
1010

1111
Configure webhooks for the services you want to ingest. See instructions in the [README](https://github.com/tinybirdco/dev-stack-analytics-template/blob/main/README.md).

apps/web/src/app/api/datasources/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export async function GET(request: Request) {
88
return NextResponse.json({ error: 'Token is required' }, { status: 400 });
99
}
1010

11-
const response = await fetch('https://api.tinybird.co/v0/datasources', {
11+
const response = await fetch(`${process.env.NEXT_PUBLIC_TINYBIRD_API_HOST}/v0/datasources`, {
1212
headers: {
1313
'Authorization': `Bearer ${token}`,
1414
},

apps/web/src/app/api/pipes/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { NextRequest, NextResponse } from "next/server";
22

3-
const TINYBIRD_API_URL = "https://api.tinybird.co/v0/pipes";
3+
const TINYBIRD_API_URL = `${process.env.NEXT_PUBLIC_TINYBIRD_API_HOST}/v0/pipes`;
44

55
export async function GET(request: NextRequest) {
66
const searchParams = request.nextUrl.searchParams;

apps/web/src/app/api/query/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export async function GET(request: Request) {
99
return NextResponse.json({ error: 'Token and query are required' }, { status: 400 });
1010
}
1111

12-
const url = new URL('https://api.tinybird.co/v0/sql');
12+
const url = new URL(`${process.env.NEXT_PUBLIC_TINYBIRD_API_HOST}/v0/sql`);
1313
url.searchParams.set('q', query);
1414

1515
const response = await fetch(url.toString(), {

apps/web/src/components/time-range.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import { cn } from '@/lib/utils'
33
import { DateRange } from 'react-day-picker'
44
import { DateRangePicker } from '@/components/ui/date-range-picker'
55

6+
export type TimeRange = 'hourly' | 'daily' | 'weekly' | 'monthly';
7+
68
interface TimeRangeProps {
7-
timeRange: string
8-
onTimeRangeChange: (range: string) => void
9+
timeRange: TimeRange
10+
onTimeRangeChange: (range: TimeRange) => void
911
dateRange: DateRange | undefined
1012
onDateRangeChange: (range: DateRange | undefined) => void
1113
className?: string
@@ -22,7 +24,7 @@ export function TimeRange({
2224
<div className={cn("flex items-center gap-2", className)}>
2325
<div className="flex gap-1">
2426
<Button
25-
variant={timeRange === 'hourly' ? 'default' : 'outline'}
27+
variant={timeRange == 'hourly' ? 'default' : 'outline'}
2628
size="sm"
2729
onClick={() => onTimeRangeChange('hourly')}
2830
>

apps/web/src/components/tools/vercel/dashboard.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { addDays, format } from 'date-fns'
66
import { DateRange } from 'react-day-picker'
77
import { pipe } from '@/lib/tinybird'
88
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
9-
import { TimeRange } from '@/components/time-range'
9+
import { TimeRange, type TimeRange as TR } from '@/components/time-range'
1010
import MetricCard from '@/components/metric-card'
1111
import { DeploymentsChart, DeploymentsData } from './deployments-chart'
1212
import { DurationChart, DurationData } from './duration-chart'
@@ -21,7 +21,7 @@ interface VercelMetrics {
2121

2222
export default function VercelDashboard() {
2323
const [token] = useQueryState('token')
24-
const [timeRange, setTimeRange] = useState('daily')
24+
const [timeRange, setTimeRange] = useState<TR>('daily')
2525
const [dateRange, setDateRange] = useState<DateRange>({
2626
from: addDays(new Date(), -7),
2727
to: new Date()
@@ -115,6 +115,7 @@ export default function VercelDashboard() {
115115
<CardContent>
116116
<DeploymentsChart
117117
data={deploymentsData}
118+
timeRange={timeRange}
118119
/>
119120
</CardContent>
120121
</Card>
@@ -124,7 +125,9 @@ export default function VercelDashboard() {
124125
<CardTitle>Deploy Duration</CardTitle>
125126
</CardHeader>
126127
<CardContent>
127-
<DurationChart data={durationData} />
128+
<DurationChart
129+
data={durationData}
130+
timeRange={timeRange} />
128131
</CardContent>
129132
</Card>
130133
</div>

apps/web/src/components/tools/vercel/deployments-chart.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { BarChart, Bar, XAxis, YAxis } from 'recharts'
22
import { ChartContainer, ChartTooltip, ChartConfig } from '@/components/ui/chart'
33
import { format } from 'date-fns'
4+
import { type TimeRange } from '@/components/time-range'
45

56
export interface DeploymentsData {
67
period: string
@@ -19,9 +20,20 @@ const chartConfig = {
1920
},
2021
} satisfies ChartConfig
2122

22-
export function DeploymentsChart({ data }: { data: DeploymentsData[] }) {
23+
export function DeploymentsChart({ data, timeRange }: { data: DeploymentsData[]; timeRange: TimeRange }) {
2324
if (!data.length) return <div className={`flex items-center justify-center`}>No data available</div>
2425

26+
let dateFormat = 'yyyy-MM-dd HH:mm'
27+
if (timeRange === 'hourly') {
28+
dateFormat = 'yyyy-MM-dd HH:mm'
29+
} else if (timeRange === 'daily') {
30+
dateFormat = 'd MMMM'
31+
} else if (timeRange === 'weekly') {
32+
dateFormat = 'd MMMM'
33+
} else if (timeRange === 'monthly') {
34+
dateFormat = 'MMMM'
35+
}
36+
2537
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2638
const chartData = data.reduce((acc: any[], curr: DeploymentsData) => {
2739
const existing = acc.find(d => d.period === curr.period)
@@ -46,7 +58,7 @@ export function DeploymentsChart({ data }: { data: DeploymentsData[] }) {
4658
dataKey="period"
4759
tickLine={false}
4860
axisLine={false}
49-
tickFormatter={(value) => format(new Date(value), 'd HH:mm')}
61+
tickFormatter={(value) => format(new Date(value), dateFormat)}
5062
/>
5163
<YAxis
5264
tickLine={false}
@@ -59,7 +71,7 @@ export function DeploymentsChart({ data }: { data: DeploymentsData[] }) {
5971
return (
6072
<div className="rounded-lg border bg-background p-2 shadow-sm">
6173
<div className="text-xs text-muted-foreground">
62-
{format(new Date(data.period), 'd HH:mm')}
74+
{format(new Date(data.period), dateFormat)}
6375
</div>
6476
{
6577
// eslint-disable-next-line @typescript-eslint/no-explicit-any

apps/web/src/components/tools/vercel/duration-chart.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { format } from 'date-fns'
22
import { Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'
33
import { Card } from '@/components/ui/card'
4+
import { type TimeRange } from '@/components/time-range'
45

56
export interface DurationData {
67
period: string
@@ -10,19 +11,32 @@ export interface DurationData {
1011

1112
interface DurationChartProps {
1213
data: DurationData[]
14+
timeRange: TimeRange
1315
}
1416

15-
export function DurationChart({ data }: DurationChartProps) {
17+
export function DurationChart({ data, timeRange }: DurationChartProps) {
18+
19+
let dateFormat = 'yyyy-MM-dd HH:mm'
20+
if (timeRange === 'hourly') {
21+
dateFormat = 'yyyy-MM-dd HH:mm'
22+
} else if (timeRange === 'daily') {
23+
dateFormat = 'd MMMM'
24+
} else if (timeRange === 'weekly') {
25+
dateFormat = 'd MMMM'
26+
} else if (timeRange === 'monthly') {
27+
dateFormat = 'MMMM'
28+
}
29+
1630
return (
1731
<ResponsiveContainer width="100%" height={350}>
1832
<LineChart data={data}>
19-
<XAxis
20-
dataKey="period"
33+
<XAxis
34+
dataKey="period"
2135
tickLine={false}
2236
axisLine={false}
23-
tickFormatter={(value) => format(new Date(value), 'd MMM HH:mm')}
37+
tickFormatter={(value) => format(new Date(value), dateFormat)}
2438
/>
25-
<YAxis
39+
<YAxis
2640
tickLine={false}
2741
axisLine={false}
2842
tickFormatter={(value) => `${value}s`}
@@ -33,7 +47,7 @@ export function DurationChart({ data }: DurationChartProps) {
3347
return (
3448
<Card className="p-2">
3549
<div className="text-sm text-muted-foreground">
36-
{format(new Date(payload[0].payload.period), 'd MMM HH:mm')}
50+
{format(new Date(payload[0].payload.period), dateFormat)}
3751
</div>
3852
<div className="font-bold">
3953
Avg: {payload[0].payload.avg_duration}s

0 commit comments

Comments
 (0)