Some checks failed
Build & Deploy KLZ Cables / 🔍 Prepare Environment (push) Successful in 8s
Build & Deploy KLZ Cables / 🏗️ Build App (push) Has been cancelled
Build & Deploy KLZ Cables / 🚀 Deploy (push) Has been cancelled
Build & Deploy KLZ Cables / ⚡ PageSpeed (push) Has been cancelled
Build & Deploy KLZ Cables / 🔔 Notifications (push) Has been cancelled
Build & Deploy KLZ Cables / 🧪 Quality Assurance (push) Has been cancelled
201 lines
6.9 KiB
TypeScript
201 lines
6.9 KiB
TypeScript
import client, { ensureAuthenticated } from '../lib/directus';
|
|
import { updateSettings, uploadFiles } from '@directus/sdk';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
// Helper for ESM __dirname
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
async function setupBranding() {
|
|
console.log('🎨 Refining Directus Branding for Premium Website Look...');
|
|
|
|
// 1. Authenticate
|
|
await ensureAuthenticated();
|
|
|
|
try {
|
|
// 2. Upload Assets (MIME FIXED)
|
|
console.log('📤 Re-uploading assets for clean IDs...');
|
|
|
|
const getMimeType = (filePath: string) => {
|
|
const ext = path.extname(filePath).toLowerCase();
|
|
switch (ext) {
|
|
case '.svg':
|
|
return 'image/svg+xml';
|
|
case '.png':
|
|
return 'image/png';
|
|
case '.jpg':
|
|
case '.jpeg':
|
|
return 'image/jpeg';
|
|
case '.ico':
|
|
return 'image/x-icon';
|
|
default:
|
|
return 'application/octet-stream';
|
|
}
|
|
};
|
|
|
|
const uploadAsset = async (filePath: string, title: string) => {
|
|
if (!fs.existsSync(filePath)) {
|
|
console.warn(`⚠️ File not found: ${filePath}`);
|
|
return null;
|
|
}
|
|
const mimeType = getMimeType(filePath);
|
|
const form = new FormData();
|
|
const fileBuffer = fs.readFileSync(filePath);
|
|
const blob = new Blob([fileBuffer], { type: mimeType });
|
|
form.append('file', blob, path.basename(filePath));
|
|
form.append('title', title);
|
|
const res = await client.request(uploadFiles(form));
|
|
return res.id;
|
|
};
|
|
|
|
const logoWhiteId = await uploadAsset(
|
|
path.resolve(__dirname, '../public/logo-white.svg'),
|
|
'Logo White',
|
|
);
|
|
const logoBlueId = await uploadAsset(
|
|
path.resolve(__dirname, '../public/logo-blue.svg'),
|
|
'Logo Blue',
|
|
);
|
|
const faviconId = await uploadAsset(
|
|
path.resolve(__dirname, '../public/favicon.ico'),
|
|
'Favicon',
|
|
);
|
|
|
|
// Smoother Background SVG
|
|
const bgSvgPath = path.resolve(__dirname, '../public/login-bg.svg');
|
|
fs.writeFileSync(
|
|
bgSvgPath,
|
|
`<svg width="1920" height="1080" viewBox="0 0 1920 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<rect width="1920" height="1080" fill="#001a4d"/>
|
|
<ellipse cx="960" cy="540" rx="800" ry="600" fill="url(#paint0_radial_premium)"/>
|
|
<defs>
|
|
<radialGradient id="paint0_radial_premium" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(960 540) rotate(90) scale(600 800)">
|
|
<stop stop-color="#003d82" stop-opacity="0.8"/>
|
|
<stop offset="1" stop-color="#001a4d" stop-opacity="0"/>
|
|
</radialGradient>
|
|
</defs>
|
|
</svg>`,
|
|
);
|
|
const backgroundId = await uploadAsset(bgSvgPath, 'Login Bg');
|
|
if (fs.existsSync(bgSvgPath)) fs.unlinkSync(bgSvgPath);
|
|
|
|
// 3. Update Settings with "Premium Web" Theme
|
|
console.log('⚙️ Updating Directus settings...');
|
|
|
|
const COLOR_PRIMARY = '#001a4d'; // Deep Blue
|
|
const COLOR_ACCENT = '#82ed20'; // Sustainability Green
|
|
const COLOR_SECONDARY = '#003d82';
|
|
|
|
const customCss = `
|
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
|
|
|
/* Global Login Styles */
|
|
body, .v-app {
|
|
font-family: 'Inter', sans-serif !important;
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
|
|
/* Glassmorphism Effect for Login Card */
|
|
.public-view .v-card {
|
|
background: rgba(255, 255, 255, 0.95) !important;
|
|
backdrop-filter: blur(20px);
|
|
border: 1px solid rgba(255, 255, 255, 0.3) !important;
|
|
border-radius: 32px !important;
|
|
box-shadow: 0 50px 100px -20px rgba(0, 0, 0, 0.4) !important;
|
|
padding: 40px !important;
|
|
}
|
|
|
|
.public-view .v-button {
|
|
border-radius: 9999px !important;
|
|
height: 56px !important;
|
|
font-weight: 600 !important;
|
|
letter-spacing: -0.01em !important;
|
|
transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1) !important;
|
|
}
|
|
|
|
.public-view .v-button:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 15px 30px rgba(130, 237, 32, 0.2) !important;
|
|
}
|
|
|
|
.public-view .v-input {
|
|
--v-input-border-radius: 12px !important;
|
|
--v-input-background-color: #f8f9fa !important;
|
|
}
|
|
`;
|
|
|
|
const publicNote = `
|
|
<div style="font-family: 'Inter', sans-serif; text-align: center; margin-top: 24px;">
|
|
<p style="color: rgba(255,255,255,0.7); font-size: 14px; margin-bottom: 4px; font-weight: 500;">KLZ INFRASTRUCTURE ENGINE</p>
|
|
<h1 style="color: #ffffff; font-size: 18px; font-weight: 700; margin: 0;">Sustainable Energy. <span style="color: #82ed20;">Industrial Reliability.</span></h1>
|
|
</div>
|
|
`;
|
|
|
|
await client.request(
|
|
updateSettings({
|
|
project_name: 'KLZ Cables',
|
|
project_url: 'https://klz-cables.com',
|
|
project_color: COLOR_ACCENT,
|
|
project_descriptor: 'Sustainable Energy Infrastructure',
|
|
|
|
// FIXED: Use WHITE logo for the Blue Sidebar
|
|
project_logo: logoWhiteId as any,
|
|
|
|
public_foreground: logoWhiteId as any,
|
|
public_background: backgroundId as any,
|
|
public_note: publicNote,
|
|
public_favicon: faviconId as any,
|
|
custom_css: customCss,
|
|
|
|
// DEEP PREMIUM THEME
|
|
theme_light_overrides: {
|
|
// Brands
|
|
primary: COLOR_ACCENT, // Buttons/Actions are GREEN like the website
|
|
secondary: COLOR_SECONDARY,
|
|
|
|
// Content Area
|
|
background: '#f1f3f7',
|
|
backgroundNormal: '#ffffff',
|
|
backgroundAccent: '#eef2ff',
|
|
|
|
// Sidebar Branding
|
|
navigationBackground: COLOR_PRIMARY,
|
|
navigationForeground: '#ffffff',
|
|
navigationBackgroundHover: 'rgba(255,255,255,0.05)',
|
|
navigationForegroundHover: '#ffffff',
|
|
navigationBackgroundActive: 'rgba(130, 237, 32, 0.15)', // Subtle Green highlight
|
|
navigationForegroundActive: COLOR_ACCENT, // Active item is GREEN
|
|
|
|
// Module Bar (Thin far left)
|
|
moduleBarBackground: '#000d26',
|
|
moduleBarForeground: '#ffffff',
|
|
moduleBarForegroundActive: COLOR_ACCENT,
|
|
|
|
// UI Standards
|
|
borderRadius: '16px', // Larger radius for modern feel
|
|
borderWidth: '1px',
|
|
borderColor: '#e2e8f0',
|
|
formFieldHeight: '48px', // Touch-target height
|
|
} as any,
|
|
|
|
theme_dark_overrides: {
|
|
primary: COLOR_ACCENT,
|
|
background: '#0a0a0a',
|
|
navigationBackground: '#000000',
|
|
moduleBarBackground: COLOR_PRIMARY,
|
|
borderRadius: '16px',
|
|
formFieldHeight: '48px',
|
|
} as any,
|
|
}),
|
|
);
|
|
|
|
console.log('✨ Premium Theme applied successfully!');
|
|
} catch (error: any) {
|
|
console.error('❌ Error:', JSON.stringify(error, null, 2));
|
|
}
|
|
}
|
|
|
|
setupBranding();
|