Improved structure

This commit is contained in:
2026-02-07 00:40:37 +01:00
parent 3c7e964d1c
commit 9cf69fde7d
4 changed files with 56 additions and 25 deletions
+29 -12
View File
@@ -1,23 +1,40 @@
import { Card, CardContent } from "@/components/ui/card"; import { Card, CardContent } from "@/components/ui/card";
import { LiveRun } from "@/modules/live-run/types";
import { useEffect, useState } from "react";
export type RunInfo = { export default function RunTimer({ runInfo }: { runInfo: LiveRun }) {
category: "any%" | "100%"; const [time, setTime] = useState("00:00:00");
problems: number;
currentAttempt: number; useEffect(() => {
pbTime: string; // Update function calculates elapsed time
worldRecord: string; const updateTime = () => {
const elapsedMs = Date.now() - runInfo.start;
const totalSeconds = elapsedMs / 1000;
const hours = String(Math.floor(totalSeconds / 3600)).padStart(2, "0");
const minutes = String(Math.floor((totalSeconds % 3600) / 60)).padStart(
2,
"0",
);
const seconds = (totalSeconds % 60).toFixed(2);
setTime(
`${totalSeconds / 3600 >= 1 ? hours + ":" : ""}${minutes}:${seconds}`,
);
}; };
export default function RunTimer({ runInfo }: { runInfo: RunInfo }) { // Update immediately and then every second
updateTime();
const interval = setInterval(updateTime, 50);
return () => clearInterval(interval); // cleanup on unmount
}, [runInfo.start]);
return ( return (
<Card className="relative text-center overflow-hidden"> <Card className="relative text-center overflow-hidden">
<div className="absolute inset-0 bg-linear-to-b from-primary/5 to-transparent pointer-events-none" /> <div className="absolute inset-0 bg-linear-to-b from-primary/5 to-transparent pointer-events-none" />
<CardContent className="relative"> <CardContent className="relative">
<p className="timer-display text-primary text-4xl font-bold">1:52.34</p> <p className="timer-display text-primary text-4xl font-bold">{time}</p>
<p className="mt-2 font-mono text-sm text-muted-foreground">
PB: {runInfo.pbTime} | Diff:{" "}
<span className="text-red-400">+0:12</span>
</p>
</CardContent> </CardContent>
</Card> </Card>
); );
+6 -9
View File
@@ -1,20 +1,16 @@
"use client"; "use client";
import { Card, CardContent } from "@/components/ui/card"; import { Card, CardContent } from "@/components/ui/card";
import RunTimer, { RunInfo } from "./components/RunTimer"; import RunTimer from "./components/RunTimer";
import RunChat, { ChatMessage } from "./components/RunChat"; import RunChat, { ChatMessage } from "./components/RunChat";
import { FileTree } from "./components/FileTree"; import { FileTree } from "./components/FileTree";
import { File } from "lucide-react"; import { File } from "lucide-react";
import Editor from "./components/Editor"; import Editor from "./components/Editor";
import useAction from "@/hook/use-action";
import { getLiveRun } from "@/modules/live-run/actions";
export default function Run() { export default function Run() {
const runInfo: RunInfo = { const [runInfo] = useAction(getLiveRun);
category: "any%",
problems: 5,
pbTime: "4:35",
worldRecord: "3:58",
currentAttempt: 47,
};
const chatMessages: ChatMessage[] = [ const chatMessages: ChatMessage[] = [
{ user: "Alice", message: "Nice split!", time: "1:53" }, { user: "Alice", message: "Nice split!", time: "1:53" },
@@ -59,7 +55,8 @@ export default function Run() {
{/* Timer & Chat */} {/* Timer & Chat */}
<div className="flex flex-col gap-6 h-full w-sm"> <div className="flex flex-col gap-6 h-full w-sm">
<RunTimer runInfo={runInfo} /> {runInfo && <RunTimer runInfo={runInfo} />}
{/* {runInfo && <ProblemCard {...runInfo.problem} />} */}
<RunChat chatMessages={chatMessages} /> <RunChat chatMessages={chatMessages} />
</div> </div>
</div> </div>
+12 -3
View File
@@ -3,8 +3,7 @@
import { createClient } from "@/lib/supabase/server"; import { createClient } from "@/lib/supabase/server";
import { getSession, getSessionRedirect } from "../account/core"; import { getSession, getSessionRedirect } from "../account/core";
import * as Core from "./core"; import * as Core from "./core";
import { Run } from "./types"; import { LiveRun, Run } from "./types";
import { redirect } from "next/navigation";
export async function getLiveRuns(): Promise<Run[]> { export async function getLiveRuns(): Promise<Run[]> {
const supabase = await createClient(); const supabase = await createClient();
@@ -51,6 +50,16 @@ export async function getLiveRuns(): Promise<Run[]> {
]; ];
} }
export async function getLiveRun(): Promise<LiveRun> {
return {
username: "selimaj",
start: new Date().getTime(),
problem: "solve",
category: "any%",
runsCount: 0,
};
}
export async function getLiveRunMoves() { export async function getLiveRunMoves() {
const code = `// Import the necessary React library features const code = `// Import the necessary React library features
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
@@ -77,7 +86,7 @@ root.render(<App />);`.repeat(3);
} }
return chunks.map((chunk, index) => ({ return chunks.map((chunk, index) => ({
latency: 1, // 100ms per chunk latency: 120, // 100ms per chunk
cursor: index * 4, // approximate cursor position cursor: index * 4, // approximate cursor position
changes: { changes: {
from: index * 4, from: index * 4,
+8
View File
@@ -1,3 +1,11 @@
export interface LiveRun {
username: string;
start: number;
runsCount: number;
problem: string;
category: "any%" | "100%";
}
export interface Run { export interface Run {
id: number; id: number;
username: string; username: string;