genosociograma

import React, { useState, useCallback, useMemo } from ‘react’; import { Plus, Filter, Search, Users, Calendar, Heart, Briefcase, Activity, Eye, EyeOff, Download, Upload, BarChart3, Trash2, Brain, Clock, MapPin, Book, Star } from ‘lucide-react’; const GenosociogramApp = () => { const [people, setPeople] = useState([]); const [relationships, setRelationships] = useState([]); const [showForm, setShowForm] = useState(false); const [editingPerson, setEditingPerson] = useState(null); const [activeTab, setActiveTab] = useState(‘identification’); const [filters, setFilters] = useState({ showHealth: true, showRelationships: true, showProfessions: true, showDates: true, showNames: true, showSecrets: false, showTraumas: false, generation: ‘all’, gender: ‘all’, livingStatus: ‘all’ }); const [searchTerm, setSearchTerm] = useState(”); const [showAnalysis, setShowAnalysis] = useState(false); const [formData, setFormData] = useState({ // 1. Identificação e Início da Vida id: ”, nomeCompleto: ”, nome: ”, historiaDoNome: ”, projecaoDoNome: ”, homenagens: ”, sexo: ‘masculino’, dataNascimento: ”, horaNascimento: ”, localNascimento: ”, historiaDoNascimento: ”, dataConcepcao: ”, filiacao: ”, posicaoFratria: ”, papelFamiliar: ”, relacaoPacienteIndice: ”, statusVital: ‘vivo’, // 2. Ancestralidade e Linhagem apelidos: ”, sobrenomesMae: ”, sobrenomesPai: ”, ausenciaSobrenomes: ”, sobrenomesAvos: ”, analiseHerancaNomes: ”, linhagemMaterna: ”, linhagemPaterna: ”, aliancasExclusoes: ”, historicoRelacionamentos: ”, padroesCarreira: ”, historicoSaude: ”, padroesMigracao: ”, eventosTraumaticos: ”, padroesDivorcio: ”, recursosForças: ”, valoresCrencas: ”, acontecimentosSignificativos: ”, vinculoPais: ”, dinamicaPais: ”, dinamicaFratria: ”, confitosSecretos: ”, estadoCivil: ‘solteiro’, parceiro: ”, filhos: ”, // 4. Carreira e Finanças profissao: ”, setorAtividade: ”, relacionamentoDinheiro: ”, situacaoFinanceira: ”, // 5. Saúde e Sofrimento doencas: ”, vicios: ”, padroesSaudeRecorrentes: ”, causasSofrimento: ”, eventosTraumaticosDetalhes: ”, // 6. Aspectos Pessoais religiao: ”, dons: ”, tatuagens: ”, recursosForçasPessoais: ”, observacoes: ”, escolaridade: ”, // 7. Dados de Morte dataFalecimento: ”, idadeObito: ”, causaMorte: ”, localFalecimento: ”, // 8. Análise Sistêmica segredos: ”, gisant: ”, fantasmaTransgeracional: ”, simetrias: ”, comportamentosRepetitivos: ”, paraQueDor: ”, potencialCura: ”, sintoma: ”, buscaPessoa: ”, generation: 1, position: { x: 200, y: 200 } }); const resetForm = () => { setFormData({ id: ”, nomeCompleto: ”, nome: ”, historiaDoNome: ”, projecaoDoNome: ”, homenagens: ”, sexo: ‘masculino’, dataNascimento: ”, horaNascimento: ”, localNascimento: ”, historiaDoNascimento: ”, dataConcepcao: ”, filiacao: ”, posicaoFratria: ”, papelFamiliar: ”, relacaoPacienteIndice: ”, statusVital: ‘vivo’, apelidos: ”, sobrenomesMae: ”, sobrenomesPai: ”, ausenciaSobrenomes: ”, sobrenomesAvos: ”, analiseHerancaNomes: ”, linhagemMaterna: ”, linhagemPaterna: ”, aliancasExclusoes: ”, historicoRelacionamentos: ”, padroesCarreira: ”, historicoSaude: ”, padroesMigracao: ”, eventosTraumaticos: ”, padroesDivorcio: ”, recursosForças: ”, valoresCrencas: ”, acontecimentosSignificativos: ”, vinculoPais: ”, dinamicaPais: ”, dinamicaFratria: ”, confitosSecretos: ”, estadoCivil: ‘solteiro’, parceiro: ”, filhos: ”, profissao: ”, setorAtividade: ”, relacionamentoDinheiro: ”, situacaoFinanceira: ”, doencas: ”, vicios: ”, padroesSaudeRecorrentes: ”, causasSofrimento: ”, eventosTraumaticosDetalhes: ”, religiao: ”, dons: ”, tatuagens: ”, recursosForçasPessoais: ”, observacoes: ”, escolaridade: ”, dataFalecimento: ”, idadeObito: ”, causaMorte: ”, localFalecimento: ”, segredos: ”, gisant: ”, fantasmaTransgeracional: ”, simetrias: ”, comportamentosRepetitivos: ”, paraQueDor: ”, potencialCura: ”, sintoma: ”, buscaPessoa: ”, generation: 1, position: { x: 200 + Math.random() * 400, y: 200 + Math.random() * 300 } }); setActiveTab(‘identification’); }; const handleSubmit = () => { if (editingPerson) { setPeople(prev => prev.map(p => p.id === editingPerson.id ? { …formData, id: editingPerson.id } : p)); setEditingPerson(null); } else { const newPerson = { …formData, id: Date.now().toString() }; setPeople(prev => […prev, newPerson]); } resetForm(); setShowForm(false); }; const handleEdit = (person) => { setFormData(person); setEditingPerson(person); setShowForm(true); }; const handleDelete = (personId) => { setPeople(prev => prev.filter(p => p.id !== personId)); setRelationships(prev => prev.filter(r => r.from !== personId && r.to !== personId)); }; const filteredPeople = useMemo(() => { return people.filter(person => { if (searchTerm && !person.nomeCompleto.toLowerCase().includes(searchTerm.toLowerCase()) && !person.nome.toLowerCase().includes(searchTerm.toLowerCase())) { return false; } if (filters.generation !== ‘all’ && person.generation !== parseInt(filters.generation)) { return false; } if (filters.gender !== ‘all’ && person.sexo !== filters.gender) { return false; } if (filters.livingStatus !== ‘all’) { if (filters.livingStatus === ‘vivo’ && person.statusVital !== ‘vivo’) return false; if (filters.livingStatus === ‘falecido’ && person.statusVital !== ‘falecido’) return false; } return true; }); }, [people, filters, searchTerm]); const analyzePatterns = () => { const analysis = { namePatterns: {}, healthPatterns: {}, professionPatterns: {}, traumaPatterns: {}, secretPatterns: {}, symmetryPatterns: {}, generationStats: {}, genderDistribution: { masculino: 0, feminino: 0, outro: 0 }, livingStatus: { vivo: 0, falecido: 0 }, birthPatterns: {}, deathPatterns: {}, financialPatterns: {} }; people.forEach(person => { // Análise de nomes if (person.nome) { const firstName = person.nome.split(‘ ‘)[0]; analysis.namePatterns[firstName] = (analysis.namePatterns[firstName] || 0) + 1; } // Análise de saúde if (person.doencas) { const issues = person.doencas.split(‘,’).map(i => i.trim()); issues.forEach(issue => { analysis.healthPatterns[issue] = (analysis.healthPatterns[issue] || 0) + 1; }); } // Análise de profissões if (person.profissao) { analysis.professionPatterns[person.profissao] = (analysis.professionPatterns[person.profissao] || 0) + 1; } // Análise de traumas if (person.eventosTraumaticos) { const traumas = person.eventosTraumaticos.split(‘,’).map(t => t.trim()); traumas.forEach(trauma => { analysis.traumaPatterns[trauma] = (analysis.traumaPatterns[trauma] || 0) + 1; }); } // Análise de segredos if (person.segredos) { analysis.secretPatterns[‘Presença de segredos’] = (analysis.secretPatterns[‘Presença de segredos’] || 0) + 1; } // Simetrias if (person.simetrias) { analysis.symmetryPatterns[‘Simetrias identificadas’] = (analysis.symmetryPatterns[‘Simetrias identificadas’] || 0) + 1; } // Estatísticas por geração analysis.generationStats[person.generation] = (analysis.generationStats[person.generation] || 0) + 1; // Distribuição por gênero analysis.genderDistribution[person.sexo]++; // Status vital analysis.livingStatus[person.statusVital]++; // Padrões de nascimento (mês) if (person.dataNascimento) { const month = new Date(person.dataNascimento).getMonth() + 1; analysis.birthPatterns[`Mês ${month}`] = (analysis.birthPatterns[`Mês ${month}`] || 0) + 1; } // Padrões de morte (mês) if (person.dataFalecimento) { const month = new Date(person.dataFalecimento).getMonth() + 1; analysis.deathPatterns[`Mês ${month}`] = (analysis.deathPatterns[`Mês ${month}`] || 0) + 1; } // Situação financeira if (person.situacaoFinanceira) { analysis.financialPatterns[person.situacaoFinanceira] = (analysis.financialPatterns[person.situacaoFinanceira] || 0) + 1; } }); return analysis; }; const renderPerson = (person) => { const x = person.position?.x || 200; const y = person.position?.y || 200; return (
handleEdit(person)} >
{filters.showNames && (
{person.nome || person.nomeCompleto}
)}
{person.apelidos && (
“{person.apelidos}”
)} {filters.showDates && person.dataNascimento && (
*{new Date(person.dataNascimento).getFullYear()} {person.statusVital === ‘falecido’ && person.dataFalecimento && ` †${new Date(person.dataFalecimento).getFullYear()}`}
)} {person.posicaoFratria && (
{person.posicaoFratria}
)} {filters.showProfessions && person.profissao && (
{person.profissao}
)} {filters.showHealth && person.doencas && (
{person.doencas.length > 20 ? person.doencas.substring(0, 20) + ‘…’ : person.doencas}
)} {filters.showTraumas && person.eventosTraumaticos && (
Traumas
)} {filters.showSecrets && person.segredos && (
Segredo
)}
Gen: {person.generation} {person.sexo === ‘masculino’ ? ‘♂’ : person.sexo === ‘feminino’ ? ‘♀’ : ‘⚲’}
{person.papelFamiliar && (
{person.papelFamiliar.length > 15 ? person.papelFamiliar.substring(0, 15) + ‘…’ : person.papelFamiliar}
)}
); }; const analysis = showAnalysis ? analyzePatterns() : null; const tabs = [ { id: ‘identification’, label: ‘Identificação’, icon: Users }, { id: ‘ancestry’, label: ‘Ancestralidade’, icon: Heart }, { id: ‘career’, label: ‘Carreira’, icon: Briefcase }, { id: ‘health’, label: ‘Saúde’, icon: Activity }, { id: ‘personal’, label: ‘Pessoal’, icon: Star }, { id: ‘death’, label: ‘Morte’, icon: Calendar }, { id: ‘systemic’, label: ‘Análise Sistêmica’, icon: Brain } ]; return (
{/* Header */}

Genosociograma Terapêutico Completo

{/* Sidebar com filtros */}

Filtros Terapêuticos

{/* Busca */}
setSearchTerm(e.target.value)} className=”w-full pl-9 pr-3 py-2 border rounded-lg” placeholder=”Nome ou sobrenome…” />
{/* Filtros visuais */}

