Files
lifeforge/src/modules/CodeTime/components/CodeTimeMostProjects.tsx
melvinchia3636 dfca82db04 24w05
Former-commit-id: 13d14d1be55b13ee093152761525d6c653346f7e [formerly bd7fa26e477ed6ec6f29264b334234a524e817b6] [formerly f8f03c336ee607a40d9cb199b6d678d7e06f2ed0 [formerly 8a6ab981fd8b2f9cb0ea32c09cebdea19da700f9]]
Former-commit-id: 541311e8af601763e6f837005b7d8d0041d828a8 [formerly dbd731371e8f5903020485a2f53e2c102283f3ec]
Former-commit-id: e0af0ac7a35bb0400722e54588bf62bacb3a888c
2024-02-02 20:48:19 +08:00

116 lines
4.5 KiB
TypeScript

/* eslint-disable @typescript-eslint/restrict-plus-operands */
/* eslint-disable @typescript-eslint/indent */
import { Icon } from '@iconify/react/dist/iconify.js'
import React, { useState } from 'react'
import HoursAndMinutesFromSeconds from './HoursAndMinutesFromSeconds'
import useFetch from '../../../hooks/useFetch'
import APIComponentWithFallback from '../../../components/general/APIComponentWithFallback'
function CodeTimeMostProjects(): React.ReactElement {
const [lastForProjects, setLastForProjects] = useState<
'24 hours' | '7 days' | '30 days'
>('24 hours')
const [topProjects] = useFetch<Record<string, number>>(
`code-time/projects?last=${lastForProjects}`
)
return (
<div className="mt-16 flex w-full flex-col gap-6">
<div className="flex w-full items-center justify-between">
<h1 className="mb-2 flex items-center gap-2 text-2xl font-semibold">
<Icon icon="tabler:clipboard" className="text-3xl" />
<span className="ml-2">
Projects You&apos;ve Spent Most Time Doing
</span>
</h1>
<div className="flex items-center gap-2">
<p className="font-medium tracking-wider">in the last</p>
<div className="flex gap-2 rounded-lg p-2">
{['24 hours', '7 days', '30 days'].map((last, index) => (
<button
key={index}
onClick={() => {
setLastForProjects(last as '24 hours' | '7 days' | '30 days')
}}
className={`rounded-md p-4 px-6 tracking-wide ${
lastForProjects === last
? 'bg-bg-200 font-semibold text-bg-800 dark:bg-bg-700/50 dark:text-bg-100'
: 'text-bg-400 hover:bg-bg-200/50 dark:hover:bg-bg-700/50'
}`}
>
{last}
</button>
))}
</div>
</div>
</div>
<APIComponentWithFallback data={topProjects}>
<div className="flex w-full">
{typeof topProjects !== 'string' &&
Object.keys(topProjects).length > 0 &&
Object.entries(topProjects)
.slice(0, 5)
.map(([key, value], index) => (
<div
className={`h-6 border ${index === 0 && 'rounded-l-lg'} ${
index === 4 && 'rounded-r-lg'
} ${
[
'bg-red-500/20 border-red-500',
'bg-orange-500/20 border-orange-500',
'bg-yellow-500/20 border-yellow-500',
'bg-blue-500/20 border-blue-500',
'bg-emerald-500/20 border-emerald-500'
][index]
}`}
key={key}
style={{
width: `${Math.round(
(value /
Object.entries(topProjects)
.slice(0, 5)
.reduce((a, b) => a + b[1], 0)) *
100
)}%`
}}
></div>
))}
</div>
<ul className="flex flex-col gap-4">
{topProjects !== null &&
Object.keys(topProjects).length > 0 &&
Object.entries(topProjects)
.slice(0, 5)
.map(([key, value], index) => (
<li
key={key}
className="relative flex items-center justify-between gap-4 rounded-lg bg-bg-50 p-6 shadow-[4px_4px_10px_0px_rgba(0,0,0,0.05)] dark:bg-bg-900"
>
<div className="flex items-center gap-4 text-lg font-medium">
<div
className={`h-4 w-4 rounded-md border ${
[
'bg-red-500/20 border-red-500',
'bg-orange-500/20 border-orange-500',
'bg-yellow-500/20 border-yellow-500',
'bg-blue-500/20 border-blue-500',
'bg-emerald-500/20 border-emerald-500'
][index]
} rounded-full`}
></div>
{key}
</div>
<div className="text-3xl font-semibold">
<HoursAndMinutesFromSeconds seconds={value} />
</div>
</li>
))}
</ul>
</APIComponentWithFallback>
</div>
)
}
export default CodeTimeMostProjects