fix: build fix
This commit is contained in:
parent
b87ab63ac2
commit
0ab12e0583
4 changed files with 65 additions and 34 deletions
|
|
@ -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(() => {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue