-
-
Notifications
You must be signed in to change notification settings - Fork 175
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e6fe909
commit 23eca68
Showing
4 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
44 changes: 44 additions & 0 deletions
44
clients/apps/web/src/app/maintainer/[organization]/subscriptions/subscribers/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import SubscribersPage from '@/components/Subscriptions/SubscribersPage' | ||
import { getServerSideAPI } from '@/utils/api' | ||
import { Platforms } from '@polar-sh/sdk' | ||
import { Metadata, ResolvingMetadata } from 'next' | ||
import { DataTableSearchParams, parseSearchParams } from 'polarkit/datatable' | ||
|
||
export async function generateMetadata( | ||
{ | ||
params, | ||
}: { | ||
params: { organization: string } | ||
}, | ||
parent: ResolvingMetadata, | ||
): Promise<Metadata> { | ||
return { | ||
title: `${params.organization}`, // " | Polar is added by the template" | ||
} | ||
} | ||
|
||
export default async function Page({ | ||
params, | ||
searchParams, | ||
}: { | ||
params: { organization: string } | ||
searchParams: DataTableSearchParams | ||
}) { | ||
const api = getServerSideAPI() | ||
const organization = await api.organizations.lookup({ | ||
organizationName: params.organization, | ||
platform: Platforms.GITHUB, | ||
}) | ||
|
||
const { pagination, sorting } = parseSearchParams(searchParams, [ | ||
{ id: 'started_at', desc: true }, | ||
]) | ||
|
||
return ( | ||
<SubscribersPage | ||
organization={organization} | ||
pagination={pagination} | ||
sorting={sorting} | ||
/> | ||
) | ||
} |
182 changes: 182 additions & 0 deletions
182
clients/apps/web/src/components/Subscriptions/SubscribersPage.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
'use client' | ||
|
||
import { DashboardBody } from '@/components/Layout/MaintainerLayout' | ||
import { | ||
Organization, | ||
PolarSubscriptionSchemasUser, | ||
Subscription, | ||
SubscriptionStatus, | ||
SubscriptionTierType, | ||
} from '@polar-sh/sdk' | ||
import { useRouter } from 'next/navigation' | ||
import { api } from 'polarkit' | ||
import { | ||
Avatar, | ||
DataTable, | ||
DataTableColumnDef, | ||
DataTableColumnHeader, | ||
FormattedDateTime, | ||
} from 'polarkit/components/ui/atoms' | ||
import { | ||
DataTablePaginationState, | ||
DataTableSortingState, | ||
getAPIParams, | ||
serializeSearchParams, | ||
} from 'polarkit/datatable' | ||
import React, { useEffect, useState } from 'react' | ||
import { subscriptionStatusDisplayNames, tiersTypeDisplayNames } from './utils' | ||
|
||
interface SubscribersPageProps { | ||
organization: Organization | ||
pagination: DataTablePaginationState | ||
sorting: DataTableSortingState | ||
} | ||
|
||
const SubscribersPage: React.FC<SubscribersPageProps> = ({ | ||
organization, | ||
pagination, | ||
sorting, | ||
}) => { | ||
const router = useRouter() | ||
const [subscriptions, setSubscriptions] = useState< | ||
Subscription[] | undefined | ||
>() | ||
const [pageCount, setPageCount] = useState<number | undefined>() | ||
|
||
const setPagination = ( | ||
updaterOrValue: | ||
| DataTablePaginationState | ||
| ((old: DataTablePaginationState) => DataTablePaginationState), | ||
) => { | ||
const updatedPagination = | ||
typeof updaterOrValue === 'function' | ||
? updaterOrValue(pagination) | ||
: updaterOrValue | ||
|
||
router.push( | ||
`/maintainer/${ | ||
organization.name | ||
}/subscriptions/subscribers?${serializeSearchParams( | ||
updatedPagination, | ||
sorting, | ||
)}`, | ||
) | ||
} | ||
|
||
const setSorting = ( | ||
updaterOrValue: | ||
| DataTableSortingState | ||
| ((old: DataTableSortingState) => DataTableSortingState), | ||
) => { | ||
const updatedSorting = | ||
typeof updaterOrValue === 'function' | ||
? updaterOrValue(sorting) | ||
: updaterOrValue | ||
|
||
router.push( | ||
`/maintainer/${ | ||
organization.name | ||
}/subscriptions/subscribers?${serializeSearchParams( | ||
pagination, | ||
updatedSorting, | ||
)}`, | ||
) | ||
} | ||
|
||
useEffect(() => { | ||
api.subscriptions | ||
.searchSubscriptions({ | ||
platform: organization.platform, | ||
organizationName: organization.name, | ||
...getAPIParams(pagination, sorting), | ||
}) | ||
.then((subscriptions) => { | ||
setSubscriptions(subscriptions.items || []) | ||
setPageCount(subscriptions.pagination.max_page) | ||
}) | ||
}, [organization, pagination, sorting]) | ||
|
||
const columns: DataTableColumnDef<Subscription>[] = [ | ||
{ | ||
accessorKey: 'user', | ||
enableSorting: true, | ||
header: ({ column }) => ( | ||
<DataTableColumnHeader column={column} title="User" /> | ||
), | ||
cell: (props) => { | ||
const user = props.getValue() as PolarSubscriptionSchemasUser | ||
return ( | ||
<div className="flex flex-row gap-2"> | ||
<Avatar avatar_url={user.avatar_url} name={user.username} /> | ||
<div className="fw-medium">{user.username}</div> | ||
</div> | ||
) | ||
}, | ||
}, | ||
{ | ||
accessorKey: 'status', | ||
enableSorting: true, | ||
header: ({ column }) => ( | ||
<DataTableColumnHeader column={column} title="Status" /> | ||
), | ||
cell: (props) => | ||
subscriptionStatusDisplayNames[props.getValue() as SubscriptionStatus], | ||
}, | ||
{ | ||
accessorKey: 'started_at', | ||
enableSorting: true, | ||
header: ({ column }) => ( | ||
<DataTableColumnHeader column={column} title="Subscription date" /> | ||
), | ||
cell: (props) => ( | ||
<FormattedDateTime datetime={props.getValue() as string} /> | ||
), | ||
}, | ||
{ | ||
accessorKey: 'current_period_end', | ||
enableSorting: true, | ||
header: ({ column }) => ( | ||
<DataTableColumnHeader column={column} title="Renewal date" /> | ||
), | ||
cell: (props) => ( | ||
<FormattedDateTime datetime={props.getValue() as string} /> | ||
), | ||
}, | ||
{ | ||
accessorKey: 'subscription_tier.type', | ||
id: 'subscription_tier_type', | ||
enableSorting: true, | ||
header: ({ column }) => ( | ||
<DataTableColumnHeader column={column} title="Tier group" /> | ||
), | ||
cell: (props) => | ||
tiersTypeDisplayNames[props.getValue() as SubscriptionTierType], | ||
}, | ||
{ | ||
accessorKey: 'subscription_tier.name', | ||
id: 'subscription_tier', | ||
enableSorting: true, | ||
header: ({ column }) => ( | ||
<DataTableColumnHeader column={column} title="Tier" /> | ||
), | ||
}, | ||
] | ||
|
||
return ( | ||
<DashboardBody> | ||
{subscriptions && pageCount !== undefined && ( | ||
<DataTable | ||
columns={columns} | ||
data={subscriptions} | ||
pageCount={pageCount} | ||
pagination={pagination} | ||
onPaginationChange={setPagination} | ||
sorting={sorting} | ||
onSortingChange={setSorting} | ||
/> | ||
)} | ||
</DashboardBody> | ||
) | ||
} | ||
|
||
export default SubscribersPage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters