prisma types
This commit is contained in:
1 parent
ff371798a9
commit
d868baade5
17 files changed
+166
-146
No files matched your search
@@ -18,8 +18,11 @@ export async function authMiddleware(req: Request, ctx: FreshContext): Promise<R
|
|||||||
const url = new URL(req.url)
|
const url = new URL(req.url)
|
||||||
const path = url.pathname
|
const path = url.pathname
|
||||||
|
|
||||||
|
console.log("authing...")
|
||||||
|
|
||||||
// Allow public paths without authentication
|
// Allow public paths without authentication
|
||||||
if (PUBLIC_PATHS.includes(path)) {
|
if (PUBLIC_PATHS.includes(path)) {
|
||||||
|
console.log("noauth")
|
||||||
return await ctx.next()
|
return await ctx.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,11 +41,10 @@ export async function authMiddleware(req: Request, ctx: FreshContext): Promise<R
|
|||||||
// Redirect to login page for non-API routes
|
// Redirect to login page for non-API routes
|
||||||
return new Response(null, {
|
return new Response(null, {
|
||||||
status: 302,
|
status: 302,
|
||||||
headers: { Location: "/" }
|
headers: { Location: "/login" }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
// Verify session
|
// Verify session
|
||||||
const session = sessions.get(sessionId)
|
const session = sessions.get(sessionId)
|
||||||
|
|
||||||
@@ -61,23 +63,10 @@ export async function authMiddleware(req: Request, ctx: FreshContext): Promise<R
|
|||||||
throw new Error("User not found")
|
throw new Error("User not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add user to state for use in handlers
|
|
||||||
ctx.state.user = user
|
ctx.state.user = user
|
||||||
|
ctx.state.pg = pg
|
||||||
|
|
||||||
|
console.log("woas")
|
||||||
|
|
||||||
return await ctx.next()
|
return await ctx.next()
|
||||||
} catch (error) {
|
|
||||||
console.error("Auth error:", error)
|
|
||||||
|
|
||||||
if (path.startsWith("/api/")) {
|
|
||||||
return new Response(JSON.stringify({ error: "Unauthorized" }), {
|
|
||||||
status: 401,
|
|
||||||
headers: { "Content-Type": "application/json" }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redirect to login page for non-API routes
|
|
||||||
return new Response(null, {
|
|
||||||
status: 302,
|
|
||||||
headers: { Location: "/" }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { FreshContext } from "$fresh/server.ts"
|
||||||
|
|
||||||
|
export async function errorMiddleware(req: Request, ctx: FreshContext): Promise<Response> {
|
||||||
|
try {
|
||||||
|
const response = await ctx.next()
|
||||||
|
return response
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error handling ${req.method} ${new URL(req.url).pathname}:`, error)
|
||||||
|
|
||||||
|
// Check if this is an API route
|
||||||
|
const isApiRoute = new URL(req.url).pathname.startsWith("/api/")
|
||||||
|
|
||||||
|
if (isApiRoute) {
|
||||||
|
return new Response(JSON.stringify({
|
||||||
|
error: "Internal server error",
|
||||||
|
message: error.message
|
||||||
|
}), {
|
||||||
|
status: 500,
|
||||||
|
headers: { "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// For non-API routes, return a redirect to an error page or render an error component
|
||||||
|
return new Response(null, {
|
||||||
|
status: 302,
|
||||||
|
headers: { Location: "/?error=server_error" }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
import * as bcrypt from "https://deno.land/x/bcrypt@v0.4.1/mod.ts"
|
import * as bcrypt from "https://deno.land/x/bcrypt@v0.4.1/mod.ts"
|
||||||
import { load } from "$std/dotenv/mod.ts"
|
import { load } from "$std/dotenv/mod.ts"
|
||||||
import { PrismaClient } from "prisma/generated/index.js";
|
import { PrismaClient } from "prisma/generated/index.ts";
|
||||||
|
|
||||||
// Load environment variables
|
// Load environment variables
|
||||||
await load({ export: true })
|
await load({ export: true })
|
||||||
@@ -32,7 +32,7 @@ export function createPg(log: Console) {
|
|||||||
return prisma.user.findUnique({ where: { email } })
|
return prisma.user.findUnique({ where: { email } })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function userWants(user: any) {
|
async function userWants(user: User) {
|
||||||
const wants = await prisma.want.findMany({
|
const wants = await prisma.want.findMany({
|
||||||
where: { userId: user.id },
|
where: { userId: user.id },
|
||||||
include: { _count: { select: { offers: true } } },
|
include: { _count: { select: { offers: true } } },
|
||||||
@@ -46,7 +46,7 @@ export function createPg(log: Console) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function userOffers(user: any) {
|
async function userOffers(user: User) {
|
||||||
return prisma.offer.findMany({
|
return prisma.offer.findMany({
|
||||||
where: {
|
where: {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
|
|||||||
+17
-15
@@ -1,11 +1,7 @@
|
|||||||
import { h } from 'preact';
|
import { h } from 'preact';
|
||||||
import { route } from 'preact-router';
|
// import { route } from 'preact-router';
|
||||||
import { useSelector } from 'react-redux'
|
|
||||||
|
|
||||||
import { State } from './../store';
|
import OfferGroup from "./offer.group.tsx";
|
||||||
import * as toast from './../toast';
|
|
||||||
|
|
||||||
import OfferGroup from './../components/offer.group';
|
|
||||||
|
|
||||||
const GroupNav = (want) => {
|
const GroupNav = (want) => {
|
||||||
if (!want._count.offers) return null
|
if (!want._count.offers) return null
|
||||||
@@ -19,19 +15,25 @@ const GroupNav = (want) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function Home() {
|
function Main({ wants, offers }) {
|
||||||
const offers = useSelector((state: State) => state.offers);
|
|
||||||
const wants = useSelector((state: State) => state.wants);
|
|
||||||
|
|
||||||
if (offers && offers.length === 0) {
|
if (offers && offers.length === 0) {
|
||||||
toast.info('no offers', 'You have no offers yet, search for some more items.');
|
// Redirect to search if no offers
|
||||||
route('/search');
|
if (typeof window !== 'undefined') {
|
||||||
|
// route('/search');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!offers || !wants) return <div>loading...</div>;
|
if (!offers || !wants) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>No wants or offers found.</p>
|
||||||
|
<a href="/search" class="button">Search Records</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main >
|
<main>
|
||||||
<nav>
|
<nav>
|
||||||
<div class='header'>
|
<div class='header'>
|
||||||
<span>Record</span>
|
<span>Record</span>
|
||||||
@@ -46,4 +48,4 @@ function Home() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Home;
|
export default Main;
|
||||||
@@ -1,50 +1,29 @@
|
|||||||
import { h } from 'preact';
|
import { h } from 'preact';
|
||||||
import { ExternalLink, Check } from 'react-feather';
|
|
||||||
import { useState, useCallback } from 'preact/hooks';
|
import { useState, useCallback } from 'preact/hooks';
|
||||||
import _ from 'lodash'
|
import { ExternalLink, Check } from 'lucide-preact';
|
||||||
|
import _ from 'lodash';
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
|
||||||
import { State } from './../store';
|
|
||||||
|
|
||||||
import http from '../http';
|
|
||||||
|
|
||||||
function OfferLine(offer) {
|
function OfferLine(offer) {
|
||||||
const ws = useSelector((state: State) => state.ws);
|
// Server-side rendering version doesn't support interactive status changes
|
||||||
|
|
||||||
function setStatus(status) {
|
|
||||||
ws.sendOfferStatusSet(offer.id, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
const accepted = offer.status === 'Accepted';
|
const accepted = offer.status === 'Accepted';
|
||||||
const classes = `${accepted ? 'accepted' : ''}`;
|
const classes = `${accepted ? 'accepted' : ''}`;
|
||||||
const btnText = accepted
|
const btnText = accepted
|
||||||
? offer.status
|
? offer.status
|
||||||
: 'Accept';
|
: 'Accept';
|
||||||
|
|
||||||
const negBtn = accepted
|
|
||||||
? <button onClick={() => setStatus('Pending')} class='neg'>Cancel</button>
|
|
||||||
: <button onClick={() => setStatus('Declined')} class='neg'>Decline</button>;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="line">
|
<div class="line">
|
||||||
<div class='number'>${offer.total}</div>
|
<div class='number'>${offer.total}</div>
|
||||||
<div class='number'>{offer.condition}</div>
|
<div class='number'>{offer.condition}</div>
|
||||||
<button onClick={() => setStatus('Accepted')} disabled={accepted} class={classes} >{btnText}</button>
|
<div class='number'>{offer.status}</div>
|
||||||
{negBtn}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function OfferPriceBtn(offer) {
|
function OfferPriceBtn(offer) {
|
||||||
const ws = useSelector((state: State) => state.ws);
|
|
||||||
const accepted = offer.status === 'Accepted';
|
const accepted = offer.status === 'Accepted';
|
||||||
const confirmed = offer.status === 'Confirmed';
|
const confirmed = offer.status === 'Confirmed';
|
||||||
|
|
||||||
function setStatus() {
|
|
||||||
if (accepted) return ws.sendOfferStatusSet(offer.id, 'Pending')
|
|
||||||
ws.sendOfferStatusSet(offer.id, 'Accepted');
|
|
||||||
}
|
|
||||||
|
|
||||||
const classes = `${accepted ? 'accepted' : ''} ${confirmed ? 'confirmed' : ''}`;
|
const classes = `${accepted ? 'accepted' : ''} ${confirmed ? 'confirmed' : ''}`;
|
||||||
const btnText = accepted
|
const btnText = accepted
|
||||||
? offer.status
|
? offer.status
|
||||||
@@ -55,7 +34,7 @@ function OfferPriceBtn(offer) {
|
|||||||
: 'Click to accept this offer';
|
: 'Click to accept this offer';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button disabled={confirmed} title={title} onClick={() => setStatus()} class={classes}>${offer.total} {offer.condition}</button>
|
<button disabled={true} title={title} class={classes}>${offer.total} {offer.condition}</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,29 +44,7 @@ function OfferConditionSlider([condition, offers], i, groupId, rangeMin, rangeMa
|
|||||||
const markersId = `${id}-markers`
|
const markersId = `${id}-markers`
|
||||||
const steps = offers.map(o => o.total)
|
const steps = offers.map(o => o.total)
|
||||||
const initialValue = _.last(offers.filter(o => o.status === 'Accepted'))?.total || 0
|
const initialValue = _.last(offers.filter(o => o.status === 'Accepted'))?.total || 0
|
||||||
|
const acceptedPriceLabel = initialValue ? `$${initialValue}` : '-'
|
||||||
const ws = useSelector((state: State) => state.ws);
|
|
||||||
const [acceptedPrice, setAcceptedPrice] = useState(initialValue)
|
|
||||||
|
|
||||||
const sendOffers = useCallback(_.debounce(function send(v) {
|
|
||||||
const accepted = offers.filter(o => Number(o.total) <= v).map(o => o.id)
|
|
||||||
const pending = offers.filter(o => Number(o.total) > v).map(o => o.id)
|
|
||||||
ws.sendOfferStatusSet(accepted, 'Accepted')
|
|
||||||
ws.sendOfferStatusSet(pending, 'Pending')
|
|
||||||
}, 1000), [])
|
|
||||||
|
|
||||||
function onChange(target) {
|
|
||||||
const highest = () => {
|
|
||||||
return _.findLast(steps, s => target.value >= Number(s)) || 0
|
|
||||||
}
|
|
||||||
|
|
||||||
const v = highest()
|
|
||||||
target.value = v
|
|
||||||
setAcceptedPrice(v)
|
|
||||||
sendOffers(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
const acceptedPriceLabel = acceptedPrice ? `$${acceptedPrice}` : '-'
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={id}>
|
<div key={id}>
|
||||||
@@ -101,8 +58,8 @@ function OfferConditionSlider([condition, offers], i, groupId, rangeMin, rangeMa
|
|||||||
step={step}
|
step={step}
|
||||||
min={rangeMin}
|
min={rangeMin}
|
||||||
max={rangeMax}
|
max={rangeMax}
|
||||||
value={acceptedPrice}
|
value={initialValue}
|
||||||
onChange={e => onChange((e.target as HTMLInputElement)) } />
|
disabled={true} />
|
||||||
|
|
||||||
<datalist id={markersId}>
|
<datalist id={markersId}>
|
||||||
{offers.map(o => <option value={o.total}></option>)}
|
{offers.map(o => <option value={o.total}></option>)}
|
||||||
@@ -113,8 +70,6 @@ function OfferConditionSlider([condition, offers], i, groupId, rangeMin, rangeMa
|
|||||||
|
|
||||||
|
|
||||||
export default function OfferGroup(group, i) {
|
export default function OfferGroup(group, i) {
|
||||||
const ws = useSelector((state: State) => state.ws);
|
|
||||||
|
|
||||||
const format = group.details.formats[0].text ? `${group.details.formats[0].text} - ` : '';
|
const format = group.details.formats[0].text ? `${group.details.formats[0].text} - ` : '';
|
||||||
const descriptions = group.details.formats.map(f => f.descriptions.join(' ')).join(' ')
|
const descriptions = group.details.formats.map(f => f.descriptions.join(' ')).join(' ')
|
||||||
const detailText = `${format} ${descriptions}`;
|
const detailText = `${format} ${descriptions}`;
|
||||||
|
|||||||
@@ -1,21 +1,9 @@
|
|||||||
import { h } from 'preact';
|
import { h } from 'preact';
|
||||||
import { ExternalLink, Check } from 'react-feather';
|
import { ExternalLink, Check } from 'lucide-preact';
|
||||||
import { useState } from 'preact/hooks';
|
|
||||||
|
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
|
||||||
import { State } from './../store';
|
|
||||||
|
|
||||||
import http from '../http';
|
|
||||||
|
|
||||||
export default function Offer(offer) {
|
export default function Offer(offer) {
|
||||||
const ws = useSelector((state: State) => state.ws);
|
|
||||||
|
|
||||||
const { want: { data: details } } = offer;
|
const { want: { data: details } } = offer;
|
||||||
|
|
||||||
function setStatus(status) {
|
|
||||||
ws.sendOfferStatusSet(offer.id, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
const accepted = offer.status === 'Accepted';
|
const accepted = offer.status === 'Accepted';
|
||||||
const classes = `${accepted ? 'accepted' : ''}`;
|
const classes = `${accepted ? 'accepted' : ''}`;
|
||||||
const btnText = accepted
|
const btnText = accepted
|
||||||
@@ -23,8 +11,8 @@ export default function Offer(offer) {
|
|||||||
: 'Accept';
|
: 'Accept';
|
||||||
|
|
||||||
const negBtn = accepted
|
const negBtn = accepted
|
||||||
? <button onClick={() => setStatus('Pending')} class='neg'>Cancel</button>
|
? <button disabled={true} class='neg'>Cancel</button>
|
||||||
: <button onClick={() => setStatus('Declined')} class='neg'>Decline</button>;
|
: <button disabled={true} class='neg'>Decline</button>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="offer">
|
<div class="offer">
|
||||||
@@ -36,7 +24,7 @@ export default function Offer(offer) {
|
|||||||
<div class='number'>shipped by itself: ${offer.comparison}</div>
|
<div class='number'>shipped by itself: ${offer.comparison}</div>
|
||||||
</section>
|
</section>
|
||||||
<img src={details.thumb} />
|
<img src={details.thumb} />
|
||||||
<button onClick={() => setStatus('Accepted')} disabled={accepted} class={classes} >{btnText}</button>
|
<button disabled={true} class={classes}>{btnText}</button>
|
||||||
{negBtn}
|
{negBtn}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
+6
-2
@@ -4,10 +4,11 @@
|
|||||||
"check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx",
|
"check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx",
|
||||||
"cli": "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable -A -",
|
"cli": "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable -A -",
|
||||||
"manifest": "deno task cli manifest $(pwd)",
|
"manifest": "deno task cli manifest $(pwd)",
|
||||||
"start": "deno run --unstable-detect-cjs -A --watch=static/,routes/ dev.ts",
|
"start": "deno run -A --watch=static/,routes/ dev.ts",
|
||||||
"build": "deno run -A dev.ts build",
|
"build": "deno run -A dev.ts build",
|
||||||
"preview": "deno run -A main.ts",
|
"preview": "deno run -A main.ts",
|
||||||
"prisma-generate": "deno run -A --env-file npm:prisma generate",
|
"prisma-clean": "rm -rf prisma/generated",
|
||||||
|
"prisma-generate": "deno task prisma-clean && deno run -A --env-file npm:prisma generate",
|
||||||
"prisma:migrate": "deno run -A --env-file npm:prisma migrate dev",
|
"prisma:migrate": "deno run -A --env-file npm:prisma migrate dev",
|
||||||
"update": "deno run -A -r https://fresh.deno.dev/update ."
|
"update": "deno run -A -r https://fresh.deno.dev/update ."
|
||||||
},
|
},
|
||||||
@@ -22,7 +23,10 @@
|
|||||||
"@twind/core": "https://esm.sh/@twind/core@1.1.3",
|
"@twind/core": "https://esm.sh/@twind/core@1.1.3",
|
||||||
"@twind/preset-tailwind": "https://esm.sh/@twind/preset-tailwind@1.1.4/",
|
"@twind/preset-tailwind": "https://esm.sh/@twind/preset-tailwind@1.1.4/",
|
||||||
"@twind/preset-autoprefix": "https://esm.sh/@twind/preset-autoprefix@1.0.7/",
|
"@twind/preset-autoprefix": "https://esm.sh/@twind/preset-autoprefix@1.0.7/",
|
||||||
|
|
||||||
"less": "npm:less@4.2.0",
|
"less": "npm:less@4.2.0",
|
||||||
|
"lucide-preact": "npm:lucide-preact@^0.475.0",
|
||||||
|
"@prisma/client": "npm:@prisma/client@^6.6.0",
|
||||||
|
|
||||||
"api/": "./api/",
|
"api/": "./api/",
|
||||||
"api": "./api/",
|
"api": "./api/",
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { defineConfig } from "$fresh/server.ts";
|
import { defineConfig } from "$fresh/server.ts";
|
||||||
import twind from "$fresh/plugins/twindv1.ts";
|
// import twind from "$fresh/plugins/twindv1.ts";
|
||||||
import twindConfig from "./twind.config.ts";
|
// import twindConfig from "./twind.config.ts";
|
||||||
import { authMiddleware } from "api/auth.middleware.ts";
|
import { authMiddleware } from "api/auth.middleware.ts";
|
||||||
|
import { errorMiddleware } from "api/error.middleware.ts";
|
||||||
import lessPlugin from "./less.plugin.ts";
|
import lessPlugin from "./less.plugin.ts";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@@ -10,6 +11,7 @@ export default defineConfig({
|
|||||||
lessPlugin()
|
lessPlugin()
|
||||||
],
|
],
|
||||||
middleware: {
|
middleware: {
|
||||||
auth: authMiddleware
|
auth: authMiddleware,
|
||||||
|
error: errorMiddleware,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -8,6 +8,9 @@ import * as $api_auth_login from './routes/api/auth/login.ts'
|
|||||||
import * as $api_auth_logout from './routes/api/auth/logout.ts'
|
import * as $api_auth_logout from './routes/api/auth/logout.ts'
|
||||||
import * as $api_auth_register from './routes/api/auth/register.ts'
|
import * as $api_auth_register from './routes/api/auth/register.ts'
|
||||||
import * as $api_auth_status from './routes/api/auth/status.ts'
|
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 $index from './routes/index.tsx'
|
||||||
import * as $login from './routes/login.tsx'
|
import * as $login from './routes/login.tsx'
|
||||||
import * as $register from './routes/register.tsx'
|
import * as $register from './routes/register.tsx'
|
||||||
@@ -22,6 +25,9 @@ const manifest = {
|
|||||||
'./routes/api/auth/logout.ts': $api_auth_logout,
|
'./routes/api/auth/logout.ts': $api_auth_logout,
|
||||||
'./routes/api/auth/register.ts': $api_auth_register,
|
'./routes/api/auth/register.ts': $api_auth_register,
|
||||||
'./routes/api/auth/status.ts': $api_auth_status,
|
'./routes/api/auth/status.ts': $api_auth_status,
|
||||||
|
'./routes/api/offers.ts': $api_offers,
|
||||||
|
'./routes/api/wants.ts': $api_wants,
|
||||||
|
'./routes/home.tsx': $home,
|
||||||
'./routes/index.tsx': $index,
|
'./routes/index.tsx': $index,
|
||||||
'./routes/login.tsx': $login,
|
'./routes/login.tsx': $login,
|
||||||
'./routes/register.tsx': $register,
|
'./routes/register.tsx': $register,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^6.6.0",
|
"@prisma/client": "^6.6.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"zod": "^3.24.3"
|
"zod": "^3.24.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client"
|
||||||
output = "./generated"
|
output = "./generated"
|
||||||
moduleFormat = "esm"
|
moduleFormat = "esm"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { FreshContext } from "$fresh/server.ts";
|
||||||
|
import { Pg } from 'api/pg.ts'
|
||||||
|
import { User } from 'prisma/generated/index.d.ts'
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
pg: Pg;
|
||||||
|
user: User
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function handler(
|
||||||
|
req: Request,
|
||||||
|
ctx: FreshContext<State>,
|
||||||
|
) {
|
||||||
|
ctx.state.data = "myData";
|
||||||
|
const resp = await ctx.next();
|
||||||
|
resp.headers.set("server", "fresh server");
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { Handlers } from "$fresh/server.ts"
|
||||||
|
import { createPg } from "../../api/pg.ts"
|
||||||
|
|
||||||
|
export const handler: Handlers = {
|
||||||
|
async GET(_req, ctx) {
|
||||||
|
const user = ctx.state.user
|
||||||
|
const pg = createPg(console)
|
||||||
|
const offers = await pg.userOffers(user)
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(offers), {
|
||||||
|
status: 200,
|
||||||
|
headers: { "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { Handlers } from "$fresh/server.ts"
|
||||||
|
import { createPg } from "../../api/pg.ts"
|
||||||
|
|
||||||
|
export const handler: Handlers = {
|
||||||
|
async GET(_req, ctx) {
|
||||||
|
const user = ctx.state.user
|
||||||
|
const pg = createPg(console)
|
||||||
|
const wants = await pg.userWants(user)
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(wants), {
|
||||||
|
status: 200,
|
||||||
|
headers: { "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Handlers, PageProps } from "$fresh/server.ts";
|
||||||
|
import { createPg, Pg } from "../api/pg.ts";
|
||||||
|
import Main from "../components/main.tsx";
|
||||||
|
import { User } from 'prisma/generated/index.d.ts'
|
||||||
|
|
||||||
|
export const handler: Handlers = {
|
||||||
|
async GET(req, ctx) {
|
||||||
|
const user: User = ctx.state.user;
|
||||||
|
const pg: Pg = createPg(console);
|
||||||
|
|
||||||
|
const wants = await pg.userWants(user);
|
||||||
|
const offers = await pg.userOffers(user);
|
||||||
|
|
||||||
|
return ctx.render({ wants, offers });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Home({ data }: PageProps) {
|
||||||
|
const { wants, offers } = data || {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div id="mcrates">
|
||||||
|
<Main wants={wants} offers={offers} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import { Handlers, PageProps } from "$fresh/server.ts";
|
|
||||||
import { getCookies } from "$std/http/cookie.ts";
|
|
||||||
import { sessions } from "../api/auth.middleware.ts";
|
|
||||||
|
|
||||||
export const handler: Handlers = {
|
|
||||||
async GET(req, ctx) {
|
|
||||||
const cookies = getCookies(req.headers);
|
|
||||||
const sessionId = cookies.session;
|
|
||||||
|
|
||||||
// Check if session exists and is valid
|
|
||||||
if (!sessionId || !sessions.has(sessionId)) {
|
|
||||||
return new Response("", {
|
|
||||||
status: 307,
|
|
||||||
headers: { Location: "/login" },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx.render();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function Home() {
|
|
||||||
return (
|
|
||||||
<div id="mcrates">
|
|
||||||
<h1>Welcome to crates</h1>
|
|
||||||
<p>You are logged in!</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
import { h } from "preact";
|
|
||||||
import { Handlers, PageProps } from "$fresh/server.ts";
|
import { Handlers, PageProps } from "$fresh/server.ts";
|
||||||
import { getCookies, setCookie } from "$std/http/cookie.ts";
|
import { getCookies, setCookie } from "$std/http/cookie.ts";
|
||||||
import { z } from "npm:zod";
|
import { z } from "npm:zod";
|
||||||
import Swirl from "../components/swirl.tsx";
|
import Swirl from "../components/swirl.tsx";
|
||||||
import { sessions } from "../api/auth.middleware.ts";
|
import { sessions } from "api/auth.middleware.ts";
|
||||||
import * as bcrypt from "https://deno.land/x/bcrypt@v0.4.1/mod.ts";
|
import * as bcrypt from "https://deno.land/x/bcrypt@v0.4.1/mod.ts";
|
||||||
import { createPg } from "../api/pg.ts";
|
import { createPg } from "api/pg.ts";
|
||||||
|
|
||||||
export const handler: Handlers = {
|
export const handler: Handlers = {
|
||||||
async GET(req, ctx) {
|
async GET(req, ctx) {
|
||||||
@@ -16,7 +15,7 @@ export const handler: Handlers = {
|
|||||||
if (sessionId && sessions.has(sessionId)) {
|
if (sessionId && sessions.has(sessionId)) {
|
||||||
return new Response("", {
|
return new Response("", {
|
||||||
status: 307,
|
status: 307,
|
||||||
headers: { Location: "/" },
|
headers: { Location: "/home" },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +79,7 @@ export const handler: Handlers = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Set cookie and redirect
|
// Set cookie and redirect
|
||||||
const headers = new Headers({ Location: "/" });
|
const headers = new Headers({ Location: "/home" });
|
||||||
setCookie(headers, {
|
setCookie(headers, {
|
||||||
name: "session",
|
name: "session",
|
||||||
value: sessionId,
|
value: sessionId,
|
||||||
|
|||||||
Reference in new issue
Block a user