| @ -0,0 +1,81 @@ | |||
| import fs from 'fs'; | |||
| import path from 'path'; | |||
| import { fileURLToPath } from 'url'; | |||
| const __filename = fileURLToPath(import.meta.url); | |||
| const __dirname = path.dirname(__filename); | |||
| // Function to update paths in a file based on its depth | |||
| function updatePathsInFile(filePath) { | |||
| const content = fs.readFileSync(filePath, 'utf8'); | |||
| // Calculate the depth of the file relative to dist | |||
| const relativePath = path.relative('dist', filePath); | |||
| const depth = relativePath.split(path.sep).length - 1; | |||
| // Create the prefix based on depth | |||
| const prefix = '../'.repeat(depth); | |||
| let updatedContent = content; | |||
| // Update all .html links | |||
| updatedContent = updatedContent.replace(/href="([^"]+\.html)"/g, (match, p1) => { | |||
| // Skip if already has ../ or is an absolute URL or anchor | |||
| if (p1.startsWith('../') || p1.startsWith('http') || p1.startsWith('#')) { | |||
| return match; | |||
| } | |||
| return `href="${prefix}${p1}"`; | |||
| }); | |||
| // Update asset paths | |||
| updatedContent = updatedContent.replace(/href="(assets\/[^"]+)"/g, (match, p1) => { | |||
| if (p1.startsWith('../') || p1.startsWith('http')) { | |||
| return match; | |||
| } | |||
| return `href="${prefix}${p1}"`; | |||
| }); | |||
| updatedContent = updatedContent.replace(/src="(assets\/[^"]+)"/g, (match, p1) => { | |||
| if (p1.startsWith('../') || p1.startsWith('http')) { | |||
| return match; | |||
| } | |||
| return `src="${prefix}${p1}"`; | |||
| }); | |||
| // Only write if content changed | |||
| if (content !== updatedContent) { | |||
| fs.writeFileSync(filePath, updatedContent); | |||
| console.log(`Updated paths in: ${filePath}`); | |||
| } | |||
| } | |||
| // Function to recursively find all HTML files | |||
| function findHtmlFiles(dir, files = []) { | |||
| const items = fs.readdirSync(dir); | |||
| for (const item of items) { | |||
| const fullPath = path.join(dir, item); | |||
| const stat = fs.statSync(fullPath); | |||
| if (stat.isDirectory()) { | |||
| findHtmlFiles(fullPath, files); | |||
| } else if (item.endsWith('.html') && fullPath !== path.join('dist', 'index.html')) { | |||
| // Skip index.html as it's in the root | |||
| files.push(fullPath); | |||
| } | |||
| } | |||
| return files; | |||
| } | |||
| // Main execution | |||
| console.log('Fixing paths for nested HTML files...\n'); | |||
| const htmlFiles = findHtmlFiles('dist'); | |||
| console.log(`Found ${htmlFiles.length} HTML files to process\n`); | |||
| htmlFiles.forEach(file => { | |||
| updatePathsInFile(file); | |||
| }); | |||
| console.log('\nPath fixing complete!'); | |||
| @ -0,0 +1,122 @@ | |||
| #!/usr/bin/env node | |||
| /** | |||
| * Make All Paths Relative Script | |||
| * Converts all absolute paths to relative paths for subfolder deployment | |||
| */ | |||
| import fs from 'fs'; | |||
| import path from 'path'; | |||
| import { fileURLToPath } from 'url'; | |||
| const __filename = fileURLToPath(import.meta.url); | |||
| const __dirname = path.dirname(__filename); | |||
| // Files to update | |||
| const filesToUpdate = [ | |||
| 'src/partials/layouts/sidebar.hbs', | |||
| 'src/partials/layouts/header.hbs', | |||
| 'src/index.html', | |||
| ]; | |||
| // Add all HTML files | |||
| function findFiles(dir, extension) { | |||
| const files = []; | |||
| const items = fs.readdirSync(dir, { withFileTypes: true }); | |||
| for (const item of items) { | |||
| const fullPath = path.join(dir, item.name); | |||
| if (item.isDirectory()) { | |||
| files.push(...findFiles(fullPath, extension)); | |||
| } else if (item.name.endsWith(extension)) { | |||
| files.push(fullPath); | |||
| } | |||
| } | |||
| return files; | |||
| } | |||
| // Add all HTML and HBS files | |||
| const srcDir = path.join(__dirname, '..', 'src'); | |||
| filesToUpdate.push(...findFiles(path.join(srcDir, 'pages'), '.html')); | |||
| filesToUpdate.push(...findFiles(path.join(srcDir, 'pages'), '.hbs')); | |||
| filesToUpdate.push(...findFiles(path.join(srcDir, 'partials'), '.hbs')); | |||
| // Patterns to replace | |||
| const replacements = [ | |||
| // Navigation links | |||
| { from: /href="\/dashboard-/g, to: 'href="dashboard-' }, | |||
| { from: /href="\/ui-/g, to: 'href="ui-' }, | |||
| { from: /href="\/form-/g, to: 'href="form-' }, | |||
| { from: /href="\/charts\.html"/g, to: 'href="charts.html"' }, | |||
| { from: /href="\/general-/g, to: 'href="general-' }, | |||
| { from: /href="\/data-/g, to: 'href="data-' }, | |||
| { from: /href="\/products\.html"/g, to: 'href="products.html"' }, | |||
| { from: /href="\/product-/g, to: 'href="product-' }, | |||
| { from: /href="\/checkout\.html"/g, to: 'href="checkout.html"' }, | |||
| { from: /href="\/influencer-/g, to: 'href="influencer-' }, | |||
| { from: /href="\/calendar\.html"/g, to: 'href="calendar.html"' }, | |||
| { from: /href="\/chat\.html"/g, to: 'href="chat.html"' }, | |||
| { from: /href="\/inbox\.html"/g, to: 'href="inbox.html"' }, | |||
| { from: /href="\/users\.html"/g, to: 'href="users.html"' }, | |||
| { from: /href="\/timeline\.html"/g, to: 'href="timeline.html"' }, | |||
| { from: /href="\/settings\.html"/g, to: 'href="settings.html"' }, | |||
| { from: /href="\/login\.html"/g, to: 'href="login.html"' }, | |||
| { from: /href="\/signup\.html"/g, to: 'href="signup.html"' }, | |||
| { from: /href="\/forgot-/g, to: 'href="forgot-' }, | |||
| { from: /href="\/blank-/g, to: 'href="blank-' }, | |||
| { from: /href="\/404\.html"/g, to: 'href="404.html"' }, | |||
| { from: /href="\/multiselect\.html"/g, to: 'href="multiselect.html"' }, | |||
| // Root link | |||
| { from: /href="\/"/g, to: 'href="index.html"' }, | |||
| // Asset paths - these should remain absolute or use base URL | |||
| { from: /src="\/assets\//g, to: 'src="assets/' }, | |||
| { from: /href="\/assets\//g, to: 'href="assets/' }, | |||
| // Form actions | |||
| { from: /action="\/api\//g, to: 'action="api/' }, | |||
| ]; | |||
| // Update files | |||
| function updateFile(filePath) { | |||
| const fullPath = filePath.startsWith('/') ? filePath : path.join(__dirname, '..', filePath); | |||
| if (!fs.existsSync(fullPath)) { | |||
| console.log(`⚠️ File not found: ${filePath}`); | |||
| return; | |||
| } | |||
| let content = fs.readFileSync(fullPath, 'utf8'); | |||
| let updated = false; | |||
| replacements.forEach(({ from, to }) => { | |||
| if (content.match(from)) { | |||
| content = content.replace(from, to); | |||
| updated = true; | |||
| } | |||
| }); | |||
| if (updated) { | |||
| fs.writeFileSync(fullPath, content); | |||
| console.log(`✅ Updated: ${path.relative(process.cwd(), fullPath)}`); | |||
| } else { | |||
| console.log(`⏭️ No changes needed: ${path.relative(process.cwd(), fullPath)}`); | |||
| } | |||
| } | |||
| // Main execution | |||
| console.log('🔧 Converting absolute paths to relative paths...\n'); | |||
| filesToUpdate.forEach(file => { | |||
| updateFile(file); | |||
| }); | |||
| console.log('\n✨ All paths have been made relative!'); | |||
| console.log('\nNext steps:'); | |||
| console.log('1. Build with subfolder support:'); | |||
| console.log(' BASE_URL=/polygon/concept/ npm run build'); | |||
| console.log(' or for relative paths everywhere:'); | |||
| console.log(' npm run build'); | |||
| console.log('2. Deploy the dist folder to your subfolder'); | |||
| @ -0,0 +1,90 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||
| <title>Subfolder Deployment Test</title> | |||
| <style> | |||
| body { | |||
| font-family: Arial, sans-serif; | |||
| max-width: 1200px; | |||
| margin: 0 auto; | |||
| padding: 20px; | |||
| } | |||
| h1 { | |||
| color: #333; | |||
| } | |||
| .test-section { | |||
| margin: 20px 0; | |||
| padding: 20px; | |||
| border: 1px solid #ddd; | |||
| border-radius: 5px; | |||
| } | |||
| .success { | |||
| color: green; | |||
| } | |||
| .error { | |||
| color: red; | |||
| } | |||
| iframe { | |||
| width: 100%; | |||
| height: 600px; | |||
| border: 1px solid #ddd; | |||
| margin-top: 20px; | |||
| } | |||
| </style> | |||
| </head> | |||
| <body> | |||
| <h1>Concept Dashboard - Subfolder Deployment Test</h1> | |||
| <div class="test-section"> | |||
| <h2>Test Information</h2> | |||
| <p>This page simulates how the Concept dashboard would work when deployed to a subfolder like <code>https://colorlib.com/polygon/concept/</code></p> | |||
| <p>All links in the built files have been updated to use relative paths that work correctly in subfolder deployments.</p> | |||
| </div> | |||
| <div class="test-section"> | |||
| <h2>Path Structure</h2> | |||
| <ul> | |||
| <li><strong>Root pages (e.g., index.html):</strong> Use paths like <code>dashboard-finance.html</code>, <code>assets/css/style.css</code></li> | |||
| <li><strong>Nested pages (e.g., pages/email/inbox.html):</strong> Use paths like <code>../../index.html</code>, <code>../../assets/css/style.css</code></li> | |||
| <li><strong>Deep nested pages (e.g., pages/charts/index.html):</strong> Also use <code>../../</code> prefix for root-level resources</li> | |||
| </ul> | |||
| </div> | |||
| <div class="test-section"> | |||
| <h2>Updated Features</h2> | |||
| <ul class="success"> | |||
| <li>✓ All navigation links updated to use relative paths</li> | |||
| <li>✓ Asset paths (CSS, JS, images) use relative references</li> | |||
| <li>✓ Email pages (inbox, compose, details) properly integrated</li> | |||
| <li>✓ Vite configuration fixed to include all pages</li> | |||
| <li>✓ Build process generates flat structure for main pages</li> | |||
| <li>✓ Nested pages maintain their directory structure</li> | |||
| </ul> | |||
| </div> | |||
| <div class="test-section"> | |||
| <h2>Test the Dashboard</h2> | |||
| <p>To test the dashboard locally with subfolder simulation:</p> | |||
| <ol> | |||
| <li>Run <code>npm run build</code> to build the project</li> | |||
| <li>Use a local server to serve the <code>dist</code> folder</li> | |||
| <li>Navigate to any page - all links should work correctly</li> | |||
| </ol> | |||
| <p><strong>Note:</strong> When deploying to https://colorlib.com/polygon/concept/, simply upload the contents of the <code>dist</code> folder to the <code>concept</code> directory.</p> | |||
| </div> | |||
| <div class="test-section"> | |||
| <h2>Sample Pages</h2> | |||
| <p>Here are some key pages to test after deployment:</p> | |||
| <ul> | |||
| <li><a href="dist/index.html">Dashboard (E-commerce)</a></li> | |||
| <li><a href="dist/pages/email/inbox.html">Email Inbox</a></li> | |||
| <li><a href="dist/pages/dashboards/finance.html">Finance Dashboard</a></li> | |||
| <li><a href="dist/pages/ui-elements/cards.html">UI Cards</a></li> | |||
| <li><a href="dist/pages/ecommerce/products.html">Products Page</a></li> | |||
| </ul> | |||
| </div> | |||
| </body> | |||
| </html> | |||