forked from DiceDB/alloy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e54d64f
commit c85b3d3
Showing
8 changed files
with
207 additions
and
13 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,9 @@ | ||
import Image from "next/image"; | ||
import Playground from "@/components/Playground/Playground"; | ||
|
||
export default function Home() { | ||
return ( | ||
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]"> | ||
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start"> | ||
<Image | ||
src="/logo.png" | ||
alt="Next.js logo" | ||
width={180} | ||
height={38} | ||
priority | ||
/> | ||
<main> | ||
<Playground /> | ||
</main> | ||
</div> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,47 @@ | ||
// Feature specific | ||
|
||
'use client'; | ||
|
||
import React from 'react'; | ||
import { useEffect, useRef } from 'react'; | ||
import { Dice1 } from 'lucide-react'; | ||
|
||
interface CliProps { | ||
output: string[]; | ||
command: string; | ||
setCommand: React.Dispatch<React.SetStateAction<string>>; | ||
handleCommand: React.KeyboardEventHandler<HTMLInputElement>; | ||
} | ||
|
||
export default function Cli({ output, command, setCommand, handleCommand }: CliProps) { | ||
const terminalRef = useRef<HTMLDivElement>(null); | ||
|
||
useEffect(() => { | ||
if (terminalRef.current) { | ||
terminalRef.current.scrollTop = terminalRef.current.scrollHeight; | ||
} | ||
}, [output]); | ||
|
||
return ( | ||
<div className="flex-grow flex flex-col"> | ||
<div ref={terminalRef} className="flex-grow overflow-auto mb-4 font-mono"> | ||
{output.map((line, index) => ( | ||
<div key={index} className={line.startsWith('dice>') ? 'text-blue-400' : 'text-green-400'}> | ||
{line} | ||
</div> | ||
))} | ||
</div> | ||
<div className="flex items-center bg-gray-700 rounded px-2 mb-4"> | ||
<Dice1 className="w-4 h-4 text-green-500 mr-2" /> | ||
<span className="text-green-500">dice></span> | ||
<input | ||
type="text" | ||
value={command} | ||
onChange={(e) => setCommand(e.target.value)} | ||
onKeyDown={handleCommand} | ||
placeholder="Enter DiceDB command..." | ||
className="bg-transparent border-none outline-none w-full py-2 text-white placeholder-gray-500 ml-2" | ||
/> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
|
||
'use client'; | ||
|
||
export default function Footer({ timeLeft, triggers }: { timeLeft: string, triggers: number }) { | ||
return ( | ||
<div className="bg-gray-100 rounded-lg p-4 text-gray-900 text-sm"> | ||
<div className="flex justify-between items-center"> | ||
<span>Cleanup in: {timeLeft} mins</span> | ||
<span>Command Triggers left: {triggers}</span> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
'use client'; | ||
|
||
|
||
export default function Header() { | ||
return ( | ||
<header className="flex items-center mb-4"> | ||
<h1 className="text-2xl font-bold">DiceDB PlayGround</h1> | ||
</header> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
"use client"; | ||
|
||
import React from "react"; | ||
import { useState, useEffect } from "react"; | ||
import Cli from "@/components/Cli/Cli"; | ||
import Header from "@/components/Header/Header"; | ||
import Footer from "@/components/Footer/Footer"; | ||
import SearchBox from "@/components/Search/SearchBox"; | ||
|
||
export default function Playground() { | ||
const [command, setCommand] = useState(""); | ||
const [output, setOutput] = useState<string[]>([]); | ||
const [triggers, setTriggers] = useState<number>(1000); | ||
const [search, setSearch] = useState(""); | ||
const [timeLeft, setTimeLeft] = useState<number>(15 * 60); | ||
const [store, setStore] = useState<{ [key: string]: string }>({ | ||
hello: "world", | ||
}); | ||
|
||
const handleCommand = (e: React.KeyboardEvent<HTMLInputElement>) => { | ||
if (e.key === "Enter") { | ||
const newOutput = `dice> ${command}`; | ||
let result = ""; | ||
|
||
const [cmd, ...args] = command.split(" "); | ||
|
||
switch (cmd.toUpperCase()) { | ||
case "GET": | ||
result = store[args[0]] || "(nil)"; | ||
break; | ||
case "SET": | ||
if (args.length === 2) { | ||
const [key, value] = args; | ||
setStore((prevStore) => ({ ...prevStore, [key]: value })); | ||
result = "OK"; | ||
} else { | ||
result = "Invalid command. Usage: SET key value"; | ||
} | ||
break; | ||
default: | ||
result = `Unknown command: ${cmd}`; | ||
} | ||
|
||
setOutput([...output, newOutput, result]); | ||
setCommand(""); | ||
setTriggers((prev) => prev - 1); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
const timer = setInterval(() => { | ||
setTimeLeft((prev) => (prev > 0 ? prev - 1 : 0)); | ||
}, 1000); | ||
|
||
return () => clearInterval(timer); | ||
}, []); | ||
|
||
const formatTime = (seconds: number): string => { | ||
const minutes = Math.floor(seconds / 60); | ||
const remainingSeconds = seconds % 60; | ||
return `${minutes}:${remainingSeconds < 10 ? "0" : ""}${remainingSeconds}`; | ||
}; | ||
|
||
return ( | ||
<> | ||
<div className="min-h-screen flex flex-col bg-gray-900 text-gray-100 p-4"> | ||
<Header /> | ||
<main className="flex-grow flex overflow-hidden"> | ||
<div className="w-1/2 p-4 bg-gray-800 text-white flex flex-col"> | ||
<Cli | ||
output={output} | ||
command={command} | ||
setCommand={setCommand} | ||
handleCommand={(e) => handleCommand(e)} | ||
/> | ||
<Footer timeLeft={formatTime(timeLeft)} triggers={triggers} /> | ||
</div> | ||
<div className="w-1/2 p-4 bg-white shadow-md overflow-auto"> | ||
<SearchBox search={search} setSearch={setSearch} /> | ||
</div> | ||
</main> | ||
</div> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
'use client'; | ||
|
||
import React from 'react'; | ||
import { Search } from 'lucide-react'; | ||
interface SearchBoxProps { | ||
search: string; | ||
setSearch: React.Dispatch<React.SetStateAction<string>> | ||
} | ||
|
||
export default function SearchBox({ search , setSearch}: SearchBoxProps) { | ||
return ( | ||
<div> | ||
<div className="mb-4"> | ||
<div className="flex items-center bg-gray-100 rounded px-2"> | ||
<Search className="text-gray-400 mr-2" /> | ||
<input | ||
type="text" | ||
value={search} | ||
onChange={(e) => setSearch(e.target.value)} | ||
placeholder="Search commands..." | ||
className="bg-transparent border-none outline-none w-full py-2 text-gray-900 placeholder-gray-500" | ||
/> | ||
</div> | ||
</div> | ||
<div className="space-y-2"> | ||
{['SET', 'GET', 'DEL'].map((cmd) => ( | ||
<button | ||
key={cmd} | ||
className="w-full text-left bg-gray-700 hover:bg-gray-600 rounded p-2 transition-colors" | ||
> | ||
{cmd} | ||
</button> | ||
))} | ||
</div> | ||
</div> | ||
); | ||
} |