densha 0.1.5

Next.js-like web application framework built with Kotoba
Documentation
// Densha Tauri Application Frontend
// This script handles the desktop app interface and IPC communication

const { invoke } = window.__TAURI__.tauri;

class DenshaApp {
    constructor() {
        this.currentPage = '/';
        this.init();
    }

    async init() {
        this.bindEvents();
        await this.loadPage('/');
    }

    bindEvents() {
        // Navigation buttons
        document.getElementById('home-btn').addEventListener('click', () => this.navigate('/'));
        document.getElementById('about-btn').addEventListener('click', () => this.navigate('/about'));
        document.getElementById('api-btn').addEventListener('click', () => this.showApiInterface());

        // Handle browser back/forward buttons
        window.addEventListener('popstate', (event) => {
            if (event.state && event.state.page) {
                this.loadPage(event.state.page);
            }
        });
    }

    async navigate(page) {
        // Update active navigation button
        document.querySelectorAll('.nav-btn').forEach(btn => btn.classList.remove('active'));

        if (page === '/') {
            document.getElementById('home-btn').classList.add('active');
        } else if (page === '/about') {
            document.getElementById('about-btn').classList.add('active');
        }

        // Load the page
        await this.loadPage(page);

        // Update browser history
        history.pushState({ page }, '', page);
    }

    async loadPage(pagePath) {
        this.currentPage = pagePath;
        const mainContent = document.getElementById('main-content');

        // Show loading state
        mainContent.innerHTML = `
            <div class="loading">
                <div class="spinner"></div>
                <p>Loading page...</p>
            </div>
        `;

        try {
            // Request page content from Rust backend
            const htmlContent = await invoke('get_page_content', { pagePath });

            // Update content
            mainContent.innerHTML = `
                <div class="content-card">
                    <h2>Page: ${pagePath}</h2>
                    <div class="page-content">
                        ${htmlContent}
                    </div>
                </div>
            `;

        } catch (error) {
            console.error('Failed to load page:', error);
            mainContent.innerHTML = `
                <div class="content-card">
                    <h2>Error Loading Page</h2>
                    <div class="error">
                        <p>Failed to load page: ${pagePath}</p>
                        <p>Error: ${error}</p>
                    </div>
                </div>
            `;
        }
    }

    async showApiInterface() {
        // Update active navigation button
        document.querySelectorAll('.nav-btn').forEach(btn => btn.classList.remove('active'));
        document.getElementById('api-btn').classList.add('active');

        const mainContent = document.getElementById('main-content');

        mainContent.innerHTML = `
            <div class="content-card">
                <h2>🔌 API Testing Interface</h2>
                <p>Test your Densha API endpoints directly from the desktop app.</p>

                <div class="api-section">
                    <h3>Available Endpoints</h3>
                    <div style="display: grid; gap: 1rem; margin: 1rem 0;">
                        <div style="display: flex; gap: 0.5rem;">
                            <button class="btn btn-success" onclick="app.testApi('/hello', 'GET')">GET /api/hello</button>
                            <button class="btn btn-secondary" onclick="app.testApi('/users', 'GET')">GET /api/users</button>
                        </div>
                        <div style="display: flex; gap: 0.5rem;">
                            <button class="btn" onclick="app.testApi('/users', 'POST')">POST /api/users</button>
                            <button class="btn btn-secondary" onclick="app.testApi('/health', 'GET')">GET /api/health</button>
                        </div>
                    </div>
                </div>

                <div class="api-section">
                    <h3>API Response</h3>
                    <div id="api-result" class="api-result">
                        Click a button above to test an API endpoint.
                    </div>
                </div>
            </div>
        `;
    }

    async testApi(endpoint, method) {
        const resultDiv = document.getElementById('api-result');

        resultDiv.innerHTML = `
            <div style="color: var(--secondary-color);">
                <div class="spinner" style="width: 20px; height: 20px; display: inline-block; margin-right: 0.5rem;"></div>
                Testing ${method} ${endpoint}...
            </div>
        `;

        try {
            const response = await invoke('get_api_response', {
                endpoint: endpoint.replace('/api/', ''),
                method
            });

            resultDiv.innerHTML = `
                <div style="color: var(--success-color); margin-bottom: 0.5rem;">
                     Success - ${method} ${endpoint}
                </div>
                <pre style="background: white; padding: 1rem; border-radius: 0.25rem; overflow-x: auto;">${JSON.stringify(JSON.parse(response), null, 2)}</pre>
            `;

        } catch (error) {
            resultDiv.innerHTML = `
                <div style="color: var(--error-color); margin-bottom: 0.5rem;">
                     Error - ${method} ${endpoint}
                </div>
                <pre style="background: white; padding: 1rem; border-radius: 0.25rem; color: var(--error-color);">${error}</pre>
            `;
        }
    }

    async listFiles() {
        try {
            const files = await invoke('list_files', { directory: 'app' });
            console.log('Files in app directory:', files);
            return files;
        } catch (error) {
            console.error('Failed to list files:', error);
            return [];
        }
    }
}

// Initialize the app when DOM is loaded
let app;
document.addEventListener('DOMContentLoaded', () => {
    app = new DenshaApp();
});

// Handle Tauri-specific events
if (window.__TAURI__) {
    console.log('🚀 Densha Tauri App initialized');

    // Listen for file system changes (if implemented in Rust backend)
    // This would require additional IPC commands for file watching
}