import React, { useState, useEffect, useCallback } from 'react' import { FileText, Plus, FileDown, Sparkles, Download, Trash2, Tag, Copy, Check, Clock, AlertCircle, } from 'lucide-react' import { useAuth } from '../contexts/AuthContext' import { reportService, type ReportTemplateOutput, type GeneratedReportOutput, } from '../services/reportService' import { projectService } from '../services/projectService' import { categoryService } from '../services/categoryService' import type { Project, Category } from '../types/task' import { CreateTemplateModal } from '../components/reports/CreateTemplateModal' import { GenerateReportModal } from '../components/reports/GenerateReportModal' export const ReportsPage: React.FC = () => { const { activeOrg } = useAuth() const orgId = activeOrg?.id const [activeTab, setActiveTab] = useState<'templates' | 'history' | 'guide'>('templates') const [templates, setTemplates] = useState([]) const [history, setHistory] = useState([]) const [projects, setProjects] = useState([]) const [categories, setCategories] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [copiedTag, setCopiedTag] = useState(null) // Modais const [isCreateOpen, setIsCreateOpen] = useState(false) const [isGenerateOpen, setIsGenerateOpen] = useState(false) const [generateInitialTemplateId, setGenerateInitialTemplateId] = useState(undefined) const loadData = useCallback(async () => { if (!orgId) return try { setLoading(true) setError(null) const [tpls, hist, projs, cats] = await Promise.all([ reportService.listTemplates(orgId), reportService.listHistory(orgId).catch(() => []), projectService.listProjects(orgId).catch(() => []), categoryService.listCategories(orgId).catch(() => []), ]) setTemplates(tpls) setHistory(hist) setProjects(projs) setCategories(cats) } catch (err: unknown) { console.error(err) setError('Falha ao carregar modelos e relatórios') } finally { setLoading(false) } }, [orgId]) useEffect(() => { loadData() }, [loadData]) const handleDeleteTemplate = async (templateId: number) => { if (!orgId) return if (!window.confirm('Tem certeza de que deseja excluir este modelo de relatório?')) return try { await reportService.deleteTemplate(orgId, templateId) setTemplates((prev) => prev.filter((t) => t.id !== templateId)) } catch (err: unknown) { console.error(err) alert(err instanceof Error ? err.message : 'Erro ao excluir modelo') } } const handleOpenGenerate = (templateId?: number) => { setGenerateInitialTemplateId(templateId) setIsGenerateOpen(true) } const handleCopyTag = (tag: string) => { navigator.clipboard.writeText(tag) setCopiedTag(tag) setTimeout(() => setCopiedTag(null), 2000) } const standardTags = [ { tag: '{{nome}}', desc: 'Nome do colaborador (pega automaticamente do usuário logado)' }, { tag: '{{periodo}}', desc: 'Período formatado no padrão escolhido no modelo (ex.: 01/10/2026 até 31/10/2026)' }, { tag: '{{data_inicio}}', desc: 'Data inicial do período escolhido (ex: 01/10/2026)' }, { tag: '{{data_fim}}', desc: 'Data final do período escolhido (ex: 31/10/2026)' }, { tag: '{{periodo_vigencia}}', desc: 'Intervalo formatado no modelo (ex: 01/10/2026 até 31/10/2026)' }, { tag: '{{mes_ano}}', desc: 'Mês e ano por extenso (ex: Outubro/2026)' }, { tag: '{{email_usuario}}', desc: 'E-mail do usuário logado' }, { tag: '{{organizacao}}', desc: 'Nome da organização / workspace ativo' }, { tag: '{{total_horas}}', desc: 'Total de horas trabalhadas no período (ex: 142h 30m)' }, { tag: '{{data_emissao}}', desc: 'Data de geração do relatório (ex: 31/10/2026)' }, ] const tableItemTags = [ { tag: '{{item.titulo}}', desc: 'Título da tarefa (em linhas repetidas de tabelas)' }, { tag: '{{item.data}}', desc: 'Data da tarefa / conclusão' }, { tag: '{{item.tempo}}', desc: 'Duração / horas trabalhadas' }, { tag: '{{item.status}}', desc: 'Status da tarefa (Concluído, Em Andamento)' }, { tag: '{{item.categoria}}', desc: 'Nome da categoria (ex: Reunião, Feature)' }, { tag: '{{item.projeto}}', desc: 'Nome do projeto da tarefa' }, ] return (
{/* Top Banner */} {error && (
{error}
)}
Workspace: {activeOrg?.name || 'BeeTask'}
Templates .DOCX

Central de Relatórios

Cadastre seus modelos corporativos em Word e gere relatórios de atividades e reuniões com preenchimento 100% automático.

{/* Action Buttons */}
{/* Tabs */}
{/* Tab 1: Modelos de Relatório */} {activeTab === 'templates' && (
{loading ? (
{[1, 2, 3].map((i) => (
))}
) : templates.length === 0 ? (

Nenhum modelo de relatório cadastrado

Faça o upload do seu primeiro template em formato Word (.docx) com a identidade visual da sua organização.

) : (
{templates.map((tpl) => (
{tpl.scope === 'PROJECT' && tpl.projectName ? `Projeto: ${tpl.projectName}` : 'Organização'}

{tpl.name}

{tpl.description && (

{tpl.description}

)}
{/* Informações adicionais se houver */} {(tpl.managerName || tpl.customProjectName || tpl.projectName) && (
{tpl.managerName && (
Gestor: {tpl.managerName}
)} {(tpl.customProjectName || tpl.projectName) && (
Projeto: {tpl.customProjectName || tpl.projectName}
)}
)} {/* Tags configuradas */}
Campos e Seções ({tpl.sections.length})
{tpl.sections.map((s) => ( {`{{${s.sectionKey}}}`} {s.sectionType === 'DATE' && ( [{s.dateFormat || 'data'}] )} {s.defaultValue && ( )} ))}
{/* Actions */}
))}
)}
)} {/* Tab 2: Histórico de Emissões */} {activeTab === 'history' && (
{history.length === 0 ? (
Nenhum relatório foi emitido neste workspace ainda.
) : (
{history.map((rep) => ( ))}
Relatório / Período Período de Vigência Emitido por Data de Emissão Download
{rep.title} {rep.startDate} até {rep.endDate} {rep.userName || 'Você'} {new Date(rep.createdAt).toLocaleDateString('pt-BR')} Baixar (.DOCX)
)}
)} {/* Tab 3: Guia de Tags do Word */} {activeTab === 'guide' && (

Como preparar seu Template no Microsoft Word (.docx)

Basta abrir seu arquivo Word habitual e digitar as tags com chaves duplas nos locais onde deseja que as informações apareçam.

{/* Tags Globais de Período e Usuário */}
Tags Globais de Período e Cabeçalho
{standardTags.map((t) => (
{t.tag}

{t.desc}

))}
{/* Tags em Tabelas Dinâmicas */}
Tags para Tabelas com Repetição de Linhas

Crie uma tabela no Word com um cabeçalho e 1 linha contendo as tags abaixo. O BeeTask multiplicará as linhas para cada tarefa encontrada no período!

{tableItemTags.map((t) => (
{t.tag}

{t.desc}

))}
)} {/* Modais */} {orgId && ( <> setIsCreateOpen(false)} onSuccess={(newTemplate) => { setTemplates((prev) => [newTemplate, ...prev]) }} orgId={orgId} projects={projects} categories={categories} /> setIsGenerateOpen(false)} orgId={orgId} templates={templates} projects={projects} initialTemplateId={generateInitialTemplateId} /> )}
) }