Add remaining admin dashboard files (final chunk)

This commit is contained in:
George Birikorang 2025-09-19 21:37:57 -07:00
parent 758728a093
commit 7f70170fe1
513 changed files with 7857 additions and 0 deletions

View file

@ -0,0 +1,272 @@
const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
class AdminSync {
constructor() {
this.mainRepoPath = "temp-main";
this.adminRepoPath = process.cwd();
this.mainRepoUrl = "https://git.kh3group.com/george/website.git";
this.syncLog = [];
}
async syncToMain() {
console.log("🚀 Starting sync to main site...");
this.log("Starting sync process");
try {
// Step 1: Clone main repository
await this.cloneMainRepo();
// Step 2: Sync products.json
await this.syncProducts();
// Step 3: Sync images
await this.syncImages();
// Step 4: Validate changes
await this.validateChanges();
// Step 5: Commit and push
await this.commitAndPush();
// Step 6: Cleanup
this.cleanup();
console.log("✅ Successfully synced to main site!");
console.log("🌐 Your changes should be live shortly.");
this.log("Sync completed successfully");
} catch (error) {
console.error("❌ Sync failed:", error.message);
this.log(`Sync failed: ${error.message}`, "error");
this.cleanup();
process.exit(1);
}
}
async cloneMainRepo() {
console.log("📥 Cloning main repository...");
this.log("Cloning main repository");
if (fs.existsSync(this.mainRepoPath)) {
execSync(`rm -rf ${this.mainRepoPath}`);
}
try {
execSync(`git clone ${this.mainRepoUrl} ${this.mainRepoPath}`, {
stdio: "pipe",
});
execSync(`cd ${this.mainRepoPath} && git checkout main`, {
stdio: "pipe",
});
this.log("Main repository cloned successfully");
} catch (error) {
throw new Error(`Failed to clone repository: ${error.message}`);
}
}
async syncProducts() {
console.log("📦 Syncing products.json...");
this.log("Syncing products data");
const adminProductsPath = path.join(
this.adminRepoPath,
"data/products.json"
);
const mainProductsPath = path.join(this.mainRepoPath, "data/products.json");
if (!fs.existsSync(adminProductsPath)) {
throw new Error("products.json not found in admin repo");
}
// Ensure main data directory exists
const mainDataDir = path.dirname(mainProductsPath);
if (!fs.existsSync(mainDataDir)) {
fs.mkdirSync(mainDataDir, { recursive: true });
}
// Copy products.json
fs.copyFileSync(adminProductsPath, mainProductsPath);
console.log(" ✅ Products synced");
this.log("Products data synced successfully");
}
async syncImages() {
console.log("🖼️ Syncing images...");
this.log("Syncing product images");
const adminImagesPath = path.join(
this.adminRepoPath,
"assets/images/products"
);
const mainImagesPath = path.join(
this.mainRepoPath,
"assets/images/products"
);
// Create main images directory if it doesn't exist
if (!fs.existsSync(mainImagesPath)) {
fs.mkdirSync(mainImagesPath, { recursive: true });
}
let imagesProcessed = 0;
let imagesRemoved = 0;
if (fs.existsSync(adminImagesPath)) {
// Get all files in admin images directory
const adminImages = fs.readdirSync(adminImagesPath);
const mainImages = fs.existsSync(mainImagesPath)
? fs.readdirSync(mainImagesPath)
: [];
// Copy new/updated images
for (const image of adminImages) {
const srcPath = path.join(adminImagesPath, image);
const destPath = path.join(mainImagesPath, image);
if (fs.statSync(srcPath).isFile()) {
fs.copyFileSync(srcPath, destPath);
console.log(` 📸 Copied: ${image}`);
imagesProcessed++;
}
}
// Remove orphaned images (in main but not in admin)
for (const image of mainImages) {
const adminImagePath = path.join(adminImagesPath, image);
if (!fs.existsSync(adminImagePath)) {
fs.unlinkSync(path.join(mainImagesPath, image));
console.log(` 🗑️ Removed: ${image}`);
imagesRemoved++;
}
}
}
console.log(
` ✅ Images synced (${imagesProcessed} copied, ${imagesRemoved} removed)`
);
this.log(
`Images synced: ${imagesProcessed} copied, ${imagesRemoved} removed`
);
}
async validateChanges() {
console.log("🔍 Validating changes...");
this.log("Validating synced data");
// Validate JSON
const productsPath = path.join(this.mainRepoPath, "data/products.json");
if (!fs.existsSync(productsPath)) {
throw new Error("products.json not found after sync");
}
let productsData;
try {
productsData = JSON.parse(fs.readFileSync(productsPath, "utf8"));
} catch (error) {
throw new Error("Invalid JSON in products.json");
}
if (!productsData.products || !Array.isArray(productsData.products)) {
throw new Error("Invalid products.json structure");
}
// Check if all referenced images exist
let missingImages = 0;
for (const product of productsData.products) {
if (product.images) {
for (const imagePath of product.images) {
const fullPath = path.join(this.mainRepoPath, imagePath);
if (!fs.existsSync(fullPath)) {
console.warn(`⚠️ Warning: Image not found: ${imagePath}`);
missingImages++;
}
}
}
}
if (missingImages > 0) {
console.warn(`⚠️ Found ${missingImages} missing images`);
}
console.log(" ✅ Validation passed");
this.log(`Validation passed (${missingImages} missing images)`);
}
async commitAndPush() {
console.log("💾 Committing and pushing changes...");
this.log("Committing and pushing changes");
try {
// Add all changes
execSync(`cd ${this.mainRepoPath} && git add .`, { stdio: "pipe" });
// Check if there are changes to commit
try {
execSync(`cd ${this.mainRepoPath} && git diff --cached --quiet`, {
stdio: "pipe",
});
console.log(" ℹ️ No changes to commit");
this.log("No changes to commit");
return;
} catch (error) {
// There are changes, proceed with commit
}
// Commit changes
const commitMessage = `Update products and images from admin dashboard - ${new Date().toISOString()}`;
execSync(`cd ${this.mainRepoPath} && git commit -m "${commitMessage}"`, {
stdio: "pipe",
});
// Push to main branch
execSync(`cd ${this.mainRepoPath} && git push origin main`, {
stdio: "pipe",
});
console.log(" ✅ Changes pushed to main repository");
this.log("Changes pushed successfully");
} catch (error) {
throw new Error(`Failed to commit/push: ${error.message}`);
}
}
cleanup() {
console.log("🧹 Cleaning up...");
this.log("Cleaning up temporary files");
if (fs.existsSync(this.mainRepoPath)) {
execSync(`rm -rf ${this.mainRepoPath}`);
}
}
log(message, type = "info") {
const timestamp = new Date().toISOString();
const logEntry = {
timestamp,
type,
message,
};
this.syncLog.push(logEntry);
// Save log to file
const logPath = path.join(this.adminRepoPath, "sync-log.json");
fs.writeFileSync(logPath, JSON.stringify(this.syncLog, null, 2));
}
// Method to get sync history
getSyncHistory() {
const logPath = path.join(this.adminRepoPath, "sync-log.json");
if (fs.existsSync(logPath)) {
return JSON.parse(fs.readFileSync(logPath, "utf8"));
}
return [];
}
}
// Run sync if called directly
if (require.main === module) {
const sync = new AdminSync();
sync.syncToMain();
}
module.exports = AdminSync;