add top spenders to top page

This commit is contained in:
keyan 2022-02-02 15:50:12 -06:00
parent 9490b3dc5f
commit 8829fccdef
5 changed files with 81 additions and 34 deletions

View File

@ -41,19 +41,33 @@ export default {
return me.name?.toUpperCase() === name?.toUpperCase() || !(await models.user.findUnique({ where: { name } })) return me.name?.toUpperCase() === name?.toUpperCase() || !(await models.user.findUnique({ where: { name } }))
}, },
topUsers: async (parent, { cursor, within }, { models, me }) => { topUsers: async (parent, { cursor, within, userType }, { models, me }) => {
const decodedCursor = decodeCursor(cursor) const decodedCursor = decodeCursor(cursor)
const users = await models.$queryRaw(` let users
SELECT users.name, users.created_at, sum("ItemAct".sats) as stacked if (userType === 'spent') {
FROM "ItemAct" users = await models.$queryRaw(`
JOIN "Item" on "ItemAct"."itemId" = "Item".id SELECT users.name, users.created_at, sum("ItemAct".sats) as amount
JOIN users on "Item"."userId" = users.id FROM "ItemAct"
WHERE act <> 'BOOST' AND "ItemAct"."userId" <> users.id AND "ItemAct".created_at <= $1 JOIN users on "ItemAct"."userId" = users.id
${topClause(within)} WHERE "ItemAct".created_at <= $1
GROUP BY users.id, users.name ${topClause(within)}
ORDER BY stacked DESC NULLS LAST, users.created_at DESC GROUP BY users.id, users.name
OFFSET $2 ORDER BY amount DESC NULLS LAST, users.created_at DESC
LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset) OFFSET $2
LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset)
} else {
users = await models.$queryRaw(`
SELECT users.name, users.created_at, sum("ItemAct".sats) as amount
FROM "ItemAct"
JOIN "Item" on "ItemAct"."itemId" = "Item".id
JOIN users on "Item"."userId" = users.id
WHERE act <> 'BOOST' AND "ItemAct"."userId" <> users.id AND "ItemAct".created_at <= $1
${topClause(within)}
GROUP BY users.id, users.name
ORDER BY amount DESC NULLS LAST, users.created_at DESC
OFFSET $2
LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset)
}
return { return {
cursor: users.length === LIMIT ? nextCursorEncoded(decodedCursor) : null, cursor: users.length === LIMIT ? nextCursorEncoded(decodedCursor) : null,

View File

@ -6,7 +6,7 @@ export default gql`
user(name: String!): User user(name: String!): User
users: [User!] users: [User!]
nameAvailable(name: String!): Boolean! nameAvailable(name: String!): Boolean!
topUsers(cursor: String, within: String!): Users topUsers(cursor: String, within: String!, userType: String!): TopUsers
} }
type Users { type Users {
@ -14,6 +14,17 @@ export default gql`
users: [User!]! users: [User!]!
} }
type TopUsers {
cursor: String
users: [TopUser!]!
}
type TopUser {
name: String!
createdAt: String!
amount: Int!
}
extend type Mutation { extend type Mutation {
setName(name: String!): Boolean setName(name: String!): Boolean
setSettings(tipDefault: Int!): Boolean setSettings(tipDefault: Int!): Boolean

View File

@ -6,20 +6,20 @@ import { useRouter } from 'next/router'
export default function TopHeader ({ cat }) { export default function TopHeader ({ cat }) {
const router = useRouter() const router = useRouter()
const within = router.query.within const within = router.query.within
const userType = router.query.userType || 'stacked'
return ( return (
<> <>
<Navbar className='pt-0'> <Navbar className='pt-0'>
<Nav <Nav
className={`${styles.navbarNav} justify-content-around`} className={`${styles.navbarNav} justify-content-around`}
activeKey={cat} activeKey={cat.split('/')[0]}
> >
<Nav.Item> <Nav.Item>
<Link href={`/top/posts/${within}`} passHref> <Link href={`/top/posts/${within}`} passHref>
<Nav.Link <Nav.Link
eventKey='posts' eventKey='posts'
className={styles.navLink} className={styles.navLink}
onClick={() => localStorage.setItem('topWithin', 'day')}
> >
posts posts
</Nav.Link> </Nav.Link>
@ -30,18 +30,16 @@ export default function TopHeader ({ cat }) {
<Nav.Link <Nav.Link
eventKey='comments' eventKey='comments'
className={styles.navLink} className={styles.navLink}
onClick={() => localStorage.setItem('topWithin', 'week')}
> >
comments comments
</Nav.Link> </Nav.Link>
</Link> </Link>
</Nav.Item> </Nav.Item>
<Nav.Item> <Nav.Item>
<Link href={`/top/users/${within}`} passHref> <Link href={`/top/users/stacked/${within}`} passHref>
<Nav.Link <Nav.Link
eventKey='users' eventKey='users'
className={styles.navLink} className={styles.navLink}
onClick={() => localStorage.setItem('topWithin', 'month')}
> >
users users
</Nav.Link> </Nav.Link>
@ -49,6 +47,34 @@ export default function TopHeader ({ cat }) {
</Nav.Item> </Nav.Item>
</Nav> </Nav>
</Navbar> </Navbar>
{cat.split('/')[0] === 'users' &&
<Navbar className='pt-0'>
<Nav
className={`${styles.navbarNav} justify-content-around`}
activeKey={userType}
>
<Nav.Item>
<Link href={`/top/users/stacked/${within}`} passHref>
<Nav.Link
eventKey='stacked'
className={styles.navLink}
>
stacked
</Nav.Link>
</Link>
</Nav.Item>
<Nav.Item>
<Link href={`/top/users/spent/${within}`} passHref>
<Nav.Link
eventKey='spent'
className={styles.navLink}
>
spent
</Nav.Link>
</Link>
</Nav.Item>
</Nav>
</Navbar>}
<Navbar className='pt-0'> <Navbar className='pt-0'>
<Nav <Nav
className={styles.navbarNav} className={styles.navbarNav}
@ -59,7 +85,6 @@ export default function TopHeader ({ cat }) {
<Nav.Link <Nav.Link
eventKey='day' eventKey='day'
className={styles.navLink} className={styles.navLink}
onClick={() => localStorage.setItem('topWithin', 'day')}
> >
day day
</Nav.Link> </Nav.Link>
@ -70,7 +95,6 @@ export default function TopHeader ({ cat }) {
<Nav.Link <Nav.Link
eventKey='week' eventKey='week'
className={styles.navLink} className={styles.navLink}
onClick={() => localStorage.setItem('topWithin', 'week')}
> >
week week
</Nav.Link> </Nav.Link>
@ -81,7 +105,6 @@ export default function TopHeader ({ cat }) {
<Nav.Link <Nav.Link
eventKey='month' eventKey='month'
className={styles.navLink} className={styles.navLink}
onClick={() => localStorage.setItem('topWithin', 'month')}
> >
month month
</Nav.Link> </Nav.Link>
@ -92,7 +115,6 @@ export default function TopHeader ({ cat }) {
<Nav.Link <Nav.Link
eventKey='year' eventKey='year'
className={styles.navLink} className={styles.navLink}
onClick={() => localStorage.setItem('topWithin', 'year')}
> >
year year
</Nav.Link> </Nav.Link>
@ -103,7 +125,6 @@ export default function TopHeader ({ cat }) {
<Nav.Link <Nav.Link
eventKey='forever' eventKey='forever'
className={styles.navLink} className={styles.navLink}
onClick={() => localStorage.removeItem('topWithin')}
> >
forever forever
</Nav.Link> </Nav.Link>

View File

@ -39,11 +39,11 @@ export const USER_FIELDS = gql`
}` }`
export const TOP_USERS = gql` export const TOP_USERS = gql`
query TopUsers($cursor: String, $within: String!) { query TopUsers($cursor: String, $within: String!, $userType: String!) {
topUsers(cursor: $cursor, within: $within) { topUsers(cursor: $cursor, within: $within, userType: $userType) {
users { users {
name name
stacked amount
} }
cursor cursor
} }

View File

@ -1,19 +1,20 @@
import Layout from '../../../components/layout' import Layout from '../../../../components/layout'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { getGetServerSideProps } from '../../../api/ssrApollo' import { getGetServerSideProps } from '../../../../api/ssrApollo'
import TopHeader from '../../../components/top-header' import TopHeader from '../../../../components/top-header'
import { TOP_USERS } from '../../../fragments/users' import { TOP_USERS } from '../../../../fragments/users'
import { useQuery } from '@apollo/client' import { useQuery } from '@apollo/client'
import Link from 'next/link' import Link from 'next/link'
import MoreFooter from '../../../components/more-footer' import MoreFooter from '../../../../components/more-footer'
export const getServerSideProps = getGetServerSideProps(TOP_USERS) export const getServerSideProps = getGetServerSideProps(TOP_USERS)
export default function Index ({ data: { topUsers: { users, cursor } } }) { export default function Index ({ data: { topUsers: { users, cursor } } }) {
const router = useRouter() const router = useRouter()
const userType = router.query.userType
const { data, fetchMore } = useQuery(TOP_USERS, { const { data, fetchMore } = useQuery(TOP_USERS, {
variables: { within: router.query?.within } variables: { within: router.query?.within, userType: router.query?.userType }
}) })
if (data) { if (data) {
@ -22,12 +23,12 @@ export default function Index ({ data: { topUsers: { users, cursor } } }) {
return ( return (
<Layout> <Layout>
<TopHeader cat='users' /> <TopHeader cat={'users/' + userType} />
{users.map(user => ( {users.map(user => (
<Link href={`/${user.name}`} key={user.name}> <Link href={`/${user.name}`} key={user.name}>
<div className='d-flex align-items-center pointer'> <div className='d-flex align-items-center pointer'>
<h3 className='mb-0'>@{user.name}</h3> <h3 className='mb-0'>@{user.name}</h3>
<h2 className='ml-2 mb-0'><small className='text-success'>{user.stacked} stacked</small></h2> <h2 className='ml-2 mb-0'><small className='text-success'>{user.amount} {userType}</small></h2>
</div> </div>
</Link> </Link>
))} ))}