diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 5ec3f196f..1e8fe5216 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -184,11 +184,11 @@ "description_placeholder": "Enter description", "pick_a_date": "Pick a date", "select_user_or_group": { - "add_to_split_pro": "Add to Split Pro", + "add_to_split_pro": "Add to Expense", "note": "Note: sending invite is disabled for now because of spam", "only_one_group_time": "You can have only one group at a time", "send_invite": "Send invite to user", - "warning": "Warning: Don't use send invite if it's invalid email. use add to Split Pro instead. Your account will be blocked if this feature is misused" + "warning": "Warning: Don't use send invite if it's invalid email. Use add to expense instead. Your account will be blocked if this feature is misused" }, "split_type_section": { "direction": { @@ -324,12 +324,12 @@ "no_members": { "add_members": "Add members", "add_members_details": { - "add_to_split_pro": "Add to Split Pro", + "add_to_split_pro": "Add to Group", "note": "Note: sending email invites is disabled", "placeholder": "Enter name or email", "send_invite": "Send invite to user", "title": "Add members", - "warning": "Warning: Don't use send invite if it's invalid email. use add to Split Pro instead. Your account will be blocked if this feature is misused" + "warning": "Warning: Don't use send invite if it's invalid email. Use add to group instead. Your account will be blocked if this feature is misused" }, "invite_link": "Invite link", "no_members": "No members in the group yet." @@ -441,6 +441,11 @@ "on": "on", "or": "or", "outstanding_balances": "Outstanding balances", + "people_list_empty": { + "no_contacts": "You have not shared expenses with anyone", + "no_matches": "No one matches that name", + "all_added": "Everyone you share expenses with is already in this group" + }, "total_balance": "Total balance", "select_currency": "Select currency", "select_balance": "Select balance", diff --git a/src/components/AddExpense/SelectUserOrGroup.tsx b/src/components/AddExpense/SelectUserOrGroup.tsx index 85ef2265b..df1c16c36 100644 --- a/src/components/AddExpense/SelectUserOrGroup.tsx +++ b/src/components/AddExpense/SelectUserOrGroup.tsx @@ -10,6 +10,7 @@ import { z } from 'zod'; import { useAddExpenseStore } from '~/store/addStore'; import { api } from '~/utils/api'; import { deserializeDefaultSplit } from '~/lib/defaultSplit'; +import { peopleListEmptyReason } from '~/lib/peopleList'; import { EntityAvatar } from '../ui/avatar'; import { Button } from '../ui/button'; @@ -45,6 +46,13 @@ export const SelectUserOrGroup: React.FC<{ (f.name ?? f.email)?.toLowerCase().includes(nameOrEmail.toLowerCase()), ); + /* Both friends and groups populate this list, so either one counts as having contacts. */ + const emptyReason = peopleListEmptyReason({ + isLoading: friendsQuery.isPending || groupsQuery.isPending, + hasAnyContacts: 0 < (friendsQuery.data?.length ?? 0) || 0 < (groupsQuery.data?.length ?? 0), + isFiltering: '' !== nameOrEmail.trim(), + }); + const onAddEmailClick = useCallback( (invite = false) => { if (isEmail.success) { @@ -212,8 +220,13 @@ export const SelectUserOrGroup: React.FC<{ ) : null} {0 === filteredFriends?.length && 0 === filteredGroups?.length ? ( -
+
empty user image + {emptyReason ? ( +

+ {t(`ui.people_list_empty.${emptyReason}`)} +

+ ) : null}
) : null}
diff --git a/src/components/group/AddMembers.tsx b/src/components/group/AddMembers.tsx index 0a101537d..f6a617b26 100644 --- a/src/components/group/AddMembers.tsx +++ b/src/components/group/AddMembers.tsx @@ -9,6 +9,7 @@ import { z } from 'zod'; import { Button } from '~/components/ui/button'; import { AppDrawer } from '~/components/ui/drawer'; +import { peopleListEmptyReason } from '~/lib/peopleList'; import { api } from '~/utils/api'; import { EntityAvatar } from '../ui/avatar'; @@ -45,6 +46,15 @@ const AddMembers: React.FC<{ (friend.name ?? friend.email)?.toLowerCase().includes(inputValue.toLowerCase()), ); + /* Says why the list is blank instead of rendering nothing, which reads as a broken dialog. */ + const emptyReason = filteredUsers?.length + ? null + : peopleListEmptyReason({ + isLoading: friendsQuery.isPending, + hasAnyContacts: 0 < (friendsQuery.data?.length ?? 0), + isFiltering: '' !== inputValue.trim(), + }); + function onUserSelect(userId: number) { setUserIds((prev) => ({ ...prev, [userId]: !prev[userId] })); } @@ -160,6 +170,11 @@ const AddMembers: React.FC<{
+ {emptyReason ? ( +

+ {t(`ui.people_list_empty.${emptyReason}`)} +

+ ) : null} {filteredUsers?.map((friend) => (