-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(dashboard): add rewards history
- Loading branch information
Showing
10 changed files
with
273 additions
and
9 deletions.
There are no files selected for viewing
19 changes: 15 additions & 4 deletions
19
apps/api-gql/internal/delivery/gql/resolvers/community-redemptions.resolver.go
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { useQuery } from '@urql/vue' | ||
import { createGlobalState } from '@vueuse/core' | ||
import { unref } from 'vue' | ||
|
||
import type { RewardsRedemptionsHistoryQuery, TwitchRedemptionsOpts } from '@/gql/graphql' | ||
import type { MaybeRef } from 'vue' | ||
|
||
import { graphql } from '@/gql/gql.js' | ||
|
||
export type Redemption = RewardsRedemptionsHistoryQuery['rewardsRedemptionsHistory']['redemptions'][0] | ||
|
||
export const useCommunityRewardsApi = createGlobalState(() => { | ||
const useHistory = (opts: MaybeRef<TwitchRedemptionsOpts>) => useQuery({ | ||
query: graphql(` | ||
query RewardsRedemptionsHistory($opts: TwitchRedemptionsOpts!) { | ||
rewardsRedemptionsHistory(opts: $opts) { | ||
redemptions { | ||
id | ||
channelId | ||
user { | ||
id | ||
displayName | ||
login | ||
profileImageUrl | ||
} | ||
reward { | ||
id | ||
cost | ||
imageUrls | ||
title | ||
usedTimes | ||
} | ||
redeemedAt | ||
prompt | ||
} | ||
total | ||
} | ||
} | ||
`), | ||
get variables() { | ||
return { | ||
opts: unref(opts), | ||
} | ||
}, | ||
}) | ||
|
||
return { | ||
useHistory, | ||
} | ||
}) |
22 changes: 22 additions & 0 deletions
22
frontend/dashboard/src/features/community-rewards-history/community-rewards-history.vue
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,22 @@ | ||
<script setup lang="ts"> | ||
import { useCommunityRewardsTable } from './composables/community-rewards-history-table' | ||
import CommunityRewardsPage from './ui/community-rewards-history-page.vue' | ||
import Pagination from '@/components/pagination.vue' | ||
const rewardsTable = useCommunityRewardsTable() | ||
</script> | ||
|
||
<template> | ||
<CommunityRewardsPage> | ||
<template #pagination> | ||
<Pagination | ||
:total="rewardsTable.total.value" | ||
:table="rewardsTable.table" | ||
:pagination="rewardsTable.pagination.value" | ||
@update:page="(page) => rewardsTable.pagination.value.pageIndex = page" | ||
@update:page-size="(pageSize) => rewardsTable.pagination.value.pageSize = pageSize" | ||
/> | ||
</template> | ||
</CommunityRewardsPage> | ||
</template> |
126 changes: 126 additions & 0 deletions
126
...ard/src/features/community-rewards-history/composables/community-rewards-history-table.ts
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,126 @@ | ||
import { | ||
type ColumnDef, | ||
getCoreRowModel, | ||
getFacetedRowModel, | ||
getFacetedUniqueValues, | ||
getFilteredRowModel, | ||
getPaginationRowModel, | ||
getSortedRowModel, | ||
useVueTable, | ||
} from '@tanstack/vue-table' | ||
import { createGlobalState } from '@vueuse/core' | ||
import { computed, h } from 'vue' | ||
|
||
import CommunityRewardsTableRewardCell from '../ui/cells/community-rewards-history-table-reward-cell.vue' | ||
|
||
import type { Redemption } from '@/api/community-rewards' | ||
import type { TwitchRedemptionsOpts } from '@/gql/graphql' | ||
|
||
import { useProfile } from '@/api/auth.js' | ||
import { useCommunityRewardsApi } from '@/api/community-rewards' | ||
import { usePagination } from '@/composables/use-pagination' | ||
import UsersTableCellUser from '@/features/admin-panel/manage-users/ui/users-table-cell-user.vue' | ||
import { valueUpdater } from '@/helpers/value-updater' | ||
|
||
export const useCommunityRewardsTable = createGlobalState(() => { | ||
const communityRewardsApi = useCommunityRewardsApi() | ||
const { data: profile } = useProfile() | ||
|
||
const { pagination, setPagination } = usePagination() | ||
const params = computed<TwitchRedemptionsOpts>(() => { | ||
return { | ||
byChannelId: profile.value?.selectedDashboardId, | ||
userSearch: undefined, | ||
page: pagination.value.pageIndex, | ||
perPage: pagination.value.pageSize, | ||
rewardsIds: [], | ||
} | ||
}) | ||
const historyResult = communityRewardsApi.useHistory(params) | ||
|
||
const history = computed<Redemption[]>(() => { | ||
return historyResult.data.value?.rewardsRedemptionsHistory.redemptions ?? [] | ||
}) | ||
const total = computed(() => { | ||
return historyResult.data.value?.rewardsRedemptionsHistory.total ?? 0 | ||
}) | ||
const pageCount = computed(() => { | ||
return Math.ceil(total.value / pagination.value.pageSize) | ||
}) | ||
|
||
const tableColumns = computed<ColumnDef<Redemption>[]>(() => [ | ||
{ | ||
accessorKey: 'reward', | ||
size: 20, | ||
header: () => 'Reward', | ||
cell: ({ row }) => { | ||
return h(CommunityRewardsTableRewardCell, { | ||
name: row.original.reward.title, | ||
imageUrl: row.original.reward.imageUrls?.at(-1), | ||
}) | ||
}, | ||
}, | ||
{ | ||
accessorKey: 'user', | ||
size: 20, | ||
header: () => 'User', | ||
cell: ({ row }) => { | ||
return h('a', { | ||
class: 'flex flex-col', | ||
href: `https://twitch.tv/${row.original.user.login}`, | ||
target: '_blank', | ||
}, h(UsersTableCellUser, { | ||
avatar: row.original.user.profileImageUrl, | ||
name: row.original.user.login, | ||
displayName: row.original.user.displayName, | ||
})) | ||
}, | ||
}, | ||
{ | ||
accessorKey: 'cost', | ||
size: 5, | ||
header: () => 'Cost', | ||
cell: ({ row }) => row.original.reward.cost, | ||
}, | ||
{ | ||
accessorKey: 'input', | ||
size: 65, | ||
header: () => 'User input', | ||
cell: ({ row }) => row.original.prompt, | ||
}, | ||
]) | ||
|
||
const table = useVueTable({ | ||
get pageCount() { | ||
return pageCount.value | ||
}, | ||
get data() { | ||
return history.value | ||
}, | ||
get columns() { | ||
return tableColumns.value | ||
}, | ||
manualPagination: true, | ||
enableRowSelection: true, | ||
onPaginationChange: (updaterOrValue) => valueUpdater(updaterOrValue, pagination), | ||
// onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sorting), | ||
// onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFilters), | ||
// onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibility), | ||
// onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelection), | ||
getCoreRowModel: getCoreRowModel(), | ||
getFilteredRowModel: getFilteredRowModel(), | ||
getPaginationRowModel: getPaginationRowModel(), | ||
getSortedRowModel: getSortedRowModel(), | ||
getFacetedRowModel: getFacetedRowModel(), | ||
getFacetedUniqueValues: getFacetedUniqueValues(), | ||
}) | ||
|
||
return { | ||
table, | ||
total, | ||
pageCount, | ||
pagination, | ||
setPagination, | ||
isLoading: historyResult.fetching, | ||
} | ||
}) |
18 changes: 18 additions & 0 deletions
18
...atures/community-rewards-history/ui/cells/community-rewards-history-table-reward-cell.vue
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,18 @@ | ||
<script setup lang="ts"> | ||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' | ||
defineProps<{ | ||
imageUrl?: string | ||
name: string | ||
}>() | ||
</script> | ||
|
||
<template> | ||
<div class="flex items-center gap-4 max-sm:justify-start"> | ||
<Avatar class="size-9"> | ||
<AvatarImage v-if="imageUrl" :src="imageUrl" :alt="name" loading="lazy" /> | ||
<AvatarFallback>{{ name }}</AvatarFallback> | ||
</Avatar> | ||
{{ name }} | ||
</div> | ||
</template> |
11 changes: 11 additions & 0 deletions
11
...nd/dashboard/src/features/community-rewards-history/ui/community-rewards-history-page.vue
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,11 @@ | ||
<script setup lang="ts"> | ||
import CommunityRewardsTable from './community-rewards-history-table.vue' | ||
</script> | ||
|
||
<template> | ||
<div class="flex flex-col w-full gap-4"> | ||
<slot name="pagination" /> | ||
<CommunityRewardsTable /> | ||
<slot name="pagination" /> | ||
</div> | ||
</template> |
14 changes: 14 additions & 0 deletions
14
...d/dashboard/src/features/community-rewards-history/ui/community-rewards-history-table.vue
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,14 @@ | ||
<script setup lang="ts"> | ||
import { useCommunityRewardsTable } from '../composables/community-rewards-history-table' | ||
import Table from '@/components/table.vue' | ||
const rewardsTable = useCommunityRewardsTable() | ||
</script> | ||
|
||
<template> | ||
<Table | ||
:table="rewardsTable.table" | ||
:is-loading="rewardsTable.isLoading.value" | ||
/> | ||
</template> |
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