diff --git a/api/resolvers/item.js b/api/resolvers/item.js index 1f21da31..172650f1 100644 --- a/api/resolvers/item.js +++ b/api/resolvers/item.js @@ -146,6 +146,10 @@ function recentClause (type) { } } +const subClause = (sub, num) => { + return sub ? ` AND "subName" = $${num} ` : ` AND ("subName" IS NOT NULL OR "subName" = $${num}) ` +} + export default { Query: { itemRepetition: async (parent, { parentId }, { me, models }) => { @@ -194,10 +198,6 @@ export default { const decodedCursor = decodeCursor(cursor) let items; let user; let pins; let subFull - const subClause = (num) => { - return sub ? ` AND "subName" = $${num} ` : ` AND ("subName" IS NULL OR "subName" = $${num}) ` - } - const activeOrMine = () => { return me ? ` AND (status <> 'STOPPED' OR "userId" = ${me.id}) ` : ' AND status <> \'STOPPED\' ' } @@ -229,7 +229,7 @@ export default { ${SELECT} FROM "Item" WHERE "parentId" IS NULL AND created_at <= $1 - ${subClause(3)} + ${subClause(sub, 3)} ${activeOrMine()} ${await filterClause(me, models)} ${recentClause(type)} @@ -264,7 +264,7 @@ export default { FROM "Item" WHERE "parentId" IS NULL AND created_at <= $1 AND "pinId" IS NULL - ${subClause(3)} + ${subClause(sub, 3)} AND status = 'ACTIVE' AND "maxBid" > 0 ORDER BY "maxBid" DESC, created_at ASC) UNION ALL @@ -272,7 +272,7 @@ export default { FROM "Item" WHERE "parentId" IS NULL AND created_at <= $1 AND "pinId" IS NULL - ${subClause(3)} + ${subClause(sub, 3)} AND ((status = 'ACTIVE' AND "maxBid" = 0) OR status = 'NOSATS') ORDER BY created_at DESC) ) a @@ -292,7 +292,7 @@ export default { FROM "Item" WHERE "parentId" IS NULL AND "Item".created_at <= $1 AND "Item".created_at > $3 AND "pinId" IS NULL AND NOT bio AND "deletedAt" IS NULL - ${subClause(4)} + ${subClause(sub, 4)} ${await filterClause(me, models)} ${await newTimedOrderByWeightedSats(me, models, 1)} OFFSET $2 @@ -305,7 +305,7 @@ export default { FROM "Item" WHERE "parentId" IS NULL AND "Item".created_at <= $1 AND "pinId" IS NULL AND NOT bio AND "deletedAt" IS NULL - ${subClause(3)} + ${subClause(sub, 3)} ${await filterClause(me, models)} ${await newTimedOrderByWeightedSats(me, models, 1)} OFFSET $2 @@ -323,7 +323,8 @@ export default { ) FROM "Item" WHERE "pinId" IS NOT NULL - ) rank_filter WHERE RANK = 1`) + ${subClause(sub, 1)} + ) rank_filter WHERE RANK = 1`, sub) } break } @@ -428,7 +429,7 @@ export default { items } }, - moreFlatComments: async (parent, { cursor, name, sort, within }, { me, models }) => { + moreFlatComments: async (parent, { sub, cursor, name, sort, within }, { me, models }) => { const decodedCursor = decodeCursor(cursor) let comments, user @@ -437,11 +438,13 @@ export default { comments = await models.$queryRaw(` ${SELECT} FROM "Item" - WHERE "parentId" IS NOT NULL AND created_at <= $1 + JOIN "Item" root ON "Item"."rootId" = root.id + WHERE "Item"."parentId" IS NOT NULL AND "Item".created_at <= $1 + AND (root."subName" = $3 OR (root."subName" IS NULL AND $3 IS NULL)) ${await filterClause(me, models)} - ORDER BY created_at DESC + ORDER BY "Item".created_at DESC OFFSET $2 - LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset) + LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset, sub) break case 'user': if (!name) { @@ -467,13 +470,15 @@ export default { comments = await models.$queryRaw(` ${SELECT} FROM "Item" - WHERE "parentId" IS NOT NULL AND "deletedAt" IS NULL + JOIN "Item" root ON "Item"."rootId" = root.id + WHERE "Item"."parentId" IS NOT NULL AND"Item"."deletedAt" IS NULL + AND (root."subName" = $3 OR (root."subName" IS NULL AND $3 IS NULL)) AND "Item".created_at <= $1 ${topClause(within)} ${await filterClause(me, models)} ${await topOrderByWeightedSats(me, models)} OFFSET $2 - LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset) + LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset, sub) break default: throw new UserInputError('invalid sort type', { argumentName: 'sort' }) @@ -664,7 +669,7 @@ export default { } }, upsertPoll: async (parent, { id, ...data }, { me, models }) => { - const { forward, boost, title, text, options } = data + const { sub, forward, boost, title, text, options } = data if (!me) { throw new AuthenticationError('you must be logged in') } @@ -693,16 +698,16 @@ export default { throw new AuthenticationError('item does not belong to you') } const [item] = await serialize(models, - models.$queryRaw(`${SELECT} FROM update_poll($1, $2, $3, $4, $5, $6) AS "Item"`, - Number(id), title, text, Number(boost || 0), options, Number(fwdUser?.id))) + models.$queryRaw(`${SELECT} FROM update_poll($1, $2, $3, $4, $5, $6, $7) AS "Item"`, + sub || 'bitcoin', Number(id), title, text, Number(boost || 0), options, Number(fwdUser?.id))) await createMentions(item, models) item.comments = [] return item } else { const [item] = await serialize(models, - models.$queryRaw(`${SELECT} FROM create_poll($1, $2, $3, $4, $5, $6, $7, '${ITEM_SPAM_INTERVAL}') AS "Item"`, - title, text, 1, Number(boost || 0), Number(me.id), options, Number(fwdUser?.id))) + models.$queryRaw(`${SELECT} FROM create_poll($1, $2, $3, $4, $5, $6, $7, $8, '${ITEM_SPAM_INTERVAL}') AS "Item"`, + sub || 'bitcoin', title, text, 1, Number(boost || 0), Number(me.id), options, Number(fwdUser?.id))) await createMentions(item, models) item.comments = [] @@ -1028,7 +1033,7 @@ export const createMentions = async (item, models) => { } } -export const updateItem = async (parent, { id, data: { title, url, text, boost, forward, bounty, parentId } }, { me, models }) => { +export const updateItem = async (parent, { id, data: { sub, title, url, text, boost, forward, bounty, parentId } }, { me, models }) => { // update iff this item belongs to me const old = await models.item.findUnique({ where: { id: Number(id) } }) if (Number(old.userId) !== Number(me?.id)) { @@ -1059,15 +1064,16 @@ export const updateItem = async (parent, { id, data: { title, url, text, boost, const [item] = await serialize(models, models.$queryRaw( - `${SELECT} FROM update_item($1, $2, $3, $4, $5, $6, $7) AS "Item"`, - Number(id), title, url, text, Number(boost || 0), bounty ? Number(bounty) : null, Number(fwdUser?.id))) + `${SELECT} FROM update_item($1, $2, $3, $4, $5, $6, $7, $8) AS "Item"`, + old.parentId ? null : sub || 'bitcoin', Number(id), title, url, text, + Number(boost || 0), bounty ? Number(bounty) : null, Number(fwdUser?.id))) await createMentions(item, models) return item } -const createItem = async (parent, { title, url, text, boost, forward, bounty, parentId }, { me, models }) => { +const createItem = async (parent, { sub, title, url, text, boost, forward, bounty, parentId }, { me, models }) => { if (!me) { throw new AuthenticationError('you must be logged in') } @@ -1091,7 +1097,8 @@ const createItem = async (parent, { title, url, text, boost, forward, bounty, pa const [item] = await serialize( models, models.$queryRaw( - `${SELECT} FROM create_item($1, $2, $3, $4, $5, $6, $7, $8, '${ITEM_SPAM_INTERVAL}') AS "Item"`, + `${SELECT} FROM create_item($1, $2, $3, $4, $5, $6, $7, $8, $9, '${ITEM_SPAM_INTERVAL}') AS "Item"`, + parentId ? null : sub || 'bitcoin', title, url, text, diff --git a/api/resolvers/search.js b/api/resolvers/search.js index ec75a84f..fa73c79d 100644 --- a/api/resolvers/search.js +++ b/api/resolvers/search.js @@ -79,7 +79,7 @@ export default { items } }, - search: async (parent, { q: query, sub, cursor, sort, what, when }, { me, models, search }) => { + search: async (parent, { q: query, cursor, sort, what, when }, { me, models, search }) => { const decodedCursor = decodeCursor(cursor) let sitems @@ -105,7 +105,9 @@ export default { const queryArr = query.trim().split(/\s+/) const url = queryArr.find(word => word.startsWith('url:')) const nym = queryArr.find(word => word.startsWith('nym:')) - query = queryArr.filter(word => !word.startsWith('url:') && !word.startsWith('nym:')).join(' ') + const sub = queryArr.find(word => word.startsWith('~')) + const exclude = [url, nym, sub] + query = queryArr.filter(word => !exclude.includes(word)).join(' ') if (url) { whatArr.push({ wildcard: { url: `*${url.slice(4).toLowerCase()}*` } }) @@ -115,6 +117,10 @@ export default { whatArr.push({ wildcard: { 'user.name': `*${nym.slice(4).toLowerCase()}*` } }) } + if (sub) { + whatArr.push({ match: { 'sub.name': sub.slice(1).toLowerCase() } }) + } + const sortArr = [] switch (sort) { case 'recent': @@ -204,9 +210,6 @@ export default { bool: { must: [ ...whatArr, - sub - ? { match: { 'sub.name': sub } } - : { bool: { must_not: { exists: { field: 'sub.name' } } } }, me ? { bool: { diff --git a/api/typeDefs/item.js b/api/typeDefs/item.js index 23ee493a..12fa7141 100644 --- a/api/typeDefs/item.js +++ b/api/typeDefs/item.js @@ -3,7 +3,7 @@ import { gql } from 'apollo-server-micro' export default gql` extend type Query { items(sub: String, sort: String, type: String, cursor: String, name: String, within: String): Items - moreFlatComments(sort: String!, cursor: String, name: String, within: String): Comments + moreFlatComments(sub: String, sort: String!, cursor: String, name: String, within: String): Comments moreBookmarks(cursor: String, name: String!): Items item(id: ID!): Item comments(id: ID!, sort: String): [Item!]! @@ -12,7 +12,7 @@ export default gql` related(cursor: String, title: String, id: ID, minMatch: String, limit: Int): Items allItems(cursor: String): Items getBountiesByUserName(name: String!, cursor: String, , limit: Int): Items - search(q: String, sub: String, cursor: String, what: String, sort: String, when: String): Items + search(q: String, cursor: String, what: String, sort: String, when: String): Items auctionPosition(sub: String, id: ID, bid: Int!): Int! itemRepetition(parentId: ID): Int! outlawedItems(cursor: String): Items @@ -35,12 +35,12 @@ export default gql` extend type Mutation { bookmarkItem(id: ID): Item deleteItem(id: ID): Item - upsertLink(id: ID, title: String!, url: String!, boost: Int, forward: String): Item! - upsertDiscussion(id: ID, title: String!, text: String, boost: Int, forward: String): Item! - upsertBounty(id: ID, title: String!, text: String, bounty: Int!, boost: Int, forward: String): Item! - upsertJob(id: ID, sub: ID!, title: String!, company: String!, location: String, remote: Boolean, + upsertLink(id: ID, sub: String, title: String!, url: String!, boost: Int, forward: String): Item! + upsertDiscussion(id: ID, sub: String, title: String!, text: String, boost: Int, forward: String): Item! + upsertBounty(id: ID, sub: String, title: String!, text: String, bounty: Int!, boost: Int, forward: String): Item! + upsertJob(id: ID, sub: String!, title: String!, company: String!, location: String, remote: Boolean, text: String!, url: String!, maxBid: Int!, status: String, logo: Int): Item! - upsertPoll(id: ID, title: String!, text: String, options: [String!]!, boost: Int, forward: String): Item! + upsertPoll(id: ID, sub: String, title: String!, text: String, options: [String!]!, boost: Int, forward: String): Item! createComment(text: String!, parentId: ID!): Item! updateComment(id: ID!, text: String!): Item! dontLikeThis(id: ID!): Boolean! diff --git a/api/typeDefs/sub.js b/api/typeDefs/sub.js index 9e1ad04c..4a96855c 100644 --- a/api/typeDefs/sub.js +++ b/api/typeDefs/sub.js @@ -2,12 +2,12 @@ import { gql } from 'apollo-server-micro' export default gql` extend type Query { - sub(name: ID!): Sub - subLatestPost(name: ID!): String + sub(name: String!): Sub + subLatestPost(name: String!): String } type Sub { - name: ID! + name: String! createdAt: String! updatedAt: String! postTypes: [String!]! diff --git a/components/bounty-form.js b/components/bounty-form.js index f0a18073..ae3d62c4 100644 --- a/components/bounty-form.js +++ b/components/bounty-form.js @@ -10,6 +10,7 @@ import { bountySchema } from '../lib/validate' export function BountyForm ({ item, + sub, editThreshold, titleLabel = 'title', bountyLabel = 'bounty', @@ -24,6 +25,7 @@ export function BountyForm ({ const [upsertBounty] = useMutation( gql` mutation upsertBounty( + $sub: String $id: ID $title: String! $bounty: Int! @@ -32,6 +34,7 @@ export function BountyForm ({ $forward: String ) { upsertBounty( + sub: $sub id: $id title: $title bounty: $bounty @@ -59,6 +62,7 @@ export function BountyForm ({ (async ({ boost, bounty, ...values }) => { const { error } = await upsertBounty({ variables: { + sub: item?.sub?.name || sub?.name, id: item?.id, boost: boost ? Number(boost) : undefined, bounty: bounty ? Number(bounty) : undefined, @@ -72,7 +76,8 @@ export function BountyForm ({ if (item) { await router.push(`/items/${item.id}`) } else { - await router.push('/recent') + const prefix = sub?.name ? `/~${sub.name}/` : '' + await router.push(prefix + '/recent') } }) } diff --git a/components/discussion-form.js b/components/discussion-form.js index 1738dc96..02e2ebcf 100644 --- a/components/discussion-form.js +++ b/components/discussion-form.js @@ -13,7 +13,7 @@ import { Button } from 'react-bootstrap' import { discussionSchema } from '../lib/validate' export function DiscussionForm ({ - item, editThreshold, titleLabel = 'title', + item, sub, editThreshold, titleLabel = 'title', textLabel = 'text', buttonText = 'post', adv, handleSubmit }) { @@ -23,8 +23,8 @@ export function DiscussionForm ({ // const me = useMe() const [upsertDiscussion] = useMutation( gql` - mutation upsertDiscussion($id: ID, $title: String!, $text: String, $boost: Int, $forward: String) { - upsertDiscussion(id: $id, title: $title, text: $text, boost: $boost, forward: $forward) { + mutation upsertDiscussion($sub: String, $id: ID, $title: String!, $text: String, $boost: Int, $forward: String) { + upsertDiscussion(sub: $sub, id: $id, title: $title, text: $text, boost: $boost, forward: $forward) { id } }` @@ -56,7 +56,7 @@ export function DiscussionForm ({ schema={schema} onSubmit={handleSubmit || (async ({ boost, ...values }) => { const { error } = await upsertDiscussion({ - variables: { id: item?.id, boost: boost ? Number(boost) : undefined, ...values } + variables: { sub: item?.sub?.name || sub?.name, id: item?.id, boost: boost ? Number(boost) : undefined, ...values } }) if (error) { throw new Error({ message: error.toString() }) @@ -65,7 +65,8 @@ export function DiscussionForm ({ if (item) { await router.push(`/items/${item.id}`) } else { - await router.push('/recent') + const prefix = sub?.name ? `/~${sub.name}/` : '' + await router.push(prefix + '/recent') } })} storageKeyPrefix={item ? undefined : 'discussion'} diff --git a/components/error-boundary.js b/components/error-boundary.js index 83e1b4b7..5ae01f06 100644 --- a/components/error-boundary.js +++ b/components/error-boundary.js @@ -1,5 +1,5 @@ import React from 'react' -import LayoutError from './layout-error' +import LayoutStatic from './layout-static' import styles from '../styles/404.module.css' class ErrorBoundary extends React.Component { @@ -25,10 +25,10 @@ class ErrorBoundary extends React.Component { if (this.state.hasError) { // You can render any custom fallback UI return ( - +

something went wrong

-
+ ) } diff --git a/components/footer.js b/components/footer.js index 55c2846f..6499912b 100644 --- a/components/footer.js +++ b/components/footer.js @@ -19,7 +19,7 @@ import { useEffect, useState } from 'react' // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX const COLORS = { light: { - body: '#f5f5f5', + body: '#f5f5f7', color: '#212529', navbarVariant: 'light', navLink: 'rgba(0, 0, 0, 0.55)', @@ -157,9 +157,9 @@ export default function Footer ({ noLinks }) { {!noLinks && <> {mounted && -
- darkMode.toggle()} className='fill-grey theme' /> - +
+ darkMode.toggle()} width={20} height={20} className='fill-grey theme' /> +
}
diff --git a/components/header.js b/components/header.js index a80d772a..17397790 100644 --- a/components/header.js +++ b/components/header.js @@ -16,6 +16,8 @@ import NoteIcon from '../svgs/notification-4-fill.svg' import { useQuery, gql } from '@apollo/client' import LightningIcon from '../svgs/bolt.svg' import CowboyHat from './cowboy-hat' +import { Form, Select } from './form' +import SearchIcon from '../svgs/search-line.svg' function WalletSummary ({ me }) { if (!me) return null @@ -25,34 +27,44 @@ function WalletSummary ({ me }) { export default function Header ({ sub }) { const router = useRouter() - const path = router.asPath.split('?')[0] const [fired, setFired] = useState() + const [topNavKey, setTopNavKey] = useState('') + const [dropNavKey, setDropNavKey] = useState('') + const [prefix, setPrefix] = useState('') + const [path, setPath] = useState('') const me = useMe() - const prefix = sub ? `/~${sub}` : '' - // there's always at least 2 on the split, e.g. '/' yields ['',''] - const topNavKey = path.split('/')[sub ? 2 : 1] - const dropNavKey = path.split('/').slice(sub ? 2 : 1).join('/') - const { data: subLatestPost } = useQuery(gql` - query subLatestPost($name: ID!) { - subLatestPost(name: $name) - } - `, { variables: { name: 'jobs' }, pollInterval: 600000, fetchPolicy: 'network-only' }) + + useEffect(() => { + // there's always at least 2 on the split, e.g. '/' yields ['',''] + const path = router.asPath.split('?')[0] + console.log(path, path.split('/')[sub ? 2 : 1], path.split('/').slice(sub ? 2 : 1).join('/')) + setPrefix(sub ? `/~${sub}` : '') + setTopNavKey(path.split('/')[sub ? 2 : 1] ?? '') + setDropNavKey(path.split('/').slice(sub ? 2 : 1).join('/')) + setPath(path) + }, [sub, router.asPath]) + + // const { data: subLatestPost } = useQuery(gql` + // query subLatestPost($name: ID!) { + // subLatestPost(name: $name) + // } + // `, { variables: { name: 'jobs' }, pollInterval: 600000, fetchPolicy: 'network-only' }) const { data: hasNewNotes } = useQuery(gql` { hasNewNotes } `, { pollInterval: 30000, fetchPolicy: 'cache-and-network' }) - const [lastCheckedJobs, setLastCheckedJobs] = useState(new Date().getTime()) - useEffect(() => { - if (me) { - setLastCheckedJobs(me.lastCheckedJobs) - } else { - if (sub === 'jobs') { - localStorage.setItem('lastCheckedJobs', new Date().getTime()) - } - setLastCheckedJobs(localStorage.getItem('lastCheckedJobs')) - } - }, [sub]) + // const [lastCheckedJobs, setLastCheckedJobs] = useState(new Date().getTime()) + // useEffect(() => { + // if (me) { + // setLastCheckedJobs(me.lastCheckedJobs) + // } else { + // if (sub === 'jobs') { + // localStorage.setItem('lastCheckedJobs', new Date().getTime()) + // } + // setLastCheckedJobs(localStorage.getItem('lastCheckedJobs')) + // } + // }, [sub]) const Corner = () => { if (me) { @@ -63,7 +75,7 @@ export default function Header ({ sub }) { - + {hasNewNotes?.hasNewNotes && {' '} @@ -73,11 +85,9 @@ export default function Header ({ sub }) {
- e.preventDefault()}> - {`@${me?.name}`} - - + e.preventDefault()}> + {`@${me?.name}`} + } alignRight > @@ -142,7 +152,7 @@ export default function Header ({ sub }) { }, []) } return path !== '/login' && path !== '/signup' && !path.startsWith('/invites') && -
+
diff --git a/components/search.js b/components/search.js index fcb4e454..7c3a3cfc 100644 --- a/components/search.js +++ b/components/search.js @@ -49,7 +49,7 @@ export default function Search ({ sub }) { } const showSearch = atBottom || searching || router.query.q - const filter = router.query.q && !sub + const filter = sub !== 'jobs' return ( <>
@@ -100,7 +100,7 @@ export default function Search ({ sub }) { { if (navigator.share) { @@ -29,7 +30,7 @@ export default function Share ({ item }) { : ( - + diff --git a/components/table-of-contents.js b/components/table-of-contents.js index 59475199..8bf4e03b 100644 --- a/components/table-of-contents.js +++ b/components/table-of-contents.js @@ -26,7 +26,7 @@ export default function Toc ({ text }) { return ( - + diff --git a/fragments/comments.js b/fragments/comments.js index 863dc4f2..059127fa 100644 --- a/fragments/comments.js +++ b/fragments/comments.js @@ -42,8 +42,8 @@ export const COMMENT_FIELDS = gql` export const MORE_FLAT_COMMENTS = gql` ${COMMENT_FIELDS} - query MoreFlatComments($sort: String!, $cursor: String, $name: String, $within: String) { - moreFlatComments(sort: $sort, cursor: $cursor, name: $name, within: $within) { + query MoreFlatComments($sub: String, $sort: String!, $cursor: String, $name: String, $within: String) { + moreFlatComments(sub: $sub, sort: $sort, cursor: $cursor, name: $name, within: $within) { cursor comments { ...CommentFields diff --git a/fragments/subs.js b/fragments/subs.js index fc6025d0..de00dfa0 100644 --- a/fragments/subs.js +++ b/fragments/subs.js @@ -1,5 +1,6 @@ import { gql } from '@apollo/client' import { ITEM_FIELDS } from './items' +import { COMMENT_FIELDS } from './comments' export const SUB_FIELDS = gql` fragment SubFields on Sub { @@ -12,7 +13,7 @@ export const SUB_FIELDS = gql` export const SUB = gql` ${SUB_FIELDS} - query Sub($sub: ID!) { + query Sub($sub: String!) { sub(name: $sub) { ...SubFields } @@ -21,11 +22,11 @@ export const SUB = gql` export const SUB_ITEMS = gql` ${SUB_FIELDS} ${ITEM_FIELDS} - query SubRecent($sub: String, $sort: String) { + query SubItems($sub: String!, $sort: String, $type: String) { sub(name: $sub) { ...SubFields } - items(sub: $sub, sort: $sort) { + items(sub: $sub, sort: $sort, type: $type) { cursor items { ...ItemFields @@ -42,11 +43,11 @@ export const SUB_ITEMS = gql` export const SUB_SEARCH = gql` ${SUB_FIELDS} ${ITEM_FIELDS} - query SubSearch($sub: String, $q: String, $cursor: String) { + query SubSearch($sub: String!, $q: String, $cursor: String) { sub(name: $sub) { ...SubFields } - search(q: $q, sub: $sub, cursor: $cursor) { + search(q: $q, cursor: $cursor) { cursor items { ...ItemFields @@ -57,3 +58,21 @@ export const SUB_SEARCH = gql` } } ` + +export const SUB_FLAT_COMMENTS = gql` + ${SUB_FIELDS} + ${COMMENT_FIELDS} + + query SubFlatComments($sub: String!, $sort: String!, $cursor: String) { + sub(name: $sub) { + ...SubFields + } + + moreFlatComments(sub: $sub, sort: $sort, cursor: $cursor) { + cursor + comments { + ...CommentFields + } + } + } +` diff --git a/pages/404.js b/pages/404.js index 90319b37..158cdb97 100644 --- a/pages/404.js +++ b/pages/404.js @@ -1,12 +1,12 @@ import { Image } from 'react-bootstrap' -import LayoutError from '../components/layout-error' +import LayoutStatic from '../components/layout-static' import styles from '../styles/404.module.css' export default function fourZeroFour () { return ( - +

404page not found

-
+ ) } diff --git a/pages/500.js b/pages/500.js index 5dbe3ed2..cabd4ab4 100644 --- a/pages/500.js +++ b/pages/500.js @@ -1,12 +1,12 @@ import { Image } from 'react-bootstrap' -import LayoutError from '../components/layout-error' +import LayoutStatic from '../components/layout-static' import styles from '../styles/404.module.css' export default function fourZeroFour () { return ( - +

500server error

-
+ ) } diff --git a/pages/email.js b/pages/email.js index 9911dc1b..233caa4a 100644 --- a/pages/email.js +++ b/pages/email.js @@ -1,14 +1,14 @@ -import LayoutError from '../components/layout-error' +import LayoutStatic from '../components/layout-static' import { Image } from 'react-bootstrap' export default function Email () { return ( - +

Check your email

A sign in link has been sent to your email address

-
+ ) } diff --git a/pages/login.js b/pages/login.js index b2c9d308..5d1d71b7 100644 --- a/pages/login.js +++ b/pages/login.js @@ -1,6 +1,6 @@ import { providers, getSession } from 'next-auth/client' import Link from 'next/link' -import LayoutCenter from '../components/layout-center' +import LayoutStatic from '../components/layout-static' import Login from '../components/login' export async function getServerSideProps ({ req, res, query: { callbackUrl, error = null } }) { @@ -31,11 +31,11 @@ function LoginFooter ({ callbackUrl }) { export default function LoginPage (props) { return ( - + } {...props} /> - + ) } diff --git a/pages/post.js b/pages/post.js index 316aabad..377f68ae 100644 --- a/pages/post.js +++ b/pages/post.js @@ -9,6 +9,8 @@ import { getGetServerSideProps } from '../api/ssrApollo' import AccordianItem from '../components/accordian-item' import { PollForm } from '../components/poll-form' import { BountyForm } from '../components/bounty-form' +import { Form, Select } from '../components/form' +import { useEffect, useState } from 'react' export const getServerSideProps = getGetServerSideProps() @@ -61,9 +63,44 @@ export function PostForm () { } } +export function SubSelect ({ children }) { + const router = useRouter() + const [sub, setSub] = useState(router.query.sub || 'bitcoin') + + useEffect(() => { + setSub(router.query.sub || 'bitcoin') + }, [router.query?.sub]) + + return ( +
+
+