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, ` `, ); 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; } /* Inject Headline via CSS to avoid raw HTML display in public_note */ .public-view .form::before { content: 'Sustainable Energy. Industrial Reliability.'; display: block; text-align: center; font-size: 18px; font-weight: 700; color: #ffffff; margin-bottom: 8px; } .public-view .form::after { content: 'KLZ INFRASTRUCTURE ENGINE'; display: block; text-align: center; font-size: 11px; font-weight: 600; letter-spacing: 0.1em; color: rgba(255, 255, 255, 0.5); margin-top: 24px; } `; const publicNote = ''; 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();