diff --git a/src/components/Admin/Categories.svelte b/src/components/Admin/Categories.svelte new file mode 100644 index 00000000..e69de29b diff --git a/src/components/Admin/Contributions.svelte b/src/components/Admin/Contributions.svelte index db2f4e53..d8485f33 100644 --- a/src/components/Admin/Contributions.svelte +++ b/src/components/Admin/Contributions.svelte @@ -1,7 +1,12 @@ - - - +
+ +
+
+ + + +
+ + + +
+
diff --git a/src/components/Admin/ExportCsv.svelte b/src/components/Admin/ExportCsv.svelte new file mode 100644 index 00000000..e69de29b diff --git a/src/components/Admin/Filters.svelte b/src/components/Admin/Filters.svelte index 3245b2b3..01844db8 100644 --- a/src/components/Admin/Filters.svelte +++ b/src/components/Admin/Filters.svelte @@ -3,11 +3,15 @@ import ActiveFilterIcon from "../../svgs/ActiveFilterIcon.svelte"; import Search from "./Search.svelte"; import { apiGatewaysGetCollection } from "../../openapi/client/index"; - import { apiGatewayChargesGetCollection } from "../../openapi/client/index"; + import { + apiGatewayChargesGetCollection, + type ApiGatewayChargesGetCollectionData, + } from "../../openapi/client/index"; import { t } from "../../i18n/store"; import { onMount } from "svelte"; - let { onApplyFilters, currentTarget } = $props<{ + let { filters, onApplyFilters, currentTarget } = $props<{ + filters: ApiGatewayChargesGetCollectionData["query"]; onApplyFilters: (filters: any) => void; currentTarget?: string; }>(); @@ -54,15 +58,17 @@ alert($t("contributions.filters.dateRange.errors.invalidRange")); return; } + onApplyFilters({ - paymentMethod: selectedPaymentMethod, - chargeStatus: selectedChargeStatus, - rangeAmount: selectedRangeAmount, - from: dateFrom - ? new Date(new Date(dateFrom).getTime() - 24 * 60 * 60 * 1000).toISOString() + ...filters, + "checkout.gateway": selectedPaymentMethod || undefined, + status: selectedChargeStatus || undefined, + "money.amount[gte]": selectedRangeAmount || undefined, + "dateCreated[after]": dateFrom + ? new Date(new Date(dateFrom).getTime()).toISOString() : undefined, - to: dateTo - ? new Date(new Date(dateTo).getTime() + 24 * 60 * 60 * 1000).toISOString() + "dateCreated[before]": dateTo + ? new Date(new Date(dateTo).getTime()).toISOString() : undefined, }); } @@ -94,17 +100,13 @@ } if (dateFrom) { - const fromDate = new Date( - new Date(dateFrom).getTime() - 24 * 60 * 60 * 1000, - ).toISOString(); + const fromDate = new Date(new Date(dateFrom).getTime()).toISOString(); queryParams["dateCreated[strictly_after]"] = fromDate; filenameParams.from = dateFrom; } if (dateTo) { - const toDate = new Date( - new Date(dateTo).getTime() + 24 * 60 * 60 * 1000, - ).toISOString(); + const toDate = new Date(new Date(dateTo).getTime()).toISOString(); queryParams["dateCreated[strictly_before]"] = toDate; filenameParams.to = dateTo; } @@ -127,8 +129,8 @@ while (hasMoreData) { const pageQueryParams = { ...queryParams, - itemsPerPage: "50", - page: currentPage.toString(), + itemsPerPage: 50, + page: currentPage, }; const pageResponse = await apiGatewayChargesGetCollection({ @@ -208,6 +210,16 @@ isExporting = false; } } + + $effect(() => { + if (typeof filters["checkout.gateway"] === "undefined") selectedPaymentMethod = ""; + if (typeof filters.status === "undefined") selectedChargeStatus = ""; + if (typeof filters["money.amount[gte]"] === "undefined") selectedRangeAmount = ""; + if (typeof filters["money.amount[between]"] === "undefined") selectedRangeAmount = ""; + + if (typeof filters["dateCreated[after]"] === "undefined") dateFrom = ""; + if (typeof filters["dateCreated[before]"] === "undefined") dateTo = ""; + });
- {#if selectedPaymentMethod || selectedChargeStatus || selectedRangeAmount || dateFrom || dateTo} + {#if selectedPaymentMethod !== "" || selectedChargeStatus !== "" || selectedRangeAmount !== "" || dateFrom !== "" || dateTo !== ""} diff --git a/src/components/Admin/FiltersTags.svelte b/src/components/Admin/FiltersTags.svelte new file mode 100644 index 00000000..852a215f --- /dev/null +++ b/src/components/Admin/FiltersTags.svelte @@ -0,0 +1,120 @@ + + +
+

+ {title} +

+ + {#each tags as tag} + + {#if tag.values} + {`${tag.values.from} - ${tag.values.to}`} + {:else} + {tag.value} + {/if} + + + {/each} +
diff --git a/src/components/Admin/Table.svelte b/src/components/Admin/Table.svelte index 1e547b68..0cf9b7f7 100644 --- a/src/components/Admin/Table.svelte +++ b/src/components/Admin/Table.svelte @@ -29,6 +29,7 @@ Accounting, ApiProjectsIdOrSlugGetData, ApiUsersIdGetData, + ApiGatewayChargesGetCollectionData, } from "../../../src/openapi/client/index.ts"; import DetailsRow from "./DetailsRow.svelte"; import { client } from "../../openapi/client/client.gen.ts"; @@ -207,11 +208,11 @@ } async function loadCharges(filters: { - chargeStatus: string; - rangeAmount: string; - from?: string; - to?: string; paymentMethod: string; + chargeStatus: string; + rangeAmount?: string; + dateFrom?: string; + dateTo?: string; target?: string; }) { const current = Number(itemsPerPage); @@ -272,8 +273,8 @@ (filters.rangeAmount.includes("..") ? { "money.amount[between]": filters.rangeAmount } : { "money.amount[gte]": filters.rangeAmount })), - ...(filters.from && { "dateCreated[strictly_after]": filters.from }), - ...(filters.to && { "dateCreated[strictly_before]": filters.to }), + ...(filters.dateFrom && { "dateCreated[strictly_after]": filters.dateFrom }), + ...(filters.dateTo && { "dateCreated[strictly_before]": filters.dateTo }), ...(filters.paymentMethod && filters.paymentMethod !== "all" && { "checkout.gateway": `/v4/gateways/${filters.paymentMethod}`, @@ -487,21 +488,12 @@ }; } - let { filters } = $props<{ - filters: { - paymentMethod: string; - chargeStatus: string; - rangeAmount: string; - from?: string; - to?: string; - target?: string; - }; - }>(); + let { filters } = $props(); $effect(() => { - const { chargeStatus, rangeAmount, from, to, paymentMethod, target } = filters; + const { paymentMethod, chargeStatus, rangeAmount, dateFrom, dateTo, target } = filters; charges = []; - loadCharges({ chargeStatus, rangeAmount, from, to, paymentMethod, target }); + loadCharges({ paymentMethod, chargeStatus, rangeAmount, dateFrom, dateTo, target }); }); diff --git a/src/components/library/Tag.svelte b/src/components/library/Tag.svelte index b36c9e3f..3e45dab2 100644 --- a/src/components/library/Tag.svelte +++ b/src/components/library/Tag.svelte @@ -14,13 +14,13 @@ success: "bg-variant2", warning: "bg-variant4", error: "bg-tertiary", - bold: "bg-grey border-grey text-secondary font-bold", + bold: "bg-grey border-grey text-secondary font-bold border-soft-purple", };
{ const authorId: string | null = extractId(update.author); if (!authorId) return undefined; @@ -61,13 +53,15 @@ {#if type === "small"}
- {formatDate(update.date ?? "")} + {#if update.date} + {formatDate(new Date(update.date), $locale)} + {/if}
@@ -80,7 +74,7 @@ {update.title}
- {formatDate(update.date ?? "")} + {#if update.date} + {formatDate(new Date(update.date), $locale)} + {/if}
diff --git a/src/i18n/locales/ca.json b/src/i18n/locales/ca.json index dcc6c815..a199f8dc 100644 --- a/src/i18n/locales/ca.json +++ b/src/i18n/locales/ca.json @@ -605,8 +605,7 @@ "wallet": "Moneder" }, "status": { - "in_pending": "Pendent", - "charged": "Cobrat", + "in_charge": "Cobrat", "to_refund": "Per reemborsar", "refunded": "Reemborsat" }, @@ -717,8 +716,7 @@ "title": "Estat de l'aportació", "options": { "all": "Tots", - "in_pending": "Pendent", - "charged": "Cobrat", + "in_charge": "Cobrat", "to_refund": "Per reemborsar", "refunded": "Reemborsat" } diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 28cb218d..e91018c9 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -597,8 +597,7 @@ "wallet": "Wallet" }, "status": { - "in_pending": "Pending", - "charged": "Charged", + "in_charge": "Charged", "to_refund": "To refund", "refunded": "Refunded" }, @@ -709,8 +708,6 @@ "title": "Charge status", "options": { "all": "All", - "in_pending": "Pending", - "charged": "Charged", "to_refund": "To be refunded", "refunded": "Refunded" } diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index 67118012..68e1ff52 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -601,10 +601,12 @@ "wallet": "Monedero" }, "status": { - "in_pending": "Pendiente", - "charged": "Cobrado", + "to_charge": "Por cobrar", + "in_charge": "Cobrado", "to_refund": "Por reembolsar", - "refunded": "Reembolsado" + "refunded": "Reembolsado", + "to_wallet": "Por reembolsar a monedero", + "walleted": "Reembolsado a monedero" }, "refund": { "to_wallet": "Sí", @@ -713,10 +715,12 @@ "title": "Estado de Aporte", "options": { "all": "Todos", - "in_pending": "Pendiente", - "charged": "Cobrado", + "to_charge": "Por cobrar", + "in_charge": "Cobrado", "to_refund": "Por reembolsar", - "refunded": "Reembolsado" + "refunded": "Reembolsado", + "to_wallet": "Por reembolsar a monedero", + "walleted": "Reembolsado a monedero" } }, "projectStatus": { @@ -881,6 +885,9 @@ "totalPaid": "Total pagado:", "totalUnpaid": "Falta por pagar:" } + }, + "charges": { + "lastContributions": "Últimos aportes:" } }, "footer": { diff --git a/src/svgs/CloseIcon.svelte b/src/svgs/CloseIcon.svelte index 3b65d452..3e800305 100644 --- a/src/svgs/CloseIcon.svelte +++ b/src/svgs/CloseIcon.svelte @@ -1,4 +1,18 @@ - + import type { ClassNameValue } from "tailwind-merge"; + + interface Props { + class?: ClassNameValue; + } + + let { class: classes }: Props = $props(); + + + diff --git a/src/utils/dates.ts b/src/utils/dates.ts new file mode 100644 index 00000000..cb5daf06 --- /dev/null +++ b/src/utils/dates.ts @@ -0,0 +1,11 @@ +import type { Locale } from "../i18n/locales"; + +export function formatDate(date: Date, locale: Locale) { + const options: Intl.DateTimeFormatOptions = { + day: "2-digit", + month: "short", + year: "numeric", + }; + + return date.toLocaleDateString(locale, options); +}