diff options
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/_componenets/Footer/Footer.tsx | 27 | ||||
| -rw-r--r-- | src/app/_componenets/SubscriberTable/SubscriberTable.tsx | 67 | ||||
| -rw-r--r-- | src/app/_componenets/SubscriberTable/SubscriberTableRow.tsx | 35 | ||||
| -rw-r--r-- | src/app/_componenets/TitleBar/TitleBar.tsx | 18 | ||||
| -rw-r--r-- | src/app/globals.css | 24 | ||||
| -rw-r--r-- | src/app/layout.tsx | 9 | ||||
| -rw-r--r-- | src/app/page.tsx | 138 |
7 files changed, 181 insertions, 137 deletions
diff --git a/src/app/_componenets/Footer/Footer.tsx b/src/app/_componenets/Footer/Footer.tsx new file mode 100644 index 0000000..f23c677 --- /dev/null +++ b/src/app/_componenets/Footer/Footer.tsx @@ -0,0 +1,27 @@ + +import React from 'react'; + +const Footer = () => { + return ( + <footer> + <div className="text-center"> + <p className="text-bold"> + Information + </p> + <p className="text-m"> + Information is collected once per hour. Data collection will stop once a liver has graduated. + <br/> + This page is in now way affiliated with ANYCOLOR or with any of the channels listed here. + <br/> + Date Started: 2023-03-26 + </p> + <p className="p-4"> + <a className="hover:underline text-bold" href="https://github.com/pinapelz/Nijitrack">Source Code</a><br/> + We are currently under construction! + </p> + </div> + </footer> + ); +}; + +export default Footer; diff --git a/src/app/_componenets/SubscriberTable/SubscriberTable.tsx b/src/app/_componenets/SubscriberTable/SubscriberTable.tsx new file mode 100644 index 0000000..a538bdd --- /dev/null +++ b/src/app/_componenets/SubscriberTable/SubscriberTable.tsx @@ -0,0 +1,67 @@ +import React from "react"; +import Image from "next/image"; +import ChannelRow from "./SubscriberTableRow"; + +interface ChannelDataProp { + channel_name: string; + profile_pic: string; + subscribers: number; + sub_org: string; + video_count: number; + day_diff: number; +} + +interface SubscriberDataTableProp { + channel_data: ChannelDataProp[]; + timestamp: string; +} + +const DataTable = ({ channel_data, timestamp }: SubscriberDataTableProp) => { + if (!channel_data) { + return null; + } + +return ( + <> + <div className="text-center sm:mt-5"> + <h1 className="text-2xl font-bold text-gray-800">Subscriber Count</h1> + <p className="text-gray-500 text-sm">Last Updated: {timestamp}</p> + </div> + <div className="px-2 sm:px-48 py-4 sm:py-8 relative shadow-md rounded-l text-left overflow-auto"> + <table className="w-full text-m sm:text-xl text-black bg-white"> + <thead className="text-m sm:text-lg text-white" style={{ backgroundColor: '#2D4B71' }}> + <tr> + <th scope="col" className="py-1 px-1 sm:px-3 hidden sm:table-cell"> + RANK + </th> + <th scope="col" className="py-1 px-1 sm:px-3"> + CHANNEL + </th> + <th scope="col" className="py-1 px-1 sm:px-3 hidden sm:table-cell"> + GROUP + </th> + <th scope="col" className="py-1 px-1 sm:px-3 hidden sm:table-cell"> + VIDEO COUNT + </th> + <th scope="col" className="py-1 px-1 sm:px-3"> + SUBSCRIBERS + </th> + <th scope="col" className="py-1 px-1 sm:px-3"> + DIFF (24H) + </th> + </tr> + </thead> + <tbody> + {channel_data.map((channel, index) => ( + <ChannelRow key={index} channel={channel} index={index} /> + ))} + </tbody> + </table> + </div> + </> +); +}; + +export default DataTable; +export type { SubscriberDataTableProp }; +export type { ChannelDataProp }; diff --git a/src/app/_componenets/SubscriberTable/SubscriberTableRow.tsx b/src/app/_componenets/SubscriberTable/SubscriberTableRow.tsx new file mode 100644 index 0000000..619a5b8 --- /dev/null +++ b/src/app/_componenets/SubscriberTable/SubscriberTableRow.tsx @@ -0,0 +1,35 @@ +"use client" +import React from 'react'; +import Image from 'next/image'; +import { ChannelDataProp } from './SubscriberTable'; + +interface ChannelRowProps { + channel: ChannelDataProp; + index: number; +} + +const ChannelRow: React.FC<ChannelRowProps> = ({ channel, index }) => ( +<tr key={index} className="border-b hover:bg-gray-100 cursor-pointer"> + <td className="py-3 px-1 sm:px-3 hidden sm:table-cell">{index + 1}</td> + <td className="py-3 px-1 sm:px-3 flex items-center"> + <Image + src={channel.profile_pic} + alt={channel.channel_name} + width={50} + height={50} + className="rounded-full" + /> + <span className="ml-2"> + {channel.channel_name} + </span> + </td> + <td className="py-3 px-1 sm:px-3 hidden sm:table-cell">{channel.sub_org}</td> + <td className="py-3 px-1 sm:px-3 hidden sm:table-cell">{channel.video_count}</td> + <td className="py-3 px-1 sm:px-3">{Number(channel.subscribers).toLocaleString()}</td> + <td className="py-3 px-1 sm:px-3"> + {channel.day_diff > 0 ? `+${Number(channel.day_diff).toLocaleString()}` : Number(channel.day_diff).toLocaleString()} + </td> + </tr> +); + +export default ChannelRow;
\ No newline at end of file diff --git a/src/app/_componenets/TitleBar/TitleBar.tsx b/src/app/_componenets/TitleBar/TitleBar.tsx new file mode 100644 index 0000000..27bebfc --- /dev/null +++ b/src/app/_componenets/TitleBar/TitleBar.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import Image from 'next/image'; + +interface TitleBarProps { + title: string; +} + +const TitleBar: React.FC<TitleBarProps> = ({ title }) => { + return ( + <div className="title-bar p-5 shadow-md" style={{ backgroundColor: '#2D4B71' }}> + <div style={{ width: 'fit-content', whiteSpace: 'nowrap', overflow: 'hidden' }}> + <span className="text-white text-4xl font-bold">{title}</span> + </div> + </div> + ); +}; + +export default TitleBar;
\ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css index fd81e88..b5c61c9 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,27 +1,3 @@ @tailwind base; @tailwind components; @tailwind utilities; - -:root { - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; -} - -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - } -} - -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 40e027f..ae0349f 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,12 +1,13 @@ import type { Metadata } from 'next' import { Inter } from 'next/font/google' +import Footer from './_componenets/Footer/Footer' import './globals.css' const inter = Inter({ subsets: ['latin'] }) export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', + title: 'Nijitracker - Nijisanji Subscriber Tracker', + description: 'Nijitracker, historical subscriber data for members of Nijisanji', } export default function RootLayout({ @@ -16,7 +17,9 @@ export default function RootLayout({ }) { return ( <html lang="en"> - <body className={inter.className}>{children}</body> + <body className={inter.className}>{children} + <Footer /> + </body> </html> ) } diff --git a/src/app/page.tsx b/src/app/page.tsx index b973266..81c12b6 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,113 +1,31 @@ -import Image from 'next/image' +import SubscriberTable, {SubscriberDataTableProp} from './_componenets/SubscriberTable/SubscriberTable'; +import TitleBar from './_componenets/TitleBar/TitleBar'; -export default function Home() { - return ( - <main className="flex min-h-screen flex-col items-center justify-between p-24"> - <div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex"> - <p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30"> - Get started by editing - <code className="font-mono font-bold">src/app/page.tsx</code> - </p> - <div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none"> - <a - className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0" - href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app" - target="_blank" - rel="noopener noreferrer" - > - By{' '} - <Image - src="/vercel.svg" - alt="Vercel Logo" - className="dark:invert" - width={100} - height={24} - priority - /> - </a> - </div> - </div> - - <div className="relative flex place-items-center before:absolute before:h-[300px] before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]"> - <Image - className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert" - src="/next.svg" - alt="Next.js Logo" - width={180} - height={37} - priority - /> - </div> - - <div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left"> - <a - href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app" - className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30" - target="_blank" - rel="noopener noreferrer" - > - <h2 className={`mb-3 text-2xl font-semibold`}> - Docs{' '} - <span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none"> - -> - </span> - </h2> - <p className={`m-0 max-w-[30ch] text-sm opacity-50`}> - Find in-depth information about Next.js features and API. - </p> - </a> - - <a - href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" - className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30" - target="_blank" - rel="noopener noreferrer" - > - <h2 className={`mb-3 text-2xl font-semibold`}> - Learn{' '} - <span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none"> - -> - </span> - </h2> - <p className={`m-0 max-w-[30ch] text-sm opacity-50`}> - Learn about Next.js in an interactive course with quizzes! - </p> - </a> - - <a - href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app" - className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30" - target="_blank" - rel="noopener noreferrer" - > - <h2 className={`mb-3 text-2xl font-semibold`}> - Templates{' '} - <span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none"> - -> - </span> - </h2> - <p className={`m-0 max-w-[30ch] text-sm opacity-50`}> - Explore starter templates for Next.js. - </p> - </a> +async function Home(){ + const apiUrl = process.env.NEXT_PUBLIC_API_URL + const data: SubscriberDataTableProp = await getData(); + return( + <> + <TitleBar title="Nijitracker" /> + <div className="sm:block hidden mt-4" style={{ overflow: 'hidden', height: '88vh', position: 'relative' }}> + <iframe src={apiUrl} style={{ position: 'absolute', top: 0, left: 0 }} width="100%" height="100%"></iframe> + </div> + <SubscriberTable {...data} /> + </> + ); +} - <a - href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app" - className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30" - target="_blank" - rel="noopener noreferrer" - > - <h2 className={`mb-3 text-2xl font-semibold`}> - Deploy{' '} - <span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none"> - -> - </span> - </h2> - <p className={`m-0 max-w-[30ch] text-sm opacity-50`}> - Instantly deploy your Next.js site to a shareable URL with Vercel. - </p> - </a> - </div> - </main> - ) +async function getData(){ + const apiUrl = process.env.NEXT_PUBLIC_API_URL + const response = await fetch(apiUrl+'/api/subscribers', { + headers: { + 'Cache-Control': 'no-cache' + }, + cache: 'no-cache' + }); + if(!response.ok){ + console.log(response.statusText); + } + return response.json(); } +export default Home;
\ No newline at end of file |
