๐Ÿ† Ultimate Capstone โ€ข Project 20 / 20

Full Capstone Application: Modern Frontend Dev Studio & Playground

1. Project Overview & Architectural Goal

Mubarak ho! Aapne web development ke sabhi core fundamentals master kar liye hain. Is Ultimate Capstone Project me hum ek production-grade, browser-based Frontend Developer Studio & Live Sandbox banayenge (jaise CodePen ya JSFiddle ka mini version).

Ye project hamare seekhe hue saare 6 modules ke concepts ko combine karta hai:

  • HTML5: Semantic layout, iframes, accessible form controls, modals.
  • CSS3 Advanced: CSS Grid split-pane view, Flexbox toolbars, responsive mobile breakpoint toggles, custom themes.
  • JavaScript ES6+: Virtual console interception (console.log ko UI me capture karna), asynchronous sandbox rendering via Blob URLs, localStorage database for saving user snippets, and file export (Blob + URL.createObjectURL) to download code as standalone .html files!

2. Live Interactive Preview

๐Ÿ’ป โšก ๐Ÿš€

Frontend Dev Studio Live Sandbox

Hamari website par already ek full-fledged live sandbox chal raha hai jo is capstone architecture par based hai!

Launch Studio Playground โšก

3. Capstone Architecture & Requirements

Feature Area Technical Implementation Learner Benefit
Split-Pane Editor HTML, CSS, JS textareas with instant Live Reload DOM input events & iframe manipulation
Virtual Console Overriding console.log inside iframe and messaging parent window via postMessage Advanced JS execution & security sandboxing
Snippet Persistence localStorage.setItem("snippets", JSON.stringify(data)) Client-side database design
File Exporter new Blob([fullCode], { type: "text/html" }) and simulated download anchor Web APIs & File handling
Responsive Previewer Resize iframe container width to 375px (Mobile), 768px (Tablet), 100% (Desktop) CSS Layout & Responsive testing

4. Folder Structure

frontend-dev-studio/
โ”œโ”€โ”€ index.html        (Main Studio Layout)
โ”œโ”€โ”€ css/
โ”‚   โ””โ”€โ”€ studio.css    (Grid split-screen & dark IDE styles)
โ”œโ”€โ”€ js/
โ”‚   โ”œโ”€โ”€ editor.js     (Input listeners, live runner & iframe injector)
โ”‚   โ”œโ”€โ”€ console.js    (Virtual console logger)
โ”‚   โ””โ”€โ”€ storage.js    (Snippet save/load/export engine)
โ””โ”€โ”€ README.md

5. Complete Production-Grade Source Code

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DevStudio - Modern Frontend Code Playground</title>
  <link rel="stylesheet" href="css/studio.css">
</head>
<body>
  <header class="studio-header">
    <div class="brand">
      <span class="logo-icon">โšก</span>
      <strong>DevStudio</strong>
    </div>

    <div class="actions">
      <button id="run-btn" class="btn btn-run">โ–ถ Run Code</button>
      <button id="save-btn" class="btn btn-save">๐Ÿ’พ Save Snippet</button>
      <button id="export-btn" class="btn btn-export">๐Ÿ“ฅ Export HTML</button>
      <button id="clear-console-btn" class="btn btn-clear">๐Ÿงน Clear Console</button>
    </div>
  </header>

  <main class="studio-workspace">
    <!-- Left: Code Editors -->
    <section class="editors-pane">
      <div class="editor-box">
        <div class="editor-title">HTML5</div>
        <textarea id="html-code" spellcheck="false" placeholder="<!-- Write HTML here -->">&lt;div class="card"&gt;
  &lt;h2&gt;Hello World ๐Ÿš€&lt;/h2&gt;
  &lt;p&gt;Welcome to my custom DevStudio capstone!&lt;/p&gt;
  &lt;button id="click-me"&gt;Click Me!&lt;/button&gt;
