From 0d35e75edbc75f186e4a1ed52fbc3549ee9f5cd6 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Mon, 1 Jun 2026 21:19:05 -0700 Subject: init commit --- src/app/create/page.tsx | 207 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 src/app/create/page.tsx (limited to 'src/app/create/page.tsx') diff --git a/src/app/create/page.tsx b/src/app/create/page.tsx new file mode 100644 index 0000000..744ab95 --- /dev/null +++ b/src/app/create/page.tsx @@ -0,0 +1,207 @@ +"use client"; +import { useState } from "react"; +import { MdLibraryMusic } from "react-icons/md"; +import { FaCopy, FaCheck, FaExternalLinkAlt } from "react-icons/fa"; +import { Root, Navbar, Logo, LogoIcon, NavLink } from "../styles/shared"; +import { + Content, + Heading, + Subheading, + Form, + FieldGroup, + Label, + Input, + Divider, + Row, + GenerateButton, + OutputSection, + OutputLabel, + CodeBox, + CopyButton, + OpenLink, +} from "./page.styles"; + +interface TypingPayload { + file1?: string; + lrc?: string; + offset?: number; + title?: string; + artist?: string; + skip_backing?: boolean; +} + +export default function CreatePage() { + const [lrc, setLrc] = useState(""); + const [file1, setFile1] = useState(""); + const [offset, setOffset] = useState(""); + + const [typingTitle, setTypingTitle] = useState(""); + const [typingArtist, setTypingArtist] = useState(""); + const [skipBacking, setSkipBacking] = useState(true); + + const [code, setCode] = useState(null); + const [copiedCode, setCopiedCode] = useState(false); + const [copiedUrl, setCopiedUrl] = useState(false); + + const resetCopyStates = () => { + setCopiedCode(false); + setCopiedUrl(false); + }; + + const generate = () => { + const payload: TypingPayload = {}; + if (file1.trim()) payload.file1 = file1.trim(); + if (lrc.trim()) payload.lrc = lrc.trim(); + if (offset.trim() !== "") payload.offset = Number(offset); + if (typingTitle.trim()) payload.title = typingTitle.trim(); + if (typingArtist.trim()) payload.artist = typingArtist.trim(); + payload.skip_backing = skipBacking; + + setCode(btoa(JSON.stringify(payload))); + resetCopyStates(); + }; + + const copy = (text: string, which: "code" | "url") => { + navigator.clipboard.writeText(text); + if (which === "code") { + setCopiedCode(true); + setTimeout(() => setCopiedCode(false), 2000); + } else { + setCopiedUrl(true); + setTimeout(() => setCopiedUrl(false), 2000); + } + }; + + const shareUrl = code ? `${window.location.origin}/game?code=${code}` : ""; + + return ( + + + + + + + LRC-Type + + ← Back + + + + Create a Code + + Generate a shareable code for your typing game session. + + +
+ + + setFile1(e.target.value)} + /> + + + + + setLrc(e.target.value)} + /> + + + + + setOffset(e.target.value)} + step="25" + /> + + + + + + + + setTypingTitle(e.target.value)} + /> + + + + setTypingArtist(e.target.value)} + /> + + + + + + + setSkipBacking(e.target.checked)} + style={{ width: "18px", height: "18px", marginTop: "10px" }} + /> + + + + Generate Code + + + {code && ( + +
+ Code + + {code} + copy(code, "code")} + aria-label="Copy code" + > + {copiedCode ? : } + + +
+ +
+ Share URL + + {shareUrl} + copy(shareUrl, "url")} + aria-label="Copy URL" + > + {copiedUrl ? : } + + +
+ + + Open in Typing Game + +
+ )} +
+
+ ); +} -- cgit v1.2.3