@carlonicora/nextjs-jsonapi 1.29.6 → 1.31.0
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/dist/{BlockNoteEditor-4NQ5LSD6.mjs → BlockNoteEditor-CUIQPN6C.mjs} +3 -3
- package/dist/{BlockNoteEditor-AZNYW5Y7.js → BlockNoteEditor-NBASFIQP.js} +13 -13
- package/dist/{BlockNoteEditor-AZNYW5Y7.js.map → BlockNoteEditor-NBASFIQP.js.map} +1 -1
- package/dist/billing/index.js +331 -331
- package/dist/billing/index.mjs +2 -2
- package/dist/{chunk-5KQXRLK3.js → chunk-HBCIT6KE.js} +12 -1
- package/dist/chunk-HBCIT6KE.js.map +1 -0
- package/dist/{chunk-CWRYS2F3.js → chunk-ITBPDMUX.js} +537 -453
- package/dist/chunk-ITBPDMUX.js.map +1 -0
- package/dist/{chunk-WQ3KF6BG.mjs → chunk-RACFENTQ.mjs} +12 -1
- package/dist/chunk-RACFENTQ.mjs.map +1 -0
- package/dist/{chunk-ZQEFAWFP.mjs → chunk-TM4RWVZE.mjs} +984 -900
- package/dist/chunk-TM4RWVZE.mjs.map +1 -0
- package/dist/client/index.js +3 -3
- package/dist/client/index.mjs +2 -2
- package/dist/components/index.d.mts +17 -1
- package/dist/components/index.d.ts +17 -1
- package/dist/components/index.js +7 -3
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +6 -2
- package/dist/contexts/index.js +3 -3
- package/dist/contexts/index.mjs +2 -2
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/core/index.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{s3.service-BMT7W6KS.d.mts → s3.service-D2vIfl9y.d.mts} +8 -0
- package/dist/{s3.service-DsXo9nop.d.ts → s3.service-D7NyMnNY.d.ts} +8 -0
- package/dist/server/index.d.mts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +1 -1
- package/package.json +1 -1
- package/src/components/containers/ReactMarkdownContainer.tsx +1 -1
- package/src/components/forms/GdprConsentCheckbox.tsx +45 -0
- package/src/components/forms/index.ts +1 -0
- package/src/features/auth/components/GdprConsentSection.tsx +50 -0
- package/src/features/auth/components/forms/ForgotPassword.tsx +1 -1
- package/src/features/auth/components/forms/Login.tsx +4 -4
- package/src/features/auth/components/forms/Register.tsx +12 -1
- package/src/features/auth/components/index.ts +1 -0
- package/src/features/auth/data/auth.service.ts +20 -0
- package/src/features/company/components/forms/CompanyConfigurationEditor.tsx +1 -1
- package/src/features/company/components/forms/CompanyDeleter.tsx +1 -1
- package/src/features/user/components/widgets/UserSearchPopover.tsx +1 -1
- package/dist/chunk-5KQXRLK3.js.map +0 -1
- package/dist/chunk-CWRYS2F3.js.map +0 -1
- package/dist/chunk-WQ3KF6BG.mjs.map +0 -1
- package/dist/chunk-ZQEFAWFP.mjs.map +0 -1
- /package/dist/{BlockNoteEditor-4NQ5LSD6.mjs.map → BlockNoteEditor-CUIQPN6C.mjs.map} +0 -0
|
@@ -283,6 +283,14 @@ declare class AuthService extends AbstractService {
|
|
|
283
283
|
static saveToken(params: {
|
|
284
284
|
dehydratedAuth: JsonApiHydratedDataInterface;
|
|
285
285
|
}): Promise<void>;
|
|
286
|
+
static completeOAuthRegistration(params: {
|
|
287
|
+
pendingId: string;
|
|
288
|
+
termsAcceptedAt: string;
|
|
289
|
+
marketingConsent: boolean;
|
|
290
|
+
marketingConsentAt: string | null;
|
|
291
|
+
}): Promise<{
|
|
292
|
+
code: string;
|
|
293
|
+
}>;
|
|
286
294
|
}
|
|
287
295
|
|
|
288
296
|
declare class CompanyService extends AbstractService {
|
package/dist/server/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import { A as ApiData } from '../ApiData-DPKNfY-9.mjs';
|
|
|
2
2
|
import { M as ModuleWithPermissions, A as Action } from '../notification.interface-D5MbtfZK.mjs';
|
|
3
3
|
import { A as ApiRequestDataTypeInterface } from '../ApiRequestDataTypeInterface-CUKFDBx2.mjs';
|
|
4
4
|
import { A as ApiResponseInterface } from '../ApiResponseInterface-zeewugD7.mjs';
|
|
5
|
-
export { d as ServerAuthService, C as ServerCompanyService, e as ServerContentService, F as ServerFeatureService, f as ServerNotificationService, h as ServerPushService, R as ServerRoleService, k as ServerS3Service, U as ServerUserService } from '../s3.service-
|
|
5
|
+
export { d as ServerAuthService, C as ServerCompanyService, e as ServerContentService, F as ServerFeatureService, f as ServerNotificationService, h as ServerPushService, R as ServerRoleService, k as ServerS3Service, U as ServerUserService } from '../s3.service-D2vIfl9y.mjs';
|
|
6
6
|
import 'lucide-react';
|
|
7
7
|
import '../ApiDataInterface-DPP8s46n.mjs';
|
|
8
8
|
import '../content.interface-BSpowEiW.mjs';
|
package/dist/server/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { A as ApiData } from '../ApiData-DPKNfY-9.js';
|
|
|
2
2
|
import { M as ModuleWithPermissions, A as Action } from '../notification.interface-CmKmObIU.js';
|
|
3
3
|
import { A as ApiRequestDataTypeInterface } from '../ApiRequestDataTypeInterface-CUKFDBx2.js';
|
|
4
4
|
import { A as ApiResponseInterface } from '../ApiResponseInterface-CAIAeP5d.js';
|
|
5
|
-
export { d as ServerAuthService, C as ServerCompanyService, e as ServerContentService, F as ServerFeatureService, f as ServerNotificationService, h as ServerPushService, R as ServerRoleService, k as ServerS3Service, U as ServerUserService } from '../s3.service-
|
|
5
|
+
export { d as ServerAuthService, C as ServerCompanyService, e as ServerContentService, F as ServerFeatureService, f as ServerNotificationService, h as ServerPushService, R as ServerRoleService, k as ServerS3Service, U as ServerUserService } from '../s3.service-D7NyMnNY.js';
|
|
6
6
|
import 'lucide-react';
|
|
7
7
|
import '../ApiDataInterface-DPP8s46n.js';
|
|
8
8
|
import '../content.interface-DFQ7mkpL.js';
|
package/dist/server/index.js
CHANGED
|
@@ -15,7 +15,7 @@ var _chunk3ZPK4QOBjs = require('../chunk-3ZPK4QOB.js');
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
var
|
|
18
|
+
var _chunkHBCIT6KEjs = require('../chunk-HBCIT6KE.js');
|
|
19
19
|
require('../chunk-LXKSUWAV.js');
|
|
20
20
|
require('../chunk-IBS6NI7D.js');
|
|
21
21
|
|
|
@@ -86,7 +86,7 @@ var ServerSession = class {
|
|
|
86
86
|
if (!rawModules) return false;
|
|
87
87
|
const modules = JSON.parse(_pako2.default.ungzip(Buffer.from(rawModules, "base64"), { to: "string" }));
|
|
88
88
|
const selectedModule = modules.find((module) => module.id === params.module.moduleId);
|
|
89
|
-
return
|
|
89
|
+
return _chunkHBCIT6KEjs.checkPermissionsFromServer.call(void 0, {
|
|
90
90
|
module: params.module,
|
|
91
91
|
action: params.action,
|
|
92
92
|
data: params.data,
|
|
@@ -296,5 +296,5 @@ _chunk7QVYU63Ejs.__name.call(void 0, ServerJsonApiDelete, "ServerJsonApiDelete")
|
|
|
296
296
|
|
|
297
297
|
|
|
298
298
|
|
|
299
|
-
exports.ServerAuthService =
|
|
299
|
+
exports.ServerAuthService = _chunkHBCIT6KEjs.AuthService; exports.ServerCompanyService = _chunkHBCIT6KEjs.CompanyService; exports.ServerContentService = _chunkHBCIT6KEjs.ContentService; exports.ServerFeatureService = _chunkHBCIT6KEjs.FeatureService; exports.ServerJsonApiDelete = ServerJsonApiDelete; exports.ServerJsonApiGet = ServerJsonApiGet; exports.ServerJsonApiPatch = ServerJsonApiPatch; exports.ServerJsonApiPost = ServerJsonApiPost; exports.ServerJsonApiPut = ServerJsonApiPut; exports.ServerNotificationService = _chunkHBCIT6KEjs.NotificationService; exports.ServerPushService = _chunkHBCIT6KEjs.PushService; exports.ServerRoleService = _chunkHBCIT6KEjs.RoleService; exports.ServerS3Service = _chunkHBCIT6KEjs.S3Service; exports.ServerSession = ServerSession; exports.ServerUserService = _chunkHBCIT6KEjs.UserService; exports.configureServerJsonApi = configureServerJsonApi; exports.getServerApiUrl = getServerApiUrl; exports.getServerAppUrl = getServerAppUrl; exports.getServerToken = _chunkYUO55Q5Ajs.getServerToken; exports.getServerTrackablePages = getServerTrackablePages; exports.invalidateCacheTag = invalidateCacheTag; exports.invalidateCacheTags = invalidateCacheTags; exports.serverRequest = _chunk3ZPK4QOBjs.serverRequest;
|
|
300
300
|
//# sourceMappingURL=index.js.map
|
package/dist/server/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@ export function ReactMarkdownContainer({
|
|
|
19
19
|
initialLines = 4,
|
|
20
20
|
size = "normal",
|
|
21
21
|
}: ReactMarkdownContainerProps) {
|
|
22
|
-
const t = useTranslations("
|
|
22
|
+
const t = useTranslations("ui.buttons");
|
|
23
23
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
24
24
|
const [showExpandButton, setShowExpandButton] = useState(false);
|
|
25
25
|
const contentRef = useRef<HTMLDivElement>(null);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
import { FieldValues, Path, UseFormReturn } from "react-hook-form";
|
|
5
|
+
import { Checkbox, FieldDescription } from "../../shadcnui";
|
|
6
|
+
import { FormFieldWrapper } from "./FormFieldWrapper";
|
|
7
|
+
|
|
8
|
+
interface GdprConsentCheckboxProps<T extends FieldValues> {
|
|
9
|
+
form: UseFormReturn<T>;
|
|
10
|
+
id: Path<T>;
|
|
11
|
+
label: ReactNode;
|
|
12
|
+
description?: string;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function GdprConsentCheckbox<T extends FieldValues>({
|
|
17
|
+
form,
|
|
18
|
+
id,
|
|
19
|
+
label,
|
|
20
|
+
description,
|
|
21
|
+
required,
|
|
22
|
+
}: GdprConsentCheckboxProps<T>) {
|
|
23
|
+
return (
|
|
24
|
+
<FormFieldWrapper form={form} name={id} orientation="horizontal">
|
|
25
|
+
{(field) => (
|
|
26
|
+
<div className="flex flex-row items-start space-x-3 space-y-0">
|
|
27
|
+
<Checkbox
|
|
28
|
+
checked={field.value}
|
|
29
|
+
onCheckedChange={field.onChange}
|
|
30
|
+
aria-required={required}
|
|
31
|
+
/>
|
|
32
|
+
<div className="space-y-1 leading-none">
|
|
33
|
+
<span className="text-sm font-normal">
|
|
34
|
+
{label}
|
|
35
|
+
{required && <span className="text-destructive ml-1">*</span>}
|
|
36
|
+
</span>
|
|
37
|
+
{description && (
|
|
38
|
+
<FieldDescription className="text-xs">{description}</FieldDescription>
|
|
39
|
+
)}
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
)}
|
|
43
|
+
</FormFieldWrapper>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -17,6 +17,7 @@ export * from "./FormSelect";
|
|
|
17
17
|
export * from "./FormSlider";
|
|
18
18
|
export * from "./FormSwitch";
|
|
19
19
|
export * from "./FormTextarea";
|
|
20
|
+
export * from "./GdprConsentCheckbox";
|
|
20
21
|
export * from "./MultiFileUploader";
|
|
21
22
|
export * from "./PasswordInput";
|
|
22
23
|
export { FormFeatures } from "../../features/feature/components/forms/FormFeatures";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useTranslations } from "next-intl";
|
|
4
|
+
import { FieldValues, Path, UseFormReturn } from "react-hook-form";
|
|
5
|
+
import { GdprConsentCheckbox } from "../../../components/forms/GdprConsentCheckbox";
|
|
6
|
+
import { Link } from "../../../shadcnui";
|
|
7
|
+
|
|
8
|
+
interface GdprConsentSectionProps<T extends FieldValues> {
|
|
9
|
+
form: UseFormReturn<T>;
|
|
10
|
+
termsCheckboxId?: Path<T>;
|
|
11
|
+
marketingCheckboxId?: Path<T>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function GdprConsentSection<T extends FieldValues>({
|
|
15
|
+
form,
|
|
16
|
+
termsCheckboxId = "termsAccepted" as Path<T>,
|
|
17
|
+
marketingCheckboxId = "marketingConsent" as Path<T>,
|
|
18
|
+
}: GdprConsentSectionProps<T>) {
|
|
19
|
+
const t = useTranslations("auth.gdpr");
|
|
20
|
+
|
|
21
|
+
const termsLabel = (
|
|
22
|
+
<>
|
|
23
|
+
{t("terms_prefix")}{" "}
|
|
24
|
+
<Link href="/terms" target="_blank" rel="noopener" className="underline">
|
|
25
|
+
{t("terms_of_service")}
|
|
26
|
+
</Link>{" "}
|
|
27
|
+
{t("and")}{" "}
|
|
28
|
+
<Link href="/privacy" target="_blank" rel="noopener" className="underline">
|
|
29
|
+
{t("privacy_policy")}
|
|
30
|
+
</Link>
|
|
31
|
+
</>
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div className="space-y-4 py-4">
|
|
36
|
+
<GdprConsentCheckbox
|
|
37
|
+
form={form}
|
|
38
|
+
id={termsCheckboxId}
|
|
39
|
+
label={termsLabel}
|
|
40
|
+
required
|
|
41
|
+
/>
|
|
42
|
+
<GdprConsentCheckbox
|
|
43
|
+
form={form}
|
|
44
|
+
id={marketingCheckboxId}
|
|
45
|
+
label={t("marketing_consent")}
|
|
46
|
+
description={t("marketing_description")}
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -58,7 +58,7 @@ export function ForgotPassword() {
|
|
|
58
58
|
<CardHeader data-testid="page-forgot-password-container">
|
|
59
59
|
<CardTitle className="text-primary flex flex-col items-center pb-10 text-4xl">
|
|
60
60
|
<Image src="/logo.webp" alt="Logo" width={100} height={100} priority />
|
|
61
|
-
{t("auth.forgot_password")}
|
|
61
|
+
{t("auth.buttons.forgot_password")}
|
|
62
62
|
</CardTitle>
|
|
63
63
|
<CardDescription className="text-sm">
|
|
64
64
|
{showConfirmation ? <> </> : <>{t(`auth.add_email_to_reset`)}</>}
|
|
@@ -69,7 +69,7 @@ export function Login() {
|
|
|
69
69
|
<CardHeader data-testid="page-login-container">
|
|
70
70
|
<CardTitle className="text-primary flex flex-col items-center pb-10 text-4xl">
|
|
71
71
|
<Image src="/logo.webp" alt="Logo" width={100} height={100} priority />
|
|
72
|
-
{t("auth.login")}
|
|
72
|
+
{t("auth.buttons.login")}
|
|
73
73
|
</CardTitle>
|
|
74
74
|
|
|
75
75
|
<CardDescription className="text-sm">{t(`auth.login_description`)}</CardDescription>
|
|
@@ -95,7 +95,7 @@ export function Login() {
|
|
|
95
95
|
testId="form-login-input-password"
|
|
96
96
|
/>
|
|
97
97
|
<Button className="mt-4 w-full" type={"submit"} data-testid="form-login-button-submit">
|
|
98
|
-
{t(`auth.login`)}
|
|
98
|
+
{t(`auth.buttons.login`)}
|
|
99
99
|
</Button>
|
|
100
100
|
</>
|
|
101
101
|
)}
|
|
@@ -114,7 +114,7 @@ export function Login() {
|
|
|
114
114
|
className="flex w-full justify-start"
|
|
115
115
|
onClick={() => setComponentType(AuthComponent.Register)}
|
|
116
116
|
>
|
|
117
|
-
{t(`auth.register`)}
|
|
117
|
+
{t(`auth.buttons.register`)}
|
|
118
118
|
</Link>
|
|
119
119
|
<Link
|
|
120
120
|
href="#"
|
|
@@ -122,7 +122,7 @@ export function Login() {
|
|
|
122
122
|
onClick={() => setComponentType(AuthComponent.ForgotPassword)}
|
|
123
123
|
data-testid="form-login-link-forgot-password"
|
|
124
124
|
>
|
|
125
|
-
{t(`auth.forgot_password`)}
|
|
125
|
+
{t(`auth.buttons.forgot_password`)}
|
|
126
126
|
</Link>
|
|
127
127
|
</div>
|
|
128
128
|
</CardFooter>
|
|
@@ -8,6 +8,7 @@ import { SubmitHandler, useForm } from "react-hook-form";
|
|
|
8
8
|
import { v4 } from "uuid";
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { errorToast, FormInput, FormPassword } from "../../../../components";
|
|
11
|
+
import { GdprConsentSection } from "../GdprConsentSection";
|
|
11
12
|
import {
|
|
12
13
|
Button,
|
|
13
14
|
CardContent,
|
|
@@ -44,6 +45,10 @@ export default function Register() {
|
|
|
44
45
|
.regex(/^(?=.*[0-9])(?=.*[^a-zA-Z0-9]).*$/, {
|
|
45
46
|
message: t(`auth.errors.password_invalid_format`),
|
|
46
47
|
}),
|
|
48
|
+
termsAccepted: z.literal(true, {
|
|
49
|
+
message: t("auth.gdpr.terms_required"),
|
|
50
|
+
}),
|
|
51
|
+
marketingConsent: z.boolean().optional(),
|
|
47
52
|
});
|
|
48
53
|
|
|
49
54
|
const form = useForm<z.infer<typeof formSchema>>({
|
|
@@ -53,6 +58,8 @@ export default function Register() {
|
|
|
53
58
|
name: "",
|
|
54
59
|
email: "",
|
|
55
60
|
password: "",
|
|
61
|
+
termsAccepted: false as unknown as true,
|
|
62
|
+
marketingConsent: false,
|
|
56
63
|
},
|
|
57
64
|
});
|
|
58
65
|
|
|
@@ -64,6 +71,9 @@ export default function Register() {
|
|
|
64
71
|
name: values.name,
|
|
65
72
|
email: values.email,
|
|
66
73
|
password: values.password,
|
|
74
|
+
termsAcceptedAt: new Date().toISOString(),
|
|
75
|
+
marketingConsent: values.marketingConsent ?? false,
|
|
76
|
+
marketingConsentAt: values.marketingConsent ? new Date().toISOString() : null,
|
|
67
77
|
};
|
|
68
78
|
|
|
69
79
|
await AuthService.register(payload);
|
|
@@ -78,7 +88,7 @@ export default function Register() {
|
|
|
78
88
|
<CardHeader>
|
|
79
89
|
<CardTitle className="text-primary flex flex-col items-center pb-10 text-4xl">
|
|
80
90
|
<Image src="/logo.webp" alt="Logo" width={100} height={100} priority />
|
|
81
|
-
{t(`auth.register`)}
|
|
91
|
+
{t(`auth.buttons.register`)}
|
|
82
92
|
</CardTitle>
|
|
83
93
|
<CardDescription className="text-sm">
|
|
84
94
|
{showConfirmation ? <> </> : <>{t(`auth.register_description`)}</>}
|
|
@@ -120,6 +130,7 @@ export default function Register() {
|
|
|
120
130
|
name={t(`user.fields.password.label`)}
|
|
121
131
|
placeholder={t(`user.fields.password.placeholder`)}
|
|
122
132
|
/>
|
|
133
|
+
<GdprConsentSection form={form} />
|
|
123
134
|
<Button className="mt-4 w-full" type={"submit"}>
|
|
124
135
|
{t(`auth.buttons.register`)}
|
|
125
136
|
</Button>
|
|
@@ -154,4 +154,24 @@ export class AuthService extends AbstractService {
|
|
|
154
154
|
});
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
|
+
|
|
158
|
+
static async completeOAuthRegistration(params: {
|
|
159
|
+
pendingId: string;
|
|
160
|
+
termsAcceptedAt: string;
|
|
161
|
+
marketingConsent: boolean;
|
|
162
|
+
marketingConsentAt: string | null;
|
|
163
|
+
}): Promise<{ code: string }> {
|
|
164
|
+
const endpoint = new EndpointCreator({ endpoint: Modules.Auth, id: "oauth", childEndpoint: "complete" });
|
|
165
|
+
|
|
166
|
+
const response: ApiResponseInterface = await JsonApiPost({
|
|
167
|
+
classKey: Modules.Auth,
|
|
168
|
+
endpoint: endpoint.generate(),
|
|
169
|
+
body: params,
|
|
170
|
+
language: "en",
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
if (!response.ok) throw new Error(response.error);
|
|
174
|
+
|
|
175
|
+
return response.data as unknown as { code: string };
|
|
176
|
+
}
|
|
157
177
|
}
|
|
@@ -110,7 +110,7 @@ function CompanyConfigurationEditorInternal({ company }: CompanyConfigurationEdi
|
|
|
110
110
|
</DialogTrigger>
|
|
111
111
|
<DialogContent className={`flex max-h-[70vh] max-w-4xl flex-col overflow-y-auto`}>
|
|
112
112
|
<DialogHeader>
|
|
113
|
-
<DialogTitle>{t(`entities.
|
|
113
|
+
<DialogTitle>{t(`entities.configurations`, { count: 2 })}</DialogTitle>
|
|
114
114
|
<DialogDescription className="text-destructive">
|
|
115
115
|
{t(`features.configuration.warning_description`)}
|
|
116
116
|
</DialogDescription>
|
|
@@ -81,7 +81,7 @@ export const UserSearchPopover = ({ children, onSelect, align = "start", classNa
|
|
|
81
81
|
) : (
|
|
82
82
|
<div className="text-muted-foreground py-6 text-center text-sm">
|
|
83
83
|
{isLoading
|
|
84
|
-
? t(`
|
|
84
|
+
? t(`ui.buttons.loading`)
|
|
85
85
|
: t(`ui.search.no_results`, { type: t(`entities.users`, { count: 1 }) })}
|
|
86
86
|
</div>
|
|
87
87
|
)}
|