removendo contador cards
This commit is contained in:
parent
251362852d
commit
985311211a
6 changed files with 47 additions and 76 deletions
|
|
@ -34,16 +34,16 @@ export function AppShell() {
|
||||||
|
|
||||||
<nav className="hidden items-center gap-1 md:flex">
|
<nav className="hidden items-center gap-1 md:flex">
|
||||||
<NavLink to="/" end className={navLinkClassName}>
|
<NavLink to="/" end className={navLinkClassName}>
|
||||||
<PlusCircle size={18} />
|
<ListTodo size={18} />
|
||||||
Nova Tarefa
|
Minhas Tarefas
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<NavLink to="/board" className={navLinkClassName}>
|
<NavLink to="/board" className={navLinkClassName}>
|
||||||
<Columns size={18} />
|
<Columns size={18} />
|
||||||
Quadro
|
Quadro
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<NavLink to="/tasks" className={navLinkClassName}>
|
<NavLink to="/new" className={navLinkClassName}>
|
||||||
<ListTodo size={18} />
|
<PlusCircle size={18} />
|
||||||
Minhas Tarefas
|
Nova Tarefa
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -73,16 +73,16 @@ export function AppShell() {
|
||||||
<footer className="border-t border-border-soft bg-surface py-6 md:hidden">
|
<footer className="border-t border-border-soft bg-surface py-6 md:hidden">
|
||||||
<nav className="flex justify-around px-4">
|
<nav className="flex justify-around px-4">
|
||||||
<NavLink to="/" end className={navLinkClassName}>
|
<NavLink to="/" end className={navLinkClassName}>
|
||||||
<PlusCircle size={18} />
|
<ListTodo size={18} />
|
||||||
Criar
|
Tarefas
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<NavLink to="/board" className={navLinkClassName}>
|
<NavLink to="/board" className={navLinkClassName}>
|
||||||
<Columns size={18} />
|
<Columns size={18} />
|
||||||
Quadro
|
Quadro
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<NavLink to="/tasks" className={navLinkClassName}>
|
<NavLink to="/new" className={navLinkClassName}>
|
||||||
<ListTodo size={18} />
|
<PlusCircle size={18} />
|
||||||
Tarefas
|
Criar
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</nav>
|
</nav>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { differenceInSeconds, parseISO } from 'date-fns'
|
import { differenceInSeconds, parseISO } from 'date-fns'
|
||||||
import { Play, Square } from 'lucide-react'
|
import { Clock, Play, Square } from 'lucide-react'
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
|
|
||||||
import { taskService } from '../services/taskService'
|
import { taskService } from '../services/taskService'
|
||||||
|
|
@ -96,37 +96,54 @@ export function TaskTimer({ task, onUpdate }: TaskTimerProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-3 rounded-xl bg-app-bg/50 p-2 pl-3">
|
<div className={cn(
|
||||||
|
"group relative flex items-center gap-3 overflow-hidden rounded-2xl border p-2 transition-all duration-500",
|
||||||
|
runningItem
|
||||||
|
? "border-brand/30 bg-brand/5 shadow-xl shadow-brand/10"
|
||||||
|
: "border-border-soft bg-surface shadow-sm hover:border-brand/20 hover:bg-app-bg/30"
|
||||||
|
)}>
|
||||||
|
{/* Active Indicator Pulse */}
|
||||||
|
{runningItem && (
|
||||||
|
<div className="absolute left-0 top-0 h-full w-1 bg-brand animate-pulse" />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className={cn(
|
||||||
|
"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl transition-all duration-500",
|
||||||
|
runningItem ? "bg-brand text-white scale-110 shadow-lg shadow-brand/30" : "bg-app-bg text-text-muted group-hover:bg-white"
|
||||||
|
)}>
|
||||||
|
<Clock size={18} className={runningItem ? "animate-spin [animation-duration:3s]" : ""} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="text-[10px] font-black uppercase tracking-wider text-text-muted/60">
|
<span className="text-[10px] font-black uppercase tracking-widest text-text-muted/60">
|
||||||
Tempo Gasto
|
{runningItem ? 'Contagem Ativa' : 'Tempo Total'}
|
||||||
</span>
|
</span>
|
||||||
<span className={cn(
|
<span className={cn(
|
||||||
"font-mono text-sm font-bold tabular-nums",
|
"text-base font-black tabular-nums tracking-tight transition-colors duration-500",
|
||||||
runningItem ? "text-brand" : "text-text-main"
|
runningItem ? "text-brand" : "text-text-main"
|
||||||
)}>
|
)}>
|
||||||
{formatDuration(displaySeconds)}
|
{formatDuration(displaySeconds)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-1.5 ml-auto">
|
<div className="ml-auto pr-1">
|
||||||
{runningItem ? (
|
{runningItem ? (
|
||||||
<button
|
<button
|
||||||
onClick={handleStop}
|
onClick={handleStop}
|
||||||
disabled={isActionLoading}
|
disabled={isActionLoading}
|
||||||
className="flex h-8 w-8 items-center justify-center rounded-lg bg-rose-500 text-white shadow-lg shadow-rose-500/20 transition-all hover:bg-rose-600 active:scale-95 disabled:opacity-50"
|
className="flex h-9 w-9 items-center justify-center rounded-xl bg-rose-500 text-white shadow-lg shadow-rose-500/30 transition-all hover:scale-110 hover:bg-rose-600 active:scale-90 disabled:opacity-50"
|
||||||
title="Parar Cronômetro"
|
title="Parar Cronômetro"
|
||||||
>
|
>
|
||||||
<Square size={14} fill="currentColor" />
|
<Square size={16} fill="currentColor" />
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
onClick={handleStart}
|
onClick={handleStart}
|
||||||
disabled={isActionLoading}
|
disabled={isActionLoading}
|
||||||
className="flex h-8 w-8 items-center justify-center rounded-lg bg-brand text-white shadow-lg shadow-brand/20 transition-all hover:bg-brand-strong active:scale-95 disabled:opacity-50"
|
className="flex h-9 w-9 items-center justify-center rounded-xl bg-brand text-white shadow-lg shadow-brand/30 transition-all hover:scale-110 hover:bg-brand-strong active:scale-90 disabled:opacity-50"
|
||||||
title="Iniciar Cronômetro"
|
title="Iniciar Cronômetro"
|
||||||
>
|
>
|
||||||
<Play size={14} fill="currentColor" className="ml-0.5" />
|
<Play size={16} fill="currentColor" className="ml-0.5" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ export function CreateTaskPage() {
|
||||||
|
|
||||||
<div className="mt-8 flex flex-col gap-3">
|
<div className="mt-8 flex flex-col gap-3">
|
||||||
<Link
|
<Link
|
||||||
to="/tasks"
|
to="/"
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl bg-brand py-3 font-bold text-white shadow-lg shadow-brand/20 transition-all hover:bg-brand-strong"
|
className="inline-flex items-center justify-center gap-2 rounded-xl bg-brand py-3 font-bold text-white shadow-lg shadow-brand/20 transition-all hover:bg-brand-strong"
|
||||||
>
|
>
|
||||||
Ver Minhas Tarefas
|
Ver Minhas Tarefas
|
||||||
|
|
@ -130,7 +130,7 @@ export function CreateTaskPage() {
|
||||||
<div className="mx-auto max-w-3xl pb-20">
|
<div className="mx-auto max-w-3xl pb-20">
|
||||||
<div className="mb-8 flex items-center justify-between">
|
<div className="mb-8 flex items-center justify-between">
|
||||||
<Link
|
<Link
|
||||||
to="/tasks"
|
to="/"
|
||||||
className="inline-flex items-center gap-2 text-sm font-bold text-text-muted transition-colors hover:text-brand"
|
className="inline-flex items-center gap-2 text-sm font-bold text-text-muted transition-colors hover:text-brand"
|
||||||
>
|
>
|
||||||
<ArrowLeft size={16} />
|
<ArrowLeft size={16} />
|
||||||
|
|
@ -244,7 +244,7 @@ export function CreateTaskPage() {
|
||||||
|
|
||||||
<div className="mt-10 flex items-center justify-end gap-4">
|
<div className="mt-10 flex items-center justify-end gap-4">
|
||||||
<Link
|
<Link
|
||||||
to="/tasks"
|
to="/"
|
||||||
className="px-6 py-3 text-sm font-bold text-text-muted hover:text-text-main"
|
className="px-6 py-3 text-sm font-bold text-text-muted hover:text-text-main"
|
||||||
>
|
>
|
||||||
Cancelar
|
Cancelar
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ export function TaskBoardPage() {
|
||||||
<RefreshCw size={18} className={isLoading ? 'animate-spin' : ''} />
|
<RefreshCw size={18} className={isLoading ? 'animate-spin' : ''} />
|
||||||
</button>
|
</button>
|
||||||
<Link
|
<Link
|
||||||
to="/"
|
to="/new"
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl bg-brand px-6 py-3 text-sm font-bold text-white shadow-lg shadow-brand/20 transition-all hover:scale-[1.02] hover:bg-brand-strong active:scale-95"
|
className="inline-flex items-center justify-center gap-2 rounded-xl bg-brand px-6 py-3 text-sm font-bold text-white shadow-lg shadow-brand/20 transition-all hover:scale-[1.02] hover:bg-brand-strong active:scale-95"
|
||||||
>
|
>
|
||||||
<Plus size={20} />
|
<Plus size={20} />
|
||||||
|
|
|
||||||
|
|
@ -93,14 +93,7 @@ export function TaskListPage() {
|
||||||
})
|
})
|
||||||
}, [tasks, searchQuery, statusFilter])
|
}, [tasks, searchQuery, statusFilter])
|
||||||
|
|
||||||
const stats = useMemo(() => {
|
|
||||||
return {
|
|
||||||
total: tasks.length,
|
|
||||||
completed: tasks.filter((t) => t.status === 'COMPLETED').length,
|
|
||||||
inProgress: tasks.filter((t) => t.status === 'IN_PROGRESS').length,
|
|
||||||
pending: tasks.filter((t) => t.status === 'NOT_STARTED').length,
|
|
||||||
}
|
|
||||||
}, [tasks])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-8 pb-12">
|
<div className="space-y-8 pb-12">
|
||||||
|
|
@ -115,7 +108,7 @@ export function TaskListPage() {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Link
|
<Link
|
||||||
to="/"
|
to="/new"
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl bg-brand px-6 py-3 text-sm font-bold text-white shadow-lg shadow-brand/20 transition-all hover:scale-[1.02] hover:bg-brand-strong active:scale-95"
|
className="inline-flex items-center justify-center gap-2 rounded-xl bg-brand px-6 py-3 text-sm font-bold text-white shadow-lg shadow-brand/20 transition-all hover:scale-[1.02] hover:bg-brand-strong active:scale-95"
|
||||||
>
|
>
|
||||||
<Plus size={20} />
|
<Plus size={20} />
|
||||||
|
|
@ -123,46 +116,7 @@ export function TaskListPage() {
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Stats Grid */}
|
|
||||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
||||||
{[
|
|
||||||
{ label: 'Total', value: stats.total, icon: Layers, color: 'text-text-main' },
|
|
||||||
{
|
|
||||||
label: 'Em Andamento',
|
|
||||||
value: stats.inProgress,
|
|
||||||
icon: Clock,
|
|
||||||
color: 'text-amber-600',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Concluídas',
|
|
||||||
value: stats.completed,
|
|
||||||
icon: CheckCircle2,
|
|
||||||
color: 'text-emerald-600',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Pendentes',
|
|
||||||
value: stats.pending,
|
|
||||||
icon: AlertCircle,
|
|
||||||
color: 'text-brand',
|
|
||||||
},
|
|
||||||
].map((stat, i) => (
|
|
||||||
<motion.div
|
|
||||||
initial={{ opacity: 0, y: 20 }}
|
|
||||||
animate={{ opacity: 1, y: 0 }}
|
|
||||||
transition={{ delay: i * 0.1 }}
|
|
||||||
key={stat.label}
|
|
||||||
className="rounded-2xl border border-border-soft bg-surface p-5 shadow-sm"
|
|
||||||
>
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<stat.icon size={20} className={stat.color} />
|
|
||||||
<span className="text-xs font-bold uppercase tracking-wider text-text-muted">
|
|
||||||
{stat.label}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<p className="mt-4 text-3xl font-black text-text-main">{stat.value}</p>
|
|
||||||
</motion.div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Toolbar */}
|
{/* Toolbar */}
|
||||||
<div className="flex flex-col gap-4 rounded-2xl border border-border-soft bg-surface p-4 shadow-sm lg:flex-row lg:items-center">
|
<div className="flex flex-col gap-4 rounded-2xl border border-border-soft bg-surface p-4 shadow-sm lg:flex-row lg:items-center">
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ export const router = createBrowserRouter([
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
index: true,
|
index: true,
|
||||||
element: <CreateTaskPage />,
|
element: <TaskListPage />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'tasks',
|
path: 'new',
|
||||||
element: <TaskListPage />,
|
element: <CreateTaskPage />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'board',
|
path: 'board',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue