diff --git a/api/resolvers/wallet.js b/api/resolvers/wallet.js index 8a8cd9de..db796a0d 100644 --- a/api/resolvers/wallet.js +++ b/api/resolvers/wallet.js @@ -49,46 +49,62 @@ export default { connectAddress: async (parent, args, { lnd }) => { return process.env.LND_CONNECT_ADDRESS }, - walletHistory: async (parent, { cursor }, { me, models, lnd }) => { + walletHistory: async (parent, { cursor, inc }, { me, models, lnd }) => { const decodedCursor = decodeCursor(cursor) if (!me) { throw new AuthenticationError('you must be logged in') } + const include = new Set(inc.split(',')) + const queries = [] + + if (include.has('invoice')) { + queries.push( + `(SELECT ('invoice' || id) as id, id as "factId", bolt11, created_at as "createdAt", + COALESCE("msatsReceived", "msatsRequested") as msats, NULL as "msatsFee", + CASE WHEN "confirmedAt" IS NOT NULL THEN 'CONFIRMED' + WHEN "expiresAt" <= $2 THEN 'EXPIRED' + WHEN cancelled THEN 'CANCELLED' + ELSE 'PENDING' END as status, + 'invoice' as type + FROM "Invoice" + WHERE "userId" = $1 + AND created_at <= $2)`) + } + + if (include.has('withdrawal')) { + queries.push( + `(SELECT ('withdrawal' || id) as id, id as "factId", bolt11, created_at as "createdAt", + CASE WHEN status = 'CONFIRMED' THEN "msatsPaid" + ELSE "msatsPaying" END as msats, + CASE WHEN status = 'CONFIRMED' THEN "msatsFeePaid" + ELSE "msatsFeePaying" END as "msatsFee", + COALESCE(status::text, 'PENDING') as status, + 'withdrawal' as type + FROM "Withdrawl" + WHERE "userId" = $1 + AND created_at <= $2)`) + } + // TODO // 1. union invoices and withdrawals (check) // 2. add to union spending and receiving + if (queries.length === 0) { + return { + cursor: null, + facts: [] + } + } + let history = await models.$queryRaw(` - (SELECT id, bolt11, created_at as "createdAt", - COALESCE("msatsReceived", "msatsRequested") as msats, NULL as "msatsFee", - CASE WHEN "confirmedAt" IS NOT NULL THEN 'CONFIRMED' - WHEN "expiresAt" <= $2 THEN 'EXPIRED' - WHEN cancelled THEN 'CANCELLED' - ELSE 'PENDING' END as status, - 'invoice' as type - FROM "Invoice" - WHERE "userId" = $1 - AND created_at <= $2 - ORDER BY created_at desc - LIMIT ${LIMIT}+$3) - UNION ALL - (SELECT id, bolt11, created_at as "createdAt", - CASE WHEN status = 'CONFIRMED' THEN "msatsPaid" - ELSE "msatsPaying" END as msats, - CASE WHEN status = 'CONFIRMED' THEN "msatsFeePaid" - ELSE "msatsFeePaying" END as "msatsFee", - COALESCE(status::text, 'PENDING') as status, - 'withdrawal' as type - FROM "Withdrawl" - WHERE "userId" = $1 - AND created_at <= $2 - ORDER BY created_at desc - LIMIT ${LIMIT}+$3) + ${queries.join(' UNION ALL ')} ORDER BY "createdAt" DESC OFFSET $3 LIMIT ${LIMIT}`, me.id, decodedCursor.time, decodedCursor.offset) + console.log(history) + history = history.map(f => { if (f.bolt11) { const inv = lnpr.decode(f.bolt11) @@ -113,6 +129,8 @@ export default { return f }) + console.log(history) + return { cursor: history.length === LIMIT ? nextCursorEncoded(decodedCursor) : null, facts: history diff --git a/api/ssrApollo.js b/api/ssrApollo.js index 07177eff..6817bd7a 100644 --- a/api/ssrApollo.js +++ b/api/ssrApollo.js @@ -30,7 +30,7 @@ export default async function getSSRApolloClient (req, me = null) { } export function getGetServerSideProps (query, variables = null, foundField) { - return async function ({ req, params }) { + return async function ({ req, query: params }) { const client = await getSSRApolloClient(req) const { error, data } = await client.query({ query, diff --git a/api/typeDefs/wallet.js b/api/typeDefs/wallet.js index ae444ab6..b623636f 100644 --- a/api/typeDefs/wallet.js +++ b/api/typeDefs/wallet.js @@ -5,7 +5,7 @@ export default gql` invoice(id: ID!): Invoice! withdrawl(id: ID!): Withdrawl! connectAddress: String! - walletHistory(cursor: String): History + walletHistory(cursor: String, inc: String): History } extend type Mutation { @@ -41,6 +41,7 @@ export default gql` type Fact { id: ID! + factId: ID! bolt11: String createdAt: String! msats: Int! diff --git a/components/form.js b/components/form.js index 9c13c658..905d15f5 100644 --- a/components/form.js +++ b/components/form.js @@ -175,33 +175,31 @@ export function Input ({ label, groupClassName, ...props }) { ) } -export function Checkbox ({ children, label, extra, handleChange, ...props }) { +export function Checkbox ({ children, label, extra, handleChange, inline, ...props }) { // React treats radios and checkbox inputs differently other input types, select, and textarea. // Formik does this too! When you specify `type` to useField(), it will // return the correct bag of props for you - const [field, { value }] = useField({ ...props, type: 'checkbox' }) + const [field] = useField({ ...props, type: 'checkbox' }) return ( -
- - { - field.onChange(e) - handleChange && handleChange(e.target.checked) - }} - /> - -
{label}
- {extra && -
- {extra} -
} -
-
- {children} -
+ + { + field.onChange(e) + handleChange && handleChange(e.target.checked) + }} + /> + +
{label}
+ {extra && +
+ {extra} +
} +
+
) } diff --git a/components/user-header.js b/components/user-header.js index 84e08104..6a804350 100644 --- a/components/user-header.js +++ b/components/user-header.js @@ -113,7 +113,7 @@ export default function UserHeader ({ user }) { diff --git a/fragments/wallet.js b/fragments/wallet.js index 4ccfd425..ea6632ac 100644 --- a/fragments/wallet.js +++ b/fragments/wallet.js @@ -25,10 +25,11 @@ export const WITHDRAWL = gql` }` export const WALLET_HISTORY = gql` - query WalletHistory($cursor: String) { - walletHistory(cursor: $cursor) { + query WalletHistory($cursor: String, $inc: String) { + walletHistory(cursor: $cursor, inc: $inc) { facts { id + factId type createdAt msats diff --git a/lib/apollo.js b/lib/apollo.js index c2ac272d..0447dfea 100644 --- a/lib/apollo.js +++ b/lib/apollo.js @@ -66,7 +66,7 @@ export default function getApolloClient () { } }, walletHistory: { - keyArgs: false, + keyArgs: ['inc'], merge (existing, incoming) { if (isFirstPage(incoming.cursor, existing?.facts)) { return incoming diff --git a/pages/satistics.js b/pages/satistics.js index 9c59afdb..44083a49 100644 --- a/pages/satistics.js +++ b/pages/satistics.js @@ -12,6 +12,8 @@ import styles from '../styles/satistics.module.css' import Moon from '../svgs/moon-fill.svg' import Check from '../svgs/check-double-line.svg' import ThumbDown from '../svgs/thumb-down-fill.svg' +import { Checkbox, Form } from '../components/form' +import { useRouter } from 'next/router' export const getServerSideProps = getGetServerSideProps(WALLET_HISTORY) @@ -83,7 +85,29 @@ function Satus ({ status }) { export default function Satistics ({ data: { walletHistory: { facts, cursor } } }) { const me = useMe() const { value: darkMode } = useDarkMode() - const { data, fetchMore } = useQuery(WALLET_HISTORY) + const router = useRouter() + const { data, fetchMore } = useQuery(WALLET_HISTORY, { variables: { inc: router.query.inc } }) + + console.log(router.query.inc, data) + + function filterRoutePush (filter, add) { + const inc = new Set(router.query.inc.split(',')) + inc.delete('') + // depending on addrem, add or remove filter + if (add) { + inc.add(filter) + } else { + inc.delete(filter) + } + + const incstr = [...inc].join(',') + router.push(`/satistics?inc=${incstr}`) + } + + function included (filter) { + const inc = new Set(router.query.inc.split(',')) + return inc.has(filter) + } if (data) { ({ walletHistory: { facts, cursor } } = data) @@ -97,32 +121,61 @@ export default function Satistics ({ data: { walletHistory: { facts, cursor } } return ( - - - - - - - - - - {facts.map((f, i) => ( - - - - - - - - ))} - -
typedetailsats
{f.type} -
- {f.description || 'no description'} -
- -
{f.msats / 1000}
- +
+
+
+ filterRoutePush('invoice', c)} + /> + filterRoutePush('withdrawal', c)} + /> + filterRoutePush('stacked', c)} + /> + filterRoutePush('spent', c)} + /> +
+
+ + + + + + + + + + {facts.map((f, i) => ( + + + + + + + + ))} + +
typedetailsats
{f.type} +
+ {f.description || 'no description'} +
+ +
{f.msats / 1000}
+ +
) } diff --git a/styles/globals.scss b/styles/globals.scss index 89b9eeba..2a2457f9 100644 --- a/styles/globals.scss +++ b/styles/globals.scss @@ -64,6 +64,10 @@ $tooltip-bg: #5c8001; line-height: 1.2rem; } +.custom-checkbox.custom-control-inline { + margin-right: .5rem; +} + .table { color: var(--theme-color); background-color: var(--theme-body);