🎮ArcadeLab

Enterprise Movie Studio Hub

by LuckyFlare17
761 lines26.0 KB
▶ Play
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Enterprise Movie Studio Hub</title>
    <style>
        :root {
            --bg-color: #0f0f12;
            --card-bg: #16161a;
            --card-hover: #1f1f26;
            --primary: #e50914;
            --primary-hover: #b80710;
            --text: #ffffff;
            --text-muted: #8e8e93;
            --border: #2c2c35;
            --success: #2ecc71;
            --danger: #e74c3c;
            --warning: #f1c40f;
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
        }

        body {
            background-color: var(--bg-color);
            color: var(--text);
            padding: 20px;
            display: flex;
            justify-content: center;
        }

        .container {
            width: 100%;
            max-width: 1300px;
            display: grid;
            grid-template-columns: 1fr;
            gap: 20px;
        }

        @media (min-width: 992px) {
            .container {
                grid-template-columns: 380px 1fr;
            }
        }

        header {
            grid-column: 1 / -1;
            text-align: center;
            padding: 15px 0;
            border-bottom: 3px solid var(--primary);
            background: var(--card-bg);
            border-radius: 8px;
        }

        header h1 {
            font-size: 2.2rem;
            letter-spacing: 1px;
        }

        header span {
            color: var(--primary);
        }

        .stats-grid {
            grid-column: 1 / -1;
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
        }

        .stat-card {
            background: var(--card-bg);
            padding: 15px;
            border-radius: 8px;
            border: 1px solid var(--border);
            text-align: center;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }

        .stat-card .num {
            font-size: 1.6rem;
            font-weight: bold;
            margin-top: 5px;
        }

        .stat-card .label {
            font-size: 0.75rem;
            color: var(--text-muted);
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .color-primary { color: var(--primary); }
        .color-success { color: var(--success); }
        .color-danger { color: var(--danger); }

        .filter-bar {
            grid-column: 1 / -1;
            background: var(--card-bg);
            padding: 15px;
            border-radius: 8px;
            border: 1px solid var(--border);
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
            gap: 15px;
        }

        .form-box {
            background-color: var(--card-bg);
            padding: 20px;
            border-radius: 8px;
            border: 1px solid var(--border);
            height: fit-content;
            box-shadow: 0 4px 10px rgba(0,0,0,0.2);
        }

        .form-box h2 {
            font-size: 1.3rem;
            margin-bottom: 15px;
            color: var(--primary);
            border-bottom: 1px solid var(--border);
            padding-bottom: 8px;
        }

        .form-grid-2 {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
        }

        .form-group {
            margin-bottom: 12px;
        }

        label {
            display: block;
            font-size: 0.8rem;
            margin-bottom: 4px;
            color: var(--text-muted);
            font-weight: 600;
        }

        input, select, textarea {
            width: 100%;
            padding: 10px;
            background: #202026;
            border: 1px solid var(--border);
            color: white;
            border-radius: 6px;
            font-size: 0.9rem;
            transition: border 0.2s;
        }

        input:focus, select:focus, textarea:focus {
            outline: none;
            border-color: var(--primary);
        }

        button.btn-submit {
            width: 100%;
            padding: 12px;
            background: var(--primary);
            color: white;
            border: none;
            border-radius: 6px;
            font-weight: bold;
            cursor: pointer;
            font-size: 1rem;
            margin-top: 10px;
            transition: background 0.2s, transform 0.1s;
        }

        button.btn-submit:hover {
            background: var(--primary-hover);
        }

        button.btn-submit:active {
            transform: scale(0.98);
        }

        .main-content {
            display: flex;
            flex-direction: column;
            gap: 15px;
        }

        .movie-list {
            display: grid;
            grid-template-columns: 1fr;
            gap: 15px;
            align-content: start;
        }

        @media (min-width: 1200px) {
            .movie-list {
                grid-template-columns: 1fr 1fr;
            }
        }

        .movie-card {
            background: var(--card-bg);
            border: 1px solid var(--border);
            border-radius: 8px;
            padding: 18px;
            position: relative;
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            transition: transform 0.2s, background-color 0.2s;
        }

        .movie-card:hover {
            background-color: var(--card-hover);
            transform: translateY(-2px);
        }

        .delete-btn {
            position: absolute;
            top: 12px;
            right: 15px;
            background: none;
            border: none;
            color: var(--text-muted);
            font-size: 1.4rem;
            cursor: pointer;
            width: auto;
            margin: 0;
            padding: 0;
        }

        .delete-btn:hover {
            color: var(--primary);
        }

        .movie-card h3 {
            font-size: 1.4rem;
            margin-bottom: 5px;
            padding-right: 25px;
            color: #fff;
        }

        .movie-meta-tags {
            display: flex;
            flex-wrap: wrap;
            gap: 5px;
            margin-bottom: 12px;
        }

        .tag {
            font-size: 0.75rem;
            background: #252530;
            padding: 3px 8px;
            border-radius: 4px;
            color: #e0e0e6;
            border: 1px solid #3a3a4a;
        }

        .tag-fsk {
            background: #34495e;
            font-weight: bold;
        }

        .movie-card p.story-text {
            font-size: 0.9rem;
            line-height: 1.45;
            margin-bottom: 12px;
            color: #d1d1d6;
            font-style: italic;
        }

        .movie-details-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 8px;
            font-size: 0.85rem;
            border-top: 1px solid var(--border);
            padding-top: 10px;
            margin-bottom: 12px;
            color: #b0b0b5;
        }

        /* Szenen-Bereich im Projekt */
        .scenes-section {
            border-top: 1px solid var(--border);
            padding-top: 12px;
            margin-bottom: 12px;
        }

        .scenes-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 8px;
        }

        .scenes-header h4 {
            font-size: 0.95rem;
            color: var(--primary);
        }

        .btn-small {
            background: #252530;
            border: 1px solid var(--border);
            color: white;
            padding: 4px 8px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 0.75rem;
        }

        .btn-small:hover {
            border-color: var(--primary);
        }

        .scenes-list {
            display: flex;
            flex-direction: column;
            gap: 6px;
            max-height: 150px;
            overflow-y: auto;
            margin-bottom: 8px;
        }

        .scene-item {
            background: #1f1f26;
            padding: 6px 10px;
            border-radius: 4px;
            font-size: 0.8rem;
            display: flex;
            justify-content: space-between;
            align-items: center;
            border-left: 3px solid var(--warning);
        }

        .scene-item.done {
            border-left-color: var(--success);
        }

        .scene-info {
            display: flex;
            gap: 10px;
            align-items: center;
        }

        .footer-row {
            display: flex;
            justify-content: space-between;
            align-items: center;
            border-top: 1px solid var(--border);
            padding-top: 10px;
            margin-top: auto;
        }

        .status-badge {
            font-size: 0.75rem;
            padding: 4px 10px;
            border-radius: 20px;
            font-weight: bold;
            text-transform: uppercase;
        }
        .status-plan { background: #d35400; color: white; }
        .status-prod { background: #2980b9; color: white; }
        .status-done { background: #27ae60; color: white; }

        .profit-badge {
            font-size: 0.85rem;
            font-weight: bold;
        }

        /* Modal für Szene hinzufügen */
        .modal {
            display: none;
            position: fixed;
            top: 0; left: 0; width: 100%; height: 100%;
            background: rgba(0,0,0,0.7);
            justify-content: center;
            align-items: center;
            z-index: 1000;
        }
        .modal-content {
            background: var(--card-bg);
            padding: 20px;
            border-radius: 8px;
            width: 100%;
            max-width: 400px;
            border: 1px solid var(--border);
        }
    </style>
</head>
<body>

<div class="container">
    <header>
        <h1>Enterprise <span>Movie Studio Hub</span></h1>
    </header>

    <!-- Dashboard Statistik -->
    <div class="stats-grid">
        <div class="stat-card">
            <div class="label">Gesamtprojekte</div>
            <div class="num" id="stat-count">0</div>
        </div>
        <div class="stat-card">
            <div class="label">Gesamtbudget</div>
            <div class="num" id="stat-budget">0 Mio. €</div>
        </div>
        <div class="stat-card">
            <div class="label">Erwartetes Box-Office</div>
            <div class="num" id="stat-revenue">0 Mio. €</div>
        </div>
        <div class="stat-card">
            <div class="label">Netto-Bilanz (ROI)</div>
            <div class="num" id="stat-profit">0 Mio. €</div>
        </div>
    </div>

    <!-- Filter & Suche -->
    <div class="filter-bar">
        <div class="form-group" style="margin: 0;">
            <label for="search-input">Projektsuche</label>
            <input type="text" id="search-input" placeholder="Titel oder Regisseur..." oninput="filterMovies()">
        </div>
        <div class="form-group" style="margin: 0;">
            <label for="filter-genre">Genre Filter</label>
            <select id="filter-genre" onchange="filterMovies()">
                <option value="all">Alle Genres</option>
                <option value="Sci-Fi">Sci-Fi</option>
                <option value="Action">Action</option>
                <option value="Drama">Drama</option>
                <option value="Komödie">Komödie</option>
                <option value="Horror">Horror</option>
                <option value="Thriller">Thriller</option>
                <option value="Animation">Animation</option>
            </select>
        </div>
        <div class="form-group" style="margin: 0;">
            <label for="filter-status">Status Filter</label>
            <select id="filter-status" onchange="filterMovies()">
                <option value="all">Alle Phasen</option>
                <option value="plan">In Planung</option>
                <option value="prod">In Produktion</option>
                <option value="done">Fertiggestellt</option>
            </select>
        </div>
    </div>

    <!-- Formular zum Erfassen -->
    <div class="form-box">
        <h2>Neues Projekt erfassen</h2>
        <form id="movie-form">
            <div class="form-group">
                <label for="title">Filmtitel / Projekttitel</label>
                <input type="text" id="title" required>
            </div>
            <div class="form-grid-2">
                <div class="form-group">
                    <label for="genre">Genre</label>
                    <select id="genre">
                        <option value="Sci-Fi">Sci-Fi</option>
                        <option value="Action">Action</option>
                        <option value="Drama">Drama</option>
                        <option value="Komödie">Komödie</option>
                        <option value="Horror">Horror</option>
                        <option value="Thriller">Thriller</option>
                        <option value="Animation">Animation</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="format">Format</label>
                    <select id="format">
                        <option value="Kinofilm">Kinofilm</option>
                        <option value="Streaming-Serie">Streaming-Serie</option>
                        <option value="Dokumentation">Dokumentation</option>
                    </select>
                </div>
            </div>
            <div class="form-grid-2">
                <div class="form-group">
                    <label for="director">Regisseur / Showrunner</label>
                    <input type="text" id="director" required>
                </div>
                <div class="form-group">
                    <label for="fsk">FSK Freigabe</label>
                    <select id="fsk">
                        <option value="FSK 0">FSK 0</option>
                        <option value="FSK 6">FSK 6</option>
                        <option value="FSK 12">FSK 12</option>
                        <option value="FSK 16">FSK 16</option>
                        <option value="FSK 18">FSK 18</option>
                    </select>
                </div>
            </div>
            <div class="form-group">
                <label for="cast">Hauptbesetzung (Kommagetrennt)</label>
                <input type="text" id="cast">
            </div>
            <div class="form-grid-2">
                <div class="form-group">
                    <label for="budget">Budget (Mio. €)</label>
                    <input type="number" step="0.1" id="budget" required>
                </div>
                <div class="form-group">
                    <label for="revenue">Erw. Umsatz (Mio. €)</label>
                    <input type="number" step="0.1" id="revenue" required>
                </div>
            </div>
            <div class="form-grid-2">
                <div class="form-group">
                    <label for="release">Geplanter Start</label>
                    <input type="date" id="release" required>
                </div>
                <div class="form-group">
                    <label for="status">Projektstatus</label>
                    <select id="status">
                        <option value="plan">In Planung</option>
                        <option value="prod">In Produktion</option>
                        <option value="done">Fertiggestellt</option>
                    </select>
                </div>
            </div>
            <div class="form-group">
                <label for="story">Logline / Core Story</label>
                <textarea id="story" rows="3"></textarea>
            </div>
            <button type="submit" class="btn-submit">Projekt einbuchen</button>
        </form>
    </div>

    <!-- Hauptbereich / Projektliste -->
    <div class="main-content">
        <div id="movie-display" class="movie-list"></div>
    </div>
</div>

<!-- Modal zum Hinzufügen einer Szene -->
<div id="scene-modal" class="modal">
    <div class="modal-content">
        <h2 style="color: var(--primary); margin-bottom: 12px; font-size: 1.1rem;">Szene aufnehmen</h2>
        <form id="scene-form">
            <input type="hidden" id="modal-movie-index">
            <div class="form-group">
                <label for="scene-num">Szenennummer / Titel</label>
                <input type="text" id="scene-num" placeholder="z.B. Szene 1: Intro" required>
            </div>
            <div class="form-group">
                <label for="scene-loc">Drehort</label>
                <input type="text" id="scene-loc" placeholder="z.B. Studio A / Berlin" required>
            </div>
            <div class="form-group">
                <label for="scene-desc">Beschreibung</label>
                <textarea id="scene-desc" rows="2" placeholder="Was passiert in der Szene?"></textarea>
            </div>
            <div class="form-group">
                <label for="scene-status">Status</label>
                <select id="scene-status">
                    <option value="Geplant">Geplant</option>
                    <option value="Gedreht">Gedreht</option>
                </select>
            </div>
            <div style="display: flex; gap: 10px; margin-top: 15px;">
                <button type="button" class="btn-small" style="flex:1; padding: 8px;" onclick="closeSceneModal()">Abbrechen</button>
                <button type="submit" class="btn-submit" style="flex:1; margin-top:0;">Speichern</button>
            </div>
        </form>
    </div>
</div>

<script>
    let movies = JSON.parse(localStorage.getItem('enterprise_studio_movies')) || [];
    const movieForm = document.getElementById('movie-form');
    const movieDisplay = document.getElementById('movie-display');
    const sceneModal = document.getElementById('scene-modal');
    const sceneForm = document.getElementById('scene-form');

    function updateApp() {
        localStorage.setItem('enterprise_studio_movies', JSON.stringify(movies));
        filterMovies();
        calculateDashboard();
    }

    function calculateDashboard() {
        const count = movies.length;
        const totalBudget = movies.reduce((sum, m) => sum + parseFloat(m.budget || 0), 0);
        const totalRevenue = movies.reduce((sum, m) => sum + parseFloat(m.revenue || 0), 0);
        const netProfit = totalRevenue - totalBudget;

        document.getElementById('stat-count').textContent = count;
        document.getElementById('stat-budget').textContent = totalBudget.toFixed(1) + ' Mio. €';
        document.getElementById('stat-revenue').textContent = totalRevenue.toFixed(1) + ' Mio. €';

        const profitElement = document.getElementById('stat-profit');
        profitElement.textContent = (netProfit >= 0 ? '+' : '') + netProfit.toFixed(1) + ' Mio. €';
        profitElement.className = 'num ' + (netProfit >= 0 ? 'color-success' : 'color-danger');
    }

    function filterMovies() {
        const searchQuery = document.getElementById('search-input').value.toLowerCase();
        const genreFilter = document.getElementById('filter-genre').value;
        const statusFilter = document.getElementById('filter-status').value;

        movieDisplay.innerHTML = '';

        const filtered = movies.filter(movie => {
            const matchesSearch = movie.title.toLowerCase().includes(searchQuery) ||
                                  movie.director.toLowerCase().includes(searchQuery);
            const matchesGenre = genreFilter === 'all' || movie.genre === genreFilter;
            const matchesStatus = statusFilter === 'all' || movie.status === statusFilter;
            return matchesSearch && matchesGenre && matchesStatus;
        });

        if (filtered.length === 0) {
            movieDisplay.innerHTML = '<p style="color: var(--text-muted); grid-column: 1/-1; text-align: center; padding: 20px;">Keine Filmprojekte gefunden, die den Filtern entsprechen.</p>';
            return;
        }

        filtered.forEach((movie) => {
            const realIndex = movies.indexOf(movie);
            const card = document.createElement('div');
            card.className = 'movie-card';

            let statusText = 'In Planung';
            let statusClass = 'status-plan';
            if(movie.status === 'prod') { statusText = 'In Produktion'; statusClass = 'status-prod'; }
            if(movie.status === 'done') { statusText = 'Fertiggestellt'; statusClass = 'status-done'; }

            const singleProfit = parseFloat(movie.revenue) - parseFloat(movie.budget);
            const profitClass = singleProfit >= 0 ? 'color-success' : 'color-danger';
            
            const dateFormatted = movie.release ? new Date(movie.release).toLocaleDateString('de-DE', {
                year: 'numeric', month: '2-digit', day: '2-digit'
            }) : 'Unbekannt';

            // Szenen HTML generieren
            let scenesHtml = '';
            if (movie.scenes && movie.scenes.length > 0) {
                movie.scenes.forEach((scene, sIdx) => {
                    const isDone = scene.status === 'Gedreht';
                    scenesHtml += `
                        <div class="scene-item ${isDone ? 'done' : ''}">
                            <div class="scene-info">
                                <strong>${scene.number}</strong> 
                                <span style="color: var(--text-muted);">(${scene.location})</span>
                            </div>
                            <div style="display: flex; gap: 8px; align-items: center;">
                                <span style="font-size: 0.75rem; color: ${isDone ? 'var(--success)' : 'var(--warning)'};">${scene.status}</span>
                                <button class="btn-small" onclick="deleteScene(${realIndex}, ${sIdx})" title="Szene löschen">&times;</button>
                            </div>
                        </div>
                    `;
                });
            } else {
                scenesHtml = '<p style="font-size: 0.8rem; color: var(--text-muted); text-align: center; padding: 5px;">Keine Szenen erfasst.</p>';
            }

            card.innerHTML = `
                <button class="delete-btn" onclick="deleteMovie(${realIndex})" title="Projekt löschen">&times;</button>
                <div>
                    <h3>${movie.title}</h3>
                    <div class="movie-meta-tags">
                        <span class="tag">${movie.format}</span>
                        <span class="tag">${movie.genre}</span>
                        <span class="tag tag-fsk">${movie.fsk}</span>
                    </div>
                    <p class="story-text">"${movie.story || 'Keine Logline vorhanden.'}"</p>
                    <div class="movie-details-grid">
                        <div><strong>Regie:</strong> ${movie.director}</div>
                        <div><strong>Start:</strong> ${dateFormatted}</div>
                        <div style="grid-column: 1 / -1;"><strong>Cast:</strong> ${movie.cast || 'Keine Angaben'}</div>
                    </div>
                    
                    <div class="scenes-section">
                        <div class="scenes-header">
                            <h4>Szenen (${movie.scenes ? movie.scenes.length : 0})</h4>
                            <button class="btn-small" onclick="openSceneModal(${realIndex})">+ Szene hinzufügen</button>
                        </div>
                        <div class="scenes-list">
                            ${scenesHtml}
                        </div>
                    </div>
                </div>
                <div class="footer-row">
                    <span class="status-badge ${statusClass}">${statusText}</span>
                    <span class="profit-badge ${profitClass}">Bilanz: ${singleProfit >= 0 ? '+' : ''}${singleProfit.toFixed(1)} Mio. €</span>
                </div>
            `;
            movieDisplay.appendChild(card);
        });
    }

    movieForm.addEventListener('submit', function(e) {
        e.preventDefault();
        const newMovie = {
            title: document.getElementById('title').value,
            genre: document.getElementById('genre').value,
            format: document.getElementById('format').value,
            director: document.getElementById('director').value,
            fsk: document.getElementById('fsk').value,
            cast: document.getElementById('cast').value,
            budget: document.getElementById('budget').value,
            revenue: document.getElementById('revenue').value,
            release: document.getElementById('release').value,
            status: document.getElementById('status').value,
            story: document.getElementById('story').value,
            scenes: [] // Initial leeres Array für Szenen
        };
        movies.push(newMovie);
        updateApp();
        movieForm.reset();
    });

    function deleteMovie(index) {
        if(confirm('Möchtest du dieses Filmprojekt wirklich unwiderruflich löschen?')) {
            movies.splice(index, 1);
            updateApp();
        }
    }

    // Szenen Management Funktionen
    function openSceneModal(movieIndex) {
        document.getElementById('modal-movie-index').value = movieIndex;
        sceneModal.style.display = 'flex';
    }

    function closeSceneModal() {
        sceneModal.style.display = 'none';
        sceneForm.reset();
    }

    sceneForm.addEventListener('submit', function(e) {
        e.preventDefault();
        const mIndex = document.getElementById('modal-movie-index').value;
        const newScene = {
            number: document.getElementById('scene-num').value,
            location: document.getElementById('scene-loc').value,
            description: document.getElementById('scene-desc').value,
            status: document.getElementById('scene-status').value
        };

        if (!movies[mIndex].scenes) {
            movies[mIndex].scenes = [];
        }
        movies[mIndex].scenes.push(newScene);
        updateApp();
        closeSceneModal();
    });

    function deleteScene(movieIndex, sceneIndex) {
        movies[movieIndex].scenes.splice(sceneIndex, 1);
        updateApp();
    }

    updateApp();
</script>

</body>
</html>

Game Source: Enterprise Movie Studio Hub

Creator: LuckyFlare17

Libraries: none

Complexity: complex (761 lines, 26.0 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: enterprise-movie-studio-hub-luckyflare17" to link back to the original. Then publish at arcadelab.ai/publish.