develop-updateui #1
@@ -11,7 +11,12 @@
|
|||||||
"status": "Status",
|
"status": "Status",
|
||||||
"videos": "Videos",
|
"videos": "Videos",
|
||||||
"selected": "{{count}} selected",
|
"selected": "{{count}} selected",
|
||||||
"copy": "Copy"
|
"copy": "Copy",
|
||||||
|
"rowsPerPage": "Rows per page",
|
||||||
|
"next": "Next",
|
||||||
|
"previous": "Previous",
|
||||||
|
"page": "Page {{current}} of {{total}}",
|
||||||
|
"records": "records"
|
||||||
},
|
},
|
||||||
"app": {
|
"app": {
|
||||||
"name": "EcoStream"
|
"name": "EcoStream"
|
||||||
|
|||||||
@@ -11,7 +11,12 @@
|
|||||||
"status": "Trạng thái",
|
"status": "Trạng thái",
|
||||||
"videos": "Video",
|
"videos": "Video",
|
||||||
"selected": "{{count}} mục đã chọn",
|
"selected": "{{count}} mục đã chọn",
|
||||||
"copy": "Sao chép"
|
"copy": "Sao chép",
|
||||||
|
"rowsPerPage": "Số hàng mỗi trang",
|
||||||
|
"next": "Tiếp",
|
||||||
|
"previous": "Trước",
|
||||||
|
"page": "Trang {{current}} trên {{total}}",
|
||||||
|
"records": "bản ghi"
|
||||||
},
|
},
|
||||||
"app": {
|
"app": {
|
||||||
"name": "EcoStream"
|
"name": "EcoStream"
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ import { useAuthStore } from "@/stores/auth";
|
|||||||
import { useQuery } from "@pinia/colada";
|
import { useQuery } from "@pinia/colada";
|
||||||
import { useTranslation } from "i18next-vue";
|
import { useTranslation } from "i18next-vue";
|
||||||
import type { ColumnDef } from "@tanstack/vue-table";
|
import type { ColumnDef } from "@tanstack/vue-table";
|
||||||
|
import { computed, defineComponent, ref } from "vue";
|
||||||
|
import AppButton from "@/components/ui/AppButton.vue";
|
||||||
|
|
||||||
|
const pageSizeOptions = [5, 10, 20, 50] as const;
|
||||||
|
|
||||||
const normalizeHistoryStatus = (status?: string) => {
|
const normalizeHistoryStatus = (status?: string) => {
|
||||||
switch ((status || '').toLowerCase()) {
|
switch ((status || '').toLowerCase()) {
|
||||||
@@ -35,6 +39,8 @@ const PaymentHistory = defineComponent({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const toast = useAppToast();
|
const toast = useAppToast();
|
||||||
const downloadingInvoiceId = ref<string | null>(null);
|
const downloadingInvoiceId = ref<string | null>(null);
|
||||||
|
const page = ref(1);
|
||||||
|
const limit = ref(10);
|
||||||
|
|
||||||
const formatTermLabel = (months: number) => t('settings.billing.termOption', { months });
|
const formatTermLabel = (months: number) => t('settings.billing.termOption', { months });
|
||||||
const formatPaymentMethodLabel = (value?: string) => {
|
const formatPaymentMethodLabel = (value?: string) => {
|
||||||
@@ -74,9 +80,13 @@ const PaymentHistory = defineComponent({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
const { data, isLoading } = useQuery({
|
const { data, isLoading } = useQuery({
|
||||||
key: ['paymentHistory'],
|
key: () => ['paymentHistory', page.value, limit.value],
|
||||||
query: () => client.listPaymentHistory().then(res => (res.payments || []).map(mapHistoryItem)),
|
query: () => client.listPaymentHistory(page.value, limit.value).then(res => ({
|
||||||
|
...res,
|
||||||
|
items: (res.payments || []).map(mapHistoryItem)
|
||||||
|
})),
|
||||||
});
|
});
|
||||||
|
const totalPages = computed(() => Math.max(1, Math.ceil((data.value?.total || 0) / (data.value?.limit || limit.value || 1))));
|
||||||
|
|
||||||
const handleDownloadInvoice = async (item: PaymentHistoryItem) => {
|
const handleDownloadInvoice = async (item: PaymentHistoryItem) => {
|
||||||
if (!item.id) return;
|
if (!item.id) return;
|
||||||
@@ -193,11 +203,26 @@ const PaymentHistory = defineComponent({
|
|||||||
),
|
),
|
||||||
meta: {
|
meta: {
|
||||||
headerClass: 'col-span-2 flex justify-center',
|
headerClass: 'col-span-2 flex justify-center',
|
||||||
cellClass: 'col-span-2 justify-center',
|
cellClass: 'col-span-2 flex justify-center',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const previousPage = () => {
|
||||||
|
if (!data.value?.hasPrev || isLoading.value) return;
|
||||||
|
page.value -= 1;
|
||||||
|
};
|
||||||
|
const nextPage = () => {
|
||||||
|
if (!data.value?.hasNext || isLoading.value) return;
|
||||||
|
page.value += 1;
|
||||||
|
};
|
||||||
|
const changePageSize = (event: Event) => {
|
||||||
|
const nextLimit = Number((event.target as HTMLSelectElement).value) || 10;
|
||||||
|
if (nextLimit === limit.value) return;
|
||||||
|
limit.value = nextLimit;
|
||||||
|
page.value = 1;
|
||||||
|
};
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<div class="px-6 py-4">
|
<div class="px-6 py-4">
|
||||||
<div class="flex items-center gap-4 mb-4">
|
<div class="flex items-center gap-4 mb-4">
|
||||||
@@ -211,7 +236,7 @@ const PaymentHistory = defineComponent({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<BaseTable
|
<BaseTable
|
||||||
data={data.value || []}
|
data={data.value?.items || []}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
loading={isLoading.value}
|
loading={isLoading.value}
|
||||||
emptyText={t('settings.billing.noPaymentHistory')}
|
emptyText={t('settings.billing.noPaymentHistory')}
|
||||||
@@ -219,7 +244,7 @@ const PaymentHistory = defineComponent({
|
|||||||
{{
|
{{
|
||||||
loading: () => (
|
loading: () => (
|
||||||
<div class="px-4 py-6 space-y-3">
|
<div class="px-4 py-6 space-y-3">
|
||||||
{Array.from({ length: 3 }).map((_, index) => (
|
{Array.from({ length: 10 }).map((_, index) => (
|
||||||
<div key={index} class="grid grid-cols-12 gap-4 items-center animate-pulse">
|
<div key={index} class="grid grid-cols-12 gap-4 items-center animate-pulse">
|
||||||
<div class="col-span-3 h-4 rounded bg-muted/50" />
|
<div class="col-span-3 h-4 rounded bg-muted/50" />
|
||||||
<div class="col-span-2 h-4 rounded bg-muted/50" />
|
<div class="col-span-2 h-4 rounded bg-muted/50" />
|
||||||
@@ -240,6 +265,28 @@ const PaymentHistory = defineComponent({
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</BaseTable>
|
</BaseTable>
|
||||||
|
|
||||||
|
<div class="mt-4 flex flex-col gap-3 text-xs text-foreground/55 sm:flex-row sm:items-center sm:justify-between">
|
||||||
|
<div>{t('common.page', { current: data.value?.page || page.value, total: totalPages.value })} · {data.value?.total || 0} {t('common.records')}</div>
|
||||||
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
|
<label class="flex items-center gap-2">
|
||||||
|
<span>{t('common.rowsPerPage')}</span>
|
||||||
|
<select
|
||||||
|
class="rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground"
|
||||||
|
value={String(limit.value)}
|
||||||
|
onChange={changePageSize}
|
||||||
|
>
|
||||||
|
{pageSizeOptions.map((option) => (
|
||||||
|
<option key={option} value={String(option)}>{option}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<div class="flex items-center gap-2 xl:justify-end">
|
||||||
|
<AppButton size="sm" variant="secondary" disabled={!data.value?.hasPrev || isLoading.value} onClick={previousPage}>{t('common.previous')}</AppButton>
|
||||||
|
<AppButton size="sm" variant="secondary" disabled={!data.value?.hasNext || isLoading.value} onClick={nextPage}>{t('common.next')}</AppButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ onMounted(loadTemplates);
|
|||||||
</div>
|
</div>
|
||||||
<div class="space-y-2 md:col-span-2">
|
<div class="space-y-2 md:col-span-2">
|
||||||
<label class="text-sm font-medium text-foreground/70">Description</label>
|
<label class="text-sm font-medium text-foreground/70">Description</label>
|
||||||
<AdminTextarea v-model="createForm.description" rows="3" placeholder="Optional" />
|
<AdminTextarea v-model="createForm.description" :rows="3" placeholder="Optional" />
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-2 md:col-span-2">
|
<div class="space-y-2 md:col-span-2">
|
||||||
<label class="text-sm font-medium text-foreground/70">VAST URL</label>
|
<label class="text-sm font-medium text-foreground/70">VAST URL</label>
|
||||||
@@ -488,7 +488,7 @@ onMounted(loadTemplates);
|
|||||||
</div>
|
</div>
|
||||||
<div class="space-y-2 md:col-span-2">
|
<div class="space-y-2 md:col-span-2">
|
||||||
<label class="text-sm font-medium text-foreground/70">Description</label>
|
<label class="text-sm font-medium text-foreground/70">Description</label>
|
||||||
<AdminTextarea v-model="editForm.description" rows="3" />
|
<AdminTextarea v-model="editForm.description" :rows="3" />
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-2 md:col-span-2">
|
<div class="space-y-2 md:col-span-2">
|
||||||
<label class="text-sm font-medium text-foreground/70">VAST URL</label>
|
<label class="text-sm font-medium text-foreground/70">VAST URL</label>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import AdminInput from "./components/AdminInput.vue";
|
|||||||
import AdminSelect from "./components/AdminSelect.vue";
|
import AdminSelect from "./components/AdminSelect.vue";
|
||||||
import AdminTable from "./components/AdminTable.vue";
|
import AdminTable from "./components/AdminTable.vue";
|
||||||
import AdminSectionCard from "./components/AdminSectionCard.vue";
|
import AdminSectionCard from "./components/AdminSectionCard.vue";
|
||||||
import BillingPlansSection from "@/routes/settings/Billing/components/BillingPlansSection.vue";
|
import PlanSelection from "@/routes/settings/Billing/components/PlanSelection.tsx";
|
||||||
import type { Plan as ModelPlan } from "@/server/gen/proto/app/v1/common";
|
import type { Plan as ModelPlan } from "@/server/gen/proto/app/v1/common";
|
||||||
import { type ColumnDef } from "@tanstack/vue-table";
|
import { type ColumnDef } from "@tanstack/vue-table";
|
||||||
import { computed, h, onMounted, reactive, ref, watch } from "vue";
|
import { computed, h, onMounted, reactive, ref, watch } from "vue";
|
||||||
@@ -470,21 +470,10 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overflow-hidden rounded-lg border border-border">
|
<div class="overflow-hidden rounded-lg border border-border">
|
||||||
<BillingPlansSection
|
<PlanSelection
|
||||||
title="Available plans"
|
|
||||||
description="Reuse the same plan cards from the billing screen when creating an admin payment."
|
|
||||||
:is-loading="plansLoading"
|
|
||||||
:plans="plans"
|
|
||||||
:current-plan-id="selectedPlanId"
|
:current-plan-id="selectedPlanId"
|
||||||
:selecting-plan-id="selectedPlanId"
|
:selected-plan-id="selectedPlanId"
|
||||||
:format-money="(amount) => formatMoney(amount, 'USD')"
|
@upgrade="selectPlan"
|
||||||
:get-plan-storage-text="getPlanStorageText"
|
|
||||||
:get-plan-duration-text="getPlanDurationText"
|
|
||||||
:get-plan-uploads-text="getPlanUploadsText"
|
|
||||||
current-plan-label="Selected"
|
|
||||||
selecting-label="Selected"
|
|
||||||
choose-label="Select plan"
|
|
||||||
@select="selectPlan"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -38,10 +38,17 @@ export interface CreatePaymentResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ListPaymentHistoryRequest {
|
export interface ListPaymentHistoryRequest {
|
||||||
|
page?: number | undefined;
|
||||||
|
limit?: number | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ListPaymentHistoryResponse {
|
export interface ListPaymentHistoryResponse {
|
||||||
payments?: PaymentHistoryItem[] | undefined;
|
payments?: PaymentHistoryItem[] | undefined;
|
||||||
|
total?: number | undefined;
|
||||||
|
page?: number | undefined;
|
||||||
|
limit?: number | undefined;
|
||||||
|
hasPrev?: boolean | undefined;
|
||||||
|
hasNext?: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TopupWalletRequest {
|
export interface TopupWalletRequest {
|
||||||
@@ -325,11 +332,17 @@ export const CreatePaymentResponse: MessageFns<CreatePaymentResponse> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function createBaseListPaymentHistoryRequest(): ListPaymentHistoryRequest {
|
function createBaseListPaymentHistoryRequest(): ListPaymentHistoryRequest {
|
||||||
return {};
|
return { page: 0, limit: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ListPaymentHistoryRequest: MessageFns<ListPaymentHistoryRequest> = {
|
export const ListPaymentHistoryRequest: MessageFns<ListPaymentHistoryRequest> = {
|
||||||
encode(_: ListPaymentHistoryRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: ListPaymentHistoryRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
|
if (message.page !== undefined && message.page !== 0) {
|
||||||
|
writer.uint32(8).int32(message.page);
|
||||||
|
}
|
||||||
|
if (message.limit !== undefined && message.limit !== 0) {
|
||||||
|
writer.uint32(16).int32(message.limit);
|
||||||
|
}
|
||||||
return writer;
|
return writer;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -340,6 +353,22 @@ export const ListPaymentHistoryRequest: MessageFns<ListPaymentHistoryRequest> =
|
|||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
switch (tag >>> 3) {
|
switch (tag >>> 3) {
|
||||||
|
case 1: {
|
||||||
|
if (tag !== 8) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.page = reader.int32();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
if (tag !== 16) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.limit = reader.int32();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((tag & 7) === 4 || tag === 0) {
|
if ((tag & 7) === 4 || tag === 0) {
|
||||||
break;
|
break;
|
||||||
@@ -349,26 +378,37 @@ export const ListPaymentHistoryRequest: MessageFns<ListPaymentHistoryRequest> =
|
|||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
|
|
||||||
fromJSON(_: any): ListPaymentHistoryRequest {
|
fromJSON(object: any): ListPaymentHistoryRequest {
|
||||||
return {};
|
return {
|
||||||
|
page: isSet(object.page) ? globalThis.Number(object.page) : 0,
|
||||||
|
limit: isSet(object.limit) ? globalThis.Number(object.limit) : 0,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(_: ListPaymentHistoryRequest): unknown {
|
toJSON(message: ListPaymentHistoryRequest): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
|
if (message.page !== undefined && message.page !== 0) {
|
||||||
|
obj.page = Math.round(message.page);
|
||||||
|
}
|
||||||
|
if (message.limit !== undefined && message.limit !== 0) {
|
||||||
|
obj.limit = Math.round(message.limit);
|
||||||
|
}
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
create<I extends Exact<DeepPartial<ListPaymentHistoryRequest>, I>>(base?: I): ListPaymentHistoryRequest {
|
create<I extends Exact<DeepPartial<ListPaymentHistoryRequest>, I>>(base?: I): ListPaymentHistoryRequest {
|
||||||
return ListPaymentHistoryRequest.fromPartial(base ?? ({} as any));
|
return ListPaymentHistoryRequest.fromPartial(base ?? ({} as any));
|
||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<ListPaymentHistoryRequest>, I>>(_: I): ListPaymentHistoryRequest {
|
fromPartial<I extends Exact<DeepPartial<ListPaymentHistoryRequest>, I>>(object: I): ListPaymentHistoryRequest {
|
||||||
const message = createBaseListPaymentHistoryRequest();
|
const message = createBaseListPaymentHistoryRequest();
|
||||||
|
message.page = object.page ?? 0;
|
||||||
|
message.limit = object.limit ?? 0;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseListPaymentHistoryResponse(): ListPaymentHistoryResponse {
|
function createBaseListPaymentHistoryResponse(): ListPaymentHistoryResponse {
|
||||||
return { payments: [] };
|
return { payments: [], total: 0, page: 0, limit: 0, hasPrev: false, hasNext: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ListPaymentHistoryResponse: MessageFns<ListPaymentHistoryResponse> = {
|
export const ListPaymentHistoryResponse: MessageFns<ListPaymentHistoryResponse> = {
|
||||||
@@ -378,6 +418,21 @@ export const ListPaymentHistoryResponse: MessageFns<ListPaymentHistoryResponse>
|
|||||||
PaymentHistoryItem.encode(v!, writer.uint32(10).fork()).join();
|
PaymentHistoryItem.encode(v!, writer.uint32(10).fork()).join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (message.total !== undefined && message.total !== 0) {
|
||||||
|
writer.uint32(16).int64(message.total);
|
||||||
|
}
|
||||||
|
if (message.page !== undefined && message.page !== 0) {
|
||||||
|
writer.uint32(24).int32(message.page);
|
||||||
|
}
|
||||||
|
if (message.limit !== undefined && message.limit !== 0) {
|
||||||
|
writer.uint32(32).int32(message.limit);
|
||||||
|
}
|
||||||
|
if (message.hasPrev !== undefined && message.hasPrev !== false) {
|
||||||
|
writer.uint32(40).bool(message.hasPrev);
|
||||||
|
}
|
||||||
|
if (message.hasNext !== undefined && message.hasNext !== false) {
|
||||||
|
writer.uint32(48).bool(message.hasNext);
|
||||||
|
}
|
||||||
return writer;
|
return writer;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -399,6 +454,46 @@ export const ListPaymentHistoryResponse: MessageFns<ListPaymentHistoryResponse>
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
case 2: {
|
||||||
|
if (tag !== 16) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.total = longToNumber(reader.int64());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
if (tag !== 24) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.page = reader.int32();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
if (tag !== 32) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.limit = reader.int32();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
if (tag !== 40) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.hasPrev = reader.bool();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case 6: {
|
||||||
|
if (tag !== 48) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.hasNext = reader.bool();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((tag & 7) === 4 || tag === 0) {
|
if ((tag & 7) === 4 || tag === 0) {
|
||||||
break;
|
break;
|
||||||
@@ -413,6 +508,19 @@ export const ListPaymentHistoryResponse: MessageFns<ListPaymentHistoryResponse>
|
|||||||
payments: globalThis.Array.isArray(object?.payments)
|
payments: globalThis.Array.isArray(object?.payments)
|
||||||
? object.payments.map((e: any) => PaymentHistoryItem.fromJSON(e))
|
? object.payments.map((e: any) => PaymentHistoryItem.fromJSON(e))
|
||||||
: [],
|
: [],
|
||||||
|
total: isSet(object.total) ? globalThis.Number(object.total) : 0,
|
||||||
|
page: isSet(object.page) ? globalThis.Number(object.page) : 0,
|
||||||
|
limit: isSet(object.limit) ? globalThis.Number(object.limit) : 0,
|
||||||
|
hasPrev: isSet(object.hasPrev)
|
||||||
|
? globalThis.Boolean(object.hasPrev)
|
||||||
|
: isSet(object.has_prev)
|
||||||
|
? globalThis.Boolean(object.has_prev)
|
||||||
|
: false,
|
||||||
|
hasNext: isSet(object.hasNext)
|
||||||
|
? globalThis.Boolean(object.hasNext)
|
||||||
|
: isSet(object.has_next)
|
||||||
|
? globalThis.Boolean(object.has_next)
|
||||||
|
: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -421,6 +529,21 @@ export const ListPaymentHistoryResponse: MessageFns<ListPaymentHistoryResponse>
|
|||||||
if (message.payments?.length) {
|
if (message.payments?.length) {
|
||||||
obj.payments = message.payments.map((e) => PaymentHistoryItem.toJSON(e));
|
obj.payments = message.payments.map((e) => PaymentHistoryItem.toJSON(e));
|
||||||
}
|
}
|
||||||
|
if (message.total !== undefined && message.total !== 0) {
|
||||||
|
obj.total = Math.round(message.total);
|
||||||
|
}
|
||||||
|
if (message.page !== undefined && message.page !== 0) {
|
||||||
|
obj.page = Math.round(message.page);
|
||||||
|
}
|
||||||
|
if (message.limit !== undefined && message.limit !== 0) {
|
||||||
|
obj.limit = Math.round(message.limit);
|
||||||
|
}
|
||||||
|
if (message.hasPrev !== undefined && message.hasPrev !== false) {
|
||||||
|
obj.hasPrev = message.hasPrev;
|
||||||
|
}
|
||||||
|
if (message.hasNext !== undefined && message.hasNext !== false) {
|
||||||
|
obj.hasNext = message.hasNext;
|
||||||
|
}
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -430,6 +553,11 @@ export const ListPaymentHistoryResponse: MessageFns<ListPaymentHistoryResponse>
|
|||||||
fromPartial<I extends Exact<DeepPartial<ListPaymentHistoryResponse>, I>>(object: I): ListPaymentHistoryResponse {
|
fromPartial<I extends Exact<DeepPartial<ListPaymentHistoryResponse>, I>>(object: I): ListPaymentHistoryResponse {
|
||||||
const message = createBaseListPaymentHistoryResponse();
|
const message = createBaseListPaymentHistoryResponse();
|
||||||
message.payments = object.payments?.map((e) => PaymentHistoryItem.fromPartial(e)) || [];
|
message.payments = object.payments?.map((e) => PaymentHistoryItem.fromPartial(e)) || [];
|
||||||
|
message.total = object.total ?? 0;
|
||||||
|
message.page = object.page ?? 0;
|
||||||
|
message.limit = object.limit ?? 0;
|
||||||
|
message.hasPrev = object.hasPrev ?? false;
|
||||||
|
message.hasNext = object.hasNext ?? false;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -888,6 +1016,17 @@ type KeysOfUnion<T> = T extends T ? keyof T : never;
|
|||||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||||
|
|
||||||
|
function longToNumber(int64: { toString(): string }): number {
|
||||||
|
const num = globalThis.Number(int64.toString());
|
||||||
|
if (num > globalThis.Number.MAX_SAFE_INTEGER) {
|
||||||
|
throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
|
||||||
|
}
|
||||||
|
if (num < globalThis.Number.MIN_SAFE_INTEGER) {
|
||||||
|
throw new globalThis.Error("Value is smaller than Number.MIN_SAFE_INTEGER");
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
function isSet(value: any): boolean {
|
function isSet(value: any): boolean {
|
||||||
return value !== null && value !== undefined;
|
return value !== null && value !== undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,12 +322,15 @@ export const meMethods = {
|
|||||||
const metadata = context.get("grpcMetadata");
|
const metadata = context.get("grpcMetadata");
|
||||||
return await plansClient.listPlans({}, metadata);
|
return await plansClient.listPlans({}, metadata);
|
||||||
},
|
},
|
||||||
listPaymentHistory: async () => {
|
listPaymentHistory: validateFn(
|
||||||
|
z.number().int().min(1).optional(),
|
||||||
|
z.number().int().min(1).max(100).optional(),
|
||||||
|
)(async (page, limit) => {
|
||||||
const context = getContext();
|
const context = getContext();
|
||||||
const paymentsClient = context.get("paymentsServiceClient");
|
const paymentsClient = context.get("paymentsServiceClient");
|
||||||
const metadata = context.get("grpcMetadata");
|
const metadata = context.get("grpcMetadata");
|
||||||
return await paymentsClient.listPaymentHistory({}, metadata);
|
return await paymentsClient.listPaymentHistory({ page, limit }, metadata);
|
||||||
},
|
}),
|
||||||
createPayment: validateFn(
|
createPayment: validateFn(
|
||||||
z.object({
|
z.object({
|
||||||
planId: z.string().trim().min(1),
|
planId: z.string().trim().min(1),
|
||||||
|
|||||||
Reference in New Issue
Block a user