update packages and reduce bundle size
This commit is contained in:
parent
356f7e072c
commit
e87610c45b
@ -1,6 +1,6 @@
|
|||||||
import { ApolloClient, InMemoryCache } from '@apollo/client'
|
import { ApolloClient, InMemoryCache } from '@apollo/client'
|
||||||
import { SchemaLink } from '@apollo/client/link/schema'
|
import { SchemaLink } from '@apollo/client/link/schema'
|
||||||
import { makeExecutableSchema } from 'graphql-tools'
|
import { makeExecutableSchema } from '@graphql-tools/schema'
|
||||||
import { getSession } from 'next-auth/client'
|
import { getSession } from 'next-auth/client'
|
||||||
import resolvers from './resolvers'
|
import resolvers from './resolvers'
|
||||||
import typeDefs from './typeDefs'
|
import typeDefs from './typeDefs'
|
||||||
|
@ -9,6 +9,9 @@ import { Bar } from 'recharts/lib/cartesian/Bar'
|
|||||||
import { Tooltip } from 'recharts/lib/component/Tooltip'
|
import { Tooltip } from 'recharts/lib/component/Tooltip'
|
||||||
import { Legend } from 'recharts/lib/component/Legend'
|
import { Legend } from 'recharts/lib/component/Legend'
|
||||||
import { ResponsiveContainer } from 'recharts/lib/component/ResponsiveContainer'
|
import { ResponsiveContainer } from 'recharts/lib/component/ResponsiveContainer'
|
||||||
|
import { PieChart } from 'recharts/lib/chart/PieChart'
|
||||||
|
import { Cell } from 'recharts/lib/component/Cell'
|
||||||
|
import { Pie } from 'recharts/lib/polar/Pie'
|
||||||
import { abbrNum } from '../lib/format'
|
import { abbrNum } from '../lib/format'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
@ -169,3 +172,29 @@ export function WhenComposedChart ({ data, lineNames, areaNames, barNames }) {
|
|||||||
</ResponsiveContainer>
|
</ResponsiveContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function GrowthPieChart ({ data }) {
|
||||||
|
return (
|
||||||
|
<ResponsiveContainer width='100%' height={250} minWidth={200}>
|
||||||
|
<PieChart margin={{ top: 5, right: 5, bottom: 5, left: 5 }}>
|
||||||
|
<Pie
|
||||||
|
dataKey='value'
|
||||||
|
isAnimationActive={false}
|
||||||
|
data={data}
|
||||||
|
cx='50%'
|
||||||
|
cy='50%'
|
||||||
|
outerRadius={80}
|
||||||
|
fill='var(--bs-secondary)'
|
||||||
|
label
|
||||||
|
>
|
||||||
|
{
|
||||||
|
data.map((entry, index) => (
|
||||||
|
<Cell key={`cell-${index}`} fill={COLORS[index]} />
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</Pie>
|
||||||
|
<Tooltip />
|
||||||
|
</PieChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
)
|
||||||
|
}
|
@ -46,9 +46,11 @@ export default function FeeButton ({ parentId, hasImgLink, baseFee, ChildButton,
|
|||||||
const { data } = useQuery(query, { pollInterval: 1000, nextFetchPolicy: 'cache-and-network' })
|
const { data } = useQuery(query, { pollInterval: 1000, nextFetchPolicy: 'cache-and-network' })
|
||||||
const repetition = data?.itemRepetition || 0
|
const repetition = data?.itemRepetition || 0
|
||||||
const formik = useFormikContext()
|
const formik = useFormikContext()
|
||||||
const boost = formik?.values?.boost || 0
|
const boost = Number(formik?.values?.boost) || 0
|
||||||
const cost = baseFee * (hasImgLink ? 10 : 1) * Math.pow(10, repetition) + Number(boost)
|
const cost = baseFee * (hasImgLink ? 10 : 1) * Math.pow(10, repetition) + Number(boost)
|
||||||
|
|
||||||
|
console.log('cost', cost, 'baseFee', baseFee, repetition, hasImgLink, boost)
|
||||||
|
|
||||||
const show = alwaysShow || !formik?.isSubmitting
|
const show = alwaysShow || !formik?.isSubmitting
|
||||||
return (
|
return (
|
||||||
<div className='d-flex align-items-center'>
|
<div className='d-flex align-items-center'>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import * as Yup from 'yup'
|
import { string } from 'yup'
|
||||||
import Toc from './table-of-contents'
|
import Toc from './table-of-contents'
|
||||||
import Badge from 'react-bootstrap/Badge'
|
import Badge from 'react-bootstrap/Badge'
|
||||||
import Button from 'react-bootstrap/Button'
|
import Button from 'react-bootstrap/Button'
|
||||||
@ -12,7 +12,7 @@ import Share from './share'
|
|||||||
import CowboyHat from './cowboy-hat'
|
import CowboyHat from './cowboy-hat'
|
||||||
|
|
||||||
export default function ItemJob ({ item, toc, rank, children }) {
|
export default function ItemJob ({ item, toc, rank, children }) {
|
||||||
const isEmail = Yup.string().email().isValidSync(item.url)
|
const isEmail = string().email().isValidSync(item.url)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
106
lib/validate.js
106
lib/validate.js
@ -1,4 +1,4 @@
|
|||||||
import * as Yup from 'yup'
|
import { string, ValidationError, number, object, array, addMethod } from 'yup'
|
||||||
import { BOOST_MIN, MAX_POLL_CHOICE_LENGTH, MAX_TITLE_LENGTH, MAX_POLL_NUM_CHOICES, MIN_POLL_NUM_CHOICES, SUBS_NO_JOBS } from './constants'
|
import { BOOST_MIN, MAX_POLL_CHOICE_LENGTH, MAX_TITLE_LENGTH, MAX_POLL_NUM_CHOICES, MIN_POLL_NUM_CHOICES, SUBS_NO_JOBS } from './constants'
|
||||||
import { NAME_QUERY } from '../fragments/users'
|
import { NAME_QUERY } from '../fragments/users'
|
||||||
import { URL_REGEXP, WS_REGEXP } from './url'
|
import { URL_REGEXP, WS_REGEXP } from './url'
|
||||||
@ -13,14 +13,14 @@ export async function ssValidate (schema, data, ...args) {
|
|||||||
await schema.validate(data)
|
await schema.validate(data)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Yup.ValidationError) {
|
if (e instanceof ValidationError) {
|
||||||
throw new Error(`${e.path}: ${e.message}`)
|
throw new Error(`${e.path}: ${e.message}`)
|
||||||
}
|
}
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Yup.addMethod(Yup.string, 'or', function (schemas, msg) {
|
addMethod(string, 'or', function (schemas, msg) {
|
||||||
return this.test({
|
return this.test({
|
||||||
name: 'or',
|
name: 'or',
|
||||||
message: msg,
|
message: msg,
|
||||||
@ -36,12 +36,12 @@ Yup.addMethod(Yup.string, 'or', function (schemas, msg) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const titleValidator = Yup.string().required('required').trim().max(
|
const titleValidator = string().required('required').trim().max(
|
||||||
MAX_TITLE_LENGTH,
|
MAX_TITLE_LENGTH,
|
||||||
({ max, value }) => `${Math.abs(max - value.length)} too many`
|
({ max, value }) => `${Math.abs(max - value.length)} too many`
|
||||||
)
|
)
|
||||||
|
|
||||||
const intValidator = Yup.number().typeError('must be a number').integer('must be whole')
|
const intValidator = number().typeError('must be a number').integer('must be whole')
|
||||||
|
|
||||||
async function usernameExists (client, name) {
|
async function usernameExists (client, name) {
|
||||||
if (!client) {
|
if (!client) {
|
||||||
@ -70,7 +70,7 @@ export function advPostSchemaMembers (client) {
|
|||||||
},
|
},
|
||||||
message: `must be divisble be ${BOOST_MIN}`
|
message: `must be divisble be ${BOOST_MIN}`
|
||||||
}),
|
}),
|
||||||
forward: Yup.string()
|
forward: string()
|
||||||
.test({
|
.test({
|
||||||
name: 'name',
|
name: 'name',
|
||||||
test: async name => {
|
test: async name => {
|
||||||
@ -84,12 +84,12 @@ export function advPostSchemaMembers (client) {
|
|||||||
|
|
||||||
export function subSelectSchemaMembers (client) {
|
export function subSelectSchemaMembers (client) {
|
||||||
return {
|
return {
|
||||||
sub: Yup.string().required('required').oneOf(SUBS_NO_JOBS, 'required')
|
sub: string().required('required').oneOf(SUBS_NO_JOBS, 'required')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bountySchema (client) {
|
export function bountySchema (client) {
|
||||||
return Yup.object({
|
return object({
|
||||||
title: titleValidator,
|
title: titleValidator,
|
||||||
bounty: intValidator
|
bounty: intValidator
|
||||||
.min(1000, 'must be at least 1000')
|
.min(1000, 'must be at least 1000')
|
||||||
@ -100,7 +100,7 @@ export function bountySchema (client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function discussionSchema (client) {
|
export function discussionSchema (client) {
|
||||||
return Yup.object({
|
return object({
|
||||||
title: titleValidator,
|
title: titleValidator,
|
||||||
...advPostSchemaMembers(client),
|
...advPostSchemaMembers(client),
|
||||||
...subSelectSchemaMembers()
|
...subSelectSchemaMembers()
|
||||||
@ -108,19 +108,19 @@ export function discussionSchema (client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function linkSchema (client) {
|
export function linkSchema (client) {
|
||||||
return Yup.object({
|
return object({
|
||||||
title: titleValidator,
|
title: titleValidator,
|
||||||
url: Yup.string().matches(URL_REGEXP, 'invalid url').required('required'),
|
url: string().matches(URL_REGEXP, 'invalid url').required('required'),
|
||||||
...advPostSchemaMembers(client),
|
...advPostSchemaMembers(client),
|
||||||
...subSelectSchemaMembers()
|
...subSelectSchemaMembers()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pollSchema (client, numExistingChoices = 0) {
|
export function pollSchema (client, numExistingChoices = 0) {
|
||||||
return Yup.object({
|
return object({
|
||||||
title: titleValidator,
|
title: titleValidator,
|
||||||
options: Yup.array().of(
|
options: array().of(
|
||||||
Yup.string().trim().test('my-test', 'required', function (value) {
|
string().trim().test('my-test', 'required', function (value) {
|
||||||
return (this.path !== 'options[0]' && this.path !== 'options[1]') || value
|
return (this.path !== 'options[0]' && this.path !== 'options[1]') || value
|
||||||
}).max(MAX_POLL_CHOICE_LENGTH,
|
}).max(MAX_POLL_CHOICE_LENGTH,
|
||||||
({ max, value }) => `${Math.abs(max - value.length)} too many characters`
|
({ max, value }) => `${Math.abs(max - value.length)} too many characters`
|
||||||
@ -138,8 +138,8 @@ export function pollSchema (client, numExistingChoices = 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function userSchema (client) {
|
export function userSchema (client) {
|
||||||
return Yup.object({
|
return object({
|
||||||
name: Yup.string()
|
name: string()
|
||||||
.required('required')
|
.required('required')
|
||||||
.matches(/^[\w_]+$/, 'only letters, numbers, and _')
|
.matches(/^[\w_]+$/, 'only letters, numbers, and _')
|
||||||
.max(32, 'too long')
|
.max(32, 'too long')
|
||||||
@ -154,85 +154,85 @@ export function userSchema (client) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const commentSchema = Yup.object({
|
export const commentSchema = object({
|
||||||
text: Yup.string().required('required').trim()
|
text: string().required('required').trim()
|
||||||
})
|
})
|
||||||
|
|
||||||
export const jobSchema = Yup.object({
|
export const jobSchema = object({
|
||||||
title: titleValidator,
|
title: titleValidator,
|
||||||
company: Yup.string().required('required').trim(),
|
company: string().required('required').trim(),
|
||||||
text: Yup.string().required('required').trim(),
|
text: string().required('required').trim(),
|
||||||
url: Yup.string()
|
url: string()
|
||||||
.or([Yup.string().email(), Yup.string().url()], 'invalid url or email')
|
.or([string().email(), string().url()], 'invalid url or email')
|
||||||
.required('required'),
|
.required('required'),
|
||||||
maxBid: intValidator.min(0, 'must be at least 0').required('required'),
|
maxBid: intValidator.min(0, 'must be at least 0').required('required'),
|
||||||
location: Yup.string().test(
|
location: string().test(
|
||||||
'no-remote',
|
'no-remote',
|
||||||
"don't write remote, just check the box",
|
"don't write remote, just check the box",
|
||||||
v => !v?.match(/\bremote\b/gi))
|
v => !v?.match(/\bremote\b/gi))
|
||||||
.when('remote', {
|
.when('remote', {
|
||||||
is: (value) => !value,
|
is: (value) => !value,
|
||||||
then: Yup.string().required('required').trim()
|
then: string().required('required').trim()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
export const emailSchema = Yup.object({
|
export const emailSchema = object({
|
||||||
email: Yup.string().email('email is no good').required('required')
|
email: string().email('email is no good').required('required')
|
||||||
})
|
})
|
||||||
|
|
||||||
export const urlSchema = Yup.object({
|
export const urlSchema = object({
|
||||||
url: Yup.string().matches(URL_REGEXP, 'invalid url').required('required')
|
url: string().matches(URL_REGEXP, 'invalid url').required('required')
|
||||||
})
|
})
|
||||||
|
|
||||||
export const namedUrlSchema = Yup.object({
|
export const namedUrlSchema = object({
|
||||||
text: Yup.string().required('required').trim(),
|
text: string().required('required').trim(),
|
||||||
url: Yup.string().matches(URL_REGEXP, 'invalid url').required('required')
|
url: string().matches(URL_REGEXP, 'invalid url').required('required')
|
||||||
})
|
})
|
||||||
|
|
||||||
export const amountSchema = Yup.object({
|
export const amountSchema = object({
|
||||||
amount: intValidator.required('required').positive('must be positive')
|
amount: intValidator.required('required').positive('must be positive')
|
||||||
})
|
})
|
||||||
|
|
||||||
export const settingsSchema = Yup.object({
|
export const settingsSchema = object({
|
||||||
tipDefault: intValidator.required('required').positive('must be positive'),
|
tipDefault: intValidator.required('required').positive('must be positive'),
|
||||||
fiatCurrency: Yup.string().required('required').oneOf(SUPPORTED_CURRENCIES),
|
fiatCurrency: string().required('required').oneOf(SUPPORTED_CURRENCIES),
|
||||||
nostrPubkey: Yup.string().nullable()
|
nostrPubkey: string().nullable()
|
||||||
.or([
|
.or([
|
||||||
Yup.string().nullable().matches(NOSTR_PUBKEY_HEX, 'must be 64 hex chars'),
|
string().nullable().matches(NOSTR_PUBKEY_HEX, 'must be 64 hex chars'),
|
||||||
Yup.string().nullable().matches(NOSTR_PUBKEY_BECH32, 'invalid bech32 encoding')], 'invalid pubkey'),
|
string().nullable().matches(NOSTR_PUBKEY_BECH32, 'invalid bech32 encoding')], 'invalid pubkey'),
|
||||||
nostrRelays: Yup.array().of(
|
nostrRelays: array().of(
|
||||||
Yup.string().matches(WS_REGEXP, 'invalid web socket address')
|
string().matches(WS_REGEXP, 'invalid web socket address')
|
||||||
).max(NOSTR_MAX_RELAY_NUM,
|
).max(NOSTR_MAX_RELAY_NUM,
|
||||||
({ max, value }) => `${Math.abs(max - value.length)} too many`)
|
({ max, value }) => `${Math.abs(max - value.length)} too many`)
|
||||||
})
|
})
|
||||||
|
|
||||||
const warningMessage = 'If I logout, even accidentally, I will never be able to access my account again'
|
const warningMessage = 'If I logout, even accidentally, I will never be able to access my account again'
|
||||||
export const lastAuthRemovalSchema = Yup.object({
|
export const lastAuthRemovalSchema = object({
|
||||||
warning: Yup.string().matches(warningMessage, 'does not match').required('required')
|
warning: string().matches(warningMessage, 'does not match').required('required')
|
||||||
})
|
})
|
||||||
|
|
||||||
export const withdrawlSchema = Yup.object({
|
export const withdrawlSchema = object({
|
||||||
invoice: Yup.string().required('required').trim(),
|
invoice: string().required('required').trim(),
|
||||||
maxFee: intValidator.required('required').min(0, 'must be at least 0')
|
maxFee: intValidator.required('required').min(0, 'must be at least 0')
|
||||||
})
|
})
|
||||||
|
|
||||||
export const lnAddrSchema = Yup.object({
|
export const lnAddrSchema = object({
|
||||||
addr: Yup.string().email('address is no good').required('required'),
|
addr: string().email('address is no good').required('required'),
|
||||||
amount: intValidator.required('required').positive('must be positive'),
|
amount: intValidator.required('required').positive('must be positive'),
|
||||||
maxFee: intValidator.required('required').min(0, 'must be at least 0')
|
maxFee: intValidator.required('required').min(0, 'must be at least 0')
|
||||||
})
|
})
|
||||||
|
|
||||||
export const bioSchema = Yup.object({
|
export const bioSchema = object({
|
||||||
bio: Yup.string().required('required').trim()
|
bio: string().required('required').trim()
|
||||||
})
|
})
|
||||||
|
|
||||||
export const inviteSchema = Yup.object({
|
export const inviteSchema = object({
|
||||||
gift: intValidator.positive('must be greater than 0').required('required'),
|
gift: intValidator.positive('must be greater than 0').required('required'),
|
||||||
limit: intValidator.positive('must be positive')
|
limit: intValidator.positive('must be positive')
|
||||||
})
|
})
|
||||||
|
|
||||||
export const pushSubscriptionSchema = Yup.object({
|
export const pushSubscriptionSchema = object({
|
||||||
endpoint: Yup.string().url().required('required').trim(),
|
endpoint: string().url().required('required').trim(),
|
||||||
p256dh: Yup.string().required('required').trim(),
|
p256dh: string().required('required').trim(),
|
||||||
auth: Yup.string().required('required').trim()
|
auth: string().required('required').trim()
|
||||||
})
|
})
|
||||||
|
4333
package-lock.json
generated
4333
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
60
package.json
60
package.json
@ -10,79 +10,75 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/client": "^3.7.17",
|
"@apollo/client": "^3.7.17",
|
||||||
"@apollo/server": "^4.7.5",
|
"@apollo/server": "^4.8.1",
|
||||||
"@as-integrations/next": "^2.0.1",
|
"@as-integrations/next": "^2.0.1",
|
||||||
|
"@graphql-tools/schema": "^10.0.0",
|
||||||
"@noble/secp256k1": "^1.7.1",
|
"@noble/secp256k1": "^1.7.1",
|
||||||
"@opensearch-project/opensearch": "^1.1.0",
|
"@opensearch-project/opensearch": "^2.3.1",
|
||||||
"@prisma/client": "^2.30.3",
|
"@prisma/client": "^2.30.3",
|
||||||
"@synonymdev/slashtags-auth": "^1.0.0-alpha.5",
|
"@synonymdev/slashtags-auth": "^1.0.0-alpha.5",
|
||||||
"@synonymdev/slashtags-sdk": "^1.0.0-alpha.36",
|
"@synonymdev/slashtags-sdk": "^1.0.0-alpha.36",
|
||||||
"acorn": "^8.10.0",
|
"acorn": "^8.10.0",
|
||||||
"ajv": "^8.12.0",
|
"ajv": "^8.12.0",
|
||||||
"async-retry": "^1.3.1",
|
"async-retry": "^1.3.1",
|
||||||
"aws-sdk": "^2.1248.0",
|
"aws-sdk": "^2.1421.0",
|
||||||
"babel-plugin-inline-react-svg": "^2.0.1",
|
"babel-plugin-inline-react-svg": "^2.0.2",
|
||||||
"bech32": "^2.0.0",
|
"bech32": "^2.0.0",
|
||||||
"bolt11": "^1.4.0",
|
"bolt11": "^1.4.1",
|
||||||
"bootstrap": "^5.3.0",
|
"bootstrap": "^5.3.0",
|
||||||
"browserslist": "^4.21.4",
|
"browserslist": "^4.21.4",
|
||||||
"canonical-json": "0.0.4",
|
"canonical-json": "0.0.4",
|
||||||
"clipboard-copy": "^4.0.1",
|
"clipboard-copy": "^4.0.1",
|
||||||
"cross-fetch": "^3.1.5",
|
"cross-fetch": "^3.1.8",
|
||||||
"domino": "^2.1.6",
|
"domino": "^2.1.6",
|
||||||
"eslint-config-next": "^13.4.10",
|
"eslint-config-next": "^13.4.12",
|
||||||
"formik": "^2.2.6",
|
"formik": "^2.4.2",
|
||||||
"github-slugger": "^1.5.0",
|
"github-slugger": "^1.5.0",
|
||||||
"graphql": "^16.7.1",
|
"graphql": "^16.7.1",
|
||||||
"graphql-tag": "^2.12.6",
|
"graphql-tag": "^2.12.6",
|
||||||
"graphql-tools": "^8.3.10",
|
|
||||||
"graphql-type-json": "^0.3.2",
|
"graphql-type-json": "^0.3.2",
|
||||||
"jquery": "^3.6.1",
|
"ln-service": "^56.9.0",
|
||||||
"ln-service": "^54.2.6",
|
"mathjs": "^11.9.1",
|
||||||
"mathjs": "^11.8.2",
|
|
||||||
"mdast-util-find-and-replace": "^1.1.1",
|
"mdast-util-find-and-replace": "^1.1.1",
|
||||||
"mdast-util-from-markdown": "^1.2.0",
|
"mdast-util-from-markdown": "^1.3.1",
|
||||||
"mdast-util-to-string": "^3.1.0",
|
"mdast-util-to-string": "^3.2.0",
|
||||||
"next": "^13.4.10",
|
"next": "^13.4.12",
|
||||||
"next-auth": "^3.29.10",
|
"next-auth": "^3.29.10",
|
||||||
"next-plausible": "^3.10.1",
|
"next-plausible": "^3.10.1",
|
||||||
"next-seo": "^4.29.0",
|
"next-seo": "^4.29.0",
|
||||||
"nextjs-progressbar": "0.0.16",
|
"nextjs-progressbar": "0.0.16",
|
||||||
"node-s3-url-encode": "^0.0.4",
|
"node-s3-url-encode": "^0.0.4",
|
||||||
"nostr": "^0.2.7",
|
"nostr": "^0.2.8",
|
||||||
"opentimestamps": "^0.4.9",
|
"opentimestamps": "^0.4.9",
|
||||||
"page-metadata-parser": "^1.1.4",
|
"page-metadata-parser": "^1.1.4",
|
||||||
"pageres": "^7.1.0",
|
"pageres": "^7.1.0",
|
||||||
"pg-boss": "^7.4.0",
|
"pg-boss": "^9.0.3",
|
||||||
"popper.js": "^1.16.1",
|
|
||||||
"prisma": "^2.30.3",
|
"prisma": "^2.30.3",
|
||||||
"qrcode.react": "^3.1.0",
|
"qrcode.react": "^3.1.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-avatar-editor": "^13.0.0",
|
"react-avatar-editor": "^13.0.0",
|
||||||
"react-bootstrap": "^2.8.0",
|
"react-bootstrap": "^2.8.0",
|
||||||
"react-countdown": "^2.3.3",
|
"react-countdown": "^2.3.5",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-longpressable": "^1.1.1",
|
"react-longpressable": "^1.1.1",
|
||||||
"react-markdown": "^8.0.7",
|
"react-markdown": "^8.0.7",
|
||||||
"react-string-replace": "^0.4.4",
|
"react-string-replace": "^0.4.4",
|
||||||
"react-syntax-highlighter": "^15.5.0",
|
"react-syntax-highlighter": "^15.5.0",
|
||||||
"react-textarea-autosize": "^8.3.4",
|
"react-textarea-autosize": "^8.5.2",
|
||||||
"react-twitter-embed": "^4.0.4",
|
"react-twitter-embed": "^4.0.4",
|
||||||
"react-youtube": "^7.14.0",
|
"react-youtube": "^7.14.0",
|
||||||
"recharts": "^2.1.16",
|
"recharts": "^2.7.2",
|
||||||
"remark-directive": "^2.0.1",
|
"remark-directive": "^2.0.1",
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
"remove-markdown": "^0.3.0",
|
"remove-markdown": "^0.3.0",
|
||||||
"sass": "^1.56.0",
|
"sass": "^1.64.1",
|
||||||
"secp256k1": "^4.0.3",
|
"secp256k1": "^4.0.3",
|
||||||
"swr": "^1.3.0",
|
"tldts": "^5.7.112",
|
||||||
"tldts": "^5.7.104",
|
|
||||||
"typescript": "^5.1.6",
|
"typescript": "^5.1.6",
|
||||||
"unist-util-visit": "^4.1.1",
|
"unist-util-visit": "^4.1.2",
|
||||||
"url-unshort": "^6.1.0",
|
"url-unshort": "^6.1.0",
|
||||||
"uuid": "^8.3.2",
|
|
||||||
"web-push": "^3.6.2",
|
"web-push": "^3.6.2",
|
||||||
"webln": "^0.2.2",
|
"webln": "^0.3.2",
|
||||||
"webpack": "^5.88.2",
|
"webpack": "^5.88.2",
|
||||||
"workbox-precaching": "^7.0.0",
|
"workbox-precaching": "^7.0.0",
|
||||||
"workbox-recipes": "^7.0.0",
|
"workbox-recipes": "^7.0.0",
|
||||||
@ -90,7 +86,7 @@
|
|||||||
"workbox-strategies": "^7.0.0",
|
"workbox-strategies": "^7.0.0",
|
||||||
"workbox-webpack-plugin": "^7.0.0",
|
"workbox-webpack-plugin": "^7.0.0",
|
||||||
"workbox-window": "^7.0.0",
|
"workbox-window": "^7.0.0",
|
||||||
"yup": "^0.32.11"
|
"yup": "^1.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.16.0"
|
"node": "16.16.0"
|
||||||
@ -108,10 +104,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.2",
|
"@babel/core": "^7.22.9",
|
||||||
"@babel/eslint-parser": "^7.19.1",
|
"@babel/eslint-parser": "^7.22.9",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^8.45.0",
|
||||||
"eslint-plugin-compat": "^4.1.4",
|
"eslint-plugin-compat": "^4.1.4",
|
||||||
"standard": "^16.0.4"
|
"standard": "^17.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,14 @@ import { getGetServerSideProps } from '../../api/ssrApollo'
|
|||||||
import { CopyInput, Form, Select } from '../../components/form'
|
import { CopyInput, Form, Select } from '../../components/form'
|
||||||
import { CenterLayout } from '../../components/layout'
|
import { CenterLayout } from '../../components/layout'
|
||||||
import { useMe } from '../../components/me'
|
import { useMe } from '../../components/me'
|
||||||
import { WhenComposedChart } from '../../components/when-charts'
|
|
||||||
import { useQuery } from '@apollo/client'
|
import { useQuery } from '@apollo/client'
|
||||||
import PageLoading from '../../components/page-loading'
|
import PageLoading from '../../components/page-loading'
|
||||||
import { WHENS } from '../../lib/constants'
|
import { WHENS } from '../../lib/constants'
|
||||||
|
import dynamic from 'next/dynamic'
|
||||||
|
|
||||||
|
const WhenComposedChart = dynamic(() => import('../../components/charts').then(mod => mod.WhenComposedChart), {
|
||||||
|
loading: () => <div>Loading...</div>
|
||||||
|
})
|
||||||
|
|
||||||
const REFERRALS = gql`
|
const REFERRALS = gql`
|
||||||
query Referrals($when: String!)
|
query Referrals($when: String!)
|
||||||
|
@ -17,6 +17,11 @@ import Countdown from 'react-countdown'
|
|||||||
import { abbrNum } from '../lib/format'
|
import { abbrNum } from '../lib/format'
|
||||||
import PageLoading from '../components/page-loading'
|
import PageLoading from '../components/page-loading'
|
||||||
import { useShowModal } from '../components/modal'
|
import { useShowModal } from '../components/modal'
|
||||||
|
import dynamic from 'next/dynamic'
|
||||||
|
|
||||||
|
const GrowthPieChart = dynamic(() => import('../components/charts').then(mod => mod.GrowthPieChart), {
|
||||||
|
loading: () => <div>Loading...</div>
|
||||||
|
})
|
||||||
|
|
||||||
const REWARDS = gql`
|
const REWARDS = gql`
|
||||||
{
|
{
|
||||||
@ -97,32 +102,6 @@ const COLORS = [
|
|||||||
'var(--bs-grey)'
|
'var(--bs-grey)'
|
||||||
]
|
]
|
||||||
|
|
||||||
function GrowthPieChart ({ data }) {
|
|
||||||
return (
|
|
||||||
<ResponsiveContainer width='100%' height={250} minWidth={200}>
|
|
||||||
<PieChart margin={{ top: 5, right: 5, bottom: 5, left: 5 }}>
|
|
||||||
<Pie
|
|
||||||
dataKey='value'
|
|
||||||
isAnimationActive={false}
|
|
||||||
data={data}
|
|
||||||
cx='50%'
|
|
||||||
cy='50%'
|
|
||||||
outerRadius={80}
|
|
||||||
fill='var(--bs-secondary)'
|
|
||||||
label
|
|
||||||
>
|
|
||||||
{
|
|
||||||
data.map((entry, index) => (
|
|
||||||
<Cell key={`cell-${index}`} fill={COLORS[index]} />
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</Pie>
|
|
||||||
<Tooltip />
|
|
||||||
</PieChart>
|
|
||||||
</ResponsiveContainer>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function DonateButton () {
|
export function DonateButton () {
|
||||||
const showModal = useShowModal()
|
const showModal = useShowModal()
|
||||||
const [donateToRewards] = useMutation(
|
const [donateToRewards] = useMutation(
|
||||||
|
@ -4,8 +4,15 @@ import Layout from '../../components/layout'
|
|||||||
import Col from 'react-bootstrap/Col'
|
import Col from 'react-bootstrap/Col'
|
||||||
import Row from 'react-bootstrap/Row'
|
import Row from 'react-bootstrap/Row'
|
||||||
import { UsageHeader } from '../../components/usage-header'
|
import { UsageHeader } from '../../components/usage-header'
|
||||||
import { WhenLineChart, WhenAreaChart } from '../../components/when-charts'
|
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
import dynamic from "next/dynamic"
|
||||||
|
|
||||||
|
const WhenAreaChart = dynamic(() => import('../../components/charts').then(mod => mod.WhenAreaChart), {
|
||||||
|
loading: () => <div>Loading...</div>
|
||||||
|
});
|
||||||
|
const WhenLineChart = dynamic(() => import('../../components/charts').then(mod => mod.WhenLineChart), {
|
||||||
|
loading: () => <div>Loading...</div>
|
||||||
|
});
|
||||||
|
|
||||||
export const getServerSideProps = getGetServerSideProps(
|
export const getServerSideProps = getGetServerSideProps(
|
||||||
gql`
|
gql`
|
||||||
@ -61,37 +68,38 @@ export default function Growth ({
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { when } = router.query
|
const { when } = router.query
|
||||||
const avg = ['year', 'forever'].includes(when) ? 'avg daily ' : ''
|
const avg = ['year', 'forever'].includes(when) ? 'avg daily ' : ''
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<UsageHeader />
|
<UsageHeader />
|
||||||
<Row>
|
<Row>
|
||||||
<Col className='mt-3'>
|
<Col className='mt-3'>
|
||||||
<div className='text-center text-muted fw-bold'>{avg}stackers</div>
|
<div className='text-center text-muted fw-bold'>{avg}stackers</div>
|
||||||
<WhenLineChart data={stackerGrowth} />
|
<WhenLineChart data={stackerGrowth} />
|
||||||
</Col>
|
</Col>
|
||||||
<Col className='mt-3'>
|
<Col className='mt-3'>
|
||||||
<div className='text-center text-muted fw-bold'>stacking</div>
|
<div className='text-center text-muted fw-bold'>stacking</div>
|
||||||
<WhenAreaChart data={stackingGrowth} />
|
<WhenAreaChart data={stackingGrowth} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Col className='mt-3'>
|
<Col className='mt-3'>
|
||||||
<div className='text-center text-muted fw-bold'>{avg}spenders</div>
|
<div className='text-center text-muted fw-bold'>{avg}spenders</div>
|
||||||
<WhenLineChart data={spenderGrowth} />
|
<WhenLineChart data={spenderGrowth} />
|
||||||
</Col>
|
</Col>
|
||||||
<Col className='mt-3'>
|
<Col className='mt-3'>
|
||||||
<div className='text-center text-muted fw-bold'>spending</div>
|
<div className='text-center text-muted fw-bold'>spending</div>
|
||||||
<WhenAreaChart data={spendingGrowth} />
|
<WhenAreaChart data={spendingGrowth} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Col className='mt-3'>
|
<Col className='mt-3'>
|
||||||
<div className='text-center text-muted fw-bold'>registrations</div>
|
<div className='text-center text-muted fw-bold'>registrations</div>
|
||||||
<WhenAreaChart data={registrationGrowth} />
|
<WhenAreaChart data={registrationGrowth} />
|
||||||
</Col>
|
</Col>
|
||||||
<Col className='mt-3'>
|
<Col className='mt-3'>
|
||||||
<div className='text-center text-muted fw-bold'>items</div>
|
<div className='text-center text-muted fw-bold'>items</div>
|
||||||
<WhenAreaChart data={itemGrowth} />
|
<WhenAreaChart data={itemGrowth} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user