&lt;/div&gt;</textarea>
      </div>

      <div class="editor-box">
        <div class="editor-title">CSS3</div>
        <textarea id="css-code" spellcheck="false" placeholder="/* Write CSS here */">body {
  font-family: system-ui, sans-serif;
  display: grid;
  place-items: center;
  min-height: 90vh;
  background: #0f172a;
  color: #fff;
}
.card {
  background: #1e293b;
  padding: 2rem;
  border-radius: 12px;
  border: 1px solid #334155;
  text-align: center;
}
button {
  background: #38bdf8;
  color: #0f172a;
  font-weight: bold;
  border: none;
  padding: 0.6rem 1.2rem;
  border-radius: 6px;
  cursor: pointer;
  margin-top: 1rem;
}</textarea>
      </div>

      <div class="editor-box">
        <div class="editor-title">JavaScript</div>
        <textarea id="js-code" spellcheck="false" placeholder="// Write JS here">console.log("DevStudio initialized successfully!");

document.getElementById("click-me").addEventListener("click", () => {
  console.log("Button clicked at: " + new Date().toLocaleTimeString());
  alert("Interactive JS working!");
});</textarea>
      </div>
    </section>

    <!-- Right: Live Preview & Virtual Console -->
    <section class="preview-pane">
      <div class="preview-header">Live Result</div>
      <iframe id="live-frame" sandbox="allow-scripts allow-modals"></iframe>
      
      <div class="console-box">
        <div class="console-header">Console Logs</div>
        <div id="console-logs" class="console-logs"></div>
      </div>
    </section>
  </main>

  <script src="js/editor.js"></script>
</body>
</html>

css/studio.css

* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #0b0f19; color: #f8fafc; height: 100vh; display: flex; flex-direction: column; overflow: hidden; }

