JSFiddle - React, Tailwind, and code Playground

by velo_ninja

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Report Management System</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div id="app">
        <h1>Report Management System</h1>
        <div id="menu">
            <button id="add-module-btn">Add New Report Module</button>
            <div id="report-types"></div>
        </div>
        <div id="report-form"></div>
        <div id="report-output"></div>
        <div id="saved-reports"></div>
    </div>
    <script type="module" src="app.js"></script>
</body>
</html>

CSS

body {
    font-family: Arial, sans-serif;
    margin: 20px;
    background-color: #f4f4f4;
}

#app {
    max-width: 800px;
    margin: 0 auto;
    background: white;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
}

h1, h2 {
    text-align: center;
}

button {
    padding: 10px 15px;
    background-color: #007bff;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    margin: 5px;
}

button:hover {
    background-color: #0056b3;
}

form {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

input, select {
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
}

#report-output {
    margin-top: 20px;
    padding: 15px;
    background: #e9ecef;
    border-radius: 4px;
}

#saved-reports {
    margin-top: 20px;
}

.report-item {
    padding: 10px;
    border-bottom: 1px solid #ddd;
}

.report-item button {
    float: right;
}

JavaScript

// app.js - Main application logic

// Registry for report modules
const reportModules = new Map();

// Function to register a new report module
function registerReportModule(name, module) {
    reportModules.set(name, module);
    updateReportTypesMenu();
}

// Function to update the menu with available report types
function updateReportTypesMenu() {
    const reportTypesDiv = document.getElementById('report-types');
    reportTypesDiv.innerHTML = '';
    reportModules.forEach((module, name) => {
        const btn = document.createElement('button');
        btn.textContent = `Generate ${name} Report`;
        btn.onclick = () => loadReportForm(name);
        reportTypesDiv.appendChild(btn);
    });
}

// Function to load the form for a specific report type
function loadReportForm(name) {
    const module = reportModules.get(name);
    if (!module) return;

    const formDiv = document.getElementById('report-form');
    formDiv.innerHTML = '';

    const form = document.createElement('form');
    module.getFormFields().forEach(field => {
        const label = document.createElement('label');
        label.textContent = field.label;

        let input;
        if (field.type === 'select') {
            input = document.createElement('select');
            field.options.forEach(opt => {
                const option = document.createElement('option');
                option.value = opt.value;
                option.textContent = opt.label;
                input.appendChild(option);
            });
        } else {
            input = document.createElement('input');
            input.type = field.type;
        }
        input.name = field.name;
        form.appendChild(label);
        form.appendChild(input);
    });

    const submitBtn = document.createElement('button');
    submitBtn.type = 'submit';
    submitBtn.textContent = 'Generate Report';
    form.appendChild(submitBtn);

    form.onsubmit = (e)...