-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a31444e
commit 0775515
Showing
8 changed files
with
478 additions
and
228 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import { useState } from "react" | ||
import { | ||
BarChart, | ||
Block, | ||
Card, | ||
Flex, | ||
Text, | ||
Title, | ||
Toggle, | ||
ToggleItem, | ||
} from "@tremor/react" | ||
import useSWR from "swr" | ||
import { fetcher, useUrlFilters } from "../lib/helpers" | ||
|
||
// Basic formatters for the chart values | ||
const dollarFormatter = (value: number) => | ||
`$ ${Intl.NumberFormat("us").format(value).toString()}` | ||
|
||
const numberFormatter = (value: number) => | ||
`${Intl.NumberFormat("us").format(value).toString()}` | ||
|
||
export default function ChartView() { | ||
const filters = useUrlFilters() | ||
const [selectedKpi, setSelectedKpi] = useState("tally") | ||
const { data, error } = useSWR( | ||
["https://play.clickhouse.com/?user=play", `issues-${filters.org}`], | ||
([url]) => | ||
fetcher(url, { | ||
method: "POST", | ||
body: ` | ||
with | ||
events as ( | ||
SELECT * | ||
FROM github_events | ||
WHERE repo_name like '${filters.org}/%' and event_type = 'IssuesEvent' | ||
), | ||
timeseries as ( | ||
WITH | ||
coalesce(toStartOfDay((select min(created_at) from events)), today()) AS start, | ||
coalesce(toStartOfDay((select max(created_at) from events)), today()) AS end | ||
SELECT arrayJoin( | ||
arrayMap( | ||
x -> toDate(x), | ||
range( | ||
toUInt32(start), | ||
toUInt32(end), | ||
24 * 3600 | ||
) | ||
) | ||
) as date | ||
), | ||
opened as ( | ||
select count(*) as opened, toDate(created_at) as created_at | ||
from events where (action = 'opened' or action = 'reopened') | ||
group by created_at | ||
), | ||
closed as ( | ||
select count(*) as closed, toDate(created_at) as created_at | ||
from events where action = 'closed' | ||
group by created_at | ||
), | ||
stats as ( | ||
select | ||
timeseries.date as date, | ||
sum(opened.opened) as opened, | ||
sum(closed.closed) as closed, | ||
sum(opened.opened - closed.closed) as tally | ||
from | ||
timeseries | ||
left join | ||
closed on closed.created_at = timeseries.date | ||
left join | ||
opened on opened.created_at = timeseries.date | ||
group by | ||
timeseries.date | ||
) | ||
SELECT | ||
date, | ||
sum(opened) as opened, | ||
sum(closed) as closed, | ||
sum(sum(tally)) OVER w AS tally | ||
FROM | ||
stats | ||
GROUP BY date | ||
WINDOW w AS (ORDER BY date ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) | ||
FORMAT JSON`, | ||
}) | ||
) | ||
// console.log("data", data) | ||
// console.log("error", error) | ||
|
||
// map formatters by selectedKpi | ||
const formatters: { [key: string]: any } = { | ||
Sales: dollarFormatter, | ||
Profit: dollarFormatter, | ||
Customers: numberFormatter, | ||
} | ||
|
||
if (!data) return <div>Loading...</div> | ||
|
||
const chartData = data.data | ||
return ( | ||
<Card> | ||
<div className="md:flex justify-between"> | ||
<Block> | ||
<Flex | ||
justifyContent="justify-start" | ||
spaceX="space-x-0.5" | ||
alignItems="items-center" | ||
> | ||
<Title>Issue History</Title> | ||
</Flex> | ||
<Text>Issue growth across all repos</Text> | ||
</Block> | ||
<div className="mt-6 md:mt-0"> | ||
<Toggle | ||
color="zinc" | ||
defaultValue={selectedKpi} | ||
handleSelect={(value) => setSelectedKpi(value)} | ||
> | ||
<ToggleItem value="tally" text="Tally" /> | ||
<ToggleItem value="opened" text="Opened" /> | ||
<ToggleItem value="closed" text="Closed" /> | ||
</Toggle> | ||
</div> | ||
</div> | ||
<BarChart | ||
data={chartData} | ||
dataKey="date" | ||
categories={[selectedKpi]} | ||
colors={["blue"]} | ||
showLegend={false} | ||
valueFormatter={formatters[selectedKpi]} | ||
yAxisWidth="w-14" | ||
height="h-96" | ||
marginTop="mt-8" | ||
/> | ||
</Card> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,24 @@ | ||
import { useState } from "react"; | ||
import { Block, Card, ColGrid, Tab, TabList, Text, Title } from "@tremor/react"; | ||
import { useState } from "react" | ||
import { Block, Card, ColGrid, Tab, TabList, Text, Title } from "@tremor/react" | ||
import Stars from "./Stars" | ||
import Issues from "./Issues" | ||
import Navbar from "./Navbar" | ||
import { useRouter } from "next/router" | ||
|
||
export default function KpiCardGrid() { | ||
const [selectedView, setSelectedView] = useState(1); | ||
return ( | ||
<main className="bg-slate-50 p-6 sm:p-10"> | ||
<Title>Dashboard</Title> | ||
<Text>Lorem ipsum dolor sit amet, consetetur sadipscing elitr.</Text> | ||
|
||
<TabList | ||
defaultValue={1} | ||
handleSelect={(value) => setSelectedView(value)} | ||
marginTop="mt-6" | ||
> | ||
<Tab value={1} text="Overview" /> | ||
<Tab value={2} text="Detail" /> | ||
</TabList> | ||
|
||
{selectedView === 1 ? ( | ||
<div className="min-h-full"> | ||
<Navbar /> | ||
<main className="bg-slate-50 p-6 sm:p-10"> | ||
<> | ||
<ColGrid | ||
numColsMd={2} | ||
numColsLg={3} | ||
gapX="gap-x-6" | ||
gapY="gap-y-6" | ||
marginTop="mt-6" | ||
> | ||
<Card> | ||
{/* Placeholder to set height */} | ||
<div className="h-28" /> | ||
</Card> | ||
<Card> | ||
{/* Placeholder to set height */} | ||
<div className="h-28" /> | ||
</Card> | ||
<Card> | ||
{/* Placeholder to set height */} | ||
<div className="h-28" /> | ||
</Card> | ||
</ColGrid> | ||
|
||
<Block marginTop="mt-6"> | ||
<Card> | ||
<div className="h-80" /> | ||
</Card> | ||
<Stars /> | ||
</Block> | ||
<Block marginTop="mt-6"> | ||
<Issues /> | ||
</Block> | ||
</> | ||
) : ( | ||
<Block marginTop="mt-6"> | ||
<Card> | ||
<div className="h-96" /> | ||
</Card> | ||
</Block> | ||
)} | ||
</main> | ||
); | ||
</main> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { Fragment, useContext, useEffect, useState } from "react" | ||
import { Router, useRouter } from "next/router" | ||
import { useUrlFilters } from "../lib/helpers" | ||
|
||
export default function Navbar() { | ||
const filters = useUrlFilters() | ||
const [gitHubOrg, setGitHubOrg] = useState(filters.org) | ||
const router = useRouter() | ||
|
||
useEffect(() => { | ||
setGitHubOrg(filters.org) | ||
}, [filters.org]) | ||
|
||
return ( | ||
<nav className="bg-white shadow"> | ||
<> | ||
<div className="mx-auto px-2 sm:px-4 lg:px-8"> | ||
<div className="flex h-16 justify-between"> | ||
<div className="flex px-2 lg:px-0"> | ||
<div className="flex flex-shrink-0 items-center"> | ||
<img | ||
className="block h-8 w-auto lg:hidden" | ||
src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" | ||
alt="Your Company" | ||
/> | ||
<img | ||
className="hidden h-8 w-auto lg:block" | ||
src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" | ||
alt="Your Company" | ||
/> | ||
</div> | ||
<div className="hidden lg:ml-6 lg:flex lg:space-x-8"> | ||
{/* Date picker */} | ||
</div> | ||
</div> | ||
<div className="flex flex-1 items-center justify-center px-2 lg:ml-6 lg:justify-end"> | ||
<div className="w-full max-w-lg lg:max-w-xs"> | ||
<div className="mt-1 flex rounded-md shadow-sm"> | ||
<div className="relative flex flex-grow items-stretch focus-within:z-10"> | ||
<input | ||
type="email" | ||
name="email" | ||
id="email" | ||
value={gitHubOrg} | ||
onChange={(e) => setGitHubOrg(e.target.value)} | ||
className="block w-full rounded-none rounded-l-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" | ||
placeholder="John Smith" | ||
/> | ||
</div> | ||
<button | ||
type="button" | ||
onClick={() => { | ||
return router.push(`/?org=${gitHubOrg}`) | ||
}} | ||
className="relative -ml-px inline-flex items-center space-x-2 rounded-r-md border border-gray-300 bg-gray-50 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500" | ||
> | ||
<span>Go</span> | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
</nav> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { useState } from "react" | ||
import { | ||
AreaChart, | ||
Block, | ||
Card, | ||
Flex, | ||
Icon, | ||
Text, | ||
Title, | ||
Toggle, | ||
ToggleItem, | ||
} from "@tremor/react" | ||
import useSWR from "swr" | ||
import { fetcher, useUrlFilters } from "../lib/helpers" | ||
|
||
export default function ChartView() { | ||
const filters = useUrlFilters() | ||
const [selectedKpi, setSelectedKpi] = useState("stars") | ||
const { data, error } = useSWR( | ||
["https://play.clickhouse.com/?user=play", `stars-${filters.org}`], | ||
([url]) => | ||
fetcher(url, { | ||
method: "POST", | ||
body: ` | ||
WITH data AS ( | ||
select * from github_events | ||
WHERE repo_name like '${filters.org}/%' AND event_type = 'WatchEvent' | ||
) | ||
SELECT | ||
count(actor_login) as daily, | ||
toDate(created_at) as date, | ||
sum(count(actor_login)) OVER w AS stars | ||
FROM | ||
data | ||
GROUP BY toDate(created_at) | ||
WINDOW w AS (ORDER BY date ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) | ||
FORMAT JSON`, | ||
}) | ||
) | ||
// console.log("data", data) | ||
// console.log("error", error) | ||
|
||
if (!data) return <div>Loading...</div> | ||
|
||
const starHistory = data.data | ||
const max = parseInt(starHistory[starHistory.length - 1]["stars"]) | ||
return ( | ||
<Card> | ||
<div className="md:flex justify-between"> | ||
<Block> | ||
<Flex | ||
justifyContent="justify-start" | ||
spaceX="space-x-0.5" | ||
alignItems="items-center" | ||
> | ||
<Title>Star History</Title> | ||
</Flex> | ||
<Text>Star growth across all repos</Text> | ||
</Block> | ||
<div className="mt-6 md:mt-0"> | ||
<Toggle | ||
color="zinc" | ||
defaultValue={selectedKpi} | ||
handleSelect={(value) => setSelectedKpi(value)} | ||
> | ||
<ToggleItem value="stars" text="Growth" /> | ||
<ToggleItem value="daily" text="Daily" /> | ||
</Toggle> | ||
</div> | ||
</div> | ||
<AreaChart | ||
data={starHistory} | ||
dataKey="date" | ||
categories={[selectedKpi]} | ||
colors={["blue"]} | ||
showLegend={false} | ||
yAxisWidth="w-14" | ||
height="h-96" | ||
marginTop="mt-8" | ||
maxValue={selectedKpi == "stars" ? max : undefined} | ||
/> | ||
</Card> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { useRouter } from "next/router" | ||
|
||
// @ts-ignore | ||
export const fetcher = (...args) => fetch(...args).then((res) => res.json()) | ||
|
||
type UrlFilters = { | ||
org: string | string[] | ||
} | ||
export const useUrlFilters = (): UrlFilters => { | ||
const router = useRouter() | ||
const query = router.query | ||
const filters = { | ||
org: query.org || "supabase", | ||
} | ||
return filters | ||
} |
Oops, something went wrong.
0775515
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
githubanalytics – ./
githubanalytics-git-main-copple.vercel.app
githubanalytics-ashen.vercel.app
githubanalytics-copple.vercel.app