diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/CompactTable/CompactTable.tsx | 65 | ||||
| -rw-r--r-- | src/components/DataChart/DataChart.tsx | 130 | ||||
| -rw-r--r-- | src/components/Divider/Divider.tsx | 18 | ||||
| -rw-r--r-- | src/components/Footer/Footer.tsx | 48 | ||||
| -rw-r--r-- | src/components/SubscriberTable/SubscriberTable.tsx | 123 | ||||
| -rw-r--r-- | src/components/SubscriberTable/SubscriberTableRow.tsx | 70 | ||||
| -rw-r--r-- | src/components/TitleBar/TitleBar.tsx | 71 | ||||
| -rw-r--r-- | src/components/channel-card.tsx | 131 | ||||
| -rw-r--r-- | src/components/ui/avatar.tsx | 76 | ||||
| -rw-r--r-- | src/components/ui/badge.tsx | 54 | ||||
| -rw-r--r-- | src/components/ui/card.tsx | 125 |
11 files changed, 503 insertions, 408 deletions
diff --git a/src/components/CompactTable/CompactTable.tsx b/src/components/CompactTable/CompactTable.tsx index 64eb4f2..6ec6b7c 100644 --- a/src/components/CompactTable/CompactTable.tsx +++ b/src/components/CompactTable/CompactTable.tsx @@ -1,36 +1,45 @@ -import React from 'react'; +import type React from "react"; interface CompactTableProps { - tableData: { - dates: string[]; - milestones: string[]; - } - + tableData: { + dates: string[]; + milestones: string[]; + }; } const CompactTable: React.FC<CompactTableProps> = ({ tableData }) => { - return ( - <div className="max-w-full mx-auto bg-gray-100 shadow-md rounded-lg overflow-hidden"> - <div className="flex gap-x-4"> - <div className="w-1/2 px-4 py-5"> - <h2 className="text-lg font-semibold text-gray-900">Dates</h2> - <ul className="mt-3"> - {tableData.dates.map((date, index) => ( - <li key={index} className="text-gray-700 text-sm py-1 border-b border-gray-200">{date}</li> - ))} - </ul> - </div> - <div className="w-1/2 px-4 py-5"> - <h2 className="text-lg font-semibold text-gray-900">Milestones</h2> - <ul className="mt-3"> - {tableData.milestones.map((milestone, index) => ( - <li key={index} className="text-gray-700 text-sm py-1 border-b border-gray-200">{milestone.toLocaleString()}</li> - ))} - </ul> - </div> - </div> - </div> - ); + return ( + <div className="max-w-full mx-auto bg-gray-100 shadow-md rounded-lg overflow-hidden"> + <div className="flex gap-x-4"> + <div className="w-1/2 px-4 py-5"> + <h2 className="text-lg font-semibold text-gray-900">Dates</h2> + <ul className="mt-3"> + {tableData.dates.map((date, index) => ( + <li + key={index} + className="text-gray-700 text-sm py-1 border-b border-gray-200" + > + {date} + </li> + ))} + </ul> + </div> + <div className="w-1/2 px-4 py-5"> + <h2 className="text-lg font-semibold text-gray-900">Milestones</h2> + <ul className="mt-3"> + {tableData.milestones.map((milestone, index) => ( + <li + key={index} + className="text-gray-700 text-sm py-1 border-b border-gray-200" + > + {milestone.toLocaleString()} + </li> + ))} + </ul> + </div> + </div> + </div> + ); }; export default CompactTable; diff --git a/src/components/DataChart/DataChart.tsx b/src/components/DataChart/DataChart.tsx index 4f8eecd..3b8304a 100644 --- a/src/components/DataChart/DataChart.tsx +++ b/src/components/DataChart/DataChart.tsx @@ -1,82 +1,82 @@ -import React from "react"; import { - Chart as ChartJS, - CategoryScale, - LinearScale, - PointElement, - LineElement, - Title, - Tooltip, - Legend, + CategoryScale, + Chart as ChartJS, + Legend, + LineElement, + LinearScale, + PointElement, + Title, + Tooltip, } from "chart.js"; +import type React from "react"; import { Line } from "react-chartjs-2"; ChartJS.register( - CategoryScale, - LinearScale, - PointElement, - LineElement, - Title, - Tooltip, - Legend + CategoryScale, + LinearScale, + PointElement, + LineElement, + Title, + Tooltip, + Legend, ); interface DataChartProps { - chartData?: any; - graphTitle?: string; - fullData?: boolean; - overrideBorderColor?: string - overrideBGColor?: string + chartData?: any; + graphTitle?: string; + fullData?: boolean; + overrideBorderColor?: string; + overrideBGColor?: string; } const DataChart: React.FC<DataChartProps> = ({ - chartData, - graphTitle, - fullData, - overrideBGColor, - overrideBorderColor + chartData, + graphTitle, + fullData, + overrideBGColor, + overrideBorderColor, }) => { - const options = { - responsive: true, - plugins: { - legend: { - position: "top" as const, - }, - title: { - display: true, - text: graphTitle || "Historical Subscriber Data", - font: { - size: 18, - }, - }, - }, - scales: { - x: { - ticks: { - autoSkip: true, - maxTicksLimit: 10, - }, - }, - }, - }; + const options = { + responsive: true, + plugins: { + legend: { + position: "top" as const, + }, + title: { + display: true, + text: graphTitle || "Historical Subscriber Data", + font: { + size: 18, + }, + }, + }, + scales: { + x: { + ticks: { + autoSkip: true, + maxTicksLimit: 10, + }, + }, + }, + }; - const data = { - labels: chartData.labels, - datasets: [ - { - label: "Subscriber Count", - data: chartData.datasets, - borderColor: overrideBorderColor||"rgb(255, 99, 132)", - backgroundColor: overrideBGColor||"rgba(255, 99, 132, 0.5)", - }, - ], - }; + const data = { + labels: chartData.labels, + datasets: [ + { + label: "Subscriber Count", + data: chartData.datasets, + borderColor: overrideBorderColor || "rgb(255, 99, 132)", + backgroundColor: overrideBGColor || "rgba(255, 99, 132, 0.5)", + }, + ], + }; - if (!fullData) { - return <Line options={options} data={data} />; - } else { - return <Line options={options} data={chartData} />; - } + if (!fullData) { + return <Line options={options} data={data} />; + } else { + return <Line options={options} data={chartData} />; + } }; export default DataChart; diff --git a/src/components/Divider/Divider.tsx b/src/components/Divider/Divider.tsx index 55e6844..e2ef41b 100644 --- a/src/components/Divider/Divider.tsx +++ b/src/components/Divider/Divider.tsx @@ -1,12 +1,14 @@ interface DividerProps { - text: string; + text: string; } const Divider = (props: DividerProps) => { - return ( - <div className="flex flex-row items-center justify-center bg-black h-24 mt-8"> - <div className="px-2 text-white text-4xl font-extrabold">{props.text}</div> - </div> - ) -} -export default Divider;
\ No newline at end of file + return ( + <div className="flex flex-row items-center justify-center bg-black h-24 mt-8"> + <div className="px-2 text-white text-4xl font-extrabold"> + {props.text} + </div> + </div> + ); +}; +export default Divider; diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx index 22573cd..8686e4c 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/components/Footer/Footer.tsx @@ -1,26 +1,32 @@ - -import React from 'react'; +import React from "react"; const Footer = () => { - return ( - <footer> - <div className="text-center mt-4"> - <p className="font-bold"> - Information - </p> - <p className="text-m"> - Information is collected once per hour. Data collection will stop upon graduation - <br/> - This page is in no way affiliated with Phase Connect or with any of the channels listed here. - <br/> - Data Collection Started: 2022-04-01 (Earlier data may not be fully accurate) - </p> - <p className="p-4"> - <a className="hover:underline text-bold" href="https://github.com/pinapelz/Nijitrack">Source Code</a><br/> - </p> - </div> - </footer> - ); + return ( + <footer> + <div className="text-center mt-4"> + <p className="font-bold">Information</p> + <p className="text-m"> + Information is collected once per hour. Data collection will stop upon + graduation + <br /> + This page is in no way affiliated with Phase Connect or with any of + the channels listed here. + <br /> + Data Collection Started: 2022-04-01 (Earlier data may not be fully + accurate) + </p> + <p className="p-4"> + <a + className="hover:underline text-bold" + href="https://github.com/pinapelz/Nijitrack" + > + Source Code + </a> + <br /> + </p> + </div> + </footer> + ); }; export default Footer; diff --git a/src/components/SubscriberTable/SubscriberTable.tsx b/src/components/SubscriberTable/SubscriberTable.tsx index b07c75d..05080ca 100644 --- a/src/components/SubscriberTable/SubscriberTable.tsx +++ b/src/components/SubscriberTable/SubscriberTable.tsx @@ -2,67 +2,82 @@ import React from "react"; import ChannelRow from "./SubscriberTableRow"; interface ChannelDataProp { - channel_name: string; - profile_pic: string; - subscribers: number; - sub_org: string; - video_count: number; - day_diff: number; - views: number; + channel_name: string; + profile_pic: string; + subscribers: number; + sub_org: string; + video_count: number; + day_diff: number; + views: number; } interface SubscriberDataTableProp { - channel_data: ChannelDataProp[]; - timestamp: string; + channel_data: ChannelDataProp[]; + timestamp: string; } const DataTable = ({ channel_data, timestamp }: SubscriberDataTableProp) => { - if (!channel_data) { - return null; - } + 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 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 rounded-md" style={{ backgroundColor: 'black' }}> - <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 hidden sm:table-cell"> - VIEW 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> - </> -); + 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 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 rounded-md" + style={{ backgroundColor: "black" }} + > + <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 hidden sm:table-cell" + > + VIEW 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; diff --git a/src/components/SubscriberTable/SubscriberTableRow.tsx b/src/components/SubscriberTable/SubscriberTableRow.tsx index 040c693..595a2c1 100644 --- a/src/components/SubscriberTable/SubscriberTableRow.tsx +++ b/src/components/SubscriberTable/SubscriberTableRow.tsx @@ -1,36 +1,48 @@ -"use client" -import React from 'react'; -import Image from 'next/image'; -import { ChannelDataProp } from './SubscriberTable'; +"use client"; +import Image from "next/image"; +import type React from "react"; +import type { ChannelDataProp } from "./SubscriberTable"; interface ChannelRowProps { - channel: ChannelDataProp; - index: number; + channel: ChannelDataProp; + index: number; } const ChannelRow: React.FC<ChannelRowProps> = ({ channel, index }) => ( -<tr key={index} className="border-b hover:bg-gray-100 cursor-pointer" onClick={() => window.location.href = "/stats/"+channel.channel_name}> - <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 hidden sm:table-cell">{Number(channel.views).toLocaleString()}</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> + <tr + key={index} + className="border-b hover:bg-gray-100 cursor-pointer" + onClick={() => (window.location.href = "/stats/" + channel.channel_name)} + > + <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 hidden sm:table-cell"> + {Number(channel.views).toLocaleString()} + </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 +export default ChannelRow; diff --git a/src/components/TitleBar/TitleBar.tsx b/src/components/TitleBar/TitleBar.tsx index 171e03a..127534e 100644 --- a/src/components/TitleBar/TitleBar.tsx +++ b/src/components/TitleBar/TitleBar.tsx @@ -1,32 +1,51 @@ -import React from 'react'; -import '../TitleBar/TitleBarStyle.css' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faHouse } from '@fortawesome/free-solid-svg-icons' +import type React from "react"; +import "../TitleBar/TitleBarStyle.css"; +import { faHouse } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; interface TitleBarProps { - title: string; - redirectUrl?: string; - showHomeButton?: boolean; - backgroundColor?: string; + title: string; + redirectUrl?: string; + showHomeButton?: boolean; + backgroundColor?: string; } -const TitleBar: React.FC<TitleBarProps> = ({ title, redirectUrl, showHomeButton, backgroundColor }) => { - return ( - <> - <div className="title-bar p-5 shadow-md" style={{ backgroundColor: backgroundColor || '#2D4B71' }}> - <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> - <a href={redirectUrl}> - <span className="text-white text-4xl font-bold" style={{ fontFamily: 'Quantico, sans-serif' }}>{title}</span> - </a> - {showHomeButton && ( - <a href="/" className='text-white text-3xl'> - <FontAwesomeIcon icon={faHouse} /> - </a> - )} - </div> - </div> - </> - ); +const TitleBar: React.FC<TitleBarProps> = ({ + title, + redirectUrl, + showHomeButton, + backgroundColor, +}) => { + return ( + <> + <div + className="title-bar p-5 shadow-md" + style={{ backgroundColor: backgroundColor || "#2D4B71" }} + > + <div + style={{ + display: "flex", + justifyContent: "space-between", + alignItems: "center", + }} + > + <a href={redirectUrl}> + <span + className="text-white text-4xl font-bold" + style={{ fontFamily: "Quantico, sans-serif" }} + > + {title} + </span> + </a> + {showHomeButton && ( + <a href="/" className="text-white text-3xl"> + <FontAwesomeIcon icon={faHouse} /> + </a> + )} + </div> + </div> + </> + ); }; -export default TitleBar;
\ No newline at end of file +export default TitleBar; diff --git a/src/components/channel-card.tsx b/src/components/channel-card.tsx index b66a6e0..c19f492 100644 --- a/src/components/channel-card.tsx +++ b/src/components/channel-card.tsx @@ -1,59 +1,84 @@ -import { AvatarImage, AvatarFallback, Avatar } from "@/components/ui/avatar" -import { CardTitle, CardHeader, CardContent, Card } from "@/components/ui/card" -import { Badge } from "@/components/ui/badge" +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Badge } from "@/components/ui/badge"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; interface ChannelCardProps { - channel_id: string - name: string - avatarUrl: string - subscriberCount: number - videoCount: number - viewCount: number - suborg: string - nextMilestone: string - nextMilestoneDays: string - nextMilestoneDate: string + channel_id: string; + name: string; + avatarUrl: string; + subscriberCount: number; + videoCount: number; + viewCount: number; + suborg: string; + nextMilestone: string; + nextMilestoneDays: string; + nextMilestoneDate: string; } export function ChannelCard(props: ChannelCardProps) { - const { channel_id, name, avatarUrl, subscriberCount, videoCount, viewCount, suborg, nextMilestone, nextMilestoneDays, nextMilestoneDate } = props - return ( - <Card className="w-[500px] shadow-lg rounded-lg overflow-hidden mt-4 py-4"> - <CardHeader> - <div className="flex items-center space-x-4 p-4"> - <Avatar> - <AvatarImage src={avatarUrl}/> - <AvatarFallback>PR</AvatarFallback> - </Avatar> - <div> - <a className="hover:underline" href={`https://youtube.com/channel/${channel_id}`}><CardTitle>{name}</CardTitle></a> - <Badge variant="secondary">{suborg}</Badge> - </div> - </div> - </CardHeader> - <CardContent className="px-4 py-2 space-y-4"> - <div className="flex flex-col items-center"> - <span className="text-l text-gray-600">Subscribers</span> - <span className="font-semibold">{Number(subscriberCount).toLocaleString()}</span> - </div> - <div className="flex flex-col items-center"> - <span className="text-l text-gray-600">Videos</span> - <span className="font-semibold">{videoCount}</span> - </div> - <div className="flex flex-col items-center"> - <span className="text-l text-gray-600">View Count</span> - <span className="font-semibold">{Number(viewCount).toLocaleString()}</span> - </div> - <div className="flex flex-col items-center"> - <span className="text-l text-gray-600">Next Milestone</span> - <span className="font-semibold">{Number(nextMilestone).toLocaleString()}</span> - <div className="flex justify-center items-center"> - <span className="text-sm text-gray-600 px-2">{nextMilestoneDays} days</span> - <span className="text-sm text-gray-600 px-2">{nextMilestoneDate}</span> - </div> - - </div> - </CardContent> - </Card> - ) + const { + channel_id, + name, + avatarUrl, + subscriberCount, + videoCount, + viewCount, + suborg, + nextMilestone, + nextMilestoneDays, + nextMilestoneDate, + } = props; + return ( + <Card className="w-[500px] shadow-lg rounded-lg overflow-hidden mt-4 py-4"> + <CardHeader> + <div className="flex items-center space-x-4 p-4"> + <Avatar> + <AvatarImage src={avatarUrl} /> + <AvatarFallback>PR</AvatarFallback> + </Avatar> + <div> + <a + className="hover:underline" + href={`https://youtube.com/channel/${channel_id}`} + > + <CardTitle>{name}</CardTitle> + </a> + <Badge variant="secondary">{suborg}</Badge> + </div> + </div> + </CardHeader> + <CardContent className="px-4 py-2 space-y-4"> + <div className="flex flex-col items-center"> + <span className="text-l text-gray-600">Subscribers</span> + <span className="font-semibold"> + {Number(subscriberCount).toLocaleString()} + </span> + </div> + <div className="flex flex-col items-center"> + <span className="text-l text-gray-600">Videos</span> + <span className="font-semibold">{videoCount}</span> + </div> + <div className="flex flex-col items-center"> + <span className="text-l text-gray-600">View Count</span> + <span className="font-semibold"> + {Number(viewCount).toLocaleString()} + </span> + </div> + <div className="flex flex-col items-center"> + <span className="text-l text-gray-600">Next Milestone</span> + <span className="font-semibold"> + {Number(nextMilestone).toLocaleString()} + </span> + <div className="flex justify-center items-center"> + <span className="text-sm text-gray-600 px-2"> + {nextMilestoneDays} days + </span> + <span className="text-sm text-gray-600 px-2"> + {nextMilestoneDate} + </span> + </div> + </div> + </CardContent> + </Card> + ); } diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx index 1c69f50..3c884e8 100644 --- a/src/components/ui/avatar.tsx +++ b/src/components/ui/avatar.tsx @@ -1,50 +1,50 @@ -"use client" +"use client"; -import * as React from "react" -import * as AvatarPrimitive from "@radix-ui/react-avatar" +import * as AvatarPrimitive from "@radix-ui/react-avatar"; +import * as React from "react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const Avatar = React.forwardRef< - React.ElementRef<typeof AvatarPrimitive.Root>, - React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> + React.ElementRef<typeof AvatarPrimitive.Root>, + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> >(({ className, ...props }, ref) => ( - <AvatarPrimitive.Root - ref={ref} - className={cn( - "relative flex h-12 w-12 overflow-hidden rounded-full", - className - )} - {...props} - /> -)) -Avatar.displayName = AvatarPrimitive.Root.displayName + <AvatarPrimitive.Root + ref={ref} + className={cn( + "relative flex h-12 w-12 overflow-hidden rounded-full", + className, + )} + {...props} + /> +)); +Avatar.displayName = AvatarPrimitive.Root.displayName; const AvatarImage = React.forwardRef< - React.ElementRef<typeof AvatarPrimitive.Image>, - React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image> + React.ElementRef<typeof AvatarPrimitive.Image>, + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image> >(({ className, ...props }, ref) => ( - <AvatarPrimitive.Image - ref={ref} - className={cn("aspect-square h-full w-full", className)} - {...props} - /> -)) -AvatarImage.displayName = AvatarPrimitive.Image.displayName + <AvatarPrimitive.Image + ref={ref} + className={cn("aspect-square h-full w-full", className)} + {...props} + /> +)); +AvatarImage.displayName = AvatarPrimitive.Image.displayName; const AvatarFallback = React.forwardRef< - React.ElementRef<typeof AvatarPrimitive.Fallback>, - React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback> + React.ElementRef<typeof AvatarPrimitive.Fallback>, + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback> >(({ className, ...props }, ref) => ( - <AvatarPrimitive.Fallback - ref={ref} - className={cn( - "flex h-full w-full items-center justify-center rounded-full bg-muted", - className - )} - {...props} - /> -)) -AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName + <AvatarPrimitive.Fallback + ref={ref} + className={cn( + "flex h-full w-full items-center justify-center rounded-full bg-muted", + className, + )} + {...props} + /> +)); +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; -export { Avatar, AvatarImage, AvatarFallback } +export { Avatar, AvatarImage, AvatarFallback }; diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx index f000e3e..f38976c 100644 --- a/src/components/ui/badge.tsx +++ b/src/components/ui/badge.tsx @@ -1,36 +1,36 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" +import { type VariantProps, cva } from "class-variance-authority"; +import type * as React from "react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const badgeVariants = cva( - "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", - { - variants: { - variant: { - default: - "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", - secondary: - "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", - destructive: - "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", - outline: "text-foreground", - }, - }, - defaultVariants: { - variant: "default", - }, - } -) + "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); export interface BadgeProps - extends React.HTMLAttributes<HTMLDivElement>, - VariantProps<typeof badgeVariants> {} + extends React.HTMLAttributes<HTMLDivElement>, + VariantProps<typeof badgeVariants> {} function Badge({ className, variant, ...props }: BadgeProps) { - return ( - <div className={cn(badgeVariants({ variant }), className)} {...props} /> - ) + return ( + <div className={cn(badgeVariants({ variant }), className)} {...props} /> + ); } -export { Badge, badgeVariants } +export { Badge, badgeVariants }; diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index 0f7034b..2681236 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -1,79 +1,86 @@ -import * as React from "react" +import * as React from "react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const Card = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes<HTMLDivElement> + HTMLDivElement, + React.HTMLAttributes<HTMLDivElement> >(({ className, ...props }, ref) => ( - <div - ref={ref} - className={cn( - "rounded-lg border bg-card text-card-foreground shadow-sm", - className - )} - {...props} - /> -)) -Card.displayName = "Card" + <div + ref={ref} + className={cn( + "rounded-lg border bg-card text-card-foreground shadow-sm", + className, + )} + {...props} + /> +)); +Card.displayName = "Card"; const CardHeader = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes<HTMLDivElement> + HTMLDivElement, + React.HTMLAttributes<HTMLDivElement> >(({ className, ...props }, ref) => ( - <div - ref={ref} - className={cn("flex flex-col space-y-1 px-4", className)} - {...props} - /> -)) -CardHeader.displayName = "CardHeader" + <div + ref={ref} + className={cn("flex flex-col space-y-1 px-4", className)} + {...props} + /> +)); +CardHeader.displayName = "CardHeader"; const CardTitle = React.forwardRef< - HTMLParagraphElement, - React.HTMLAttributes<HTMLHeadingElement> + HTMLParagraphElement, + React.HTMLAttributes<HTMLHeadingElement> >(({ className, ...props }, ref) => ( - <h3 - ref={ref} - className={cn( - "text-2xl font-semibold leading-none tracking-tight", - className - )} - {...props} - /> -)) -CardTitle.displayName = "CardTitle" + <h3 + ref={ref} + className={cn( + "text-2xl font-semibold leading-none tracking-tight", + className, + )} + {...props} + /> +)); +CardTitle.displayName = "CardTitle"; const CardDescription = React.forwardRef< - HTMLParagraphElement, - React.HTMLAttributes<HTMLParagraphElement> + HTMLParagraphElement, + React.HTMLAttributes<HTMLParagraphElement> >(({ className, ...props }, ref) => ( - <p - ref={ref} - className={cn("text-sm text-muted-foreground", className)} - {...props} - /> -)) -CardDescription.displayName = "CardDescription" + <p + ref={ref} + className={cn("text-sm text-muted-foreground", className)} + {...props} + /> +)); +CardDescription.displayName = "CardDescription"; const CardContent = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes<HTMLDivElement> + HTMLDivElement, + React.HTMLAttributes<HTMLDivElement> >(({ className, ...props }, ref) => ( - <div ref={ref} className={cn("p-6 pt-0", className)} {...props} /> -)) -CardContent.displayName = "CardContent" + <div ref={ref} className={cn("p-6 pt-0", className)} {...props} /> +)); +CardContent.displayName = "CardContent"; const CardFooter = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes<HTMLDivElement> + HTMLDivElement, + React.HTMLAttributes<HTMLDivElement> >(({ className, ...props }, ref) => ( - <div - ref={ref} - className={cn("flex items-center p-6 pt-0", className)} - {...props} - /> -)) -CardFooter.displayName = "CardFooter" + <div + ref={ref} + className={cn("flex items-center p-6 pt-0", className)} + {...props} + /> +)); +CardFooter.displayName = "CardFooter"; -export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } +export { + Card, + CardHeader, + CardFooter, + CardTitle, + CardDescription, + CardContent, +}; |
