8
8
type Dispatch ,
9
9
type CSSProperties ,
10
10
} from 'react' ;
11
+ import { Trans , useTranslation } from 'react-i18next' ;
11
12
import { useDispatch } from 'react-redux' ;
12
13
13
14
import { pushModal } from 'loot-core/src/client/actions/modals' ;
@@ -37,37 +38,58 @@ type ManageUserDirectoryContentProps = {
37
38
setLoading ?: Dispatch < SetStateAction < boolean > > ;
38
39
} ;
39
40
40
- function getUserDirectoryErrors ( reason ) {
41
- switch ( reason ) {
42
- case 'unauthorized' :
43
- return 'You are not logged in.' ;
44
- case 'token-expired' :
45
- return 'Login expired, please login again.' ;
46
- case 'user-cant-be-empty' :
47
- return 'Please enter a value for the username; the field cannot be empty.' ;
48
- case 'role-cant-be-empty' :
49
- return 'Select a role; the field cannot be empty.' ;
50
- case 'user-already-exists' :
51
- return 'The username you entered already exists. Please choose a different username.' ;
52
- case 'not-all-deleted' :
53
- return 'Not all users were deleted. Check if one of the selected users is the server owner.' ;
54
- case 'role-does-not-exists' :
55
- return 'Selected role does not exists, possibly a bug? Visit https://actualbudget.org/contact/ for support.' ;
56
- default :
57
- return `An internal error occurred, sorry! Visit https://actualbudget.org/contact/ for support. (ref: ${ reason } )` ;
41
+ function useGetUserDirectoryErrors ( ) {
42
+ const { t } = useTranslation ( ) ;
43
+
44
+ function getUserDirectoryErrors ( reason ) {
45
+ switch ( reason ) {
46
+ case 'unauthorized' :
47
+ return t ( 'You are not logged in.' ) ;
48
+ case 'token-expired' :
49
+ return t ( 'Login expired, please login again.' ) ;
50
+ case 'user-cant-be-empty' :
51
+ return t (
52
+ 'Please enter a value for the username; the field cannot be empty.' ,
53
+ ) ;
54
+ case 'role-cant-be-empty' :
55
+ return t ( 'Select a role; the field cannot be empty.' ) ;
56
+ case 'user-already-exists' :
57
+ return t (
58
+ 'The username you entered already exists. Please choose a different username.' ,
59
+ ) ;
60
+ case 'not-all-deleted' :
61
+ return t (
62
+ 'Not all users were deleted. Check if one of the selected users is the server owner.' ,
63
+ ) ;
64
+ case 'role-does-not-exists' :
65
+ return t (
66
+ 'Selected role does not exists, possibly a bug? Visit https://actualbudget.org/contact/ for support.' ,
67
+ ) ;
68
+ default :
69
+ return t (
70
+ 'An internal error occurred, sorry! Visit https://actualbudget.org/contact/ for support. (ref: {{reason}})' ,
71
+ { reason } ,
72
+ ) ;
73
+ }
58
74
}
75
+
76
+ return { getUserDirectoryErrors } ;
59
77
}
60
78
61
79
function UserDirectoryContent ( {
62
80
isModal,
63
81
setLoading,
64
82
} : ManageUserDirectoryContentProps ) {
83
+ const { t } = useTranslation ( ) ;
84
+
65
85
const [ allUsers , setAllUsers ] = useState ( [ ] ) ;
66
86
const [ page , setPage ] = useState ( 0 ) ;
67
87
const [ filter , setFilter ] = useState ( '' ) ;
68
88
const dispatch = useDispatch ( ) ;
69
89
const actions = useActions ( ) ;
70
90
91
+ const { getUserDirectoryErrors } = useGetUserDirectoryErrors ( ) ;
92
+
71
93
const filteredUsers = useMemo ( ( ) => {
72
94
return (
73
95
filter === ''
@@ -127,18 +149,18 @@ function UserDirectoryContent({
127
149
actions . addNotification ( {
128
150
type : 'error' ,
129
151
id : 'login-expired' ,
130
- title : 'Login expired' ,
152
+ title : t ( 'Login expired' ) ,
131
153
sticky : true ,
132
154
message : getUserDirectoryErrors ( error ) ,
133
155
button : {
134
- title : 'Go to login' ,
156
+ title : t ( 'Go to login' ) ,
135
157
action : ( ) => actions . signOut ( ) ,
136
158
} ,
137
159
} ) ;
138
160
} else {
139
161
actions . addNotification ( {
140
162
type : 'error' ,
141
- title : 'Something happened while deleting users' ,
163
+ title : t ( 'Something happened while deleting users' ) ,
142
164
sticky : true ,
143
165
message : getUserDirectoryErrors ( error ) ,
144
166
} ) ;
@@ -208,20 +230,22 @@ function UserDirectoryContent({
208
230
} }
209
231
>
210
232
< Text >
211
- Manage and view users who can create new budgets or be invited to
212
- access existing ones.{ ' ' }
213
- < Link
214
- variant = "external"
215
- to = "https://actualbudget.org/docs/budgeting/users/"
216
- linkColor = "muted"
217
- >
218
- Learn more
219
- </ Link >
233
+ < Trans >
234
+ Manage and view users who can create new budgets or be invited
235
+ to access existing ones.{ ' ' }
236
+ < Link
237
+ variant = "external"
238
+ to = "https://actualbudget.org/docs/budgeting/users/"
239
+ linkColor = "muted"
240
+ >
241
+ Learn more
242
+ </ Link >
243
+ </ Trans >
220
244
</ Text >
221
245
</ View >
222
246
< View style = { { flex : 1 } } />
223
247
< Search
224
- placeholder = " Filter users..."
248
+ placeholder = { t ( ' Filter users...' ) }
225
249
value = { filter }
226
250
onChange = { onSearchChange }
227
251
/>
@@ -235,7 +259,7 @@ function UserDirectoryContent({
235
259
style = { { marginBottom : - 1 } }
236
260
>
237
261
{ filteredUsers . length === 0 ? (
238
- < EmptyMessage text = " No users" style = { { marginTop : 15 } } />
262
+ < EmptyMessage text = { t ( ' No users' ) } style = { { marginTop : 15 } } />
239
263
) : (
240
264
< UsersList
241
265
users = { filteredUsers }
@@ -258,11 +282,11 @@ function UserDirectoryContent({
258
282
< Stack direction = "row" align = "center" justify = "flex-end" spacing = { 2 } >
259
283
{ selectedInst . items . size > 0 && (
260
284
< Button onPress = { onDeleteSelected } >
261
- Delete { selectedInst . items . size } users
285
+ < Trans > Delete { selectedInst . items . size } users </ Trans >
262
286
</ Button >
263
287
) }
264
288
< Button variant = "primary" onPress = { onAddUser } >
265
- Add new user
289
+ < Trans > Add new user</ Trans >
266
290
</ Button >
267
291
</ Stack >
268
292
</ View >
0 commit comments