@hed-hog/contact 0.0.279 → 0.0.286
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/contact.service.d.ts +2 -148
- package/dist/contact.service.d.ts.map +1 -1
- package/dist/person/dto/create-followup.dto.d.ts +5 -0
- package/dist/person/dto/create-followup.dto.d.ts.map +1 -0
- package/dist/person/dto/create-followup.dto.js +31 -0
- package/dist/person/dto/create-followup.dto.js.map +1 -0
- package/dist/person/dto/create-interaction.dto.d.ts +12 -0
- package/dist/person/dto/create-interaction.dto.d.ts.map +1 -0
- package/dist/person/dto/create-interaction.dto.js +39 -0
- package/dist/person/dto/create-interaction.dto.js.map +1 -0
- package/dist/person/dto/create.dto.d.ts +24 -0
- package/dist/person/dto/create.dto.d.ts.map +1 -1
- package/dist/person/dto/create.dto.js +56 -1
- package/dist/person/dto/create.dto.js.map +1 -1
- package/dist/person/dto/duplicates-query.dto.d.ts +8 -0
- package/dist/person/dto/duplicates-query.dto.d.ts.map +1 -0
- package/dist/person/dto/duplicates-query.dto.js +45 -0
- package/dist/person/dto/duplicates-query.dto.js.map +1 -0
- package/dist/person/dto/merge.dto.d.ts +6 -0
- package/dist/person/dto/merge.dto.d.ts.map +1 -0
- package/dist/person/dto/merge.dto.js +35 -0
- package/dist/person/dto/merge.dto.js.map +1 -0
- package/dist/person/dto/update-lifecycle-stage.dto.d.ts +13 -0
- package/dist/person/dto/update-lifecycle-stage.dto.d.ts.map +1 -0
- package/dist/person/dto/update-lifecycle-stage.dto.js +34 -0
- package/dist/person/dto/update-lifecycle-stage.dto.js.map +1 -0
- package/dist/person/dto/update.dto.d.ts +8 -1
- package/dist/person/dto/update.dto.d.ts.map +1 -1
- package/dist/person/dto/update.dto.js +36 -0
- package/dist/person/dto/update.dto.js.map +1 -1
- package/dist/person/person.controller.d.ts +57 -1
- package/dist/person/person.controller.d.ts.map +1 -1
- package/dist/person/person.controller.js +85 -3
- package/dist/person/person.controller.js.map +1 -1
- package/dist/person/person.service.d.ts +79 -0
- package/dist/person/person.service.d.ts.map +1 -1
- package/dist/person/person.service.js +730 -9
- package/dist/person/person.service.js.map +1 -1
- package/hedhog/data/route.yaml +18 -0
- package/hedhog/frontend/app/_components/crm-coming-soon.tsx.ejs +110 -110
- package/hedhog/frontend/app/_components/crm-nav.tsx.ejs +73 -73
- package/hedhog/frontend/app/_lib/crm-mocks.ts.ejs +498 -256
- package/hedhog/frontend/app/_lib/crm-sections.tsx.ejs +81 -81
- package/hedhog/frontend/app/accounts/_components/account-form-sheet.tsx.ejs +477 -0
- package/hedhog/frontend/app/accounts/_components/account-types.ts.ejs +62 -0
- package/hedhog/frontend/app/accounts/page.tsx.ejs +892 -15
- package/hedhog/frontend/app/activities/page.tsx.ejs +812 -15
- package/hedhog/frontend/app/contact-type/page.tsx.ejs +105 -91
- package/hedhog/frontend/app/dashboard/page.tsx.ejs +491 -573
- package/hedhog/frontend/app/document-type/page.tsx.ejs +105 -91
- package/hedhog/frontend/app/follow-ups/page.tsx.ejs +696 -15
- package/hedhog/frontend/app/page.tsx.ejs +5 -5
- package/hedhog/frontend/app/person/_components/person-form-sheet.tsx.ejs +1440 -1103
- package/hedhog/frontend/app/person/_components/person-interaction-dialog.tsx.ejs +4 -3
- package/hedhog/frontend/app/person/_components/person-types.ts.ejs +14 -0
- package/hedhog/frontend/app/person/page.tsx.ejs +112 -190
- package/hedhog/frontend/app/pipeline/_components/lead-detail-sheet.tsx.ejs +599 -0
- package/hedhog/frontend/app/pipeline/page.tsx.ejs +1048 -299
- package/hedhog/frontend/app/reports/page.tsx.ejs +15 -15
- package/hedhog/frontend/messages/en.json +268 -0
- package/hedhog/frontend/messages/pt.json +233 -0
- package/package.json +6 -6
- package/src/contact.service.ts +2 -2
- package/src/person/dto/create-followup.dto.ts +15 -0
- package/src/person/dto/create-interaction.dto.ts +23 -0
- package/src/person/dto/create.dto.ts +50 -0
- package/src/person/dto/duplicates-query.dto.ts +34 -0
- package/src/person/dto/merge.dto.ts +15 -0
- package/src/person/dto/update-lifecycle-stage.dto.ts +19 -0
- package/src/person/dto/update.dto.ts +31 -1
- package/src/person/person.controller.ts +63 -2
- package/src/person/person.service.ts +1096 -7
|
@@ -119,9 +119,10 @@ export function PersonInteractionDialog({
|
|
|
119
119
|
try {
|
|
120
120
|
setIsSubmitting(true);
|
|
121
121
|
await request({
|
|
122
|
-
url: `/person/${person.id}`,
|
|
123
|
-
method: '
|
|
124
|
-
data:
|
|
122
|
+
url: `/person/${person.id}/followup`,
|
|
123
|
+
method: 'POST',
|
|
124
|
+
data: values,
|
|
125
|
+
showErrors: false,
|
|
125
126
|
});
|
|
126
127
|
toast.success(t('followupSuccess'));
|
|
127
128
|
onOpenChange(false);
|
|
@@ -128,6 +128,11 @@ export type Person = {
|
|
|
128
128
|
source?: PersonSource | null;
|
|
129
129
|
lifecycle_stage?: PersonLifecycleStage | null;
|
|
130
130
|
next_action_at?: string | null;
|
|
131
|
+
score?: number | null;
|
|
132
|
+
deal_value?: number | null;
|
|
133
|
+
tags?: string[] | null;
|
|
134
|
+
last_interaction_at?: string | null;
|
|
135
|
+
interaction_count?: number | null;
|
|
131
136
|
employer_company_id?: number | null;
|
|
132
137
|
employer_company?: PersonRelationSummary | null;
|
|
133
138
|
created_at: string;
|
|
@@ -136,6 +141,15 @@ export type Person = {
|
|
|
136
141
|
document?: PersonDocument[];
|
|
137
142
|
};
|
|
138
143
|
|
|
144
|
+
export type PersonInteraction = {
|
|
145
|
+
id: number;
|
|
146
|
+
type: PersonInteractionType;
|
|
147
|
+
notes?: string | null;
|
|
148
|
+
created_at: string;
|
|
149
|
+
user_id?: number | null;
|
|
150
|
+
user_name?: string | null;
|
|
151
|
+
};
|
|
152
|
+
|
|
139
153
|
export type ContactTypeOption = {
|
|
140
154
|
id: number;
|
|
141
155
|
code: string;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { CrmNav } from '../_components/crm-nav';
|
|
4
3
|
import { CopyButton } from '@/components/copy-button';
|
|
5
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
EmptyState,
|
|
6
|
+
Page,
|
|
7
|
+
PageHeader,
|
|
8
|
+
PaginationFooter,
|
|
9
|
+
SearchBar,
|
|
10
|
+
type SearchBarControl,
|
|
11
|
+
} from '@/components/entity-list';
|
|
6
12
|
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
|
7
13
|
import { Badge } from '@/components/ui/badge';
|
|
8
14
|
import { Button } from '@/components/ui/button';
|
|
@@ -14,14 +20,7 @@ import {
|
|
|
14
20
|
DropdownMenuSeparator,
|
|
15
21
|
DropdownMenuTrigger,
|
|
16
22
|
} from '@/components/ui/dropdown-menu';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
Select,
|
|
20
|
-
SelectContent,
|
|
21
|
-
SelectItem,
|
|
22
|
-
SelectTrigger,
|
|
23
|
-
SelectValue,
|
|
24
|
-
} from '@/components/ui/select';
|
|
23
|
+
import { KpiCardsGrid } from '@/components/ui/kpi-cards-grid';
|
|
25
24
|
import { Skeleton } from '@/components/ui/skeleton';
|
|
26
25
|
import {
|
|
27
26
|
Table,
|
|
@@ -48,10 +47,6 @@ import {
|
|
|
48
47
|
Building2,
|
|
49
48
|
CalendarDays,
|
|
50
49
|
CheckCircle2,
|
|
51
|
-
ChevronLeft,
|
|
52
|
-
ChevronRight,
|
|
53
|
-
ChevronsLeft,
|
|
54
|
-
ChevronsRight,
|
|
55
50
|
FileText,
|
|
56
51
|
LayoutGrid,
|
|
57
52
|
List,
|
|
@@ -61,7 +56,6 @@ import {
|
|
|
61
56
|
Pencil,
|
|
62
57
|
Phone,
|
|
63
58
|
Plus,
|
|
64
|
-
Search,
|
|
65
59
|
Trash2,
|
|
66
60
|
User,
|
|
67
61
|
UserCheck,
|
|
@@ -718,6 +712,78 @@ export default function PeoplePage() {
|
|
|
718
712
|
|
|
719
713
|
const peopleRows = table.getRowModel().rows;
|
|
720
714
|
|
|
715
|
+
const statsCards = [
|
|
716
|
+
{
|
|
717
|
+
key: 'total',
|
|
718
|
+
title: t('statsTotal'),
|
|
719
|
+
value: stats.total,
|
|
720
|
+
icon: Users,
|
|
721
|
+
accentClassName: 'from-slate-500/20 via-slate-400/10 to-transparent',
|
|
722
|
+
iconContainerClassName: 'bg-slate-100 text-slate-700',
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
key: 'active',
|
|
726
|
+
title: t('statsActive'),
|
|
727
|
+
value: stats.active,
|
|
728
|
+
icon: CheckCircle2,
|
|
729
|
+
accentClassName: 'from-green-500/20 via-emerald-500/10 to-transparent',
|
|
730
|
+
iconContainerClassName: 'bg-green-50 text-green-600',
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
key: 'individual',
|
|
734
|
+
title: t('statsIndividual'),
|
|
735
|
+
value: stats.individual,
|
|
736
|
+
icon: UserCheck,
|
|
737
|
+
accentClassName: 'from-blue-500/20 via-cyan-500/10 to-transparent',
|
|
738
|
+
iconContainerClassName: 'bg-blue-50 text-blue-600',
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
key: 'company',
|
|
742
|
+
title: t('statsCompany'),
|
|
743
|
+
value: stats.company,
|
|
744
|
+
icon: Building2,
|
|
745
|
+
accentClassName: 'from-amber-500/20 via-orange-500/10 to-transparent',
|
|
746
|
+
iconContainerClassName: 'bg-amber-50 text-amber-600',
|
|
747
|
+
},
|
|
748
|
+
];
|
|
749
|
+
|
|
750
|
+
const searchControls: SearchBarControl[] = [
|
|
751
|
+
...(allowCompanyRegistration
|
|
752
|
+
? [
|
|
753
|
+
{
|
|
754
|
+
id: 'type-filter',
|
|
755
|
+
type: 'select' as const,
|
|
756
|
+
value: typeFilter,
|
|
757
|
+
onChange: (value: string) => {
|
|
758
|
+
setTypeFilter(value);
|
|
759
|
+
setPage(1);
|
|
760
|
+
},
|
|
761
|
+
placeholder: t('filterByType'),
|
|
762
|
+
options: [
|
|
763
|
+
{ value: 'all', label: t('allTypes') },
|
|
764
|
+
{ value: 'individual', label: t('individual') },
|
|
765
|
+
{ value: 'company', label: t('company') },
|
|
766
|
+
],
|
|
767
|
+
},
|
|
768
|
+
]
|
|
769
|
+
: []),
|
|
770
|
+
{
|
|
771
|
+
id: 'status-filter',
|
|
772
|
+
type: 'select',
|
|
773
|
+
value: statusFilter,
|
|
774
|
+
onChange: (value: string) => {
|
|
775
|
+
setStatusFilter(value);
|
|
776
|
+
setPage(1);
|
|
777
|
+
},
|
|
778
|
+
placeholder: t('filterByStatus'),
|
|
779
|
+
options: [
|
|
780
|
+
{ value: 'all', label: t('allStatuses') },
|
|
781
|
+
{ value: 'active', label: t('active') },
|
|
782
|
+
{ value: 'inactive', label: t('inactive') },
|
|
783
|
+
],
|
|
784
|
+
},
|
|
785
|
+
];
|
|
786
|
+
|
|
721
787
|
return (
|
|
722
788
|
<Page>
|
|
723
789
|
<PageHeader
|
|
@@ -745,104 +811,26 @@ export default function PeoplePage() {
|
|
|
745
811
|
]}
|
|
746
812
|
/>
|
|
747
813
|
|
|
748
|
-
<
|
|
749
|
-
|
|
750
|
-
<div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
|
|
751
|
-
<Card className="py-0">
|
|
752
|
-
<CardContent className="flex items-center justify-between p-4">
|
|
753
|
-
<div>
|
|
754
|
-
<p className="text-xs text-muted-foreground">{t('statsTotal')}</p>
|
|
755
|
-
<p className="text-xl font-semibold">{stats.total}</p>
|
|
756
|
-
</div>
|
|
757
|
-
<Users className="h-5 w-5 text-muted-foreground" />
|
|
758
|
-
</CardContent>
|
|
759
|
-
</Card>
|
|
760
|
-
<Card className="py-0">
|
|
761
|
-
<CardContent className="flex items-center justify-between p-4">
|
|
762
|
-
<div>
|
|
763
|
-
<p className="text-xs text-muted-foreground">
|
|
764
|
-
{t('statsActive')}
|
|
765
|
-
</p>
|
|
766
|
-
<p className="text-xl font-semibold">{stats.active}</p>
|
|
767
|
-
</div>
|
|
768
|
-
<CheckCircle2 className="h-5 w-5 text-green-600" />
|
|
769
|
-
</CardContent>
|
|
770
|
-
</Card>
|
|
771
|
-
<Card className="py-0">
|
|
772
|
-
<CardContent className="flex items-center justify-between p-4">
|
|
773
|
-
<div>
|
|
774
|
-
<p className="text-xs text-muted-foreground">
|
|
775
|
-
{t('statsIndividual')}
|
|
776
|
-
</p>
|
|
777
|
-
<p className="text-xl font-semibold">{stats.individual}</p>
|
|
778
|
-
</div>
|
|
779
|
-
<UserCheck className="h-5 w-5 text-blue-600" />
|
|
780
|
-
</CardContent>
|
|
781
|
-
</Card>
|
|
782
|
-
<Card className="py-0">
|
|
783
|
-
<CardContent className="flex items-center justify-between p-4">
|
|
784
|
-
<div>
|
|
785
|
-
<p className="text-xs text-muted-foreground">
|
|
786
|
-
{t('statsCompany')}
|
|
787
|
-
</p>
|
|
788
|
-
<p className="text-xl font-semibold">{stats.company}</p>
|
|
789
|
-
</div>
|
|
790
|
-
<Building2 className="h-5 w-5 text-amber-600" />
|
|
791
|
-
</CardContent>
|
|
792
|
-
</Card>
|
|
793
|
-
</div>
|
|
814
|
+
<KpiCardsGrid items={statsCards} />
|
|
794
815
|
|
|
795
816
|
<div className="flex flex-col gap-4 xl:flex-row xl:items-center">
|
|
796
|
-
<div className="
|
|
797
|
-
<
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
setSearchInput(event.target.value);
|
|
817
|
+
<div className="flex-1">
|
|
818
|
+
<SearchBar
|
|
819
|
+
searchQuery={searchInput}
|
|
820
|
+
onSearchChange={(value) => {
|
|
821
|
+
setSearchInput(value);
|
|
802
822
|
setPage(1);
|
|
803
823
|
}}
|
|
824
|
+
onSearch={() => {
|
|
825
|
+
setPage(1);
|
|
826
|
+
void refetch();
|
|
827
|
+
}}
|
|
804
828
|
placeholder={t('searchByNamePlaceholder')}
|
|
805
|
-
|
|
829
|
+
controls={searchControls}
|
|
806
830
|
/>
|
|
807
831
|
</div>
|
|
808
832
|
|
|
809
833
|
<div className="flex flex-col gap-2 sm:flex-row sm:flex-wrap xl:justify-end">
|
|
810
|
-
{allowCompanyRegistration ? (
|
|
811
|
-
<Select
|
|
812
|
-
value={typeFilter}
|
|
813
|
-
onValueChange={(value) => {
|
|
814
|
-
setTypeFilter(value);
|
|
815
|
-
setPage(1);
|
|
816
|
-
}}
|
|
817
|
-
>
|
|
818
|
-
<SelectTrigger className="w-full sm:w-44">
|
|
819
|
-
<SelectValue placeholder={t('filterByType')} />
|
|
820
|
-
</SelectTrigger>
|
|
821
|
-
<SelectContent>
|
|
822
|
-
<SelectItem value="all">{t('allTypes')}</SelectItem>
|
|
823
|
-
<SelectItem value="individual">{t('individual')}</SelectItem>
|
|
824
|
-
<SelectItem value="company">{t('company')}</SelectItem>
|
|
825
|
-
</SelectContent>
|
|
826
|
-
</Select>
|
|
827
|
-
) : null}
|
|
828
|
-
|
|
829
|
-
<Select
|
|
830
|
-
value={statusFilter}
|
|
831
|
-
onValueChange={(value) => {
|
|
832
|
-
setStatusFilter(value);
|
|
833
|
-
setPage(1);
|
|
834
|
-
}}
|
|
835
|
-
>
|
|
836
|
-
<SelectTrigger className="w-full sm:w-36">
|
|
837
|
-
<SelectValue placeholder={t('filterByStatus')} />
|
|
838
|
-
</SelectTrigger>
|
|
839
|
-
<SelectContent>
|
|
840
|
-
<SelectItem value="all">{t('allStatuses')}</SelectItem>
|
|
841
|
-
<SelectItem value="active">{t('active')}</SelectItem>
|
|
842
|
-
<SelectItem value="inactive">{t('inactive')}</SelectItem>
|
|
843
|
-
</SelectContent>
|
|
844
|
-
</Select>
|
|
845
|
-
|
|
846
834
|
<div className="flex items-center justify-between gap-3 sm:justify-start">
|
|
847
835
|
<span className="text-xs font-medium text-muted-foreground">
|
|
848
836
|
{t('viewMode')}
|
|
@@ -908,17 +896,14 @@ export default function PeoplePage() {
|
|
|
908
896
|
</div>
|
|
909
897
|
)
|
|
910
898
|
) : paginate.data.length === 0 ? (
|
|
911
|
-
<
|
|
912
|
-
<Users className="
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
{t('newPerson')}
|
|
920
|
-
</Button>
|
|
921
|
-
</div>
|
|
899
|
+
<EmptyState
|
|
900
|
+
icon={<Users className="h-12 w-12" />}
|
|
901
|
+
title={t('emptyStateTitle')}
|
|
902
|
+
description={t('emptyStateDescription')}
|
|
903
|
+
actionLabel={t('newPerson')}
|
|
904
|
+
actionIcon={<Plus className="mr-2 h-4 w-4" />}
|
|
905
|
+
onAction={openCreateSheet}
|
|
906
|
+
/>
|
|
922
907
|
) : (
|
|
923
908
|
<>
|
|
924
909
|
{viewMode === 'table' ? (
|
|
@@ -1230,81 +1215,18 @@ export default function PeoplePage() {
|
|
|
1230
1215
|
</div>
|
|
1231
1216
|
)}
|
|
1232
1217
|
|
|
1233
|
-
<div className="
|
|
1234
|
-
<
|
|
1235
|
-
{
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
onValueChange={(value) => {
|
|
1246
|
-
setPageSize(Number(value));
|
|
1247
|
-
setPage(1);
|
|
1248
|
-
}}
|
|
1249
|
-
>
|
|
1250
|
-
<SelectTrigger className="w-20">
|
|
1251
|
-
<SelectValue />
|
|
1252
|
-
</SelectTrigger>
|
|
1253
|
-
<SelectContent>
|
|
1254
|
-
{[12, 20, 30, 40, 50].map((size) => (
|
|
1255
|
-
<SelectItem key={size} value={String(size)}>
|
|
1256
|
-
{size}
|
|
1257
|
-
</SelectItem>
|
|
1258
|
-
))}
|
|
1259
|
-
</SelectContent>
|
|
1260
|
-
</Select>
|
|
1261
|
-
</div>
|
|
1262
|
-
|
|
1263
|
-
<div className="flex items-center gap-2">
|
|
1264
|
-
<Button
|
|
1265
|
-
variant="outline"
|
|
1266
|
-
size="icon"
|
|
1267
|
-
onClick={() => setPage(1)}
|
|
1268
|
-
disabled={page <= 1}
|
|
1269
|
-
>
|
|
1270
|
-
<ChevronsLeft className="h-4 w-4" />
|
|
1271
|
-
</Button>
|
|
1272
|
-
<Button
|
|
1273
|
-
variant="outline"
|
|
1274
|
-
size="icon"
|
|
1275
|
-
onClick={() =>
|
|
1276
|
-
setPage((previous) => Math.max(1, previous - 1))
|
|
1277
|
-
}
|
|
1278
|
-
disabled={page <= 1}
|
|
1279
|
-
>
|
|
1280
|
-
<ChevronLeft className="h-4 w-4" />
|
|
1281
|
-
</Button>
|
|
1282
|
-
<span className="min-w-32 text-center text-sm">
|
|
1283
|
-
{t('paginationLabel', {
|
|
1284
|
-
current: page,
|
|
1285
|
-
total: pageCount,
|
|
1286
|
-
})}
|
|
1287
|
-
</span>
|
|
1288
|
-
<Button
|
|
1289
|
-
variant="outline"
|
|
1290
|
-
size="icon"
|
|
1291
|
-
onClick={() =>
|
|
1292
|
-
setPage((previous) => Math.min(pageCount, previous + 1))
|
|
1293
|
-
}
|
|
1294
|
-
disabled={page >= pageCount}
|
|
1295
|
-
>
|
|
1296
|
-
<ChevronRight className="h-4 w-4" />
|
|
1297
|
-
</Button>
|
|
1298
|
-
<Button
|
|
1299
|
-
variant="outline"
|
|
1300
|
-
size="icon"
|
|
1301
|
-
onClick={() => setPage(pageCount)}
|
|
1302
|
-
disabled={page >= pageCount}
|
|
1303
|
-
>
|
|
1304
|
-
<ChevronsRight className="h-4 w-4" />
|
|
1305
|
-
</Button>
|
|
1306
|
-
</div>
|
|
1307
|
-
</div>
|
|
1218
|
+
<div className="border-t p-4">
|
|
1219
|
+
<PaginationFooter
|
|
1220
|
+
currentPage={page}
|
|
1221
|
+
pageSize={pageSize}
|
|
1222
|
+
totalItems={paginate.total}
|
|
1223
|
+
onPageChange={setPage}
|
|
1224
|
+
onPageSizeChange={(nextPageSize) => {
|
|
1225
|
+
setPageSize(nextPageSize);
|
|
1226
|
+
setPage(1);
|
|
1227
|
+
}}
|
|
1228
|
+
pageSizeOptions={[12, 20, 30, 40, 50]}
|
|
1229
|
+
/>
|
|
1308
1230
|
</div>
|
|
1309
1231
|
</>
|
|
1310
1232
|
)}
|