You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

123 lines
4.1 KiB

import Link from "next/link";
import { useId } from "react";
import { UiIcon } from "./ui-icon";
type InfoProgressCardProps = {
title: string;
requiredLabel: boolean;
estimate: string;
progress: number;
tooltip?: string;
slug: string;
};
const RADIUS = 12;
const CIRCUMFERENCE = 2 * Math.PI * RADIUS;
export function InfoProgressCard({
title,
requiredLabel = false,
estimate,
progress,
tooltip,
slug,
}: InfoProgressCardProps) {
const tooltipId = useId();
const normalizedProgress = Math.max(0, Math.min(progress, 100));
const dashOffset = CIRCUMFERENCE - (normalizedProgress / 100) * CIRCUMFERENCE;
return (
<Link href={`/questions-list/${slug}`} className="block">
<article className="flex items-center gap-2 rounded-[15px] bg-white px-3 py-3 shadow-[0_12px_40px_rgba(15,23,42,0.08)]">
<div className="relative flex h-[44px] w-[44px] shrink-0 items-center justify-center rounded-[10px] bg-linear-to-br from-[#EA3D59] to-[#F76B8A] text-white">
<UiIcon name="person" aria-hidden="true" className="size-6" />
</div>
<div className="min-w-0 flex-1">
<div className="flex items-start justify-between gap-3">
<div className="min-w-0">
<h2 className="truncate group-14 leading-none font-bold tracking-[-0.03em] text-[#171717]">
{title}{" "}
<span className="group-10 font-bold text-[#FF6175]">
{requiredLabel && "(Required)"}
</span>
</h2>
</div>
{tooltip ? (
<div className="group relative shrink-0">
<button
type="button"
aria-label="More information"
aria-describedby={tooltipId}
className="flex h-4 w-4 items-center justify-center rounded-md bg-[#F24E63] text-white"
>
<UiIcon
name="question"
aria-hidden="true"
className="size-[10px]"
/>
</button>
<div
id={tooltipId}
role="tooltip"
className="pointer-events-none absolute top-full right-0 z-10 mt-2 w-48 rounded-[10px] bg-[#171717] px-3 py-2 group-10 leading-4 font-medium text-white opacity-0 shadow-lg transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100"
>
{tooltip}
</div>
</div>
) : null}
</div>
<div className="mt-2 flex items-center justify-between">
<p className="group-10 font-semibold text-[#747474]">
Estimate time: {estimate}
</p>
<div className="flex items-center gap-1">
{normalizedProgress < 100 ? (
<svg
aria-hidden="true"
className="-rotate-90"
viewBox="0 0 32 32"
width="12"
height="12"
>
<circle
cx="16"
cy="16"
r={RADIUS}
fill="none"
stroke="#E5E7EB"
strokeWidth="4"
/>
<circle
cx="16"
cy="16"
r={RADIUS}
fill="none"
stroke="#222222"
strokeWidth="4"
strokeLinecap="round"
strokeDasharray={CIRCUMFERENCE}
strokeDashoffset={dashOffset}
/>
</svg>
) : (
<UiIcon
name="success"
aria-hidden="true"
className="mt-0.5 size-3"
/>
)}
<span className="group-10 font-semibold text-[#111111]">
{normalizedProgress}%
</span>
</div>
</div>
</div>
</article>
</Link>
);
}
export default InfoProgressCard;