Initial commit

This commit is contained in:
2026-05-22 12:52:44 +00:00
commit 996ca0d621
122 changed files with 22749 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
#!/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(' <li><a href="/wholesale.php">Wholesale</a></li>\n', '')
c = c.replace(' <li><a href="/careers.php">Careers</a></li>\n', '')
# Also try without leading spaces
c = c.replace('<li><a href="/wholesale.php">Wholesale</a></li>\n', '')
c = c.replace('<li><a href="/careers.php">Careers</a></li>\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!")
+37
View File
@@ -0,0 +1,37 @@
-- 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`;
+96
View File
@@ -0,0 +1,96 @@
-- 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;
+402
View File
@@ -0,0 +1,402 @@
-- 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;