From b4397b355f57bc0e710d3b5470a5ab31bb71fe6c Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 19 Oct 2025 03:26:15 +0000 Subject: [PATCH] Sfepro v1 --- add_contact.php | 76 ++++++++++++ add_deal.php | 86 +++++++++++++ assets/css/custom.css | 37 ++++++ assets/js/main.js | 1 + contacts.php | 97 +++++++++++++++ db/config.php | 34 +++++ delete_contact.php | 41 +++++++ delete_deal.php | 28 +++++ edit_contact.php | 99 +++++++++++++++ edit_deal.php | 116 +++++++++++++++++ footer.php | 14 +++ header.php | 40 ++++++ index.php | 280 ++++++++++++++++++++---------------------- privacy.php | 11 ++ sitemap.xml | 21 ++++ 15 files changed, 837 insertions(+), 144 deletions(-) create mode 100644 add_contact.php create mode 100644 add_deal.php create mode 100644 assets/css/custom.css create mode 100644 assets/js/main.js create mode 100644 contacts.php create mode 100644 delete_contact.php create mode 100644 delete_deal.php create mode 100644 edit_contact.php create mode 100644 edit_deal.php create mode 100644 footer.php create mode 100644 header.php create mode 100644 privacy.php create mode 100644 sitemap.xml diff --git a/add_contact.php b/add_contact.php new file mode 100644 index 0000000..23fd65e --- /dev/null +++ b/add_contact.php @@ -0,0 +1,76 @@ +prepare("INSERT INTO contacts (name, company, email, phone, source, tags) VALUES (?, ?, ?, ?, ?, ?)"); + $stmt->execute([$name, $company, $email, $phone, $source, $tags]); + header("Location: index.php?success=1"); + exit(); + } catch (PDOException $e) { + $error_message = "Error: " . $e->getMessage(); + } + } +} + +include 'header.php'; +?> + +
+
+
+
+

Add New Contact

