diff --git a/api/src/pg.ts b/api/src/pg.ts index d2d06c2..d729fe1 100644 --- a/api/src/pg.ts +++ b/api/src/pg.ts @@ -24,6 +24,7 @@ export default function createPg(log: Log, prisma: PrismaClient) { return prisma.want.findMany({ where: { userId: user.id }, include: { _count: { select: { offers: true }} }, + orderBy: { offers: { _count: 'desc' } } }); } diff --git a/client/src/app.tsx b/client/src/app.tsx index 58eb9ee..ebd4a87 100644 --- a/client/src/app.tsx +++ b/client/src/app.tsx @@ -9,7 +9,7 @@ import store, { wsState } from './store' import Nav from './components/nav'; -import Offers from './routes/offers'; +import Main from './routes/main'; import Acp from './routes/acp'; import Login from './routes/login'; import Search from './routes/search'; @@ -18,7 +18,7 @@ import Info from './routes/info'; if (window.location.host === 'matescrates.au') LogRocket.init('yh0dy3/mcrates'); -const Main = () => { +const Mcrates = () => { const dispatch = useDispatch(); // i have no idea why this is needed, @@ -38,10 +38,10 @@ const Main = () => { } return ( -
+
+ ); }; const App = () => { return ( -
+ ); } diff --git a/client/src/components/offer.group.tsx b/client/src/components/offer.group.tsx index 2cbb83c..53f7086 100644 --- a/client/src/components/offer.group.tsx +++ b/client/src/components/offer.group.tsx @@ -63,7 +63,7 @@ export default function OfferGroup(group, i) { const detailText = `${format} ${descriptions}`; return ( -
+

{group.details.artists_sort} - {group.details.title}

diff --git a/client/src/routes/main.tsx b/client/src/routes/main.tsx new file mode 100644 index 0000000..36541bf --- /dev/null +++ b/client/src/routes/main.tsx @@ -0,0 +1,41 @@ +import { h } from 'preact'; +import { route } from 'preact-router'; +import { useSelector } from 'react-redux' + +import { State } from './../store'; +import * as toast from './../toast'; + +import OfferGroup from './../components/offer.group'; + +const GroupNav = (want) => { + const href = want._count.offers ? `#${want.release}` : null; + return ( + + ); +}; + +function Home() { + const offers = useSelector((state: State) => state.offers); + const wants = useSelector((state: State) => state.wants); + + if (offers && offers.length === 0) { + toast.info('no offers', 'You have no offers yet, search for some more items.'); + route('/search'); + } + + if (!offers || !wants) return
loading...
; + + return ( +
+ +
+ {offers.map(OfferGroup)} +
+
+ ); +} + +export default Home; diff --git a/client/src/routes/offers.tsx b/client/src/routes/offers.tsx deleted file mode 100644 index 8852cfc..0000000 --- a/client/src/routes/offers.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { h } from 'preact'; -import { route } from 'preact-router'; -import { useSelector } from 'react-redux' - -import { State } from './../store'; -import * as toast from './../toast'; - -import OfferGroup from './../components/offer.group'; - -function Home() { - const offers = useSelector((state: State) => state.offers); - - if (offers && offers.length === 0) { - toast.info('no offers', 'You have no offers yet, search for some more items.'); - route('/search'); - } - - if (!offers) return
loading...
; - - return ( -
- {offers.map(OfferGroup)} -
- ); -} - -export default Home; diff --git a/client/src/style/index.less b/client/src/style/index.less index 5baa384..b075e66 100644 --- a/client/src/style/index.less +++ b/client/src/style/index.less @@ -131,6 +131,11 @@ button, input, optgroup, select, textarea { line-height:var(--base-line-height); } +button, [type=submit] { + padding: var(--spacing-half); + background: var(--background-1); +} + input:hover, textarea:hover { color:var(--base-font-color); border:var(--hover-border) @@ -194,180 +199,6 @@ p { margin:0 0 var(--spacing) } -// ok actual styles - -body { - padding-top: calc(var(--spacing)/2); -} - -main { - padding: 0 var(--spacing-double) 0 var(--spacing-double); -} - -button, [type=submit] { - padding: var(--spacing-half); - background: var(--background-1); - -} - -.landing { - display: grid; - - grid-template-columns: 1fr 2fr; - grid-gap: calc(var(--spacing-double) * 2); - grid-template-areas: - "login swirl" - "login words"; - - .login { - grid-area: login; - button { - width: 100%; - } - } - - .swirl { - grid-area: swirl; - height: 15rem; - } - - .words { - grid-area: words; - text-align: center; - } -} - -.info { - display: grid; - - grid-template-areas: - "words swirl" - "words contact"; - - grid-template-columns: 1fr 1fr; - grid-template-rows: min-content 1fr; - - section { - margin-bottom: var(--spacing); - } - - .contact { - grid-area: contact; - text-align: center; - } - - .words { - grid-area: words; - } - - .swirl { - grid-area: swirl; - height: 15rem; - } -} - -.alt-text, .alt { - font-family: var(--secondary-font-family); - // font-size: var(--small-font-size); - text-transform: uppercase; -} - -article { - background-color: var(--background-1); - - button { - border-color: var(--background-2); - } -} - -.search { - display: grid; - grid-template-columns: 1fr 2fr; - - .results { - display: grid; - padding-left: var(--spacing); - grid-gap: var(--spacing); - - article { - display: grid; - padding: var(--spacing); - grid-template-columns: 1fr 4fr min-content; - } - } - - button { - margin-right: var(--spacing); - background: var(--background-2); - border-color: var(--background-1); - - &.added { - background: var(--color-green); - cursor: auto; - } - } -} - -.list { - display: grid; - grid-template-columns: - 1fr 1fr 1fr; - - grid-gap: var(--spacing); - - article { - display: grid; - - // grid-template-rows: - // 1fr min-content min-content; - - grid-template-areas: - "title img" - "details details" - "remove remove"; - - button { - margin-top: var(--spacing-half); - grid-area: remove - } - - .details { - grid-area: details; - } - - padding: var(--spacing); - - img { - justify-self: end; - } - } -} - -form { - margin-bottom: var(--spacing); - - label, input { - display: block; - } - - input, button { - width: 100%; - } - - input { - padding: var(--spacing-half); - margin-bottom: var(--spacing); - } - - label { - font-family: var(--secondary-font-family); - font-size: var(--small-font-size); - text-transform: uppercase; - margin-bottom: var(--spacing-half); - } - -} - a { color: var(--secondary-font-color); font-family: var(--secondary-font-family); @@ -378,181 +209,10 @@ a { } } -header { - display: grid; - grid-template-columns: 1fr 1fr min-content; - padding-bottom: var(--spacing); - - a { - font-size: var(--small-font-size); - margin-right: var(--spacing); - } - - a { - white-space: nowrap; - } -} - -.bundles { - flex-flow: row; - - .bundle { - margin-bottom: var(--spacing-double); - - section { - margin-bottom: var(--spacing); - } - - .items { - display: grid; - grid-template-columns: repeat(5, 1fr); - - div { - margin-right: var(--spacing); - margin-bottom: var(--spacing); - - display: grid; - - &.bold { - font-weight: bold; - background: var(--background-2); - } - } - } - } -} - -.offers { - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: var(--spacing); - - .offer { - display: grid; - grid-template-columns: 1fr min-content; - grid-template-rows: min-content min-content; - grid-template-areas: - "details img" - "lines lines"; - - padding: var(--spacing); - background: var(--background-1); - - .details { - font-size: var(--small-font-size); - } - - .status { - margin-top: var(--spacing-half); - } - - section { - grid-area: details; - } - - img { - grid-area: img; - justify-self: end; - margin-left: var(--spacing-half); - } - - .lines { - grid-area: lines; - display: flex; - flex-wrap: wrap; - column-gap: var(--spacing-half); - - button { - margin-top: var(--spacing-half); - border-color: var(--background-2); - - &.accepted { - background: var(--color-accepted); - } - - &.confirmed { - cursor: auto; - background: var(--color-confirmed); - } - - &.neg { - margin-left: var(--spacing-half); - } - } - } - } -} - -.number { +.alt-text, .alt { font-family: var(--secondary-font-family); + // font-size: var(--small-font-size); text-transform: uppercase; } -.swirl { - background-image: url("./../assets/swirl.fix.svg"); - background-size: contain; - background-repeat: no-repeat; - background-position: center; - - margin-bottom: var(--spacing); -} - -@media (max-width:900px) { - .landing { - grid-template-columns: 1fr; - grid-template-areas: - "swirl" - "login" - "words"; - } - - .list { - grid-template-columns: 1fr; - } - - .search { - grid-template-columns: 1fr; - } - - .offers { - grid-template-columns: 1fr; - } - - .info { - grid-template-columns: 1fr; - // is necessary for some reason - grid-template-areas: - "swirl" - "contact" - "words"; - } - - main { - padding: 0 var(--spacing) 0 var(--spacing); - } -} - -@media (max-width:1200px) { - img { - width: 5rem; - } -} - - -// ------------ -// toasts - -.iziToast { - border-radius: 0; - border-color: var(--base-border-color); - - .iziToast-body { - font-family: var(--base-font-family); - font-size: var(--base-font-size); - } - - .iziToast-title { - font-family: var(--secondary-font-family); - text-transform: uppercase; - } -} +@import 'styles.less'; diff --git a/client/src/style/styles.less b/client/src/style/styles.less new file mode 100644 index 0000000..fa9c66c --- /dev/null +++ b/client/src/style/styles.less @@ -0,0 +1,403 @@ +body { + padding-top: calc(var(--spacing)/2); + overflow: hidden; +} + +#mcrates { + padding: 0 var(--spacing-double) 0 var(--spacing-double); + display: grid; + + grid-template-areas: + "header header" + "main main" + "footer footer"; + + height: 100vh; + width: 100vw; + display: grid; + grid-template-columns: 1fr; + grid-template-rows: min-content 1fr min-content; +} + +.landing { + display: grid; + + grid-template-columns: 1fr 2fr; + grid-gap: calc(var(--spacing-double) * 2); + grid-template-areas: + "login swirl" + "login words"; + + .login { + grid-area: login; + button { + width: 100%; + } + } + + .swirl { + grid-area: swirl; + height: 15rem; + } + + .words { + grid-area: words; + text-align: center; + } +} + +.info { + display: grid; + + grid-template-areas: + "words swirl" + "words contact"; + + grid-template-columns: 1fr 1fr; + grid-template-rows: min-content 1fr; + + section { + margin-bottom: var(--spacing); + } + + .contact { + grid-area: contact; + text-align: center; + } + + .words { + grid-area: words; + } + + .swirl { + grid-area: swirl; + height: 15rem; + } +} + +article { + background-color: var(--background-1); + + button { + border-color: var(--background-2); + } +} + +.search { + display: grid; + grid-template-columns: 1fr 2fr; + + .results { + display: grid; + padding-left: var(--spacing); + grid-gap: var(--spacing); + + article { + display: grid; + padding: var(--spacing); + grid-template-columns: 1fr 4fr min-content; + } + } + + button { + margin-right: var(--spacing); + background: var(--background-2); + border-color: var(--background-1); + + &.added { + background: var(--color-green); + cursor: auto; + } + } +} + +.list { + display: grid; + grid-template-columns: + 1fr 1fr 1fr; + + grid-gap: var(--spacing); + + article { + display: grid; + + grid-template-areas: + "title img" + "details details" + "remove remove"; + + button { + margin-top: var(--spacing-half); + grid-area: remove + } + + .details { + grid-area: details; + } + + padding: var(--spacing); + + img { + justify-self: end; + } + } +} + +form { + margin-bottom: var(--spacing); + + label, input { + display: block; + } + + input, button { + width: 100%; + } + + input { + padding: var(--spacing-half); + margin-bottom: var(--spacing); + } + + label { + font-family: var(--secondary-font-family); + font-size: var(--small-font-size); + text-transform: uppercase; + margin-bottom: var(--spacing-half); + } + +} + +header { + grid-area: header; + + display: grid; + grid-template-columns: 1fr 1fr min-content; + + border-bottom: var(--base-border); + padding-bottom: var(--spacing-half); + margin-bottom: var(--spacing-half); + + a { + font-size: var(--small-font-size); + margin-right: var(--spacing); + } + + a { + white-space: nowrap; + } +} + +main { + grid-area: main; + + display: grid; + grid-template-areas: + "nav content"; + + grid-template-columns: + 1fr 1fr; + + column-gap: var(--spacing); + + overflow: hidden; + + nav { + // duck scrollbars + padding-right: var(--spacing-half); + + grid-area: nav; + + div { + display: grid; + grid-template-columns: + 1fr min-content; + + a { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + + overflow: scroll; + } + + .offers { + grid-area: content; + overflow: scroll; + } +} + +.bundles { + flex-flow: row; + + .bundle { + margin-bottom: var(--spacing-double); + + section { + margin-bottom: var(--spacing); + } + + .items { + display: grid; + grid-template-columns: repeat(5, 1fr); + + div { + margin-right: var(--spacing); + margin-bottom: var(--spacing); + + display: grid; + + &.bold { + font-weight: bold; + background: var(--background-2); + } + } + } + } +} + +.offers { + display: grid; + // grid-template-columns: 1fr 1fr; + grid-gap: var(--spacing); + + .offer { + display: grid; + grid-template-columns: 1fr min-content; + grid-template-rows: min-content min-content; + grid-template-areas: + "details img" + "lines lines"; + + padding: var(--spacing); + background: var(--background-1); + + .details { + font-size: var(--small-font-size); + } + + .status { + margin-top: var(--spacing-half); + } + + section { + grid-area: details; + } + + img { + grid-area: img; + justify-self: end; + margin-left: var(--spacing-half); + } + + .lines { + grid-area: lines; + display: flex; + flex-wrap: wrap; + column-gap: var(--spacing-half); + + button { + margin-top: var(--spacing-half); + border-color: var(--background-2); + + &.accepted { + background: var(--color-accepted); + } + + &.confirmed { + cursor: auto; + background: var(--color-confirmed); + } + + &.neg { + margin-left: var(--spacing-half); + } + } + } + } +} + +.number { + font-family: var(--secondary-font-family); + text-transform: uppercase; +} + +.swirl { + background-image: url("./../assets/swirl.fix.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + + margin-bottom: var(--spacing); +} + +@media (max-width:900px) { + .landing { + grid-template-columns: 1fr; + grid-template-areas: + "swirl" + "login" + "words"; + } + + .list { + grid-template-columns: 1fr; + } + + .search { + grid-template-columns: 1fr; + } + + .offers { + grid-template-columns: 1fr; + } + + .info { + grid-template-columns: 1fr; + // is necessary for some reason + grid-template-areas: + "swirl" + "contact" + "words"; + } + + #mcrates { + padding: 0 var(--spacing) 0 var(--spacing); + } + + main { + grid-template-columns: 1fr; + grid-template-rows: 1fr 3fr; + grid-gap: var(--spacing-half); + grid-template-areas: + "nav" + "content"; + } +} + +@media (max-width:1200px) { + img { + width: 5rem; + } +} + + +// ------------ +// toasts + +.iziToast { + border-radius: 0; + border-color: var(--base-border-color); + + .iziToast-body { + font-family: var(--base-font-family); + font-size: var(--base-font-size); + } + + .iziToast-title { + font-family: var(--secondary-font-family); + text-transform: uppercase; + } +}