summaryrefslogtreecommitdiffhomepage
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/App.jsx7
-rw-r--r--src/components/Blogs.jsx66
-rw-r--r--src/components/Button.jsx15
-rw-r--r--src/components/Game.jsx23
-rw-r--r--src/components/GameCard.jsx26
-rw-r--r--src/components/Games.jsx93
-rw-r--r--src/components/Home.jsx43
-rw-r--r--src/components/Layout.jsx60
-rw-r--r--src/components/index.jsx10
9 files changed, 343 insertions, 0 deletions
diff --git a/src/components/App.jsx b/src/components/App.jsx
new file mode 100644
index 0000000..da6a873
--- /dev/null
+++ b/src/components/App.jsx
@@ -0,0 +1,7 @@
+import React from "react";
+import Routes from "../routes";
+
+export default (props) => {
+ return (<Routes />);
+}
+
diff --git a/src/components/Blogs.jsx b/src/components/Blogs.jsx
new file mode 100644
index 0000000..f52f286
--- /dev/null
+++ b/src/components/Blogs.jsx
@@ -0,0 +1,66 @@
+import React, { useState, useEffect } from "react";
+import { Link, useNavigate } from "react-router-dom";
+
+const Blogs = () => {
+ const navigate = useNavigate();
+ const [blogs, setBlogs] = useState([]);
+
+ useEffect(() => {
+ const url = "/api/v1/blogs/index";
+ fetch(url).then((response) => {
+ if (response.ok) {
+ return response.json();
+ }
+ throw new Error("Network response was not ok.");
+ }).then((response) => setBlogs(response)).catch(() => navigate("/"));
+ }, []);
+
+ const allBlogs = blogs.map((blog, index) => (
+ <div key={index} className="col-md-6 col-lg-4">
+ <div className="card mb-4">
+ <img src={blog.image} className="card-img-top" alt={`${blog.name} image`}/>
+ <div className="card-body">
+ <h5 className="card-title">{blog.name}</h5>
+ <Link to={`/blog/${blog.id}`} className="btn custom-button">
+ View Post
+ </Link>
+ </div>
+ </div>
+ </div>
+ ));
+ const noBlog = (
+ <div className="vw-100 vh-50 dflex align-items-center justify-content-center">
+ <h4> Nothing Yet! </h4>
+ </div>
+ );
+
+ return (
+ <>
+ <section className="jumbotron jumbotron-fluid text-center">
+ <div className="container py-5">
+ <h1 className="display-4">Welcome to my Blog</h1>
+ <p className="lead text-muted">
+ Yup, this is my blog and stuff. Enjoy it :)
+ </p>
+ </div>
+ </section>
+ <div className="py-5">
+ <main className="container">
+ <div className="text-end mb-3">
+ <Link to="/blog" className="btn custom-button">
+ Write New Blog
+ </Link>
+ </div>
+ <div className="row">
+ {blogs.length > 0 ? allBlogs : noBlog}
+ </div>
+ <Link to="/" className="btn btn-link">
+ Home
+ </Link>
+ </main>
+ </div>
+ </>
+ );
+};
+
+export default Blogs;
diff --git a/src/components/Button.jsx b/src/components/Button.jsx
new file mode 100644
index 0000000..de199d0
--- /dev/null
+++ b/src/components/Button.jsx
@@ -0,0 +1,15 @@
+import React from "react";
+import { Link } from "react-router-dom";
+
+export default function Button ({ link, width = 36, height = 16, spinner = 4 })
+{
+ return (
+ <>
+ <div className={`w-${ width } h-${ height } relative grid rounded-[5px] cursor-pointer overflow-hidden place-items-center before:content-[''] before:absolute before:w-${ spinner } before:bg-amber-400 before:rotate-[32deg] before:h-[1%] before:transition-all before:duration-500 before:ease-linear before:animate-[buttonSpin_1.5s_linear_infinite] hover:before:h-[2800%] hover:before:transition-all hover:before:duration-0 hover:before:ease-linear after:absolute after:content-[''] after:bg-stone-800 after:rounded-[5px] after:inset-0 after:transition-all after:duration-200 after:ease-in-out hover:after:inset-[5px] hover:after:transition-all hover:after:duration-200 hover:after:ease-in-out`}>
+ <div className="z-[3]">
+ { link }
+ </div>
+ </div>
+ </>
+ )
+};
diff --git a/src/components/Game.jsx b/src/components/Game.jsx
new file mode 100644
index 0000000..8b80b8e
--- /dev/null
+++ b/src/components/Game.jsx
@@ -0,0 +1,23 @@
+import React, { useState, useEffect } from "react";
+import { useParams } from "react-router-dom";
+//import { Link } from "react-router-dom";
+import GameCard from "./GameCard";
+import Button from "./Button";
+
+//<Route path="/games/:user/:game" element={<Game />} />
+
+//export default () => (
+export default function Games () {
+ let { user, game } = useParams();
+//http://localhost:3000/api/v1/game/realtradam/orc-arena-of-time/index.html
+ return(
+ <>
+ <div>
+ <div className="flex flex-col gap-16 max-w-6xl shrink">
+ <div className="title font-bold text-6xl font-title">Orc: Arena of Time</div>
+ <iframe style={{ aspectRatio: 1 }} className="bg-black aspect-square max-h-[90vh] rounded" src="http://localhost:3000/api/v1/game/realtradam/orc-arena-of-time/index.html" title={game}></iframe>
+ </div>
+ </div>
+ </>
+ );
+};
diff --git a/src/components/GameCard.jsx b/src/components/GameCard.jsx
new file mode 100644
index 0000000..9cd815d
--- /dev/null
+++ b/src/components/GameCard.jsx
@@ -0,0 +1,26 @@
+import React from "react";
+//import { Link } from "react-router-dom";
+
+//game = {
+// card_img: "",
+// char_img: "",
+// title_img: ""
+//}
+
+export default function GameCard ({ link = "./", width = "72", game = { card_img: "https://ggayane.github.io/css-experiments/cards/dark_rider-cover.jpg", char_img: "https://ggayane.github.io/css-experiments/cards/dark_rider-character.png", title_img: "https://ggayane.github.io/css-experiments/cards/dark_rider-title.png" } })
+{
+
+ return (
+ <>
+ <a href={ link } className="block w-min pt-10 px-1" target="_blank">
+ <div className="gameCard">
+ <div className="gameCardWrapper">
+ <img src={`/api/v1/games_img/realtradam/${game.titleSlug}.png?type=card`} className="gameCardCoverImg" />
+ </div>
+ <img src={`/api/v1/games_img/realtradam/${game.titleSlug}.png?type=title`} className="gameTitleImg p-5%" />
+ <img src={`/api/v1/games_img/realtradam/${game.titleSlug}.png?type=char`} className="gameCharacterImg" />
+ </div>
+ </a>
+ </>
+ )
+};
diff --git a/src/components/Games.jsx b/src/components/Games.jsx
new file mode 100644
index 0000000..f1545b8
--- /dev/null
+++ b/src/components/Games.jsx
@@ -0,0 +1,93 @@
+import React, { useState, useEffect } from "react";
+//import { Link } from "react-router-dom";
+import GameCard from "./GameCard";
+import Button from "./Button";
+
+//export default () => (
+export default function Games () {
+ const [games, setGames] = useState([]);
+ useEffect(() => {
+ const url = "/api/v1/games";
+ fetch(url).then((response) => {
+ if (response.ok) {
+ return response.json();
+ }
+ throw new Error("Network response was not ok.");
+ }).then((response) => setGames(response)).catch(() => navigate("/"));
+ }, []);
+ const allGames = games.map((game) => (
+ <GameCard game={game} key={game.id}/>
+ ));
+ var handleSubmit = (e) => {
+ e.preventDefault() //stops submit from happening
+ const form = e.target;
+ const formData = new FormData()
+ formData.append('game[title]', form.title.value)
+ for(let i =0; i < form.game_files.files.length; i++)
+ {
+ formData.append('game[game_files][]', form.game_files.files[i], form.game_files.files[i].value);
+ }
+ formData.append('game[card_img]', form.card_img.files[0], form.card_img.value);
+ formData.append('game[char_img]', form.char_img.files[0], form.char_img.value);
+ formData.append('game[title_img]', form.title_img.files[0], form.title_img.value);
+
+ for (var pair of formData.entries()) {
+ console.log(pair[0] + ', ' + pair[1])
+ };
+
+ fetch('http://127.0.0.1:3000/api/v1/games', {
+ method: 'post',
+ body: formData,
+ });
+ }
+ return(
+ <>
+ <div>
+ <div className="flex flex-col gap-16 max-w-6xl shrink">
+ <div className="title font-bold text-6xl font-title">Games</div>
+ <div className="">
+ <div className="jumbotron jumbotron-fluid bg-transparent">
+ <div className="container secondary-color">
+ <form onSubmit={handleSubmit} action="/upload" method="post" className="flex flex-col gap-4">
+ <div>
+ <label>Title</label>
+ <input type="text" name="title" />
+ </div>
+ <div>
+ <label>Files</label>
+ <input type="file" multiple="multiple" name="game_files" />
+ </div>
+ <div>
+ <label>Card Image</label>
+ <input type="file" name="card_img" />
+ </div>
+ <div>
+ <label>Character Image</label>
+ <input type="file" name="char_img" />
+ </div>
+ <div>
+ <label>Title Image</label>
+ <input type="file" name="title_img" />
+ </div>
+ <div style={{ boxShadow: 'rgba(255,255,255,.1) 0 1px 0,rgba(0,0,0,.8) 0 1px 7px 0 inset' }} className="p-[5px] w-min h-min bg-stone-800 rounded-[5px]">
+ <Button width={ 28 } height={ 12 } link={ <button type="submit" className="w-28 h-12 bg-stone-transparent text-stone-50 rounded">Submit</button> }/>
+ </div>
+
+ </form>
+ </div>
+ </div>
+ </div>
+ { allGames }
+ <div className="flex flex-row flex-wrap gap-20 justify-around">
+ <GameCard />
+ <GameCard />
+ <GameCard />
+ <GameCard />
+ <GameCard />
+ <GameCard />
+ </div>
+ </div>
+ </div>
+ </>
+ );
+};
diff --git a/src/components/Home.jsx b/src/components/Home.jsx
new file mode 100644
index 0000000..863d81d
--- /dev/null
+++ b/src/components/Home.jsx
@@ -0,0 +1,43 @@
+import React, { } from "react";
+//import { Link } from "react-router-dom";
+import GameCard from "./GameCard";
+
+//export default () => (
+export default function Home () {
+ var handleSubmit = (e) => {
+ e.preventDefault() //stops submit from happening
+
+ const formData = new FormData()
+ formData.append('game[title]', e.target.title.value)
+ formData.append('game[game_file]', e.target.game_file.files[0], e.target.game_file.value)
+
+ for (var pair of formData.entries()) {
+ console.log(pair[0] + ', ' + pair[1])
+ };
+
+ fetch('http://127.0.0.1:3000/api/v1/games', {
+ method: 'post',
+ body: formData,
+ });
+ }
+ return(
+ <>
+ <div>
+ <div className="flex flex-col gap-16 max-w-6xl shrink">
+ <div className="title font-bold text-6xl font-title">Get To Know Me a Little</div>
+ <div className="">
+ <div className="jumbotron jumbotron-fluid bg-transparent">
+ <div className="container secondary-color">
+ <h1 className="text-2xl">Debug! Again</h1>
+ <p className="">
+Ea optio vitae culpa voluptatem consectetur. Ab quisquam sed ipsum. Perspiciatis minus odit quas qui consequuntur dicta reiciendis a. Nihil minima sed aliquam.
+ </p>
+ <hr className="my-4" />
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </>
+ );
+};
diff --git a/src/components/Layout.jsx b/src/components/Layout.jsx
new file mode 100644
index 0000000..79e7813
--- /dev/null
+++ b/src/components/Layout.jsx
@@ -0,0 +1,60 @@
+import React from "react";
+import { Outlet, Link } from "react-router-dom";
+import Button from "./Button";
+export default function Layout ({userData})
+{
+ console.log(userData);
+ //const [userData, setUserData] = useState({ name: "" });
+
+ // if the user tries to access the isolated domain then we redirect them
+ // this is NOT done for security, only for good UX
+ // rails serves the react app no matter what
+ // so the app would be broken when served on the isolated domain
+ const domain = window.location.host;
+ console.log(domain);
+ if(domain === "localhost:3000")
+ {
+ window.location.replace("http://127.0.0.1:3000");
+ }
+
+ return (
+ <>
+ <div id="page" className="star flex flex-row min-h-screen max-h-screen bg-amber-400 text-stone-950 text-xl bg-star bg-repeat bg-[length:170px_170px]">
+ <div id="sidebar" className="flex flex-row shrink-0 grow-0 h-vh w-64 items-top bg-stone-800">
+ <nav id="sidebar-content" dir="rtl" className="text-stone-50 p-6 w-full h-screen overflow-y-auto overflow-x-hidden">
+ <div dir='ltr'>
+ { userData.name ? <div className="flex items-end gap-2 pb-2"> <div className="text-xs"> Logged in as: </div> <div>{userData.name}</div> </div> : <a href="https://github.com/login/oauth/authorize?client_id=74468ad0847e527262d9" className="pb-2"> Login with Github </a> }
+ <div className="text-3xl py-10 text-center font-title">Adam Malczewski</div>
+ <div className="flex flex-col items-center gap-1 w-full">
+ <Button link={ <Link to="/" className="absolute flex top-0 left-0 w-36 h-16 text-stone-50 bg-transparent justify-center items-center" role="button"><div className="h-min">About Me</div></Link> }/>
+ <Button link={ <Link to="/blogs" className="absolute flex top-0 left-0 w-36 h-16 text-stone-50 bg-transparent justify-center items-center" role="button"><div className="h-min">Blog</div></Link> }/>
+ <Button link={ <Link to="/games" className="absolute flex top-0 left-0 w-36 h-16 text-stone-50 bg-transparent justify-center items-center" role="button"><div className="h-min">Games</div></Link> }/>
+ <Button link={ <div className="text-stone-50 bg-transparent w-36 h-16 flex justify-center items-center">
+ <a id="contact" href="mailto:[email protected]" className="w-36 h-16 relative text-center whitespace-nowrap flex justify-center items-center">
+ <div className="contact w-36 h-16 flex items-center justify-center">
+ <span className="h-min">Contact</span>
+ </div>
+ <div className="contact w-36 h-16 flex items-center justify-center">
+ <span className="text-sm h-min">[email protected]</span>
+ </div>
+ </a>
+ </div> }/>
+ <div className="socials flex flex-row place-content-center gap-1">
+ <Button link={<a id="contact" href="https://github.com/realtradam" className="absolute flex top-0 left-0 w-10 h-16 text-stone-50 bg-transparent justify-center items-center"><i className="fa-brands fa-github"></i></a>} width={10} height={16} spinner={3}/>
+ <Button link={<a id="contact" href="https://www.linkedin.com/in/adammalczewski/" className="absolute flex top-0 left-0 w-10 h-16 text-stone-50 bg-transparent justify-center items-center"><i className="fa-brands fa-linkedin"></i></a>} width={10} height={16} spinner={3}/>
+ <Button link={<a id="contact" href="https://tradam.itch.io" className="absolute flex top-0 left-0 w-10 h-16 text-stone-50 bg-transparent justify-center items-center"><i className="fa-brands fa-itch-io"></i></a>} width={10} height={16} spinner={3}/>
+ </div>
+ </div>
+ </div>
+ </nav>
+ <div id="sawtooth-wrap" className="sawtooth-left-wrap h-full">
+ <div id="sawtooth" className="sawtooth-left w-4 h-full bg-amber-400"></div>
+ </div>
+ </div>
+ <div id="radial-wrap" className="shrink w-full max-h-vh h-vh overflow-auto overflow-x-hidden">
+ <div id="content" className="flex justify-center items-center w-full p-20"> <Outlet /> </div>
+ </div>
+ </div>
+ </>
+ )
+};
diff --git a/src/components/index.jsx b/src/components/index.jsx
new file mode 100644
index 0000000..0044916
--- /dev/null
+++ b/src/components/index.jsx
@@ -0,0 +1,10 @@
+import React from "react";
+import { createRoot } from "react-dom/client";
+import App from "./App";
+
+document.addEventListener("turbo:load", () => {
+ const root = createRoot(
+ document.body.appendChild(document.createElement("div"))
+ );
+ root.render(<App />);
+});