Elementos Visuais

{/* Filtros por categoria */}

Filtros

{/* Lista de pessoas */}

Pessoas Cadastradas ({filteredPeople.length})

{filteredPeople.map(person => (
handleEdit(person)} >
{person.nome || person.nomeCompleto}
Gen {person.generation} | {person.sexo === ‘masculino’ ? ‘♂’ : person.sexo === ‘feminino’ ? ‘♀’ : ‘⚲’} {person.papelFamiliar && ` | ${person.papelFamiliar.substring(0, 15)}`}
))}
{/* Área principal */}
{showAnalysis && analysis && (

Análise Sistêmica de Padrões

📊 Estatísticas Gerais

Total de pessoas: {people.length}
Vivos: {analysis.livingStatus.vivo || 0} | Falecidos: {analysis.livingStatus.falecido || 0}
♂ {analysis.genderDistribution.masculino} | ♀ {analysis.genderDistribution.feminino} | ⚲ {analysis.genderDistribution.outro}
{Object.keys(analysis.namePatterns).length > 0 && (

🔤 Padrões de Nomes

{Object.entries(analysis.namePatterns) .sort((a, b) => b[1] – a[1]) .slice(0, 3) .map(([name, count]) => (
{name}: {count}x
))}
)} {Object.keys(analysis.healthPatterns).length > 0 && (

🏥 Padrões de Saúde

{Object.entries(analysis.healthPatterns) .sort((a, b) => b[1] – a[1]) .slice(0, 3) .map(([issue, count]) => (
{issue}: {count}x
))}
)} {Object.keys(analysis.traumaPatterns).length > 0 && (

⚡ Padrões Traumáticos

{Object.entries(analysis.traumaPatterns) .sort((a, b) => b[1] – a[1]) .slice(0, 3) .map(([trauma, count]) => (
{trauma}: {count}x
))}
)} {Object.keys(analysis.professionPatterns).length > 0 && (

💼 Padrões Profissionais

{Object.entries(analysis.professionPatterns) .sort((a, b) => b[1] – a[1]) .slice(0, 3) .map(([prof, count]) => (
{prof}: {count}x
))}
)} {Object.keys(analysis.secretPatterns).length > 0 && (

🔒 Segredos Familiares

{Object.entries(analysis.secretPatterns).map(([secret, count]) => (
{secret}: {count}
))}
)}
)} {/* Canvas do genosociograma */}
{filteredPeople.map(person => renderPerson(person))} {filteredPeople.length === 0 && (

Nenhuma pessoa encontrada

Comece adicionando pessoas ao genograma ou ajuste os filtros

)}
{/* Modal do formulário */} {showForm && (

{editingPerson ? ‘Editar Pessoa’ : ‘Nova Pessoa no Genograma’}

{/* Tabs */}
{tabs.map(tab => { const Icon = tab.icon; return ( ); })}
{activeTab === ‘identification’ && (

1. Identificação e Início da Vida

setFormData(prev => ({ …prev, nomeCompleto: e.target.value }))} className=”w-full p-2 border rounded-lg” required />
setFormData(prev => ({ …prev, nome: e.target.value }))} className=”w-full p-2 border rounded-lg” />