From fab90a0bd8549edf210256deeaedd194798678ed Mon Sep 17 00:00:00 2001 From: oiov Date: Sun, 4 May 2025 20:42:34 +0800 Subject: [PATCH] chore AnalyticsRetention config --- app/(protected)/admin/urls/page.tsx | 1 + app/(protected)/dashboard/page.tsx | 10 +++++++++- app/(protected)/dashboard/urls/meta-chart.tsx | 13 +++++++++++-- app/(protected)/dashboard/urls/meta.tsx | 12 ++++++++++-- app/(protected)/dashboard/urls/page.tsx | 1 + app/(protected)/dashboard/urls/url-list.tsx | 8 ++++++-- components/sections/pricing.tsx | 2 +- config/team.ts | 4 ++-- lib/enums.ts | 16 ++++++++-------- public/sw.js.map | 2 +- 10 files changed, 50 insertions(+), 19 deletions(-) diff --git a/app/(protected)/admin/urls/page.tsx b/app/(protected)/admin/urls/page.tsx index bc20387..b9c5205 100644 --- a/app/(protected)/admin/urls/page.tsx +++ b/app/(protected)/admin/urls/page.tsx @@ -31,6 +31,7 @@ export default async function DashboardPage() { name: user.name || "", apiKey: user.apiKey || "", role: user.role, + team: user.team, }} action="/api/url/admin" /> diff --git a/app/(protected)/dashboard/page.tsx b/app/(protected)/dashboard/page.tsx index cb3a042..072c90f 100644 --- a/app/(protected)/dashboard/page.tsx +++ b/app/(protected)/dashboard/page.tsx @@ -94,7 +94,13 @@ async function LiveLogSection() { async function UserUrlsListSection({ user, }: { - user: { id: string; name: string; apiKey: string; role: UserRole }; + user: { + id: string; + name: string; + apiKey: string; + role: UserRole; + team: string; + }; }) { return ( @@ -185,6 +192,7 @@ export default async function DashboardPage() { name: user.name || "", apiKey: user.apiKey || "", role: user.role, + team: user.team, }} /> diff --git a/app/(protected)/dashboard/urls/meta-chart.tsx b/app/(protected)/dashboard/urls/meta-chart.tsx index a96155f..57f95ba 100644 --- a/app/(protected)/dashboard/urls/meta-chart.tsx +++ b/app/(protected)/dashboard/urls/meta-chart.tsx @@ -3,12 +3,13 @@ import * as React from "react"; import { useState } from "react"; import Link from "next/link"; -import { UrlMeta } from "@prisma/client"; +import { UrlMeta, User } from "@prisma/client"; import { VisSingleContainer, VisTooltip, VisTopoJSONMap } from "@unovis/react"; import { TopoJSONMap } from "@unovis/ts"; import { WorldMapTopoJSON } from "@unovis/ts/maps"; import { Area, AreaChart, CartesianGrid, XAxis } from "recharts"; +import { TeamPlanQuota } from "@/config/team"; import { getCountryName, getDeviceVendor } from "@/lib/contries"; import { DATE_DIMENSION_ENUMS } from "@/lib/enums"; import { isLink, removeUrlSuffix, timeAgo } from "@/lib/utils"; @@ -144,10 +145,12 @@ export function DailyPVUVChart({ data, timeRange, setTimeRange, + user, }: { data: UrlMeta[]; timeRange: string; setTimeRange: React.Dispatch>; + user: Pick; }) { const [activeChart, setActiveChart] = React.useState("pv"); @@ -232,7 +235,13 @@ export function DailyPVUVChart({ {DATE_DIMENSION_ENUMS.map((e) => ( - + TeamPlanQuota[user.team!].SL_AnalyticsRetention + } + key={e.value} + value={e.value} + > {e.label} ))} diff --git a/app/(protected)/dashboard/urls/meta.tsx b/app/(protected)/dashboard/urls/meta.tsx index bdf186c..7000681 100644 --- a/app/(protected)/dashboard/urls/meta.tsx +++ b/app/(protected)/dashboard/urls/meta.tsx @@ -4,6 +4,7 @@ import { useState } from "react"; import { UrlMeta, User } from "@prisma/client"; import useSWR from "swr"; +import { TeamPlanQuota } from "@/config/team"; import { DATE_DIMENSION_ENUMS } from "@/lib/enums"; import { fetcher } from "@/lib/utils"; import { @@ -19,7 +20,7 @@ import { EmptyPlaceholder } from "@/components/shared/empty-placeholder"; import { DailyPVUVChart } from "./meta-chart"; export interface UrlMetaProps { - user: Pick; + user: Pick; action: string; urlId: string; } @@ -57,7 +58,13 @@ export default function UserUrlMetaInfo({ user, action, urlId }: UrlMetaProps) { {DATE_DIMENSION_ENUMS.map((e) => ( - + TeamPlanQuota[user.team!].SL_AnalyticsRetention + } + key={e.value} + value={e.value} + > {e.label} ))} @@ -74,6 +81,7 @@ export default function UserUrlMetaInfo({ user, action, urlId }: UrlMetaProps) { data={data} timeRange={timeRange} setTimeRange={setTimeRange} + user={user} /> ); diff --git a/app/(protected)/dashboard/urls/page.tsx b/app/(protected)/dashboard/urls/page.tsx index 28c3a6d..94fcefa 100644 --- a/app/(protected)/dashboard/urls/page.tsx +++ b/app/(protected)/dashboard/urls/page.tsx @@ -32,6 +32,7 @@ export default async function DashboardPage() { name: user.name || "", apiKey: user.apiKey || "", role: user.role, + team: user.team, }} action="/api/url" /> diff --git a/app/(protected)/dashboard/urls/url-list.tsx b/app/(protected)/dashboard/urls/url-list.tsx index fc0dcc1..09aa11b 100644 --- a/app/(protected)/dashboard/urls/url-list.tsx +++ b/app/(protected)/dashboard/urls/url-list.tsx @@ -58,7 +58,7 @@ import { PaginationWrapper } from "@/components/shared/pagination"; import UserUrlMetaInfo from "./meta"; export interface UrlListProps { - user: Pick; + user: Pick; action: string; } @@ -533,7 +533,11 @@ export default function UserUrlsList({ user, action }: UrlListProps) { {isShowStats && selectedUrlId === short.id && ( diff --git a/components/sections/pricing.tsx b/components/sections/pricing.tsx index f8d210b..17d6c2d 100644 --- a/components/sections/pricing.tsx +++ b/components/sections/pricing.tsx @@ -54,7 +54,7 @@ const getBenefits = (plan) => [ icon: , }, { - text: "API Access", + text: "Open API Access", checked: plan.APP_ApiAccess, icon: , }, diff --git a/config/team.ts b/config/team.ts index 2fcb0e7..e263992 100644 --- a/config/team.ts +++ b/config/team.ts @@ -15,7 +15,7 @@ export const TeamPlanQuota = { premium: { SL_TrackedClicks: 1000000, SL_NewLinks: 5000, - SL_AnalyticsRetention: 360, + SL_AnalyticsRetention: 365, SL_Domains: 2, SL_AdvancedAnalytics: true, RC_NewRecords: 2, @@ -28,7 +28,7 @@ export const TeamPlanQuota = { business: { SL_TrackedClicks: 10000000, SL_NewLinks: 10000, - SL_AnalyticsRetention: 360, + SL_AnalyticsRetention: 1000, SL_Domains: 2, SL_AdvancedAnalytics: true, RC_NewRecords: 10, diff --git a/lib/enums.ts b/lib/enums.ts index e4b1070..c9cf5f4 100644 --- a/lib/enums.ts +++ b/lib/enums.ts @@ -302,12 +302,12 @@ export const TIME_RANGES: Record = { }; export const DATE_DIMENSION_ENUMS = [ - { value: "24h", label: "Last 24 Hours" }, - { value: "7d", label: "Last 7 Days" }, - { value: "30d", label: "Last 30 Days" }, - { value: "60d", label: "Last 2 Months" }, - { value: "90d", label: "Last 3 Months" }, - { value: "180d", label: "Last 6 Months" }, - { value: "365d", label: "Last 1 Year" }, - { value: "All", label: "All the time" }, + { value: "24h", label: "Last 24 Hours", key: 1 }, + { value: "7d", label: "Last 7 Days", key: 7 }, + { value: "30d", label: "Last 30 Days", key: 30 }, + { value: "60d", label: "Last 2 Months", key: 60 }, + { value: "90d", label: "Last 3 Months", key: 90 }, + { value: "180d", label: "Last 6 Months", key: 180 }, + { value: "365d", label: "Last 1 Year", key: 365 }, + { value: "All", label: "All the time", key: 1000 }, ] as const; diff --git a/public/sw.js.map b/public/sw.js.map index 654058f..e98d8e5 100644 --- a/public/sw.js.map +++ b/public/sw.js.map @@ -1 +1 @@ -{"version":3,"file":"sw.js","sources":["../../../../../../private/var/folders/9b/3qmyp8zd2xvdspdrp149fyg00000gn/T/84a526ee999ca6e0fd3d092ae1f98419/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-routing@6.6.0/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-core@6.6.0/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAa,EAEZ,CAAA;EAQDC,CAAI,CAAA,CAAA,CAAA,CAACC,CAAW,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAE,CAAA;AAElBC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAyB,EAAE,CAAA;AAI3BC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAA6B,CAAC,CAAA,CAAA,CAAG,CAAE,CAAA,CAAA,CAAA,CAAA,CAAIC,oBAA+B,CAAC,CAAA;EAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAW,EAAC,CAAW,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAO,EAAE,CAAC,CAAA;GAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAe,EAAE,CAAO,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;QAAEC,CAAO,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;QAAEC,CAAQ,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;QAAEC,CAAK,CAAA,CAAA,CAAA,CAAA,CAAA;AAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA;AAAM,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAC,CAAK,CAAA,CAAA,CAAA,CAAA,CAAA;EAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAIF,QAAQ,CAAIA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAQ,CAACG,CAAI,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAK,gBAAgB,CAAE,CAAA,CAAA;AAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,OAAO,CAAIC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAQ,CAACJ,CAAQ,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAACK,IAAI,CAAE,CAAA,CAAA;EAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAM,EAAE,CAAG,CAAA,CAAA,CAAA;EAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAU,EAAE,CAAI,CAAA,CAAA,CAAA,CAAA;YAAEC,CAAO,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAER,CAAQ,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAACQ,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA;AAAQ,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAC,CAAC,CAAA;EAAC,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAOR,QAAQ,CAAA;EAAC,CAAA,CAAA,CAAA,CAAA,CAAA;KAAG,CAAA;AAAE,CAAA,CAAA,CAAC,CAAC,CAAA,CAAE,CAAK,CAAA,CAAA,CAAA,CAAA,CAAC,CAAA;AACxWL,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAA6B,CAAC,CAAA,CAAA,CAAA,CAAA,CAAK,CAAE,CAAA,CAAA,CAAA,CAAA,CAAIc,mBAA8B,CAAC,CAAA;EAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAW,EAAC,CAAK,CAAA,CAAA,CAAA,CAAA,CAAA;EAAEZ,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAO,EAAE,CAAA,CAAA;EAAG,CAAC,CAAC,CAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAK,CAAC,CAAA;;"} \ No newline at end of file +{"version":3,"file":"sw.js","sources":["../../../../../../private/var/folders/9b/3qmyp8zd2xvdspdrp149fyg00000gn/T/b39f7ec81926291e2188b7329b4a3ec8/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-routing@6.6.0/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/songjunxi/Desktop/repos/wrdo-app/wr.do/node_modules/.pnpm/workbox-core@6.6.0/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"} \ No newline at end of file