Skip to content

Commit

Permalink
Merge pull request #149
Browse files Browse the repository at this point in the history
fix: address float parse
  • Loading branch information
johnshift authored Sep 17, 2024
2 parents f6ffad8 + 0f1e4cd commit 40798ea
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 8 deletions.
56 changes: 49 additions & 7 deletions src/grants/components/grant-stat-item/grantee-stat-item.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React from 'react';

import { Skeleton } from '@nextui-org/react';
import { Button, Skeleton } from '@nextui-org/react';

import { cn } from '@/shared/utils/cn';
import { copyToClipboard } from '@/shared/utils/copy-to-clipboard';

import { GranteeProjectStat } from '@/grants/core/schemas';

Expand All @@ -16,13 +15,28 @@ export const GranteeStatItem = ({ granteeStat, level = 1 }: Props) => {
const hasChildren = !!stats && stats.length > 0;
const hasGap = hasChildren || level === 1;

const text = formatStat(value);

const onCopy = () => {
copyToClipboard({ text: value, options: { icon: '✅' } });
};

return (
<Container hasGap={hasGap} hasChildren={hasChildren}>
<Inner hasChildren={hasChildren}>
<span className="text-13 font-medium leading-tight text-white md:text-2xl md:text-white/60">
{label}
</span>
<span className="text-xl font-medium">{trimStat(value)}</span>
<div className="flex items-center gap-1">
<span className="text-xl font-medium" onClick={onCopy}>
{text}
</span>
{text.includes('...') && (
<Button isIconOnly size="sm" onClick={onCopy}>
<CopyIcon />
</Button>
)}
</div>
</Inner>

{hasChildren && (
Expand Down Expand Up @@ -111,12 +125,40 @@ export const GranteeStatsSkeleton = () => (
</>
);

export const trimStat = (input: string): string => {
const num = parseFloat(input);
// Regular expression to match a valid number (integer, float, or scientific notation)
const NUM_REGEX = /^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;

export const formatStat = (input: string): string => {
const trimmed = input.trim();

if (!isNaN(num)) {
if (NUM_REGEX.test(trimmed)) {
const num = parseFloat(trimmed);
return num.toFixed(2);
}

if (trimmed.startsWith('0x')) {
return `${trimmed.slice(0, 6)}... ${trimmed.slice(-4)}`;
}

return input;
};

const CopyIcon = () => (
<svg
data-slot="icon"
data-darkreader-inline-stroke=""
fill="none"
strokeWidth="1.5"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
className="size-5 text-white/60"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
></path>
</svg>
);
2 changes: 1 addition & 1 deletion src/grants/components/toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const Toaster = () => {
className: 'lg:ml-[248px]',
style: {
color: 'white',
backgroundColor: 'rgba(255,255,255,0.10)',
backgroundColor: '#2b2b2b',
},
success: {
icon: '🎉',
Expand Down
20 changes: 20 additions & 0 deletions src/shared/utils/copy-to-clipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import toast, { ToastOptions } from 'react-hot-toast';

interface Props {
text: string;
message?: string;
options?: ToastOptions;
}

export const copyToClipboard = ({
text,
message = 'Copied to clipboard!',
options,
}: Props) => {
if (!navigator.clipboard) {
return;
}

navigator.clipboard.writeText(text);
toast.success(message, options);
};

0 comments on commit 40798ea

Please sign in to comment.