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)}
>
{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
)}
);
};
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 (
{filters.showNames && (
{person.apelidos && (
{person.nome || person.nomeCompleto}
)}
“{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 && (
Gen: {person.generation}
{person.sexo === ‘masculino’ ? ‘♂’ : person.sexo === ‘feminino’ ? ‘♀’ : ‘⚲’}
{person.papelFamiliar && (
{person.papelFamiliar.length > 15 ? person.papelFamiliar.substring(0, 15) + ‘…’ : person.papelFamiliar}
)}
{/* Header */}
);
};
export default GenosociogramApp;
Genosociograma Terapêutico Completo
{/* Sidebar com filtros */}
{/* Busca */}
setSearchTerm(e.target.value)}
className=”w-full pl-9 pr-3 py-2 border rounded-lg”
placeholder=”Nome ou sobrenome…”
/>
{/* Filtros visuais */}
{/* Filtros por categoria */}
{/* Lista de pessoas */}
{/* Área principal */}
)}
Filtros Terapêuticos
{/* Busca */}
Elementos Visuais
Filtros
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)}`}
{showAnalysis && analysis && (
{Object.keys(analysis.namePatterns).length > 0 && (
)}
{Object.keys(analysis.healthPatterns).length > 0 && (
)}
{Object.keys(analysis.traumaPatterns).length > 0 && (
)}
{Object.keys(analysis.professionPatterns).length > 0 && (
)}
{Object.keys(analysis.secretPatterns).length > 0 && (
)}
)}
{/* Canvas do genosociograma */}
{/* Modal do formulário */}
{showForm && (
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}
🔤 Padrões de Nomes
{Object.entries(analysis.namePatterns) .sort((a, b) => b[1] – a[1]) .slice(0, 3) .map(([name, count]) => ({name}: {count}x
))}
🏥 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
))}
⚡ Padrões Traumáticos
{Object.entries(analysis.traumaPatterns) .sort((a, b) => b[1] – a[1]) .slice(0, 3) .map(([trauma, count]) => ({trauma}: {count}x
))}
💼 Padrões Profissionais
{Object.entries(analysis.professionPatterns) .sort((a, b) => b[1] – a[1]) .slice(0, 3) .map(([prof, count]) => ({prof}: {count}x
))}
🔒 Segredos Familiares
{Object.entries(analysis.secretPatterns).map(([secret, count]) => ({secret}: {count}
))}
{filteredPeople.map(person => renderPerson(person))}
{filteredPeople.length === 0 && (
)}
Nenhuma pessoa encontrada
Comece adicionando pessoas ao genograma ou ajuste os filtros
{editingPerson ? ‘Editar Pessoa’ : ‘Nova Pessoa no Genograma’}
{/* Tabs */}
{tabs.map(tab => {
const Icon = tab.icon;
return (
);
})}
{activeTab === ‘identification’ && (
)}
{activeTab === ‘ancestry’ && (
)}
{activeTab === ‘career’ && (
)}
{activeTab === ‘health’ && (
)}
{activeTab === ‘personal’ && (
)}
{activeTab === ‘death’ && (
)}
{activeTab === ‘systemic’ && (
)}
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”
/>
setFormData(prev => ({ …prev, homenagens: e.target.value }))}
className=”w-full p-2 border rounded-lg”
placeholder=”Santos, antepassados…”
/>
setFormData(prev => ({ …prev, apelidos: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
setFormData(prev => ({ …prev, dataNascimento: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
setFormData(prev => ({ …prev, horaNascimento: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
setFormData(prev => ({ …prev, localNascimento: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
setFormData(prev => ({ …prev, dataConcepcao: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
setFormData(prev => ({ …prev, posicaoFratria: e.target.value }))}
className=”w-full p-2 border rounded-lg”
placeholder=”Ex: Filho mais velho de 3, Caçula…”
/>
setFormData(prev => ({ …prev, papelFamiliar: e.target.value }))}
className=”w-full p-2 border rounded-lg”
placeholder=”Ex: O provedor, O bode expiatório…”
/>
setFormData(prev => ({ …prev, relacaoPacienteIndice: e.target.value }))}
className=”w-full p-2 border rounded-lg”
placeholder=”Mãe, Pai, Irmão…”
/>
2. Ancestralidade e Linhagem
setFormData(prev => ({ …prev, sobrenomesMae: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
setFormData(prev => ({ …prev, sobrenomesPai: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
setFormData(prev => ({ …prev, parceiro: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
setFormData(prev => ({ …prev, filhos: e.target.value }))}
className=”w-full p-2 border rounded-lg”
placeholder=”Nomes, idades, perdas…”
/>
4. Carreira e Finanças
setFormData(prev => ({ …prev, profissao: e.target.value }))}
className=”w-full p-2 border rounded-lg”
placeholder=”Vocação ou fardo familiar?”
/>
setFormData(prev => ({ …prev, setorAtividade: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
setFormData(prev => ({ …prev, escolaridade: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
5. Saúde e Sofrimento
6. Aspectos Pessoais e Análise
7. Dados de Morte (Se Aplicável)
setFormData(prev => ({ …prev, dataFalecimento: e.target.value }))}
className=”w-full p-2 border rounded-lg”
/>
setFormData(prev => ({ …prev, idadeObito: e.target.value }))}
className=”w-full p-2 border rounded-lg”
placeholder=”Ciclos repetitivos de mortes precoces?”
/>
setFormData(prev => ({ …prev, causaMorte: e.target.value }))}
className=”w-full p-2 border rounded-lg”
placeholder=”Biológica, acidente, suicídio, violência…”
/>
setFormData(prev => ({ …prev, localFalecimento: e.target.value }))}
className=”w-full p-2 border rounded-lg”
placeholder=”Diferente do nascimento? Migração, exílio, afastamento…”
/>