From 9566af5b9e52322db4ac956c1c50384db4f217da Mon Sep 17 00:00:00 2001 From: Hiroyuki Date: Thu, 22 Aug 2024 16:59:35 +0000 Subject: [PATCH] feat: add CircularProgressBar components to gpu princing page --- package-lock.json | 60 ++++++++++++++ package.json | 1 + .../pricing-page/gpus/CircularProgressBar.tsx | 78 +++++++++++++++++++ .../pricing-page/gpus/gpu-table.tsx | 10 ++- src/components/ui/progress.tsx | 28 +++++++ 5 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 src/components/pricing-page/gpus/CircularProgressBar.tsx create mode 100644 src/components/ui/progress.tsx diff --git a/package-lock.json b/package-lock.json index 5251de62..4a5f223c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,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", @@ -2180,6 +2181,65 @@ } } }, + "node_modules/@radix-ui/react-progress": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.0.tgz", + "integrity": "sha512-aSzvnYpP725CROcxAOEBVZZSIQVQdHgBr2QQFKySsaD14u8dNT0batuXI+AAGDdAHfXH8rbnHmjYFqVJ21KkRg==", + "dependencies": { + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress/node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-roving-focus": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz", diff --git a/package.json b/package.json index 99a6a8d1..f70f4839 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/components/pricing-page/gpus/CircularProgressBar.tsx b/src/components/pricing-page/gpus/CircularProgressBar.tsx new file mode 100644 index 00000000..12f05cd8 --- /dev/null +++ b/src/components/pricing-page/gpus/CircularProgressBar.tsx @@ -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 = ({ + 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 ( + + {/* Background Circle */} + + {/* Secondary Progress Bar */} + + {/* Primary Progress Bar */} + + + ); +}; + +export default CircularProgressBar; diff --git a/src/components/pricing-page/gpus/gpu-table.tsx b/src/components/pricing-page/gpus/gpu-table.tsx index f4b4809b..0f20ea94 100644 --- a/src/components/pricing-page/gpus/gpu-table.tsx +++ b/src/components/pricing-page/gpus/gpu-table.tsx @@ -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 }; @@ -171,9 +172,12 @@ export const Tables = ({ -
- Round -
+
, + React.ComponentPropsWithoutRef +>(({ className, value, ...props }, ref) => ( + + + +)) +Progress.displayName = ProgressPrimitive.Root.displayName + +export { Progress }