diff --git a/src/app/globals.css b/src/app/globals.css index 6b717ad..7bf3eac 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -9,7 +9,7 @@ @media (prefers-color-scheme: dark) { :root { - --background: #0a0a0a; + --background: #181818; --foreground: #ededed; } } @@ -19,3 +19,7 @@ body { background: var(--background); font-family: Arial, Helvetica, sans-serif; } + +.tofvesson-emph { + color: #FF6961 +} \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f7fa87e..e9cb75d 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,20 +1,20 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; +import { Doto, Orbitron } from "next/font/google"; import "./globals.css"; -const geistSans = Geist({ - variable: "--font-geist-sans", +const orbitron = Doto({ + variable: "--font-doto", subsets: ["latin"], }); -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], +const spaceGrotesk = Orbitron({ + variable: "--font-orbitron", + subsets: ["latin"] }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Tofvesson Family", + description: "Welcome to our humble, digital home!", }; export default function RootLayout({ @@ -25,7 +25,7 @@ export default function RootLayout({ return ( {children} diff --git a/src/app/page.tsx b/src/app/page.tsx index 3eee014..5d4649b 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,101 +1,57 @@ -import Image from "next/image"; +"use client"; +import Button from "@/components/button" +import TypeText from "@/components/typetext"; +import BlinkText from "@/components/blinktext"; +import Delay from "@/components/delay"; +import React from "react"; + +const names = [ + "citizen", + "Mikael", + "Niklas", + "Anna", + "Eva", + "Calle", + "Emma", + "Gabriel", + "Rebecca" +]; export default function Home() { - return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{" "} - - src/app/page.tsx - - . -
  2. -
  3. Save and see your changes instantly.
  4. -
+ React.useEffect(() => { + const handler = (e: Event) => e.preventDefault(); + document.addEventListener('contextmenu', handler); + return () => document.removeEventListener('contextmenu', handler); + }, []); -
- - Vercel logomark - Deploy now - - - Read our docs - + const [cycle, setCycle] = React.useState({ index: 0, show: true }); + const [showButton, setShowButton] = React.useState(false); + const [hideButton, setHideButton] = React.useState(false); + + return ( +
+
+
+ + { setShowButton(true); }}> Welcome, + { showButton &&
{ + if (!cycle.show) { + return setTimeout(setCycle, 200, { index: (cycle.index + 1) % names.length, show: true }); + } else { + return setTimeout(setCycle, 3000, { index: cycle.index, show: false }); + } + } }>{`${names[cycle.index]}!`}
} +
+
_
+
-
); } diff --git a/src/components/blinktext.tsx b/src/components/blinktext.tsx new file mode 100644 index 0000000..bac2643 --- /dev/null +++ b/src/components/blinktext.tsx @@ -0,0 +1,17 @@ +"use client"; +import React from "react"; + +export type BlinkTextProps = { children: any, interval: number, props?: React.HTMLAttributes }; +export default function BlinkText({ children, interval, props }: BlinkTextProps) { + const elementProps = props ? props : {}; + const [show, setShow] = React.useState(false); + React.useEffect(() => { + const intervalRef = setInterval(() => { + setShow(!show); + }, interval); + + return () => clearInterval(intervalRef); + }, [show]); + + return
{children}
+} \ No newline at end of file diff --git a/src/components/button.tsx b/src/components/button.tsx new file mode 100644 index 0000000..08dd0c8 --- /dev/null +++ b/src/components/button.tsx @@ -0,0 +1,34 @@ +import { ReactNode } from "react" + +export type ButtonProps = { children?: any, border?: boolean, invertColors?: boolean, href?: string, onClick?: React.MouseEventHandler, className?: string } + +export default function Button({ children, border, invertColors, href, onClick, className }: ButtonProps) { + return + { children } + +} \ No newline at end of file diff --git a/src/components/delay.tsx b/src/components/delay.tsx new file mode 100644 index 0000000..2d095d3 --- /dev/null +++ b/src/components/delay.tsx @@ -0,0 +1,30 @@ +"use client"; +import React from "react"; + +export type DelayProps = { children: any, delay?: number, useOpacity?: boolean, onComplete?: () => void, shouldWait?: boolean }; +export default function Delay({ children, delay, useOpacity, onComplete, shouldWait }: DelayProps) { + const [show, setShow] = React.useState(false); + React.useEffect(() => { + if (delay == undefined) { + return; + } + + if (shouldWait) { + return; + } + const intervalRef = setInterval(() => { + setShow(true); + if (onComplete) { + setInterval(onComplete, 0); + } + }, delay); + + return () => clearInterval(intervalRef); + }, [shouldWait, delay]); + + if (useOpacity) { + return
{children}
+ } + + return <>{show && children} +} \ No newline at end of file diff --git a/src/components/loading.tsx b/src/components/loading.tsx new file mode 100644 index 0000000..ea7826f --- /dev/null +++ b/src/components/loading.tsx @@ -0,0 +1,14 @@ +export type LoadingProps = React.HTMLAttributes + +export default function Loading(props: LoadingProps) { + console.log(props.className); + return ( +
+ + Loading... +
+ ) +} \ No newline at end of file diff --git a/src/components/typetext.tsx b/src/components/typetext.tsx new file mode 100644 index 0000000..e587fc1 --- /dev/null +++ b/src/components/typetext.tsx @@ -0,0 +1,31 @@ +"use client"; +import React from "react"; + +export type TypeTextProps = { children: string, interval: number | null, onComplete?: () => NodeJS.Timeout | void, reverse?: boolean }; +export default function TypeText({ children, interval, onComplete, reverse }: TypeTextProps) { + const [length, setLength] = React.useState(reverse ? children.length : 0); + React.useEffect(() => { + if (interval == null) { + return; + } + + if (length > children.length) { + setLength(children.length); + return; + } else if ((!reverse && length == children.length) || (reverse && length == 0)) { + if (onComplete) { + const onCompleteRef = onComplete(); + return onCompleteRef && (() => clearInterval(onCompleteRef)); + } + return; + } + + const intervalRef = setInterval(() => { + setLength(length + (reverse ? -1 : 1)); + }, interval); + + return () => clearInterval(intervalRef); + }, [length, children, reverse, interval]); + + return <>{children.substring(0, length)} +} \ No newline at end of file