feat: button approach layout for task page in mobile
This commit is contained in:
parent
32e9451416
commit
f9a4afcc06
|
@ -1,4 +1,3 @@
|
||||||
import React from "react";
|
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
import {
|
import {
|
||||||
ResizableHandle,
|
ResizableHandle,
|
||||||
|
@ -8,16 +7,21 @@ import {
|
||||||
import markdownStyles from "@/styles/markdown-styles.module.css";
|
import markdownStyles from "@/styles/markdown-styles.module.css";
|
||||||
import { tutorialData } from "@/constants/tutorial-data";
|
import { tutorialData } from "@/constants/tutorial-data";
|
||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
import { buttonVariants } from "@/components/ui/button";
|
import { Button, buttonVariants } from "@/components/ui/button";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import EditorWindow from "@/components/task/editor-window";
|
import EditorWindow from "@/components/task/editor-window";
|
||||||
import { LANGUAGE_VERSIONS } from "@/constants/language-options";
|
import { LANGUAGE_VERSIONS } from "@/constants/language-options";
|
||||||
import { markdownToHtml } from "@/lib/markdown-to-html";
|
import { markdownToHtml } from "@/lib/markdown-to-html";
|
||||||
|
import TaskPage from "@/components/task-page";
|
||||||
|
|
||||||
const languages = Object.keys(LANGUAGE_VERSIONS);
|
const languages = Object.keys(LANGUAGE_VERSIONS);
|
||||||
|
|
||||||
const Page = async ({ params }: { params: { taskId: string[] } }) => {
|
const Page = async ({ params }: { params: { taskId: string[] } }) => {
|
||||||
|
// const [activeMobileView, setActiveMobileView] = useState<
|
||||||
|
// "tutorial" | "code" | "output"
|
||||||
|
// >("tutorial");
|
||||||
|
|
||||||
if (!params.taskId[0] || !languages.includes(params.taskId[0])) {
|
if (!params.taskId[0] || !languages.includes(params.taskId[0])) {
|
||||||
notFound();
|
notFound();
|
||||||
}
|
}
|
||||||
|
@ -41,113 +45,13 @@ const Page = async ({ params }: { params: { taskId: string[] } }) => {
|
||||||
const content = await markdownToHtml(tutorial?.content || "");
|
const content = await markdownToHtml(tutorial?.content || "");
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="md:hidden w-full h-full">
|
<TaskPage
|
||||||
<ResizablePanelGroup
|
params={params}
|
||||||
direction="vertical"
|
langTutorial={langTutorial}
|
||||||
className="max-w-[1440px] mx-auto h-full"
|
tutorial={tutorial}
|
||||||
>
|
tutorialIndex={tutorialIndex}
|
||||||
<ResizablePanel defaultSize={50}>
|
content={content}
|
||||||
<ScrollArea className="h-[calc(100vh-55px)]">
|
/>
|
||||||
<div className="px-4 py-6 flex flex-col gap-4 h-full mb-[60vh]">
|
|
||||||
<div
|
|
||||||
className={cn("grow", markdownStyles["markdown"])}
|
|
||||||
dangerouslySetInnerHTML={{ __html: content }}
|
|
||||||
></div>
|
|
||||||
<div className="flex justify-between">
|
|
||||||
<div className="mb-6">
|
|
||||||
{langTutorial?.tutorial[tutorialIndex - 1] && (
|
|
||||||
<Link
|
|
||||||
href={`/dashboard/task/${params.taskId[0]}/${
|
|
||||||
Number(params.taskId[1]) - 1
|
|
||||||
}`}
|
|
||||||
className={buttonVariants({
|
|
||||||
variant: "outline",
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
Prev
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-6">
|
|
||||||
{langTutorial?.tutorial[tutorialIndex + 1] && (
|
|
||||||
<Link
|
|
||||||
href={`/dashboard/task/${params.taskId[0]}/${
|
|
||||||
Number(params.taskId[1]) + 1
|
|
||||||
}`}
|
|
||||||
className={buttonVariants({ variant: "outline" })}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ScrollArea>
|
|
||||||
</ResizablePanel>
|
|
||||||
<ResizableHandle withHandle />
|
|
||||||
<ResizablePanel defaultSize={50}>
|
|
||||||
<EditorWindow
|
|
||||||
language={params.taskId[0]}
|
|
||||||
step={Number(params.taskId[1]) || 1}
|
|
||||||
/>
|
|
||||||
</ResizablePanel>
|
|
||||||
</ResizablePanelGroup>
|
|
||||||
</div>
|
|
||||||
<div className="hidden md:block w-full h-full">
|
|
||||||
<ResizablePanelGroup
|
|
||||||
direction="horizontal"
|
|
||||||
className="max-w-[1440px] mx-auto h-full"
|
|
||||||
>
|
|
||||||
<ResizablePanel defaultSize={50}>
|
|
||||||
<ScrollArea className="h-[calc(100vh-55px)]">
|
|
||||||
<div className="px-4 py-6 flex flex-col gap-4 h-full">
|
|
||||||
<div
|
|
||||||
className={cn("grow", markdownStyles["markdown"])}
|
|
||||||
dangerouslySetInnerHTML={{ __html: content }}
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<div className="flex justify-between">
|
|
||||||
<div className="mb-6">
|
|
||||||
{langTutorial?.tutorial[tutorialIndex - 1] && (
|
|
||||||
<Link
|
|
||||||
href={`/dashboard/task/${params.taskId[0]}/${
|
|
||||||
Number(params.taskId[1]) - 1
|
|
||||||
}`}
|
|
||||||
className={buttonVariants({
|
|
||||||
variant: "outline",
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
Prev
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-6">
|
|
||||||
{langTutorial?.tutorial[tutorialIndex + 1] && (
|
|
||||||
<Link
|
|
||||||
href={`/dashboard/task/${params.taskId[0]}/${
|
|
||||||
Number(params.taskId[1]) + 1
|
|
||||||
}`}
|
|
||||||
className={buttonVariants({ variant: "outline" })}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ScrollArea>
|
|
||||||
</ResizablePanel>
|
|
||||||
<ResizableHandle withHandle />
|
|
||||||
<ResizablePanel defaultSize={50}>
|
|
||||||
<EditorWindow
|
|
||||||
language={params.taskId[0]}
|
|
||||||
step={Number(params.taskId[1]) || 1}
|
|
||||||
/>
|
|
||||||
</ResizablePanel>
|
|
||||||
</ResizablePanelGroup>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ export function MobileSidebar({ className }: SidebarProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Sheet open={open} onOpenChange={setOpen}>
|
<Sheet open={open} onOpenChange={setOpen}>
|
||||||
<SheetTrigger asChild>
|
<SheetTrigger asChild className="cursor-pointer">
|
||||||
<MenuIcon />
|
<MenuIcon />
|
||||||
</SheetTrigger>
|
</SheetTrigger>
|
||||||
<SheetContent side="left" className="!px-0">
|
<SheetContent side="left" className="!px-0">
|
||||||
|
|
|
@ -0,0 +1,315 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
|
import {
|
||||||
|
ResizableHandle,
|
||||||
|
ResizablePanel,
|
||||||
|
ResizablePanelGroup,
|
||||||
|
} from "@/components/ui/resizable";
|
||||||
|
import markdownStyles from "@/styles/markdown-styles.module.css";
|
||||||
|
import { tutorialData } from "@/constants/tutorial-data";
|
||||||
|
import { notFound } from "next/navigation";
|
||||||
|
import { Button, buttonVariants } from "@/components/ui/button";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import EditorWindow from "@/components/task/editor-window";
|
||||||
|
import { LANGUAGE_VERSIONS } from "@/constants/language-options";
|
||||||
|
import { markdownToHtml } from "@/lib/markdown-to-html";
|
||||||
|
import Header from "./task/header";
|
||||||
|
import Image from "next/image";
|
||||||
|
import ThemeToggle from "./layout/ThemeToggle/theme-toggle";
|
||||||
|
|
||||||
|
const languages = Object.keys(LANGUAGE_VERSIONS);
|
||||||
|
|
||||||
|
interface LangTutorial {
|
||||||
|
id: number;
|
||||||
|
language: string;
|
||||||
|
tutorial: {
|
||||||
|
id: number;
|
||||||
|
content: string;
|
||||||
|
code: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Tutorial {
|
||||||
|
id: number;
|
||||||
|
content: string;
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TaskPage = ({
|
||||||
|
params,
|
||||||
|
langTutorial,
|
||||||
|
tutorial,
|
||||||
|
tutorialIndex,
|
||||||
|
content,
|
||||||
|
}: {
|
||||||
|
params: { taskId: string[] };
|
||||||
|
langTutorial: LangTutorial;
|
||||||
|
tutorial: Tutorial;
|
||||||
|
tutorialIndex: number;
|
||||||
|
content: string;
|
||||||
|
}) => {
|
||||||
|
const [activeMobileView, setActiveMobileView] = useState<
|
||||||
|
"tutorial" | "code" | "output"
|
||||||
|
>("tutorial");
|
||||||
|
|
||||||
|
// if (!params.taskId[0] || !languages.includes(params.taskId[0])) {
|
||||||
|
// notFound();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const langTutorial = tutorialData.find(
|
||||||
|
// (t) => t.language === params.taskId[0],
|
||||||
|
// )!;
|
||||||
|
|
||||||
|
// const tutorial = langTutorial.tutorial.find(
|
||||||
|
// (t) => t.id === (Number(params.taskId[1]) || 1),
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const tutorialIndex = langTutorial.tutorial.findIndex(
|
||||||
|
// (t) => t.id === (Number(params.taskId[1]) || 1),
|
||||||
|
// );
|
||||||
|
|
||||||
|
// if (!tutorial || tutorialIndex === -1) {
|
||||||
|
// notFound();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const content = await markdownToHtml(tutorial?.content || "");
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="md:hidden flex items-center justify-center gap-4 fixed w-screen bottom-0 left-0 z-50 px-4 py-3 bg-background border-t">
|
||||||
|
<Button
|
||||||
|
variant={activeMobileView === "tutorial" ? "default" : "outline"}
|
||||||
|
onClick={() => setActiveMobileView("tutorial")}
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
Tutorial
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant={activeMobileView === "code" ? "default" : "outline"}
|
||||||
|
onClick={() => setActiveMobileView("code")}
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
Code
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant={activeMobileView === "output" ? "default" : "outline"}
|
||||||
|
onClick={() => setActiveMobileView("output")}
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
Output
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="md:hidden w-full h-full">
|
||||||
|
{/* <ResizablePanelGroup
|
||||||
|
direction="vertical"
|
||||||
|
className="max-w-[1440px] mx-auto h-full"
|
||||||
|
> */}
|
||||||
|
{/* <ResizablePanel defaultSize={50}> */}
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"fixed left-0 top-0 h-[calc(100vh-59px)] w-screen transition-transform translate-x-0",
|
||||||
|
activeMobileView === "tutorial"
|
||||||
|
? "translate-x-0"
|
||||||
|
: activeMobileView === "code"
|
||||||
|
? "-translate-x-full"
|
||||||
|
: activeMobileView === "output"
|
||||||
|
? "-translate-x-[200%]"
|
||||||
|
: "",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="border-b px-4 bg-background">
|
||||||
|
<nav className="flex justify-between items-center max-w-[1440px] mx-auto py-2">
|
||||||
|
<Link href="/dashboard" className="inline-block w-fit">
|
||||||
|
<Image
|
||||||
|
src="/Skilld AI Logos/Skilld Logo-colour on black.png"
|
||||||
|
alt="Skilld Logo"
|
||||||
|
width={100}
|
||||||
|
height={30}
|
||||||
|
className="hidden dark:block h-[25px] w-[80px] md:w-[100px] md:h-[30px] object-contain"
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
src="/Skilld AI Logos/Skilld Logo-colour.png"
|
||||||
|
alt="Skilld Logo"
|
||||||
|
width={100}
|
||||||
|
height={30}
|
||||||
|
className="dark:hidden h-[25px] w-[80px] md:w-[100px] md:h-[30px] object-contain"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-8">
|
||||||
|
{/* <Link href="/">Home</Link> */}
|
||||||
|
<Link href="/dashboard">Dashboard</Link>
|
||||||
|
{/* <Link href="/login">Login</Link> */}
|
||||||
|
<ThemeToggle />
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ScrollArea className="h-[calc(100vh-calc(53px+59px))]">
|
||||||
|
<div className="p-4 flex flex-col gap-4 h-full">
|
||||||
|
<div
|
||||||
|
className={cn("grow", markdownStyles["markdown"])}
|
||||||
|
dangerouslySetInnerHTML={{ __html: content }}
|
||||||
|
></div>
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<div className="mb-6">
|
||||||
|
{langTutorial?.tutorial[tutorialIndex - 1] && (
|
||||||
|
<Link
|
||||||
|
href={`/dashboard/task/${params.taskId[0]}/${
|
||||||
|
Number(params.taskId[1]) - 1
|
||||||
|
}`}
|
||||||
|
className={buttonVariants({
|
||||||
|
variant: "outline",
|
||||||
|
size: "sm",
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
Prev
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-6">
|
||||||
|
{langTutorial?.tutorial[tutorialIndex + 1] && (
|
||||||
|
<Link
|
||||||
|
href={`/dashboard/task/${params.taskId[0]}/${
|
||||||
|
Number(params.taskId[1]) + 1
|
||||||
|
}`}
|
||||||
|
className={buttonVariants({
|
||||||
|
variant: "outline",
|
||||||
|
size: "sm",
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
|
</div>
|
||||||
|
{/* </ResizablePanel> */}
|
||||||
|
{/* <ResizableHandle withHandle /> */}
|
||||||
|
{/* <ResizablePanel defaultSize={50}> */}
|
||||||
|
<EditorWindow
|
||||||
|
activeMobileView={activeMobileView}
|
||||||
|
language={params.taskId[0]}
|
||||||
|
step={Number(params.taskId[1]) || 1}
|
||||||
|
/>
|
||||||
|
{/* </ResizablePanel> */}
|
||||||
|
{/* </ResizablePanelGroup> */}
|
||||||
|
</div>
|
||||||
|
{/* <div className="md:hidden w-full h-full">
|
||||||
|
<ResizablePanelGroup
|
||||||
|
direction="vertical"
|
||||||
|
className="max-w-[1440px] mx-auto h-full"
|
||||||
|
>
|
||||||
|
<ResizablePanel defaultSize={50}>
|
||||||
|
<ScrollArea className="h-[calc(100vh-55px)]">
|
||||||
|
<div className="px-4 py-6 flex flex-col gap-4 h-full mb-[60vh]">
|
||||||
|
<div
|
||||||
|
className={cn("grow", markdownStyles["markdown"])}
|
||||||
|
dangerouslySetInnerHTML={{ __html: content }}
|
||||||
|
></div>
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<div className="mb-6">
|
||||||
|
{langTutorial?.tutorial[tutorialIndex - 1] && (
|
||||||
|
<Link
|
||||||
|
href={`/dashboard/task/${params.taskId[0]}/${
|
||||||
|
Number(params.taskId[1]) - 1
|
||||||
|
}`}
|
||||||
|
className={buttonVariants({
|
||||||
|
variant: "outline",
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
Prev
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-6">
|
||||||
|
{langTutorial?.tutorial[tutorialIndex + 1] && (
|
||||||
|
<Link
|
||||||
|
href={`/dashboard/task/${params.taskId[0]}/${
|
||||||
|
Number(params.taskId[1]) + 1
|
||||||
|
}`}
|
||||||
|
className={buttonVariants({ variant: "outline" })}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle withHandle />
|
||||||
|
<ResizablePanel defaultSize={50}>
|
||||||
|
<EditorWindow
|
||||||
|
language={params.taskId[0]}
|
||||||
|
step={Number(params.taskId[1]) || 1}
|
||||||
|
/>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</div> */}
|
||||||
|
<div className="hidden md:block w-full h-full">
|
||||||
|
<ResizablePanelGroup
|
||||||
|
direction="horizontal"
|
||||||
|
className="max-w-[1440px] mx-auto h-full"
|
||||||
|
>
|
||||||
|
<ResizablePanel defaultSize={50}>
|
||||||
|
<ScrollArea className="h-[calc(100vh-55px)]">
|
||||||
|
<div className="px-4 py-6 flex flex-col gap-4 h-full">
|
||||||
|
<div
|
||||||
|
className={cn("grow", markdownStyles["markdown"])}
|
||||||
|
dangerouslySetInnerHTML={{ __html: content }}
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<div className="mb-6">
|
||||||
|
{langTutorial?.tutorial[tutorialIndex - 1] && (
|
||||||
|
<Link
|
||||||
|
href={`/dashboard/task/${params.taskId[0]}/${
|
||||||
|
Number(params.taskId[1]) - 1
|
||||||
|
}`}
|
||||||
|
className={buttonVariants({
|
||||||
|
variant: "outline",
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
Prev
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-6">
|
||||||
|
{langTutorial?.tutorial[tutorialIndex + 1] && (
|
||||||
|
<Link
|
||||||
|
href={`/dashboard/task/${params.taskId[0]}/${
|
||||||
|
Number(params.taskId[1]) + 1
|
||||||
|
}`}
|
||||||
|
className={buttonVariants({ variant: "outline" })}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle withHandle />
|
||||||
|
<ResizablePanel defaultSize={50}>
|
||||||
|
<EditorWindow
|
||||||
|
activeMobileView={activeMobileView}
|
||||||
|
language={params.taskId[0]}
|
||||||
|
step={Number(params.taskId[1]) || 1}
|
||||||
|
/>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TaskPage;
|
|
@ -19,13 +19,14 @@ import { notFound, useRouter } from "next/navigation";
|
||||||
import { defineTheme } from "@/utils/define-theme";
|
import { defineTheme } from "@/utils/define-theme";
|
||||||
import Preview from "./preview";
|
import Preview from "./preview";
|
||||||
import { MyComponents } from "./my-components";
|
import { MyComponents } from "./my-components";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
|
||||||
export default function EditorWindow({
|
export default function EditorWindow({
|
||||||
|
activeMobileView: activeMobileView,
|
||||||
language: lang,
|
language: lang,
|
||||||
step,
|
step,
|
||||||
}: {
|
}: {
|
||||||
|
activeMobileView: "tutorial" | "code" | "output";
|
||||||
language: string;
|
language: string;
|
||||||
step: number;
|
step: number;
|
||||||
}) {
|
}) {
|
||||||
|
@ -51,17 +52,17 @@ export default function EditorWindow({
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
defineTheme("oceanic-next").then((_) => setTheme("oceanic-next"));
|
defineTheme("cobalt").then((_) => setTheme("cobalt"));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
function handleThemeChange(th: any) {
|
function handleThemeChange(th: string) {
|
||||||
const theme = th;
|
const themee = th;
|
||||||
// console.log("theme...", theme);
|
// console.log("theme...", theme);
|
||||||
|
|
||||||
if (["light", "vs-dark"].includes(theme)) {
|
if (["light", "vs-dark"].includes(themee)) {
|
||||||
setTheme(theme);
|
setTheme(themee);
|
||||||
} else {
|
} else {
|
||||||
defineTheme(theme).then((_) => setTheme(theme));
|
defineTheme(themee).then((_) => setTheme(themee));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,20 +96,33 @@ export default function EditorWindow({
|
||||||
// console.log(tutorial);
|
// console.log(tutorial);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ResizablePanelGroup direction="vertical" className="border-r">
|
<>
|
||||||
<ResizablePanel defaultSize={50}>
|
<div className="md:hidden">
|
||||||
<div className="h-full ">
|
{/* <ResizablePanelGroup direction="vertical" className="border-r">
|
||||||
|
<ResizablePanel defaultSize={50}> */}
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"fixed left-0 top-0 h-[calc(100vh-59px)] w-screen translate-x-full transition-transform ",
|
||||||
|
activeMobileView === "tutorial"
|
||||||
|
? "translate-x-full"
|
||||||
|
: activeMobileView === "code"
|
||||||
|
? "translate-x-0"
|
||||||
|
: activeMobileView === "output"
|
||||||
|
? "-translate-x-full"
|
||||||
|
: "",
|
||||||
|
)}
|
||||||
|
>
|
||||||
<div className="p-2 flex gap-4">
|
<div className="p-2 flex gap-4">
|
||||||
<ThemeDropdown
|
<ThemeDropdown
|
||||||
handleThemeChange={handleThemeChange}
|
handleThemeChange={handleThemeChange}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
<LanguagesDropdown
|
{/* <LanguagesDropdown
|
||||||
handleLanguageChange={handleLanguageChange}
|
handleLanguageChange={handleLanguageChange}
|
||||||
language={lang}
|
language={lang}
|
||||||
/>
|
/> */}
|
||||||
</div>
|
</div>
|
||||||
<div className="h-full">
|
<div className="h-[calc(100vh-calc(57px+53px))]">
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
codeValue={codeValue}
|
codeValue={codeValue}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -121,11 +135,22 @@ export default function EditorWindow({
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ResizablePanel>
|
{/* </ResizablePanel> */}
|
||||||
<ResizableHandle withHandle />
|
{/* <ResizableHandle withHandle /> */}
|
||||||
<ResizablePanel defaultSize={50}>
|
{/* <ResizablePanel defaultSize={50}> */}
|
||||||
<ErrorBoundary FallbackComponent={PreviewErrorFallback}>
|
<ErrorBoundary FallbackComponent={PreviewErrorFallback}>
|
||||||
<div className="bg-white text-black h-full p-4">
|
<div
|
||||||
|
className={cn(
|
||||||
|
"bg-white text-black p-4 fixed left-0 h-[calc(100vh-59px)] w-screen transition-transform translate-x-[200%]",
|
||||||
|
activeMobileView === "tutorial"
|
||||||
|
? "translate-x-[200%]"
|
||||||
|
: activeMobileView === "code"
|
||||||
|
? "translate-x-[100%]"
|
||||||
|
: activeMobileView === "output"
|
||||||
|
? "translate-x-0"
|
||||||
|
: "",
|
||||||
|
)}
|
||||||
|
>
|
||||||
{lang === "react" ? (
|
{lang === "react" ? (
|
||||||
<Preview
|
<Preview
|
||||||
componentName={componentName}
|
componentName={componentName}
|
||||||
|
@ -142,9 +167,61 @@ export default function EditorWindow({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</ResizablePanel>
|
{/* </ResizablePanel> */}
|
||||||
</ResizablePanelGroup>
|
{/* </ResizablePanelGroup> */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="hidden md:block h-[calc(100vh-55px)]">
|
||||||
|
<ResizablePanelGroup direction="vertical" className="border-r">
|
||||||
|
<ResizablePanel defaultSize={50}>
|
||||||
|
<div className="h-full ">
|
||||||
|
<div className="p-2 flex gap-4">
|
||||||
|
<ThemeDropdown
|
||||||
|
handleThemeChange={handleThemeChange}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
|
{/* <LanguagesDropdown
|
||||||
|
handleLanguageChange={handleLanguageChange}
|
||||||
|
language={lang}
|
||||||
|
/> */}
|
||||||
|
</div>
|
||||||
|
<div className="h-full">
|
||||||
|
<CodeEditor
|
||||||
|
codeValue={codeValue}
|
||||||
|
// @ts-ignore
|
||||||
|
// defaultCode={CODE_SNIPPETS[language]}
|
||||||
|
defaultCode={tutorial?.code || ""}
|
||||||
|
onChange={handleCodeChange}
|
||||||
|
theme={theme}
|
||||||
|
// language={language}
|
||||||
|
language={lang}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ResizablePanel>
|
||||||
|
<ResizableHandle withHandle />
|
||||||
|
<ResizablePanel defaultSize={50}>
|
||||||
|
<ErrorBoundary FallbackComponent={PreviewErrorFallback}>
|
||||||
|
<div className="bg-white text-black h-full p-4">
|
||||||
|
{lang === "react" ? (
|
||||||
|
<Preview
|
||||||
|
componentName={componentName}
|
||||||
|
tutorialCode={tutorial?.code || ""}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Output
|
||||||
|
// @ts-ignore
|
||||||
|
codeValue={codeValue || tutorial?.code || ""}
|
||||||
|
// codeValue={codeValue || CODE_SNIPPETS[language]}
|
||||||
|
// language={language}
|
||||||
|
language={lang}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</ErrorBoundary>
|
||||||
|
</ResizablePanel>
|
||||||
|
</ResizablePanelGroup>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import React from "react";
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
return (
|
return (
|
||||||
<header className="border-b px-4 h-min">
|
<header className="border-b px-4 hidden md:block">
|
||||||
<nav className="flex justify-between items-center max-w-[1440px] mx-auto py-2">
|
<nav className="flex justify-between items-center max-w-[1440px] mx-auto py-2">
|
||||||
<Link href="/dashboard" className="inline-block w-fit">
|
<Link href="/dashboard" className="inline-block w-fit">
|
||||||
<Image
|
<Image
|
||||||
|
|
|
@ -51,5 +51,5 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown pre {
|
.markdown pre {
|
||||||
@apply p-4 rounded-md my-4 overflow-x-auto max-w-[320px] xs:max-w-full;
|
@apply p-4 rounded-md my-4 overflow-x-auto max-w-[calc(100vw-32px)] xs:max-w-full;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue