Skip to content

Commit

Permalink
feat: add CircularProgressBar components to gpu princing page
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroyukikumazawa committed Aug 22, 2024
1 parent 6fb3714 commit 9566af5
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 3 deletions.
60 changes: 60 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@radix-ui/react-hover-card": "^1.0.7",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-progress": "^1.1.0",
"@radix-ui/react-slider": "^1.2.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-switch": "^1.0.3",
Expand Down
78 changes: 78 additions & 0 deletions src/components/pricing-page/gpus/CircularProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { cn } from '@/lib/utils';
import * as React from 'react';

interface CircularProgressBarProps {
diameter?: number; // Diameter of the entire SVG element
strokeWidth?: number; // Width of the stroke for the progress circles
progressValue: number; // Progress value (0-100) representing the percentage of the circle that is filled
primaryColor?: string; // Color of the primary progress bar
secondaryColor?: string; // Color of the secondary progress bar
backgroundCircleColor?: string; // Background color for the circle behind the progress bars
gapSize?: number; // Gap between the primary and secondary progress bars
className?: string; // Additional custom class names for styling
}

const CircularProgressBar: React.FC<CircularProgressBarProps> = ({
diameter = 100,
strokeWidth = 10,
progressValue,
primaryColor = '#ff4757',
secondaryColor = '#e5e7eb',
backgroundCircleColor = '#ffffff',
gapSize = 1,
className,
}) => {
// Radius of the progress circles
const radius = (diameter - strokeWidth) / 2;
// Circumference of the circles (used for calculating strokeDasharray)
const circumference = 2 * Math.PI * radius;
// Offset for the primary progress bar (determines how much of the circle is filled)
const primaryOffset = circumference - (progressValue / 100) * circumference;
// Offset for the secondary progress bar (adjusted for gap between bars)
const secondaryOffset = circumference - (1 - (progressValue + gapSize * 2) / 100) * circumference;

return (
<svg
width={diameter}
height={diameter}
className={cn("relative transform rotate-[-90deg]", className)} // Rotates the progress bar to start from the top
>
{/* Background Circle */}
<circle
cx={diameter / 2}
cy={diameter / 2}
r={radius}
stroke={backgroundCircleColor}
strokeWidth={strokeWidth}
fill="transparent"
/>
{/* Secondary Progress Bar */}
<circle
cx={diameter / 2}
cy={diameter / 2}
r={radius}
stroke={secondaryColor}
strokeWidth={strokeWidth}
fill="transparent"
strokeDasharray={circumference}
strokeDashoffset={secondaryOffset}
strokeLinecap="butt"
transform={`rotate(${(progressValue + gapSize) * 3.6}, ${diameter / 2}, ${diameter / 2})`}
/>
{/* Primary Progress Bar */}
<circle
cx={diameter / 2}
cy={diameter / 2}
r={radius}
stroke={primaryColor}
strokeWidth={strokeWidth}
fill="transparent"
strokeDasharray={circumference}
strokeDashoffset={primaryOffset}
strokeLinecap="butt"
/>
</svg>
);
};

export default CircularProgressBar;
10 changes: 7 additions & 3 deletions src/components/pricing-page/gpus/gpu-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import clsx from "clsx";
import Filter, { defaultFilters, type Filters } from "./filter";
import { Skeleton } from "../../ui/skeleton";
import arrowUpRight from '../../../assets/icons/arrow-up-right.svg';
import CircularProgressBar from "./CircularProgressBar";

export interface Gpus {
availability: { total: number; available: number };
Expand Down Expand Up @@ -171,9 +172,12 @@ export const Tables = ({
</div>
</div>
</div>
<div className="">
Round
</div>
<CircularProgressBar
diameter={80}
strokeWidth={15}
progressValue={((data?.availability?.available || 0) / (data?.availability?.total || 1) * 100)}
gapSize={1.5}
/>
</div>
<div className="flex gap-4">
<Filter
Expand Down
28 changes: 28 additions & 0 deletions src/components/ui/progress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"use client"

import * as React from "react"
import * as ProgressPrimitive from "@radix-ui/react-progress"

import { cn } from "@/lib/utils"

const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
<ProgressPrimitive.Root
ref={ref}
className={cn(
"relative h-4 w-full overflow-hidden rounded-full bg-secondary",
className
)}
{...props}
>
<ProgressPrimitive.Indicator
className="h-full w-full flex-1 bg-primary transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
))
Progress.displayName = ProgressPrimitive.Root.displayName

export { Progress }

0 comments on commit 9566af5

Please sign in to comment.