/* 04 Muro de matches + 05 Perfil de match */ const MATCHES = [ { id:'lucia', name:'Lucía', age:27, city:'Madrid', score:93, badges:['Verificada','Cruce Club'], job:'Estratega en agencia', tags:['Cine indie','Vermut','Cerámica','Berlín-fan'], bio:'Escribo copies de día y guiones malos de noche. Me encanta la gente que se ríe fuerte y planifica poco.' }, { id:'mateo', name:'Mateo', age:29, city:'Madrid', score:91, badges:['Verificado','Cruce Club'], job:'Arquitecto', tags:['Correr','Vinilos','Puentes al norte','Cocinar'], bio:'Diseño espacios. Colecciono discos que ya nadie escucha. Busco alguien con quien construir cosas — pequeñas o grandes.' }, { id:'carmen', name:'Carmen', age:32, city:'Sevilla', score:89, badges:['Verificada','Cruce Signature'], job:'Fotógrafa freelance', tags:['Analógica','Viajar','Perros','Flamenco'], bio:'Sevilla es mi puerto. Salgo a fotografiar y vuelvo con historias. Me pierde una buena tortilla y una conversación que no tenga fin.' }, { id:'nerea', name:'Nerea', age:25, city:'Bilbao', score:87, badges:['Verificada'], job:'Product designer', tags:['Skate','Ambient','Sushi','Correr playa'], bio:'Bilbao. Diseño apps que no dan asco. Directa. Si me escribes con "hola guapa" te bloqueo.' }, { id:'diego', name:'Diego', age:28, city:'Barcelona', score:85, badges:['Verificado','Cruce Club'], job:'Chef de partida', tags:['Cocina asiática','Correr','Techno','Pádel'], bio:'Cocino para vivir y vivo para cocinar. Vengo de Bogotá, resido en Poblenou. Me río mucho — casi demasiado.' }, { id:'javier', name:'Javier', age:31, city:'Barcelona', score:84, badges:['Verificado','Cruce Signature'], job:'Founder SaaS', tags:['Vela','Vinos','Trekking','Lectura'], bio:'Empecé una empresa a los 26. Ahora quiero acordarme de mí. Busco alguien con criterio propio y risa fácil.' }, { id:'pablo', name:'Pablo', age:34, city:'Madrid', score:82, badges:['Verificado'], job:'Profesor de filosofía', tags:['Libros','Café de puchero','Tenis','Debate'], bio:'Enseño a adolescentes a pensar. Fuera del aula, café, tenis y demasiadas ganas de discutir sobre casi todo.' }, { id:'alba', name:'Alba', age:30, city:'Valencia', score:81, badges:['Verificada','Cruce Club'], job:'Bióloga marina', tags:['Buceo','Yoga','Cine coreano','Té matcha'], bio:'Vivo entre Valencia y el mar. Silencios cómodos, planes lentos y noches de películas subtituladas.' }, ]; const CURRENT_USER = { id: 'you', name: 'Tú', premium: false, }; function Wall({ go }) { const [filter, setFilter] = useState('all'); const [selected, setSelected] = useState(null); // Fase 1c: matches reales de la API (null = sin sesión o aún cargando -> demo) const [real, setReal] = useState(null); useEffect(() => { const s = window.CruceAPI && window.CruceAPI.Session.get(); if (!s) return; fetch('api/bridge.php/matches', { headers: { Authorization: 'Bearer ' + s.token } }) .then(r => r.ok ? r.json() : Promise.reject()) .then(d => { if (!d.ok) return; setReal(d.matches.map(m => ({ id: 'u' + m.id, name: m.name, age: m.age || '—', city: m.city || '', score: m.affinity, real: true, badges: [ m.verified ? 'Verificado' : null, m.plan === 'signature' ? 'Cruce Signature' : m.plan === 'club' ? 'Cruce Club' : null, m.intent_match ? 'Busca lo mismo' : null, ].filter(Boolean), job: m.job || '', tags: m.tags && m.tags.length ? m.tags : ['Recién llegado/a'], bio: m.bio || 'Este perfil aún no ha escrito su presentación.', venue: m.venue_prefs || '', }))); }) .catch(() => {}); // sin conexión: se queda el muro demo }, []); const list = real || MATCHES; const filtered = filter === 'all' ? list : list.filter(m => m.city === filter); if (selected) { return setSelected(null)} go={go}/>; } return (
Tu muro · actualizado ahora

{list.length} {list.length === 1 ? 'persona que' : 'personas que'} encajan contigo.

Ordenadas por afinidad. Toca cualquier perfil para leer más. Para hablar, activa Cruce Club.

{!real && (

MURO DEMO — entra con tu cuenta para ver personas reales.

)}
Chat bloqueado
Desbloquea el chat y videollamada.
Desde 29€ / mes. Cancela cuando quieras.
{['all','Madrid','Barcelona','Valencia','Sevilla','Bilbao'].map(c => ( ))}
Ordenados por CRUCE-Q
{filtered.map(m => ( setSelected(m)}/> ))}
Las sugerencias son orientativas. Puedes pedir revisión humana o ver por qué te sugerimos a alguien.
); } function MatchCard({ match, onOpen }) { return (
{match.score == null ? '—' : match.score}{match.score != null && %}
AFINIDAD
{match.badges.includes('Verificada') || match.badges.includes('Verificado') ? (
Verificado
) : null} {match.badges.includes('Cruce Signature') && (
Signature
)}
{match.name}, {match.age}
{match.city} · {match.job}
{match.tags.slice(0,3).map(t => {t})}
); } function ProfileView({ match, onBack, go }) { const [tab, setTab] = useState('bio'); return (
PERFIL · {match.id.toUpperCase()}
{(!match.real || match.verified) &&
Perfil verificado
}
ID: CR-{match.id.toUpperCase()}-{new Date().getFullYear()}
{[match.id, match.id, match.id, match.id].map((k,i) => (
))}

{match.name}, {match.age}

{match.city} · {match.job}
{match.badges.map(b => (
{b.includes('Verific') && } {b}
))}
AFINIDAD CRUCE-Q
{match.score == null ? '—' : match.score}{match.score != null && %}
{[ {t:'Valores', v:92}, {t:'Estilo de vida', v:88}, {t:'Comunicación', v:95}, {t:'Química', v:90}, ].map(b => (
{b.t}
{b.v}
))}
{['bio','intereses','test'].map(t => ( ))}
{tab === 'bio' && (

"{match.bio}"

{!match.real && ( <>
BUSCANDO
Relación seria
MASCOTAS
Sí, un gato
IDIOMAS
ES · EN · IT
)}
PLAN IDEAL
{match.real ? (match.venue || 'Por definir') : 'Vermut y museo'}
)} {tab === 'intereses' && (
{[...match.tags, 'Podcast','Vino natural','Arte moderno','Correr sin app','Berlín'].map(t => ( {t} ))}
)} {tab === 'test' && ( match.real ? (

Las respuestas del test son privadas. La afinidad que ves se calcula sobre ellas sin revelarlas.

) : (

Respuestas del test — solo las que compartió públicamente:

{[ {q:'Noche perfecta', a:'Sesión de vinilos en casa'}, {q:'Frase que la define', a:'"Nunca podría estar con alguien que no lea".'}, {q:'Fines de semana', a:'Cultura y museos'}, ].map((x,i) => (
P{i+1} · {x.q.toUpperCase()}
{x.a}
))}
))}
Chat y videollamada bloqueados
Activa Cruce Club para escribir a {match.name}.
); } function AppTopBar({ current, go }) { const me = (window.CruceAPI && window.CruceAPI.Session.get()) || null; const nav = [ { id: 'wall', label: 'Muro', icon: }, { id: 'chat', label: 'Mensajes', icon: , badge: 2 }, { id: 'events', label: 'Eventos', icon: }, { id: 'me', label: 'Mi perfil', icon: }, ]; return (
Cruce
); } window.Wall = Wall; window.AppTopBar = AppTopBar; window.MATCHES = MATCHES;