home index

This commit is contained in:
Nathan Rashleigh committed 2025-05-02 01:32:28 +10:00
1 parent a4d8608a3e
commit b6c6e54ef8
8 files changed
+47 -123

No files matched your search

+2 -1
View File
@@ -3,8 +3,9 @@ import { getCookies } from "$std/http/cookie.ts"
import { CratesCtx } from 'api/mw.service.ts'
const PROTECTED = [
"/api/auth",
"/",
"/home",
"/api/auth",
]
// Open Deno KV database
+4 -40
View File
@@ -1,46 +1,10 @@
import { h } from 'preact';
import { route } from 'preact-router';
import { useEffect } from 'preact/hooks';
import { useSelector } from 'react-redux'
import LogRocket from 'logrocket';
import { User } from 'prismaClient'
import http from './../http';
import { State } from './../store';
import Swirl from './swirl';
function showAdmin(user) {
function showAdmin(user: User) {
return user && user.email === 'ntr@mnml.gg';
}
const DEFAULT_ROUTE = '/';
const Nav = () => {
const user = useSelector((state: State) => state.user);
useEffect(() => {
if (!user) {
route('/login');
return;
}
route(DEFAULT_ROUTE)
if (window.location.host === 'crates.ntwl.xyz') {
LogRocket.identify(user.id, {
name: user.email,
email: user.email,
});
}
return;
}, [user])
async function logoutClick(e) {
e.preventDefault();
await http.postLogout();
window.location.reload();
}
const Nav = ({ user }) => {
const nav = () => (
<nav>
<a href="/">Offers</a>
@@ -65,7 +29,7 @@ const Nav = () => {
const userNav = () => (
<nav>
<a href="/info">Info</a>
<a href="/auth/logout" onClick={logoutClick}>Logout</a>
<a href="/api/auth/logout" >Logout</a>
</nav>
)
+2
View File
@@ -13,6 +13,7 @@ import * as $api_auth_status from './routes/api/auth/status.ts'
import * as $api_offers from './routes/api/offers.ts'
import * as $api_wants from './routes/api/wants.ts'
import * as $home from './routes/home.tsx'
import * as $index from './routes/index.tsx'
import * as $login from './routes/login.tsx'
import * as $register from './routes/register.tsx'
@@ -31,6 +32,7 @@ const manifest = {
'./routes/api/offers.ts': $api_offers,
'./routes/api/wants.ts': $api_wants,
'./routes/home.tsx': $home,
'./routes/index.tsx': $index,
'./routes/login.tsx': $login,
'./routes/register.tsx': $register,
},
+1
View File
@@ -1,4 +1,5 @@
import { type PageProps } from "$fresh/server.ts";
export default function App({ Component }: PageProps) {
return (
<html>
+5 -43
View File
@@ -6,12 +6,7 @@ import { z } from "npm:zod"
import { zx } from "npm:zodix"
import { createSession } from "api/mw.auth.ts"
import {
ValidationError,
InvalidCredentialsError,
NotLoggedInError,
ServerError
} from "api/errors.ts"
import { InvalidCredentialsError } from "api/errors.ts"
import { CratesState } from 'api/mw.service.ts'
const LoginSchema = z.object({
@@ -21,7 +16,6 @@ const LoginSchema = z.object({
export const handler: Handlers<{email: string}, CratesState> = {
async POST(req, ctx) {
try {
const { email, password } = await zx.parseForm(req, LoginSchema)
// Create pg instance for database operations
@@ -50,41 +44,9 @@ export const handler: Handlers<{email: string}, CratesState> = {
sameSite: "Lax"
})
// Return user data
return new Response(JSON.stringify({
email: user.email
}), {
status: 200,
headers
})
} catch (error) {
// Let the error middleware handle custom errors
if (error instanceof ValidationError ||
error instanceof InvalidCredentialsError) {
throw error
}
console.error("Login error:", error)
throw new ServerError("An error occurred during login")
}
return new Response(null, {
status: 302,
headers: { Location: "/home" }
});
},
// GET handler to check login status
async GET(req, ctx) {
// This would be handled by the auth middleware
// If the request reaches here, the user is authenticated
const user = ctx.state.user
if (!user) {
throw new NotLoggedInError()
}
return new Response(JSON.stringify({
id: user.id,
email: user.email
}), {
status: 200,
headers: { "Content-Type": "application/json" }
})
}
}
+9 -33
View File
@@ -1,13 +1,13 @@
import { Handlers } from "$fresh/server.ts"
import { setCookie } from "$std/http/cookie.ts"
import { z } from "https://deno.land/x/zod@v3.22.4/mod.ts"
import { z } from "npm:zod"
import { zx } from "npm:zodix"
import { createPg } from "api/pg.ts"
import { createSession } from "api/mw.auth.ts"
import {
ValidationError,
ResourceExistsError,
ServerError
} from "api/errors.ts"
import { ResourceExistsError } from "api/errors.ts"
import { CratesState } from 'api/mw.service.ts'
// Define validation schema with Zod
const RegisterSchema = z.object({
@@ -16,30 +16,16 @@ const RegisterSchema = z.object({
discogs: z.string().optional()
})
export const handler: Handlers = {
export const handler: Handlers<{email: string}, CratesState> = {
async POST(req, _ctx) {
try {
const data = await req.formData()
// Validate input data with Zod
const result = RegisterSchema.safeParse(data)
if (!result.success) {
// Throw validation error
throw new ValidationError("Validation failed", result.error.format())
}
const { discogs, email, password } = result.data
const { discogs, email, password } = await zx.parseForm(req, RegisterSchema)
// Create pg instance for database operations
const pg = createPg(console)
// Check if user exists
const existingUser = await pg.userFindEmail(email)
if (existingUser) {
throw new ResourceExistsError("User with this email")
}
if (existingUser) throw new ResourceExistsError("User with this email")
// Create user
const params = { discogs, email, password, data: {} }
@@ -68,15 +54,5 @@ export const handler: Handlers = {
status: 200,
headers
})
} catch (error) {
// Let the error middleware handle custom errors
if (error instanceof ValidationError ||
error instanceof ResourceExistsError) {
throw error
}
console.error("Registration error:", error)
throw new ServerError("An error occurred during registration")
}
}
}
+6 -6
View File
@@ -3,6 +3,7 @@ import Main from "../components/main.tsx";
import { CratesState } from "api/mw.service.ts"
import { Offer, Want } from "prismaClient"
import Nav from '../components/nav.tsx'
interface HomeData {
wants: Want[],
@@ -13,21 +14,20 @@ export const handler: Handlers<HomeData, CratesState> = {
async GET(_req, ctx) {
const { pg, offers, user } = ctx.state
console.log(user)
const wants = await pg.userWants(user);
const uOffers = await offers.userOffers(user);
return await ctx.render({ wants, offers: uOffers });
return await ctx.render({ user, wants, offers: uOffers });
},
};
export default function Home({ data }: PageProps) {
const { wants, offers } = data || {};
const { user, wants, offers } = data
return (
<div id="mcrates">
<>
<Nav user={user} />
<Main wants={wants} offers={offers} />
</div>
</>
);
}
+18
View File
@@ -0,0 +1,18 @@
import { Handlers } from "$fresh/server.ts"
import { CratesState } from 'api/mw.service.ts'
export const handler: Handlers<{email: string}, CratesState> = {
GET(_req, ctx) {
const { user } = ctx.state
if (user) return new Response(null, {
status: 302,
headers: { Location: "/home" }
});
return new Response(null, {
status: 302,
headers: { Location: "/login" }
});
}
}