feat: add url metas
This commit is contained in:
@@ -84,7 +84,7 @@ function generateStatsList(
|
||||
let totalClicks = 0;
|
||||
|
||||
records.forEach((record) => {
|
||||
const dimValue = record[dimension] ?? ("(None)" as any);
|
||||
const dimValue = record[dimension] || ("(None)" as any);
|
||||
const click = record.click;
|
||||
|
||||
if (!dimensionCounts[dimValue]) {
|
||||
@@ -101,7 +101,7 @@ function generateStatsList(
|
||||
for (const [dimValue, clicks] of Object.entries(dimensionCounts)) {
|
||||
const percentage = (clicks / totalClicks) * 100;
|
||||
statsList.push({
|
||||
dimension: dimValue,
|
||||
dimension: dimValue ?? "(None)",
|
||||
clicks,
|
||||
percentage: percentage.toFixed(0) + "%",
|
||||
});
|
||||
@@ -229,8 +229,12 @@ export function DailyPVUVChart({ data }: { data: UrlMeta[] }) {
|
||||
</ChartContainer>
|
||||
|
||||
<div className="my-5 grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||||
<StatsList data={refererStats} title="Referrers" />
|
||||
<StatsList data={countryStats} title="Regions" />
|
||||
{refererStats.length > 0 && (
|
||||
<StatsList data={refererStats} title="Referrers" />
|
||||
)}
|
||||
{countryStats.length > 0 && (
|
||||
<StatsList data={countryStats} title="Regions" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<VisSingleContainer data={{ areas: areaData }}>
|
||||
|
||||
+19
-11
@@ -2,17 +2,22 @@ import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
import { createUserShortUrlMeta, getUrlBySuffix } from "@/lib/dto/short-urls";
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const url = new URL(req.url);
|
||||
const slug = url.searchParams.get("slug");
|
||||
const referer = url.searchParams.get("referer");
|
||||
const ip = url.searchParams.get("ip");
|
||||
const city = url.searchParams.get("city");
|
||||
const region = url.searchParams.get("region");
|
||||
const country = url.searchParams.get("country");
|
||||
const latitude = url.searchParams.get("latitude");
|
||||
const longitude = url.searchParams.get("longitude");
|
||||
const {
|
||||
slug,
|
||||
referer,
|
||||
ip,
|
||||
city,
|
||||
region,
|
||||
country,
|
||||
latitude,
|
||||
longitude,
|
||||
lang,
|
||||
device,
|
||||
browser,
|
||||
} = await req.json();
|
||||
|
||||
if (!slug || !ip) return Response.json(null);
|
||||
|
||||
const res = await getUrlBySuffix(slug);
|
||||
@@ -26,7 +31,7 @@ export async function GET(req: NextRequest) {
|
||||
return Response.json(null);
|
||||
}
|
||||
|
||||
// console.log("[api/s]", ip, res.id);
|
||||
console.log("[api/s]", device, browser);
|
||||
await createUserShortUrlMeta({
|
||||
urlId: res.id,
|
||||
click: 1,
|
||||
@@ -37,6 +42,9 @@ export async function GET(req: NextRequest) {
|
||||
latitude,
|
||||
longitude,
|
||||
referer,
|
||||
lang,
|
||||
device,
|
||||
browser,
|
||||
});
|
||||
return Response.json(res.target);
|
||||
}
|
||||
|
||||
+36
-4
@@ -1,6 +1,7 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { geolocation } from "@vercel/functions";
|
||||
import { auth } from "auth";
|
||||
import UAParser from "ua-parser-js";
|
||||
|
||||
import { siteConfig } from "./config/site";
|
||||
|
||||
@@ -12,13 +13,44 @@ export default auth(async (req) => {
|
||||
const ip = req.headers.get("X-Forwarded-For");
|
||||
if (req.url.includes("/s/")) {
|
||||
const match = req.url.match(/[^/]+$/);
|
||||
const geo = geolocation(req);
|
||||
|
||||
if (match) {
|
||||
const geo = geolocation(req);
|
||||
const userLanguage = req.headers.get("accept-language")?.split(",")[0];
|
||||
|
||||
const ua = req.headers.get("user-agent");
|
||||
const parser = new UAParser();
|
||||
parser.setUA(ua);
|
||||
const browser = parser.getBrowser();
|
||||
const device = parser.getDevice();
|
||||
|
||||
console.log(device, browser);
|
||||
|
||||
const referer = req.headers.get("referer") || "(None)";
|
||||
const res = await fetch(
|
||||
`${siteConfig.url}/api/s?slug=${match[0]}&referer=${referer}&ip=${ip}&city=${geo?.city}®ion=${geo?.region}&country=${geo?.country}&latitude=${geo?.latitude}&longitude=${geo?.longitude}&flag=${geo?.flag}`,
|
||||
);
|
||||
// const res1 = await fetch(
|
||||
// `${siteConfig.url}/api/s?slug=${match[0]}&referer=${referer}&ip=${ip}&city=${geo?.city}®ion=${geo?.region}&country=${geo?.country}&latitude=${geo?.latitude}&longitude=${geo?.longitude}&flag=${geo?.flag}`,
|
||||
// );
|
||||
|
||||
const res = await fetch(`${siteConfig.url}/api/s`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
slug: match[0],
|
||||
referer,
|
||||
ip,
|
||||
city: geo?.city,
|
||||
region: geo?.region,
|
||||
country: geo?.country,
|
||||
latitude: geo?.latitude,
|
||||
longitude: geo?.longitude,
|
||||
flag: geo?.flag,
|
||||
lang: userLanguage,
|
||||
device: device.model || "Unknown",
|
||||
browser: browser.name || "Unknown",
|
||||
}),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
return NextResponse.redirect(`${siteConfig.url}/docs/short-urls`);
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
"swr": "^2.2.5",
|
||||
"tailwind-merge": "^2.4.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"ua-parser-js": "^1.0.38",
|
||||
"vaul": "^0.9.1",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
|
||||
Generated
+8
@@ -230,6 +230,9 @@ importers:
|
||||
tailwindcss-animate:
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7(tailwindcss@3.4.6)
|
||||
ua-parser-js:
|
||||
specifier: ^1.0.38
|
||||
version: 1.0.38
|
||||
vaul:
|
||||
specifier: ^0.9.1
|
||||
version: 0.9.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -6234,6 +6237,9 @@ packages:
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
ua-parser-js@1.0.38:
|
||||
resolution: {integrity: sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==}
|
||||
|
||||
unbox-primitive@1.0.2:
|
||||
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
|
||||
|
||||
@@ -13665,6 +13671,8 @@ snapshots:
|
||||
|
||||
typescript@5.5.3: {}
|
||||
|
||||
ua-parser-js@1.0.38: {}
|
||||
|
||||
unbox-primitive@1.0.2:
|
||||
dependencies:
|
||||
call-bind: 1.0.7
|
||||
|
||||
@@ -171,5 +171,8 @@ ALTER TABLE "url_metas" ADD COLUMN "region" TEXT;
|
||||
ALTER TABLE "url_metas" ADD COLUMN "latitude" TEXT;
|
||||
ALTER TABLE "url_metas" ADD COLUMN "longitude" TEXT;
|
||||
ALTER TABLE "url_metas" ADD COLUMN "referer" TEXT;
|
||||
ALTER TABLE "url_metas" ADD COLUMN "lang" TEXT;
|
||||
ALTER TABLE "url_metas" ADD COLUMN "device" TEXT;
|
||||
ALTER TABLE "url_metas" ADD COLUMN "browser" TEXT;
|
||||
|
||||
ALTER TABLE "user_url" ADD COLUMN "expiration" TEXT NOT NULL DEFAULT '-1';
|
||||
ALTER TABLE "user_urls" ADD COLUMN "expiration" TEXT NOT NULL DEFAULT '-1';
|
||||
@@ -133,6 +133,9 @@ model UrlMeta {
|
||||
latitude String?
|
||||
longitude String?
|
||||
referer String?
|
||||
lang String?
|
||||
device String?
|
||||
browser String?
|
||||
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
updatedAt DateTime @default(now()) @map(name: "updated_at")
|
||||
|
||||
Reference in New Issue
Block a user