mcpengine/servers/xero/final-batch.py

158 lines
3.9 KiB
Python

#!/usr/bin/env python3
import os
BASE_DIR = "/Users/jakeshore/.clawdbot/workspace/mcpengine-repo/servers/xero/src/apps"
MAIN_TSX = '''import React, { Suspense, Component, ErrorInfo, ReactNode } from 'react';
import { createRoot } from 'react-dom/client';
const App = React.lazy(() => import('./App'));
interface ErrorBoundaryProps {
children: ReactNode;
}
interface ErrorBoundaryState {
hasError: boolean;
error?: Error;
}
class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
constructor(props: ErrorBoundaryProps) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error('Error caught by boundary:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
<div style={{ padding: '2rem', textAlign: 'center' }}>
<h1>Something went wrong</h1>
<p>{this.state.error?.message}</p>
</div>
);
}
return this.props.children;
}
}
const LoadingSkeleton = () => (
<div className="loading-skeleton">
<div className="shimmer" style={{ height: '60px', marginBottom: '1rem' }}></div>
<div className="shimmer" style={{ height: '120px', marginBottom: '1rem' }}></div>
<div className="shimmer" style={{ height: '400px' }}></div>
</div>
);
const container = document.getElementById('root');
if (container) {
const root = createRoot(container);
root.render(
<ErrorBoundary>
<Suspense fallback={<LoadingSkeleton />}>
<App />
</Suspense>
</ErrorBoundary>
);
}
'''
# Remaining 9 apps
apps = [
{
"name": "profit-loss",
"title": "Profit & Loss",
"subtitle": "P&L report viewer",
"icon": "📈",
},
{
"name": "balance-sheet",
"title": "Balance Sheet",
"subtitle": "Balance sheet viewer",
"icon": "⚖️",
},
{
"name": "trial-balance",
"title": "Trial Balance",
"subtitle": "Trial balance viewer",
"icon": "🧮",
},
{
"name": "aged-receivables",
"title": "Aged Receivables",
"subtitle": "AR aging report",
"icon": "📊",
},
{
"name": "aged-payables",
"title": "Aged Payables",
"subtitle": "AP aging report",
"icon": "📉",
},
{
"name": "employee-directory",
"title": "Employee Directory",
"subtitle": "Employee records",
"icon": "👥",
},
{
"name": "payroll-dashboard",
"title": "Payroll Dashboard",
"subtitle": "Pay runs, slips, and leave",
"icon": "💰",
},
{
"name": "tax-center",
"title": "Tax Center",
"subtitle": "Tax rates and returns",
"icon": "🏛️",
},
{
"name": "org-overview",
"title": "Organisation Overview",
"subtitle": "Organisation info, settings, and metrics",
"icon": "🏢",
},
]
for app in apps:
app_dir = os.path.join(BASE_DIR, app["name"])
# Create index.html
html_content = f'''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{app["title"]} - Xero MCP</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
'''
with open(os.path.join(app_dir, "index.html"), "w") as f:
f.write(html_content)
# Create main.tsx
with open(os.path.join(app_dir, "main.tsx"), "w") as f:
f.write(MAIN_TSX)
# Copy styles.css from template
os.system(f"cp {BASE_DIR}/invoice-dashboard/styles.css {app_dir}/styles.css")
print(f"✅ Created {app['name']}")
print("\n✨ All files created!")