mirror of
https://github.com/documenso/documenso.git
synced 2025-11-15 17:21:41 +10:00
chore: new query
This commit is contained in:
@ -0,0 +1,25 @@
|
|||||||
|
'use server';
|
||||||
|
|
||||||
|
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||||
|
import { isAdmin } from '@documenso/lib/next-auth/guards/is-admin';
|
||||||
|
import { getSigningVolume } from '@documenso/lib/server-only/admin/get-signing-volume-fix';
|
||||||
|
|
||||||
|
type SearchOptions = {
|
||||||
|
search: string;
|
||||||
|
page: number;
|
||||||
|
perPage: number;
|
||||||
|
sortBy: 'name' | 'createdAt' | 'signingVolume';
|
||||||
|
sortOrder: 'asc' | 'desc';
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function search({ search, page, perPage, sortBy, sortOrder }: SearchOptions) {
|
||||||
|
const { user } = await getRequiredServerComponentSession();
|
||||||
|
|
||||||
|
if (!isAdmin(user)) {
|
||||||
|
throw new Error('Unauthorized');
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = await getSigningVolume({ search, page, perPage, sortBy, sortOrder });
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-
|
|||||||
import { isAdmin } from '@documenso/lib/next-auth/guards/is-admin';
|
import { isAdmin } from '@documenso/lib/next-auth/guards/is-admin';
|
||||||
|
|
||||||
import { LeaderboardTable } from './data-table-leaderboard';
|
import { LeaderboardTable } from './data-table-leaderboard';
|
||||||
|
import { search as search2 } from './fetch-leaderboard-fix.actions';
|
||||||
import { search } from './fetch-leaderboard.actions';
|
import { search } from './fetch-leaderboard.actions';
|
||||||
|
|
||||||
type AdminLeaderboardProps = {
|
type AdminLeaderboardProps = {
|
||||||
@ -40,6 +41,14 @@ export default async function Leaderboard({ searchParams = {} }: AdminLeaderboar
|
|||||||
sortOrder,
|
sortOrder,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { leaderboard: signingVolume2, totalPages: totalPagesFix2 } = await search2({
|
||||||
|
search: searchString,
|
||||||
|
page,
|
||||||
|
perPage,
|
||||||
|
sortBy,
|
||||||
|
sortOrder,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-4xl font-semibold">
|
<h2 className="text-4xl font-semibold">
|
||||||
@ -54,6 +63,18 @@ export default async function Leaderboard({ searchParams = {} }: AdminLeaderboar
|
|||||||
sortBy={sortBy}
|
sortBy={sortBy}
|
||||||
sortOrder={sortOrder}
|
sortOrder={sortOrder}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<h2 className="mt-20 text-2xl font-semibold">
|
||||||
|
<Trans>Signing Volume 2</Trans>
|
||||||
|
</h2>
|
||||||
|
<LeaderboardTable
|
||||||
|
signingVolume={signingVolume2}
|
||||||
|
totalPages={totalPagesFix2}
|
||||||
|
page={page}
|
||||||
|
perPage={perPage}
|
||||||
|
sortBy={sortBy}
|
||||||
|
sortOrder={sortOrder}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
148
packages/lib/server-only/admin/get-signing-volume-fix.ts
Normal file
148
packages/lib/server-only/admin/get-signing-volume-fix.ts
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
import { prisma } from '@documenso/prisma';
|
||||||
|
import { Prisma } from '@documenso/prisma/client';
|
||||||
|
|
||||||
|
export type SigningVolume = {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
signingVolume: number;
|
||||||
|
createdAt: Date;
|
||||||
|
planId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetSigningVolumeOptions = {
|
||||||
|
search?: string;
|
||||||
|
page?: number;
|
||||||
|
perPage?: number;
|
||||||
|
sortBy?: 'name' | 'createdAt' | 'signingVolume';
|
||||||
|
sortOrder?: 'asc' | 'desc';
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function getSigningVolume({
|
||||||
|
search = '',
|
||||||
|
page = 1,
|
||||||
|
perPage = 10,
|
||||||
|
sortBy = 'signingVolume',
|
||||||
|
sortOrder = 'desc',
|
||||||
|
}: GetSigningVolumeOptions) {
|
||||||
|
const whereClause = Prisma.validator<Prisma.SubscriptionWhereInput>()({
|
||||||
|
status: 'ACTIVE',
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
|
User: {
|
||||||
|
OR: [
|
||||||
|
{ name: { contains: search, mode: 'insensitive' } },
|
||||||
|
{ email: { contains: search, mode: 'insensitive' } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
team: {
|
||||||
|
name: { contains: search, mode: 'insensitive' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const orderByClause = getOrderByClause({ sortBy, sortOrder });
|
||||||
|
|
||||||
|
const [subscriptions, totalCount] = await Promise.all([
|
||||||
|
prisma.subscription.findMany({
|
||||||
|
where: whereClause,
|
||||||
|
include: {
|
||||||
|
User: {
|
||||||
|
include: {
|
||||||
|
Document: {
|
||||||
|
where: {
|
||||||
|
status: 'COMPLETED',
|
||||||
|
deletedAt: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
team: {
|
||||||
|
include: {
|
||||||
|
document: {
|
||||||
|
where: {
|
||||||
|
status: 'COMPLETED',
|
||||||
|
deletedAt: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
orderBy: orderByClause,
|
||||||
|
skip: Math.max(page - 1, 0) * perPage,
|
||||||
|
take: perPage,
|
||||||
|
}),
|
||||||
|
prisma.subscription.count({
|
||||||
|
where: whereClause,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const leaderboardWithVolume: SigningVolume[] = subscriptions.map((subscription) => {
|
||||||
|
const name =
|
||||||
|
subscription.User?.name || subscription.team?.name || subscription.User?.email || 'Unknown';
|
||||||
|
|
||||||
|
const userSignedDocs = subscription.User?.Document?.length || 0;
|
||||||
|
const teamSignedDocs = subscription.team?.document?.length || 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: subscription.id,
|
||||||
|
name,
|
||||||
|
signingVolume: userSignedDocs + teamSignedDocs,
|
||||||
|
createdAt: subscription.createdAt,
|
||||||
|
planId: subscription.planId,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
leaderboard: leaderboardWithVolume,
|
||||||
|
totalPages: Math.ceil(totalCount / perPage),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOrderByClause(options: {
|
||||||
|
sortBy: string;
|
||||||
|
sortOrder: 'asc' | 'desc';
|
||||||
|
}): Prisma.SubscriptionOrderByWithRelationInput | Prisma.SubscriptionOrderByWithRelationInput[] {
|
||||||
|
const { sortBy, sortOrder } = options;
|
||||||
|
|
||||||
|
if (sortBy === 'name') {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
User: {
|
||||||
|
name: sortOrder,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
team: {
|
||||||
|
name: sortOrder,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sortBy === 'createdAt') {
|
||||||
|
return {
|
||||||
|
createdAt: sortOrder,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default: sort by signing volume
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
User: {
|
||||||
|
Document: {
|
||||||
|
_count: sortOrder,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
team: {
|
||||||
|
document: {
|
||||||
|
_count: sortOrder,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user