feat: update deps & fix stuff
This commit is contained in:
parent
d8b308a18c
commit
5d115afa71
12 changed files with 474 additions and 493 deletions
|
@ -4,7 +4,7 @@
|
|||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 3.4.8 | :white_check_mark: |
|
||||
| 3.6.x | :white_check_mark: |
|
||||
| < 3 | :x: |
|
||||
| < 2 | :x: |
|
||||
|
||||
|
|
62
package.json
62
package.json
|
@ -26,27 +26,25 @@
|
|||
"@dicedtomato/mantine-data-grid": "0.0.23",
|
||||
"@emotion/react": "^11.10.5",
|
||||
"@emotion/server": "^11.10.0",
|
||||
"@mantine/core": "^5.6.3",
|
||||
"@mantine/dropzone": "^5.6.3",
|
||||
"@mantine/form": "^5.6.3",
|
||||
"@mantine/hooks": "^5.6.3",
|
||||
"@mantine/modals": "^5.6.3",
|
||||
"@mantine/next": "^5.6.3",
|
||||
"@mantine/notifications": "^5.6.3",
|
||||
"@mantine/nprogress": "^5.6.3",
|
||||
"@mantine/prism": "^5.6.3",
|
||||
"@prisma/client": "^4.5.0",
|
||||
"@prisma/internals": "^4.5.0",
|
||||
"@prisma/migrate": "^4.5.0",
|
||||
"@sapphire/shapeshift": "^3.7.0",
|
||||
"@tanstack/react-query": "^4.13.0",
|
||||
"argon2": "^0.30.1",
|
||||
"chart.js": "^3.9.1",
|
||||
"chartjs-plugin-datalabels": "^2.1.0",
|
||||
"color-hash": "^2.0.1",
|
||||
"@mantine/core": "^5.9.2",
|
||||
"@mantine/dropzone": "^5.9.2",
|
||||
"@mantine/form": "^5.9.2",
|
||||
"@mantine/hooks": "^5.9.2",
|
||||
"@mantine/modals": "^5.9.2",
|
||||
"@mantine/next": "^5.9.2",
|
||||
"@mantine/notifications": "^5.9.2",
|
||||
"@mantine/nprogress": "^5.9.2",
|
||||
"@mantine/prism": "^5.9.2",
|
||||
"@prisma/client": "^4.7.1",
|
||||
"@prisma/internals": "^4.7.1",
|
||||
"@prisma/migrate": "^4.7.1",
|
||||
"@sapphire/shapeshift": "^3.7.1",
|
||||
"@tanstack/react-query": "^4.19.1",
|
||||
"argon2": "^0.30.2",
|
||||
"chart.js": "^4.0.1",
|
||||
"colorette": "^2.0.19",
|
||||
"cookie": "^0.5.0",
|
||||
"dayjs": "^1.11.6",
|
||||
"dayjs": "^1.11.7",
|
||||
"dotenv": "^16.0.3",
|
||||
"dotenv-expand": "^9.0.0",
|
||||
"exiftool-vendored": "^18.6.0",
|
||||
|
@ -54,42 +52,42 @@
|
|||
"fastify-plugin": "^4.4.0",
|
||||
"fflate": "^0.7.4",
|
||||
"find-my-way": "^7.3.1",
|
||||
"katex": "^0.16.3",
|
||||
"katex": "^0.16.4",
|
||||
"minio": "^7.0.32",
|
||||
"ms": "canary",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"next": "^13.0.0",
|
||||
"next": "^13.0.6",
|
||||
"otplib": "^12.0.1",
|
||||
"prisma": "^4.5.0",
|
||||
"prisma": "^4.7.1",
|
||||
"prismjs": "^1.29.0",
|
||||
"qrcode": "^1.5.1",
|
||||
"react": "^18.2.0",
|
||||
"react-chartjs-2": "^4.3.1",
|
||||
"react-chartjs-2": "^5.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-feather": "^2.0.10",
|
||||
"react-markdown": "^8.0.4",
|
||||
"recoil": "^0.7.6",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"sharp": "^0.31.1"
|
||||
"sharp": "^0.31.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cookie": "^0.5.1",
|
||||
"@types/katex": "^0.14.0",
|
||||
"@types/minio": "^7.0.14",
|
||||
"@types/minio": "^7.0.15",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^18.11.7",
|
||||
"@types/node": "^18.11.12",
|
||||
"@types/qrcode": "^1.5.0",
|
||||
"@types/react": "^18.0.24",
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/sharp": "^0.31.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild": "^0.15.12",
|
||||
"eslint": "^8.26.0",
|
||||
"eslint-config-next": "^13.0.0",
|
||||
"esbuild": "^0.16.4",
|
||||
"eslint": "^8.29.0",
|
||||
"eslint-config-next": "^13.0.6",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.8.4"
|
||||
"prettier": "^2.8.1",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
5
src/components/icons/DatabaseIcon.tsx
Normal file
5
src/components/icons/DatabaseIcon.tsx
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { Database } from 'react-feather';
|
||||
|
||||
export default function DatabaseIcon({ ...props }) {
|
||||
return <Database size={15} {...props} />;
|
||||
}
|
|
@ -33,6 +33,7 @@ import GoogleIcon from './GoogleIcon';
|
|||
import EyeIcon from './EyeIcon';
|
||||
import RefreshIcon from './RefreshIcon';
|
||||
import KeyIcon from './KeyIcon';
|
||||
import DatabaseIcon from './DatabaseIcon';
|
||||
|
||||
export {
|
||||
ActivityIcon,
|
||||
|
@ -70,4 +71,5 @@ export {
|
|||
EyeIcon,
|
||||
RefreshIcon,
|
||||
KeyIcon,
|
||||
DatabaseIcon,
|
||||
};
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { SimpleGrid } from '@mantine/core';
|
||||
import { FileIcon } from 'components/icons';
|
||||
import StatCard from 'components/StatCard';
|
||||
import { useStats } from 'lib/queries/stats';
|
||||
import { percentChange } from 'lib/utils/client';
|
||||
import { Database, Eye, Users } from 'react-feather';
|
||||
import { EyeIcon, DatabaseIcon, UserIcon, FileIcon } from 'components/icons';
|
||||
|
||||
export function StatCards() {
|
||||
const stats = useStats();
|
||||
|
@ -35,7 +34,7 @@ export function StatCards() {
|
|||
title: 'STORAGE',
|
||||
value: stats.isSuccess ? latest.data.size : '...',
|
||||
desc: 'of storage used',
|
||||
icon: <Database size={15} />,
|
||||
icon: <DatabaseIcon />,
|
||||
diff:
|
||||
stats.isSuccess && before?.data
|
||||
? percentChange(before.data.size_num, latest.data.size_num)
|
||||
|
@ -48,7 +47,7 @@ export function StatCards() {
|
|||
title: 'VIEWS',
|
||||
value: stats.isSuccess ? latest.data.views_count.toLocaleString() : '...',
|
||||
desc: 'total page views',
|
||||
icon: <Eye size={15} />,
|
||||
icon: <EyeIcon />,
|
||||
diff:
|
||||
stats.isSuccess && before?.data
|
||||
? percentChange(before.data.views_count, latest.data.views_count)
|
||||
|
@ -61,7 +60,7 @@ export function StatCards() {
|
|||
title: 'USERS',
|
||||
value: stats.isSuccess ? latest.data.count_users.toLocaleString() : '...',
|
||||
desc: 'total registered users',
|
||||
icon: <Users size={15} />,
|
||||
icon: <UserIcon />,
|
||||
}}
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
|
|
@ -11,18 +11,12 @@ import {
|
|||
PointElement,
|
||||
Tooltip,
|
||||
} from 'chart.js';
|
||||
import ChartDataLabels from 'chartjs-plugin-datalabels';
|
||||
import ColorHash from 'color-hash';
|
||||
import { useStats } from 'lib/queries/stats';
|
||||
import { bytesToHuman } from 'lib/utils/bytes';
|
||||
import { useMemo } from 'react';
|
||||
import { Chart, Pie } from 'react-chartjs-2';
|
||||
import { Chart } from 'react-chartjs-2';
|
||||
|
||||
const hash = new ColorHash();
|
||||
ChartJS.register(ArcElement);
|
||||
ChartJS.register(ChartDataLabels);
|
||||
ChartJS.register(LinearScale);
|
||||
ChartJS.register(CategoryScale, PointElement, LineController, LineElement, Tooltip);
|
||||
ChartJS.register(ArcElement, LinearScale, CategoryScale, PointElement, LineController, LineElement, Tooltip);
|
||||
|
||||
const CHART_OPTIONS = (theme: MantineTheme): ChartOptions => ({
|
||||
plugins: {
|
||||
|
@ -30,10 +24,6 @@ const CHART_OPTIONS = (theme: MantineTheme): ChartOptions => ({
|
|||
enabled: true,
|
||||
intersect: false,
|
||||
},
|
||||
|
||||
datalabels: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
|
||||
scales: {
|
||||
|
@ -60,17 +50,15 @@ const CHART_OPTIONS = (theme: MantineTheme): ChartOptions => ({
|
|||
},
|
||||
});
|
||||
|
||||
type LineChartData = ChartData<'line', number[], string>;
|
||||
type ChartDataMemo = {
|
||||
export type LineChartData = ChartData<'line', number[], string>;
|
||||
export type ChartDataMemo = {
|
||||
views: LineChartData;
|
||||
uploads: LineChartData;
|
||||
uploadTypes: ChartData<'pie', number[], string>;
|
||||
storage: LineChartData;
|
||||
} | void;
|
||||
|
||||
export default function Graphs() {
|
||||
const historicalStats = useStats(10);
|
||||
const latest = historicalStats.data?.[0];
|
||||
const theme = useMantineTheme();
|
||||
|
||||
const chartOptions = useMemo(() => CHART_OPTIONS(theme), [theme]);
|
||||
|
@ -89,7 +77,7 @@ export default function Graphs() {
|
|||
labels,
|
||||
datasets: [
|
||||
{
|
||||
label: 'Views',
|
||||
label: ' Views',
|
||||
data: viewData,
|
||||
borderColor: theme.colors.blue[6],
|
||||
backgroundColor: theme.colors.blue[0],
|
||||
|
@ -101,7 +89,7 @@ export default function Graphs() {
|
|||
labels,
|
||||
datasets: [
|
||||
{
|
||||
label: 'Uploads',
|
||||
label: ' Uploads',
|
||||
data: uploadData,
|
||||
borderColor: theme.colors.blue[6],
|
||||
backgroundColor: theme.colors.blue[0],
|
||||
|
@ -109,22 +97,11 @@ export default function Graphs() {
|
|||
],
|
||||
},
|
||||
|
||||
uploadTypes: {
|
||||
labels: latest?.data.types_count.map((x) => x.mimetype),
|
||||
datasets: [
|
||||
{
|
||||
data: latest?.data.types_count.map((x) => x.count),
|
||||
label: 'Upload Types',
|
||||
backgroundColor: latest?.data.types_count.map((x) => hash.hex(x.mimetype)),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
storage: {
|
||||
labels,
|
||||
datasets: [
|
||||
{
|
||||
label: 'Storage',
|
||||
label: ' Storage',
|
||||
data: storageData,
|
||||
borderColor: theme.colors.blue[6],
|
||||
backgroundColor: theme.colors.blue[0],
|
||||
|
@ -139,37 +116,8 @@ export default function Graphs() {
|
|||
<LoadingOverlay visible={historicalStats.isLoading} />
|
||||
|
||||
<Grid>
|
||||
{/* 1/4 - upload types */}
|
||||
<Grid.Col md={12} lg={4}>
|
||||
<Card>
|
||||
<Title size='h4'>Upload Types</Title>
|
||||
{chartData && (
|
||||
<Pie
|
||||
data={chartData.uploadTypes}
|
||||
options={{
|
||||
plugins: {
|
||||
datalabels: {
|
||||
formatter: (_, ctx) => {
|
||||
// mime: count
|
||||
const mime = ctx.chart.data.labels[ctx.dataIndex];
|
||||
const count = ctx.chart.data.datasets[0].data[ctx.dataIndex];
|
||||
return `${mime}: ${count}`;
|
||||
},
|
||||
|
||||
color: 'white',
|
||||
textShadowBlur: 7,
|
||||
textShadowColor: 'black',
|
||||
},
|
||||
},
|
||||
}}
|
||||
style={{ maxHeight: '20vh' }}
|
||||
/>
|
||||
)}
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
|
||||
{/* 3/4 - views */}
|
||||
<Grid.Col md={12} lg={8}>
|
||||
<Grid.Col md={12}>
|
||||
<Card>
|
||||
<Title size='h4'>Total Views</Title>
|
||||
{chartData && (
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import { Box, Card, LoadingOverlay } from '@mantine/core';
|
||||
import { Box, Card, Center, Grid, LoadingOverlay, Title } from '@mantine/core';
|
||||
import { ChartData } from 'chart.js';
|
||||
import { SmallTable } from 'components/SmallTable';
|
||||
import { useStats } from 'lib/queries/stats';
|
||||
import { colorHash } from 'lib/utils/client';
|
||||
import { useMemo } from 'react';
|
||||
import { Pie } from 'react-chartjs-2';
|
||||
|
||||
export default function Types() {
|
||||
const stats = useStats();
|
||||
|
@ -9,6 +13,23 @@ export default function Types() {
|
|||
|
||||
const latest = stats.data[0];
|
||||
|
||||
const chartData = useMemo<{
|
||||
uploadTypes: ChartData<'pie', number[], string>;
|
||||
}>(() => {
|
||||
return {
|
||||
uploadTypes: {
|
||||
labels: latest?.data.types_count.map((x) => x.mimetype),
|
||||
datasets: [
|
||||
{
|
||||
data: latest?.data.types_count.map((x) => x.count),
|
||||
label: ' Count',
|
||||
backgroundColor: latest?.data.types_count.map((x) => colorHash(x.mimetype)),
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}, [latest]);
|
||||
|
||||
return (
|
||||
<Box mt='md'>
|
||||
{latest.data.count_by_user.length ? (
|
||||
|
@ -23,6 +44,9 @@ export default function Types() {
|
|||
</Card>
|
||||
) : null}
|
||||
<Card>
|
||||
<Title size='h4'>Upload Types</Title>
|
||||
<Grid>
|
||||
<Grid.Col md={12} lg={8}>
|
||||
<SmallTable
|
||||
columns={[
|
||||
{ id: 'mimetype', name: 'Type' },
|
||||
|
@ -30,6 +54,12 @@ export default function Types() {
|
|||
]}
|
||||
rows={latest.data.types_count}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col md={12} lg={4}>
|
||||
<Center>{chartData && <Pie data={chartData.uploadTypes} style={{ maxHeight: '20vh' }} />}</Center>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Card>
|
||||
</Box>
|
||||
);
|
||||
|
|
|
@ -8,7 +8,8 @@ import { useEffect } from 'react';
|
|||
export default function PrismCode({ code, ext, ...props }) {
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (ext !== 'txt') await import(`prismjs/components/prism-${extToPrismComponent(ext)}`);
|
||||
const component = extToPrismComponent[ext];
|
||||
if (component && ext !== 'txt') await import(`prismjs/components/prism-${component}`);
|
||||
})();
|
||||
}, [ext]);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ export default {
|
|||
json: 'JSON',
|
||||
vim: 'Vim Script',
|
||||
txt: 'Plain Text',
|
||||
html: 'HTML',
|
||||
};
|
||||
|
||||
export const extToPrismComponent = (ext: string) => {
|
||||
|
@ -75,5 +76,6 @@ export const extToPrismComponent = (ext: string) => {
|
|||
vb: 'visual-basic',
|
||||
json: 'json',
|
||||
vim: 'vim',
|
||||
html: 'html',
|
||||
}[ext];
|
||||
};
|
||||
|
|
|
@ -138,3 +138,18 @@ export function expireReadToDate(expires: string): Date {
|
|||
}[expires]
|
||||
);
|
||||
}
|
||||
|
||||
export function colorHash(str: string) {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
|
||||
let color = '#';
|
||||
for (let i = 0; i < 3; i++) {
|
||||
let value = (hash >> (i * 8)) & 0xff;
|
||||
color += ('00' + value.toString(16)).substr(-2);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { PrismaClient } from '@prisma/client';
|
||||
import { Migrate } from '@prisma/migrate/dist/Migrate';
|
||||
import { ensureDatabaseExists } from '@prisma/migrate/dist/utils/ensureDatabaseExists';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
import { ServerResponse } from 'http';
|
||||
import { Datasource } from '../lib/datasources';
|
||||
import Logger from '../lib/logger';
|
||||
|
|
Loading…
Reference in a new issue