diff --git a/src/app/(app)/problems/[id]/layout.tsx b/src/app/(app)/problems/[id]/layout.tsx index 98c1de3..71b6454 100644 --- a/src/app/(app)/problems/[id]/layout.tsx +++ b/src/app/(app)/problems/[id]/layout.tsx @@ -1,8 +1,12 @@ import prisma from "@/lib/prisma"; +import { + ResizableHandle, + ResizablePanel, + ResizablePanelGroup, +} from "@/components/ui/resizable"; import { notFound } from "next/navigation"; +import { ProblemStoreProvider } from "@/providers/problem-store-provider"; import { PlaygroundHeader } from "@/components/features/playground/header"; -import { ProblemEditorProvider } from "@/providers/problem-editor-provider"; -import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable"; interface PlaygroundLayoutProps { params: Promise<{ id: string }>; @@ -38,7 +42,7 @@ export default async function PlaygroundLayout({ return (
- - +
); } diff --git a/src/components/features/playground/workspace/editor/components/copy-button.tsx b/src/components/features/playground/workspace/editor/components/copy-button.tsx index 91de795..000d5e6 100644 --- a/src/components/features/playground/workspace/editor/components/copy-button.tsx +++ b/src/components/features/playground/workspace/editor/components/copy-button.tsx @@ -10,10 +10,10 @@ import { cn } from "@/lib/utils"; import { useState } from "react"; import { Check, Copy } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { useProblemEditor } from "@/hooks/use-problem-editor"; +import { useProblem } from "@/hooks/use-problem"; export function CopyButton() { - const { editor } = useProblemEditor(); + const { editor } = useProblem(); const [copied, setCopied] = useState(false); const handleCopy = async () => { diff --git a/src/components/features/playground/workspace/editor/components/footer.tsx b/src/components/features/playground/workspace/editor/components/footer.tsx index a95606c..d4836d4 100644 --- a/src/components/features/playground/workspace/editor/components/footer.tsx +++ b/src/components/features/playground/workspace/editor/components/footer.tsx @@ -2,7 +2,7 @@ import { cn } from "@/lib/utils"; import { useEffect, useState } from "react"; -import { useProblemEditor } from "@/hooks/use-problem-editor"; +import { useProblem } from "@/hooks/use-problem"; interface WorkspaceEditorFooterProps { className?: string; @@ -12,7 +12,7 @@ export function WorkspaceEditorFooter({ className, ...props }: WorkspaceEditorFooterProps) { - const { editor } = useProblemEditor(); + const { editor } = useProblem(); const [position, setPosition] = useState<{ lineNumber: number; column: number } | null>(null); useEffect(() => { diff --git a/src/components/features/playground/workspace/editor/components/format-button.tsx b/src/components/features/playground/workspace/editor/components/format-button.tsx index 0b2b7fb..ddcc687 100644 --- a/src/components/features/playground/workspace/editor/components/format-button.tsx +++ b/src/components/features/playground/workspace/editor/components/format-button.tsx @@ -8,10 +8,10 @@ import { } from "@/components/ui/tooltip"; import { Paintbrush } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { useProblemEditor } from "@/hooks/use-problem-editor"; +import { useProblem } from "@/hooks/use-problem"; export function FormatButton() { - const { editor } = useProblemEditor(); + const { editor } = useProblem(); return ( diff --git a/src/components/features/playground/workspace/editor/components/language-selector.tsx b/src/components/features/playground/workspace/editor/components/language-selector.tsx index fae25e4..c7f5f98 100644 --- a/src/components/features/playground/workspace/editor/components/language-selector.tsx +++ b/src/components/features/playground/workspace/editor/components/language-selector.tsx @@ -8,14 +8,14 @@ import { SelectValue, } from "@/components/ui/select"; import { Loading } from "@/components/loading"; -import { useProblemEditor } from "@/hooks/use-problem-editor"; +import { useProblem } from "@/hooks/use-problem"; import { EditorLanguageIcons } from "@/config/editor-language-icons"; export function LanguageSelector() { - const { hydrated, currentLang, changeLang, editorLanguageConfigs } = useProblemEditor(); + const { hydrated, currentLang, changeLang, editorLanguageConfigs } = useProblem(); if (!hydrated) { - return + return ; } return ( diff --git a/src/components/features/playground/workspace/editor/components/redo-button.tsx b/src/components/features/playground/workspace/editor/components/redo-button.tsx index c4c6074..c914f5e 100644 --- a/src/components/features/playground/workspace/editor/components/redo-button.tsx +++ b/src/components/features/playground/workspace/editor/components/redo-button.tsx @@ -8,10 +8,10 @@ import { } from "@/components/ui/tooltip"; import { Redo2 } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { useProblemEditor } from "@/hooks/use-problem-editor"; +import { useProblem } from "@/hooks/use-problem"; export function RedoButton() { - const { editor } = useProblemEditor(); + const { editor } = useProblem(); return ( diff --git a/src/components/features/playground/workspace/editor/components/reset-button.tsx b/src/components/features/playground/workspace/editor/components/reset-button.tsx index 8f67ae5..9c56776 100644 --- a/src/components/features/playground/workspace/editor/components/reset-button.tsx +++ b/src/components/features/playground/workspace/editor/components/reset-button.tsx @@ -8,10 +8,10 @@ import { } from "@/components/ui/tooltip"; import { RotateCcw } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { useProblemEditor } from "@/hooks/use-problem-editor"; +import { useProblem } from "@/hooks/use-problem"; export function ResetButton() { - const { editor, currentTemplate } = useProblemEditor(); + const { editor, currentTemplate } = useProblem(); const handleReset = () => { if (editor) { diff --git a/src/components/features/playground/workspace/editor/components/undo-button.tsx b/src/components/features/playground/workspace/editor/components/undo-button.tsx index c6103fc..60dfffe 100644 --- a/src/components/features/playground/workspace/editor/components/undo-button.tsx +++ b/src/components/features/playground/workspace/editor/components/undo-button.tsx @@ -8,10 +8,10 @@ import { } from "@/components/ui/tooltip"; import { Undo2 } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { useProblemEditor } from "@/hooks/use-problem-editor"; +import { useProblem } from "@/hooks/use-problem"; export function UndoButton() { - const { editor } = useProblemEditor(); + const { editor } = useProblem(); return ( diff --git a/src/components/problem-editor.tsx b/src/components/problem-editor.tsx index a5da2ef..4a118bd 100644 --- a/src/components/problem-editor.tsx +++ b/src/components/problem-editor.tsx @@ -5,8 +5,8 @@ import { highlighter } from "@/lib/shiki"; import type { editor } from "monaco-editor"; import { Loading } from "@/components/loading"; import { shikiToMonaco } from "@shikijs/monaco"; +import { useProblem } from "@/hooks/use-problem"; import type { Monaco } from "@monaco-editor/react"; -import { useProblemEditor } from "@/hooks/use-problem-editor"; import { DefaultEditorOptionConfig } from "@/config/editor-option"; // Dynamically import Monaco Editor with SSR disabled @@ -25,8 +25,7 @@ const Editor = dynamic( ); export function CodeEditor() { - - const { setEditor, currentLang, currentPath, currentTheme, currentValue, changeValue } = useProblemEditor(); + const { setEditor, currentLang, currentPath, currentTheme, currentValue, changeValue } = useProblem(); const handleBeforeMount = (monaco: Monaco) => { shikiToMonaco(highlighter, monaco); @@ -34,7 +33,7 @@ export function CodeEditor() { const handleOnMount = (editor: editor.IStandaloneCodeEditor) => { setEditor(editor); - } + }; const handleOnChange = (value: string | undefined) => { if (value === undefined) return; diff --git a/src/components/run-code.tsx b/src/components/run-code.tsx index 03d2ec6..bd9ce42 100644 --- a/src/components/run-code.tsx +++ b/src/components/run-code.tsx @@ -1,13 +1,18 @@ "use client"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; import { useState } from "react"; import { judge } from "@/app/actions/judge"; import { Button } from "@/components/ui/button"; +import { useProblem } from "@/hooks/use-problem"; import { LoaderCircleIcon, PlayIcon } from "lucide-react"; -import { useProblemEditor } from "@/hooks/use-problem-editor"; import { showExitCodeToast } from "@/lib/show-exit-code-toast"; -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; interface RunCodeProps { className?: string; @@ -17,7 +22,7 @@ export function RunCode({ className, ...props }: RunCodeProps) { - const { currentLang, editor } = useProblemEditor(); + const { currentLang, editor } = useProblem(); const [isLoading, setIsLoading] = useState(false); const handleJudge = async () => { diff --git a/src/hooks/use-problem-editor.ts b/src/hooks/use-problem.ts similarity index 70% rename from src/hooks/use-problem-editor.ts rename to src/hooks/use-problem.ts index daf1637..e86f601 100644 --- a/src/hooks/use-problem-editor.ts +++ b/src/hooks/use-problem.ts @@ -2,7 +2,7 @@ import { getPath } from "@/lib/utils"; import { EditorLanguage } from "@prisma/client"; import { useCallback, useEffect, useMemo } from "react"; import { useMonacoTheme } from "@/hooks/use-monaco-theme"; -import { useProblemEditorStore } from "@/providers/problem-editor-provider"; +import { useProblemStore } from "@/providers/problem-store-provider"; /** * Generates a localStorage key for storing the editor language of a problem. @@ -34,27 +34,29 @@ const getStoredProblemValue = ( language: EditorLanguage ) => localStorage.getItem(getProblemValueStorageKey(problemId, language)) ?? defaultValue; -export const useProblemEditor = () => { +export const useProblem = () => { const { currentTheme } = useMonacoTheme(); - - const hydrated = useProblemEditorStore((state) => state.hydrated); - const editor = useProblemEditorStore((state) => state.editor); - const globalLang = useProblemEditorStore((state) => state.globalLang); - const currentLang = useProblemEditorStore((state) => state.currentLang); - const currentValue = useProblemEditorStore((state) => state.currentValue); - const setEditor = useProblemEditorStore((state) => state.setEditor); - const setGlobalLang = useProblemEditorStore((state) => state.setGlobalLang); - const setCurrentLang = useProblemEditorStore((state) => state.setCurrentLang); - const setCurrentValue = useProblemEditorStore((state) => state.setCurrentValue); - const problemId = useProblemEditorStore((state) => state.problemId); - const templates = useProblemEditorStore((state) => state.templates); - const editorLanguageConfigs = useProblemEditorStore((state) => state.editorLanguageConfigs); - const languageServerConfigs = useProblemEditorStore((state) => state.languageServerConfigs); + const { + hydrated, + editor, + globalLang, + currentLang, + currentValue, + setEditor, + setGlobalLang, + setCurrentLang, + setCurrentValue, + problemId, + templates, + editorLanguageConfigs, + languageServerConfigs, + } = useProblemStore((state) => state); // Get the default template for the current language from the templates list - const currentTemplate = useMemo(() => { - return templates.find((t) => t.language === currentLang)?.template || ""; - }, [templates, currentLang]); + const currentTemplate = useMemo( + () => templates.find((t) => t.language === currentLang)?.template || "", + [templates, currentLang] + ); const currentEditorLanguageConfig = useMemo( () => editorLanguageConfigs.find((c) => c.language === currentLang), @@ -66,9 +68,10 @@ export const useProblemEditor = () => { [languageServerConfigs, currentLang] ); - const currentPath = useMemo(() => { - return currentEditorLanguageConfig ? getPath(currentEditorLanguageConfig) : ""; - }, [currentEditorLanguageConfig]); + const currentPath = useMemo( + () => (currentEditorLanguageConfig ? getPath(currentEditorLanguageConfig) : ""), + [currentEditorLanguageConfig] + ); // On initialization, load the stored language and corresponding code content useEffect(() => {