This commit is contained in:
Flatlogic Bot 2026-02-28 17:01:09 +00:00
parent eedf246822
commit 3b76e4ec5b
2 changed files with 68 additions and 23 deletions

View File

@ -0,0 +1,10 @@
-- Migration: Add startup_followers table
CREATE TABLE IF NOT EXISTS startup_followers (
id INT AUTO_INCREMENT PRIMARY KEY,
startup_id INT NOT NULL,
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_follow (startup_id, user_id),
FOREIGN KEY (startup_id) REFERENCES startups(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

View File

@ -22,6 +22,11 @@ if (!$startup) {
exit; exit;
} }
// Check if current user is following
$stmt = db()->prepare("SELECT 1 FROM startup_followers WHERE startup_id = ? AND user_id = ?");
$stmt->execute([$startup_id, $user_id]);
$isFollowing = (bool)$stmt->fetchColumn();
// Check for active funding round // Check for active funding round
$stmt = db()->prepare("SELECT * FROM funding_rounds WHERE startup_id = ? AND status = 'Active' LIMIT 1"); $stmt = db()->prepare("SELECT * FROM funding_rounds WHERE startup_id = ? AND status = 'Active' LIMIT 1");
$stmt->execute([$startup_id]); $stmt->execute([$startup_id]);
@ -34,6 +39,19 @@ $success = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$action = $_POST['action']; $action = $_POST['action'];
// Follow/Unfollow Actions (Available to all logged in users except the founder of this startup)
if ($action === 'follow' && $startup['founder_id'] != $user_id) {
$stmt = db()->prepare("INSERT IGNORE INTO startup_followers (startup_id, user_id) VALUES (?, ?)");
$stmt->execute([$startup_id, $user_id]);
$success = "You are now following " . $startup['name'] . "!";
$isFollowing = true;
} elseif ($action === 'unfollow' && $startup['founder_id'] != $user_id) {
$stmt = db()->prepare("DELETE FROM startup_followers WHERE startup_id = ? AND user_id = ?");
$stmt->execute([$startup_id, $user_id]);
$success = "You have unfollowed " . $startup['name'] . ".";
$isFollowing = false;
}
// Founder Actions // Founder Actions
if ($user['role'] === 'founder' && $startup['founder_id'] == $user_id) { if ($user['role'] === 'founder' && $startup['founder_id'] == $user_id) {
$round_id = isset($_POST['round_id']) ? (int)$_POST['round_id'] : 0; $round_id = isset($_POST['round_id']) ? (int)$_POST['round_id'] : 0;
@ -100,26 +118,32 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$stmt = db()->prepare("INSERT INTO startup_updates (startup_id, founder_id, title, content) VALUES (?, ?, ?, ?)"); $stmt = db()->prepare("INSERT INTO startup_updates (startup_id, founder_id, title, content) VALUES (?, ?, ?, ?)");
$stmt->execute([$startup_id, $user_id, $title, $content]); $stmt->execute([$startup_id, $user_id, $title, $content]);
// 2. Identify All Unique Investors for this startup // 2. Identify All Unique Investors AND Followers for this startup
$stmt = db()->prepare("SELECT DISTINCT u.id, u.email, u.full_name FROM investments i JOIN users u ON i.investor_id = u.id WHERE i.startup_id = ? AND i.status = 'approved'"); $stmt = db()->prepare("
$stmt->execute([$startup_id]); SELECT DISTINCT u.id, u.email, u.full_name
$investorsToNotify = $stmt->fetchAll(); FROM users u
LEFT JOIN investments i ON i.investor_id = u.id AND i.startup_id = ? AND i.status = 'approved'
LEFT JOIN startup_followers f ON f.user_id = u.id AND f.startup_id = ?
WHERE i.investor_id IS NOT NULL OR f.user_id IS NOT NULL
");
$stmt->execute([$startup_id, $startup_id]);
$peopleToNotify = $stmt->fetchAll();
// 3. Notify them // 3. Notify them
foreach ($investorsToNotify as $invUser) { foreach ($peopleToNotify as $targetUser) {
// DB Notification // DB Notification
$notif = db()->prepare("INSERT INTO notifications (user_id, content) VALUES (?, ?)"); $notif = db()->prepare("INSERT INTO notifications (user_id, content) VALUES (?, ?)");
$notif->execute([$invUser['id'], "New progress update from " . $startup['name'] . ": " . $title]); $notif->execute([$targetUser['id'], "New progress update from " . $startup['name'] . ": " . $title]);
// Email Notification // Email Notification
$subject = "New Update: " . $startup['name']; $subject = "New Update: " . $startup['name'];
$emailHtml = "<h1>New Update: " . htmlspecialchars($title) . "</h1><p>Hi " . htmlspecialchars($invUser['full_name']) . ", <strong>" . htmlspecialchars($startup['name']) . "</strong> has posted a new progress update:</p><hr><p>" . nl2br(htmlspecialchars($content)) . "</p>"; $emailHtml = "<h1>New Update: " . htmlspecialchars($title) . "</h1><p>Hi " . htmlspecialchars($targetUser['full_name']) . ", <strong>" . htmlspecialchars($startup['name']) . "</strong> has posted a new progress update:</p><hr><p>" . nl2br(htmlspecialchars($content)) . "</p>";
$emailText = "New Update: " . $title . "\n\nHi " . $invUser['full_name'] . ", " . $startup['name'] . " has posted a new progress update: " . $content; $emailText = "New Update: " . $title . "\n\nHi " . $targetUser['full_name'] . ", " . $startup['name'] . " has posted a new progress update: " . $content;
MailService::sendMail($invUser['email'], $subject, $emailHtml, $emailText); MailService::sendMail($targetUser['email'], $subject, $emailHtml, $emailText);
} }
db()->commit(); db()->commit();
$success = "Update posted and " . count($investorsToNotify) . " investors notified."; $success = "Update posted and " . count($peopleToNotify) . " backers/followers notified.";
} catch (Exception $e) { } catch (Exception $e) {
db()->rollBack(); db()->rollBack();
$error = "Failed to post update: " . $e->getMessage(); $error = "Failed to post update: " . $e->getMessage();
@ -263,13 +287,24 @@ $platformName = defined('PLATFORM_NAME') ? PLATFORM_NAME : 'Gatsby';
<div style="width: 80px; height: 80px; background: linear-gradient(135deg, var(--primary), var(--accent)); border-radius: 20px; display: flex; align-items: center; justify-content: center; color: white; font-size: 32px; font-weight: 700;"> <div style="width: 80px; height: 80px; background: linear-gradient(135deg, var(--primary), var(--accent)); border-radius: 20px; display: flex; align-items: center; justify-content: center; color: white; font-size: 32px; font-weight: 700;">
<?= substr($startup['name'], 0, 1) ?> <?= substr($startup['name'], 0, 1) ?>
</div> </div>
<div> <div style="flex: 1;">
<h1 style="margin: 0; font-size: 36px;"><?= htmlspecialchars($startup['name']) ?></h1> <h1 style="margin: 0; font-size: 36px;"><?= htmlspecialchars($startup['name']) ?></h1>
<div style="color: var(--text-secondary); display: flex; align-items: center; gap: 10px;"> <div style="color: var(--text-secondary); display: flex; align-items: center; gap: 10px;">
<span><i class="fas fa-calendar-alt"></i> Founded <?= date('M Y', strtotime($startup['created_at'])) ?></span> <span><i class="fas fa-calendar-alt"></i> Founded <?= date('M Y', strtotime($startup['created_at'])) ?></span>
<span class="badge"><?= ucfirst($startup['status']) ?></span> <span class="badge"><?= ucfirst($startup['status']) ?></span>
</div> </div>
</div> </div>
<?php if ($startup['founder_id'] != $user_id): ?>
<form method="POST">
<?php if ($isFollowing): ?>
<input type="hidden" name="action" value="unfollow">
<button type="submit" class="btn btn-outline" style="border-radius: 50px; padding: 10px 25px;"><i class="fas fa-check"></i> Following</button>
<?php else: ?>
<input type="hidden" name="action" value="follow">
<button type="submit" class="btn btn-primary" style="border-radius: 50px; padding: 10px 25px;"><i class="fas fa-plus"></i> Follow</button>
<?php endif; ?>
</form>
<?php endif; ?>
</div> </div>
<section class="card" style="margin-bottom: 40px;"> <section class="card" style="margin-bottom: 40px;">
@ -297,9 +332,9 @@ $platformName = defined('PLATFORM_NAME') ? PLATFORM_NAME : 'Gatsby';
</div> </div>
<div class="form-group" style="margin-bottom: 15px;"> <div class="form-group" style="margin-bottom: 15px;">
<label>What's happening?</label> <label>What's happening?</label>
<textarea name="update_content" class="form-control" rows="5" placeholder="Share your progress with investors..." required></textarea> <textarea name="update_content" class="form-control" rows="5" placeholder="Share your progress with backers and followers..." required></textarea>
</div> </div>
<button type="submit" class="btn btn-primary">Post & Notify Investors</button> <button type="submit" class="btn btn-primary">Post & Notify Everyone</button>
<button type="button" class="btn btn-secondary" onclick="document.getElementById('postUpdateForm').style.display='none'">Cancel</button> <button type="button" class="btn btn-secondary" onclick="document.getElementById('postUpdateForm').style.display='none'">Cancel</button>
</form> </form>
</div> </div>
@ -395,15 +430,6 @@ $platformName = defined('PLATFORM_NAME') ? PLATFORM_NAME : 'Gatsby';
<section class="card" style="margin-bottom: 30px;"> <section class="card" style="margin-bottom: 30px;">
<h3 style="margin-top: 0; margin-bottom: 20px;">Venture Stats</h3> <h3 style="margin-top: 0; margin-bottom: 20px;">Venture Stats</h3>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;"> <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
<div style="background: #f8fafc; padding: 15px; border-radius: 12px; text-align: center;">
<div style="color: var(--text-secondary); font-size: 13px; text-transform: uppercase; margin-bottom: 5px;">Total Rounds</div>
<?php
$stmt = db()->prepare("SELECT COUNT(*) FROM funding_rounds WHERE startup_id = ?");
$stmt->execute([$startup_id]);
$roundCount = $stmt->fetchColumn();
?>
<div style="font-size: 20px; font-weight: 700;"><?= $roundCount ?></div>
</div>
<div style="background: #f8fafc; padding: 15px; border-radius: 12px; text-align: center;"> <div style="background: #f8fafc; padding: 15px; border-radius: 12px; text-align: center;">
<div style="color: var(--text-secondary); font-size: 13px; text-transform: uppercase; margin-bottom: 5px;">Backers</div> <div style="color: var(--text-secondary); font-size: 13px; text-transform: uppercase; margin-bottom: 5px;">Backers</div>
<?php <?php
@ -413,6 +439,15 @@ $platformName = defined('PLATFORM_NAME') ? PLATFORM_NAME : 'Gatsby';
?> ?>
<div style="font-size: 20px; font-weight: 700;"><?= $backerCount ?></div> <div style="font-size: 20px; font-weight: 700;"><?= $backerCount ?></div>
</div> </div>
<div style="background: #f8fafc; padding: 15px; border-radius: 12px; text-align: center;">
<div style="color: var(--text-secondary); font-size: 13px; text-transform: uppercase; margin-bottom: 5px;">Followers</div>
<?php
$stmt = db()->prepare("SELECT COUNT(*) FROM startup_followers WHERE startup_id = ?");
$stmt->execute([$startup_id]);
$followerCount = $stmt->fetchColumn();
?>
<div style="font-size: 20px; font-weight: 700;"><?= $followerCount ?></div>
</div>
</div> </div>
</section> </section>
@ -457,4 +492,4 @@ $platformName = defined('PLATFORM_NAME') ? PLATFORM_NAME : 'Gatsby';
</footer> </footer>
</body> </body>
</html> </html>