imports nao usados
This commit is contained in:
parent
7c4884b6ad
commit
880d72d5d6
2 changed files with 193 additions and 104 deletions
|
|
@ -7,7 +7,6 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import net.beetechgroup.beetask.entities.task.Task;
|
import net.beetechgroup.beetask.entities.task.Task;
|
||||||
import net.beetechgroup.beetask.entities.task.TaskHistoryItem;
|
import net.beetechgroup.beetask.entities.task.TaskHistoryItem;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { motion, AnimatePresence } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import {
|
import {
|
||||||
BarChart3,
|
BarChart3,
|
||||||
Calendar,
|
Calendar,
|
||||||
|
|
@ -13,11 +13,13 @@ import {
|
||||||
Download,
|
Download,
|
||||||
AlertCircle,
|
AlertCircle,
|
||||||
Loader2,
|
Loader2,
|
||||||
ArrowUpRight,
|
|
||||||
History,
|
History,
|
||||||
Briefcase
|
Briefcase,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { dashboardService, type DashboardData } from "../services/dashboardService";
|
import {
|
||||||
|
dashboardService,
|
||||||
|
type DashboardData,
|
||||||
|
} from "../services/dashboardService";
|
||||||
import { cn } from "../lib/utils";
|
import { cn } from "../lib/utils";
|
||||||
import { format, subDays, startOfMonth, endOfMonth } from "date-fns";
|
import { format, subDays, startOfMonth, endOfMonth } from "date-fns";
|
||||||
import { ptBR } from "date-fns/locale";
|
import { ptBR } from "date-fns/locale";
|
||||||
|
|
@ -34,7 +36,7 @@ export const DashboardPage: React.FC = () => {
|
||||||
try {
|
try {
|
||||||
const result = await dashboardService.getDashboard(
|
const result = await dashboardService.getDashboard(
|
||||||
startDate.toISOString(),
|
startDate.toISOString(),
|
||||||
endDate.toISOString()
|
endDate.toISOString(),
|
||||||
);
|
);
|
||||||
setData(result);
|
setData(result);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -73,29 +75,29 @@ export const DashboardPage: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-3 bg-surface border border-border-soft p-2 rounded-2xl shadow-sm">
|
<div className="flex items-center gap-3 bg-surface border border-border-soft p-2 rounded-2xl shadow-sm">
|
||||||
<div className="flex items-center gap-2 px-3 py-2 border-r border-border-soft">
|
<div className="flex items-center gap-2 px-3 py-2 border-r border-border-soft">
|
||||||
<Calendar size={18} className="text-brand" />
|
<Calendar size={18} className="text-brand" />
|
||||||
<input
|
<input
|
||||||
type="date"
|
type="date"
|
||||||
value={format(startDate, 'yyyy-MM-dd')}
|
value={format(startDate, "yyyy-MM-dd")}
|
||||||
onChange={(e) => setStartDate(new Date(e.target.value))}
|
onChange={(e) => setStartDate(new Date(e.target.value))}
|
||||||
className="bg-transparent border-none text-sm font-bold text-text-main focus:ring-0 outline-none"
|
className="bg-transparent border-none text-sm font-bold text-text-main focus:ring-0 outline-none"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 px-3 py-2">
|
<div className="flex items-center gap-2 px-3 py-2">
|
||||||
<input
|
<input
|
||||||
type="date"
|
type="date"
|
||||||
value={format(endDate, 'yyyy-MM-dd')}
|
value={format(endDate, "yyyy-MM-dd")}
|
||||||
onChange={(e) => setEndDate(new Date(e.target.value))}
|
onChange={(e) => setEndDate(new Date(e.target.value))}
|
||||||
className="bg-transparent border-none text-sm font-bold text-text-main focus:ring-0 outline-none"
|
className="bg-transparent border-none text-sm font-bold text-text-main focus:ring-0 outline-none"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={fetchDashboardData}
|
onClick={fetchDashboardData}
|
||||||
className="p-2 bg-brand text-white rounded-xl hover:scale-105 transition-transform active:scale-95"
|
className="p-2 bg-brand text-white rounded-xl hover:scale-105 transition-transform active:scale-95"
|
||||||
>
|
>
|
||||||
<Filter size={18} />
|
<Filter size={18} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
@ -107,9 +109,14 @@ export const DashboardPage: React.FC = () => {
|
||||||
) : error ? (
|
) : error ? (
|
||||||
<div className="flex flex-col items-center justify-center min-h-[50vh] text-center p-6 bg-surface rounded-[2.5rem] border border-border-soft">
|
<div className="flex flex-col items-center justify-center min-h-[50vh] text-center p-6 bg-surface rounded-[2.5rem] border border-border-soft">
|
||||||
<AlertCircle size={48} className="text-rose-500 mb-4" />
|
<AlertCircle size={48} className="text-rose-500 mb-4" />
|
||||||
<h3 className="text-xl font-bold text-text-main mb-2">Ocorreu um erro</h3>
|
<h3 className="text-xl font-bold text-text-main mb-2">
|
||||||
|
Ocorreu um erro
|
||||||
|
</h3>
|
||||||
<p className="text-text-muted max-w-sm mb-6">{error}</p>
|
<p className="text-text-muted max-w-sm mb-6">{error}</p>
|
||||||
<button onClick={fetchDashboardData} className="px-6 py-3 bg-brand text-white rounded-xl font-bold hover:bg-brand-dark transition-all">
|
<button
|
||||||
|
onClick={fetchDashboardData}
|
||||||
|
className="px-6 py-3 bg-brand text-white rounded-xl font-bold hover:bg-brand-dark transition-all"
|
||||||
|
>
|
||||||
Tentar novamente
|
Tentar novamente
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -126,14 +133,21 @@ export const DashboardPage: React.FC = () => {
|
||||||
<div className="w-12 h-12 bg-brand/10 text-brand rounded-xl flex items-center justify-center mb-6">
|
<div className="w-12 h-12 bg-brand/10 text-brand rounded-xl flex items-center justify-center mb-6">
|
||||||
<Clock size={24} />
|
<Clock size={24} />
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm font-bold text-text-muted uppercase tracking-wider">Tempo Total</div>
|
<div className="text-sm font-bold text-text-muted uppercase tracking-wider">
|
||||||
<div className="mt-2 text-4xl font-black text-text-main">{formatMinutes(data.totalMinutesWorked)}</div>
|
Tempo Total
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 text-4xl font-black text-text-main">
|
||||||
|
{formatMinutes(data.totalMinutesWorked)}
|
||||||
|
</div>
|
||||||
<div className="mt-4 flex items-center gap-1.5 text-[10px] font-black text-brand bg-brand/5 w-fit px-2 py-1 rounded-full uppercase tracking-widest">
|
<div className="mt-4 flex items-center gap-1.5 text-[10px] font-black text-brand bg-brand/5 w-fit px-2 py-1 rounded-full uppercase tracking-widest">
|
||||||
<TrendingUp size={12} />
|
<TrendingUp size={12} />
|
||||||
Foco em alta
|
Foco em alta
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Clock size={120} className="absolute -right-10 -bottom-10 text-brand/5 -rotate-12 transition-transform group-hover:rotate-0" />
|
<Clock
|
||||||
|
size={120}
|
||||||
|
className="absolute -right-10 -bottom-10 text-brand/5 -rotate-12 transition-transform group-hover:rotate-0"
|
||||||
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|
@ -146,14 +160,21 @@ export const DashboardPage: React.FC = () => {
|
||||||
<div className="w-12 h-12 bg-accent/10 text-accent rounded-xl flex items-center justify-center mb-6">
|
<div className="w-12 h-12 bg-accent/10 text-accent rounded-xl flex items-center justify-center mb-6">
|
||||||
<CheckCircle2 size={24} />
|
<CheckCircle2 size={24} />
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm font-bold text-text-muted uppercase tracking-wider">Tarefas Concluídas</div>
|
<div className="text-sm font-bold text-text-muted uppercase tracking-wider">
|
||||||
<div className="mt-2 text-4xl font-black text-text-main">{data.finishedTasksInPeriod.length}</div>
|
Tarefas Concluídas
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 text-4xl font-black text-text-main">
|
||||||
|
{data.finishedTasksInPeriod.length}
|
||||||
|
</div>
|
||||||
<div className="mt-4 flex items-center gap-1.5 text-[10px] font-black text-accent bg-accent/5 w-fit px-2 py-1 rounded-full uppercase tracking-widest">
|
<div className="mt-4 flex items-center gap-1.5 text-[10px] font-black text-accent bg-accent/5 w-fit px-2 py-1 rounded-full uppercase tracking-widest">
|
||||||
<CheckCircle2 size={12} />
|
<CheckCircle2 size={12} />
|
||||||
Periodo de Entrega
|
Periodo de Entrega
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CheckCircle2 size={120} className="absolute -right-10 -bottom-10 text-accent/5 -rotate-12 transition-transform group-hover:rotate-0" />
|
<CheckCircle2
|
||||||
|
size={120}
|
||||||
|
className="absolute -right-10 -bottom-10 text-accent/5 -rotate-12 transition-transform group-hover:rotate-0"
|
||||||
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|
@ -166,18 +187,27 @@ export const DashboardPage: React.FC = () => {
|
||||||
<div className="w-12 h-12 bg-white/20 text-white rounded-xl flex items-center justify-center mb-6">
|
<div className="w-12 h-12 bg-white/20 text-white rounded-xl flex items-center justify-center mb-6">
|
||||||
<FileText size={24} />
|
<FileText size={24} />
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm font-bold text-white/70 uppercase tracking-wider">Média por Projeto</div>
|
<div className="text-sm font-bold text-white/70 uppercase tracking-wider">
|
||||||
|
Média por Projeto
|
||||||
|
</div>
|
||||||
<div className="mt-2 text-4xl font-black">
|
<div className="mt-2 text-4xl font-black">
|
||||||
{data.projectStats.length > 0
|
{data.projectStats.length > 0
|
||||||
? formatMinutes(Math.round(data.totalMinutesWorked / data.projectStats.length))
|
? formatMinutes(
|
||||||
: '0h 0m'}
|
Math.round(
|
||||||
|
data.totalMinutesWorked / data.projectStats.length,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: "0h 0m"}
|
||||||
</div>
|
</div>
|
||||||
<button className="mt-6 inline-flex items-center gap-2 text-xs font-black uppercase tracking-widest bg-white/10 hover:bg-white/20 px-4 py-2 rounded-xl transition-all">
|
<button className="mt-6 inline-flex items-center gap-2 text-xs font-black uppercase tracking-widest bg-white/10 hover:bg-white/20 px-4 py-2 rounded-xl transition-all">
|
||||||
<Download size={14} />
|
<Download size={14} />
|
||||||
Exportar Relatório
|
Exportar Relatório
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<TrendingUp size={160} className="absolute -right-10 -bottom-10 text-white/10 -rotate-12 transition-transform group-hover:rotate-0" />
|
<TrendingUp
|
||||||
|
size={160}
|
||||||
|
className="absolute -right-10 -bottom-10 text-white/10 -rotate-12 transition-transform group-hover:rotate-0"
|
||||||
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -187,34 +217,51 @@ export const DashboardPage: React.FC = () => {
|
||||||
<div className="flex items-center justify-between mb-8">
|
<div className="flex items-center justify-between mb-8">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Briefcase size={20} className="text-brand" />
|
<Briefcase size={20} className="text-brand" />
|
||||||
<h2 className="text-xl font-black text-text-main">Tempo por Projeto</h2>
|
<h2 className="text-xl font-black text-text-main">
|
||||||
|
Tempo por Projeto
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<BarChart3 size={20} className="text-text-muted" />
|
<BarChart3 size={20} className="text-text-muted" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{data.projectStats.length > 0 ? data.projectStats.map((stat, idx) => {
|
{data.projectStats.length > 0 ? (
|
||||||
const percentage = (stat.totalMinutes / data.totalMinutesWorked) * 100;
|
data.projectStats.map((stat, idx) => {
|
||||||
return (
|
const percentage =
|
||||||
<div key={stat.projectId} className="space-y-2">
|
(stat.totalMinutes / data.totalMinutesWorked) * 100;
|
||||||
<div className="flex items-center justify-between">
|
return (
|
||||||
<span className="font-bold text-text-main flex items-center gap-2">
|
<div key={stat.projectId} className="space-y-2">
|
||||||
<div className={cn("w-2 h-2 rounded-full", idx % 2 === 0 ? "bg-brand" : "bg-accent")} />
|
<div className="flex items-center justify-between">
|
||||||
{stat.projectName}
|
<span className="font-bold text-text-main flex items-center gap-2">
|
||||||
</span>
|
<div
|
||||||
<span className="text-sm font-black text-text-muted">{formatMinutes(stat.totalMinutes)}</span>
|
className={cn(
|
||||||
|
"w-2 h-2 rounded-full",
|
||||||
|
idx % 2 === 0 ? "bg-brand" : "bg-accent",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{stat.projectName}
|
||||||
|
</span>
|
||||||
|
<span className="text-sm font-black text-text-muted">
|
||||||
|
{formatMinutes(stat.totalMinutes)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="h-3 w-full bg-surface-muted rounded-full overflow-hidden">
|
||||||
|
<motion.div
|
||||||
|
initial={{ width: 0 }}
|
||||||
|
animate={{ width: `${percentage}%` }}
|
||||||
|
className={cn(
|
||||||
|
"h-full rounded-full",
|
||||||
|
idx % 2 === 0 ? "bg-brand" : "bg-accent",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-3 w-full bg-surface-muted rounded-full overflow-hidden">
|
);
|
||||||
<motion.div
|
})
|
||||||
initial={{ width: 0 }}
|
) : (
|
||||||
animate={{ width: `${percentage}%` }}
|
<div className="text-center py-10 opacity-50 font-bold">
|
||||||
className={cn("h-full rounded-full", idx % 2 === 0 ? "bg-brand" : "bg-accent")}
|
Nenhum dado por projeto.
|
||||||
/>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}) : (
|
|
||||||
<div className="text-center py-10 opacity-50 font-bold">Nenhum dado por projeto.</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -224,29 +271,45 @@ export const DashboardPage: React.FC = () => {
|
||||||
<div className="flex items-center justify-between mb-8">
|
<div className="flex items-center justify-between mb-8">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<History size={20} className="text-accent" />
|
<History size={20} className="text-accent" />
|
||||||
<h2 className="text-xl font-black text-text-main">Daily (Ontem)</h2>
|
<h2 className="text-xl font-black text-text-main">
|
||||||
|
Daily (Ontem)
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs font-bold text-text-muted uppercase bg-surface-muted px-2 py-1 rounded-lg">
|
<div className="text-xs font-bold text-text-muted uppercase bg-surface-muted px-2 py-1 rounded-lg">
|
||||||
{format(subDays(new Date(), 1), 'dd MMM', { locale: ptBR })}
|
{format(subDays(new Date(), 1), "dd MMM", { locale: ptBR })}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-4 max-h-[300px] overflow-y-auto pr-2 custom-scrollbar">
|
<div className="space-y-4 max-h-[300px] overflow-y-auto pr-2 custom-scrollbar">
|
||||||
{data.yesterdayTasks.length > 0 ? data.yesterdayTasks.map(task => (
|
{data.yesterdayTasks.length > 0 ? (
|
||||||
<div key={task.id} className="flex items-center justify-between p-4 bg-app-bg rounded-2xl border border-border-soft group hover:border-brand/30 transition-all">
|
data.yesterdayTasks.map((task) => (
|
||||||
<div className="flex items-center gap-3">
|
<div
|
||||||
<div className="w-10 h-10 bg-brand/10 text-brand rounded-xl flex items-center justify-center shrink-0">
|
key={task.id}
|
||||||
<Layout size={18} />
|
className="flex items-center justify-between p-4 bg-app-bg rounded-2xl border border-border-soft group hover:border-brand/30 transition-all"
|
||||||
</div>
|
>
|
||||||
<div>
|
<div className="flex items-center gap-3">
|
||||||
<div className="font-bold text-text-main line-clamp-1">{task.title}</div>
|
<div className="w-10 h-10 bg-brand/10 text-brand rounded-xl flex items-center justify-center shrink-0">
|
||||||
<div className="text-[10px] font-black uppercase text-brand tracking-widest">{task.projectName}</div>
|
<Layout size={18} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="font-bold text-text-main line-clamp-1">
|
||||||
|
{task.title}
|
||||||
|
</div>
|
||||||
|
<div className="text-[10px] font-black uppercase text-brand tracking-widest">
|
||||||
|
{task.projectName}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<ChevronRight
|
||||||
|
size={16}
|
||||||
|
className="text-text-muted group-hover:translate-x-1 transition-transform"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ChevronRight size={16} className="text-text-muted group-hover:translate-x-1 transition-transform" />
|
))
|
||||||
|
) : (
|
||||||
|
<div className="text-center py-10 opacity-50 font-bold">
|
||||||
|
Nenhuma atividade registrada ontem.
|
||||||
</div>
|
</div>
|
||||||
)) : (
|
|
||||||
<div className="text-center py-10 opacity-50 font-bold">Nenhuma atividade registrada ontem.</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -257,7 +320,9 @@ export const DashboardPage: React.FC = () => {
|
||||||
<div className="flex items-center justify-between mb-8">
|
<div className="flex items-center justify-between mb-8">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<FileText size={20} className="text-brand" />
|
<FileText size={20} className="text-brand" />
|
||||||
<h2 className="text-xl font-black text-text-main">Relatório de Entregas</h2>
|
<h2 className="text-xl font-black text-text-main">
|
||||||
|
Relatório de Entregas
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<button className="flex items-center gap-2 text-sm font-bold text-brand hover:underline bg-brand/5 px-4 py-2 rounded-xl transition-all">
|
<button className="flex items-center gap-2 text-sm font-bold text-brand hover:underline bg-brand/5 px-4 py-2 rounded-xl transition-all">
|
||||||
<Download size={16} />
|
<Download size={16} />
|
||||||
|
|
@ -269,34 +334,59 @@ export const DashboardPage: React.FC = () => {
|
||||||
<table className="w-full text-left">
|
<table className="w-full text-left">
|
||||||
<thead>
|
<thead>
|
||||||
<tr className="border-b border-border-soft">
|
<tr className="border-b border-border-soft">
|
||||||
<th className="pb-4 text-xs font-black uppercase text-text-muted tracking-widest pl-4">Tarefa</th>
|
<th className="pb-4 text-xs font-black uppercase text-text-muted tracking-widest pl-4">
|
||||||
<th className="pb-4 text-xs font-black uppercase text-text-muted tracking-widest">Projeto</th>
|
Tarefa
|
||||||
<th className="pb-4 text-xs font-black uppercase text-text-muted tracking-widest">Concluída em</th>
|
</th>
|
||||||
<th className="pb-4 text-xs font-black uppercase text-text-muted tracking-widest text-right pr-4">Status</th>
|
<th className="pb-4 text-xs font-black uppercase text-text-muted tracking-widest">
|
||||||
|
Projeto
|
||||||
|
</th>
|
||||||
|
<th className="pb-4 text-xs font-black uppercase text-text-muted tracking-widest">
|
||||||
|
Concluída em
|
||||||
|
</th>
|
||||||
|
<th className="pb-4 text-xs font-black uppercase text-text-muted tracking-widest text-right pr-4">
|
||||||
|
Status
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-border-soft/50">
|
<tbody className="divide-y divide-border-soft/50">
|
||||||
{data.finishedTasksInPeriod.length > 0 ? data.finishedTasksInPeriod.map(task => (
|
{data.finishedTasksInPeriod.length > 0 ? (
|
||||||
<tr key={task.id} className="group hover:bg-app-bg transition-colors">
|
data.finishedTasksInPeriod.map((task) => (
|
||||||
<td className="py-4 pl-4 font-bold text-text-main">{task.title}</td>
|
<tr
|
||||||
<td className="py-4 text-sm font-medium text-text-muted">
|
key={task.id}
|
||||||
<span className="px-2 py-1 bg-surface-muted rounded-lg border border-border-soft">
|
className="group hover:bg-app-bg transition-colors"
|
||||||
{task.projectName}
|
>
|
||||||
</span>
|
<td className="py-4 pl-4 font-bold text-text-main">
|
||||||
</td>
|
{task.title}
|
||||||
<td className="py-4 text-sm font-bold text-text-main">
|
</td>
|
||||||
{task.finishedAt ? format(new Date(task.finishedAt), 'dd/MM/yyyy HH:mm') : '-'}
|
<td className="py-4 text-sm font-medium text-text-muted">
|
||||||
</td>
|
<span className="px-2 py-1 bg-surface-muted rounded-lg border border-border-soft">
|
||||||
<td className="py-4 text-right pr-4">
|
{task.projectName}
|
||||||
<span className="inline-flex items-center gap-1 rounded-lg bg-green-500/10 px-2 py-1 text-[10px] font-black uppercase text-green-600 tracking-tighter">
|
</span>
|
||||||
<CheckCircle2 size={12} />
|
</td>
|
||||||
Finalizado
|
<td className="py-4 text-sm font-bold text-text-main">
|
||||||
</span>
|
{task.finishedAt
|
||||||
</td>
|
? format(
|
||||||
</tr>
|
new Date(task.finishedAt),
|
||||||
)) : (
|
"dd/MM/yyyy HH:mm",
|
||||||
|
)
|
||||||
|
: "-"}
|
||||||
|
</td>
|
||||||
|
<td className="py-4 text-right pr-4">
|
||||||
|
<span className="inline-flex items-center gap-1 rounded-lg bg-green-500/10 px-2 py-1 text-[10px] font-black uppercase text-green-600 tracking-tighter">
|
||||||
|
<CheckCircle2 size={12} />
|
||||||
|
Finalizado
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan={4} className="py-10 text-center opacity-50 font-bold">Nenhuma tarefa finalizada neste período.</td>
|
<td
|
||||||
|
colSpan={4}
|
||||||
|
className="py-10 text-center opacity-50 font-bold"
|
||||||
|
>
|
||||||
|
Nenhuma tarefa finalizada neste período.
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue