aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/create
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/create')
-rw-r--r--src/app/create/page.styles.ts168
-rw-r--r--src/app/create/page.tsx207
2 files changed, 0 insertions, 375 deletions
diff --git a/src/app/create/page.styles.ts b/src/app/create/page.styles.ts
deleted file mode 100644
index b54e095..0000000
--- a/src/app/create/page.styles.ts
+++ /dev/null
@@ -1,168 +0,0 @@
-import styled from "styled-components";
-
-export const Content = styled.div`
- max-width: 600px;
- margin: 40px auto;
- padding: 0 24px 60px;
-`;
-
-export const Heading = styled.h1`
- font-size: 22px;
- font-weight: 800;
- margin: 0 0 4px;
-`;
-
-export const Subheading = styled.p`
- font-size: 13px;
- color: #909090;
- margin: 0 0 32px;
-`;
-
-export const Form = styled.div`
- display: flex;
- flex-direction: column;
- gap: 14px;
-`;
-
-export const FieldGroup = styled.div`
- display: flex;
- flex-direction: column;
- gap: 5px;
-`;
-
-export const Label = styled.label`
- font-size: 12px;
- font-weight: 600;
- color: #606060;
- text-transform: uppercase;
- letter-spacing: 0.5px;
-`;
-
-export const Input = styled.input`
- height: 40px;
- padding: 0 12px;
- border: 1px solid #d4d4d4;
- border-radius: 8px;
- font-size: 14px;
- color: #1a1a1a;
- background-color: #fff;
- transition: border-color 0.15s;
- &:focus {
- outline: none;
- border-color: #1a1a1a;
- }
- &::placeholder {
- color: #b0b0b0;
- }
-`;
-
-export const Divider = styled.div`
- height: 1px;
- background-color: #e5e5e5;
- margin: 6px 0;
-`;
-
-export const Row = styled.div`
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 12px;
-`;
-
-export const GenerateButton = styled.button`
- height: 42px;
- padding: 0 24px;
- border-radius: 10px;
- border: none;
- background-color: #1a1a1a;
- color: #fff;
- font-size: 14px;
- font-weight: 600;
- cursor: pointer;
- transition: background-color 0.15s;
- margin-top: 6px;
- &:hover {
- background-color: #333;
- }
-`;
-
-export const ModeButton = styled.button<{ $active: boolean }>`
- height: 42px;
- padding: 0 24px;
- border-radius: 10px;
- border: none;
- cursor: pointer;
- font-size: 14px;
- font-weight: 600;
- background-color: ${(p) => (p.$active ? "#1a1a1a" : "#e5e5e5")};
- color: ${(p) => (p.$active ? "#fff" : "#1a1a1a")};
- transition: background-color 0.15s;
-`;
-
-export const OutputSection = styled.div`
- margin-top: 32px;
- display: flex;
- flex-direction: column;
- gap: 14px;
-`;
-
-export const OutputLabel = styled.div`
- font-size: 12px;
- font-weight: 600;
- color: #606060;
- text-transform: uppercase;
- letter-spacing: 0.5px;
- margin-bottom: 5px;
-`;
-
-export const CodeBox = styled.div`
- position: relative;
- background-color: #f0f0f0;
- border: 1px solid #d4d4d4;
- border-radius: 10px;
- padding: 14px 48px 14px 14px;
- font-family: "Courier New", monospace;
- font-size: 13px;
- color: #1a1a1a;
- word-break: break-all;
- line-height: 1.5;
-`;
-
-export const CopyButton = styled.button<{ $copied: boolean }>`
- position: absolute;
- top: 10px;
- right: 10px;
- width: 30px;
- height: 30px;
- border-radius: 6px;
- border: none;
- background-color: ${(p) => (p.$copied ? "#22c55e" : "#d4d4d4")};
- color: ${(p) => (p.$copied ? "#fff" : "#606060")};
- font-size: 13px;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: background-color 0.15s, color 0.15s;
- &:hover {
- background-color: ${(p) => (p.$copied ? "#16a34a" : "#c0c0c0")};
- color: #1a1a1a;
- }
-`;
-
-export const OpenLink = styled.a`
- display: inline-flex;
- align-items: center;
- gap: 6px;
- font-size: 13px;
- font-weight: 500;
- color: #1a1a1a;
- text-decoration: none;
- border: 1px solid #d4d4d4;
- border-radius: 8px;
- padding: 8px 14px;
- background-color: #fff;
- transition: background-color 0.15s;
- &:hover {
- background-color: #f0f0f0;
- }
-`;
diff --git a/src/app/create/page.tsx b/src/app/create/page.tsx
deleted file mode 100644
index 744ab95..0000000
--- a/src/app/create/page.tsx
+++ /dev/null
@@ -1,207 +0,0 @@
-"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<string | null>(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 (
- <Root>
- <Navbar>
- <Logo href="/typing">
- <LogoIcon>
- <MdLibraryMusic />
- </LogoIcon>
- LRC-Type
- </Logo>
- <NavLink href="/typing">← Back</NavLink>
- </Navbar>
-
- <Content>
- <Heading>Create a Code</Heading>
- <Subheading>
- Generate a shareable code for your typing game session.
- </Subheading>
-
- <Form>
- <FieldGroup>
- <Label>Primary Media</Label>
- <Input
- type="url"
- placeholder="https://example.com/song.mp4"
- value={file1}
- onChange={(e) => setFile1(e.target.value)}
- />
- </FieldGroup>
-
- <FieldGroup>
- <Label>LRC Lyrics</Label>
- <Input
- type="url"
- placeholder="https://example.com/song.lrc"
- value={lrc}
- onChange={(e) => setLrc(e.target.value)}
- />
- </FieldGroup>
-
- <FieldGroup>
- <Label title="Offset in milliseconds. Increase this value if the main audio is ahead of the lyrics.">
- LRC Offset (ms)
- </Label>
- <Input
- type="number"
- placeholder="0"
- value={offset}
- onChange={(e) => setOffset(e.target.value)}
- step="25"
- />
- </FieldGroup>
-
- <Divider />
-
- <Row>
- <FieldGroup>
- <Label>Title</Label>
- <Input
- type="text"
- placeholder="Song Title"
- value={typingTitle}
- onChange={(e) => setTypingTitle(e.target.value)}
- />
- </FieldGroup>
- <FieldGroup>
- <Label>Artist</Label>
- <Input
- type="text"
- placeholder="Artist Name"
- value={typingArtist}
- onChange={(e) => setTypingArtist(e.target.value)}
- />
- </FieldGroup>
- </Row>
-
- <Row>
- <FieldGroup>
- <Label title="When enabled, lyrics inside parentheses are treated as backing lyrics and skipped.">
- Skip Backing
- </Label>
- <Input
- type="checkbox"
- checked={skipBacking}
- onChange={(e) => setSkipBacking(e.target.checked)}
- style={{ width: "18px", height: "18px", marginTop: "10px" }}
- />
- </FieldGroup>
- </Row>
-
- <GenerateButton onClick={generate}>Generate Code</GenerateButton>
- </Form>
-
- {code && (
- <OutputSection>
- <div>
- <OutputLabel>Code</OutputLabel>
- <CodeBox>
- {code}
- <CopyButton
- $copied={copiedCode}
- onClick={() => copy(code, "code")}
- aria-label="Copy code"
- >
- {copiedCode ? <FaCheck /> : <FaCopy />}
- </CopyButton>
- </CodeBox>
- </div>
-
- <div>
- <OutputLabel>Share URL</OutputLabel>
- <CodeBox>
- {shareUrl}
- <CopyButton
- $copied={copiedUrl}
- onClick={() => copy(shareUrl, "url")}
- aria-label="Copy URL"
- >
- {copiedUrl ? <FaCheck /> : <FaCopy />}
- </CopyButton>
- </CodeBox>
- </div>
-
- <OpenLink href={shareUrl} target="_blank" rel="noopener noreferrer">
- <FaExternalLinkAlt /> Open in Typing Game
- </OpenLink>
- </OutputSection>
- )}
- </Content>
- </Root>
- );
-}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage