diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml deleted file mode 100644 index 0854308..0000000 --- a/.github/workflows/label.yml +++ /dev/null @@ -1,23 +0,0 @@ -# This workflow will triage pull requests and apply a label based on the -# paths that are modified in the pull request. -# -# To use this workflow, you will need to set up a .github/labeler.yml -# file with configuration. For more information, see: -# https://github.com/actions/labeler - -name: Labeler -on: [pull_request_target] - -jobs: - label: - - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - - steps: - - uses: actions/labeler@v4 - with: - repo-token: "${{ secrets.GH_TOKEN}}" - configuration-path: labeler.yml diff --git a/convex/_generated/api.d.ts b/convex/_generated/api.d.ts index f16871a..5c88e74 100644 --- a/convex/_generated/api.d.ts +++ b/convex/_generated/api.d.ts @@ -13,6 +13,7 @@ import type { FilterApi, FunctionReference, } from "convex/server"; +import type * as codeExecutions from "../codeExecutions.js"; import type * as http from "../http.js"; import type * as users from "../users.js"; @@ -25,6 +26,7 @@ import type * as users from "../users.js"; * ``` */ declare const fullApi: ApiFromModules<{ + codeExecutions: typeof codeExecutions; http: typeof http; users: typeof users; }>; diff --git a/convex/codeExecutions.ts b/convex/codeExecutions.ts new file mode 100644 index 0000000..4e3f371 --- /dev/null +++ b/convex/codeExecutions.ts @@ -0,0 +1,35 @@ +import { ConvexError, v } from "convex/values"; +import { mutation } from "./_generated/server"; + +export const saveCodeExecution = mutation({ + args: { + language: v.string(), + code: v.string(), + output: v.optional(v.string()), + error: v.optional(v.string()), + }, + + handler: async (ctx, args) => { + const identity = await ctx.auth.getUserIdentity(); + if (!identity) { + throw new ConvexError("User not authenticated"); + } + + const user = await ctx.db + .query("users") + .withIndex("by_user_id") + .filter((q) => q.eq(q.field("userId"), identity.subject)) + .first(); + + if (!user?.isPro && args.language !== "javascript") { + throw new ConvexError( + "Only Pro users can execute code in languages other than JavaScript" + ); + } + + await ctx.db.insert("codeExecutions", { + ...args, + userId: identity.subject, + }); + }, +}); diff --git a/src/app/(home)/_components/RunButton.tsx b/src/app/(home)/_components/RunButton.tsx index 4444920..e7cba4d 100644 --- a/src/app/(home)/_components/RunButton.tsx +++ b/src/app/(home)/_components/RunButton.tsx @@ -1,9 +1,73 @@ -import React from 'react' +"use client"; + +import { + getExecutionResult, + useCodeEditorState, +} from "@/store/useCodeEditorStore"; +import { useUser } from "@clerk/nextjs"; +import { Loader2, Play } from "lucide-react"; +import React from "react"; +import { motion } from "framer-motion"; +import { useMutation } from "convex/react"; +import { api } from "../../../../convex/_generated/api"; function RunButton() { + const { user } = useUser(); + const { runCode, language, isRunning } = useCodeEditorState(); + const saveCodeExecution = useMutation(api.codeExecutions.saveCodeExecution); + const handleRun = async () => { + await runCode(); + const result = getExecutionResult(); + + if (user && result) { + //convex saving + await saveCodeExecution({ + language, + code: result.code, + output: result.output || undefined, + error: result.error || undefined, + }); + } + }; + return ( -