prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$current_user_id]);
$user = $stmt->fetch();
if (!$user || $user['role'] !== 'founder') {
header("Location: dashboard.php");
exit;
}
// Onboarding check
if (!$user['onboarding_completed']) {
header("Location: founder_onboarding.php");
exit;
}
// Skill-based Matching Helper
function calculateMatchScore($me, $them) {
$score = 0;
// 1. My preferred skills vs Their skills
$myNeeds = array_filter(array_map('trim', explode(',', strtolower($me['preferred_co_founder_skills'] ?? ''))));
$theirSkills = array_filter(array_map('trim', explode(',', strtolower($them['skills'] ?? ''))));
$skillMatches = array_intersect($myNeeds, $theirSkills);
$score += count($skillMatches) * 10;
// 2. Their preferred skills vs My skills
$theirNeeds = array_filter(array_map('trim', explode(',', strtolower($them['preferred_co_founder_skills'] ?? ''))));
$mySkills = array_filter(array_map('trim', explode(',', strtolower($me['skills'] ?? ''))));
$reciprocalMatches = array_intersect($theirNeeds, $mySkills);
$score += count($reciprocalMatches) * 10;
// 3. Industry overlap
$myIndustries = array_filter(array_map('trim', explode(',', strtolower($me['startup_industries'] ?? ''))));
$theirIndustries = array_filter(array_map('trim', explode(',', strtolower($them['startup_industries'] ?? ''))));
$industryMatches = array_intersect($myIndustries, $theirIndustries);
$score += count($industryMatches) * 5;
// 4. University match (bonus)
if (!empty($me['university']) && $me['university'] === $them['university']) {
$score += 5;
}
return [
'total' => $score,
'skillMatches' => array_values($skillMatches),
'industryMatches' => array_values($industryMatches)
];
}
// Handle Swipe Logic
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'swipe') {
header('Content-Type: application/json');
$swiped_id = (int)$_POST['swiped_id'];
$direction = $_POST['direction']; // 'like' or 'dislike'
if ($swiped_id > 0 && in_array($direction, ['like', 'dislike'])) {
$stmt = db()->prepare("INSERT IGNORE INTO swipes (swiper_id, swiped_id, direction) VALUES (?, ?, ?)");
$stmt->execute([$current_user_id, $swiped_id, $direction]);
$isMatch = false;
if ($direction === 'like') {
$stmt = db()->prepare("SELECT id FROM swipes WHERE swiper_id = ? AND swiped_id = ? AND direction = 'like'");
$stmt->execute([$swiped_id, $current_user_id]);
if ($stmt->fetch()) {
$isMatch = true;
$stmt = db()->prepare("INSERT IGNORE INTO matches (user1_id, user2_id) VALUES (?, ?)");
$u1 = min($current_user_id, $swiped_id);
$u2 = max($current_user_id, $swiped_id);
$stmt->execute([$u1, $u2]);
$stmt = db()->prepare("INSERT INTO notifications (user_id, content) VALUES (?, ?)");
$stmt->execute([$swiped_id, "You have a new match! Start a conversation now."]);
$stmt->execute([$current_user_id, "You have a new match! Start a conversation now."]);
}
}
echo json_encode(['status' => 'success', 'match' => $isMatch]);
exit;
}
echo json_encode(['status' => 'error']);
exit;
}
// Fetch matches
$stmt = db()->prepare("
SELECT u.*, m.created_at as matched_at FROM matches m
JOIN users u ON (m.user1_id = u.id OR m.user2_id = u.id)
WHERE (m.user1_id = ? OR m.user2_id = ?) AND u.id != ?
ORDER BY m.created_at DESC
");
$stmt->execute([$current_user_id, $current_user_id, $current_user_id]);
$matches = $stmt->fetchAll();
// Fetch swipe candidates with scoring
$stmt = db()->prepare("
SELECT * FROM users
WHERE role = 'founder'
AND id != ?
AND onboarding_completed = 1
AND id NOT IN (SELECT swiped_id FROM swipes WHERE swiper_id = ?)
LIMIT 50
");
$stmt->execute([$current_user_id, $current_user_id]);
$allCandidates = $stmt->fetchAll();
foreach ($allCandidates as &$c) {
$c['match_data'] = calculateMatchScore($user, $c);
$c['score'] = $c['match_data']['total'];
}
usort($allCandidates, function($a, $b) { return $b['score'] <=> $a['score']; });
$swipeCandidates = array_slice($allCandidates, 0, 10);
// Fetch partners for Browse view
$search = $_GET['q'] ?? '';
$where = "role = 'founder' AND id != ? AND onboarding_completed = 1 AND id NOT IN (SELECT swiped_id FROM swipes WHERE swiper_id = ?)";
$params = [$current_user_id, $current_user_id];
if ($search) {
$where .= " AND (full_name LIKE ? OR skills LIKE ? OR university LIKE ? OR startup_industries LIKE ?)";
$params[] = "%$search%";
$params[] = "%$search%";
$params[] = "%$search%";
$params[] = "%$search%";
}
$stmt = db()->prepare("SELECT * FROM users WHERE $where LIMIT 40");
$stmt->execute($params);
$browseCandidates = $stmt->fetchAll();
foreach ($browseCandidates as &$c) {
$c['match_data'] = calculateMatchScore($user, $c);
$c['score'] = $c['match_data']['total'];
}
if (!$search) {
usort($browseCandidates, function($a, $b) { return $b['score'] <=> $a['score']; });
}
$platformName = defined('PLATFORM_NAME') ? PLATFORM_NAME : 'Gatsby';
?>
Find Partners — = htmlspecialchars($platformName) ?>
Out of candidates!
Try switching to Browse Mode or check back later.
= htmlspecialchars($c['full_name']) ?>
= htmlspecialchars($c['university']) ?> • = htmlspecialchars($c['degree_program']) ?>
= htmlspecialchars($c['bio'] ?: 'A visionary founder looking for a like-minded partner.') ?>
= $isNeeded ? ' ' : '' ?>
= htmlspecialchars(trim($skill)) ?>
= 10): ?>
Top Match
 ?>)
= substr($c['full_name'], 0, 1) ?>
= htmlspecialchars($c['full_name']) ?>
= htmlspecialchars($c['university']) ?>
= htmlspecialchars($c['bio'] ?: 'Looking for a co-founder to build something great.') ?>
= htmlspecialchars(trim($skill)) ?>