Docs
Study Timer
Displays a study timer with segmented time tracking.
Installation
Install dependencies
npm install lucide-react
Run the following command
It will create a new file called study-timer.tsx
inside the components/animata/widget
directory.
mkdir -p components/animata/widget && touch components/animata/widget/study-timer.tsx
Paste the code
Open the newly created file and paste the following code:
import React from "react";
import { GraduationCap, XCircle } from "lucide-react";
import { cn } from "@/lib/utils";
export interface StudyTimerProps {
segments: Segment[];
}
interface Segment {
value: number;
color: string;
}
export const testStudyTimerProps: StudyTimerProps = {
segments: [
{ value: 57, color: "orange" },
{ value: 24, color: "pink" },
{ value: 26, color: "yellow" },
],
};
const formatTime = (totalMinutes: number) => {
const hours = Math.floor(totalMinutes / 60);
const minutes = totalMinutes % 60;
const seconds = (totalMinutes * 60) % 60;
const formattedHours = hours.toString().padStart(2, "0");
const formattedMinutes = minutes.toString().padStart(2, "0");
const formattedSeconds = seconds.toString().padStart(2, "0");
return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
};
const StudyTimer: React.FC<StudyTimerProps> = ({ segments = testStudyTimerProps.segments }) => {
const totalMinutes = segments.reduce((acc, segment) => acc + segment.value, 0);
const time = formatTime(totalMinutes);
return (
<div className="relative flex size-52 flex-col gap-1 rounded-3xl bg-zinc-900 p-4 text-white shadow-lg">
<div className="flex items-center justify-between p-2">
<button
className={cn(
"relative flex items-center justify-center px-4 py-2",
"duration-1000 before:absolute before:inset-0 before:animate-pulse before:rounded-3xl before:border-2 before:border-sky-600",
)}
>
<GraduationCap size={18} className="text-white" />
</button>
<div className="flex cursor-pointer items-center justify-center space-x-0.5 rounded-full bg-yellow-600 px-2 py-1 font-bold text-black">
<XCircle size={10} className="fill-black text-yellow-600" />
<span className="text-xs font-bold">21</span>
</div>
</div>
<div className="mt-2 p-2">
<div className="text-xl font-bold tracking-wider">{time}</div>
<div className="flex justify-start space-x-2 overflow-x-auto text-sm">
{segments.map((segment, index) => (
<span
key={index}
className="flex items-center justify-center gap-2"
style={{ color: segment.color }}
>
{segment.value}m
{index !== segments.length - 1 && (
<div className="h-1 w-1 rounded-full border-2 border-gray-600 bg-gray-600" />
)}
</span>
))}
</div>
</div>
<div className="flex flex-1 space-x-0.5">
{segments.map((segment, index) => (
<SegmentBar key={index} segment={segment} totalSum={totalMinutes} />
))}
</div>
</div>
);
};
const SegmentBar: React.FC<{ segment: Segment; totalSum: number }> = ({ segment, totalSum }) => {
const widthPercent = (segment.value / totalSum) * 100;
return (
<div
className="h-full rounded-b-sm rounded-t-sm"
style={{
width: `${widthPercent}%`,
backgroundColor: segment.color,
}}
/>
);
};
export default StudyTimer;
Credits
Built by Chiranjibi Ranabhat yevhenyurchuk.com