fix: build fix

This commit is contained in:
Gabriel Santana de Menezes 2026-05-11 22:09:42 -04:00
parent b87ab63ac2
commit 0ab12e0583
4 changed files with 65 additions and 34 deletions

View file

@ -24,7 +24,6 @@ function formatDuration(seconds: number) {
} }
export function TaskTimer({ task, onUpdate }: TaskTimerProps) { export function TaskTimer({ task, onUpdate }: TaskTimerProps) {
const [now, setNow] = useState(new Date())
const [isActionLoading, setIsActionLoading] = useState(false) const [isActionLoading, setIsActionLoading] = useState(false)
const history = task.history ?? [] const history = task.history ?? []
@ -45,7 +44,7 @@ export function TaskTimer({ task, onUpdate }: TaskTimerProps) {
const [displaySeconds, setDisplaySeconds] = useState(0) const [displaySeconds, setDisplaySeconds] = useState(0)
useEffect(() => { useEffect(() => {
let interval: NodeJS.Timeout | null = null let interval: ReturnType<typeof setInterval> | null = null
if (runningItem) { if (runningItem) {
interval = setInterval(() => { interval = setInterval(() => {

View file

@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { Users, Check, X, ShieldAlert, Mail } from "lucide-react"; import { Users, Check, X, Mail } from "lucide-react";
import { import {
organizationService, organizationService,
type JoinRequest, type JoinRequest,

View file

@ -13,7 +13,6 @@ import {
} from "lucide-react"; } from "lucide-react";
import { useAuth } from "../contexts/AuthContext"; import { useAuth } from "../contexts/AuthContext";
import { projectService, type Project } from "../services/projectService"; import { projectService, type Project } from "../services/projectService";
import { cn } from "../lib/utils";
export const ProjectsPage: React.FC = () => { export const ProjectsPage: React.FC = () => {
const { activeOrg } = useAuth(); const { activeOrg } = useAuth();
@ -79,7 +78,8 @@ export const ProjectsPage: React.FC = () => {
Workspace Workspace
</div> </div>
<h1 className="text-4xl font-black tracking-tight text-text-main"> <h1 className="text-4xl font-black tracking-tight text-text-main">
Projetos em <span className="text-brand">{activeOrg.name}</span> Projetos em{" "}
<span className="text-brand">{activeOrg?.name ?? "..."}</span>
</h1> </h1>
<p className="mt-2 text-lg text-text-muted"> <p className="mt-2 text-lg text-text-muted">
Organize suas tarefas em fluxos de trabalho específicos. Organize suas tarefas em fluxos de trabalho específicos.
@ -87,7 +87,10 @@ export const ProjectsPage: React.FC = () => {
</div> </div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="relative hidden md:block"> <div className="relative hidden md:block">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 text-text-muted" size={16} /> <Search
className="absolute left-3 top-1/2 -translate-y-1/2 text-text-muted"
size={16}
/>
<input <input
type="text" type="text"
placeholder="Buscar projetos..." placeholder="Buscar projetos..."
@ -110,7 +113,9 @@ export const ProjectsPage: React.FC = () => {
<section className="space-y-6"> <section className="space-y-6">
<div className="flex items-center gap-2 px-2"> <div className="flex items-center gap-2 px-2">
<Target size={20} className="text-brand" /> <Target size={20} className="text-brand" />
<h2 className="text-xl font-bold text-text-main">Todos os Projetos</h2> <h2 className="text-xl font-bold text-text-main">
Todos os Projetos
</h2>
</div> </div>
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3"> <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
@ -145,8 +150,11 @@ export const ProjectsPage: React.FC = () => {
<div className="mt-8 flex items-center"> <div className="mt-8 flex items-center">
<div className="flex -space-x-2"> <div className="flex -space-x-2">
{[1, 2, 3].map(i => ( {[1, 2, 3].map((i) => (
<div key={i} className="h-8 w-8 rounded-full border-2 border-surface bg-surface-muted flex items-center justify-center text-[10px] font-bold text-text-muted"> <div
key={i}
className="h-8 w-8 rounded-full border-2 border-surface bg-surface-muted flex items-center justify-center text-[10px] font-bold text-text-muted"
>
U{i} U{i}
</div> </div>
))} ))}
@ -169,7 +177,9 @@ export const ProjectsPage: React.FC = () => {
</div> </div>
<div> <div>
<h3 className="font-bold text-text-main">Novo Projeto</h3> <h3 className="font-bold text-text-main">Novo Projeto</h3>
<p className="text-sm text-text-muted">Crie um novo espaço de trabalho.</p> <p className="text-sm text-text-muted">
Crie um novo espaço de trabalho.
</p>
</div> </div>
</button> </button>
</AnimatePresence> </AnimatePresence>
@ -177,15 +187,15 @@ export const ProjectsPage: React.FC = () => {
{filteredProjects.length === 0 && !isLoading && ( {filteredProjects.length === 0 && !isLoading && (
<div className="text-center py-20 bg-surface/50 rounded-[3rem] border-2 border-dashed border-border-soft"> <div className="text-center py-20 bg-surface/50 rounded-[3rem] border-2 border-dashed border-border-soft">
<div className="w-16 h-16 bg-surface-muted rounded-2xl flex items-center justify-center mx-auto mb-6 text-text-muted/30"> <div className="w-16 h-16 bg-surface-muted rounded-2xl flex items-center justify-center mx-auto mb-6 text-text-muted/30">
<FolderKanban size={32} /> <FolderKanban size={32} />
</div> </div>
<h3 className="text-xl font-bold text-text-main mb-2"> <h3 className="text-xl font-bold text-text-main mb-2">
Nenhum projeto encontrado Nenhum projeto encontrado
</h3> </h3>
<p className="text-text-muted max-w-xs mx-auto font-medium"> <p className="text-text-muted max-w-xs mx-auto font-medium">
Sua organização ainda não possui projetos para exibir. Sua organização ainda não possui projetos para exibir.
</p> </p>
</div> </div>
)} )}
</section> </section>
@ -197,7 +207,9 @@ export const ProjectsPage: React.FC = () => {
Acelere sua Produtividade Acelere sua Produtividade
</h2> </h2>
<p className="mt-4 text-white/80 font-medium text-lg"> <p className="mt-4 text-white/80 font-medium text-lg">
Projetos ajudam a categorizar tarefas e manter o foco no que realmente importa. Defina metas e acompanhe o progresso em tempo real. Projetos ajudam a categorizar tarefas e manter o foco no que
realmente importa. Defina metas e acompanhe o progresso em tempo
real.
</p> </p>
<div className="mt-10"> <div className="mt-10">
<button <button
@ -214,7 +226,10 @@ export const ProjectsPage: React.FC = () => {
{/* Abstract shapes */} {/* Abstract shapes */}
<div className="absolute top-0 right-0 w-64 h-64 bg-white/10 blur-3xl rounded-full translate-x-1/2 -translate-y-1/2" /> <div className="absolute top-0 right-0 w-64 h-64 bg-white/10 blur-3xl rounded-full translate-x-1/2 -translate-y-1/2" />
<div className="absolute bottom-0 left-0 w-48 h-48 bg-brand/20 blur-3xl rounded-full -translate-x-1/2 translate-y-1/2" /> <div className="absolute bottom-0 left-0 w-48 h-48 bg-brand/20 blur-3xl rounded-full -translate-x-1/2 translate-y-1/2" />
<FolderKanban size={200} className="absolute -right-20 -bottom-20 text-white/5 rotate-12" /> <FolderKanban
size={200}
className="absolute -right-20 -bottom-20 text-white/5 rotate-12"
/>
</section> </section>
{/* Info Section */} {/* Info Section */}
@ -223,9 +238,13 @@ export const ProjectsPage: React.FC = () => {
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-brand-soft text-brand mb-6"> <div className="flex h-12 w-12 items-center justify-center rounded-xl bg-brand-soft text-brand mb-6">
<Target size={24} /> <Target size={24} />
</div> </div>
<h3 className="text-xl font-bold text-text-main">Foco em Objetivos</h3> <h3 className="text-xl font-bold text-text-main">
Foco em Objetivos
</h3>
<p className="mt-3 text-text-muted leading-relaxed font-medium"> <p className="mt-3 text-text-muted leading-relaxed font-medium">
Cada projeto pode ser encarado como um objetivo específico. Use-os para separar demandas de diferentes clientes ou departamentos da sua organização. Cada projeto pode ser encarado como um objetivo específico. Use-os
para separar demandas de diferentes clientes ou departamentos da sua
organização.
</p> </p>
</div> </div>
@ -233,9 +252,13 @@ export const ProjectsPage: React.FC = () => {
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-accent-soft text-accent mb-6"> <div className="flex h-12 w-12 items-center justify-center rounded-xl bg-accent-soft text-accent mb-6">
<ShieldCheck size={24} /> <ShieldCheck size={24} />
</div> </div>
<h3 className="text-xl font-bold text-text-main">Colaboração Segura</h3> <h3 className="text-xl font-bold text-text-main">
Colaboração Segura
</h3>
<p className="mt-3 text-text-muted leading-relaxed font-medium"> <p className="mt-3 text-text-muted leading-relaxed font-medium">
Projetos herdam as permissões da organização. Apenas membros autorizados podem visualizar e interagir com as tarefas de cada projeto. Projetos herdam as permissões da organização. Apenas membros
autorizados podem visualizar e interagir com as tarefas de cada
projeto.
</p> </p>
</div> </div>
</div> </div>
@ -250,7 +273,7 @@ export const ProjectsPage: React.FC = () => {
exit={{ opacity: 0, scale: 0.9, y: 20 }} exit={{ opacity: 0, scale: 0.9, y: 20 }}
className="w-full max-w-lg bg-surface border border-border-soft rounded-[2.5rem] shadow-panel p-10 relative" className="w-full max-w-lg bg-surface border border-border-soft rounded-[2.5rem] shadow-panel p-10 relative"
> >
<button <button
onClick={() => setShowCreateForm(false)} onClick={() => setShowCreateForm(false)}
className="absolute top-8 right-8 text-text-muted hover:text-brand transition-colors" className="absolute top-8 right-8 text-text-muted hover:text-brand transition-colors"
> >
@ -261,13 +284,22 @@ export const ProjectsPage: React.FC = () => {
<div className="w-16 h-16 bg-brand text-white rounded-2xl flex items-center justify-center mb-6 shadow-lg shadow-brand/20 mx-auto"> <div className="w-16 h-16 bg-brand text-white rounded-2xl flex items-center justify-center mb-6 shadow-lg shadow-brand/20 mx-auto">
<Plus size={32} /> <Plus size={32} />
</div> </div>
<h2 className="text-3xl font-black text-text-main tracking-tight mb-3">Novo Projeto</h2> <h2 className="text-3xl font-black text-text-main tracking-tight mb-3">
<p className="text-text-muted font-medium">Dê um nome ao seu novo espaço de trabalho em {activeOrg.name}.</p> Novo Projeto
</h2>
{activeOrg && (
<p className="text-text-muted font-medium">
Dê um nome ao seu novo espaço de trabalho em{" "}
{activeOrg.name}.
</p>
)}
</div> </div>
<form onSubmit={handleCreateProject} className="space-y-6"> <form onSubmit={handleCreateProject} className="space-y-6">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-bold text-text-main ml-1">Nome do Projeto</label> <label className="text-sm font-bold text-text-main ml-1">
Nome do Projeto
</label>
<input <input
type="text" type="text"
autoFocus autoFocus

View file

@ -18,8 +18,8 @@ import { Link, useNavigate } from 'react-router-dom'
import { taskService } from '../services/taskService' import { taskService } from '../services/taskService'
import { cn } from '../lib/utils' import { cn } from '../lib/utils'
import { TASK_STATUS_LABELS } from '../types/task' import { TASK_STATUS_LABELS, TASK_STATUS_OPTIONS } from '../types/task'
import type { TaskResponse } from '../types/task' import type { TaskResponse, TaskStatus } from '../types/task'
function getStatusConfig(status: TaskResponse['status']) { function getStatusConfig(status: TaskResponse['status']) {
switch (status) { switch (status) {
@ -55,10 +55,10 @@ import { TaskTimer } from '../components/TaskTimer'
export function TaskListPage() { export function TaskListPage() {
const [tasks, setTasks] = useState<TaskResponse[]>([]) const [tasks, setTasks] = useState<TaskResponse[]>([])
const [isLoading, setIsLoading] = useState(true) const [isLoading, setIsLoading] = useState(true)
const [errorMessage, setErrorMessage] = useState<string | null>(null) const [_errorMessage, setErrorMessage] = useState<string | null>(null)
const navigate = useNavigate() const navigate = useNavigate()
const [searchQuery, setSearchQuery] = useState('') const [searchQuery, setSearchQuery] = useState('')
const [statusFilter, setStatusFilter] = useState<string | 'ALL'>('ALL') const [statusFilter, setStatusFilter] = useState<TaskStatus | 'ALL'>('ALL')
const loadTasks = async (silent = false) => { const loadTasks = async (silent = false) => {
if (!silent) setIsLoading(true) if (!silent) setIsLoading(true)
@ -154,7 +154,7 @@ export function TaskListPage() {
<div className="flex items-center gap-2 overflow-x-auto pb-2 lg:pb-0"> <div className="flex items-center gap-2 overflow-x-auto pb-2 lg:pb-0">
<Filter size={18} className="mr-2 text-text-muted shrink-0" /> <Filter size={18} className="mr-2 text-text-muted shrink-0" />
{['ALL', 'NOT_STARTED', 'IN_PROGRESS', 'COMPLETED', 'CANCELED'].map( {(['ALL', ...TASK_STATUS_OPTIONS] as const).map(
(status) => ( (status) => (
<button <button
key={status} key={status}