.studio-header { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem 1.5rem; background: #131b2e; border-bottom: 1px solid #1e293b; }
.brand { display: flex; align-items: center; gap: 0.5rem; font-size: 1.2rem; color: #38bdf8; }

.actions { display: flex; gap: 0.5rem; }
.btn { padding: 0.45rem 0.9rem; font-size: 0.85rem; font-weight: 600; border-radius: 6px; cursor: pointer; border: 1px solid transparent; }
.btn-run { background: #10b981; color: #fff; }
.btn-save { background: #6366f1; color: #fff; }
.btn-export { background: #1e293b; color: #cbd5e1; border-color: #334155; }
.btn-clear { background: #1e293b; color: #94a3b8; border-color: #334155; }

.studio-workspace { flex: 1; display: grid; grid-template-columns: 1fr 1fr; height: calc(100vh - 55px); }

/* Left Editors Pane */
.editors-pane { display: grid; grid-template-rows: 1fr 1fr 1fr; border-right: 2px solid #1e293b; background: #0f172a; }
.editor-box { display: flex; flex-direction: column; border-bottom: 1px solid #1e293b; }
.editor-title { background: #131b2e; font-size: 0.75rem; font-weight: 700; color: #94a3b8; padding: 0.3rem 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; }
textarea { flex: 1; width: 100%; background: #090d16; color: #f1f5f9; border: none; padding: 0.75rem; font-family: 'Fira Code', monospace; font-size: 0.9rem; resize: none; outline: none; line-height: 1.5; }

/* Right Preview Pane */
.preview-pane { display: flex; flex-direction: column; background: #0f172a; }
.preview-header { background: #131b2e; font-size: 0.75rem; font-weight: 700; color: #94a3b8; padding: 0.3rem 0.75rem; text-transform: uppercase; }
iframe { flex: 2; width: 100%; border: none; background: #ffffff; }

.console-box { flex: 1; display: flex; flex-direction: column; background: #090d16; border-top: 2px solid #1e293b; }
.console-header { background: #131b2e; font-size: 0.75rem; font-weight: 700; color: #94a3b8; padding: 0.3rem 0.75rem; }
.console-logs { flex: 1; padding: 0.5rem; overflow-y: auto; font-family: monospace; font-size: 0.85rem; }
.log-item { padding: 0.25rem 0.5rem; border-bottom: 1px solid #1e293b; color: #cbd5e1; }

@media (max-width: 900px) {
  .studio-workspace { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; overflow-y: auto; }
}

js/editor.js

const htmlCode = document.getElementById("html-code");
const cssCode = document.getElementById("css-code");
const jsCode = document.getElementById("js-code");
const liveFrame = document.getElementById("live-frame");
const consoleLogs = document.getElementById("console-logs");

const runBtn = document.getElementById("run-btn");
const saveBtn = document.getElementById("save-btn");
const exportBtn = document.getElementById("export-btn");
const clearConsoleBtn = document.getElementById("clear-console-btn");

// 1. Virtual Console Interception Script to inject into iframe
const consoleScript = `
  <script>
    const _origLog = console.log;
    const _origErr = console.error;
    console.log = (...args) => {
      _origLog(...args);
      window.parent.postMessage({ type: 'CONSOLE_LOG', data: args.join(' ') }, '*');
    };
    console.error = (...args) => {
      _origErr(...args);
      window.parent.postMessage({ type: 'CONSOLE_ERR', data: args.join(' ') }, '*');
    };
    window.onerror = (msg) => {
      window.parent.postMessage({ type: 'CONSOLE_ERR', data: msg }, '*');
    };
  </script>
`;

// 2. Compile and Render into sandboxed iframe
function runCode() {
  const combined = `
    <!DOCTYPE html>
    <html>
    <head>
      ${consoleScript}
      <style>${cssCode.value}</style>
    </head>
    <body>
      ${htmlCode.value}
      <script>
        try {
          ${jsCode.value}
        } catch (err) {
          console.error(err.message);
        }
      </script>
    </body>
    </html>
  `;

  liveFrame.srcdoc = combined;
}

// 3. Receive Virtual Console messages from iframe
window.addEventListener("message", (event) => {
  if (event.data && (event.data.type === "CONSOLE_LOG" || event.data.type === "CONSOLE_ERR")) {
    const div = document.createElement("div");
    div.className = "log-item";
    if (event.data.type === "CONSOLE_ERR") {
      div.style.color = "#ef4444";
      div.textContent = "โŒ " + event.data.data;
    } else {
      div.textContent = "โ–ถ " + event.data.data;
    }
    consoleLogs.appendChild(div);
    consoleLogs.scrollTop = consoleLogs.scrollHeight;
  }
});

// 4. LocalStorage Snippet Persistence
saveBtn.addEventListener("click", () => {
  const snippet = {
    html: htmlCode.value,
    css: cssCode.value,
    js: jsCode.value,
    date: new Date().toISOString()
  };
  localStorage.setItem("capstone_snippet", JSON.stringify(snippet));
  alert("โœ… Snippet saved to browser storage successfully!");
});

// 5. Standalone File Exporter (Download .html)
exportBtn.addEventListener("click", () => {
  const completeHTML = `<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Exported DevStudio Project</title>
  <style>
${cssCode.value}
  </style>
</head>
<body>
${htmlCode.value}
  <script>
${jsCode.value}
  </script>
</body>
</html>`;

  const blob = new Blob([completeHTML], { type: "text/html" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = "devstudio-project.html";
  a.click();
  URL.revokeObjectURL(url);
});

// 6. Clear Console
clearConsoleBtn.addEventListener("click", () => {
  consoleLogs.innerHTML = "";
});

// Event Listeners
runBtn.addEventListener("click", runCode);

// Auto-run on page load
runCode();

6. Production Deployment Guide (Cloudflare Pages)

Is Capstone application ko poori duniya ke sath share karne ke liye:

  1. Is folder ko apne GitHub par push karein: git push origin main.
  2. Cloudflare Pages dashboard me jakar "Connect to Git" select karein.
  3. Build command ko khali (blank) rakhein aur Output directory ko / chunein.
  4. Click Deploy โ€” 10 second me aapka custom DevStudio live URL par active ho jayega!
๐Ÿ”ฅ Capstone Project 20 / 20

Full Capstone Application: Modern Frontend Dev Studio & Playground

1. Project Overview & Architectural Goal

The crowning capstone of the curriculum: Frontend Dev Studio & Interactive Code Runner. A browser-based IDE combining an HTML/CSS/JS live code editor, responsive device previewer, console log interceptor, template library, and project ZIP exporter!

2. Live Interactive Preview

๐Ÿ’ป โšก ๐Ÿš€

Frontend Dev Studio Live Sandbox

Hamari website par already ek full-fledged live sandbox chal raha hai jo is capstone architecture par based hai!

Launch Studio Playground โšก

3. Capstone Architecture & Requirements

Feature Area Technical Implementation Learner Benefit
Split-Pane Editor HTML, CSS, JS textareas with instant Live Reload DOM input events & iframe manipulation
Virtual Console Overriding console.log inside iframe and messaging parent window via postMessage Advanced JS execution & security sandboxing
Snippet Persistence localStorage.setItem("snippets", JSON.stringify(data)) Client-side database design
File Exporter new Blob([fullCode], { type: "text/html" }) and simulated download anchor Web APIs & File handling
Responsive Previewer Resize iframe container width to 375px (Mobile), 768px (Tablet), 100% (Desktop) CSS Layout & Responsive testing

4. Folder Structure

frontend-dev-studio/
โ”œโ”€โ”€ index.html        (Main Studio Layout)
โ”œโ”€โ”€ css/
โ”‚   โ””โ”€โ”€ studio.css    (Grid split-screen & dark IDE styles)
โ”œโ”€โ”€ js/
โ”‚   โ”œโ”€โ”€ editor.js     (Input listeners, live runner & iframe injector)
โ”‚   โ”œโ”€โ”€ console.js    (Virtual console logger)
โ”‚   โ””โ”€โ”€ storage.js    (Snippet save/load/export engine)
โ””โ”€โ”€ README.md

5. Complete Production-Grade Source Code

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DevStudio - Modern Frontend Code Playground</title>
  <link rel="stylesheet" href="css/studio.css">
</head>
<body>
  <header class="studio-header">
    <div class="brand">
      <span class="logo-icon">โšก</span>
      <strong>DevStudio</strong>
    </div>

    <div class="actions">
      <button id="run-btn" class="btn btn-run">โ–ถ Run Code</button>
      <button id="save-btn" class="btn btn-save">๐Ÿ’พ Save Snippet</button>
      <button id="export-btn" class="btn btn-export">๐Ÿ“ฅ Export HTML</button>
      <button id="clear-console-btn" class="btn btn-clear">๐Ÿงน Clear Console</button>
    </div>
  </header>

  <main class="studio-workspace">
    <!-- Left: Code Editors -->
    <section class="editors-pane">
      <div class="editor-box">
        <div class="editor-title">HTML5</div>
        <textarea id="html-code" spellcheck="false" placeholder="<!-- Write HTML here -->">&lt;div class="card"&gt;
  &lt;h2&gt;Hello World ๐Ÿš€&lt;/h2&gt;
  &lt;p&gt;Welcome to my custom DevStudio capstone!&lt;/p&gt;
  &lt;button id="click-me"&gt;Click Me!&lt;/button&gt;
&lt;/div&gt;</textarea>
      </div>

      <div class="editor-box">
        <div class="editor-title">CSS3</div>
        <textarea id="css-code" spellcheck="false" placeholder="/* Write CSS here */">body {
  font-family: system-ui, sans-serif;
  display: grid;
  place-items: center;
  min-height: 90vh;
  background: #0f172a;
  color: #fff;
}
.card {
  background: #1e293b;
  padding: 2rem;
  border-radius: 12px;
  border: 1px solid #334155;
  text-align: center;
}
button {
  background: #38bdf8;
  color: #0f172a;
  font-weight: bold;
  border: none;
  padding: 0.6rem 1.2rem;
  border-radius: 6px;
  cursor: pointer;
  margin-top: 1rem;
}</textarea>
      </div>

      <div class="editor-box">
        <div class="editor-title">JavaScript</div>
        <textarea id="js-code" spellcheck="false" placeholder="// Write JS here">console.log("DevStudio initialized successfully!");

document.getElementById("click-me").addEventListener("click", () => {
  console.log("Button clicked at: " + new Date().toLocaleTimeString());
  alert("Interactive JS working!");
});</textarea>
      </div>
    </section>

    <!-- Right: Live Preview & Virtual Console -->
    <section class="preview-pane">
      <div class="preview-header">Live Result</div>
      <iframe id="live-frame" sandbox="allow-scripts allow-modals"></iframe>
      
      <div class="console-box">
        <div class="console-header">Console Logs</div>
        <div id="console-logs" class="console-logs"></div>
      </div>
    </section>
  </main>

  <script src="js/editor.js"></script>
</body>
</html>

css/studio.css

* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #0b0f19; color: #f8fafc; height: 100vh; display: flex; flex-direction: column; overflow: hidden; }

.studio-header { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem 1.5rem; background: #131b2e; border-bottom: 1px solid #1e293b; }
.brand { display: flex; align-items: center; gap: 0.5rem; font-size: 1.2rem; color: #38bdf8; }

.actions { display: flex; gap: 0.5rem; }
.btn { padding: 0.45rem 0.9rem; font-size: 0.85rem; font-weight: 600; border-radius: 6px; cursor: pointer; border: 1px solid transparent; }
.btn-run { background: #10b981; color: #fff; }
.btn-save { background: #6366f1; color: #fff; }
.btn-export { background: #1e293b; color: #cbd5e1; border-color: #334155; }
.btn-clear { background: #1e293b; color: #94a3b8; border-color: #334155; }

.studio-workspace { flex: 1; display: grid; grid-template-columns: 1fr 1fr; height: calc(100vh - 55px); }

/* Left Editors Pane */
.editors-pane { display: grid; grid-template-rows: 1fr 1fr 1fr; border-right: 2px solid #1e293b; background: #0f172a; }
.editor-box { display: flex; flex-direction: column; border-bottom: 1px solid #1e293b; }
.editor-title { background: #131b2e; font-size: 0.75rem; font-weight: 700; color: #94a3b8; padding: 0.3rem 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; }
textarea { flex: 1; width: 100%; background: #090d16; color: #f1f5f9; border: none; padding: 0.75rem; font-family: 'Fira Code', monospace; font-size: 0.9rem; resize: none; outline: none; line-height: 1.5; }

/* Right Preview Pane */
.preview-pane { display: flex; flex-direction: column; background: #0f172a; }
.preview-header { background: #131b2e; font-size: 0.75rem; font-weight: 700; color: #94a3b8; padding: 0.3rem 0.75rem; text-transform: uppercase; }
iframe { flex: 2; width: 100%; border: none; background: #ffffff; }

.console-box { flex: 1; display: flex; flex-direction: column; background: #090d16; border-top: 2px solid #1e293b; }
.console-header { background: #131b2e; font-size: 0.75rem; font-weight: 700; color: #94a3b8; padding: 0.3rem 0.75rem; }
.console-logs { flex: 1; padding: 0.5rem; overflow-y: auto; font-family: monospace; font-size: 0.85rem; }
.log-item { padding: 0.25rem 0.5rem; border-bottom: 1px solid #1e293b; color: #cbd5e1; }

@media (max-width: 900px) {
  .studio-workspace { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; overflow-y: auto; }
}

js/editor.js

const htmlCode = document.getElementById("html-code");
const cssCode = document.getElementById("css-code");
const jsCode = document.getElementById("js-code");
const liveFrame = document.getElementById("live-frame");
const consoleLogs = document.getElementById("console-logs");

const runBtn = document.getElementById("run-btn");
const saveBtn = document.getElementById("save-btn");
const exportBtn = document.getElementById("export-btn");
const clearConsoleBtn = document.getElementById("clear-console-btn");

// 1. Virtual Console Interception Script to inject into iframe
const consoleScript = `
  <script>
    const _origLog = console.log;
    const _origErr = console.error;
    console.log = (...args) => {
      _origLog(...args);
      window.parent.postMessage({ type: 'CONSOLE_LOG', data: args.join(' ') }, '*');
    };
    console.error = (...args) => {
      _origErr(...args);
      window.parent.postMessage({ type: 'CONSOLE_ERR', data: args.join(' ') }, '*');
    };
    window.onerror = (msg) => {
      window.parent.postMessage({ type: 'CONSOLE_ERR', data: msg }, '*');
    };
  </script>
`;

// 2. Compile and Render into sandboxed iframe
function runCode() {
  const combined = `
    <!DOCTYPE html>
    <html>
    <head>
      ${consoleScript}
      <style>${cssCode.value}</style>
    </head>
    <body>
      ${htmlCode.value}
      <script>
        try {
          ${jsCode.value}
        } catch (err) {
          console.error(err.message);
        }
      </script>
    </body>
    </html>
  `;

  liveFrame.srcdoc = combined;
}

// 3. Receive Virtual Console messages from iframe
window.addEventListener("message", (event) => {
  if (event.data && (event.data.type === "CONSOLE_LOG" || event.data.type === "CONSOLE_ERR")) {
    const div = document.createElement("div");
    div.className = "log-item";
    if (event.data.type === "CONSOLE_ERR") {
      div.style.color = "#ef4444";
      div.textContent = "โŒ " + event.data.data;
    } else {
      div.textContent = "โ–ถ " + event.data.data;
    }
    consoleLogs.appendChild(div);
    consoleLogs.scrollTop = consoleLogs.scrollHeight;
  }
});

// 4. LocalStorage Snippet Persistence
saveBtn.addEventListener("click", () => {
  const snippet = {
    html: htmlCode.value,
    css: cssCode.value,
    js: jsCode.value,
    date: new Date().toISOString()
  };
  localStorage.setItem("capstone_snippet", JSON.stringify(snippet));
  alert("โœ… Snippet saved to browser storage successfully!");
});

// 5. Standalone File Exporter (Download .html)
exportBtn.addEventListener("click", () => {
  const completeHTML = `<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Exported DevStudio Project</title>
  <style>
${cssCode.value}
  </style>
</head>
<body>
${htmlCode.value}
  <script>
${jsCode.value}
  </script>
</body>
</html>`;

  const blob = new Blob([completeHTML], { type: "text/html" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = "devstudio-project.html";
  a.click();
  URL.revokeObjectURL(url);
});

// 6. Clear Console
clearConsoleBtn.addEventListener("click", () => {
  consoleLogs.innerHTML = "";
});

// Event Listeners
runBtn.addEventListener("click", runCode);

// Auto-run on page load
runCode();

6. Production Deployment Guide (Cloudflare Pages)

Is Capstone application ko poori duniya ke sath share karne ke liye:

  1. Is folder ko apne GitHub par push karein: git push origin main.
  2. Cloudflare Pages dashboard me jakar "Connect to Git" select karein.
  3. Build command ko khali (blank) rakhein aur Output directory ko / chunein.
  4. Click Deploy โ€” 10 second me aapka custom DevStudio live URL par active ho jayega!