diff --git a/api/main.ts b/api/main.ts index 61153c6..a037abe 100644 --- a/api/main.ts +++ b/api/main.ts @@ -15,7 +15,7 @@ type AppState = { const router = new Router(); -const hostname = "localhost"; +const hostname = "forums.warabi.co"; const authPath = "/auth"; const port = 8000; @@ -41,8 +41,8 @@ export interface SteamUser { } export const Steam = new SteamAuth({ - realm: `http://${hostname}:${port}`, - returnUrl: `http://${hostname}:${port}${authPath}/return`, + realm: `https://${hostname}`, + returnUrl: `https://${hostname}${authPath}/return`, apiKey: Deno.env.get("STEAM_API_KEY"), }); @@ -50,6 +50,7 @@ router.get(`${authPath}/login`, async (ctx) => { try { const redirectUrl = await Steam.getRedirectUrl() as string; ctx.response.body = { url: redirectUrl }; + console.log("Redirecting to:", redirectUrl); } catch (e) { ctx.response.body = `Error: ${e}`; } @@ -57,10 +58,13 @@ router.get(`${authPath}/login`, async (ctx) => { router.get(`${authPath}/return`, async (ctx) => { try { + console.log("Authenticating user..."); const user = await Steam.authenticate(ctx) as SteamUser; + console.log(user); ctx.state.session.set("steamid", user.steamid); ctx.state.session.set("user", user); - ctx.response.redirect(`http://localhost:5173/signedIn`); + console.log("Authenticated user:", user); + ctx.response.redirect("/"); } catch (e) { ctx.response.body = `Error: ${e}`; } @@ -93,11 +97,7 @@ router.get("/api/dinosaurs/:dinosaur", (context) => { }); const store = new CookieStore(Deno.env.get("SESSION_COOKIE_KEY") as string, { - sessionDataCookieName: "warbforums_sessionData", - cookieSetDeleteOptions: { - sameSite: "none", - secure: true, - }, + sessionDataCookieName: "warbforums_sessionData" }); const app = new Application(); diff --git a/package.json b/package.json index c68859b..65d983d 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "deno task dev:api & deno task dev:vite", "dev:api": "deno run --allow-env --allow-read --allow-net api/main.ts", - "dev:vite": "deno run -A npm:vite", + "dev:vite": "deno run -A npm:vite --host", "build": "tsc -b && vite build", "serve": "deno task build && deno task dev:api", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", diff --git a/src/App.tsx b/src/App.tsx index 3b65804..14254b4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,16 +1,18 @@ import { createContext, useEffect, useState } from "react"; -import React, { BrowserRouter, Route, Routes } from "react-router-dom"; +import React from "react"; +import { BrowserRouter, Route, Routes } from "react-router-dom"; import Index from "./pages/index.tsx"; import Dinosaur from "./pages/Dinosaur.tsx"; -import "./App.css"; import AuthSuccess from "./pages/AuthSuccess.tsx"; -import type { SteamUser } from "../api/main.ts"; import Profile from "./pages/Profile.tsx"; +import Header from "./components/Header.tsx"; +import "./App.css"; +import type { SteamUser } from "../api/main.ts"; export const UserContext = createContext<{ user: SteamUser | undefined; - setUser: any; -}>({ user: undefined, setUser: () => {} }); + setUser: React.Dispatch>; +}>({ user: undefined, setUser: () => { } }); function App() { const [user, setUser] = useState(); @@ -35,13 +37,15 @@ function App() { return ( -

Welcome to the Dinosaur App

- - } /> - } /> - } /> - } /> - +
+
+ + } /> + } /> + } /> + } /> + +
); diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx new file mode 100644 index 0000000..401a873 --- /dev/null +++ b/src/components/Avatar.tsx @@ -0,0 +1,12 @@ +import React, { useContext } from "react"; +import { UserContext } from "../App.tsx"; + +export default function Avatar() { + const { user } = useContext(UserContext); + + return ( +
+ User avatar +
+ ) +} \ No newline at end of file diff --git a/src/components/Header.tsx b/src/components/Header.tsx new file mode 100644 index 0000000..cd4b470 --- /dev/null +++ b/src/components/Header.tsx @@ -0,0 +1,22 @@ +import React, { useContext } from "react"; +import { Link } from "react-router-dom"; +import { UserContext } from "../App.tsx"; +import Avatar from "./Avatar.tsx"; +import SignIn from "./SignIn.tsx"; + +const Header = () => { + const { user } = useContext(UserContext); + + return ( +
+

+ Dinosaur App +

+
+ {user ? : } +
+
+ ); +}; + +export default Header; \ No newline at end of file diff --git a/src/components/SignIn.tsx b/src/components/SignIn.tsx new file mode 100644 index 0000000..682e4e5 --- /dev/null +++ b/src/components/SignIn.tsx @@ -0,0 +1,32 @@ +import React, { useContext } from "react"; +import { UserContext } from "../App.tsx"; + +export default function SignIn() { + const { user } = useContext(UserContext); + + const printUser = async () => { + console.log(user); + }; + + const handleLogin = async () => { + try { + const response = await fetch("/auth/login"); + if (!response.ok) { + throw new Error("Failed to fetch authorization URL"); + } + const { url } = await response.json(); + globalThis.location.href = url; + } catch (error) { + console.error("Error during login:", error); + } + }; + + return ( +
+ + {user &&

Welcome, {user.personaname}!

} +
+ ); +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index 6119ad9..82384cb 100644 --- a/src/index.css +++ b/src/index.css @@ -1,68 +1,112 @@ :root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + --header-height: 64px; + --header-bg-color: #ffffff; + --header-text-color: #242424; + --header-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + --header-padding: 1rem; + --header-margin-top: 1rem; + --font-size-header: 1.25rem; + --font-weight-header: bold; + --accent-color: #242424; + --avatar-size: 48px; + --avatar-margin-top: 0.5rem; + --avatar-border-radius: 10%; + --avatar-border-width: 1px; + --route-container-margin-top: var(--header-height); } -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; +* { + box-sizing: border-box; + margin: 0; + padding: 0; } body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.6; } button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; font-family: inherit; - background-color: #1a1a1a; + font-size: inherit; cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; + background: transparent; + border-radius: 3px; + border: 1px solid #242424; + display: inline-block; + margin: 0.5rem 1rem; + padding: 0.5rem 0; + transition: all 200ms ease-in-out; + width: 11rem; } -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; +button:hover { + background-color: #242424; + color: #ffffff; +} + +.header { + display: flex; + background-color: var(--header-bg-color); + color: var(--header-text-color); + justify-content: space-between; + align-items: center; + width: 100%; + height: var(--header-height); + position: fixed; + left: 0; + top: 0; + box-shadow: var(--header-shadow); + padding: var(--header-padding); +} + +.header > * { + margin: var(--header-padding); + margin-top: var(--header-margin-top); +} + +.header h1 { + font-size: var(--font-size-header); + font-weight: var(--font-weight-header); +} + +.avatar { + width: var(--avatar-size); + height: var(--avatar-size); + margin-top: var(--avatar-margin-top); + border-radius: var(--avatar-border-radius); + border: var(--avatar-border-width) solid var(--accent-color); + object-fit: cover; +} + +.route-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin-top: var(--route-container-margin-top); +} + +/* Responsive Design */ +@media (max-width: 768px) { + .header { + height: 56px; } - a:hover { - color: #747bff; + + .header > * { + margin-top: 1rem; } - button { - background-color: #f9f9f9; + + .header h1 { + font-size: 1rem; + } + + .avatar { + width: 40px; + height: 40px; + } + + .route-container { + margin-top: 56px; } } diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 3251d94..db5b7c8 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,12 +1,10 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { Link } from "react-router-dom"; + import { Dino } from "../types.ts"; -import type { SteamUser } from "../../api/main.ts"; -import { UserContext } from "../App.tsx"; export default function Index() { const [dinosaurs, setDinosaurs] = useState([]); - const { user } = useContext(UserContext); useEffect(() => { (async () => { @@ -16,47 +14,10 @@ export default function Index() { })(); }, []); - /*useEffect(() => { - (async () => { - try { - const response = await fetch("/api/session", { - credentials: "include", - }); - const res = await response.json(); - if (res.user && res.user.steamid) { - setUser(res.user as SteamUser); - } - } catch (error) { - console.error("Error fetching user:", error); - } - })(); - }, []);*/ - - const printUser = async () => { - console.log(user); - }; - - const handleLogin = async () => { - try { - const response = await fetch("http://localhost:8000/auth/login"); - if (!response.ok) { - throw new Error("Failed to fetch authorization URL"); - } - const { url } = await response.json(); - globalThis.location.href = url; - } catch (error) { - console.error("Error during login:", error); - } - }; - return (

Dinosaur Home

Click on a dinosaur below to learn more.

- - {user &&

Welcome, {user.personaname}!

} {dinosaurs.map((dinosaur: Dino) => { return (