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 } }))
},
topUsers: async (parent, { cursor, within }, { models, me }) => {
topUsers: async (parent, { cursor, within, userType }, { models, me }) => {
const decodedCursor = decodeCursor(cursor)
const users = await models.$queryRaw(`
SELECT users.name, users.created_at, sum("ItemAct".sats) as stacked
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 stacked DESC NULLS LAST, users.created_at DESC
OFFSET $2
LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset)
let users
if (userType === 'spent') {
users = await models.$queryRaw(`
SELECT users.name, users.created_at, sum("ItemAct".sats) as amount
FROM "ItemAct"
JOIN users on "ItemAct"."userId" = users.id
WHERE "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)
} 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 {
cursor: users.length === LIMIT ? nextCursorEncoded(decodedCursor) : null,

View File

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

View File

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

View File

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

View File

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