-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding new design+new download functionality #13
base: master
Are you sure you want to change the base?
Changes from 2 commits
0f28238
d097814
3953c97
768ce16
0ee2437
fb17ca6
ad72112
c841ab8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,17 +3,72 @@ | |
"use client"; | ||
|
||
import Image from "next/image"; | ||
import React, { useState, useEffect } from "react"; | ||
import React, { useState,useRef, useEffect } from "react"; | ||
import Cli from "@/components/CLI/CLI"; | ||
import SearchBox from "@/components/Search/SearchBox"; | ||
import { Dice1, Dice3, Dice5 } from "lucide-react"; | ||
import { Dice1, Dice3, Dice5, Clock, Command, Sun, Moon, Github, Download } from "lucide-react"; | ||
|
||
import { formatTime } from "@/shared/utils/commonUtils"; | ||
import Link from "next/link"; | ||
|
||
|
||
|
||
|
||
const NavBar: React.FC<{ isDarkMode: boolean; toggleDarkMode: () => void }> = ({ isDarkMode, toggleDarkMode }) => ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We want to keep things in parity with our website dicedb.io, please open an issue for DarkMode we can take this up later. |
||
<nav className="shadow-md"> | ||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> | ||
<div className="flex items-center justify-between h-16"> | ||
<div className="flex items-center"> | ||
<Image | ||
src="https://dicedb.io/dicedb-logo-light.png" | ||
width={80} | ||
height={80} | ||
alt="DiceDB logo" | ||
className="object-contain" | ||
/> | ||
<div className="ml-10 flex items-baseline space-x-4"> | ||
<Link href="#" className=" px-3 py-2 rounded-md text-sm font-medium">Docs</Link> | ||
<Link href="#" className=" px-3 py-2 rounded-md text-sm font-medium">Blogs</Link> | ||
<Link href="#" className=" px-3 py-2 rounded-md text-sm font-medium"> | ||
GitHub | ||
</Link> | ||
</div> | ||
</div> | ||
<div className="ml-4 flex items-center md:ml-6"> | ||
<button | ||
onClick={toggleDarkMode} | ||
className=" p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white" | ||
> | ||
{isDarkMode ? <Sun className="h-6 w-6" /> : <Moon className="h-6 w-6" />} | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</nav> | ||
); | ||
export default function Playground() { | ||
const [search, setSearch] = useState(""); | ||
const [timeLeft, setTimeLeft] = useState<number>(15 * 60); | ||
const [commandsLeft, setCommandsLeft] = useState<number>(1000); | ||
const [isDarkMode, setIsDarkMode] = useState<boolean>(false); | ||
const downloadBtnRef = useRef<HTMLButtonElement>(null); | ||
const cliCodeRef = useRef<HTMLDivElement>(null); | ||
|
||
useEffect(() => { | ||
const downloadBtn = downloadBtnRef.current; | ||
const cliCode = cliCodeRef.current; | ||
|
||
if (downloadBtn && cliCode) { | ||
downloadBtn.addEventListener('click', () => { | ||
const code = cliCode.textContent || ''; | ||
const blob = new Blob([code], { type: 'text/plain' }); | ||
const link = document.createElement('a'); | ||
link.href = URL.createObjectURL(blob); | ||
link.download = 'code.txt'; | ||
link.click(); | ||
}); | ||
} | ||
}, []); | ||
useEffect(() => { | ||
const timer = setInterval(() => { | ||
setTimeLeft((prev) => (prev > 0 ? prev - 1 : 0)); | ||
|
@@ -25,9 +80,14 @@ export default function Playground() { | |
const decreaseCommandsLeft = () => { | ||
setCommandsLeft((prev) => (prev > 0 ? prev - 1 : 0)); | ||
}; | ||
const toggleDarkMode = (): void => { | ||
setIsDarkMode(!isDarkMode); | ||
}; | ||
|
||
return ( | ||
<div className="container mx-auto flex flex-col flex-grow min-h-screen bg-white text-gray-900 line-height-[1.5rem]"> | ||
<NavBar isDarkMode={isDarkMode} toggleDarkMode={toggleDarkMode} /> | ||
<div className="container mx-auto px-4 py-8"> | ||
<header className="navbar flex items-center justify-between pt-5 pb-4"> | ||
<div className="flex items-center"> | ||
<Image | ||
|
@@ -38,37 +98,77 @@ export default function Playground() { | |
className="object-contain" | ||
/> | ||
<h2 className="font-light text-2xl ml-2">PlayGround</h2> | ||
<button ref={downloadBtnRef} id="download-btn" className="font-bold py-2 px-4 rounded"> | ||
<Download/> | ||
</button> | ||
</div> | ||
</header> | ||
<main className="flex flex-grow gap-10 overflow-hidden"> | ||
<div className="w-1/2 flex flex-col bg"> | ||
<div className="bg-gray-900 rounded-lg"> | ||
<div className="bg-gray-900 px-4 py-4 flex items-center rounded-lg"> | ||
<div className="flex space-x-2"> | ||
<Dice5 className="w-4 h-4 bg-red-500"></Dice5> | ||
<Dice1 className="w-4 h-4 bg-yellow-500"></Dice1> | ||
<Dice3 className="w-4 h-4 bg-green-500"></Dice3> | ||
<main className="grid grid-cols-1 md:grid-cols-2 gap-8"> | ||
|
||
<div className="space-y-4"> | ||
<div className="border border-gray-300 dark:border-gray-700 rounded-lg overflow-hidden"> | ||
|
||
<div className="bg-gray-100 dark:bg-gray-800 px-4 py-2 flex items-center"> | ||
|
||
<div className="flex space-x-2"> | ||
<Dice5 className="w-4 h-4 text-red-500" /> | ||
<Dice1 className="w-4 h-4 text-yellow-500" /> | ||
<Dice3 className="w-4 h-4 text-green-500" /> | ||
</div> | ||
</div> | ||
|
||
<div ref={cliCodeRef} className="h-80 bg-gray-900"> | ||
<Cli decreaseCommandsLeft={decreaseCommandsLeft} /> | ||
</div> | ||
</div> | ||
|
||
<div className="flex justify-between"> | ||
<div className="w-[48%] border border-gray-300 dark:border-gray-700 rounded-lg p-4"> | ||
<div className="flex items-center space-x-2 mb-2"> | ||
<Clock className="text-red-600 dark:text-red-700" /> | ||
<span className="font-semibold">Cleanup in:</span> | ||
</div> | ||
<div className="text-2xl font-bold">{formatTime(timeLeft)}</div> | ||
<div className="mt-2 bg-gray-200 dark:bg-gray-700 rounded-full h-2"> | ||
<div | ||
className="bg-red-600 dark:bg-red-700 h-2 rounded-full" | ||
style={{ width: `${(timeLeft / (15 * 60)) * 100}%` }} | ||
></div> | ||
</div> | ||
</div> | ||
<div className="w-[48%] border border-gray-300 dark:border-gray-700 rounded-lg p-4"> | ||
<div className="flex items-center space-x-2 mb-2"> | ||
<Command className="text-green-600 dark:text-green-600" /> | ||
<span className="font-semibold">Commands left:</span> | ||
</div> | ||
<div className="text-2xl font-bold">{commandsLeft}</div> | ||
<div className="mt-2 bg-gray-200 dark:bg-gray-700 rounded-full h-2"> | ||
<div | ||
className="bg-green-600 dark:bg-green-600 h-2 rounded-full" | ||
style={{ width: `${(commandsLeft / 1000) * 100}%` }} | ||
></div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<div className="h-96 bg-gray-100 rounded-lg overflow-hidden shadow-md"> | ||
<Cli decreaseCommandsLeft={decreaseCommandsLeft}/> | ||
</div> | ||
</div> | ||
<div className="flex flex-row justify-between text-gray-900 "> | ||
<div className="mt-4 flex justify-between border border-gray-400 text-sm bg-transparent p-3 rounded-lg"> | ||
<span>Cleanup in : {formatTime(timeLeft)} mins</span> | ||
|
||
<div className="space-y-4"> | ||
<div className="border rounded-lg p-4"> | ||
<SearchBox search={search} setSearch={setSearch} /> | ||
</div> | ||
<div className="mt-4 flex justify-between border border-gray-400 text-sm bg-transparent p-3 rounded-lg"> | ||
<span>Command left: {commandsLeft}</span> | ||
<div className="border rounded-lg p-4"> | ||
<h2 className="text-xl font-semibold mb-4">Recent Commands</h2> | ||
<ul className="space-y-2 border"> | ||
{['SELECT * FROM users', 'INSERT INTO products', 'UPDATE orders SET status = "shipped"'].map((cmd, index) => ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why's this required? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can use the browser session to populate recently run commands. I've just kept a placeholder array for now. Do you think this feature is worth implementing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now I'm not sure, let's create an issue out of it and we can pick this up later after we go live. |
||
<li key={index} className=" border p-2 rounded"> | ||
{cmd} | ||
</li> | ||
))} | ||
</ul> | ||
</div> | ||
</div> | ||
</div> | ||
<div className="w-1/2 flex flex-col"> | ||
<div className="flex-grow border border-gray-400 bg-gray-100 p-4 rounded-lg shadow-md mb-4"> | ||
<SearchBox search={search} setSearch={setSearch} /> | ||
</div> | ||
</div> | ||
</main> | ||
</main> | ||
</div> | ||
</div> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove the download functionality for now, please open an issue for this we can pick up later.