Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions src/css/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -305,4 +305,69 @@
a {
@apply text-forge-accent hover:text-forge-accent-hover;
}

/* Editor Preview Styles */
.editor-preview-container {
@apply mx-auto;
}

.editor-window {
@apply transition-all duration-300 hover:shadow-2xl hover:shadow-forge-accent/10;
}

.editor-header {
@apply backdrop-blur-sm;
}

.editor-window:hover .editor-header {
@apply bg-forge-muted/70;
}

/* Add subtle glow effect */
.editor-window::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, transparent, rgba(252, 72, 63, 0.1), transparent);
border-radius: 18px;
z-index: -1;
opacity: 0;
transition: opacity 0.3s ease;
}

.editor-window:hover::before {
opacity: 1;
}

/* Feature highlights animation */
.editor-preview-container .grid > div {
@apply transition-all duration-300 hover:scale-105 hover:bg-forge-surface/80 cursor-pointer;
}

.editor-preview-container .grid > div svg {
@apply transition-transform duration-300;
}

/* Button animations */
.editor-window button {
@apply transition-all duration-300 transform hover:scale-105 active:scale-95;
}

/* Hide scrollbars while keeping scroll functionality */
* {
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Internet Explorer 10+ */
}

*::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}

/* Ensure body and html can still scroll */
html, body {
overflow-x: hidden; /* Prevent horizontal scroll */
}
}
7 changes: 5 additions & 2 deletions src/js/course.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { onAuthStateChanged } from "firebase/auth";
import { Course, User } from "./main.js";
import { initMobileMenu } from './mobile-menu.js';
import $ from "jquery";
import { initializeApp } from './utils/common.js';
import { auth } from "./firebase.js";
import $ from "jquery";

// Initialize common app functionality
initializeApp();



Expand Down
5 changes: 4 additions & 1 deletion src/js/courses.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { onAuthStateChanged } from "firebase/auth";
import { auth } from "./firebase.js";
import { Course } from "./main.js";
import { initMobileMenu } from './mobile-menu.js';
import { initializeApp } from './utils/common.js';

// Initialize common app functionality
initializeApp();



Expand Down
54 changes: 22 additions & 32 deletions src/js/editor.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,40 @@
import '../css/tailwind.css';

import { Editor } from './main.js';
import { initMobileMenu } from './mobile-menu.js';
import $ from "jquery"

import '../css/tailwind.css';
import { Editor } from './main.js';
import { initializeApp, CodeExecutor, StorageUtils } from './utils/common.js';
import $ from "jquery";

// Initialize common app functionality
initializeApp();

const code = `// Code Example
const defaultCode = `// Welcome to SyntaxForge Playground!
const amICool = true

if (amICool) {
console.log("I am very cool!")
}
else {
} else {
console.log("I am not very cool :(")
}
`

// Try editing this code!
const skills = ["JavaScript", "Python", "Ruby"]
console.log("My skills:", skills.join(", "))`;

// Load saved code from localStorage or use default
const savedCode = localStorage.getItem('playground-code') || code;

const editor = new Editor($("#editor"), savedCode)

// Save code to localStorage whenever it changes
let saveTimeout;
editor.view.dom.addEventListener('input', () => {
// Debounce saving to avoid excessive localStorage writes
clearTimeout(saveTimeout);
saveTimeout = setTimeout(() => {
const currentCode = editor.getContent();
localStorage.setItem('playground-code', currentCode);
}, 500);
});
const savedCode = StorageUtils.load('playground-code', defaultCode);

// Also save when run button is clicked
const editor = new Editor($("#editor"), savedCode);
const codeExecutor = new CodeExecutor(editor);

// Enhanced run button functionality with better feedback
editor.runButton.off('click'); // Remove default handler
editor.runButton.on("click", () => {
const currentCode = editor.getContent();
localStorage.setItem('playground-code', currentCode);
StorageUtils.save('playground-code', currentCode);

// Use the common code executor
codeExecutor.execute(currentCode);
});



// $("#run").on("click", () => {
// const content = view.state.doc.toString()
// $("#output").text("")
// for (const log of safeEval(content, null).logs) {
// $("#output").append($("<span/>").text(log))
// }
// })
129 changes: 119 additions & 10 deletions src/js/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,130 @@
import '../css/tailwind.css'

import '../css/tailwind.css';
import { Editor } from './main.js';
import { initMobileMenu } from './mobile-menu.js';
import $ from "jquery"

import { initializeApp, CodeExecutor } from './utils/common.js';
import $ from "jquery";

