Skip to content

Commit 3303b16

Browse files
committed
Merge branch '19012025-wallet-context' of https://github.com/PotLock/potlock-nextjs-app into 19012025-wallet-context
2 parents 9fdc561 + 13825c0 commit 3303b16

12 files changed

+100
-111
lines changed

src/entities/list/components/AccountCard.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ interface StatusModal {
4242
status?: RegistrationStatus | string;
4343
}
4444

45-
// TODO: Rename to `ListAccountCard`!
46-
export const AccountCard = ({
45+
export const ListAccountCard = ({
4746
dataForList,
4847
accountsWithAccess,
4948
}: {

src/entities/list/components/ListAccounts.tsx

+29-45
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
/* eslint-disable prettier/prettier */
2-
import React, { useEffect, useState } from "react";
2+
import React, { useCallback, useEffect, useMemo, useState } from "react";
33

4-
import { List } from "@/common/api/indexer";
4+
import { List, ListRegistration } from "@/common/api/indexer";
55
import { Filter, Group, GroupType, SearchBar, SortSelect } from "@/common/ui/components";
66
import { ACCOUNT_LIST_REGISTRATION_STATUS_OPTIONS } from "@/entities/_shared";
77

8-
import { AccountCard } from "./AccountCard";
98
import { ListCardSkeleton } from "./ListCardSkeleton";
109
import { NoListItem } from "./NoListItem";
1110
import { NoListItemType } from "../types";
11+
import { ListAccountCard } from "./AccountCard";
1212

1313
interface ListAccountsType {
1414
loadingListData: boolean;
1515
listData: List | undefined;
16-
filteredRegistrations: any[];
16+
listRegistrations: ListRegistration[];
1717
isLoading: boolean;
18-
setFilteredRegistrations: (value: any) => void;
1918
setStatus: (value: string) => void;
2019
}
2120

@@ -24,15 +23,14 @@ export const ListAccounts = ({
2423
loadingListData,
2524
setStatus,
2625
isLoading,
27-
filteredRegistrations,
28-
setFilteredRegistrations,
26+
listRegistrations,
2927
}: ListAccountsType) => {
3028
const [search, setSearch] = useState("");
3129
const [accountsWithAccess, setAccountsWithAccess] = useState<string[]>([]);
3230
const [statusFilter, setsStatusFilter] = useState<string>("all");
33-
const [searchedAccounts, setSearchedAccounts] = useState<any[]>([]);
3431

35-
const SORT_LIST_PROJEECTS = [
32+
33+
const SORT_LIST_PROJECTS = [
3634
{ label: "Most recent", value: "recent" },
3735
{ label: "Least recent", value: "older" },
3836
];
@@ -52,7 +50,7 @@ export const ListAccounts = ({
5250
},
5351
];
5452

55-
const handleFilter = (registration: any) => {
53+
const handleFilter = (registration: ListRegistration) => {
5654
const matchesSearch = search
5755
? registration.registrant?.near_social_profile_data?.name
5856
?.toLowerCase()
@@ -63,37 +61,23 @@ export const ListAccounts = ({
6361
return matchesSearch;
6462
};
6563

66-
useEffect(() => {
67-
const filtered = filteredRegistrations.filter(handleFilter);
68-
setSearchedAccounts(filtered ?? []);
69-
}, [search]);
70-
71-
const handleSort = (sortType: string) => {
72-
const projects = [...filteredRegistrations];
73-
74-
switch (sortType) {
75-
case "recent":
76-
projects.sort(
77-
(a, b) =>
78-
new Date(b.submitted_at).getTime() -
79-
new Date(a.submitted_at).getTime(),
80-
);
81-
82-
setFilteredRegistrations(projects);
83-
break;
84-
case "older":
85-
projects.sort(
86-
(a, b) =>
87-
new Date(a.submitted_at).getTime() -
88-
new Date(b.submitted_at).getTime(),
89-
);
90-
91-
setFilteredRegistrations(projects);
92-
break;
93-
default:
94-
break;
95-
}
96-
};
64+
65+
const searchedAccounts = useMemo(() => {
66+
return listRegistrations.filter(handleFilter);
67+
}, [search, handleFilter])
68+
69+
const handleSort = useCallback((sortType: string) => {
70+
return [...listRegistrations].sort((a, b) => {
71+
switch (sortType) {
72+
case "recent":
73+
return new Date(b.submitted_at).getTime() - new Date(a.submitted_at).getTime();
74+
case "older":
75+
return new Date(a.submitted_at).getTime() - new Date(b.submitted_at).getTime();
76+
default:
77+
return 0; // No sorting
78+
}
79+
});
80+
}, [listRegistrations]);
9781

9882
useEffect(() => {
9983
if (!loadingListData && listData) {
@@ -106,7 +90,7 @@ export const ListAccounts = ({
10690
}
10791
}, [listData]);
10892

109-
const data = search ? searchedAccounts : filteredRegistrations ?? [];
93+
const data = search ? searchedAccounts : listRegistrations ?? [];
11094

11195
return (
11296
<div className="md:pb-0 md:pt-12 flex w-full flex-col px-2 pt-10">
@@ -117,7 +101,7 @@ export const ListAccounts = ({
117101
<span
118102
style={{ color: "#DD3345", marginLeft: "8px", fontWeight: 600 }}
119103
>
120-
{filteredRegistrations?.length}
104+
{listRegistrations?.length}
121105
</span>
122106
</div>
123107
</div>
@@ -128,7 +112,7 @@ export const ListAccounts = ({
128112
/>
129113
<Filter groups={tagsList} />
130114
<SortSelect
131-
options={SORT_LIST_PROJEECTS}
115+
options={SORT_LIST_PROJECTS}
132116
onValueChange={handleSort}
133117
/>
134118
</div>
@@ -142,7 +126,7 @@ export const ListAccounts = ({
142126
) : data?.length ? (
143127
<div className="md:grid-cols-2 lg:grid-cols-3 mt-8 grid w-full grid-cols-1 gap-8">
144128
{data?.map((item, index) => (
145-
<AccountCard
129+
<ListAccountCard
146130
accountsWithAccess={accountsWithAccess}
147131
dataForList={item}
148132
key={index}

src/entities/list/components/ListConfirmationModals.tsx

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
/* eslint-disable @next/next/no-img-element */
2-
import React, { useCallback, useEffect, useState } from "react";
2+
import React, { useEffect, useState } from "react";
33

44
import Image from "next/image";
5+
import Link from "next/link";
56

67
import { Button } from "@/common/ui/components";
78

89
interface SuccessModalProps {
910
isOpen: boolean;
1011
onClose: () => void;
1112
listName: string;
12-
onViewList: () => void;
1313
isUpdate: boolean;
14+
href: string;
1415
showBackToLists?: boolean;
1516
}
1617

@@ -20,7 +21,7 @@ export const SuccessModalCreateList: React.FC<SuccessModalProps> = ({
2021
listName,
2122
isUpdate,
2223
showBackToLists,
23-
onViewList,
24+
href,
2425
}) => {
2526
if (!isOpen) return null;
2627

@@ -46,17 +47,17 @@ export const SuccessModalCreateList: React.FC<SuccessModalProps> = ({
4647
</h2>
4748
<p className="mb-6 text-center text-gray-700">
4849
You’ve successfully {isUpdate ? "Updated" : "Deployed"} {listName}, you can always make
49-
adjustments in the pot settings page.
50+
adjustments in the list settings page.
5051
</p>
51-
<button
52-
onClick={() => {
53-
onViewList();
54-
onClose();
55-
}}
56-
className="w-full rounded-md bg-red-500 px-4 py-2 font-semibold text-white transition hover:bg-red-600"
57-
>
58-
{showBackToLists ? "Back to lists" : "View list"}
59-
</button>
52+
<Button asChild>
53+
<Link
54+
href={href}
55+
onClick={onClose}
56+
aria-label={showBackToLists ? "Navigate back to lists page" : "View the created list"}
57+
>
58+
{showBackToLists ? "Back to lists" : "View list"}
59+
</Link>
60+
</Button>
6061
</div>
6162
</div>
6263
</div>

src/entities/list/components/ListDetails.tsx

+4-8
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,12 @@ interface ListDetailsType {
4040
setAdmins: (value: string[]) => void;
4141
listDetails: List | any;
4242
savedUsers: SavedUsersType;
43+
listId: number;
4344
}
4445

45-
export const ListDetails = ({ admins, listDetails, savedUsers }: ListDetailsType) => {
46+
export const ListDetails = ({ admins, listId, listDetails, savedUsers }: ListDetailsType) => {
4647
const viewer = useWalletUserSession();
47-
48-
const {
49-
push,
50-
// TODO: Pass this values down from the page level!
51-
query: { id },
52-
} = useRouter();
48+
const { push } = useRouter();
5349

5450
const [isApplyToListModalOpen, setIsApplyToListModalOpen] = useState(false);
5551
const [isApplicationSuccessful, setIsApplicationSuccessful] = useState<boolean>(false);
@@ -219,7 +215,7 @@ export const ListDetails = ({ admins, listDetails, savedUsers }: ListDetailsType
219215
{viewer.isSignedIn && (
220216
<div className="relative flex items-start gap-4">
221217
<div className="flex space-x-4">
222-
<DonateToListProjects listId={parseInt(id as string)} />
218+
<DonateToListProjects listId={listId} />
223219

224220
{!listDetails?.admin_only_registrations && (
225221
<button

src/entities/list/components/ListFormDetails.tsx

+26-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { ChangeEvent, useCallback, useEffect, useMemo, useState } from "react";
1+
import React, { ChangeEvent, useEffect, useMemo, useState } from "react";
22

33
import { zodResolver } from "@hookform/resolvers/zod";
44
import { Check } from "lucide-react";
@@ -15,7 +15,7 @@ import {
1515
} from "@/common/contracts/core/lists";
1616
import { nearSocialIpfsUpload } from "@/common/services/ipfs";
1717
import type { ByListId } from "@/common/types";
18-
import { Button, Input } from "@/common/ui/components";
18+
import { Button, Input, Spinner } from "@/common/ui/components";
1919
import { cn } from "@/common/ui/utils";
2020
import { useWalletUserSession } from "@/common/wallet";
2121
import { AccountGroup, AccountListItem, AccountProfilePicture } from "@/entities/_shared/account";
@@ -26,7 +26,6 @@ import {
2626
ListConfirmationModalProps,
2727
SuccessModalCreateList,
2828
} from "./ListConfirmationModals";
29-
import { useListDeploymentSuccessRedirect } from "../hooks/redirects";
3029
import { useListForm } from "../hooks/useListForm";
3130
import { createListSchema } from "../models/schema";
3231

@@ -51,19 +50,20 @@ export type ListFormProps = Partial<ByListId> & {
5150

5251
export const ListFormDetails: React.FC<ListFormProps> = ({ listId, isDuplicate = false }) => {
5352
const viewer = useWalletUserSession();
54-
const { back, push } = useRouter();
55-
const onEditPage = listId === undefined;
56-
57-
// TODO: Move to the corresponding page!
58-
useListDeploymentSuccessRedirect();
53+
const { back } = useRouter();
54+
const onEditPage = listId !== undefined;
5955

6056
const { isLoading: isRegistrationListLoading, data: registrations } =
6157
listsContractHooks.useRegistrations({
6258
enabled: listId !== undefined,
6359
listId: listId ?? 0,
6460
});
6561

66-
const { isLoading: isListLoading, data: list } = listsContractHooks.useList({
62+
const {
63+
isLoading: isListLoading,
64+
error,
65+
data: list,
66+
} = listsContractHooks.useList({
6767
enabled: listId !== undefined,
6868
listId: listId ?? 0,
6969
});
@@ -131,7 +131,16 @@ export const ListFormDetails: React.FC<ListFormProps> = ({ listId, isDuplicate =
131131
console.error("Error fetching list details:", error);
132132
}
133133
}
134-
}, [setValue, onEditPage, isDuplicate, setAdmins, viewer.isSignedIn, viewer.accountId, list]);
134+
}, [
135+
setValue,
136+
onEditPage,
137+
isDuplicate,
138+
setAdmins,
139+
viewer.isSignedIn,
140+
viewer.accountId,
141+
list,
142+
error,
143+
]);
135144

136145
const onSubmit: SubmitHandler<any> = async (data, event) => {
137146
// Due to conflicting submit buttons (admin and list), this is to make sure only list submit form is submitted.
@@ -265,12 +274,11 @@ export const ListFormDetails: React.FC<ListFormProps> = ({ listId, isDuplicate =
265274
[admins],
266275
);
267276

268-
// TODO: Use Next's Link component instead of these callbacks!
269-
const handleViewList = useCallback(() => push(`/list/${listId}`), [listId, push]);
270-
const handleViewLists = useCallback(() => push(`/lists`), [push]);
271-
272-
// TODO: Handle loading states for list registrations and list data
273-
return (
277+
return isListLoading || isRegistrationListLoading ? (
278+
<div className="flex h-[80vh] items-center justify-center">
279+
<Spinner className="h-20 w-20" />
280+
</div>
281+
) : (
274282
<>
275283
<div className=" mx-auto my-8 max-w-[896px] p-6 font-sans md:w-[720px] md:rounded-[16px] md:border md:border-[#DBDBDB] md:p-10">
276284
<h2 className="mb-6 text-[18px] font-semibold">List Details</h2>
@@ -458,7 +466,7 @@ export const ListFormDetails: React.FC<ListFormProps> = ({ listId, isDuplicate =
458466
)}
459467

460468
<div>
461-
<h3 className="mb-2 mt-10 text-xl font-semibold">
469+
<h3 className="mb-2 mt-10 text-lg font-semibold md:text-xl">
462470
Upload list cover image <span className="font-normal text-gray-500">(Optional)</span>
463471
</h3>
464472
<div
@@ -546,7 +554,7 @@ export const ListFormDetails: React.FC<ListFormProps> = ({ listId, isDuplicate =
546554
isUpdate={listCreateSuccess.type === "UPDATE_LIST"}
547555
listName={listCreateSuccess.data?.name}
548556
showBackToLists={!listId}
549-
onViewList={listId ? handleViewList : handleViewLists}
557+
href={listId ? `/list/${listId}` : `/lists`}
550558
/>
551559
</>
552560
);

src/entities/list/components/ListsOverview.tsx

+4-7
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,11 @@ export const ListsOverview = ({
173173
)}
174174
</div>
175175
{loading ? (
176-
Array.from({ length: 6 }, (_, index) => (
177-
<div
178-
key={index}
179-
className="mt-8 grid w-full grid-cols-1 gap-8 pb-10 md:grid-cols-2 lg:grid-cols-3"
180-
>
176+
<div className="mt-8 grid w-full grid-cols-3 gap-8 pb-10 md:grid-cols-2 lg:grid-cols-3">
177+
{Array.from({ length: 6 }, (_, index) => (
181178
<ListCardSkeleton key={index} />
182-
</div>
183-
))
179+
))}
180+
</div>
184181
) : (
185182
<>
186183
{filteredRegistrations.length > 0 ? (

src/entities/list/components/listActionsModal.tsx

+2-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type ListActionsModal = {};
1717

1818
export const ListActionsModal = create((_: ListActionsModal) => {
1919
const self = useModal();
20-
const { push, query } = useRouter();
20+
const { push } = useRouter();
2121

2222
const close = useCallback(() => {
2323
self.hide();
@@ -89,9 +89,7 @@ export const ListActionsModal = create((_: ListActionsModal) => {
8989
onClose={close}
9090
listName={data?.name as string}
9191
isUpdate={type === ListFormModalType.UPDATE_LIST}
92-
onViewList={() =>
93-
push(`/list/${data?.id ?? (Array.isArray(data) ? data[0]?.id : undefined)}`)
94-
}
92+
href={`/list/${data?.id ?? (Array.isArray(data) ? data[0]?.id : undefined)}`}
9593
/>
9694
) : (
9795
<Dialog open={self.visible}>

0 commit comments

Comments
 (0)