@nexttylabs/echo 0.9.0 → 0.11.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/CHANGELOG.md +34 -0
- package/app/(dashboard)/settings/access/page.tsx +1 -1
- package/components/layout/sidebar.tsx +2 -16
- package/components/portal/settings-forms/access-form.tsx +20 -17
- package/messages/en.json +18 -1
- package/messages/jp.json +18 -1
- package/messages/zh-CN.json +18 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @nexttylabs/echo
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- fc3d8f1: support light/dark theme
|
|
8
|
+
- cc04d9f: Use the organization member role uniformly.
|
|
9
|
+
- 5cfdeb7: feat: support editing user profile
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 76fda4d: fix organizational setting i18n
|
|
14
|
+
- 7dba561: remove legacy changeset files
|
|
15
|
+
- 158b254: show current orgnization
|
|
16
|
+
- 1e798f1: remove unuse tables and published files
|
|
17
|
+
- e3c4e1c: fix workflow errors
|
|
18
|
+
- daf9abb: first release
|
|
19
|
+
|
|
20
|
+
## 0.10.0
|
|
21
|
+
|
|
22
|
+
### Minor Changes
|
|
23
|
+
|
|
24
|
+
- fc3d8f1: support light/dark theme
|
|
25
|
+
- cc04d9f: Use the organization member role uniformly.
|
|
26
|
+
- 5cfdeb7: feat: support editing user profile
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- 76fda4d: fix organizational setting i18n
|
|
31
|
+
- 7dba561: remove legacy changeset files
|
|
32
|
+
- 158b254: show current orgnization
|
|
33
|
+
- 1e798f1: remove unuse tables and published files
|
|
34
|
+
- e3c4e1c: fix workflow errors
|
|
35
|
+
- daf9abb: first release
|
|
36
|
+
|
|
3
37
|
## 0.9.0
|
|
4
38
|
|
|
5
39
|
### Minor Changes
|
|
@@ -38,7 +38,7 @@ export default async function AccessSettingsPage() {
|
|
|
38
38
|
<p className="text-muted-foreground">{t("pageDescription")}</p>
|
|
39
39
|
</div>
|
|
40
40
|
|
|
41
|
-
<Card
|
|
41
|
+
<Card>
|
|
42
42
|
<CardHeader>
|
|
43
43
|
<CardTitle>{t("visibilityTitle")}</CardTitle>
|
|
44
44
|
<CardDescription>{t("visibilityDesc")}</CardDescription>
|
|
@@ -78,7 +78,6 @@ export function Sidebar({ user, organizations = [], currentOrgId, onClose }: Sid
|
|
|
78
78
|
const locale = useLocale() as AppLocale;
|
|
79
79
|
const [isPending, startTransition] = useTransition();
|
|
80
80
|
const pendingOrgIdRef = useRef<string | null>(null);
|
|
81
|
-
const pendingLocaleRef = useRef<AppLocale | null>(null);
|
|
82
81
|
|
|
83
82
|
const navItems = [
|
|
84
83
|
{ href: "/dashboard", label: t("dashboard"), icon: LayoutDashboard },
|
|
@@ -118,26 +117,13 @@ export function Sidebar({ user, organizations = [], currentOrgId, onClose }: Sid
|
|
|
118
117
|
pendingOrgIdRef.current = orgId;
|
|
119
118
|
};
|
|
120
119
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const nextLocale = pendingLocaleRef.current;
|
|
124
|
-
if (!nextLocale) return;
|
|
125
|
-
if (nextLocale === locale) {
|
|
126
|
-
startTransition(() => {
|
|
127
|
-
pendingLocaleRef.current = null;
|
|
128
|
-
});
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
120
|
+
const handleLocaleChange = (nextLocale: AppLocale) => {
|
|
121
|
+
if (nextLocale === locale) return;
|
|
131
122
|
const secure = window.location.protocol === "https:" ? ";secure" : "";
|
|
132
123
|
document.cookie = `${LOCALE_COOKIE_NAME}=${nextLocale};path=/;max-age=${60 * 60 * 24 * 365};samesite=lax${secure}`;
|
|
133
124
|
startTransition(() => {
|
|
134
125
|
router.refresh();
|
|
135
|
-
pendingLocaleRef.current = null;
|
|
136
126
|
});
|
|
137
|
-
}, [locale, router]);
|
|
138
|
-
|
|
139
|
-
const handleLocaleChange = (nextLocale: AppLocale) => {
|
|
140
|
-
pendingLocaleRef.current = nextLocale;
|
|
141
127
|
};
|
|
142
128
|
|
|
143
129
|
const currentOrg = organizations.find((org) => org.id === currentOrgId);
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
import { useState } from "react";
|
|
22
22
|
import { useForm, useWatch } from "react-hook-form";
|
|
23
|
+
import { useTranslations } from "next-intl";
|
|
23
24
|
import { Button } from "@/components/ui/button";
|
|
24
25
|
import { Label } from "@/components/ui/label";
|
|
25
26
|
import { Switch } from "@/components/ui/switch";
|
|
@@ -67,6 +68,7 @@ function SwitchField({
|
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
export function PortalAccessForm({ organizationId, initialSharing, initialSeo }: PortalAccessFormProps) {
|
|
71
|
+
const t = useTranslations("settings.access.form");
|
|
70
72
|
const [saving, setSaving] = useState(false);
|
|
71
73
|
const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);
|
|
72
74
|
|
|
@@ -108,7 +110,7 @@ export function PortalAccessForm({ organizationId, initialSharing, initialSeo }:
|
|
|
108
110
|
const sharingResult = await updatePortalSettings(organizationId, "sharing", sharingPayload);
|
|
109
111
|
|
|
110
112
|
if (!sharingResult.success) {
|
|
111
|
-
setMessage({ type: "error", text: sharingResult.error || "
|
|
113
|
+
setMessage({ type: "error", text: sharingResult.error || t("saveFailed") });
|
|
112
114
|
setSaving(false);
|
|
113
115
|
return;
|
|
114
116
|
}
|
|
@@ -116,9 +118,9 @@ export function PortalAccessForm({ organizationId, initialSharing, initialSeo }:
|
|
|
116
118
|
const seoResult = await updatePortalSettings(organizationId, "seo", seoPayload);
|
|
117
119
|
|
|
118
120
|
if (seoResult.success) {
|
|
119
|
-
setMessage({ type: "success", text: "
|
|
121
|
+
setMessage({ type: "success", text: t("saveSuccess") });
|
|
120
122
|
} else {
|
|
121
|
-
setMessage({ type: "error", text: seoResult.error || "
|
|
123
|
+
setMessage({ type: "error", text: seoResult.error || t("saveFailed") });
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
setSaving(false);
|
|
@@ -128,48 +130,48 @@ export function PortalAccessForm({ organizationId, initialSharing, initialSeo }:
|
|
|
128
130
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
|
129
131
|
<SwitchField
|
|
130
132
|
id="enabled"
|
|
131
|
-
label="
|
|
132
|
-
description="
|
|
133
|
+
label={t("enabled")}
|
|
134
|
+
description={t("enabledDesc")}
|
|
133
135
|
checked={enabled}
|
|
134
136
|
onCheckedChange={(checked) => form.setValue("enabled", checked)}
|
|
135
137
|
/>
|
|
136
138
|
|
|
137
139
|
<SwitchField
|
|
138
140
|
id="allowPublicVoting"
|
|
139
|
-
label="
|
|
140
|
-
description="
|
|
141
|
+
label={t("allowPublicVoting")}
|
|
142
|
+
description={t("allowPublicVotingDesc")}
|
|
141
143
|
checked={allowPublicVoting}
|
|
142
144
|
onCheckedChange={(checked) => form.setValue("allowPublicVoting", checked)}
|
|
143
145
|
/>
|
|
144
146
|
|
|
145
147
|
<SwitchField
|
|
146
148
|
id="allowPublicComments"
|
|
147
|
-
label="
|
|
148
|
-
description="
|
|
149
|
+
label={t("allowPublicComments")}
|
|
150
|
+
description={t("allowPublicCommentsDesc")}
|
|
149
151
|
checked={allowPublicComments}
|
|
150
152
|
onCheckedChange={(checked) => form.setValue("allowPublicComments", checked)}
|
|
151
153
|
/>
|
|
152
154
|
|
|
153
155
|
<SwitchField
|
|
154
156
|
id="showVoteCount"
|
|
155
|
-
label="
|
|
156
|
-
description="
|
|
157
|
+
label={t("showVoteCount")}
|
|
158
|
+
description={t("showVoteCountDesc")}
|
|
157
159
|
checked={showVoteCount}
|
|
158
160
|
onCheckedChange={(checked) => form.setValue("showVoteCount", checked)}
|
|
159
161
|
/>
|
|
160
162
|
|
|
161
163
|
<SwitchField
|
|
162
164
|
id="showAuthor"
|
|
163
|
-
label="
|
|
164
|
-
description="
|
|
165
|
+
label={t("showAuthor")}
|
|
166
|
+
description={t("showAuthorDesc")}
|
|
165
167
|
checked={showAuthor}
|
|
166
168
|
onCheckedChange={(checked) => form.setValue("showAuthor", checked)}
|
|
167
169
|
/>
|
|
168
170
|
|
|
169
171
|
<SwitchField
|
|
170
172
|
id="noIndex"
|
|
171
|
-
label="
|
|
172
|
-
description="
|
|
173
|
+
label={t("noIndex")}
|
|
174
|
+
description={t("noIndexDesc")}
|
|
173
175
|
checked={noIndex}
|
|
174
176
|
onCheckedChange={(checked) => form.setValue("noIndex", checked)}
|
|
175
177
|
/>
|
|
@@ -177,12 +179,12 @@ export function PortalAccessForm({ organizationId, initialSharing, initialSeo }:
|
|
|
177
179
|
<div className="flex items-center gap-4">
|
|
178
180
|
<Button type="submit" disabled={saving}>
|
|
179
181
|
{saving && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
|
180
|
-
|
|
182
|
+
{t("saveButton")}
|
|
181
183
|
</Button>
|
|
182
184
|
{message && (
|
|
183
185
|
<p
|
|
184
186
|
className={`text-sm ${
|
|
185
|
-
message.type === "success" ? "text-green-600" : "text-destructive"
|
|
187
|
+
message.type === "success" ? "text-green-600 dark:text-green-400" : "text-destructive"
|
|
186
188
|
}`}
|
|
187
189
|
>
|
|
188
190
|
{message.text}
|
|
@@ -192,3 +194,4 @@ export function PortalAccessForm({ organizationId, initialSharing, initialSeo }:
|
|
|
192
194
|
</form>
|
|
193
195
|
);
|
|
194
196
|
}
|
|
197
|
+
|
package/messages/en.json
CHANGED
|
@@ -273,7 +273,24 @@
|
|
|
273
273
|
"pageTitle": "Organization Access",
|
|
274
274
|
"pageDescription": "Control public access and permissions",
|
|
275
275
|
"visibilityTitle": "Visibility & Permissions",
|
|
276
|
-
"visibilityDesc": "Configure public access, voting, and indexing settings"
|
|
276
|
+
"visibilityDesc": "Configure public access, voting, and indexing settings",
|
|
277
|
+
"form": {
|
|
278
|
+
"enabled": "Public Portal",
|
|
279
|
+
"enabledDesc": "When disabled, visitors cannot access the public portal",
|
|
280
|
+
"allowPublicVoting": "Allow Public Voting",
|
|
281
|
+
"allowPublicVotingDesc": "Visitors can vote without logging in",
|
|
282
|
+
"allowPublicComments": "Allow Public Comments",
|
|
283
|
+
"allowPublicCommentsDesc": "Visitors can comment without logging in",
|
|
284
|
+
"showVoteCount": "Show Vote Count",
|
|
285
|
+
"showVoteCountDesc": "Display vote count in the feedback list",
|
|
286
|
+
"showAuthor": "Show Author",
|
|
287
|
+
"showAuthorDesc": "Display feedback submitter name",
|
|
288
|
+
"noIndex": "Block Search Engine Indexing",
|
|
289
|
+
"noIndexDesc": "When enabled, search engines will not index this page",
|
|
290
|
+
"saveButton": "Save Changes",
|
|
291
|
+
"saveSuccess": "Visibility settings saved",
|
|
292
|
+
"saveFailed": "Save failed"
|
|
293
|
+
}
|
|
277
294
|
},
|
|
278
295
|
"branding": {
|
|
279
296
|
"pageTitle": "Branding",
|
package/messages/jp.json
CHANGED
|
@@ -273,7 +273,24 @@
|
|
|
273
273
|
"pageTitle": "組織アクセス",
|
|
274
274
|
"pageDescription": "公開アクセスと権限を制御",
|
|
275
275
|
"visibilityTitle": "可視性と権限",
|
|
276
|
-
"visibilityDesc": "公開アクセス、投票、インデックス設定を構成"
|
|
276
|
+
"visibilityDesc": "公開アクセス、投票、インデックス設定を構成",
|
|
277
|
+
"form": {
|
|
278
|
+
"enabled": "ポータルを公開",
|
|
279
|
+
"enabledDesc": "無効にすると、訪問者は公開ポータルにアクセスできません",
|
|
280
|
+
"allowPublicVoting": "公開投票を許可",
|
|
281
|
+
"allowPublicVotingDesc": "訪問者はログインせずに投票できます",
|
|
282
|
+
"allowPublicComments": "公開コメントを許可",
|
|
283
|
+
"allowPublicCommentsDesc": "訪問者はログインせずにコメントできます",
|
|
284
|
+
"showVoteCount": "投票数を表示",
|
|
285
|
+
"showVoteCountDesc": "フィードバック一覧に投票数を表示します",
|
|
286
|
+
"showAuthor": "投稿者を表示",
|
|
287
|
+
"showAuthorDesc": "フィードバック投稿者の名前を表示します",
|
|
288
|
+
"noIndex": "検索エンジンのインデックスをブロック",
|
|
289
|
+
"noIndexDesc": "有効にすると、検索エンジンはこのページをインデックスしません",
|
|
290
|
+
"saveButton": "変更を保存",
|
|
291
|
+
"saveSuccess": "可視性設定を保存しました",
|
|
292
|
+
"saveFailed": "保存に失敗しました"
|
|
293
|
+
}
|
|
277
294
|
},
|
|
278
295
|
"branding": {
|
|
279
296
|
"pageTitle": "ブランディング",
|
package/messages/zh-CN.json
CHANGED
|
@@ -273,7 +273,24 @@
|
|
|
273
273
|
"pageTitle": "组织访问",
|
|
274
274
|
"pageDescription": "控制公开访问和权限",
|
|
275
275
|
"visibilityTitle": "可见性与权限",
|
|
276
|
-
"visibilityDesc": "配置公开访问、投票和索引设置"
|
|
276
|
+
"visibilityDesc": "配置公开访问、投票和索引设置",
|
|
277
|
+
"form": {
|
|
278
|
+
"enabled": "公开 Portal",
|
|
279
|
+
"enabledDesc": "关闭后访客无法访问公开门户",
|
|
280
|
+
"allowPublicVoting": "允许公开投票",
|
|
281
|
+
"allowPublicVotingDesc": "访客无需登录即可投票",
|
|
282
|
+
"allowPublicComments": "允许公开评论",
|
|
283
|
+
"allowPublicCommentsDesc": "访客无需登录即可评论",
|
|
284
|
+
"showVoteCount": "显示投票数量",
|
|
285
|
+
"showVoteCountDesc": "在反馈列表中显示投票计数",
|
|
286
|
+
"showAuthor": "显示提交者",
|
|
287
|
+
"showAuthorDesc": "显示反馈提交者名称",
|
|
288
|
+
"noIndex": "阻止搜索引擎索引",
|
|
289
|
+
"noIndexDesc": "启用后搜索引擎将不会收录此页面",
|
|
290
|
+
"saveButton": "保存更改",
|
|
291
|
+
"saveSuccess": "可见性设置已保存",
|
|
292
|
+
"saveFailed": "保存失败"
|
|
293
|
+
}
|
|
277
294
|
},
|
|
278
295
|
"branding": {
|
|
279
296
|
"pageTitle": "品牌",
|