feat: implement pluralization for client and session counts in ClientsPage and SessionsPage

This commit is contained in:
2025-06-18 18:34:59 +05:00
parent 4768ea62d2
commit d62a476172
3 changed files with 31 additions and 16 deletions
+13 -15
View File
@@ -4,16 +4,17 @@ import SpinIcon from "../components/icons/SpinIcon";
import MultySelect from "../components/MultySelect"; import MultySelect from "../components/MultySelect";
import SearchInput from "../components/SearchInput"; import SearchInput from "../components/SearchInput";
import { useState } from "react"; import { useState } from "react";
import { useDebounce } from "@uidotdev/usehooks";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { IUser } from "../types/User"; import { IUser } from "../types/User";
import api from "../utils/api"; import api from "../utils/api";
import { Client } from "../types/Client";
import pluralize from "../utils/pluralize";
function ClientsPage() { function ClientsPage() {
const [limit, setLimit] = useState(10); const [limit, setLimit] = useState(10);
const [search, setSearch] = useState<string | null>(null); const [search, setSearch] = useState<string | null>(null);
const debouncedSearch = useDebounce(search, 500); // const debouncedSearch = useDebounce(search, 500);
const { data: me } = useQuery({ const { data: me } = useQuery({
queryKey: ["me"], queryKey: ["me"],
@@ -22,13 +23,7 @@ function ClientsPage() {
const { data: clients, isLoading } = useQuery({ const { data: clients, isLoading } = useQuery({
queryKey: ["clients"], queryKey: ["clients"],
queryFn: () => api.get("clients").json<IUser[]>(), queryFn: () => api.get("clients").json<Client[]>(),
enabled: !!me,
});
const { data: count } = useQuery({
queryKey: ["clients", "count", debouncedSearch],
queryFn: () => api.get(`sessions/count?clients`).json<number>(),
enabled: !!me, enabled: !!me,
}); });
@@ -77,7 +72,10 @@ function ClientsPage() {
</div> </div>
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<p className="caption-m font-medium opacity-40"> <p className="caption-m font-medium opacity-40">
Найдено {count} клиентов Найдено{" "}
{clients?.length
? pluralize(clients?.length, "клиент")
: "0 клиентов"}
</p> </p>
<button className="flex gap-[0.278vw] items-center" onClick={reset}> <button className="flex gap-[0.278vw] items-center" onClick={reset}>
<div className="size-[1.111vw] text-[#7D7D7D]"> <div className="size-[1.111vw] text-[#7D7D7D]">
@@ -96,9 +94,9 @@ function ClientsPage() {
<SpinIcon /> <SpinIcon />
</div> </div>
) : clients?.length ? ( ) : clients?.length ? (
clients?.map(({ fullname }) => ( clients?.map(({ name }) => (
<div key={fullname} className="space-y-[0.833vw]"> <div key={name} className="space-y-[0.833vw]">
<p className="caption-m font-medium opacity-40">{fullname}</p> <p className="caption-m font-medium opacity-40">{name}</p>
</div> </div>
)) ))
) : ( ) : (
@@ -113,13 +111,13 @@ function ClientsPage() {
</div> </div>
)} )}
</div> </div>
{!!count && clients?.length === 0 && ( {!!clients?.length && clients?.length === 0 && (
<Button <Button
size="large" size="large"
variant="primary" variant="primary"
className="w-full" className="w-full"
onClick={() => setLimit((prev) => prev + 10)} onClick={() => setLimit((prev) => prev + 10)}
disabled={!!count && limit >= count} disabled={!!clients?.length && limit >= clients.length}
> >
Показать еще Показать еще
</Button> </Button>
+2 -1
View File
@@ -14,6 +14,7 @@ import Button from "../components/Button";
import SearchInput from "../components/SearchInput"; import SearchInput from "../components/SearchInput";
import CloseIcon from "../components/icons/CloseIcon"; import CloseIcon from "../components/icons/CloseIcon";
import SpinIcon from "../components/icons/SpinIcon"; import SpinIcon from "../components/icons/SpinIcon";
import pluralize from "../utils/pluralize";
function SessionsPage() { function SessionsPage() {
const [limit, setLimit] = useState(10); const [limit, setLimit] = useState(10);
@@ -118,7 +119,7 @@ function SessionsPage() {
</div> </div>
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<p className="caption-m font-medium opacity-40"> <p className="caption-m font-medium opacity-40">
Найдено {count} сеансов Найдено {count ? pluralize(count, "сеанс") : "0 сеансов"}
</p> </p>
<button className="flex gap-[0.278vw] items-center" onClick={reset}> <button className="flex gap-[0.278vw] items-center" onClick={reset}>
<div className="size-[1.111vw] text-[#7D7D7D]"> <div className="size-[1.111vw] text-[#7D7D7D]">
+16
View File
@@ -0,0 +1,16 @@
function pluralize(count: number, word: "клиент" | "сеанс"): string {
const cases = [2, 0, 1, 1, 1, 2];
const index =
count % 100 > 4 && count % 100 < 20
? 2
: cases[count % 10 < 5 ? count % 10 : 5];
const specialWords: Record<string, string[]> = {
клиент: ["клиент", "клиента", "клиентов"],
сеанс: ["сеанс", "сеанса", "сеансов"],
};
return `${count} ${specialWords[word][index]}`;
}
export default pluralize;