diff --git a/.vscode/settings.json b/.vscode/settings.json index c3d22a03..00b8e43f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,7 @@ "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { - "source.fixAll.eslint": true, - "source.fixAll.format": true + "source.fixAll.eslint": "explicit", + "source.fixAll.format": "explicit" } } diff --git a/public/images/bxl-github.svg b/public/images/bxl-github.svg new file mode 100644 index 00000000..905bdd3a --- /dev/null +++ b/public/images/bxl-github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/bxs-download.svg b/public/images/bxs-download.svg new file mode 100644 index 00000000..416efdf4 --- /dev/null +++ b/public/images/bxs-download.svg @@ -0,0 +1 @@ + diff --git a/public/images/social-media/bx-filter-alt.svg b/public/images/social-media/bx-filter-alt.svg new file mode 100644 index 00000000..f31c1a05 --- /dev/null +++ b/public/images/social-media/bx-filter-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/package/page.tsx b/src/app/package/page.tsx deleted file mode 100644 index d7bf0a28..00000000 --- a/src/app/package/page.tsx +++ /dev/null @@ -1,432 +0,0 @@ -"use client"; - -import React from "react"; -import statsList from "../projects/assets/stats.json"; -import Link from "next/link"; -import npm from "../../../public/images/social-media/npm-svgrepo-com.svg"; -import expand from "../../../public/images/social-media/expand-wide-svgrepo-com.svg"; -import Image from "next/image"; -import { Dialog, Transition } from "@headlessui/react"; -import { Fragment, useState } from "react"; -import moment from "moment"; - -type stats = { - downloads: download[]; -}; - -type download = { - downloads: number; - day: string; -}; - -const Stats = () => { - const [startDate, setStartDate] = useState(moment().format("YYYY-MM-DD")); - const [endDate, setEndDate] = useState(moment().format("YYYY-MM-DD")); - const [count, setCount] = useState(0); - const [isOpen, setIsOpen] = useState(false); - const [npmPackage, setNpmPackage] = useState({ - name: "fmdapi-node-weaver", - day: 0, - week: 3, - year: 70, - total: 70, - }); - const [packages, setPackages] = useState(statsList); - function closeModal() { - setIsOpen(false); - } - - function openModal() { - setIsOpen(true); - } - - // Function to fetch download statistics for a given package and period - async function fetchDownloadStats(packageName: string, period: string) { - const url = `https://api.npmjs.org/downloads/range/${period}/@mindfiredigital/${packageName}`; - const response = await fetch(url); - - if (!response.ok) { - console.log( - `Failed to fetch download stats for ${packageName} (${period}): ${response.statusText}` - ); - } - - const data = await response.json(); - return data; - } - - // Function to calculate average downloads from the statistics - function calculateDownloads(stats: stats): number { - return stats.downloads.reduce( - (accumulator, download) => accumulator + download.downloads, - 0 - ); - } - - // Function to fetch and process statistics for a package and period - async function getStats(packageName: string, period: string) { - try { - // Fetch download statistics - const stats = await fetchDownloadStats(packageName, period); - - // Check if stats exist - if (!stats || !stats.package) return 0; - - // Calculate average downloads - return stats; - } catch (error) { - // Log and handle errors - console.error(`${packageName} not present`); - return 0; - } - } - function handleChange( - event: React.ChangeEvent, - _package: { - name: string; - day: number; - week: number; - year: number; - total: number; - } - ) { - const range: { start: string; end: string } = getDateRange( - event.target.value as string - ); - getStats(_package.name, `${range?.start}:${range?.end}`).then((res) => { - const count = calculateDownloads(res); - console.log(count); - setPackages( - packages.map((npmPackage) => { - if (npmPackage.name === _package.name) { - npmPackage.total = count; - } - return npmPackage; - }) - ); - }); - } - - function formatDate(date: Date) { - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, "0"); - const day = String(date.getDate()).padStart(2, "0"); - return `${year}-${month}-${day}`; - } - - function getDateRange(range: string) { - const currentDate = new Date(); - const currentYear = currentDate.getFullYear(); - const currentMonth = currentDate.getMonth(); - const currentDay = currentDate.getDate(); - - switch (range.toLowerCase()) { - case "today": { - return { - start: formatDate(new Date(currentYear, currentMonth, currentDay)), - end: formatDate(new Date(currentYear, currentMonth, currentDay)), - }; - } - case "yesterday": { - const yesterdayDate = new Date( - currentYear, - currentMonth, - currentDay - 1 - ); - return { - start: formatDate(yesterdayDate), - end: formatDate(yesterdayDate), - }; - } - case "last month": { - const lastMonthStartDate = new Date(currentYear, currentMonth - 1, 1); - const lastMonthEndDate = new Date(currentYear, currentMonth, 0); - return { - start: formatDate(lastMonthStartDate), - end: formatDate(lastMonthEndDate), - }; - } - case "last quarter": { - const quarterStartMonth = Math.floor(currentMonth / 3) * 3; // Get the start month of the current quarter - const lastQuarterStartDate = new Date( - currentYear, - quarterStartMonth - 3, - 1 - ); - const lastQuarterEndDate = new Date(currentYear, quarterStartMonth, 0); - return { - start: formatDate(lastQuarterStartDate), - end: formatDate(lastQuarterEndDate), - }; - } - case "this year": { - const thisYearStartDate = new Date(currentYear, 0, 1); - return { - start: formatDate(thisYearStartDate), - end: formatDate(currentDate), - }; - } - case "this month": { - const thisMonthStartDate = new Date(currentYear, currentMonth, 1); - return { - start: formatDate(thisMonthStartDate), - end: formatDate(currentDate), - }; - } - default: - return { - start: "1000-01-01", - end: "3000-01-01", - }; - } - } - - const generateChart = async () => { - const stats = await fetchDownloadStats( - npmPackage.name, - `${startDate}:${endDate}` - ); - setCount(calculateDownloads(stats)); - }; - - return ( - - Download Statistics - - {packages.map((_package) => ( - - - - - {_package.name.replaceAll("-", " ")} - - - - - - - - - - { - openModal(); - setNpmPackage(_package); - }} - > - - - - - - - - - { - handleChange(e, _package); - }} - > - Range - Today - Yesterday - Last month - last quarter - this year - Total - this month - - - - - - - - {_package.total} - - - - - Total Downloads - - - - - - - ))} - - - - - - - - - - - - - - {npmPackage.name.replaceAll("-", " ")} - - - - Downloads - - - - - {npmPackage.day} - - - - - Daily - - - - - - - {npmPackage.week} - - - - - Weekly - - - - - - - {npmPackage.year} - - - - - Yearly - - - - - - - - - Daily Downloads Line Chart - - - - - Start Date: - - setStartDate(e.target.value)} - /> - - - - End Date: - - setEndDate(e.target.value)} - /> - - - - - Generate Chart - - - - - - - {count} - - - - - total - - - - - - - - - - - - - - - ); -}; - -export default Stats; diff --git a/src/app/packages/page.tsx b/src/app/packages/page.tsx new file mode 100644 index 00000000..2b92c800 --- /dev/null +++ b/src/app/packages/page.tsx @@ -0,0 +1,518 @@ +"use client"; + +import React, { useEffect, useState, Fragment } from "react"; +import statsList from "../projects/assets/stats.json"; +import Link from "next/link"; +import npm from "../../../public/images/social-media/npm-svgrepo-com.svg"; +import filter from "../../../public/images/social-media/bx-filter-alt.svg"; +import download from "../../../public/images/bxs-download.svg"; +import github from "../../../public/images/bxl-github.svg"; +import Image from "next/image"; +import { Dialog, Transition } from "@headlessui/react"; +import moment from "moment"; + +type stats = { + downloads: download[]; +}; + +type download = { + downloads: number; + day: string; +}; + +const Stats = () => { + const [startDate, setStartDate] = useState(moment().format("YYYY-MM-DD")); + const [endDate, setEndDate] = useState(moment().format("YYYY-MM-DD")); + + const [count, setCount] = useState(0); + const [selectedRange, setSelectedRange] = useState(false); + const [isOpen, setIsOpen] = useState(false); + const [npmPackage, setNpmPackage] = useState({ + name: "fmdapi-node-weaver", + day: 0, + week: 3, + year: 70, + total: 70, + }); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [packages, setPackages] = useState(statsList); + // const [allPackage, setAllPackage] = useState(packageList); + + function closeModal() { + setIsOpen(false); + setCount(0); + setSelectedRange(false); + } + + function openModal() { + setIsOpen(true); + } + + // Function to fetch download statistics for a given package and period + async function fetchDownloadStats(packageName: string, period: string) { + const url = `https://api.npmjs.org/downloads/range/${period}/@mindfiredigital/${packageName}`; + const response = await fetch(url); + + if (!response.ok) { + console.log( + `Failed to fetch download stats for ${packageName} (${period}): ${response.statusText}` + ); + } + + const data = await response.json(); + return data; + } + + function calculateDownloads(stats: stats): number { + if (!stats || !stats.downloads) { + return 0; // Return 0 if stats or stats.downloads is undefined + } + return stats.downloads.reduce( + (accumulator, download) => accumulator + download.downloads, + 0 + ); + } + + // Function to fetch and process statistics for a package and period + async function getStats(packageName: string, period: string) { + try { + // Fetch download statistics + const stats = await fetchDownloadStats(packageName, period); + + // Check if stats exist + if (!stats || !stats.package) return 0; + + // Calculate average downloads + return stats; + } catch (error) { + // Log and handle errors + console.error(`${packageName} not present`); + return 0; + } + } + function handleChange( + event: React.ChangeEvent, + _package: { + name: string; + day: number; + week: number; + year: number; + total: number; + } + ) { + const range: { start: string; end: string } = getDateRange( + event.target.value as string + ); + getStats(_package.name, `${range?.start}:${range?.end}`).then((res) => { + const count = calculateDownloads(res); + // console.log(count); + + packages.map((npmPackage) => { + if (npmPackage.name === _package.name) { + setCount(count); + } + return npmPackage; + }); + }); + } + + function formatDate(date: Date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + return `${year}-${month}-${day}`; + } + + function getDateRange(range: string) { + const currentDate = new Date(); + const currentYear = currentDate.getFullYear(); + const currentMonth = currentDate.getMonth(); + const currentDay = currentDate.getDate(); + + switch (range.toLowerCase()) { + case "today": { + setSelectedRange(false); + return { + start: formatDate(new Date(currentYear, currentMonth, currentDay)), + end: formatDate(new Date(currentYear, currentMonth, currentDay)), + }; + } + case "yesterday": { + setSelectedRange(false); + const yesterdayDate = new Date( + currentYear, + currentMonth, + currentDay - 1 + ); + return { + start: formatDate(yesterdayDate), + end: formatDate(yesterdayDate), + }; + } + case "last month": { + setSelectedRange(false); + const lastMonthStartDate = new Date(currentYear, currentMonth - 1, 1); + const lastMonthEndDate = new Date(currentYear, currentMonth, 0); + return { + start: formatDate(lastMonthStartDate), + end: formatDate(lastMonthEndDate), + }; + } + case "last quarter": { + setSelectedRange(false); + const quarterStartMonth = Math.floor(currentMonth / 3) * 3; // Get the start month of the current quarter + const lastQuarterStartDate = new Date( + currentYear, + quarterStartMonth - 3, + 1 + ); + const lastQuarterEndDate = new Date(currentYear, quarterStartMonth, 0); + return { + start: formatDate(lastQuarterStartDate), + end: formatDate(lastQuarterEndDate), + }; + } + case "this year": { + setSelectedRange(false); + const thisYearStartDate = new Date(currentYear, 0, 1); + return { + start: formatDate(thisYearStartDate), + end: formatDate(currentDate), + }; + } + case "this month": { + setSelectedRange(false); + const thisMonthStartDate = new Date(currentYear, currentMonth, 1); + return { + start: formatDate(thisMonthStartDate), + end: formatDate(currentDate), + }; + } + case "custom": { + setSelectedRange(true); + setCount(0); + return { + start: formatDate(new Date(currentYear, currentMonth, currentDay)), + end: formatDate(new Date(currentYear, currentMonth, currentDay)), + }; + } + default: + setSelectedRange(false); + return { + start: "1000-01-01", + end: "3000-01-01", + }; + } + } + + const generateChart = async () => { + const stats = await fetchDownloadStats( + npmPackage.name, + `${startDate}:${endDate}` + ); + setCount(calculateDownloads(stats)); + }; + + useEffect(() => { + generateChart(); + }, [startDate, endDate]); + + return ( + + Download Statistics + + {packages.map((package_list) => ( + + + + + {package_list.name.replaceAll("-", " ")} + + + + + { + openModal(); + setNpmPackage(package_list); + }} + title='Filter' + > + + + + + + + + + + + + + {package_list.total} + + + + + Downloads + + + + + + + + + + + + + + + + + + ))} + + + + + + + + + + + + + + + + + + + + + {npmPackage.name.replaceAll("-", " ")} + + + + + Select + + + handleChange(e, npmPackage)} + > + Filter + Total + Today + Yesterday + Last month + This month + Last quarter + This year + + Custom Range + + + + + + + + + + + {selectedRange === true ? ( + + + + + Start Date: + + setStartDate(e.target.value)} + /> + + + + End Date: + + setEndDate(e.target.value)} + /> + + + + + + + + + + {count} + + + + + + Downloads + + + + + + + ) : ( + + + + + + + + {count} + + + + + + Downloads + + + + + + )} + + + + + + + + + + ); +}; + +export default Stats; diff --git a/src/constants/index.ts b/src/constants/index.ts index c8b4f917..19274bc4 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -27,8 +27,8 @@ const navigations: Navigation[] = [ path: ["/contributors"], }, { - name: "Package", - path: ["/package"], + name: "Packages", + path: ["/packages"], }, { name: "GitHub", diff --git a/updateProject.mjs b/updateProject.mjs index dc5f6192..40569664 100644 --- a/updateProject.mjs +++ b/updateProject.mjs @@ -1,3 +1,4 @@ +/* eslint-disable no-undef */ // updateProjects.mjs import fs from "fs"; import path from "path"; @@ -156,6 +157,7 @@ async function updateProjects() { const contributionsMap = {}; for (const repo in contributorsObject) { + // eslint-disable-next-line no-prototype-builtins if (contributorsObject.hasOwnProperty(repo)) { contributorsObject[repo].forEach((contributor) => { if (contributor.login === "github-actions[bot]") {
- Total Downloads -
- Daily -
- Weekly -
- Yearly -
- total -
Downloads
+ Select +
+ Downloads +