diff --git a/add_client.php b/add_client.php
new file mode 100644
index 0000000..3f99418
--- /dev/null
+++ b/add_client.php
@@ -0,0 +1,27 @@
+prepare($sql);
+ $stmt->execute([$name, $website, $status]);
+
+ header("Location: clients.php?success=1");
+ exit();
+ } catch (PDOException $e) {
+ header("Location: clients.php?error=" . urlencode($e->getMessage()));
+ exit();
+ }
+ } else {
+ header("Location: clients.php?error=invalid_input");
+ exit();
+ }
+}
+?>
\ No newline at end of file
diff --git a/add_contact.php b/add_contact.php
new file mode 100644
index 0000000..d980618
--- /dev/null
+++ b/add_contact.php
@@ -0,0 +1,29 @@
+prepare($sql);
+ $stmt->execute([$client_id, $name, $email, $phone, $role]);
+
+ header("Location: contacts.php?success=1");
+ exit();
+ } catch (PDOException $e) {
+ header("Location: contacts.php?error=" . urlencode($e->getMessage()));
+ exit();
+ }
+ } else {
+ header("Location: contacts.php?error=invalid_input");
+ exit();
+ }
+}
+?>
\ No newline at end of file
diff --git a/add_expense.php b/add_expense.php
new file mode 100644
index 0000000..8d6f0cd
--- /dev/null
+++ b/add_expense.php
@@ -0,0 +1,31 @@
+prepare($sql);
+ $stmt->execute([$expense_date, $description, $amount, $category]);
+
+ // Redirect back to the expenses page with a success message
+ header("Location: expenses.php?success=1");
+ exit();
+ } catch (PDOException $e) {
+ // Handle error, maybe redirect with an error message
+ header("Location: expenses.php?error=" . urlencode($e->getMessage()));
+ exit();
+ }
+ } else {
+ // Handle invalid input
+ header("Location: expenses.php?error=invalid_input");
+ exit();
+ }
+}
+?>
\ No newline at end of file
diff --git a/add_item.php b/add_item.php
new file mode 100644
index 0000000..5ba690c
--- /dev/null
+++ b/add_item.php
@@ -0,0 +1,27 @@
+prepare($sql);
+ $stmt->execute([$name, $description, $price]);
+
+ header("Location: items.php?success=1");
+ exit();
+ } catch (PDOException $e) {
+ header("Location: items.php?error=" . urlencode($e->getMessage()));
+ exit();
+ }
+ } else {
+ header("Location: items.php?error=invalid_input");
+ exit();
+ }
+}
+?>
\ No newline at end of file
diff --git a/add_member.php b/add_member.php
index f567efd..d1d2974 100644
--- a/add_member.php
+++ b/add_member.php
@@ -27,11 +27,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$message = 'A member with this email address already exists.';
} else {
// Insert new member
- $sql = "INSERT INTO team_members (name, email, role) VALUES (:name, :email, :role)";
+ $password = password_hash('password', PASSWORD_DEFAULT);
+ $sql = "INSERT INTO team_members (name, email, role, password) VALUES (:name, :email, :role, :password)";
$stmt = $db->prepare($sql);
$stmt->bindParam(':name', $name);
$stmt->bindParam(':email', $email);
$stmt->bindParam(':role', $role);
+ $stmt->bindParam(':password', $password);
if ($stmt->execute()) {
$status = 'success';
diff --git a/add_project.php b/add_project.php
new file mode 100644
index 0000000..09f4f53
--- /dev/null
+++ b/add_project.php
@@ -0,0 +1,36 @@
+prepare($sql);
+
+ // Handle empty dates
+ $client_id = empty($client_id) ? null : $client_id;
+ $start_date = empty($start_date) ? null : $start_date;
+ $end_date = empty($end_date) ? null : $end_date;
+
+ $stmt->execute([$name, $description, $client_id, $status, $start_date, $end_date]);
+
+ header("Location: projects.php?success=1");
+ exit();
+ } catch (PDOException $e) {
+ header("Location: projects.php?error=" . urlencode($e->getMessage()));
+ exit();
+ }
+ } else {
+ header("Location: projects.php?error=invalid_input");
+ exit();
+ }
+}
+?>
diff --git a/add_ticket.php b/add_ticket.php
new file mode 100644
index 0000000..abec843
--- /dev/null
+++ b/add_ticket.php
@@ -0,0 +1,28 @@
+prepare($sql);
+ $stmt->execute([$title, $description, $status, $priority]);
+
+ header("Location: tickets.php?success=1");
+ exit();
+ } catch (PDOException $e) {
+ header("Location: tickets.php?error=" . urlencode($e->getMessage()));
+ exit();
+ }
+ } else {
+ header("Location: tickets.php?error=invalid_input");
+ exit();
+ }
+}
+?>
\ No newline at end of file
diff --git a/clients.php b/clients.php
new file mode 100644
index 0000000..86f63df
--- /dev/null
+++ b/clients.php
@@ -0,0 +1,94 @@
+query("SELECT id, name, website, status, created_at FROM clients ORDER BY name ASC");
+ $clients = $stmt->fetchAll(PDO::FETCH_ASSOC);
+} catch (PDOException $e) {
+ echo '
Error fetching clients: ' . $e->getMessage() . '
';
+ $clients = [];
+}
+?>
+
+
+
+
Clients
+
+ Add Client
+
+
+
+
+
+
+
+
+ Name
+ Website
+ Status
+ Created At
+ Actions
+
+
+
+
+
+ No clients found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contacts.php b/contacts.php
new file mode 100644
index 0000000..9b33414
--- /dev/null
+++ b/contacts.php
@@ -0,0 +1,110 @@
+query("SELECT contacts.*, clients.name as client_name FROM contacts JOIN clients ON contacts.client_id = clients.id ORDER BY contacts.name ASC");
+ $contacts = $stmt_contacts->fetchAll(PDO::FETCH_ASSOC);
+
+ $stmt_clients = $pdo->query("SELECT id, name FROM clients ORDER BY name ASC");
+ $clients = $stmt_clients->fetchAll(PDO::FETCH_ASSOC);
+} catch (PDOException $e) {
+ echo 'Error fetching data: ' . $e->getMessage() . '
';
+ $contacts = [];
+ $clients = [];
+}
+?>
+
+
+
+
Contacts
+
+ Add Contact
+
+
+
+
+
+
+
+
+ Name
+ Email
+ Phone
+ Client
+ Role
+ Actions
+
+
+
+
+
+ No contacts found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/db/setup.php b/db/setup.php
index 4957fca..a20ac9b 100644
--- a/db/setup.php
+++ b/db/setup.php
@@ -1,33 +1,120 @@
exec($sql);
- echo "Table 'team_members' created successfully (if it didn't exist). ";
+ // 1. Connect to MySQL without specifying a database
+ $dsn_nodb = "mysql:host=" . DB_HOST;
+ $pdo_nodb = new PDO($dsn_nodb, DB_USER, DB_PASS);
+ $pdo_nodb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- // Optional: Seed with some data
- $stmt = $db->query("SELECT COUNT(*) FROM team_members");
- if ($stmt->fetchColumn() == 0) {
- $seed_sql = "
- INSERT INTO `team_members` (name, email, role, status) VALUES
- ('John Doe', 'john.doe@example.com', 'Admin', 'active'),
- ('Jane Smith', 'jane.smith@example.com', 'Project Manager', 'active'),
- ('Peter Jones', 'peter.jones@example.com', 'Team Member', 'inactive');
- ";
- $db->exec($seed_sql);
- echo "Seeded 'team_members' table with initial data. ";
+ // 2. Create the database if it doesn't exist
+ $pdo_nodb->exec("CREATE DATABASE IF NOT EXISTS `" . DB_NAME . "`");
+
+ // 3. Now connect to the newly created database
+ $dsn_db = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME;
+ $pdo = new PDO($dsn_db, DB_USER, DB_PASS);
+ $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+ // 4. Create the table
+ $sql = "CREATE TABLE IF NOT EXISTS team_members (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ email VARCHAR(255) NOT NULL UNIQUE,
+ password VARCHAR(255) NOT NULL,
+ role VARCHAR(100),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ )";
+
+ $pdo->exec($sql);
+
+ $sql_expenses = "CREATE TABLE IF NOT EXISTS expenses (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ expense_date DATE NOT NULL,
+ description VARCHAR(255) NOT NULL,
+ amount DECIMAL(10, 2) NOT NULL,
+ category VARCHAR(100),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ )";
+
+ $pdo->exec($sql_expenses);
+
+ $sql_items = "CREATE TABLE IF NOT EXISTS items (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+ price DECIMAL(10, 2) NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ )";
+
+ $pdo->exec($sql_items);
+
+ $sql_tickets = "CREATE TABLE IF NOT EXISTS tickets (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ title VARCHAR(255) NOT NULL,
+ description TEXT,
+ status ENUM('Open', 'In Progress', 'Closed') NOT NULL DEFAULT 'Open',
+ priority ENUM('Low', 'Medium', 'High') NOT NULL DEFAULT 'Medium',
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ )";
+
+ $pdo->exec($sql_tickets);
+
+ $sql_clients = "CREATE TABLE IF NOT EXISTS clients (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ website VARCHAR(255),
+ status ENUM('Active', 'Inactive') NOT NULL DEFAULT 'Active',
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ )";
+
+ $pdo->exec($sql_clients);
+
+ $sql_contacts = "CREATE TABLE IF NOT EXISTS contacts (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ client_id INT NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ email VARCHAR(255) NOT NULL,
+ phone VARCHAR(50),
+ role VARCHAR(100),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE CASCADE
+ )";
+
+ $pdo->exec($sql_contacts);
+
+ $sql_projects = "CREATE TABLE IF NOT EXISTS projects (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+ client_id INT,
+ status ENUM('Not Started', 'In Progress', 'Completed') NOT NULL DEFAULT 'Not Started',
+ start_date DATE,
+ end_date DATE,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE SET NULL
+ )";
+
+ $pdo->exec($sql_projects);
+
+ // Check if there are any users in the team_members table
+ $stmt = $pdo->query("SELECT COUNT(*) FROM team_members");
+ $user_count = $stmt->fetchColumn();
+
+ if ($user_count == 0) {
+ // Insert a default admin user if no users exist
+ $admin_email = 'admin@example.com';
+ $admin_password = 'password123';
+ $hashed_password = password_hash($admin_password, PASSWORD_DEFAULT);
+
+ $insert_stmt = $pdo->prepare("INSERT INTO team_members (name, email, password, role) VALUES (?, ?, ?, ?)");
+ $insert_stmt->execute(['Admin', $admin_email, $hashed_password, 'Admin']);
+ echo "Default admin user created.\n";
}
+ echo "Database and table setup completed successfully.";
+
} catch (PDOException $e) {
die("DB setup failed: " . $e->getMessage());
}
+?>
\ No newline at end of file
diff --git a/db/setup_done.flag b/db/setup_done.flag
new file mode 100644
index 0000000..348ebd9
--- /dev/null
+++ b/db/setup_done.flag
@@ -0,0 +1 @@
+done
\ No newline at end of file
diff --git a/expenses.php b/expenses.php
new file mode 100644
index 0000000..a93786b
--- /dev/null
+++ b/expenses.php
@@ -0,0 +1,96 @@
+query("SELECT id, expense_date, description, amount, category FROM expenses ORDER BY expense_date DESC");
+ $expenses = $stmt->fetchAll(PDO::FETCH_ASSOC);
+} catch (PDOException $e) {
+ // Handle error, for now just display a message
+ echo 'Error fetching expenses: ' . $e->getMessage() . '
';
+ $expenses = [];
+}
+?>
+
+
+
+
Expenses
+
+ Add Expense
+
+
+
+
+
+
+
+
+ Date
+ Description
+ Amount
+ Category
+ Actions
+
+
+
+
+
+ No expenses found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/handle_login.php b/handle_login.php
new file mode 100644
index 0000000..216f0f7
--- /dev/null
+++ b/handle_login.php
@@ -0,0 +1,36 @@
+prepare($sql);
+ $stmt->execute([$email]);
+ $user = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if ($user && password_verify($password, $user['password'])) {
+ $_SESSION['user_id'] = $user['id'];
+ $_SESSION['user_name'] = $user['name'];
+ $_SESSION['user_role'] = $user['role'];
+ header("Location: index.php");
+ exit();
+ } else {
+ header("Location: login.php?error=Invalid credentials");
+ exit();
+ }
+ } catch (PDOException $e) {
+ header("Location: login.php?error=" . urlencode($e->getMessage()));
+ exit();
+ }
+ } else {
+ header("Location: login.php?error=Email and password are required");
+ exit();
+ }
+}
+?>
\ No newline at end of file
diff --git a/includes/auth.php b/includes/auth.php
new file mode 100644
index 0000000..9cf5fc6
--- /dev/null
+++ b/includes/auth.php
@@ -0,0 +1,14 @@
+
\ No newline at end of file
diff --git a/includes/header.php b/includes/header.php
index 9190c24..5b37741 100644
--- a/includes/header.php
+++ b/includes/header.php
@@ -1,5 +1,17 @@
@@ -31,15 +43,44 @@ session_start();
diff --git a/items.php b/items.php
new file mode 100644
index 0000000..20ede0c
--- /dev/null
+++ b/items.php
@@ -0,0 +1,89 @@
+query("SELECT id, name, description, price FROM items ORDER BY name ASC");
+ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
+} catch (PDOException $e) {
+ echo 'Error fetching items: ' . $e->getMessage() . '
';
+ $items = [];
+}
+?>
+
+
+
+
Items
+
+ Add Item
+
+
+
+
+
+
+
+
+ Name
+ Description
+ Price
+ Actions
+
+
+
+
+
+ No items found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/login.php b/login.php
new file mode 100644
index 0000000..cfc1d78
--- /dev/null
+++ b/login.php
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
Login
+
+
+
+
+
+ Email address
+
+
+
+ Password
+
+
+
+ Login
+
+
+
+
+
+
+
+
+
diff --git a/logout.php b/logout.php
new file mode 100644
index 0000000..248c535
--- /dev/null
+++ b/logout.php
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/projects.php b/projects.php
new file mode 100644
index 0000000..4babce5
--- /dev/null
+++ b/projects.php
@@ -0,0 +1,120 @@
+query("SELECT projects.*, clients.name as client_name FROM projects LEFT JOIN clients ON projects.client_id = clients.id ORDER BY projects.name ASC");
+ $projects = $stmt_projects->fetchAll(PDO::FETCH_ASSOC);
+
+ $stmt_clients = $pdo->query("SELECT id, name FROM clients ORDER BY name ASC");
+ $clients = $stmt_clients->fetchAll(PDO::FETCH_ASSOC);
+} catch (PDOException $e) {
+ echo 'Error fetching data: ' . $e->getMessage() . '
';
+ $projects = [];
+ $clients = [];
+}
+?>
+
+
+
+
Projects
+
+ Add Project
+
+
+
+
+
+
+
+
+ Name
+ Client
+ Status
+ Start Date
+ End Date
+ Actions
+
+
+
+
+
+ No projects found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Project Name
+
+
+
+ Description
+
+
+
+ Client
+
+ Select a client
+
+
+
+
+
+
+ Status
+
+ Not Started
+ In Progress
+ Completed
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tickets.php b/tickets.php
new file mode 100644
index 0000000..bb1da05
--- /dev/null
+++ b/tickets.php
@@ -0,0 +1,103 @@
+query("SELECT id, title, status, priority, created_at FROM tickets ORDER BY created_at DESC");
+ $tickets = $stmt->fetchAll(PDO::FETCH_ASSOC);
+} catch (PDOException $e) {
+ echo 'Error fetching tickets: ' . $e->getMessage() . '
';
+ $tickets = [];
+}
+?>
+
+
+
+
Tickets
+
+ Add Ticket
+
+
+
+
+
+
+
+
+ Title
+ Status
+ Priority
+ Created At
+ Actions
+
+
+
+
+
+ No tickets found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Title
+
+
+
+ Description
+
+
+
+ Status
+
+ Open
+ In Progress
+ Closed
+
+
+
+ Priority
+
+ Low
+ Medium
+ High
+
+
+
+
+
+
+
+
+
+