diff --git a/crates/api/auth.middleware.ts b/crates/api/auth.middleware.ts index cd703e4..0a501ef 100644 --- a/crates/api/auth.middleware.ts +++ b/crates/api/auth.middleware.ts @@ -3,11 +3,9 @@ import { getCookies, setCookie } from "$std/http/cookie.ts" import { createPg } from "api/pg.ts" // Define public paths that don't require authentication -const PUBLIC_PATHS = [ - "/", - "/api/auth/login", - "/api/auth/register", - "/api/auth/logout", +const PROTECTED = [ + "/home", + "/api/auth", ] // Sessions storage shared between routes @@ -18,11 +16,8 @@ export async function authMiddleware(req: Request, ctx: FreshContext): Promise ({ + userId: l.want.user.id, + listingId: l.id, + wantId: l.want.id, + + status: Status.Pending, + + condition: l.data.condition, + + item: l.data.price.value, + shipping, + total: l.data.price.value + shipping, + })) + + // we must sort the offers by price, + // sometimes a seller has multiples of a want + // to deal with this we just ignore duplicates on insert + // and ensure the cheapest one goes in first + const sorted = sortBy(offers, ['item']); + + // TODO probably need to take one of each condition of record from a store + // eg. they have a VG+ and a M we should make offers for each + + log.trace('generated offers', sorted); + const inserts = await pg.offersUpdate(sorted); + + return inserts; + } + + async function accept(ctx: Context) { + const { id } = ctx.request.body; + ctx.assert(id, 401, 'no id supplied'); + + // check the user actually has this offer + const offer = await pg.userOfferFind(ctx.state.user, id); + return pg.offerStatusSet([offer.id], Status.Accepted); + } + + async function statusSet(user: User, ids: UUID[], status: Status) { + log.info({ status, ids }, 'setting offer status'); + + // const offer = await pg.offerFindId(ids); + const update = await pg.offerStatusSet(ids, status); + + // forget about this for now + // if (status === Status.Complete) { + // log.info({ id, status }, 'completed offer, removing want...'); + // await pg.wantRm(offer.wantId); + // } + + return update; + } + + // converts offers into groups based on seller + // includes some bits of info about shipping etc + async function acpOffers() { + const offers = await pg.offersAdmin(); + + const grouped = groupBy(offers, o => o.listing.data.seller.id); + + const sellerOffers = sortBy(Object.values(grouped).map(offers => { + const shipping = offers[0]?.listing.data.seller.shipping; + const bundle = { + username: offers[0]?.listing.data.seller.username, + seller: offers[0]?.listing.data.seller.id, + shipsFrom: offers[0]?.listing.data.ships_from, + shipping, + offers: sortBy(offers, sortOffers), + mentionsAustralia: shipping.toLowerCase().includes('australia'), + mentionsWorldwide: shipping.toLowerCase().includes('world'), + } + + return bundle; + }), bundle => -bundle.offers.length); + + return sellerOffers; + } + + // also groups offers by seller for users + // but mostly just munges the structure so the details + // are easily available + async function userOffers(user: User) { + const offers = await pg.userOffers(user); + const groups = Object.values(groupBy(offers, (o) => o.wantId)) + .map(g => { + // the offer status is just the most advanced status + // based on sort + const offers = sortBy(g, sortOffers); + const status = offers[0].status; + + // now actually sort them by price + offers.sort((a, b) => a.total - b.total); + + const details = offers[0].want.data; + + return { + details, + offers, + status, + }; + }); + + return groups; + } + + async function samples() { + const user = await pg.userFindEmail('ntr@mnml.gg'); + const offerGroups = await userOffers(user); + const i = Math.floor(Math.random() * offerGroups.length / 2); + return offerGroups[i]; + } + + return { + generate, + accept, + statusSet, + acpOffers, + userOffers, + samples, + }; +} + +export type Offers = ReturnType; diff --git a/crates/components/main.tsx b/crates/components/main.tsx index 1e49cdb..990f38d 100644 --- a/crates/components/main.tsx +++ b/crates/components/main.tsx @@ -32,6 +32,8 @@ function Main({ wants, offers }) { ); } + console.log(offers) + return (