diff --git a/!install!!/fix_tjj.py b/!install!!/fix_tjj.py deleted file mode 100644 index fcdcae5..0000000 --- a/!install!!/fix_tjj.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env python3 -import subprocess, os - -BASE = '/home/tomsjavajive.com/public_html' - -# ── Fix 1: Remove wholesale and careers from footer ────────── -print("[1] Fixing footer...") -f = BASE + '/includes/footer.php' -with open(f) as fh: - c = fh.read() - -before = len(c) -c = c.replace('
  • Wholesale
  • \n', '') -c = c.replace('
  • Careers
  • \n', '') -# Also try without leading spaces -c = c.replace('
  • Wholesale
  • \n', '') -c = c.replace('
  • Careers
  • \n', '') - -with open(f, 'w') as fh: - fh.write(c) -removed = before - len(c) -print(f" Footer: removed {removed} chars (wholesale + careers)") - -# ── Fix 2: Check account pages for errors ─────────────────── -print("\n[2] Checking account pages...") -for page in ['rewards', 'wishlist', 'reviews']: - path = f'{BASE}/account/{page}.php' - r = subprocess.run( - ['/usr/local/lsws/lsphp85/bin/php', '-d', 'display_errors=1', - '-d', 'error_reporting=32767', path], - capture_output=True, text=True - ) - output = r.stdout + r.stderr - errors = [l for l in output.split('\n') - if any(x in l for x in ['Fatal','Error','Undefined','undefined','Call to'])] - if errors: - print(f" {page}.php ERRORS:") - for e in errors[:3]: - print(f" {e[:120]}") - else: - # Check if page has actual HTML content - has_html = '<' in r.stdout and len(r.stdout) > 100 - print(f" {page}.php: {'OK - has content' if has_html else 'WARNING - minimal output'}") - -# ── Fix 3: Check admin customers Modal ────────────────────── -print("\n[3] Checking admin customers...") -f2 = BASE + '/admin/customers.php' -with open(f2) as fh: - c2 = fh.read() - -print(f" Modal.open present: {'Modal.open' in c2}") -print(f" openCustomerModal present: {'openCustomerModal' in c2}") -print(f" admin.js exists: {os.path.exists(BASE+'/admin/assets/admin.js')}") - -# Check if admin.js has Modal object -if os.path.exists(BASE+'/admin/assets/admin.js'): - with open(BASE+'/admin/assets/admin.js') as fh: - js = fh.read() - print(f" Modal object in admin.js: {'Modal' in js}") - print(f" admin.js size: {len(js)} chars") -else: - print(" admin.js MISSING - this is why customer modal doesn't work!") - # Create a basic Modal object - modal_js = """ -// Modal helper -const Modal = { - open: function(id) { - const el = document.getElementById(id); - if (el) { el.style.display = 'flex'; el.classList.add('active'); } - }, - close: function(id) { - const el = document.getElementById(id); - if (el) { el.style.display = 'none'; el.classList.remove('active'); } - } -}; -document.addEventListener('keydown', function(e) { - if (e.key === 'Escape') { - document.querySelectorAll('.modal-overlay.active').forEach(m => { - m.style.display = 'none'; m.classList.remove('active'); - }); - } -}); -document.addEventListener('click', function(e) { - if (e.target.classList.contains('modal-overlay')) { - e.target.style.display = 'none'; e.target.classList.remove('active'); - } -}); -""" - os.makedirs(BASE+'/admin/assets', exist_ok=True) - with open(BASE+'/admin/assets/admin.js', 'w') as fh: - fh.write(modal_js) - print(" Created admin.js with Modal object") - -# ── Fix 4: Check account page includes ───────────────────── -print("\n[4] Checking account page structure...") -for page in ['rewards', 'wishlist', 'reviews']: - path = f'{BASE}/account/{page}.php' - with open(path) as fh: - content = fh.read() - has_auth = 'CustomerAuth::require' in content - has_header = "require_once" in content and 'header' in content - has_footer = 'footer' in content - print(f" {page}.php: auth={has_auth}, header={has_header}, footer={has_footer}, size={len(content)}") - -print("\nDone!") diff --git a/!install!!/migration_v2.sql b/!install!!/migration_v2.sql deleted file mode 100644 index b4cbb58..0000000 --- a/!install!!/migration_v2.sql +++ /dev/null @@ -1,37 +0,0 @@ --- Migration: Add wishlist table and addresses column to customers --- Run this in phpMyAdmin to add the new features - --- Add addresses column to customers table -ALTER TABLE `customers` ADD COLUMN `addresses` JSON DEFAULT NULL AFTER `billing_address`; - --- Add preferences column to customers table -ALTER TABLE `customers` ADD COLUMN `preferences` JSON DEFAULT NULL AFTER `addresses`; - --- Add is_active column to customers table if not exists -ALTER TABLE `customers` ADD COLUMN `is_active` TINYINT(1) DEFAULT 1 AFTER `preferences`; - --- Create wishlist table -CREATE TABLE IF NOT EXISTS `wishlist` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `customer_id` VARCHAR(50) NOT NULL, - `product_id` VARCHAR(50) NOT NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - UNIQUE KEY `unique_wishlist` (`customer_id`, `product_id`), - INDEX `idx_customer` (`customer_id`), - INDEX `idx_product` (`product_id`), - FOREIGN KEY (`customer_id`) REFERENCES `customers`(`customer_id`) ON DELETE CASCADE, - FOREIGN KEY (`product_id`) REFERENCES `products`(`product_id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- Add reorder_level column to products if not exists -ALTER TABLE `products` ADD COLUMN `reorder_level` INT DEFAULT 10 AFTER `low_stock_threshold`; - --- Add slug column to products if not exists -ALTER TABLE `products` ADD COLUMN `slug` VARCHAR(255) DEFAULT NULL AFTER `name`; -ALTER TABLE `products` ADD INDEX `idx_slug` (`slug`); - --- Update existing products to have slugs based on name -UPDATE `products` SET `slug` = LOWER(REPLACE(REPLACE(REPLACE(`name`, ' ', '-'), "'", ''), '"', '')) WHERE `slug` IS NULL; - --- Add is_pos_order to orders table -ALTER TABLE `orders` ADD COLUMN `is_pos_order` TINYINT(1) DEFAULT 0 AFTER `notes`; diff --git a/!install!!/migration_v3.sql b/!install!!/migration_v3.sql deleted file mode 100644 index 8b55223..0000000 --- a/!install!!/migration_v3.sql +++ /dev/null @@ -1,96 +0,0 @@ --- Migration: Add tables for push notifications, loyalty program, and integration settings --- Run this in phpMyAdmin - --- Push notification subscriptions -CREATE TABLE IF NOT EXISTS `push_subscriptions` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `customer_id` VARCHAR(50) DEFAULT NULL, - `endpoint` TEXT NOT NULL, - `p256dh_key` VARCHAR(255) NOT NULL, - `auth_key` VARCHAR(255) NOT NULL, - `is_active` TINYINT(1) DEFAULT 1, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX `idx_customer` (`customer_id`), - INDEX `idx_active` (`is_active`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- Push notifications queue -CREATE TABLE IF NOT EXISTS `push_notifications` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `notification_id` VARCHAR(50) NOT NULL UNIQUE, - `subscription_endpoint` TEXT NOT NULL, - `payload` TEXT NOT NULL, - `status` ENUM('pending', 'sent', 'failed') DEFAULT 'pending', - `error_message` TEXT DEFAULT NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `sent_at` TIMESTAMP NULL DEFAULT NULL, - INDEX `idx_status` (`status`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- Loyalty transactions history -CREATE TABLE IF NOT EXISTS `loyalty_transactions` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `transaction_id` VARCHAR(50) NOT NULL UNIQUE, - `customer_id` VARCHAR(50) NOT NULL, - `points` INT NOT NULL, - `type` ENUM('earn', 'redeem', 'tier_upgrade', 'birthday_bonus', 'referral_bonus', 'referral_welcome', 'adjustment', 'expiry') NOT NULL, - `description` VARCHAR(255) DEFAULT NULL, - `reference_amount` DECIMAL(10,2) DEFAULT NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX `idx_customer` (`customer_id`), - INDEX `idx_type` (`type`), - INDEX `idx_created` (`created_at`), - FOREIGN KEY (`customer_id`) REFERENCES `customers`(`customer_id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- Add lifetime_points and loyalty_tier to customers -ALTER TABLE `customers` - ADD COLUMN IF NOT EXISTS `lifetime_points` INT DEFAULT 0 AFTER `reward_points`, - ADD COLUMN IF NOT EXISTS `loyalty_tier` ENUM('bronze', 'silver', 'gold', 'platinum') DEFAULT 'bronze' AFTER `lifetime_points`, - ADD COLUMN IF NOT EXISTS `birthday` DATE DEFAULT NULL AFTER `loyalty_tier`, - ADD COLUMN IF NOT EXISTS `referral_code` VARCHAR(20) DEFAULT NULL AFTER `birthday`, - ADD COLUMN IF NOT EXISTS `referred_by` VARCHAR(50) DEFAULT NULL AFTER `referral_code`; - --- Add unique index on referral_code -ALTER TABLE `customers` ADD UNIQUE INDEX IF NOT EXISTS `idx_referral_code` (`referral_code`); - --- Update settings table with integration keys (INSERT IGNORE to not overwrite existing) -INSERT IGNORE INTO `settings` (`setting_key`, `setting_value`, `updated_at`) VALUES -('sendgrid_api_key', '', NOW()), -('sendgrid_from_email', 'noreply@tomsjavajive.com', NOW()), -('sendgrid_from_name', 'Tom''s Java Jive', NOW()), -('twilio_account_sid', '', NOW()), -('twilio_auth_token', '', NOW()), -('twilio_phone_number', '', NOW()), -('vapid_public_key', '', NOW()), -('vapid_private_key', '', NOW()), -('loyalty_enabled', '1', NOW()), -('email_notifications_enabled', '1', NOW()), -('sms_notifications_enabled', '0', NOW()), -('push_notifications_enabled', '1', NOW()); - --- Add Stripe checkout session column to orders -ALTER TABLE `orders` ADD COLUMN IF NOT EXISTS `stripe_checkout_session` VARCHAR(255) DEFAULT NULL AFTER `stripe_payment_intent`; - --- Payment transactions table for tracking payment attempts -CREATE TABLE IF NOT EXISTS `payment_transactions` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `transaction_id` VARCHAR(50) NOT NULL UNIQUE, - `order_id` VARCHAR(50) NOT NULL, - `customer_id` VARCHAR(50) DEFAULT NULL, - `amount` DECIMAL(10,2) NOT NULL, - `currency` VARCHAR(3) DEFAULT 'USD', - `payment_method` VARCHAR(50) DEFAULT 'stripe', - `stripe_session_id` VARCHAR(255) DEFAULT NULL, - `stripe_payment_intent` VARCHAR(255) DEFAULT NULL, - `status` ENUM('initiated', 'pending', 'processing', 'succeeded', 'failed', 'cancelled', 'refunded') DEFAULT 'initiated', - `metadata` JSON DEFAULT NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX `idx_order` (`order_id`), - INDEX `idx_customer` (`customer_id`), - INDEX `idx_status` (`status`), - INDEX `idx_stripe_session` (`stripe_session_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - diff --git a/!install!!/schema.sql b/!install!!/schema.sql deleted file mode 100644 index 131425f..0000000 --- a/!install!!/schema.sql +++ /dev/null @@ -1,402 +0,0 @@ --- Tom's Java Jive - MySQL Database Schema --- Version: 1.0 --- Compatible with MySQL 8.0+ - -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET AUTOCOMMIT = 0; -START TRANSACTION; -SET time_zone = "+00:00"; - --- -------------------------------------------------------- --- Database Schema for Tom's Java Jive --- NOTE: Database must already exist in cPanel --- Select your database in phpMyAdmin before importing --- -------------------------------------------------------- - --- -------------------------------------------------------- --- Table: settings --- -------------------------------------------------------- -CREATE TABLE `settings` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `setting_key` VARCHAR(100) NOT NULL UNIQUE, - `setting_value` JSON, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: admin_users --- -------------------------------------------------------- -CREATE TABLE `admin_users` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `user_id` VARCHAR(50) NOT NULL UNIQUE, - `email` VARCHAR(255) NOT NULL UNIQUE, - `password_hash` VARCHAR(255) DEFAULT NULL, - `name` VARCHAR(255) DEFAULT NULL, - `picture` VARCHAR(500) DEFAULT NULL, - `is_admin` TINYINT(1) DEFAULT 1, - `is_master` TINYINT(1) DEFAULT 0, - `permissions` JSON DEFAULT NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `last_login` TIMESTAMP NULL, - INDEX `idx_email` (`email`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: customers --- -------------------------------------------------------- -CREATE TABLE `customers` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `customer_id` VARCHAR(50) NOT NULL UNIQUE, - `email` VARCHAR(255) NOT NULL UNIQUE, - `password_hash` VARCHAR(255) DEFAULT NULL, - `name` VARCHAR(255) DEFAULT NULL, - `phone` VARCHAR(50) DEFAULT NULL, - `shipping_address` JSON DEFAULT NULL, - `billing_address` JSON DEFAULT NULL, - `wallet_balance` DECIMAL(10,2) DEFAULT 0.00, - `reward_points` INT DEFAULT 0, - `is_guest` TINYINT(1) DEFAULT 0, - `created_via` VARCHAR(50) DEFAULT 'web', - `email_verified` TINYINT(1) DEFAULT 0, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX `idx_email` (`email`), - INDEX `idx_customer_id` (`customer_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: products --- -------------------------------------------------------- -CREATE TABLE `products` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `product_id` VARCHAR(50) NOT NULL UNIQUE, - `name` VARCHAR(255) NOT NULL, - `description` TEXT, - `price` DECIMAL(10,2) NOT NULL, - `sale_price` DECIMAL(10,2) DEFAULT NULL, - `cost_price` DECIMAL(10,2) DEFAULT NULL, - `sku` VARCHAR(100) DEFAULT NULL, - `barcode` VARCHAR(100) DEFAULT NULL, - `category` VARCHAR(100) DEFAULT NULL, - `tags` JSON DEFAULT NULL, - `images` JSON DEFAULT NULL, - `stock` INT DEFAULT 0, - `low_stock_threshold` INT DEFAULT 10, - `weight` DECIMAL(10,2) DEFAULT NULL, - `dimensions` JSON DEFAULT NULL, - `is_active` TINYINT(1) DEFAULT 1, - `is_featured` TINYINT(1) DEFAULT 0, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX `idx_product_id` (`product_id`), - INDEX `idx_category` (`category`), - INDEX `idx_is_active` (`is_active`), - FULLTEXT INDEX `idx_search` (`name`, `description`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: orders --- -------------------------------------------------------- -CREATE TABLE `orders` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `order_id` VARCHAR(50) NOT NULL UNIQUE, - `order_number` VARCHAR(20) NOT NULL UNIQUE, - `customer_id` VARCHAR(50) DEFAULT NULL, - `customer_email` VARCHAR(255) NOT NULL, - `customer_name` VARCHAR(255) DEFAULT NULL, - `customer_phone` VARCHAR(50) DEFAULT NULL, - `items` JSON NOT NULL, - `subtotal` DECIMAL(10,2) NOT NULL, - `shipping_cost` DECIMAL(10,2) DEFAULT 0.00, - `tax` DECIMAL(10,2) DEFAULT 0.00, - `discount` DECIMAL(10,2) DEFAULT 0.00, - `gift_card_discount` DECIMAL(10,2) DEFAULT 0.00, - `wallet_amount_used` DECIMAL(10,2) DEFAULT 0.00, - `total` DECIMAL(10,2) NOT NULL, - `shipping_address` JSON DEFAULT NULL, - `billing_address` JSON DEFAULT NULL, - `shipping_method` VARCHAR(50) DEFAULT NULL, - `payment_method` VARCHAR(50) DEFAULT NULL, - `payment_status` ENUM('pending', 'paid', 'failed', 'refunded', 'partially_refunded') DEFAULT 'pending', - `order_status` ENUM('pending', 'confirmed', 'processing', 'shipped', 'delivered', 'cancelled', 'refunded') DEFAULT 'pending', - `stripe_session_id` VARCHAR(255) DEFAULT NULL, - `stripe_payment_intent` VARCHAR(255) DEFAULT NULL, - `tracking_number` VARCHAR(100) DEFAULT NULL, - `tracking_url` VARCHAR(500) DEFAULT NULL, - `notes` TEXT DEFAULT NULL, - `is_pos_order` TINYINT(1) DEFAULT 0, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX `idx_order_id` (`order_id`), - INDEX `idx_customer_id` (`customer_id`), - INDEX `idx_customer_email` (`customer_email`), - INDEX `idx_order_status` (`order_status`), - INDEX `idx_payment_status` (`payment_status`), - INDEX `idx_created_at` (`created_at`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: order_items (normalized for reporting) --- -------------------------------------------------------- -CREATE TABLE `order_items` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `order_id` VARCHAR(50) NOT NULL, - `product_id` VARCHAR(50) NOT NULL, - `name` VARCHAR(255) NOT NULL, - `price` DECIMAL(10,2) NOT NULL, - `quantity` INT NOT NULL, - `total` DECIMAL(10,2) NOT NULL, - INDEX `idx_order_id` (`order_id`), - INDEX `idx_product_id` (`product_id`), - FOREIGN KEY (`order_id`) REFERENCES `orders`(`order_id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: gift_cards --- -------------------------------------------------------- -CREATE TABLE `gift_cards` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `gift_card_id` VARCHAR(50) NOT NULL UNIQUE, - `code` VARCHAR(20) NOT NULL UNIQUE, - `initial_balance` DECIMAL(10,2) NOT NULL, - `current_balance` DECIMAL(10,2) NOT NULL, - `purchaser_email` VARCHAR(255) DEFAULT NULL, - `recipient_email` VARCHAR(255) DEFAULT NULL, - `recipient_name` VARCHAR(255) DEFAULT NULL, - `message` TEXT DEFAULT NULL, - `is_active` TINYINT(1) DEFAULT 1, - `expires_at` TIMESTAMP NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX `idx_code` (`code`), - INDEX `idx_is_active` (`is_active`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: gift_card_transactions --- -------------------------------------------------------- -CREATE TABLE `gift_card_transactions` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `gift_card_id` VARCHAR(50) NOT NULL, - `order_id` VARCHAR(50) DEFAULT NULL, - `amount` DECIMAL(10,2) NOT NULL, - `balance_after` DECIMAL(10,2) NOT NULL, - `type` ENUM('purchase', 'redemption', 'refund') NOT NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX `idx_gift_card_id` (`gift_card_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: wallet_transactions --- -------------------------------------------------------- -CREATE TABLE `wallet_transactions` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `transaction_id` VARCHAR(50) NOT NULL UNIQUE, - `customer_id` VARCHAR(50) NOT NULL, - `amount` DECIMAL(10,2) NOT NULL, - `balance_after` DECIMAL(10,2) NOT NULL, - `type` ENUM('deposit', 'withdrawal', 'purchase', 'refund', 'reward') NOT NULL, - `description` VARCHAR(255) DEFAULT NULL, - `order_id` VARCHAR(50) DEFAULT NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX `idx_customer_id` (`customer_id`), - INDEX `idx_type` (`type`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: reviews --- -------------------------------------------------------- -CREATE TABLE `reviews` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `review_id` VARCHAR(50) NOT NULL UNIQUE, - `product_id` VARCHAR(50) NOT NULL, - `customer_id` VARCHAR(50) DEFAULT NULL, - `customer_name` VARCHAR(255) NOT NULL, - `customer_email` VARCHAR(255) NOT NULL, - `rating` INT NOT NULL CHECK (rating >= 1 AND rating <= 5), - `title` VARCHAR(255) DEFAULT NULL, - `comment` TEXT, - `is_verified_purchase` TINYINT(1) DEFAULT 0, - `is_approved` TINYINT(1) DEFAULT 0, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX `idx_product_id` (`product_id`), - INDEX `idx_is_approved` (`is_approved`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: email_campaigns --- -------------------------------------------------------- -CREATE TABLE `email_campaigns` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `campaign_id` VARCHAR(50) NOT NULL UNIQUE, - `name` VARCHAR(255) NOT NULL, - `subject` VARCHAR(255) NOT NULL, - `content` TEXT NOT NULL, - `recipient_type` ENUM('all', 'customers_only', 'subscribers_only') DEFAULT 'all', - `status` ENUM('draft', 'scheduled', 'sent', 'cancelled') DEFAULT 'draft', - `scheduled_at` TIMESTAMP NULL, - `sent_at` TIMESTAMP NULL, - `recipients_count` INT DEFAULT 0, - `opened_count` INT DEFAULT 0, - `clicked_count` INT DEFAULT 0, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX `idx_status` (`status`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: email_subscribers --- -------------------------------------------------------- -CREATE TABLE `email_subscribers` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `email` VARCHAR(255) NOT NULL UNIQUE, - `name` VARCHAR(255) DEFAULT NULL, - `is_active` TINYINT(1) DEFAULT 1, - `source` VARCHAR(50) DEFAULT 'website', - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX `idx_is_active` (`is_active`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: abandoned_carts --- -------------------------------------------------------- -CREATE TABLE `abandoned_carts` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `cart_id` VARCHAR(50) NOT NULL UNIQUE, - `customer_id` VARCHAR(50) DEFAULT NULL, - `customer_email` VARCHAR(255) DEFAULT NULL, - `items` JSON NOT NULL, - `subtotal` DECIMAL(10,2) NOT NULL, - `recovery_email_sent` TINYINT(1) DEFAULT 0, - `recovered` TINYINT(1) DEFAULT 0, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX `idx_customer_email` (`customer_email`), - INDEX `idx_recovered` (`recovered`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: referrals --- -------------------------------------------------------- -CREATE TABLE `referrals` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `referral_id` VARCHAR(50) NOT NULL UNIQUE, - `referrer_customer_id` VARCHAR(50) NOT NULL, - `referral_code` VARCHAR(20) NOT NULL UNIQUE, - `referred_customer_id` VARCHAR(50) DEFAULT NULL, - `referred_email` VARCHAR(255) DEFAULT NULL, - `status` ENUM('pending', 'completed', 'expired') DEFAULT 'pending', - `reward_amount` DECIMAL(10,2) DEFAULT 5.00, - `reward_given` TINYINT(1) DEFAULT 0, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX `idx_referral_code` (`referral_code`), - INDEX `idx_referrer` (`referrer_customer_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: visitor_sessions --- -------------------------------------------------------- -CREATE TABLE `visitor_sessions` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `session_id` VARCHAR(100) NOT NULL UNIQUE, - `visitor_id` VARCHAR(50) NOT NULL, - `ip_address` VARCHAR(45) DEFAULT NULL, - `user_agent` TEXT DEFAULT NULL, - `current_page` VARCHAR(500) DEFAULT NULL, - `referrer` VARCHAR(500) DEFAULT NULL, - `country` VARCHAR(100) DEFAULT NULL, - `city` VARCHAR(100) DEFAULT NULL, - `is_active` TINYINT(1) DEFAULT 1, - `page_views` INT DEFAULT 1, - `started_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `last_activity` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX `idx_is_active` (`is_active`), - INDEX `idx_last_activity` (`last_activity`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: categories --- -------------------------------------------------------- -CREATE TABLE `categories` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `category_id` VARCHAR(50) NOT NULL UNIQUE, - `name` VARCHAR(255) NOT NULL, - `slug` VARCHAR(255) NOT NULL UNIQUE, - `description` TEXT DEFAULT NULL, - `image` VARCHAR(500) DEFAULT NULL, - `parent_id` VARCHAR(50) DEFAULT NULL, - `sort_order` INT DEFAULT 0, - `is_active` TINYINT(1) DEFAULT 1, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX `idx_slug` (`slug`), - INDEX `idx_is_active` (`is_active`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: coupons --- -------------------------------------------------------- -CREATE TABLE `coupons` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `coupon_id` VARCHAR(50) NOT NULL UNIQUE, - `code` VARCHAR(50) NOT NULL UNIQUE, - `discount_type` ENUM('percentage', 'fixed') NOT NULL DEFAULT 'percentage', - `discount_value` DECIMAL(10,2) NOT NULL, - `min_order_amount` DECIMAL(10,2) DEFAULT NULL, - `max_uses` INT DEFAULT NULL, - `times_used` INT DEFAULT 0, - `is_active` TINYINT(1) DEFAULT 1, - `starts_at` TIMESTAMP NULL, - `expires_at` TIMESTAMP NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX `idx_code` (`code`), - INDEX `idx_is_active` (`is_active`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: password_reset_tokens --- -------------------------------------------------------- -CREATE TABLE `password_reset_tokens` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `email` VARCHAR(255) NOT NULL, - `token` VARCHAR(255) NOT NULL, - `user_type` ENUM('admin', 'customer') NOT NULL, - `expires_at` TIMESTAMP NOT NULL, - `used` TINYINT(1) DEFAULT 0, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX `idx_token` (`token`), - INDEX `idx_email` (`email`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Table: sessions --- -------------------------------------------------------- -CREATE TABLE `sessions` ( - `id` INT AUTO_INCREMENT PRIMARY KEY, - `session_id` VARCHAR(128) NOT NULL UNIQUE, - `user_id` VARCHAR(50) DEFAULT NULL, - `user_type` ENUM('admin', 'customer') DEFAULT NULL, - `data` TEXT, - `ip_address` VARCHAR(45) DEFAULT NULL, - `user_agent` VARCHAR(255) DEFAULT NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `expires_at` TIMESTAMP NOT NULL, - INDEX `idx_session_id` (`session_id`), - INDEX `idx_expires_at` (`expires_at`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- -------------------------------------------------------- --- Insert default settings --- -------------------------------------------------------- -INSERT INTO `settings` (`setting_key`, `setting_value`) VALUES -('store_name', '"Tom\'s Java Jive"'), -('store_email', '"support@tomsjavajive.com"'), -('store_phone', '""'), -('store_address', '""'), -('currency', '"USD"'), -('currency_symbol', '"$"'), -('tax_rate', '0'), -('shipping', '{"flat_rate_enabled": true, "flat_rate_amount": 5.99, "free_shipping_threshold": 50, "weight_based_enabled": false}'), -('payment', '{"stripe_enabled": true, "paypal_enabled": false, "cod_enabled": false}'), -('email', '{"sendgrid_api_key": "", "sender_email": "noreply@tomsjavajive.com", "sender_name": "Tom\'s Java Jive"}'); - -COMMIT; diff --git a/.htaccess b/.htaccess index 745dda8..df1797e 100644 --- a/.htaccess +++ b/.htaccess @@ -8,9 +8,10 @@ RewriteEngine On # includes/*.php, and .git/ were all still reachable live despite the # RedirectMatch rules further down) — only mod_rewrite matching on REQUEST_URI # is confirmed to actually work here. This must come before other rewrites. -RewriteCond %{REQUEST_URI} ^/(\.git|config/|includes/.*\.php|install/|db/) +RewriteCond %{REQUEST_URI} ^/(\.git|config/|includes/.*\.php|install/|!install!!/|db/) RewriteRule .* - [F,L] -RewriteCond %{REQUEST_URI} \.sql$ +RewriteCond %{REQUEST_URI} \.sql$ [OR] +RewriteCond %{REQUEST_URI} \.py$ RewriteRule .* - [F,L] # Force HTTPS (uncomment in production) diff --git a/config/config.php b/config/config.php index d79e975..932a7ce 100644 --- a/config/config.php +++ b/config/config.php @@ -1,66 +1,2 @@