+
+
+ + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
+
+ + diff --git a/add_deal.php b/add_deal.php new file mode 100644 index 0000000..b967175 --- /dev/null +++ b/add_deal.php @@ -0,0 +1,86 @@ +query("SELECT id, name FROM contacts ORDER BY name ASC")->fetchAll(); + +$deal_stages = ['Lead', 'Qualified', 'Proposal', 'Won', 'Lost']; + +if ($_SERVER["REQUEST_METHOD"] == "POST") { + $title = trim($_POST['title']); + $value = trim($_POST['value']); + $stage = trim($_POST['stage']); + $close_date = trim($_POST['close_date']); + $contact_id = trim($_POST['contact_id']); + + if (empty($title) || empty($value) || empty($stage) || empty($contact_id)) { + $error_message = "Title, Value, Stage, and Contact are required fields."; + } elseif (!is_numeric($value)) { + $error_message = "Deal value must be a number."; + } else { + try { + $stmt = db()->prepare("INSERT INTO deals (title, value, stage, close_date, contact_id) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([$title, $value, $stage, $close_date, $contact_id]); + header("Location: index.php?success_deal=1"); + exit(); + } catch (PDOException $e) { + $error_message = "Error: " . $e->getMessage(); + } + } +} + +include 'header.php'; +?> + +
+
+
+
+

Add New Deal

+
+
+ + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
+
+ + diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..c2fe97d --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,37 @@ +/* Add your custom styles here */ +body { + background-color: #f8f9fa; +} + +.navbar { + margin-bottom: 2rem; +} + +.card { + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); +} + +/* Dashboard KPI cards */ +.card-text.fs-4 { + font-weight: 600; +} + +/* Kanban Board Styles */ +.kanban-board .card-header { + font-weight: 600; +} + +.kanban-board .card-body { + min-height: 400px; + overflow-y: auto; + background-color: #f4f6f9; +} + +.kanban-board .card-body .card { + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + transition: box-shadow 0.2s ease-in-out; +} + +.kanban-board .card-body .card:hover { + box-shadow: 0 4px 8px rgba(0,0,0,0.15); +} diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..52fef2d --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1 @@ +// Add your custom scripts here diff --git a/contacts.php b/contacts.php new file mode 100644 index 0000000..689e1fe --- /dev/null +++ b/contacts.php @@ -0,0 +1,97 @@ + '`name` ASC', + 'name_desc' => '`name` DESC', + 'company_asc' => '`company` ASC', + 'company_desc' => '`company` DESC', + 'created_at_asc' => '`created_at` ASC', + 'created_at_desc' => '`created_at` DESC', +]; +$order_by = $sort_options[$sort] ?? '`created_at` DESC'; + +try { + $pdo = db(); + $search_term = "%$search%"; + + $stmt = $pdo->prepare("SELECT * FROM contacts WHERE name LIKE :search OR company LIKE :search OR email LIKE :search ORDER BY $order_by"); + $stmt->bindParam(':search', $search_term); + $stmt->execute(); + $contacts = $stmt->fetchAll(); +} catch (PDOException $e) { + echo "Error: " . $e->getMessage(); + $contacts = []; +} +?> + +
+ ' . $_SESSION['success_message'] . '
'; + unset($_SESSION['success_message']); + } + if (isset($_SESSION['error_message'])) { + echo ''; + unset($_SESSION['error_message']); + } + ?> +
+

Contacts

+ Add Contact +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ No contacts found. Add one now. +
+ + +
+
+
+ +
+

+ | +
+ + Edit + + + Delete + + Source: +
+
+ + +
+ + + diff --git a/db/config.php b/db/config.php index cc9229f..c48fbb2 100644 --- a/db/config.php +++ b/db/config.php @@ -15,3 +15,37 @@ function db() { } return $pdo; } + +function db_init() { + $pdo = db(); + $contacts_table_sql = "" + CREATE TABLE IF NOT EXISTS `contacts` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `company` varchar(255) DEFAULT NULL, + `email` varchar(255) DEFAULT NULL, + `phone` varchar(255) DEFAULT NULL, + `source` varchar(255) DEFAULT NULL, + `tags` varchar(255) DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + """; + $pdo->exec($contacts_table_sql); + + $deals_table_sql = "" + CREATE TABLE IF NOT EXISTS `deals` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `title` VARCHAR(255) NOT NULL, + `value` DECIMAL(10, 2) NOT NULL, + `stage` VARCHAR(50) NOT NULL, + `close_date` DATE, + `contact_id` INT NOT NULL, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + """; + $pdo->exec($deals_table_sql); +} + +db_init(); diff --git a/delete_contact.php b/delete_contact.php new file mode 100644 index 0000000..15c6ac4 --- /dev/null +++ b/delete_contact.php @@ -0,0 +1,41 @@ +prepare("SELECT COUNT(*) FROM deals WHERE contact_id = :contact_id"); + $stmt->bindParam(':contact_id', $contact_id, PDO::PARAM_INT); + $stmt->execute(); + $deal_count = $stmt->fetchColumn(); + + if ($deal_count > 0) { + $_SESSION['error_message'] = "Cannot delete contact. It is associated with {$deal_count} deal(s). Please reassign or delete the deals first."; + } else { + // No associated deals, proceed with deletion + $stmt = $pdo->prepare("DELETE FROM contacts WHERE id = :id"); + $stmt->bindParam(':id', $contact_id, PDO::PARAM_INT); + + if ($stmt->execute() && $stmt->rowCount() > 0) { + $_SESSION['success_message'] = "Contact deleted successfully."; + } else { + $_SESSION['error_message'] = "Failed to delete contact or contact not found."; + } + } +} catch (PDOException $e) { + $_SESSION['error_message'] = "Database error: " . $e->getMessage(); +} + +header("Location: contacts.php"); +exit; +?> \ No newline at end of file diff --git a/delete_deal.php b/delete_deal.php new file mode 100644 index 0000000..12c347d --- /dev/null +++ b/delete_deal.php @@ -0,0 +1,28 @@ +prepare("DELETE FROM deals WHERE id = :id"); + $stmt->bindParam(':id', $deal_id, PDO::PARAM_INT); + + if ($stmt->execute() && $stmt->rowCount() > 0) { + $_SESSION['success_message'] = "Deal deleted successfully."; + } else { + $_SESSION['error_message'] = "Failed to delete deal or deal not found."; + } +} catch (PDOException $e) { + $_SESSION['error_message'] = "Database error: " . $e->getMessage(); +} + +header("Location: index.php"); +exit; +?> \ No newline at end of file diff --git a/edit_contact.php b/edit_contact.php new file mode 100644 index 0000000..d51e9d5 --- /dev/null +++ b/edit_contact.php @@ -0,0 +1,99 @@ +prepare("UPDATE contacts SET name = :name, company = :company, email = :email, phone = :phone, source = :source, tags = :tags WHERE id = :id"); + $stmt->execute([ + ':name' => $name, + ':company' => $company, + ':email' => $email, + ':phone' => $phone, + ':source' => $source, + ':tags' => $tags, + ':id' => $id + ]); + header("Location: contacts.php?status=updated"); + exit; + } catch (PDOException $e) { + $error = "Database error: " . $e->getMessage(); + } + } +} + +try { + $stmt = $pdo->prepare("SELECT * FROM contacts WHERE id = :id"); + $stmt->execute([':id' => $id]); + $contact = $stmt->fetch(); + + if (!$contact) { + header("Location: contacts.php"); + exit; + } +} catch (PDOException $e) { + echo "Error: " . $e->getMessage(); + exit; +} +?> + +
+

Edit Contact

+ + +
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + Cancel +
+
+
+ + diff --git a/edit_deal.php b/edit_deal.php new file mode 100644 index 0000000..730e0ce --- /dev/null +++ b/edit_deal.php @@ -0,0 +1,116 @@ +query("SELECT id, name, company FROM contacts ORDER BY name ASC"); + $contacts = $stmt->fetchAll(); +} catch (PDOException $e) { + $error = "Error fetching contacts: " . $e->getMessage(); + $contacts = []; +} + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $title = $_POST['title'] ?? ''; + $value = $_POST['value'] ?? 0; + $stage = $_POST['stage'] ?? 'Lead'; + $contact_id = $_POST['contact_id'] ?? null; + $close_date = $_POST['close_date'] ?? null; + + if (empty($title) || empty($contact_id)) { + $error = "Title and contact are required."; + } else { + try { + $stmt = $pdo->prepare("UPDATE deals SET title = :title, value = :value, stage = :stage, contact_id = :contact_id, close_date = :close_date WHERE id = :id"); + $stmt->execute([ + ':title' => $title, + ':value' => $value, + ':stage' => $stage, + ':contact_id' => $contact_id, + ':close_date' => !empty($close_date) ? $close_date : null, + ':id' => $id + ]); + header("Location: index.php?status=deal_updated"); + exit; + } catch (PDOException $e) { + $error = "Database error: " . $e->getMessage(); + } + } +} + +try { + $stmt = $pdo->prepare("SELECT * FROM deals WHERE id = :id"); + $stmt->execute([':id' => $id]); + $deal = $stmt->fetch(); + + if (!$deal) { + header("Location: index.php"); + exit; + } +} catch (PDOException $e) { + echo "Error: " . $e->getMessage(); + exit; +} + +$deal_stages = ['Lead', 'Prospecting', 'Qualification', 'Proposal', 'Negotiation', 'Closed Won', 'Closed Lost']; + +?> + +
+

Edit Deal

+ + +
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + Cancel +
+
+
+ + diff --git a/footer.php b/footer.php new file mode 100644 index 0000000..88941e6 --- /dev/null +++ b/footer.php @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/header.php b/header.php new file mode 100644 index 0000000..0d8531e --- /dev/null +++ b/header.php @@ -0,0 +1,40 @@ + + + + + + Sales CRM + + + + + + + + + + + + + +
diff --git a/index.php b/index.php index 7205f3d..45eb8be 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,142 @@ query(" + SELECT + d.id, d.title, d.value, d.stage, d.close_date, + c.name as contact_name, c.email as contact_email + FROM deals d + JOIN contacts c ON d.contact_id = c.id + ORDER BY d.created_at DESC +"); + +$all_deals = $deals_result ? $deals_result->fetchAll() : []; + +// --- KPI Calculations --- +$total_value = 0; +$deals_won = 0; +$deals_lost = 0; +$deals_in_progress = 0; +$deals_by_stage = [ + 'Lead' => [], + 'Contact Made' => [], + 'Proposal' => [], + 'Won' => [], + 'Lost' => [], +]; + +foreach ($all_deals as $deal) { + $total_value += $deal['value']; + if ($deal['stage'] == 'Won') { + $deals_won++; + } elseif ($deal['stage'] == 'Lost') { + $deals_lost++; + } else { + $deals_in_progress++; + } + if (array_key_exists($deal['stage'], $deals_by_stage)) { + $deals_by_stage[$deal['stage']][] = $deal; + } +} -$phpVersion = PHP_VERSION; -$now = date('Y-m-d H:i:s'); ?> - - - - - - New Style + ' . htmlspecialchars($_SESSION['success_message']) . ''; + unset($_SESSION['success_message']); +} +if (isset($_SESSION['error_message'])) { + echo ''; + unset($_SESSION['error_message']); +} ?> - - - - - - - - - - - - - - - - - - - - -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ + +
+
+
+
+
Total Pipeline Value
+

$

+
+
-
-
- Page updated: (UTC) -
- - +
+
+
+
Deals Won
+

+
+
+
+
+
+
+
Deals Lost
+

+
+
+
+
+
+
+
Deals In Progress
+

+
+
+
+ + + + +
+

Deal Pipeline

+ Add New Deal +
+ +
+ $deals): ?> +
+
+
+
+
+
+ +

No deals in this stage.

+ + +
+
+
+

+ Value: $ +

+

+ + +

+ +
+
+ + +
+
+
+ +
+ + + \ No newline at end of file diff --git a/privacy.php b/privacy.php new file mode 100644 index 0000000..59d7464 --- /dev/null +++ b/privacy.php @@ -0,0 +1,11 @@ + + +
+
+

Privacy Policy

+

This is a placeholder for your privacy policy.

+

Please replace this content with your actual privacy policy.

+
+
+ + diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..218f2cf --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,21 @@ + + + + http://your-domain.com/index.php + 2025-10-19 + daily + 1.0 + + + http://your-domain.com/add_contact.php + 2025-10-19 + weekly + 0.8 + + + http://your-domain.com/privacy.php + 2025-10-19 + monthly + 0.5 + +