tetrons 2.3.77 → 2.3.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/app/api/execute/route.ts
21
+ var route_exports = {};
22
+ __export(route_exports, {
23
+ POST: () => POST
24
+ });
25
+ module.exports = __toCommonJS(route_exports);
26
+ var import_server = require("next/server");
27
+ async function POST(req) {
28
+ const { language, code } = await req.json();
29
+ console.log(language, code);
30
+ const res = await fetch("https://emkc.org/api/v2/piston/execute", {
31
+ method: "POST",
32
+ headers: { "Content-Type": "application/json" },
33
+ body: JSON.stringify({
34
+ language,
35
+ version: "*",
36
+ files: [
37
+ {
38
+ name: `main.${language === "cpp" ? "cpp" : language}`,
39
+ content: code
40
+ }
41
+ ],
42
+ args: [],
43
+ stdin: ""
44
+ })
45
+ });
46
+ const data = await res.json();
47
+ return import_server.NextResponse.json({
48
+ stdout: data.run?.stdout ?? "",
49
+ stderr: data.run?.stderr ?? ""
50
+ });
51
+ }
52
+ // Annotate the CommonJS export names for ESM import in node:
53
+ 0 && (module.exports = {
54
+ POST
55
+ });
@@ -0,0 +1,8 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+
3
+ declare function POST(req: NextRequest): Promise<NextResponse<{
4
+ stdout: any;
5
+ stderr: any;
6
+ }>>;
7
+
8
+ export { POST };
@@ -0,0 +1,8 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+
3
+ declare function POST(req: NextRequest): Promise<NextResponse<{
4
+ stdout: any;
5
+ stderr: any;
6
+ }>>;
7
+
8
+ export { POST };
@@ -0,0 +1,30 @@
1
+ // src/app/api/execute/route.ts
2
+ import { NextResponse } from "next/server";
3
+ async function POST(req) {
4
+ const { language, code } = await req.json();
5
+ console.log(language, code);
6
+ const res = await fetch("https://emkc.org/api/v2/piston/execute", {
7
+ method: "POST",
8
+ headers: { "Content-Type": "application/json" },
9
+ body: JSON.stringify({
10
+ language,
11
+ version: "*",
12
+ files: [
13
+ {
14
+ name: `main.${language === "cpp" ? "cpp" : language}`,
15
+ content: code
16
+ }
17
+ ],
18
+ args: [],
19
+ stdin: ""
20
+ })
21
+ });
22
+ const data = await res.json();
23
+ return NextResponse.json({
24
+ stdout: data.run?.stdout ?? "",
25
+ stderr: data.run?.stderr ?? ""
26
+ });
27
+ }
28
+ export {
29
+ POST
30
+ };
package/dist/index.cjs CHANGED
@@ -90,6 +90,106 @@ var init_MathModal = __esm({
90
90
  }
91
91
  });
92
92
 
93
+ // src/components/tetrons/toolbar/CodeEditorModal.js
94
+ var CodeEditorModal_exports = {};
95
+ __export(CodeEditorModal_exports, {
96
+ default: () => CodeEditorModal_default
97
+ });
98
+ var import_react20, import_react21, CodeEditorModal, CodeEditorModal_default;
99
+ var init_CodeEditorModal = __esm({
100
+ "src/components/tetrons/toolbar/CodeEditorModal.js"() {
101
+ "use strict";
102
+ "use client";
103
+ import_react20 = __toESM(require("react"));
104
+ import_react21 = __toESM(require("@monaco-editor/react"));
105
+ CodeEditorModal = ({
106
+ isOpen,
107
+ onClose,
108
+ onSubmitCode,
109
+ onSubmitCodeWithOutput
110
+ }) => {
111
+ const [language, setLanguage] = (0, import_react20.useState)("javascript");
112
+ const [code, setCode] = (0, import_react20.useState)("// Write your code here");
113
+ const [output, setOutput] = (0, import_react20.useState)("");
114
+ const [loading, setLoading] = (0, import_react20.useState)(false);
115
+ const runCode = async () => {
116
+ setLoading(true);
117
+ try {
118
+ const res = await fetch("/api/execute", {
119
+ method: "POST",
120
+ headers: { "Content-Type": "application/json" },
121
+ body: JSON.stringify({ language, code })
122
+ });
123
+ const data = await res.json();
124
+ let result = "";
125
+ if (data.stderr) result += `Error:
126
+ ${data.stderr}
127
+ `;
128
+ if (data.stdout) result += data.stdout;
129
+ if (!data.stdout && !data.stderr) result = "No output";
130
+ setOutput(result);
131
+ } catch (err) {
132
+ console.log(err.message);
133
+ setOutput("Error running code");
134
+ }
135
+ setLoading(false);
136
+ };
137
+ const handleSubmitCode = () => {
138
+ if (onSubmitCode) {
139
+ onSubmitCode(code);
140
+ }
141
+ onClose();
142
+ };
143
+ const handleSubmitCodeWithOutput = () => {
144
+ if (onSubmitCodeWithOutput) {
145
+ onSubmitCodeWithOutput({ code, output });
146
+ }
147
+ onClose();
148
+ };
149
+ if (!isOpen) return null;
150
+ return /* @__PURE__ */ import_react20.default.createElement("div", { className: "code-modal-overlay" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "code-modal-content" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "code-modal-header" }, /* @__PURE__ */ import_react20.default.createElement("h2", null, "Run Code"), /* @__PURE__ */ import_react20.default.createElement("button", { onClick: onClose, className: "code-close-btn" }, "\xD7")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "code-modal-controls" }, /* @__PURE__ */ import_react20.default.createElement("label", { htmlFor: "language" }, "Language:"), /* @__PURE__ */ import_react20.default.createElement(
151
+ "select",
152
+ {
153
+ id: "language",
154
+ value: language,
155
+ onChange: (e) => setLanguage(e.target.value)
156
+ },
157
+ /* @__PURE__ */ import_react20.default.createElement("option", { value: "javascript" }, "JavaScript"),
158
+ /* @__PURE__ */ import_react20.default.createElement("option", { value: "python" }, "Python"),
159
+ /* @__PURE__ */ import_react20.default.createElement("option", { value: "cpp" }, "C++"),
160
+ /* @__PURE__ */ import_react20.default.createElement("option", { value: "java" }, "Java"),
161
+ /* @__PURE__ */ import_react20.default.createElement("option", { value: "typescript" }, "TypeScript")
162
+ ), /* @__PURE__ */ import_react20.default.createElement("button", { className: "run-code", onClick: runCode, disabled: loading }, loading ? "Running..." : "Run")), /* @__PURE__ */ import_react20.default.createElement(
163
+ import_react21.default,
164
+ {
165
+ height: "50vh",
166
+ theme: "vs-dark",
167
+ language,
168
+ value: code,
169
+ onChange: (v) => setCode(v ?? "")
170
+ }
171
+ ), /* @__PURE__ */ import_react20.default.createElement("div", { className: "code-output" }, /* @__PURE__ */ import_react20.default.createElement("strong", null, "Output:"), /* @__PURE__ */ import_react20.default.createElement("pre", null, output.trim() === "" ? "\u2190 Click Run to see output here" : output)), /* @__PURE__ */ import_react20.default.createElement("div", { className: "code-submit-buttons-container" }, /* @__PURE__ */ import_react20.default.createElement(
172
+ "button",
173
+ {
174
+ className: "code-submit-buttons",
175
+ onClick: handleSubmitCode,
176
+ disabled: loading || !code
177
+ },
178
+ "Submit Code Snippet Only"
179
+ ), /* @__PURE__ */ import_react20.default.createElement(
180
+ "button",
181
+ {
182
+ className: "code-submit-buttons",
183
+ onClick: handleSubmitCodeWithOutput,
184
+ disabled: loading || !code
185
+ },
186
+ "Submit Code Snippet With Output"
187
+ ))));
188
+ };
189
+ CodeEditorModal_default = CodeEditorModal;
190
+ }
191
+ });
192
+
93
193
  // src/index.ts
