From 76b05c5335aa5a409cd7f240a5aa851b7c5da945 Mon Sep 17 00:00:00 2001 From: tongo Date: Mon, 7 Aug 2023 11:24:40 +0300 Subject: [PATCH 1/3] sort donation wishes --- public/locales/bg/campaigns.json | 8 +- public/locales/en/campaigns.json | 6 + src/common/hooks/donationWish.ts | 12 +- .../client/campaigns/DonationWishes.tsx | 148 ++++++++++++++---- src/gql/donationWish.d.ts | 1 + src/gql/types.d.ts | 5 + src/service/apiEndpoints.ts | 19 ++- 7 files changed, 158 insertions(+), 41 deletions(-) diff --git a/public/locales/bg/campaigns.json b/public/locales/bg/campaigns.json index 7698020de..130c93815 100644 --- a/public/locales/bg/campaigns.json +++ b/public/locales/bg/campaigns.json @@ -95,7 +95,13 @@ "others": "други", "profile": "Профил:", "status": "Статус:", - "messages": "Послания:", + "messages": "Кампанията подкрепиха:", + "sort": { + "title" : "Сортирай:", + "date" : "Дата", + "amount": "Дарение", + "search": "Търси..." + }, "gallery": "Галерия", "report-irregularity": "Сигнализирай за злоупотреба", "financial-report": "Финансови отчети", diff --git a/public/locales/en/campaigns.json b/public/locales/en/campaigns.json index effe64cde..91e58f66e 100644 --- a/public/locales/en/campaigns.json +++ b/public/locales/en/campaigns.json @@ -89,6 +89,12 @@ "guarantor": "guarantor", "others": "others", "messages": "Messages:", + "sort": { + "title" : "Sort:", + "date" : "Date", + "amount": "Amount", + "search": "Search..." + }, "profile": "Profile:", "status": "Status:", "gallery": "Gallery", diff --git a/src/common/hooks/donationWish.ts b/src/common/hooks/donationWish.ts index 3a325f051..724d075b9 100644 --- a/src/common/hooks/donationWish.ts +++ b/src/common/hooks/donationWish.ts @@ -3,10 +3,18 @@ import { useQuery } from '@tanstack/react-query' import { endpoints } from 'service/apiEndpoints' import { DonationWishPaginatedResponse } from 'gql/donationWish' +import { PaginationData, SortData } from 'gql/types' -export function useDonationWishesList(camapignId: string, pageIndex?: number, pageSize?: number) { +export function useDonationWishesList( + campaignId: string, + paginationData?: PaginationData, + sort?: SortData, + searchData?: string, +) { return useQuery({ - queryKey: [endpoints.donationWish.listDonationWishes(camapignId, pageIndex, pageSize).url], + queryKey: [ + endpoints.donationWish.listDonationWishes(campaignId, paginationData, sort, searchData).url, + ], keepPreviousData: true, }) } diff --git a/src/components/client/campaigns/DonationWishes.tsx b/src/components/client/campaigns/DonationWishes.tsx index 0c11b74d6..1467be60b 100644 --- a/src/components/client/campaigns/DonationWishes.tsx +++ b/src/components/client/campaigns/DonationWishes.tsx @@ -2,29 +2,64 @@ import React, { useRef, useState } from 'react' import { useTranslation } from 'next-i18next' -import { Unstable_Grid2 as Grid2, Stack, Typography, Grid } from '@mui/material' -import RateReviewIcon from '@mui/icons-material/RateReview' +import { + Unstable_Grid2 as Grid2, + Stack, + Typography, + Grid, + Button, + TextField, + InputAdornment, +} from '@mui/material' +import SearchIcon from '@mui/icons-material/Search' +import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp' +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' import AccountCircleIcon from '@mui/icons-material/AccountCircle' import Pagination from '@mui/material/Pagination' import { bg, enUS } from 'date-fns/locale' +import { moneyPublic } from 'common/util/money' import { useDonationWishesList } from 'common/hooks/donationWish' import { getExactDate } from 'common/util/date' import theme from 'common/theme' +import { SortData } from 'gql/types' + +type SortButton = { + label: string + value: string +} type Props = { campaignId: string pageSize?: number } -export default function DonationWishes({ campaignId, pageSize = 12 }: Props) { +export default function DonationWishes({ campaignId, pageSize = 5 }: Props) { const { t, i18n } = useTranslation('campaigns') const locale = i18n.language == 'bg' ? bg : enUS const titleRef = useRef(null) const [pageIndex, setPageIndex] = useState(0) - const { data, isSuccess } = useDonationWishesList(campaignId, pageIndex, pageSize) + + const [sort, setSort] = useState({ + sortBy: 'createdAt', + sortOrder: 'desc', + }) + + const { data, isSuccess, refetch } = useDonationWishesList( + campaignId, + { pageIndex, pageSize }, + sort, + ) const numOfPages = isSuccess && data ? Math.ceil(data.totalCount / pageSize) : 0 + const handleSort = (value: string) => { + setSort((sort) => ({ + sortBy: value, + sortOrder: sort.sortBy === value ? (sort.sortOrder === 'desc' ? 'asc' : 'desc') : 'desc', + })) + refetch() + } + const handlePageChange = (_e: React.ChangeEvent, page: number) => { // 's impl is 1 index based // Our pagination apis are 0 index based @@ -37,37 +72,73 @@ export default function DonationWishes({ campaignId, pageSize = 12 }: Props) { } } + const sortButtons: SortButton[] = [ + { + label: t('campaign.sort.date'), + value: 'createdAt', + }, + { + label: t('campaign.sort.amount'), + value: 'amount', + }, + ] + return ( + + {t('campaign.messages')} + - - {t('campaign.messages')} + {t('campaign.sort.title')} + {sortButtons.map(({ label, value }) => ( + + ))} + + + + ), + }} + variant="outlined" + /> {isSuccess && - data && - data.items && - data.items.map((wish) => ( + data?.items?.map(({ id, person, donation, message, createdAt }) => ( @@ -86,18 +157,29 @@ export default function DonationWishes({ campaignId, pageSize = 12 }: Props) { fontSize: theme.typography.pxToRem(16), color: theme.palette.grey[800], }}> - {wish.person - ? wish.person.firstName + ' ' + wish.person.lastName - : t('donations.anonymous')} - - - {getExactDate(wish.createdAt, locale)} + {person ? person.firstName + ' ' + person.lastName : t('donations.anonymous')} + + {donation && ( + + {moneyPublic(donation.amount, donation.currency)} + + )} + + {getExactDate(createdAt, locale)} + + - {wish.message} + {message} diff --git a/src/gql/donationWish.d.ts b/src/gql/donationWish.d.ts index 4731692ba..30443a1cb 100644 --- a/src/gql/donationWish.d.ts +++ b/src/gql/donationWish.d.ts @@ -12,6 +12,7 @@ export type DonationWishResponse = { donationId?: UUID personId?: UUID person?: { firstName: string; lastName: string } + donation?: { amount: number; currency: string } createdAt: DateTime } diff --git a/src/gql/types.d.ts b/src/gql/types.d.ts index 760a0ec5a..a0841a88e 100644 --- a/src/gql/types.d.ts +++ b/src/gql/types.d.ts @@ -5,6 +5,11 @@ export type PaginationData = { pageSize: number } +export type SortData = { + sortBy: string + sortOrder: string +} + export type FilterData = { status: DonationStatus paymentProvider: PaymentProvider diff --git a/src/service/apiEndpoints.ts b/src/service/apiEndpoints.ts index a1c387aa6..e24a206fd 100644 --- a/src/service/apiEndpoints.ts +++ b/src/service/apiEndpoints.ts @@ -1,6 +1,6 @@ import { Method } from 'axios' import { DonationStatus } from 'gql/donations.enums' -import { FilterData, PaginationData } from 'gql/types' +import { FilterData, PaginationData, SortData } from 'gql/types' type Endpoint = { url: string @@ -308,10 +308,19 @@ export const endpoints = { }, donationWish: { createDonationWish: { url: '/donation-wish', method: 'POST' }, - listDonationWishes: (campaignId?: string, pageIndex?: number, pageSize?: number) => - { - url: `/donation-wish/list/${campaignId}?pageindex=${pageIndex}&pagesize=${pageSize}`, + listDonationWishes: ( + campaignId?: string, + paginationData?: PaginationData, + sort?: SortData, + searchData?: string, + ) => { + const { pageIndex, pageSize } = (paginationData as PaginationData) || {} + const { sortBy, sortOrder } = (sort as SortData) || {} + + return { + url: `/donation-wish/list/${campaignId}?pageindex=${pageIndex}&pagesize=${pageSize}&search=${searchData}&sortBy=${sortBy}&sortOrder=${sortOrder}`, method: 'GET', - }, + } + }, }, } From 926ba9a0394c295ff1ccae25152bc349933ba387 Mon Sep 17 00:00:00 2001 From: tongo Date: Mon, 7 Aug 2023 14:28:16 +0300 Subject: [PATCH 2/3] search donation wishes --- public/locales/bg/campaigns.json | 3 +- public/locales/en/campaigns.json | 3 +- .../client/campaigns/DonationWishes.tsx | 30 +++++++++++++++---- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/public/locales/bg/campaigns.json b/public/locales/bg/campaigns.json index 130c93815..f5e6d863b 100644 --- a/public/locales/bg/campaigns.json +++ b/public/locales/bg/campaigns.json @@ -100,7 +100,8 @@ "title" : "Сортирай:", "date" : "Дата", "amount": "Дарение", - "search": "Търси..." + "search": "Търси...", + "noResults": "Не са открити резултати" }, "gallery": "Галерия", "report-irregularity": "Сигнализирай за злоупотреба", diff --git a/public/locales/en/campaigns.json b/public/locales/en/campaigns.json index 91e58f66e..7bd9d5b95 100644 --- a/public/locales/en/campaigns.json +++ b/public/locales/en/campaigns.json @@ -93,7 +93,8 @@ "title" : "Sort:", "date" : "Date", "amount": "Amount", - "search": "Search..." + "search": "Search...", + "noResults": "No messages found" }, "profile": "Profile:", "status": "Status:", diff --git a/src/components/client/campaigns/DonationWishes.tsx b/src/components/client/campaigns/DonationWishes.tsx index 1467be60b..c1b72d725 100644 --- a/src/components/client/campaigns/DonationWishes.tsx +++ b/src/components/client/campaigns/DonationWishes.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState } from 'react' +import React, { useMemo, useRef, useState } from 'react' import { useTranslation } from 'next-i18next' @@ -23,6 +23,7 @@ import { useDonationWishesList } from 'common/hooks/donationWish' import { getExactDate } from 'common/util/date' import theme from 'common/theme' import { SortData } from 'gql/types' +import { debounce } from 'lodash' type SortButton = { label: string @@ -39,16 +40,18 @@ export default function DonationWishes({ campaignId, pageSize = 5 }: Props) { const locale = i18n.language == 'bg' ? bg : enUS const titleRef = useRef(null) const [pageIndex, setPageIndex] = useState(0) + const [searchValue, setSearchValue] = useState('') const [sort, setSort] = useState({ sortBy: 'createdAt', sortOrder: 'desc', }) - const { data, isSuccess, refetch } = useDonationWishesList( + const { data, isSuccess } = useDonationWishesList( campaignId, { pageIndex, pageSize }, sort, + searchValue, ) const numOfPages = isSuccess && data ? Math.ceil(data.totalCount / pageSize) : 0 @@ -57,9 +60,14 @@ export default function DonationWishes({ campaignId, pageSize = 5 }: Props) { sortBy: value, sortOrder: sort.sortBy === value ? (sort.sortOrder === 'desc' ? 'asc' : 'desc') : 'desc', })) - refetch() } + const handleSearch = (event: React.ChangeEvent) => { + setSearchValue(event.target.value) + } + + const debounceSearch = useMemo(() => debounce(handleSearch, 300), []) + const handlePageChange = (_e: React.ChangeEvent, page: number) => { // 's impl is 1 index based // Our pagination apis are 0 index based @@ -94,13 +102,18 @@ export default function DonationWishes({ campaignId, pageSize = 5 }: Props) { }}> {t('campaign.messages')} - + {t('campaign.sort.title')} @@ -112,7 +125,6 @@ export default function DonationWishes({ campaignId, pageSize = 5 }: Props) { sx={{ fontSize: theme.typography.pxToRem(14), color: 'rgba(0, 0, 0, 0.54)', - '&:after': { content: '"|"', paddingX: '1rem' }, }}> {label} {sort.sortBy === value && @@ -130,6 +142,7 @@ export default function DonationWishes({ campaignId, pageSize = 5 }: Props) { ), }} variant="outlined" + onChange={debounceSearch} /> @@ -196,6 +209,11 @@ export default function DonationWishes({ campaignId, pageSize = 5 }: Props) { ))} + + {data?.items?.length === 0 && searchValue !== '' && ( + {t('campaign.sort.noResults')} + )} + {numOfPages > 1 && ( Date: Tue, 8 Aug 2023 12:31:39 +0300 Subject: [PATCH 3/3] update sort label --- public/locales/bg/campaigns.json | 2 +- public/locales/en/campaigns.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/locales/bg/campaigns.json b/public/locales/bg/campaigns.json index f5e6d863b..2d073f6fd 100644 --- a/public/locales/bg/campaigns.json +++ b/public/locales/bg/campaigns.json @@ -97,7 +97,7 @@ "status": "Статус:", "messages": "Кампанията подкрепиха:", "sort": { - "title" : "Сортирай:", + "title" : "Сортирай по:", "date" : "Дата", "amount": "Дарение", "search": "Търси...", diff --git a/public/locales/en/campaigns.json b/public/locales/en/campaigns.json index 7bd9d5b95..5d67ea5c2 100644 --- a/public/locales/en/campaigns.json +++ b/public/locales/en/campaigns.json @@ -90,7 +90,7 @@ "others": "others", "messages": "Messages:", "sort": { - "title" : "Sort:", + "title" : "Sort by:", "date" : "Date", "amount": "Amount", "search": "Search...",