Skip to content

Commit

Permalink
add mysql playground (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
invisal authored Dec 25, 2024
1 parent 8d99fdc commit 03a5dc5
Show file tree
Hide file tree
Showing 8 changed files with 428 additions and 11 deletions.
36 changes: 36 additions & 0 deletions src/app/(public)/playground/mysql-playground-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"use client";
import { MySQLIcon } from "@/components/icons/outerbase-icon";
import { useRouter } from "next/navigation";

export default function MySQLPlaygroundButton() {
const router = useRouter();

return (
<button
className={
"text-left bg-primary text-primary-foreground p-3 px-4 rounded-lg text-sm gap-2 flex flex-col hover:bg-gray-300 w-[200px]"
}
onClick={() => {
// Random 8 character alphabeth string
const roomName = new Array(8)
.fill("a")
.map(
() => "abcdefghijklmnopqrstuvwxyz"[Math.floor(Math.random() * 26)]
)
.join("");

router.push(`/playground/mysql/${roomName}`);
}}
>
<div className="flex gap-2">
<MySQLIcon className="w-10 h-10" />
<div className="flex flex-col justify-center">
<div className="font-bold text-md">MySQL</div>
<div className="text-xs">Playground</div>
</div>
</div>

<p className="text-xs text-gray-500">Spin up a cloud MySQL sandbox.</p>
</button>
);
}
31 changes: 28 additions & 3 deletions src/app/(public)/playground/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { SQLiteIcon } from "@/components/icons/outerbase-icon";
import { buttonVariants } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import WebsiteLayout from "@/components/website-layout";
import { get_database } from "@/db";
import { dbDataset } from "@/db/schema-dataset";
import { Metadata } from "next";
import Link from "next/link";
import MySQLPlaygroundButton from "./mysql-playground-button";

export const metadata: Metadata = {
title: "SQLite Online Editor",
Expand Down Expand Up @@ -32,9 +34,32 @@ export default async function PlaygroundPage() {
a selection of sample datasets.
</p>

<Link passHref href="/playground/client" className={buttonVariants()}>
Open Database Viewer
</Link>
<div className="flex gap-2 mt-8">
<Link
passHref
href="/playground/client"
className={
"bg-primary text-primary-foreground p-3 px-4 rounded-lg text-sm gap-2 flex flex-col hover:bg-gray-300 w-[200px]"
}
prefetch={false}
>
<div className="flex gap-2">
<SQLiteIcon className="w-10 h-10" />
<div className="flex flex-col justify-center">
<div className="font-bold text-md">SQLite</div>
<div className="text-xs">Playground</div>
</div>
</div>

<p className="text-xs text-gray-500">
Launch in-memory SQLite
<br />
inside the browser
</p>
</Link>

<MySQLPlaygroundButton />
</div>
</div>

<Separator />
Expand Down
55 changes: 55 additions & 0 deletions src/app/(theme)/playground/mysql/[roomName]/page-client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"use client";
import { Studio } from "@/components/gui/studio";
import ServerLoadingAnimation from "@/components/icons/server-loading";
import MySQLPlaygroundDriver from "@/drivers/mysql/mysql-playground-driver";
import { useSearchParams } from "next/navigation";
import { useEffect, useMemo, useState } from "react";

export default function MySQLPlaygroundPageClient({
roomName,
}: {
roomName: string;
}) {
const searchParams = useSearchParams();
const [isReady, setReady] = useState(false);

const driver = useMemo(() => {
if (typeof window === "undefined") return null;

return new MySQLPlaygroundDriver(roomName, {
onReady: () => setReady(true),
});
}, [setReady, roomName]);

// Create ping useeffect
useEffect(() => {
if (!driver) return;

const interval = setInterval(() => {
driver.ping();
}, 5000);

return () => clearInterval(interval);
}, [driver]);

if (!isReady) {
return (
<div className="w-screen h-screen flex items-center justify-center flex-col gap-4">
<ServerLoadingAnimation />
<div>Setting up your database</div>
</div>
);
}

if (!driver) {
return <div>Server-side rendering is not supported</div>;
}

return (
<Studio
driver={driver}
name={searchParams.get("name") || "Unnamed Connection"}
color={searchParams.get("color") || "gray"}
/>
);
}
37 changes: 37 additions & 0 deletions src/app/(theme)/playground/mysql/[roomName]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Metadata } from "next";
import ThemeLayout from "../../../theme_layout";
import MySQLPlaygroundPageClient from "./page-client";

export const metadata: Metadata = {
title:
"SQLite Online Playground - Powerful and lightweight editor on your browser",
description:
"Explore the powerful SQLite Playground in your browser – no downloads or registration needed. Effortlessly load your SQLite files or start with a blank database, then save your work with ease. Enjoy a robust data editor, advanced query capabilities, table creation, and much more.",
keywords: [
"sqlite",
"libsql",
"browser",
"client",
"gui",
"playground",
"sandbox",
"explorer",
"studio",
],
robots: {
index: true,
follow: true,
},
};

export default async function MySQLPlaygroundEditor({
params: { roomName },
}: {
params: { roomName: string };
}) {
return (
<ThemeLayout>
<MySQLPlaygroundPageClient roomName={roomName} />
</ThemeLayout>
);
}
9 changes: 9 additions & 0 deletions src/app/storybook/server-loading/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import ServerLoadingAnimation from "@/components/icons/server-loading";

export default function ServerLoadingStorybook() {
return (
<div className="p-4">
<ServerLoadingAnimation />
</div>
);
}
14 changes: 6 additions & 8 deletions src/components/gui/connection-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button } from "@/components/ui/button";
import LogoLoading from "./logo-loading";
import { useConfig } from "@/context/config-provider";
import { useMemo } from "react";
import ServerLoadingAnimation from "../icons/server-loading";

export default function ConnectingDialog({
message,
Expand All @@ -28,11 +28,9 @@ export default function ConnectingDialog({
};

let body = (
<div>
<p className="mt-4 flex gap-4">
Connecting to <strong>{name}</strong>
</p>
</div>
<p>
Connecting to <strong>{name}</strong>
</p>
);

if (message) {
Expand All @@ -58,8 +56,8 @@ export default function ConnectingDialog({
}

return (
<div className="p-8">
<LogoLoading />
<div className="w-screen h-screen flex items-center justify-center flex-col gap-4">
<ServerLoadingAnimation />
{body}
</div>
);
Expand Down
Loading

0 comments on commit 03a5dc5

Please sign in to comment.