// Initialize common app functionality
initializeApp();

const code = `// Code Example
const previewCode = `// Welcome to SyntaxForge!
const amICool = true

if (amICool) {
console.log("I am very cool!")
}
else {
} else {
console.log("I am not very cool :(")
}
`

const editor = new Editor($("#editor"), code)
// Try editing this code!
const skills = ["JavaScript", "Python", "Ruby"]
console.log("My skills:", skills.join(", "))`;

const editor = new Editor($("#editor"), previewCode);
const codeExecutor = new CodeExecutor(editor, {
terminalOutput: false, // Use HTML output panel instead
buttonFeedback: true,
showCompletionMessage: false
});

// Disable terminal for homepage preview
editor.disableTerminal();

// Add interactive features to the editor preview
$(document).ready(() => {
const outputPanel = $('#output-panel');

// Function to execute preview code using common executor
function executePreviewCode() {
// Clear output
outputPanel.empty();

// Add command line
outputPanel.append('<div class="text-green-400">$ node main.js</div>');

try {
const result = editor.safeEval(editor.getContent());

// Add output lines with delay for better UX
if (result.logs && result.logs.length > 0) {
result.logs.forEach((log, index) => {
setTimeout(() => {
outputPanel.append(`<div class="text-forge-text">${log}</div>`);
}, 300 * (index + 1));
});

// Add completion message
setTimeout(() => {
outputPanel.append('<div class="text-forge-subtext mt-2">Process finished with exit code 0</div>');
}, 300 * (result.logs.length + 1));
} else {
outputPanel.append('<div class="text-forge-subtext mt-2">No output generated</div>');
}
} catch (error) {
outputPanel.append('<div class="text-red-400 mt-2">Error: ' + error.message + '</div>');
}
}

// Add run button functionality
$('.editor-window button').on('click', function() {
const button = $(this);
const originalText = button.text();

// Update button state
button.text('Running...').prop('disabled', true);

// Show running state in output
outputPanel.empty();
outputPanel.append('<div class="text-yellow-400">Running code...</div>');

setTimeout(() => {
// Execute the code
executePreviewCode();

// Update button to success state
button.text('✓ Executed').removeClass('bg-forge-accent hover:bg-forge-accent-hover')
.addClass('bg-green-500 hover:bg-green-600');

setTimeout(() => {
button.text(originalText).removeClass('bg-green-500 hover:bg-green-600')
.addClass('bg-forge-accent hover:bg-forge-accent-hover')
.prop('disabled', false);
}, 2000);
}, 1000);
});

// Show initial demo output
setTimeout(() => {
executePreviewCode();
outputPanel.append('<div class="text-forge-accent mt-3 text-xs">👆 Click "Run Code" to execute again!</div>');
}, 2000);

// Add typing effect on first load
setTimeout(() => {
if (editor && editor.view) {
// Simulate a small code change to show interactivity
const currentCode = editor.view.state.doc.toString();
const newLine = '\n\n// Click "Run Code" to see the magic! ✨';

// Add the new line with a subtle animation
const transaction = editor.view.state.update({
changes: {
from: currentCode.length,
insert: newLine
}
});

editor.view.dispatch(transaction);
}
}, 5000);

// Add hover effects to feature highlights
$('.editor-preview-container .grid > div').hover(
function() {
$(this).find('svg').addClass('scale-110');
},
function() {
$(this).find('svg').removeClass('scale-110');
}
);
});

11 changes: 5 additions & 6 deletions src/js/lesson.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Course, Editor, Lesson, safeEval, User } from "./main.js";
import { initMobileMenu } from './mobile-menu.js';
import $ from "jquery";
import { Course, Editor, User } from "./main.js";
import { initializeApp, AuthUtils } from './utils/common.js';
import { auth } from "./firebase.js";
import { onAuthStateChanged } from "firebase/auth";

import { marked } from "marked";
import $ from "jquery";

// Initialize mobile menu
initMobileMenu();
// Initialize common app functionality
initializeApp();

const editor = new Editor();

Expand Down
5 changes: 0 additions & 5 deletions src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ import { basicDark } from "@fsegurai/codemirror-theme-bundle";
import { indentWithTab } from "@codemirror/commands";
import { keymap, EditorView } from "@codemirror/view";
import { Prec } from "@codemirror/state";
import { initMobileMenu } from "./mobile-menu.js";


//for mobile view
initMobileMenu()

// Load JSON data
const courses = (await (await fetch("/data/courses.json")).json()) || {};
Expand Down
Loading