From ccc924ba43d4b71106cbb840e95598bdf472b253 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 26 Oct 2025 14:24:09 +0000 Subject: [PATCH] ver1 --- assets/css/custom.css | 34 ++ assets/js/main.js | 1 + chart_of_accounts.php | 303 +++++++++++++++ company_setup.php | 97 +++++ dashboard.php | 19 + db/migrate.php | 25 ++ db/migrations/001_create_users_table.sql | 10 + db/migrations/002_create_companies_table.sql | 11 + .../003_create_chart_of_accounts_table.sql | 12 + db/migrations/004_create_customers_table.sql | 11 + db/setup_db.php | 17 + includes/footer.php | 10 + includes/header.php | 38 ++ includes/session.php | 14 + includes/sidebar.php | 29 ++ index.php | 345 ++++++++++-------- login.php | 40 ++ logout.php | 21 ++ register.php | 53 +++ 19 files changed, 947 insertions(+), 143 deletions(-) create mode 100644 assets/css/custom.css create mode 100644 assets/js/main.js create mode 100644 chart_of_accounts.php create mode 100644 company_setup.php create mode 100644 dashboard.php create mode 100644 db/migrate.php create mode 100644 db/migrations/001_create_users_table.sql create mode 100644 db/migrations/002_create_companies_table.sql create mode 100644 db/migrations/003_create_chart_of_accounts_table.sql create mode 100644 db/migrations/004_create_customers_table.sql create mode 100644 db/setup_db.php create mode 100644 includes/footer.php create mode 100644 includes/header.php create mode 100644 includes/session.php create mode 100644 includes/sidebar.php create mode 100644 login.php create mode 100644 logout.php create mode 100644 register.php diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..380885b --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,34 @@ + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + background-color: #F8F9FA; + color: #212529; +} + +.navbar-brand { + font-weight: 700; +} + +.hero { + background: linear-gradient(to bottom, rgba(13, 110, 253, 0.05), rgba(255, 255, 255, 0)); + padding: 6rem 0; +} + +.hero h1 { + font-weight: 800; + font-size: 3.5rem; +} + +.feature-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 4rem; + height: 4rem; + border-radius: 0.75rem; +} + +.footer { + padding: 3rem 0; + background-color: #FFFFFF; +} diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..f4b9868 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1 @@ +// No custom JS needed for this initial step, but the file is here for future use. diff --git a/chart_of_accounts.php b/chart_of_accounts.php new file mode 100644 index 0000000..88215ab --- /dev/null +++ b/chart_of_accounts.php @@ -0,0 +1,303 @@ +prepare("SELECT id FROM companies WHERE user_id = ?"); +$stmt->execute([$user_id]); +$company = $stmt->fetch(); +$company_id = $company ? $company['id'] : null; + +// Handle POST requests +if ($_SERVER['REQUEST_METHOD'] === 'POST' && $company_id) { + $action = $_POST['action'] ?? ''; + + // ADD ACCOUNT + if ($action === 'add_account') { + $account_code = trim($_POST['account_code'] ?? ''); + $account_name = trim($_POST['account_name'] ?? ''); + $account_type = trim($_POST['account_type'] ?? ''); + $description = trim($_POST['description'] ?? ''); + + if (empty($account_code) || empty($account_name) || empty($account_type)) { + $errors[] = 'Account Code, Name, and Type are required.'; + } + if (empty($errors)) { + $stmt = $pdo->prepare("INSERT INTO chart_of_accounts (company_id, account_code, account_name, account_type, description) VALUES (?, ?, ?, ?, ?)"); + if ($stmt->execute([$company_id, $account_code, $account_name, $account_type, $description])) { + $success_message = 'Account added successfully!'; + } else { + $errors[] = 'Failed to add account. The account code may already exist.'; + } + } + } + + // EDIT ACCOUNT + if ($action === 'edit_account') { + $account_id = $_POST['account_id'] ?? null; + $account_code = trim($_POST['account_code'] ?? ''); + $account_name = trim($_POST['account_name'] ?? ''); + $account_type = trim($_POST['account_type'] ?? ''); + $description = trim($_POST['description'] ?? ''); + + if (empty($account_id) || empty($account_code) || empty($account_name) || empty($account_type)) { + $errors[] = 'All fields are required for editing.'; + } + if (empty($errors)) { + $stmt = $pdo->prepare("UPDATE chart_of_accounts SET account_code = ?, account_name = ?, account_type = ?, description = ? WHERE id = ? AND company_id = ?"); + if ($stmt->execute([$account_code, $account_name, $account_type, $description, $account_id, $company_id])) { + $success_message = 'Account updated successfully!'; + } else { + $errors[] = 'Failed to update account. The account code may already exist for another account.'; + } + } + } + + // DELETE ACCOUNT + if ($action === 'delete_account') { + $account_id = $_POST['account_id'] ?? null; + if (empty($account_id)) { + $errors[] = 'Invalid account for deletion.'; + } + if (empty($errors)) { + $stmt = $pdo->prepare("DELETE FROM chart_of_accounts WHERE id = ? AND company_id = ?"); + if ($stmt->execute([$account_id, $company_id])) { + $success_message = 'Account deleted successfully!'; + } else { + $errors[] = 'Failed to delete account.'; + } + } + } +} + +// Fetch all accounts for the company +$accounts = []; +if ($company_id) { + $stmt = $pdo->prepare("SELECT * FROM chart_of_accounts WHERE company_id = ? ORDER BY account_code"); + $stmt->execute([$company_id]); + $accounts = $stmt->fetchAll(); +} + +require_once __DIR__ . '/includes/sidebar.php'; +?> + +
+

