diff --git a/country.mmdb b/country.mmdb index b71dea2..f73ff6d 100644 Binary files a/country.mmdb and b/country.mmdb differ diff --git a/src/routes/analytic/index.ts b/src/routes/analytic/index.ts index dd81f4e..5a23a5c 100644 --- a/src/routes/analytic/index.ts +++ b/src/routes/analytic/index.ts @@ -7,10 +7,6 @@ interface Count { key: string; total: number; } -interface PageCount { - page: string; - count: number; -} export const analytic = (app: Elysia) => app @@ -83,49 +79,27 @@ export const analytic = (app: Elysia) => const fromDate = new Date(query.from); const toDate = new Date(query.to); - const filteredVisitors = await prisma.analytic.findMany({ + const visitors = await prisma.analytic.findMany({ where: { createdAt: { gte: fromDate, lte: toDate, }, - AND: { - websitesId: query.id, - }, + websitesId: query.id, }, select: { createdAt: true, }, }); - const visitorsCounts: Count[] = []; - const currentDate = new Date(fromDate); - - while (currentDate <= toDate) { - const formattedDate = currentDate.toISOString().split("T")[0]; - const count = filteredVisitors.filter((visitor) => { - const visitorDate = visitor.createdAt.toISOString().split("T")[0]; - return visitorDate === formattedDate; - }).length; - - visitorsCounts.push({ - key: formattedDate, - total: count, - }); - - currentDate.setDate(currentDate.getDate() + 1); - } - - const filteredPageViews = await prisma.analyticPage.findMany({ + const pageViews = await prisma.analyticPage.findMany({ where: { createdAt: { gte: fromDate, lte: toDate, }, - AND: { - analytic: { - websitesId: query.id, - }, + analytic: { + websitesId: query.id, }, }, select: { @@ -133,24 +107,32 @@ export const analytic = (app: Elysia) => }, }); + const visitorsCounts: Count[] = []; const pageViewsCounts: Count[] = []; - const currentDatePageViews = new Date(fromDate); - - while (currentDatePageViews <= toDate) { - const formattedDate = currentDatePageViews - .toISOString() - .split("T")[0]; - const count = filteredPageViews.filter((pageView) => { - const pageViewDate = pageView.createdAt.toISOString().split("T")[0]; - return pageViewDate === formattedDate; - }).length; - - pageViewsCounts.push({ - key: formattedDate, - total: count, - }); - - currentDatePageViews.setDate(currentDatePageViews.getDate() + 1); + + const counts: { + [key: string]: { visitors: number; pageViews: number }; + } = {}; + + for (const visitor of visitors) { + const date = visitor.createdAt.toISOString().split("T")[0]; + if (!counts[date]) { + counts[date] = { visitors: 0, pageViews: 0 }; + } + counts[date].visitors++; + } + + for (const pageView of pageViews) { + const date = pageView.createdAt.toISOString().split("T")[0]; + if (!counts[date]) { + counts[date] = { visitors: 0, pageViews: 0 }; + } + counts[date].pageViews++; + } + + for (const [key, { visitors, pageViews }] of Object.entries(counts)) { + visitorsCounts.push({ key, total: visitors }); + pageViewsCounts.push({ key, total: pageViews }); } return { @@ -181,55 +163,33 @@ export const analytic = (app: Elysia) => }; } - // const startDate = new Date("1970-01-01T00:00:00.000Z"); - // const endDate = new Date("2023-06-29T00:10:06.318Z"); - const startDate = new Date(query.from); const endDate = new Date(query.to); - const filteredPrismaData = await prisma.analyticPage.findMany({ + const filteredPrismaData = await prisma.analyticPage.groupBy({ + by: ["page"], + _count: { + page: true, + }, where: { createdAt: { gte: startDate, lte: endDate, }, - AND: { - analytic: { - websitesId: query.id, - }, + analytic: { + websitesId: query.id, }, }, orderBy: { - page: "asc", - }, - select: { - page: true, + _count: { + page: "desc", + }, }, }); - - const getPageCountArray = ( - data: { page: string }[] - ): { page: string; count: number }[] => { - const pageCountMap: { [page: string]: number } = {}; - - data.forEach((item) => { - const { page } = item; - if (pageCountMap[page]) { - pageCountMap[page]++; - } else { - pageCountMap[page] = 1; - } - }); - - const result: { page: string; count: number }[] = []; - for (const page in pageCountMap) { - result.push({ page, count: pageCountMap[page] }); - } - - return result.sort((a, b) => b.count - a.count); - }; - - const filteredData = getPageCountArray(filteredPrismaData); + const filteredData = filteredPrismaData.map((item) => ({ + page: item.page, + count: item._count.page, + })); return { success: true, @@ -259,47 +219,29 @@ export const analytic = (app: Elysia) => const startDate = new Date(query.from); const endDate = new Date(query.to); - const filteredPrismaData = await prisma.analytic.findMany({ + const filteredPrismaData = await prisma.analytic.groupBy({ + by: ["referrer"], + _count: { + referrer: true, + }, where: { createdAt: { gte: startDate, lte: endDate, }, - AND: { - websitesId: query.id, - }, + websitesId: query.id, }, orderBy: { - referrer: "asc", - }, - select: { - referrer: true, + _count: { + referrer: "desc", + }, }, }); - const getPageCountArray = ( - data: { referrer: string }[] - ): { referrer: string; count: number }[] => { - const CountMap: { [referrer: string]: number } = {}; - - data.forEach((item) => { - const { referrer } = item; - if (CountMap[referrer]) { - CountMap[referrer]++; - } else { - CountMap[referrer] = 1; - } - }); - - const result: { referrer: string; count: number }[] = []; - for (const referrer in CountMap) { - result.push({ referrer, count: CountMap[referrer] }); - } - - return result.sort((a, b) => b.count - a.count); - }; - - const filteredData = getPageCountArray(filteredPrismaData); + const filteredData = filteredPrismaData.map((item) => ({ + referrer: item.referrer, + count: item._count.referrer, + })); return { success: true, @@ -329,48 +271,28 @@ export const analytic = (app: Elysia) => const startDate = new Date(query.from); const endDate = new Date(query.to); - const filteredPrismaData = await prisma.analytic.findMany({ + const filteredPrismaData = await prisma.analytic.groupBy({ + by: ["country"], + _count: { + country: true, + }, where: { createdAt: { gte: startDate, lte: endDate, }, - AND: { - websitesId: query.id, - }, + websitesId: query.id, }, orderBy: { - country: "asc", - }, - select: { - country: true, + _count: { + country: "desc", + }, }, }); - - const getPageCountArray = ( - data: { country: string }[] - ): { country: string; count: number }[] => { - const CountMap: { [country: string]: number } = {}; - - data.forEach((item) => { - const { country } = item; - if (CountMap[country]) { - CountMap[country]++; - } else { - CountMap[country] = 1; - } - }); - - const result: { country: string; count: number }[] = []; - for (const country in CountMap) { - result.push({ country, count: CountMap[country] }); - } - - return result.sort((a, b) => b.count - a.count); - }; - - const filteredData = getPageCountArray(filteredPrismaData); - + const filteredData = filteredPrismaData.map((item) => ({ + country: item.country, + count: item._count.country, + })); return { success: true, message: "Fetched countries", @@ -399,48 +321,29 @@ export const analytic = (app: Elysia) => const startDate = new Date(query.from); const endDate = new Date(query.to); - const filteredPrismaData = await prisma.analytic.findMany({ + const filteredPrismaData = await prisma.analytic.groupBy({ + by: ["os"], + _count: { + os: true, + }, where: { createdAt: { gte: startDate, lte: endDate, }, - AND: { - websitesId: query.id, - }, + websitesId: query.id, }, orderBy: { - os: "asc", - }, - select: { - os: true, + _count: { + os: "desc", + }, }, }); - const getPageCountArray = ( - data: { os: string }[] - ): { os: string; count: number }[] => { - const CountMap: { [os: string]: number } = {}; - - data.forEach((item) => { - const { os } = item; - if (CountMap[os]) { - CountMap[os]++; - } else { - CountMap[os] = 1; - } - }); - - const result: { os: string; count: number }[] = []; - for (const os in CountMap) { - result.push({ os, count: CountMap[os] }); - } - - return result.sort((a, b) => b.count - a.count); - }; - - const filteredData = getPageCountArray(filteredPrismaData); - + const filteredData = filteredPrismaData.map((item) => ({ + os: item.os, + count: item._count.os, + })); return { success: true, message: "Fetched os", @@ -469,47 +372,29 @@ export const analytic = (app: Elysia) => const startDate = new Date(query.from); const endDate = new Date(query.to); - const filteredPrismaData = await prisma.analytic.findMany({ + const filteredPrismaData = await prisma.analytic.groupBy({ + by: ["browser"], + _count: { + browser: true, + }, where: { createdAt: { gte: startDate, lte: endDate, }, - AND: { - websitesId: query.id, - }, + websitesId: query.id, }, orderBy: { - browser: "asc", - }, - select: { - browser: true, + _count: { + browser: "desc", + }, }, }); - const getPageCountArray = ( - data: { browser: string }[] - ): { browser: string; count: number }[] => { - const CountMap: { [browser: string]: number } = {}; - - data.forEach((item) => { - const { browser } = item; - if (CountMap[browser]) { - CountMap[browser]++; - } else { - CountMap[browser] = 1; - } - }); - - const result: { browser: string; count: number }[] = []; - for (const browser in CountMap) { - result.push({ browser, count: CountMap[browser] }); - } - - return result.sort((a, b) => b.count - a.count); - }; - - const filteredData = getPageCountArray(filteredPrismaData); + const filteredData = filteredPrismaData.map((item) => ({ + browser: item.browser, + count: item._count.browser, + })); return { success: true, diff --git a/src/routes/home/index.ts b/src/routes/home/index.ts index 5835b66..9156217 100644 --- a/src/routes/home/index.ts +++ b/src/routes/home/index.ts @@ -12,20 +12,24 @@ export const home = (app: Elysia) => async ({ request, body, set }) => { try { const geo = await Reader.open("country.mmdb", {}); - const ip = - Bun.env.NODE_ENV === "production" - ? request.headers.get("x-forwarded-for") - : "149.102.229.225"; + let ip = request.headers.get("x-forwarded-for") || "149.102.229.225"; if (!ip) { set.status = 400; - throw new Error("Something went wrong"); + return "Something went wrong"; + } + + // handle edge cases where ip is an array or has a comma + if (Array.isArray(ip)) { + ip = ip[0] as string; + } + + if (ip?.includes(",")) { + ip = ip.split(",")[0] as string; } const country = await extractCountry(ip, geo); const countryIsoCode = await extractCountryIsoCode(ip, geo); - if (!geo.country(ip)) { - throw new Error("Something went wrong"); - } + const ua = parser(request.headers.get("user-agent") ?? "Unknown"); const checkWebsiteId = await prisma.websites.findUnique({ @@ -77,7 +81,7 @@ export const home = (app: Elysia) => } catch (error) { console.log(error); set.status = 500; - throw new Error("Something went wrong"); + return "Something went wrong"; } set.status = 200; return "success";