Compare commits

...

3 Commits

5 changed files with 71 additions and 46 deletions

View File

@@ -9,7 +9,7 @@ import { useTranslation } from "react-i18next";
import { z } from "zod"; import { z } from "zod";
import { TUser, TUserUpdateInput, ZUser, ZUserEmail } from "@formbricks/types/user"; import { TUser, TUserUpdateInput, ZUser, ZUserEmail } from "@formbricks/types/user";
import { PasswordConfirmationModal } from "@/app/(app)/environments/[environmentId]/settings/(account)/profile/components/password-confirmation-modal"; import { PasswordConfirmationModal } from "@/app/(app)/environments/[environmentId]/settings/(account)/profile/components/password-confirmation-modal";
import { appLanguages } from "@/lib/i18n/utils"; import { appLanguages, sortedAppLanguages } from "@/lib/i18n/utils";
import { getFormattedErrorMessage } from "@/lib/utils/helper"; import { getFormattedErrorMessage } from "@/lib/utils/helper";
import { useSignOut } from "@/modules/auth/hooks/use-sign-out"; import { useSignOut } from "@/modules/auth/hooks/use-sign-out";
import { Button } from "@/modules/ui/components/button"; import { Button } from "@/modules/ui/components/button";
@@ -198,41 +198,54 @@ export const EditProfileDetailsForm = ({
<FormField <FormField
control={form.control} control={form.control}
name="locale" name="locale"
render={({ field }) => ( render={({ field }) => {
<FormItem className="mt-4"> const selectedLanguage = appLanguages.find((l) => l.code === field.value);
<FormLabel>{t("common.language")}</FormLabel>
<FormControl> return (
<DropdownMenu> <FormItem className="mt-4">
<DropdownMenuTrigger asChild> <FormLabel>{t("common.language")}</FormLabel>
<Button <FormControl>
type="button" <DropdownMenu>
variant="ghost" <DropdownMenuTrigger asChild>
className="h-10 w-full border border-slate-300 px-3 text-left"> <Button
<div className="flex w-full items-center justify-between"> type="button"
{appLanguages.find((l) => l.code === field.value)?.label["en-US"] ?? "NA"} variant="ghost"
<ChevronDownIcon className="h-4 w-4 text-slate-500" /> className="h-10 w-full border border-slate-300 px-3 text-left">
</div> <div className="flex w-full items-center justify-between">
</Button> {selectedLanguage ? (
</DropdownMenuTrigger> <>
<DropdownMenuContent {selectedLanguage.label["en-US"]}
className="min-w-[var(--radix-dropdown-menu-trigger-width)] bg-white text-slate-700" {selectedLanguage.label.native !== selectedLanguage.label["en-US"] &&
align="start"> ` (${selectedLanguage.label.native})`}
<DropdownMenuRadioGroup value={field.value} onValueChange={field.onChange}> </>
{appLanguages.map((lang) => ( ) : (
<DropdownMenuRadioItem t("common.select")
key={lang.code} )}
value={lang.code} <ChevronDownIcon className="h-4 w-4 text-slate-500" />
className="min-h-8 cursor-pointer"> </div>
{lang.label["en-US"]} </Button>
</DropdownMenuRadioItem> </DropdownMenuTrigger>
))} <DropdownMenuContent
</DropdownMenuRadioGroup> className="min-w-[var(--radix-dropdown-menu-trigger-width)] bg-white text-slate-700"
</DropdownMenuContent> align="start">
</DropdownMenu> <DropdownMenuRadioGroup value={field.value} onValueChange={field.onChange}>
</FormControl> {sortedAppLanguages.map((lang) => (
<FormError /> <DropdownMenuRadioItem
</FormItem> key={lang.code}
)} value={lang.code}
className="min-h-8 cursor-pointer">
{lang.label["en-US"]}
{lang.label.native !== lang.label["en-US"] && ` (${lang.label.native})`}
</DropdownMenuRadioItem>
))}
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
</FormControl>
<FormError />
</FormItem>
);
}}
/> />
{isPasswordResetEnabled && ( {isPasswordResetEnabled && (

View File

@@ -3,8 +3,8 @@ import { getServerSession } from "next-auth";
import { ResponseFilterProvider } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/components/response-filter-context"; import { ResponseFilterProvider } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/components/response-filter-context";
import { getResponseCountBySurveyId } from "@/lib/response/service"; import { getResponseCountBySurveyId } from "@/lib/response/service";
import { getSurvey } from "@/lib/survey/service"; import { getSurvey } from "@/lib/survey/service";
import { authOptions } from "@/modules/auth/lib/authOptions";
import { getTranslate } from "@/lingodotdev/server"; import { getTranslate } from "@/lingodotdev/server";
import { authOptions } from "@/modules/auth/lib/authOptions";
type Props = { type Props = {
params: Promise<{ surveyId: string; environmentId: string }>; params: Promise<{ surveyId: string; environmentId: string }>;

View File

@@ -130,84 +130,102 @@ export const appLanguages = [
code: "de-DE", code: "de-DE",
label: { label: {
"en-US": "German", "en-US": "German",
native: "Deutsch",
}, },
}, },
{ {
code: "en-US", code: "en-US",
label: { label: {
"en-US": "English (US)", "en-US": "English (US)",
native: "English (US)",
}, },
}, },
{ {
code: "es-ES", code: "es-ES",
label: { label: {
"en-US": "Spanish", "en-US": "Spanish",
native: "Español",
}, },
}, },
{ {
code: "fr-FR", code: "fr-FR",
label: { label: {
"en-US": "French", "en-US": "French",
native: "Français",
}, },
}, },
{ {
code: "hu-HU", code: "hu-HU",
label: { label: {
"en-US": "Hungarian", "en-US": "Hungarian",
native: "Magyar",
}, },
}, },
{ {
code: "ja-JP", code: "ja-JP",
label: { label: {
"en-US": "Japanese", "en-US": "Japanese",
native: "日本語",
}, },
}, },
{ {
code: "nl-NL", code: "nl-NL",
label: { label: {
"en-US": "Dutch", "en-US": "Dutch",
native: "Nederlands",
}, },
}, },
{ {
code: "pt-BR", code: "pt-BR",
label: { label: {
"en-US": "Portuguese (Brazil)", "en-US": "Portuguese (Brazil)",
native: "Português (Brasil)",
}, },
}, },
{ {
code: "pt-PT", code: "pt-PT",
label: { label: {
"en-US": "Portuguese (Portugal)", "en-US": "Portuguese (Portugal)",
native: "Português (Portugal)",
}, },
}, },
{ {
code: "ro-RO", code: "ro-RO",
label: { label: {
"en-US": "Romanian", "en-US": "Romanian",
native: "Română",
}, },
}, },
{ {
code: "ru-RU", code: "ru-RU",
label: { label: {
"en-US": "Russian", "en-US": "Russian",
native: "Русский",
}, },
}, },
{ {
code: "sv-SE", code: "sv-SE",
label: { label: {
"en-US": "Swedish", "en-US": "Swedish",
native: "Svenska",
}, },
}, },
{ {
code: "zh-Hans-CN", code: "zh-Hans-CN",
label: { label: {
"en-US": "Chinese (Simplified)", "en-US": "Chinese (Simplified)",
native: "简体中文",
}, },
}, },
{ {
code: "zh-Hant-TW", code: "zh-Hant-TW",
label: { label: {
"en-US": "Chinese (Traditional)", "en-US": "Chinese (Traditional)",
native: "繁體中文",
}, },
}, },
]; ];
export const sortedAppLanguages = [...appLanguages].sort((a, b) =>
a.label["en-US"].localeCompare(b.label["en-US"])
);

View File

@@ -39,9 +39,7 @@ export const AccessTable = ({ teams }: AccessTableProps) => {
{teams.map((team) => ( {teams.map((team) => (
<TableRow key={team.id} className="border-slate-200 hover:bg-transparent"> <TableRow key={team.id} className="border-slate-200 hover:bg-transparent">
<TableCell className="font-medium">{team.name}</TableCell> <TableCell className="font-medium">{team.name}</TableCell>
<TableCell> <TableCell>{t("common.count_members", { count: team.memberCount })}</TableCell>
{t("common.count_members", { count: team.memberCount })}
</TableCell>
<TableCell> <TableCell>
<IdBadge id={team.id} /> <IdBadge id={team.id} />
</TableCell> </TableCell>

View File

@@ -97,9 +97,7 @@ export const TeamsTable = ({
{userTeams.map((team) => ( {userTeams.map((team) => (
<TableRow key={team.id} id={team.name} className="hover:bg-transparent"> <TableRow key={team.id} id={team.name} className="hover:bg-transparent">
<TableCell>{team.name}</TableCell> <TableCell>{team.name}</TableCell>
<TableCell> <TableCell>{t("common.count_members", { count: team.memberCount })}</TableCell>
{t("common.count_members", { count: team.memberCount })}
</TableCell>
<TableCell> <TableCell>
<Badge <Badge
type="success" type="success"
@@ -120,9 +118,7 @@ export const TeamsTable = ({
{otherTeams.map((team) => ( {otherTeams.map((team) => (
<TableRow key={team.id} id={team.name} className="hover:bg-transparent"> <TableRow key={team.id} id={team.name} className="hover:bg-transparent">
<TableCell>{team.name}</TableCell> <TableCell>{team.name}</TableCell>
<TableCell> <TableCell>{t("common.count_members", { count: team.memberCount })}</TableCell>
{t("common.count_members", { count: team.memberCount })}
</TableCell>
<TableCell></TableCell> <TableCell></TableCell>
<TableCell className="flex justify-end"> <TableCell className="flex justify-end">
<ManageTeamButton <ManageTeamButton