Chart of Accounts

+ +
+ +

This is the list of all financial accounts for your company.

+ + +
Please set up your company before managing accounts.
+ + + +
+ +

+ +
+ + + +
+

+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
CodeNameTypeDescriptionActions
+ + +
No accounts found. Please add one.
+
+
+ + + + + + + + + + + + + diff --git a/company_setup.php b/company_setup.php new file mode 100644 index 0000000..c0a86e6 --- /dev/null +++ b/company_setup.php @@ -0,0 +1,97 @@ +prepare("SELECT * FROM companies WHERE user_id = ?"); +$stmt->execute([$user_id]); +$company = $stmt->fetch(); + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $name = trim($_POST['name'] ?? ''); + $address = trim($_POST['address'] ?? ''); + $currency = trim($_POST['currency'] ?? 'SGD'); + $gst_number = trim($_POST['gst_number'] ?? ''); + + if (empty($name)) { + $errors[] = 'Company name is required.'; + } + + if (empty($errors)) { + if ($company) { + // Update existing record + $stmt = $pdo->prepare("UPDATE companies SET name = ?, address = ?, currency = ?, gst_number = ? WHERE user_id = ?"); + if ($stmt->execute([$name, $address, $currency, $gst_number, $user_id])) { + $success_message = 'Company settings updated successfully!'; + } else { + $errors[] = 'Failed to update settings. Please try again.'; + } + } else { + // Insert new record + $stmt = $pdo->prepare("INSERT INTO companies (user_id, name, address, currency, gst_number) VALUES (?, ?, ?, ?, ?)"); + if ($stmt->execute([$user_id, $name, $address, $currency, $gst_number])) { + $success_message = 'Company settings saved successfully!'; + } else { + $errors[] = 'Failed to save settings. Please try again.'; + } + } + // Refresh company data after update/insert + $stmt = $pdo->prepare("SELECT * FROM companies WHERE user_id = ?"); + $stmt->execute([$user_id]); + $company = $stmt->fetch(); + } +} + +require_once __DIR__ . '/includes/sidebar.php'; +?> + +

Company Settings

+

Use this form to set up or update your company's details. This information will be used on invoices and other official documents.

+ + +
+ +

+ +
+ + + +
+

+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ +
+
+
+ + \ No newline at end of file diff --git a/dashboard.php b/dashboard.php new file mode 100644 index 0000000..1607a86 --- /dev/null +++ b/dashboard.php @@ -0,0 +1,19 @@ + + + +

Dashboard

+

Welcome, ! This is your main dashboard. From here you can manage all aspects of your business.

+ +
+
+
+
+
Company Setup
+

Before you can start creating invoices or tracking inventory, you need to set up your company details.

+ Go to Company Setup +
+
+
+
+ + \ No newline at end of file diff --git a/db/migrate.php b/db/migrate.php new file mode 100644 index 0000000..01a585e --- /dev/null +++ b/db/migrate.php @@ -0,0 +1,25 @@ +exec($sql); + } catch (PDOException $e) { + echo "Error running migration: " . $e->getMessage() . "\n"; + return false; + } + } + echo "Migrations completed successfully.\n"; + return true; +} + +run_migrations(); + diff --git a/db/migrations/001_create_users_table.sql b/db/migrations/001_create_users_table.sql new file mode 100644 index 0000000..8e9556e --- /dev/null +++ b/db/migrations/001_create_users_table.sql @@ -0,0 +1,10 @@ + +CREATE TABLE IF NOT EXISTS `users` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `email` VARCHAR(255) NOT NULL, + `password` VARCHAR(255) NOT NULL, + `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `email` (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/db/migrations/002_create_companies_table.sql b/db/migrations/002_create_companies_table.sql new file mode 100644 index 0000000..2b6907c --- /dev/null +++ b/db/migrations/002_create_companies_table.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS `companies` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `user_id` INT UNSIGNED NOT NULL, + `name` VARCHAR(255) NOT NULL, + `address` TEXT, + `currency` VARCHAR(10) DEFAULT 'SGD', + `gst_number` VARCHAR(50), + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/db/migrations/003_create_chart_of_accounts_table.sql b/db/migrations/003_create_chart_of_accounts_table.sql new file mode 100644 index 0000000..c06f020 --- /dev/null +++ b/db/migrations/003_create_chart_of_accounts_table.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS `chart_of_accounts` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `company_id` INT NOT NULL, + `account_code` VARCHAR(20) NOT NULL, + `account_name` VARCHAR(255) NOT NULL, + `account_type` ENUM('Asset', 'Liability', 'Equity', 'Revenue', 'Expense') NOT NULL, + `description` TEXT, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY `company_account_code` (`company_id`, `account_code`), + FOREIGN KEY (`company_id`) REFERENCES `companies`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/db/migrations/004_create_customers_table.sql b/db/migrations/004_create_customers_table.sql new file mode 100644 index 0000000..4eafc90 --- /dev/null +++ b/db/migrations/004_create_customers_table.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS `customers` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `company_id` INT NOT NULL, + `name` VARCHAR(255) NOT NULL, + `email` VARCHAR(255), + `phone` VARCHAR(50), + `address` TEXT, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (`company_id`) REFERENCES `companies`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/db/setup_db.php b/db/setup_db.php new file mode 100644 index 0000000..0ba1ba0 --- /dev/null +++ b/db/setup_db.php @@ -0,0 +1,17 @@ + PDO::ERRMODE_EXCEPTION, + ]); + + // Create the database if it doesn't exist + $pdo->exec("CREATE DATABASE IF NOT EXISTS `" . DB_NAME . "`"); + echo "Database '" . DB_NAME . "' created or already exists.\n"; + +} catch (PDOException $e) { + die("DB ERROR: " . $e->getMessage()); +} + diff --git a/includes/footer.php b/includes/footer.php new file mode 100644 index 0000000..ebd9c06 --- /dev/null +++ b/includes/footer.php @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/includes/header.php b/includes/header.php new file mode 100644 index 0000000..ab6fcd2 --- /dev/null +++ b/includes/header.php @@ -0,0 +1,38 @@ + + + + + + + Dashboard - FAST ACCOUNTING + + + + + + + + +
+
diff --git a/includes/session.php b/includes/session.php new file mode 100644 index 0000000..b1ef4da --- /dev/null +++ b/includes/session.php @@ -0,0 +1,14 @@ + + + +
+
\ No newline at end of file diff --git a/index.php b/index.php index 7205f3d..940afe4 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,209 @@ - - + + - - - New Style - - - - - - - - - - - - - - - - - - - + + + FAST ACCOUNTING + + + + + + + + + + + + + + -
-
-

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

+ + + + + +
+
+

Modern Accounting, Made Simple.

+

The all-in-one accounting platform to manage your finances, from invoices to inventory.
Focus on your business, we'll handle the numbers.

+ +
+
+ + +
+
+
+

Everything Your Business Needs

+

A complete suite of tools to streamline your financial operations.

+
+
+
+
+
+ +
+

Easy Invoicing

+

Create and send professional invoices in seconds. Track payments and get paid faster.

+
+
+
+
+
+ +
+

Inventory Control

+

Manage stock levels, track goods, and automate purchase orders to avoid stockouts.

+
+
+
+
+
+ +
+

Financial Reports

+

Generate real-time reports like P&L, Balance Sheets, and Trial Balance with one click.

+
+
+
+
+
+ + +
+
+

© FAST ACCOUNTING. All Rights Reserved.

+
+
+ + + -
-
- Page updated: (UTC) -
+ + + + + + + diff --git a/login.php b/login.php new file mode 100644 index 0000000..3ad3724 --- /dev/null +++ b/login.php @@ -0,0 +1,40 @@ +prepare("SELECT * FROM users WHERE email = ?"); + $stmt->execute([$email]); + $user = $stmt->fetch(); + + if ($user && password_verify($password, $user['password'])) { + $_SESSION['user_id'] = $user['id']; + $_SESSION['user_name'] = $user['name']; + header('Location: /dashboard.php'); + exit; + } else { + $errors[] = 'Invalid email or password.'; + } + } + $_SESSION['login_errors'] = $errors; + header('Location: /index.php#loginModal'); + exit; +} + +// This script does not render HTML. It only processes the form. +header('Location: /index.php'); +exit; diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..910cc37 --- /dev/null +++ b/logout.php @@ -0,0 +1,21 @@ +prepare("SELECT id FROM users WHERE email = ?"); + $stmt->execute([$email]); + if ($stmt->fetch()) { + $errors[] = 'Email already in use.'; + } else { + $hashed_password = password_hash($password, PASSWORD_DEFAULT); + $stmt = $pdo->prepare("INSERT INTO users (name, email, password) VALUES (?, ?, ?)"); + if ($stmt->execute([$name, $email, $hashed_password])) { + $_SESSION['success_message'] = 'Registration successful! Please login.'; + header('Location: /index.php#loginModal'); + exit; + } else { + $errors[] = 'Something went wrong. Please try again.'; + } + } + } + // To display errors, we would need to render a form here. + // For now, we redirect back to the form with errors in session. + $_SESSION['register_errors'] = $errors; + header('Location: /index.php#signupModal'); + exit; +} +// This script does not render HTML. It only processes the form. +header('Location: /index.php'); +exit; \ No newline at end of file