diff --git a/api/resolvers/growth.js b/api/resolvers/growth.js
index 9b61837a..70681c92 100644
--- a/api/resolvers/growth.js
+++ b/api/resolvers/growth.js
@@ -1,26 +1,5 @@
import { timeUnitForRange, whenRange } from '@/lib/time'
-export function withClause (range) {
- const unit = timeUnitForRange(range)
-
- return `
- WITH range_values AS (
- SELECT date_trunc('${unit}', $1) as minval,
- date_trunc('${unit}', $2) as maxval
- ),
- times AS (
- SELECT generate_series(minval, maxval, interval '1 ${unit}') as time
- FROM range_values
- )
- `
-}
-
-export function intervalClause (range, table) {
- const unit = timeUnitForRange(range)
-
- return `date_trunc('${unit}', "${table}".created_at) >= date_trunc('${unit}', $1) AND date_trunc('${unit}', "${table}".created_at) <= date_trunc('${unit}', $2) `
-}
-
export function viewIntervalClause (range, view) {
const unit = timeUnitForRange(range)
return `"${view}".t >= date_trunc('${unit}', timezone('America/Chicago', $1)) AND date_trunc('${unit}', "${view}".t) <= date_trunc('${unit}', timezone('America/Chicago', $2)) `
@@ -42,8 +21,8 @@ export function viewGroup (range, view) {
${view}(
date_trunc('hour', timezone('America/Chicago', now())),
date_trunc('hour', timezone('America/Chicago', now())), '1 hour'::INTERVAL, 'hour')
- WHERE "${view}".t >= date_trunc('${unit}', timezone('America/Chicago', $1))
- AND "${view}".t <= date_trunc('${unit}', timezone('America/Chicago', $2)))
+ WHERE "${view}".t >= date_trunc('hour', timezone('America/Chicago', $1))
+ AND "${view}".t <= date_trunc('hour', timezone('America/Chicago', $2)))
) u`
}
diff --git a/api/resolvers/notifications.js b/api/resolvers/notifications.js
index 7cd0975c..a59b353a 100644
--- a/api/resolvers/notifications.js
+++ b/api/resolvers/notifications.js
@@ -284,6 +284,7 @@ export default {
FROM "Earn"
WHERE "userId" = $1
AND created_at < $2
+ AND (type IS NULL OR type NOT IN ('FOREVER_REFERRAL', 'ONE_DAY_REFERRAL'))
GROUP BY "userId", created_at
ORDER BY "sortTime" DESC
LIMIT ${LIMIT})`
@@ -299,6 +300,17 @@ export default {
ORDER BY "sortTime" DESC
LIMIT ${LIMIT})`
)
+ queries.push(
+ `(SELECT min(id)::text, created_at AS "sortTime", FLOOR(sum(msats) / 1000) as "earnedSats",
+ 'ReferralReward' AS type
+ FROM "Earn"
+ WHERE "userId" = $1
+ AND created_at < $2
+ AND type IN ('FOREVER_REFERRAL', 'ONE_DAY_REFERRAL')
+ GROUP BY "userId", created_at
+ ORDER BY "sortTime" DESC
+ LIMIT ${LIMIT})`
+ )
}
if (meFull.noteCowboyHat) {
@@ -487,6 +499,22 @@ export default {
return null
}
},
+ ReferralReward: {
+ sources: async (n, args, { me, models }) => {
+ const [sources] = await models.$queryRawUnsafe(`
+ SELECT
+ COALESCE(FLOOR(sum(msats) FILTER(WHERE type = 'FOREVER_REFERRAL') / 1000), 0) AS forever,
+ COALESCE(FLOOR(sum(msats) FILTER(WHERE type = 'ONE_DAY_REFERRAL') / 1000), 0) AS "oneDay"
+ FROM "Earn"
+ WHERE "userId" = $1 AND created_at = $2
+ `, Number(me.id), new Date(n.sortTime))
+ if (sources.forever + sources.oneDay > 0) {
+ return sources
+ }
+
+ return null
+ }
+ },
Mention: {
mention: async (n, args, { models }) => true,
item: async (n, args, { models, me }) => getItem(n, { id: n.id }, { models, me })
diff --git a/api/resolvers/referrals.js b/api/resolvers/referrals.js
index 5cbec9f8..b59d4a15 100644
--- a/api/resolvers/referrals.js
+++ b/api/resolvers/referrals.js
@@ -1,6 +1,6 @@
import { GraphQLError } from 'graphql'
-import { withClause, intervalClause } from './growth'
import { timeUnitForRange, whenRange } from '@/lib/time'
+import { viewGroup } from './growth'
export default {
Query: {
@@ -11,46 +11,18 @@ export default {
const range = whenRange(when, from, to)
- const [{ totalSats }] = await models.$queryRawUnsafe(`
- SELECT COALESCE(FLOOR(sum(msats) / 1000), 0) as "totalSats"
- FROM "ReferralAct"
- WHERE ${intervalClause(range, 'ReferralAct')}
- AND "ReferralAct"."referrerId" = $3
- `, ...range, Number(me.id))
-
- const [{ totalReferrals }] = await models.$queryRawUnsafe(`
- SELECT count(*)::INTEGER as "totalReferrals"
- FROM users
- WHERE ${intervalClause(range, 'users')}
- AND "referrerId" = $3
- `, ...range, Number(me.id))
-
- const stats = await models.$queryRawUnsafe(
- `${withClause(range)}
- SELECT time, json_build_array(
- json_build_object('name', 'referrals', 'value', count(*) FILTER (WHERE act = 'REFERREE')),
- json_build_object('name', 'sats', 'value', FLOOR(COALESCE(sum(msats) FILTER (WHERE act IN ('BOOST', 'STREAM', 'FEE')), 0)))
+ return await models.$queryRawUnsafe(`
+ SELECT date_trunc('${timeUnitForRange(range)}', t) at time zone 'America/Chicago' as time,
+ json_build_array(
+ json_build_object('name', 'referrals', 'value', COALESCE(SUM(referrals), 0)),
+ json_build_object('name', 'one day referrals', 'value', COALESCE(SUM(one_day_referrals), 0)),
+ json_build_object('name', 'referral sats', 'value', FLOOR(COALESCE(SUM(msats_referrals), 0) / 1000.0)),
+ json_build_object('name', 'one day referral sats', 'value', FLOOR(COALESCE(SUM(msats_one_day_referrals), 0) / 1000.0))
) AS data
- FROM times
- LEFT JOIN
- ((SELECT "ReferralAct".created_at, "ReferralAct".msats / 1000.0 as msats, "ItemAct".act::text as act
- FROM "ReferralAct"
- JOIN "ItemAct" ON "ItemAct".id = "ReferralAct"."itemActId"
- WHERE ${intervalClause(range, 'ReferralAct')}
- AND "ReferralAct"."referrerId" = $3)
- UNION ALL
- (SELECT created_at, 0.0 as sats, 'REFERREE' as act
- FROM users
- WHERE ${intervalClause(range, 'users')}
- AND "referrerId" = $3)) u ON time = date_trunc('${timeUnitForRange(range)}', u.created_at)
- GROUP BY time
- ORDER BY time ASC`, ...range, Number(me.id))
-
- return {
- totalSats,
- totalReferrals,
- stats
- }
+ FROM ${viewGroup(range, 'user_stats')}
+ WHERE id = ${me.id}
+ GROUP BY time
+ ORDER BY time ASC`, ...range)
}
}
}
diff --git a/api/resolvers/user.js b/api/resolvers/user.js
index d5dbecc8..034d9b91 100644
--- a/api/resolvers/user.js
+++ b/api/resolvers/user.js
@@ -579,7 +579,8 @@ export default {
json_build_object('name', 'comments', 'value', COALESCE(SUM(comments), 0)),
json_build_object('name', 'posts', 'value', COALESCE(SUM(posts), 0)),
json_build_object('name', 'territories', 'value', COALESCE(SUM(territories), 0)),
- json_build_object('name', 'referrals', 'value', COALESCE(SUM(referrals), 0))
+ json_build_object('name', 'referrals', 'value', COALESCE(SUM(referrals), 0)),
+ json_build_object('name', 'one day referrals', 'value', COALESCE(SUM(one_day_referrals), 0))
) AS data
FROM ${viewGroup(range, 'user_stats')}
WHERE id = ${me.id}
@@ -594,6 +595,7 @@ export default {
json_build_object('name', 'zaps', 'value', ROUND(COALESCE(SUM(msats_tipped), 0) / 1000)),
json_build_object('name', 'rewards', 'value', ROUND(COALESCE(SUM(msats_rewards), 0) / 1000)),
json_build_object('name', 'referrals', 'value', ROUND( COALESCE(SUM(msats_referrals), 0) / 1000)),
+ json_build_object('name', 'one day referrals', 'value', ROUND( COALESCE(SUM(msats_one_day_referrals), 0) / 1000)),
json_build_object('name', 'territories', 'value', ROUND(COALESCE(SUM(msats_revenue), 0) / 1000))
) AS data
FROM ${viewGroup(range, 'user_stats')}
@@ -607,6 +609,7 @@ export default {
SELECT date_trunc('${timeUnitForRange(range)}', t) at time zone 'America/Chicago' as time,
json_build_array(
json_build_object('name', 'fees', 'value', FLOOR(COALESCE(SUM(msats_fees), 0) / 1000)),
+ json_build_object('name', 'zapping', 'value', FLOOR(COALESCE(SUM(msats_zaps), 0) / 1000)),
json_build_object('name', 'donations', 'value', FLOOR(COALESCE(SUM(msats_donated), 0) / 1000)),
json_build_object('name', 'territories', 'value', FLOOR(COALESCE(SUM(msats_billing), 0) / 1000))
) AS data
diff --git a/api/ssrApollo.js b/api/ssrApollo.js
index c583be8b..83803bc3 100644
--- a/api/ssrApollo.js
+++ b/api/ssrApollo.js
@@ -72,7 +72,16 @@ function oneDayReferral (request, { me }) {
typeId: String(item.id)
})
} else if (referrer.startsWith('profile-')) {
- prismaPromise = models.user.findUnique({ where: { name: referrer.slice(8) } })
+ const name = referrer.slice(8)
+ // exclude all pages that are not user profiles
+ if (['api', 'auth', 'day', 'invites', 'invoices', 'referrals', 'rewards',
+ 'satistics', 'settings', 'stackers', 'wallet', 'withdrawals', '404', '500',
+ 'email', 'live', 'login', 'notifications', 'offline', 'search', 'share',
+ 'signup', 'territory', 'recent', 'top', 'edit', 'post', 'rss', 'saloon',
+ 'faq', 'story', 'privacy', 'copyright', 'tos', 'changes', 'guide', 'daily',
+ 'anon', 'ad'].includes(name)) continue
+
+ prismaPromise = models.user.findUnique({ where: { name } })
getData = user => ({
referrerId: user.id,
refereeId: parseInt(me.id),
diff --git a/api/typeDefs/notifications.js b/api/typeDefs/notifications.js
index 269cc9bd..14b44a7b 100644
--- a/api/typeDefs/notifications.js
+++ b/api/typeDefs/notifications.js
@@ -89,6 +89,19 @@ export default gql`
sources: EarnSources
}
+ type ReferralSources {
+ id: ID!
+ forever: Int!
+ oneDay: Int!
+ }
+
+ type ReferralReward {
+ id: ID!
+ earnedSats: Int!
+ sortTime: Date!
+ sources: ReferralSources
+ }
+
type Revenue {
id: ID!
earnedSats: Int!
@@ -143,6 +156,7 @@ export default gql`
| Invitification | Earn | JobChanged | InvoicePaid | WithdrawlPaid | Referral
| Streak | FollowActivity | ForwardedVotification | Revenue | SubStatus
| TerritoryPost | TerritoryTransfer | Reminder | ItemMention | Invoicification
+ | ReferralReward
type Notifications {
lastChecked: Date
diff --git a/api/typeDefs/referrals.js b/api/typeDefs/referrals.js
index 244d7684..1290aaa9 100644
--- a/api/typeDefs/referrals.js
+++ b/api/typeDefs/referrals.js
@@ -2,12 +2,6 @@ import { gql } from 'graphql-tag'
export default gql`
extend type Query {
- referrals(when: String, from: String, to: String): Referrals!
- }
-
- type Referrals {
- totalSats: Int!
- totalReferrals: Int!
- stats: [TimeData!]!
+ referrals(when: String, from: String, to: String): [TimeData!]!
}
`
diff --git a/components/charts.js b/components/charts.js
index f8deb618..f9b1deae 100644
--- a/components/charts.js
+++ b/components/charts.js
@@ -156,7 +156,7 @@ export function WhenComposedChart ({
data,
lineNames = [], lineAxis = 'left',
areaNames = [], areaAxis = 'left',
- barNames = [], barAxis = 'left'
+ barNames = [], barAxis = 'left', barStackId
}) {
const router = useRouter()
if (!data || data.length === 0) {
@@ -189,7 +189,7 @@ export function WhenComposedChart ({