~repos /website
git clone https://pyrossh.dev/repos/website.git
木 Personal website of pyrossh. Built with astrojs, shiki, vite.
7640f703
—
pyrossh 1 year ago
improve analytics
- components/List.tsx +13 -4
- routes/_middleware.ts +0 -1
- routes/stats.tsx +1 -1
- services/analytics.ts +12 -11
components/List.tsx
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { AnalyticsDataPoint } from "../services/analytics.ts";
|
|
2
2
|
|
|
3
|
+
type ListProps = {
|
|
4
|
+
title: string;
|
|
3
|
-
|
|
5
|
+
entries: AnalyticsDataPoint[];
|
|
6
|
+
flag?: boolean;
|
|
7
|
+
};
|
|
4
8
|
|
|
5
|
-
export default function List({ title, entries }: ListProps) {
|
|
9
|
+
export default function List({ title, entries, flag }: ListProps) {
|
|
6
10
|
return (
|
|
7
11
|
<div class="bg-white p-6 rounded-lg">
|
|
8
12
|
<div>
|
|
@@ -11,11 +15,16 @@ export default function List({ title, entries }: ListProps) {
|
|
|
11
15
|
<div class="mt-4 px-3">
|
|
12
16
|
{entries.map((entry) => (
|
|
13
17
|
<div class="flex my-2">
|
|
18
|
+
<div class="flex">
|
|
19
|
+
{flag && (
|
|
14
|
-
|
|
20
|
+
<img
|
|
21
|
+
src={`https://cdn.jsdelivr.net/npm/country-flag-emoji-json@2.0.0/dist/images/${entry.name}.svg`}
|
|
22
|
+
width="18"
|
|
23
|
+
/>
|
|
24
|
+
)}
|
|
15
25
|
<span class="text-base font-medium">{entry.name}</span>
|
|
16
26
|
</div>
|
|
17
27
|
<div class="flex-1 flex justify-end">
|
|
18
|
-
<i class="icon icon-follow clickable"></i>
|
|
19
28
|
<span class="text-base font-medium">
|
|
20
29
|
{entry.count.toString()}
|
|
21
30
|
</span>
|
routes/_middleware.ts
CHANGED
|
@@ -15,7 +15,6 @@ export async function handler(req: Request, ctx: FreshContext) {
|
|
|
15
15
|
.filter((a) => !["/_404", "/_app", "/_middleware.ts"].includes(a));
|
|
16
16
|
const userAgent = req.headers.get("user-agent") || "";
|
|
17
17
|
const referer = req.headers.get("referer") || "";
|
|
18
|
-
console.log("referer", referer, req.referrer);
|
|
19
18
|
const pathname = new URL(req.url).pathname;
|
|
20
19
|
if (
|
|
21
20
|
registeredRoutes.includes(pathname) &&
|
routes/stats.tsx
CHANGED
|
@@ -30,7 +30,7 @@ export default function Stats({ data }: PageProps<AnalyticsData>) {
|
|
|
30
30
|
</div>
|
|
31
31
|
<div class="grid grid-cols-2 gap-8">
|
|
32
32
|
<List title="Pages" entries={data.pages} />
|
|
33
|
-
<List title="Countries" entries={data.countries} />
|
|
33
|
+
<List title="Countries" entries={data.countries} flag />
|
|
34
34
|
</div>
|
|
35
35
|
<div class="grid grid-cols-2 gap-8 mt-8">
|
|
36
36
|
<List title="OS" entries={data.os} />
|
services/analytics.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import UAParser from "ua-parser-js";
|
|
2
2
|
import IPinfoWrapper from "ipinfo";
|
|
3
|
-
import { getCountryData
|
|
3
|
+
import { getCountryData } from "countries-list";
|
|
4
4
|
|
|
5
5
|
const ipInfoClient = new IPinfoWrapper("3f197e26fa9210");
|
|
6
6
|
const kv = await Deno.openKv();
|
|
@@ -18,16 +18,17 @@ export const recordVisit = async (
|
|
|
18
18
|
"analytics",
|
|
19
19
|
`${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`,
|
|
20
20
|
];
|
|
21
|
-
|
|
21
|
+
const newVisitor = await kv.get(["visitor", hostname]);
|
|
22
22
|
const keysToIncrement = [
|
|
23
|
+
newVisitor.value ? [] : ["vistor", hostname],
|
|
23
|
-
["visitors"],
|
|
24
|
+
[...prefix, "visitors"],
|
|
24
|
-
["views"],
|
|
25
|
+
[...prefix, "views"],
|
|
25
|
-
["pages", pathname],
|
|
26
|
+
[...prefix, "pages", pathname],
|
|
26
|
-
["referers", referer],
|
|
27
|
+
[...prefix, "referers", referer],
|
|
27
|
-
["countries", ipRes.countryCode],
|
|
28
|
+
[...prefix, "countries", ipRes.countryCode],
|
|
28
|
-
["os", parser.getOS().name],
|
|
29
|
+
[...prefix, "os", parser.getOS().name],
|
|
29
|
-
["browsers", parser.getBrowser().name],
|
|
30
|
+
[...prefix, "browsers", parser.getBrowser().name],
|
|
30
|
-
].filter((arr) => arr[arr.length - 1]);
|
|
31
|
+
].filter((arr) => arr.length === 0 || arr[arr.length - 1]);
|
|
31
32
|
await kv
|
|
32
33
|
.atomic()
|
|
33
34
|
.mutate(
|
|
@@ -98,7 +99,7 @@ export const getAnalyticsData = async () => {
|
|
|
98
99
|
}
|
|
99
100
|
if (entry.key[2] === "countries") {
|
|
100
101
|
const code = entry.key[3] as string;
|
|
101
|
-
const name =
|
|
102
|
+
const name = getCountryData(code).name;
|
|
102
103
|
addMetric(data.countries, name, entry.value as number);
|
|
103
104
|
}
|
|
104
105
|
}
|