94
194
  var index_exports = {};
95
195
  __export(index_exports, {
@@ -159,8 +259,8 @@ var MathInline = import_core.Node.create({
159
259
  });
160
260
 
161
261
  // src/components/tetrons/EditorContent.tsx
162
- var import_react22 = __toESM(require("react"));
163
- var import_react23 = require("@tiptap/react");
262
+ var import_react24 = __toESM(require("react"));
263
+ var import_react25 = require("@tiptap/react");
164
264
 
165
265
  // node_modules/@tiptap/extension-document/dist/index.js
166
266
  var import_core2 = require("@tiptap/core");
@@ -15840,7 +15940,7 @@ function TableContextMenu({ editor }) {
15840
15940
  }
15841
15941
 
15842
15942
  // src/components/tetrons/toolbar/TetronsToolbar.tsx
15843
- var import_react21 = __toESM(require("react"));
15943
+ var import_react23 = __toESM(require("react"));
15844
15944
 
15845
15945
  // src/components/tetrons/toolbar/ActionGroup.tsx
15846
15946
  var import_react10 = __toESM(require("react"));
@@ -16897,17 +16997,21 @@ function AiGroup({ editor }) {
16897
16997
  }
16898
16998
 
16899
16999
  // src/components/tetrons/toolbar/AddOnGroup.tsx
16900
- var import_react20 = __toESM(require("react"));
16901
- var import_fa3 = require("react-icons/fa");
17000
+ var import_react22 = __toESM(require("react"));
17001
+ var import_lucide_react = require("lucide-react");
16902
17002
  var import_dynamic = __toESM(require("next/dynamic"));
16903
17003
  var import_katex_min2 = require("katex/dist/katex.min.css");
16904
17004
  var MathModal2 = (0, import_dynamic.default)(() => Promise.resolve().then(() => (init_MathModal(), MathModal_exports)), { ssr: false });
17005
+ var CodeEditorModal2 = (0, import_dynamic.default)(() => Promise.resolve().then(() => (init_CodeEditorModal(), CodeEditorModal_exports)), {
17006
+ ssr: false
17007
+ });
16905
17008
  var AddOnGroup = ({ editor }) => {
16906
- const [isModalOpen, setModalOpen] = (0, import_react20.useState)(false);
16907
- const [latexValue, setLatexValue] = (0, import_react20.useState)("");
17009
+ const [isModalOpen, setModalOpen] = (0, import_react22.useState)(false);
17010
+ const [latexValue, setLatexValue] = (0, import_react22.useState)("");
17011
+ const [isCodeModalOpen, setCodeModalOpen] = (0, import_react22.useState)(false);
16908
17012
  if (!editor) return null;
16909
17013
  const insertCodeBlock = () => {
16910
- editor.chain().focus().toggleCodeBlock().run();
17014
+ setCodeModalOpen(true);
16911
17015
  };
16912
17016
  const handleMathInsert = (latex) => {
16913
17017
  editor.chain().focus().insertContent({
@@ -16917,25 +17021,48 @@ var AddOnGroup = ({ editor }) => {
16917
17021
  setModalOpen(false);
16918
17022
  setLatexValue("");
16919
17023
  };
16920
- return /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "group flex gap-2 items-center" }, /* @__PURE__ */ import_react20.default.createElement(
17024
+ const handleSubmitCode = (code) => {
17025
+ editor.chain().focus().insertContent({
17026
+ type: "codeBlock",
17027
+ content: [{ type: "text", text: code }]
17028
+ }).run();
17029
+ setCodeModalOpen(false);
17030
+ };
17031
+ const handleSubmitCodeWithOutput = ({
17032
+ code,
17033
+ output
17034
+ }) => {
17035
+ editor.chain().focus().insertContent({
17036
+ type: "codeBlock",
17037
+ content: [{ type: "text", text: code }]
17038
+ }).insertContent({
17039
+ type: "paragraph",
17040
+ content: [{ type: "text", text: "Output:" }]
17041
+ }).insertContent({
17042
+ type: "codeBlock",
17043
+ content: [{ type: "text", text: output }]
17044
+ }).run();
17045
+ setCodeModalOpen(false);
17046
+ };
17047
+ return /* @__PURE__ */ import_react22.default.createElement(import_react22.default.Fragment, null, /* @__PURE__ */ import_react22.default.createElement("div", { className: "group flex gap-2 items-center" }, /* @__PURE__ */ import_react22.default.createElement(
16921
17048
  "button",
16922
17049
  {
16923
17050
  type: "button",
16924
17051
  onClick: insertCodeBlock,
16925
- className: "icon-btn",
16926
- title: "Insert Code Block"
17052
+ className: "addon-btn",
17053
+ title: "Open Code Editor"
16927
17054
  },
16928
- /* @__PURE__ */ import_react20.default.createElement(import_fa3.FaCode, { size: 18 })
16929
- ), /* @__PURE__ */ import_react20.default.createElement(
17055
+ /* @__PURE__ */ import_react22.default.createElement(import_lucide_react.MessageSquareCode, { size: 18 })
17056
+ ), /* @__PURE__ */ import_react22.default.createElement(
16930
17057
  "button",
16931
17058
  {
16932
17059
  type: "button",
16933
17060
  onClick: () => setModalOpen(true),
16934
- className: "icon-btn",
17061
+ className: "addon-btn",
16935
17062
  title: "Insert Math Equation"
16936
17063
  },
16937
- /* @__PURE__ */ import_react20.default.createElement(import_fa3.FaSuperscript, { size: 18 })
16938
- )), /* @__PURE__ */ import_react20.default.createElement(
17064
+ /* @__PURE__ */ import_react22.default.createElement(import_lucide_react.SquareRadical, { size: 18 })
17065
+ )), /* @__PURE__ */ import_react22.default.createElement(
16939
17066
  MathModal2,
16940
17067
  {
16941
17068
  isOpen: isModalOpen,
@@ -16944,6 +17071,14 @@ var AddOnGroup = ({ editor }) => {
16944
17071
  value: latexValue,
16945
17072
  setValue: setLatexValue
16946
17073
  }
17074
+ ), /* @__PURE__ */ import_react22.default.createElement(
17075
+ CodeEditorModal2,
17076
+ {
17077
+ isOpen: isCodeModalOpen,
17078
+ onClose: () => setCodeModalOpen(false),
17079
+ onSubmitCode: handleSubmitCode,
17080
+ onSubmitCodeWithOutput: handleSubmitCodeWithOutput
17081
+ }
16947
17082
  ));
16948
17083
  };
16949
17084
  var AddOnGroup_default = AddOnGroup;
@@ -16954,8 +17089,8 @@ function TetronsToolbar({
16954
17089
  version,
16955
17090
  addOns = []
16956
17091
  }) {
16957
- const [autoSave, setAutoSave] = (0, import_react21.useState)(false);
16958
- (0, import_react21.useEffect)(() => {
17092
+ const [autoSave, setAutoSave] = (0, import_react23.useState)(false);
17093
+ (0, import_react23.useEffect)(() => {
16959
17094
  if (!editor) return;
16960
17095
  const handleUpdate = () => {
16961
17096
  if (!autoSave) return;
@@ -16971,7 +17106,7 @@ function TetronsToolbar({
16971
17106
  editor.off("update", handleUpdate);
16972
17107
  };
16973
17108
  }, [autoSave, editor]);
16974
- return /* @__PURE__ */ import_react21.default.createElement("div", { className: "tetrons-toolbar" }, version !== "free" && /* @__PURE__ */ import_react21.default.createElement("div", { className: "group" }, /* @__PURE__ */ import_react21.default.createElement(
17109
+ return /* @__PURE__ */ import_react23.default.createElement("div", { className: "tetrons-toolbar" }, version !== "free" && /* @__PURE__ */ import_react23.default.createElement("div", { className: "group" }, /* @__PURE__ */ import_react23.default.createElement(
16975
17110
  "input",
16976
17111
  {
16977
17112
  type: "checkbox",
@@ -16979,7 +17114,7 @@ function TetronsToolbar({
16979
17114
  checked: autoSave,
16980
17115
  onChange: (e) => setAutoSave(e.target.checked)
16981
17116
  }
16982
- ), /* @__PURE__ */ import_react21.default.createElement("label", { htmlFor: "autoSave" }, "Auto Save")), ["pro", "premium", "platinum"].includes(version) && /* @__PURE__ */ import_react21.default.createElement(FileGroup, { editor }), /* @__PURE__ */ import_react21.default.createElement(ClipboardGroup, { editor }), /* @__PURE__ */ import_react21.default.createElement(FontStyleGroup, { editor }), /* @__PURE__ */ import_react21.default.createElement(ListAlignGroup, { editor }), ["premium", "platinum"].includes(version) && /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement(InsertGroup, { editor }), /* @__PURE__ */ import_react21.default.createElement(ActionGroup, { editor })), version === "platinum" && /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement(MiscGroup, { editor }), /* @__PURE__ */ import_react21.default.createElement(AiGroup, { editor })), addOns.length > 0 && /* @__PURE__ */ import_react21.default.createElement(AddOnGroup_default, { editor }));
17117
+ ), /* @__PURE__ */ import_react23.default.createElement("label", { htmlFor: "autoSave" }, "Auto Save")), ["pro", "premium", "platinum"].includes(version) && /* @__PURE__ */ import_react23.default.createElement(FileGroup, { editor }), /* @__PURE__ */ import_react23.default.createElement(ClipboardGroup, { editor }), /* @__PURE__ */ import_react23.default.createElement(FontStyleGroup, { editor }), /* @__PURE__ */ import_react23.default.createElement(ListAlignGroup, { editor }), ["premium", "platinum"].includes(version) && /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement(InsertGroup, { editor }), /* @__PURE__ */ import_react23.default.createElement(ActionGroup, { editor })), version === "platinum" && /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement(MiscGroup, { editor }), /* @__PURE__ */ import_react23.default.createElement(AiGroup, { editor })), addOns.length > 0 && /* @__PURE__ */ import_react23.default.createElement(AddOnGroup_default, { editor }));
16983
17118
  }
16984
17119
 
16985
17120
  // src/components/tetrons/EditorContent.tsx
@@ -16988,16 +17123,16 @@ lowlight.register("js", javascript);
16988
17123
  lowlight.register("ts", typescript);
16989
17124
  function EditorContent({ apiKey }) {
16990
17125
  const typo = useTypo();
16991
- const [isValid, setIsValid] = (0, import_react22.useState)(null);
16992
- const [error, setError] = (0, import_react22.useState)(null);
16993
- const [versions, setVersions] = (0, import_react22.useState)([]);
16994
- const [userVersion, setUserVersion] = (0, import_react22.useState)(null);
16995
- const [currentVersionIndex, setCurrentVersionIndex] = (0, import_react22.useState)(
17126
+ const [isValid, setIsValid] = (0, import_react24.useState)(null);
17127
+ const [error, setError] = (0, import_react24.useState)(null);
17128
+ const [versions, setVersions] = (0, import_react24.useState)([]);
17129
+ const [userVersion, setUserVersion] = (0, import_react24.useState)(null);
17130
+ const [currentVersionIndex, setCurrentVersionIndex] = (0, import_react24.useState)(
16996
17131
  null
16997
17132
  );
16998
- const wrapperRef = (0, import_react22.useRef)(null);
17133
+ const wrapperRef = (0, import_react24.useRef)(null);
16999
17134
  const API_BASE_URL = typeof process !== "undefined" && process.env?.NEXT_PUBLIC_TETRONS_API_URL ? process.env.NEXT_PUBLIC_TETRONS_API_URL : "https://staging.tetrons.com";
17000
- (0, import_react22.useEffect)(() => {
17135
+ (0, import_react24.useEffect)(() => {
17001
17136
  const validateKey = async () => {
17002
17137
  try {
17003
17138
  const res = await fetch(`${API_BASE_URL}/api/validate`, {
@@ -17018,7 +17153,7 @@ function EditorContent({ apiKey }) {
17018
17153
  };
17019
17154
  validateKey();
17020
17155
  }, [apiKey, API_BASE_URL]);
17021
- const editor = (0, import_react23.useEditor)({
17156
+ const editor = (0, import_react25.useEditor)({
17022
17157
  extensions: [
17023
17158
  Document,
17024
17159
  Paragraph,
@@ -17080,7 +17215,7 @@ function EditorContent({ apiKey }) {
17080
17215
  },
17081
17216
  immediatelyRender: false
17082
17217
  });
17083
- (0, import_react22.useEffect)(() => {
17218
+ (0, import_react24.useEffect)(() => {
17084
17219
  return () => {
17085
17220
  editor?.destroy();
17086
17221
  };
@@ -17105,13 +17240,13 @@ function EditorContent({ apiKey }) {
17105
17240
  }
17106
17241
  };
17107
17242
  if (isValid === false) {
17108
- return /* @__PURE__ */ import_react22.default.createElement("div", { className: "editor-error" }, "\u26A0\uFE0F ", error);
17243
+ return /* @__PURE__ */ import_react24.default.createElement("div", { className: "editor-error" }, "\u26A0\uFE0F ", error);
17109
17244
  }
17110
17245
  if (isValid === null) {
17111
- return /* @__PURE__ */ import_react22.default.createElement("div", { className: "editor-loading" }, "\u{1F50D} Validating license...");
17246
+ return /* @__PURE__ */ import_react24.default.createElement("div", { className: "editor-loading" }, "\u{1F50D} Validating license...");
17112
17247
  }
17113
17248
  if (!typo) {
17114
- return /* @__PURE__ */ import_react22.default.createElement("div", { className: "editor-loading" }, "\u{1F4D6} Loading dictionary...");
17249
+ return /* @__PURE__ */ import_react24.default.createElement("div", { className: "editor-loading" }, "\u{1F4D6} Loading dictionary...");
17115
17250
  }
17116
17251
  const versionAddOnsMap = {
17117
17252
  free: [],
@@ -17120,7 +17255,7 @@ function EditorContent({ apiKey }) {
17120
17255
  platinum: ["code", "math"]
17121
17256
  };
17122
17257
  const enabledAddOns = userVersion ? versionAddOnsMap[userVersion] || [] : [];
17123
- return /* @__PURE__ */ import_react22.default.createElement("div", { className: "editor-container" }, userVersion !== "free" && /* @__PURE__ */ import_react22.default.createElement("div", { className: "editor-toolbar" }, /* @__PURE__ */ import_react22.default.createElement(
17258
+ return /* @__PURE__ */ import_react24.default.createElement("div", { className: "editor-container" }, userVersion !== "free" && /* @__PURE__ */ import_react24.default.createElement("div", { className: "editor-toolbar" }, /* @__PURE__ */ import_react24.default.createElement(
17124
17259
  "button",
17125
17260
  {
17126
17261
  type: "button",
@@ -17129,7 +17264,7 @@ function EditorContent({ apiKey }) {
17129
17264
  className: "editor-save-btn"
17130
17265
  },
17131
17266
  "Save Version"
17132
- ), /* @__PURE__ */ import_react22.default.createElement("div", { className: "editor-versions-wrapper" }, versions.length === 0 ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "editor-no-versions" }, "No saved versions") : versions.map((_, idx) => /* @__PURE__ */ import_react22.default.createElement(
17267
+ ), /* @__PURE__ */ import_react24.default.createElement("div", { className: "editor-versions-wrapper" }, versions.length === 0 ? /* @__PURE__ */ import_react24.default.createElement("span", { className: "editor-no-versions" }, "No saved versions") : versions.map((_, idx) => /* @__PURE__ */ import_react24.default.createElement(
17133
17268
  "button",
17134
17269
  {
17135
17270
  key: idx,
@@ -17139,21 +17274,21 @@ function EditorContent({ apiKey }) {
17139
17274
  title: `Restore Version ${idx + 1}`
17140
17275
  },
17141
17276
  `V${idx + 1}`
17142
- )))), editor && userVersion && /* @__PURE__ */ import_react22.default.createElement(
17277
+ )))), editor && userVersion && /* @__PURE__ */ import_react24.default.createElement(
17143
17278
  TetronsToolbar,
17144
17279
  {
17145
17280
  editor,
17146
17281
  version: userVersion,
17147
17282
  addOns: enabledAddOns
17148
17283
  }
17149
- ), /* @__PURE__ */ import_react22.default.createElement(
17284
+ ), /* @__PURE__ */ import_react24.default.createElement(
17150
17285
  "div",
17151
17286
  {
17152
17287
  ref: wrapperRef,
17153
17288
  className: "editor-content-wrapper",
17154
17289
  onClick: handleEditorClick
17155
17290
  },
17156
- editor ? /* @__PURE__ */ import_react22.default.createElement(import_react22.default.Fragment, null, /* @__PURE__ */ import_react22.default.createElement(import_react23.EditorContent, { editor }), /* @__PURE__ */ import_react22.default.createElement(TableContextMenu, { editor })) : /* @__PURE__ */ import_react22.default.createElement("div", { className: "editor-loading" }, "Loading editor...")
17291
+ editor ? /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement(import_react25.EditorContent, { editor }), /* @__PURE__ */ import_react24.default.createElement(TableContextMenu, { editor })) : /* @__PURE__ */ import_react24.default.createElement("div", { className: "editor-loading" }, "Loading editor...")
17157
17292
  ));
17158
17293
  }
17159
17294
 
package/dist/index.mjs CHANGED
@@ -67,6 +67,106 @@ var init_MathModal = __esm({
67
67
  }
68
68
  });
69
69
 
70
+ // src/components/tetrons/toolbar/CodeEditorModal.js
71
+ var CodeEditorModal_exports = {};
72
+ __export(CodeEditorModal_exports, {
73
+ default: () => CodeEditorModal_default
74
+ });
75
+ import React14, { useState as useState8 } from "react";
76
+ import Editor from "@monaco-editor/react";
77
+ var CodeEditorModal, CodeEditorModal_default;
78
+ var init_CodeEditorModal = __esm({
79
+ "src/components/tetrons/toolbar/CodeEditorModal.js"() {
80
+ "use strict";
81
+ "use client";
82
+ CodeEditorModal = ({
83
+ isOpen,
84
+ onClose,
85
+ onSubmitCode,
86
+ onSubmitCodeWithOutput
87
+ }) => {
88
+ const [language, setLanguage] = useState8("javascript");
89
+ const [code, setCode] = useState8("// Write your code here");
90
+ const [output, setOutput] = useState8("");
91
+ const [loading, setLoading] = useState8(false);
92
+ const runCode = async () => {
93
+ setLoading(true);
94
+ try {
95
+ const res = await fetch("/api/execute", {
96
+ method: "POST",
97
+ headers: { "Content-Type": "application/json" },
98
+ body: JSON.stringify({ language, code })
99
+ });
100
+ const data = await res.json();
101
+ let result = "";
102
+ if (data.stderr) result += `Error:
103
+ ${data.stderr}
104
+ `;
105
+ if (data.stdout) result += data.stdout;
106
+ if (!data.stdout && !data.stderr) result = "No output";
107
+ setOutput(result);
108
+ } catch (err) {
109
+ console.log(err.message);
110
+ setOutput("Error running code");
111
+ }
112
+ setLoading(false);
113
+ };
114
+ const handleSubmitCode = () => {
115
+ if (onSubmitCode) {
116
+ onSubmitCode(code);
117
+ }
118
+ onClose();
119
+ };
120
+ const handleSubmitCodeWithOutput = () => {
121
+ if (onSubmitCodeWithOutput) {
122
+ onSubmitCodeWithOutput({ code, output });
123
+ }
124
+ onClose();
125
+ };
126
+ if (!isOpen) return null;
127
+ return /* @__PURE__ */ React14.createElement("div", { className: "code-modal-overlay" }, /* @__PURE__ */ React14.createElement("div", { className: "code-modal-content" }, /* @__PURE__ */ React14.createElement("div", { className: "code-modal-header" }, /* @__PURE__ */ React14.createElement("h2", null, "Run Code"), /* @__PURE__ */ React14.createElement("button", { onClick: onClose, className: "code-close-btn" }, "\xD7")), /* @__PURE__ */ React14.createElement("div", { className: "code-modal-controls" }, /* @__PURE__ */ React14.createElement("label", { htmlFor: "language" }, "Language:"), /* @__PURE__ */ React14.createElement(
128
+ "select",
129
+ {
130
+ id: "language",
131
+ value: language,
132
+ onChange: (e) => setLanguage(e.target.value)
133
+ },
134
+ /* @__PURE__ */ React14.createElement("option", { value: "javascript" }, "JavaScript"),
135
+ /* @__PURE__ */ React14.createElement("option", { value: "python" }, "Python"),
136
+ /* @__PURE__ */ React14.createElement("option", { value: "cpp" }, "C++"),
137
+ /* @__PURE__ */ React14.createElement("option", { value: "java" }, "Java"),
138
+ /* @__PURE__ */ React14.createElement("option", { value: "typescript" }, "TypeScript")
139
+ ), /* @__PURE__ */ React14.createElement("button", { className: "run-code", onClick: runCode, disabled: loading }, loading ? "Running..." : "Run")), /* @__PURE__ */ React14.createElement(
140
+ Editor,
141
+ {
142
+ height: "50vh",
143
+ theme: "vs-dark",
144
+ language,
145
+ value: code,
146
+ onChange: (v) => setCode(v ?? "")
147
+ }
148
+ ), /* @__PURE__ */ React14.createElement("div", { className: "code-output" }, /* @__PURE__ */ React14.createElement("strong", null, "Output:"), /* @__PURE__ */ React14.createElement("pre", null, output.trim() === "" ? "\u2190 Click Run to see output here" : output)), /* @__PURE__ */ React14.createElement("div", { className: "code-submit-buttons-container" }, /* @__PURE__ */ React14.createElement(
149
+ "button",
150
+ {
151
+ className: "code-submit-buttons",
152
+ onClick: handleSubmitCode,
153
+ disabled: loading || !code
154
+ },
155
+ "Submit Code Snippet Only"
156
+ ), /* @__PURE__ */ React14.createElement(
157
+ "button",
158
+ {
159
+ className: "code-submit-buttons",
160
+ onClick: handleSubmitCodeWithOutput,
161
+ disabled: loading || !code
162
+ },
163
+ "Submit Code Snippet With Output"
164
+ ))));
165
+ };
166
+ CodeEditorModal_default = CodeEditorModal;
167
+ }
168
+ });
169
+
70
170
  // src/components/tetrons/extensions/MathExtension.ts
71
171
  import { Node, mergeAttributes } from "@tiptap/core";
72
172
  import katex from "katex";
@@ -124,7 +224,7 @@ var MathInline = Node.create({
124
224
  });
125
225
 
126
226
  // src/components/tetrons/EditorContent.tsx
127
- import React16, { useEffect as useEffect9, useRef as useRef7, useState as useState10 } from "react";
227
+ import React17, { useEffect as useEffect9, useRef as useRef7, useState as useState11 } from "react";
128
228
  import { useEditor, EditorContent as TiptapEditorContent } from "@tiptap/react";
129
229
 
130
230
  // node_modules/@tiptap/extension-document/dist/index.js
@@ -15805,7 +15905,7 @@ function TableContextMenu({ editor }) {
15805
15905
  }
15806
15906
 
15807
15907
  // src/components/tetrons/toolbar/TetronsToolbar.tsx
15808
- import React15, { useEffect as useEffect8, useState as useState9 } from "react";
15908
+ import React16, { useEffect as useEffect8, useState as useState10 } from "react";
15809
15909
 
15810
15910
  // src/components/tetrons/toolbar/ActionGroup.tsx
15811
15911
  import React6, { useEffect as useEffect5, useRef as useRef3, useState as useState4 } from "react";
@@ -16907,17 +17007,21 @@ function AiGroup({ editor }) {
16907
17007
  }
16908
17008
 
16909
17009
  // src/components/tetrons/toolbar/AddOnGroup.tsx
16910
- import React14, { useState as useState8 } from "react";
16911
- import { FaCode, FaSuperscript } from "react-icons/fa";
17010
+ import React15, { useState as useState9 } from "react";
17011
+ import { SquareRadical, MessageSquareCode } from "lucide-react";
16912
17012
  import dynamic from "next/dynamic";
16913
17013
  import "katex/dist/katex.min.css";
16914
17014
  var MathModal2 = dynamic(() => Promise.resolve().then(() => (init_MathModal(), MathModal_exports)), { ssr: false });
17015
+ var CodeEditorModal2 = dynamic(() => Promise.resolve().then(() => (init_CodeEditorModal(), CodeEditorModal_exports)), {
17016
+ ssr: false
17017
+ });
16915
17018
  var AddOnGroup = ({ editor }) => {
16916
- const [isModalOpen, setModalOpen] = useState8(false);
16917
- const [latexValue, setLatexValue] = useState8("");
17019
+ const [isModalOpen, setModalOpen] = useState9(false);
17020
+ const [latexValue, setLatexValue] = useState9("");
17021
+ const [isCodeModalOpen, setCodeModalOpen] = useState9(false);
16918
17022
  if (!editor) return null;
16919
17023
  const insertCodeBlock = () => {
16920
- editor.chain().focus().toggleCodeBlock().run();
17024
+ setCodeModalOpen(true);
16921
17025
  };
16922
17026
  const handleMathInsert = (latex) => {
16923
17027
  editor.chain().focus().insertContent({
@@ -16927,25 +17031,48 @@ var AddOnGroup = ({ editor }) => {
16927
17031
  setModalOpen(false);
16928
17032
  setLatexValue("");
16929
17033
  };
16930
- return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement("div", { className: "group flex gap-2 items-center" }, /* @__PURE__ */ React14.createElement(
17034
+ const handleSubmitCode = (code) => {
17035
+ editor.chain().focus().insertContent({
17036
+ type: "codeBlock",
17037
+ content: [{ type: "text", text: code }]
17038
+ }).run();
17039
+ setCodeModalOpen(false);
17040
+ };
17041
+ const handleSubmitCodeWithOutput = ({
17042
+ code,
17043
+ output
17044
+ }) => {
17045
+ editor.chain().focus().insertContent({
17046
+ type: "codeBlock",
17047
+ content: [{ type: "text", text: code }]
17048
+ }).insertContent({
17049
+ type: "paragraph",
17050
+ content: [{ type: "text", text: "Output:" }]
17051
+ }).insertContent({
17052
+ type: "codeBlock",
17053
+ content: [{ type: "text", text: output }]
17054
+ }).run();
17055
+ setCodeModalOpen(false);
17056
+ };
17057
+ return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("div", { className: "group flex gap-2 items-center" }, /* @__PURE__ */ React15.createElement(
16931
17058
  "button",
16932
17059
  {
16933
17060
  type: "button",
16934
17061
  onClick: insertCodeBlock,
16935
- className: "icon-btn",
16936
- title: "Insert Code Block"
17062
+ className: "addon-btn",
17063
+ title: "Open Code Editor"
16937
17064
  },
16938
- /* @__PURE__ */ React14.createElement(FaCode, { size: 18 })
16939
- ), /* @__PURE__ */ React14.createElement(
17065
+ /* @__PURE__ */ React15.createElement(MessageSquareCode, { size: 18 })
17066
+ ), /* @__PURE__ */ React15.createElement(
16940
17067
  "button",
16941
17068
  {
16942
17069
  type: "button",
16943
17070
  onClick: () => setModalOpen(true),
16944
- className: "icon-btn",
17071
+ className: "addon-btn",
16945
17072
  title: "Insert Math Equation"
16946
17073
  },
16947
- /* @__PURE__ */ React14.createElement(FaSuperscript, { size: 18 })
16948
- )), /* @__PURE__ */ React14.createElement(
17074
+ /* @__PURE__ */ React15.createElement(SquareRadical, { size: 18 })
17075
+ )), /* @__PURE__ */ React15.createElement(
16949
17076
  MathModal2,
16950
17077
  {
16951
17078
  isOpen: isModalOpen,
@@ -16954,6 +17081,14 @@ var AddOnGroup = ({ editor }) => {
16954
17081
  value: latexValue,
16955
17082
  setValue: setLatexValue
16956
17083
  }
17084
+ ), /* @__PURE__ */ React15.createElement(
17085
+ CodeEditorModal2,
17086
+ {
17087
+ isOpen: isCodeModalOpen,
17088
+ onClose: () => setCodeModalOpen(false),
17089
+ onSubmitCode: handleSubmitCode,
17090
+ onSubmitCodeWithOutput: handleSubmitCodeWithOutput
17091
+ }
16957
17092
  ));
16958
17093
  };
16959
17094
  var AddOnGroup_default = AddOnGroup;
@@ -16964,7 +17099,7 @@ function TetronsToolbar({
16964
17099
  version,
16965
17100
  addOns = []
16966
17101
  }) {
16967
- const [autoSave, setAutoSave] = useState9(false);
17102
+ const [autoSave, setAutoSave] = useState10(false);
16968
17103
  useEffect8(() => {
16969
17104
  if (!editor) return;
16970
17105
  const handleUpdate = () => {
@@ -16981,7 +17116,7 @@ function TetronsToolbar({
16981
17116
  editor.off("update", handleUpdate);
16982
17117
  };
16983
17118
  }, [autoSave, editor]);
16984
- return /* @__PURE__ */ React15.createElement("div", { className: "tetrons-toolbar" }, version !== "free" && /* @__PURE__ */ React15.createElement("div", { className: "group" }, /* @__PURE__ */ React15.createElement(
17119
+ return /* @__PURE__ */ React16.createElement("div", { className: "tetrons-toolbar" }, version !== "free" && /* @__PURE__ */ React16.createElement("div", { className: "group" }, /* @__PURE__ */ React16.createElement(
16985
17120
  "input",
16986
17121
  {
16987
17122
  type: "checkbox",
@@ -16989,7 +17124,7 @@ function TetronsToolbar({
16989
17124
  checked: autoSave,
16990
17125
  onChange: (e) => setAutoSave(e.target.checked)
16991
17126
  }
16992
- ), /* @__PURE__ */ React15.createElement("label", { htmlFor: "autoSave" }, "Auto Save")), ["pro", "premium", "platinum"].includes(version) && /* @__PURE__ */ React15.createElement(FileGroup, { editor }), /* @__PURE__ */ React15.createElement(ClipboardGroup, { editor }), /* @__PURE__ */ React15.createElement(FontStyleGroup, { editor }), /* @__PURE__ */ React15.createElement(ListAlignGroup, { editor }), ["premium", "platinum"].includes(version) && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(InsertGroup, { editor }), /* @__PURE__ */ React15.createElement(ActionGroup, { editor })), version === "platinum" && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(MiscGroup, { editor }), /* @__PURE__ */ React15.createElement(AiGroup, { editor })), addOns.length > 0 && /* @__PURE__ */ React15.createElement(AddOnGroup_default, { editor }));
17127
+ ), /* @__PURE__ */ React16.createElement("label", { htmlFor: "autoSave" }, "Auto Save")), ["pro", "premium", "platinum"].includes(version) && /* @__PURE__ */ React16.createElement(FileGroup, { editor }), /* @__PURE__ */ React16.createElement(ClipboardGroup, { editor }), /* @__PURE__ */ React16.createElement(FontStyleGroup, { editor }), /* @__PURE__ */ React16.createElement(ListAlignGroup, { editor }), ["premium", "platinum"].includes(version) && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(InsertGroup, { editor }), /* @__PURE__ */ React16.createElement(ActionGroup, { editor })), version === "platinum" && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(MiscGroup, { editor }), /* @__PURE__ */ React16.createElement(AiGroup, { editor })), addOns.length > 0 && /* @__PURE__ */ React16.createElement(AddOnGroup_default, { editor }));
16993
17128
  }
16994
17129
 
16995
17130
  // src/components/tetrons/EditorContent.tsx
@@ -16998,11 +17133,11 @@ lowlight.register("js", javascript);
16998
17133
  lowlight.register("ts", typescript);
16999
17134
  function EditorContent({ apiKey }) {
17000
17135
  const typo = useTypo();
17001
- const [isValid, setIsValid] = useState10(null);
17002
- const [error, setError] = useState10(null);
17003
- const [versions, setVersions] = useState10([]);
17004
- const [userVersion, setUserVersion] = useState10(null);
17005
- const [currentVersionIndex, setCurrentVersionIndex] = useState10(
17136
+ const [isValid, setIsValid] = useState11(null);
17137
+ const [error, setError] = useState11(null);
17138
+ const [versions, setVersions] = useState11([]);
17139
+ const [userVersion, setUserVersion] = useState11(null);
17140
+ const [currentVersionIndex, setCurrentVersionIndex] = useState11(
17006
17141
  null
17007
17142
  );
17008
17143
  const wrapperRef = useRef7(null);
@@ -17115,13 +17250,13 @@ function EditorContent({ apiKey }) {
17115
17250
  }
17116
17251
  };
17117
17252
  if (isValid === false) {
17118
- return /* @__PURE__ */ React16.createElement("div", { className: "editor-error" }, "\u26A0\uFE0F ", error);
17253
+ return /* @__PURE__ */ React17.createElement("div", { className: "editor-error" }, "\u26A0\uFE0F ", error);
17119
17254
  }
17120
17255
  if (isValid === null) {
17121
- return /* @__PURE__ */ React16.createElement("div", { className: "editor-loading" }, "\u{1F50D} Validating license...");
17256
+ return /* @__PURE__ */ React17.createElement("div", { className: "editor-loading" }, "\u{1F50D} Validating license...");
17122
17257
  }
17123
17258
  if (!typo) {
17124
- return /* @__PURE__ */ React16.createElement("div", { className: "editor-loading" }, "\u{1F4D6} Loading dictionary...");
17259
+ return /* @__PURE__ */ React17.createElement("div", { className: "editor-loading" }, "\u{1F4D6} Loading dictionary...");
17125
17260
  }
17126
17261
  const versionAddOnsMap = {
17127
17262
  free: [],
@@ -17130,7 +17265,7 @@ function EditorContent({ apiKey }) {
17130
17265
  platinum: ["code", "math"]
17131
17266
  };
17132
17267
  const enabledAddOns = userVersion ? versionAddOnsMap[userVersion] || [] : [];
17133
- return /* @__PURE__ */ React16.createElement("div", { className: "editor-container" }, userVersion !== "free" && /* @__PURE__ */ React16.createElement("div", { className: "editor-toolbar" }, /* @__PURE__ */ React16.createElement(
17268
+ return /* @__PURE__ */ React17.createElement("div", { className: "editor-container" }, userVersion !== "free" && /* @__PURE__ */ React17.createElement("div", { className: "editor-toolbar" }, /* @__PURE__ */ React17.createElement(
17134
17269
  "button",
17135
17270
  {
17136
17271
  type: "button",
@@ -17139,7 +17274,7 @@ function EditorContent({ apiKey }) {
17139
17274
  className: "editor-save-btn"
17140
17275
  },
17141
17276
  "Save Version"
17142
- ), /* @__PURE__ */ React16.createElement("div", { className: "editor-versions-wrapper" }, versions.length === 0 ? /* @__PURE__ */ React16.createElement("span", { className: "editor-no-versions" }, "No saved versions") : versions.map((_, idx) => /* @__PURE__ */ React16.createElement(
17277
+ ), /* @__PURE__ */ React17.createElement("div", { className: "editor-versions-wrapper" }, versions.length === 0 ? /* @__PURE__ */ React17.createElement("span", { className: "editor-no-versions" }, "No saved versions") : versions.map((_, idx) => /* @__PURE__ */ React17.createElement(
17143
17278
  "button",
17144
17279
  {
17145
17280
  key: idx,
@@ -17149,21 +17284,21 @@ function EditorContent({ apiKey }) {
17149
17284
  title: `Restore Version ${idx + 1}`
17150
17285
  },
17151
17286
  `V${idx + 1}`
17152
- )))), editor && userVersion && /* @__PURE__ */ React16.createElement(
17287
+ )))), editor && userVersion && /* @__PURE__ */ React17.createElement(
17153
17288
  TetronsToolbar,
17154
17289
  {
17155
17290
  editor,
17156
17291
  version: userVersion,
17157
17292
  addOns: enabledAddOns
17158
17293
  }
17159
- ), /* @__PURE__ */ React16.createElement(
17294
+ ), /* @__PURE__ */ React17.createElement(
17160
17295
  "div",
17161
17296
  {
17162
17297
  ref: wrapperRef,
17163
17298
  className: "editor-content-wrapper",
17164
17299
  onClick: handleEditorClick
17165
17300
  },
17166
- editor ? /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(TiptapEditorContent, { editor }), /* @__PURE__ */ React16.createElement(TableContextMenu, { editor })) : /* @__PURE__ */ React16.createElement("div", { className: "editor-loading" }, "Loading editor...")
17301
+ editor ? /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(TiptapEditorContent, { editor }), /* @__PURE__ */ React17.createElement(TableContextMenu, { editor })) : /* @__PURE__ */ React17.createElement("div", { className: "editor-loading" }, "Loading editor...")
17167
17302
  ));
17168
17303
  }
17169
17304
 
@@ -570,3 +570,122 @@
570
570
  opacity: 0.5;
571
571
  cursor: not-allowed;
572
572
  }
573
+
574
+ .code-modal-overlay {
575
+ position: fixed;
576
+ top: 0;
577
+ left: 0;
578
+ width: 100%;
579
+ height: 100%;
580
+ background: rgba(0, 0, 0, 0.6);
581
+ display: flex;
582
+ justify-content: center;
583
+ align-items: center;
584
+ z-index: 9999;
585
+ }
586
+
587
+ .code-modal-content {
588
+ background: white;
589
+ width: 90%;
590
+ max-width: 800px;
591
+ border-radius: 8px;
592
+ padding: 20px;
593
+ box-shadow: 0 0 10px #00000033;
594
+ display: flex;
595
+ flex-direction: column;
596
+ }
597
+
598
+ .code-modal-header {
599
+ display: flex;
600
+ justify-content: space-between;
601
+ align-items: center;
602
+ margin-bottom: 1rem;
603
+ }
604
+
605
+ .code-close-btn {
606
+ font-size: 24px;
607
+ border: none;
608
+ background: transparent;
609
+ cursor: pointer;
610
+ }
611
+
612
+ .code-modal-controls {
613
+ display: flex;
614
+ align-items: center;
615
+ gap: 10px;
616
+ margin-bottom: 10px;
617
+ }
618
+
619
+ .code-modal-controls select,
620
+ .code-modal-controls button {
621
+ padding: 6px 12px;
622
+ font-size: 14px;
623
+ }
624
+
625
+ .code-output {
626
+ background: #f2f2f2;
627
+ padding: 12px;
628
+ border-radius: 4px;
629
+ margin-top: 15px;
630
+ height: 150px;
631
+ overflow-y: auto;
632
+ white-space: pre-wrap;
633
+ }
634
+
635
+ .addon-btn {
636
+ padding: 8px 16px;
637
+ background: linear-gradient(to right, #7f00ff, #4f46e5);
638
+ color: white;
639
+ font-weight: bold;
640
+ border: none;
641
+ border-radius: 6px;
642
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
643
+ cursor: pointer;
644
+ transition: background 0.3s ease, transform 0.2s ease;
645
+ }
646
+
647
+ .addon-btn:hover {
648
+ background: linear-gradient(to right, #6b00d6, #4338ca);
649
+ transform: translateY(-1px);
650
+ }
651
+
652
+ .addon-btn:active {
653
+ transform: scale(0.97);
654
+ }
655
+
656
+ .run-code{
657
+ margin-left: auto;
658
+ background-color: black;
659
+ color: white;
660
+ padding: 6px 16px;
661
+ border: none;
662
+ border-radius: 4px;
663
+ cursor: pointer;
664
+ font-size: 14px;
665
+ }
666
+
667
+ .run-code:disabled {
668
+ opacity: 0.6;
669
+ cursor: not-allowed;
670
+ }
671
+
672
+ .code-submit-buttons-container{
673
+ display: flex;
674
+ justify-content: space-between;
675
+ gap: 10px;
676
+ }
677
+
678
+ .code-submit-buttons{
679
+ background-color: black;
680
+ color: white;
681
+ padding: 16px;
682
+ border: none;
683
+ border-radius: 4px;
684
+ cursor: pointer;
685
+ font-size: 14px;
686
+ }
687
+
688
+ .code-submit-buttons:disabled {
689
+ opacity: 0.6;
690
+ cursor: not-allowed;
691
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tetrons",
3
- "version": "2.3.77",
3
+ "version": "2.3.79",
4
4
  "description": "A Next.js project written in TypeScript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -13,6 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@emoji-mart/react": "1.1.1",
16
+ "@monaco-editor/react": "^4.7.0",
16
17
  "@tiptap/core": "2.24.1",
17
18
  "@tiptap/extension-code-block-lowlight": "2.24.1",
18
19
  "@tiptap/extension-color": "2.24.1",
@@ -37,11 +38,15 @@
37
38
  "html2pdf.js": "0.10.3",
38
39
  "katex": "^0.16.22",
39
40
  "lowlight": "3.3.0",
41
+ "lucide-react": "^0.537.0",
40
42
  "mime": "4.0.7",
41
- "mongoose": "8.16.0",
43
+ "mongoose": "^8.17.1",
42
44
  "openai": "^4.40.0",
45
+ "prettier": "^3.6.2",
46
+ "prettier-plugin-jsdoc": "^1.3.3",
43
47
  "react-icons": "5.5.0",
44
- "typo-js": "1.2.5"
48
+ "typo-js": "1.2.5",
49
+ "uuid": "^11.1.0"
45
50
  },
46
51
  "peerDependencies": {
47
52
  "next": "15.3.2",
@@ -56,7 +61,7 @@
56
61
  "@types/react-dom": "^18.2.7",
57
62
  "autoprefixer": "10.4.21",
58
63
  "copyfiles": "2.4.1",
59
- "eslint": "9.0.0",
64
+ "eslint": "^8.57.0",
60
65
  "eslint-config-next": "15.3.2",
61
66
  "tsup": "8.5.0",
62
67
  "typescript": "5.4.5"
@@ -102,6 +107,10 @@
102
107
  "./app/api/validate/route": {
103
108
  "import": "./dist/app/api/validate/route.mjs",
104
109
  "require": "./dist/app/api/validate/route.cjs"
110
+ },
111
+ "./app/api/execute/route": {
112
+ "import": "./dist/app/api/execute/route.mjs",
113
+ "require": "./dist/app/api/execute/route.cjs"
105
114
  }
106
115
  },
107
116
  "files": [
@@ -114,4 +123,4 @@
114
123
  "url": "https://github.com/Finapsys/Tetrons/issues"
115
124
  },
116
125
  "homepage": "https://github.com/Finapsys/Tetrons#readme"
117
- }
126
+ }