Spaces:
Build error
Build error
import React from "react"; | |
import { useTranslation } from "react-i18next"; | |
import { useSaveSettings } from "#/hooks/mutation/use-save-settings"; | |
import { useSettings } from "#/hooks/query/use-settings"; | |
import { AvailableLanguages } from "#/i18n"; | |
import { DEFAULT_SETTINGS } from "#/services/settings"; | |
import { BrandButton } from "#/components/features/settings/brand-button"; | |
import { SettingsSwitch } from "#/components/features/settings/settings-switch"; | |
import { I18nKey } from "#/i18n/declaration"; | |
import { LanguageInput } from "#/components/features/settings/app-settings/language-input"; | |
import { handleCaptureConsent } from "#/utils/handle-capture-consent"; | |
import { | |
displayErrorToast, | |
displaySuccessToast, | |
} from "#/utils/custom-toast-handlers"; | |
import { retrieveAxiosErrorMessage } from "#/utils/retrieve-axios-error-message"; | |
import { AppSettingsInputsSkeleton } from "#/components/features/settings/app-settings/app-settings-inputs-skeleton"; | |
import { useConfig } from "#/hooks/query/use-config"; | |
function AppSettingsScreen() { | |
const { t } = useTranslation(); | |
const { mutate: saveSettings, isPending } = useSaveSettings(); | |
const { data: settings, isLoading } = useSettings(); | |
const { data: config } = useConfig(); | |
const [languageInputHasChanged, setLanguageInputHasChanged] = | |
React.useState(false); | |
const [analyticsSwitchHasChanged, setAnalyticsSwitchHasChanged] = | |
React.useState(false); | |
const [ | |
soundNotificationsSwitchHasChanged, | |
setSoundNotificationsSwitchHasChanged, | |
] = React.useState(false); | |
const [ | |
proactiveConversationsSwitchHasChanged, | |
setProactiveConversationsSwitchHasChanged, | |
] = React.useState(false); | |
const formAction = (formData: FormData) => { | |
const languageLabel = formData.get("language-input")?.toString(); | |
const languageValue = AvailableLanguages.find( | |
({ label }) => label === languageLabel, | |
)?.value; | |
const language = languageValue || DEFAULT_SETTINGS.LANGUAGE; | |
const enableAnalytics = | |
formData.get("enable-analytics-switch")?.toString() === "on"; | |
const enableSoundNotifications = | |
formData.get("enable-sound-notifications-switch")?.toString() === "on"; | |
const enableProactiveConversations = | |
formData.get("enable-proactive-conversations-switch")?.toString() === | |
"on"; | |
saveSettings( | |
{ | |
LANGUAGE: language, | |
user_consents_to_analytics: enableAnalytics, | |
ENABLE_SOUND_NOTIFICATIONS: enableSoundNotifications, | |
ENABLE_PROACTIVE_CONVERSATION_STARTERS: enableProactiveConversations, | |
}, | |
{ | |
onSuccess: () => { | |
handleCaptureConsent(enableAnalytics); | |
displaySuccessToast(t(I18nKey.SETTINGS$SAVED)); | |
}, | |
onError: (error) => { | |
const errorMessage = retrieveAxiosErrorMessage(error); | |
displayErrorToast(errorMessage || t(I18nKey.ERROR$GENERIC)); | |
}, | |
onSettled: () => { | |
setLanguageInputHasChanged(false); | |
setAnalyticsSwitchHasChanged(false); | |
setSoundNotificationsSwitchHasChanged(false); | |
setProactiveConversationsSwitchHasChanged(false); | |
}, | |
}, | |
); | |
}; | |
const checkIfLanguageInputHasChanged = (value: string) => { | |
const selectedLanguage = AvailableLanguages.find( | |
({ label: langValue }) => langValue === value, | |
)?.label; | |
const currentLanguage = AvailableLanguages.find( | |
({ value: langValue }) => langValue === settings?.LANGUAGE, | |
)?.label; | |
setLanguageInputHasChanged(selectedLanguage !== currentLanguage); | |
}; | |
const checkIfAnalyticsSwitchHasChanged = (checked: boolean) => { | |
const currentAnalytics = !!settings?.USER_CONSENTS_TO_ANALYTICS; | |
setAnalyticsSwitchHasChanged(checked !== currentAnalytics); | |
}; | |
const checkIfSoundNotificationsSwitchHasChanged = (checked: boolean) => { | |
const currentSoundNotifications = !!settings?.ENABLE_SOUND_NOTIFICATIONS; | |
setSoundNotificationsSwitchHasChanged( | |
checked !== currentSoundNotifications, | |
); | |
}; | |
const checkIfProactiveConversationsSwitchHasChanged = (checked: boolean) => { | |
const currentProactiveConversations = | |
!!settings?.ENABLE_PROACTIVE_CONVERSATION_STARTERS; | |
setProactiveConversationsSwitchHasChanged( | |
checked !== currentProactiveConversations, | |
); | |
}; | |
const formIsClean = | |
!languageInputHasChanged && | |
!analyticsSwitchHasChanged && | |
!soundNotificationsSwitchHasChanged && | |
!proactiveConversationsSwitchHasChanged; | |
const shouldBeLoading = !settings || isLoading || isPending; | |
return ( | |
<form | |
data-testid="app-settings-screen" | |
action={formAction} | |
className="flex flex-col h-full justify-between" | |
> | |
{shouldBeLoading && <AppSettingsInputsSkeleton />} | |
{!shouldBeLoading && ( | |
<div className="p-9 flex flex-col gap-6"> | |
<LanguageInput | |
name="language-input" | |
defaultKey={settings.LANGUAGE} | |
onChange={checkIfLanguageInputHasChanged} | |
/> | |
<SettingsSwitch | |
testId="enable-analytics-switch" | |
name="enable-analytics-switch" | |
defaultIsToggled={!!settings.USER_CONSENTS_TO_ANALYTICS} | |
onToggle={checkIfAnalyticsSwitchHasChanged} | |
> | |
{t(I18nKey.ANALYTICS$ENABLE)} | |
</SettingsSwitch> | |
<SettingsSwitch | |
testId="enable-sound-notifications-switch" | |
name="enable-sound-notifications-switch" | |
defaultIsToggled={!!settings.ENABLE_SOUND_NOTIFICATIONS} | |
onToggle={checkIfSoundNotificationsSwitchHasChanged} | |
> | |
{t(I18nKey.SETTINGS$SOUND_NOTIFICATIONS)} | |
</SettingsSwitch> | |
{config?.APP_MODE === "saas" && ( | |
<SettingsSwitch | |
testId="enable-proactive-conversations-switch" | |
name="enable-proactive-conversations-switch" | |
defaultIsToggled={ | |
!!settings.ENABLE_PROACTIVE_CONVERSATION_STARTERS | |
} | |
onToggle={checkIfProactiveConversationsSwitchHasChanged} | |
> | |
{t(I18nKey.SETTINGS$PROACTIVE_CONVERSATION_STARTERS)} | |
</SettingsSwitch> | |
)} | |
</div> | |
)} | |
<div className="flex gap-6 p-6 justify-end border-t border-t-tertiary"> | |
<BrandButton | |
testId="submit-button" | |
variant="primary" | |
type="submit" | |
isDisabled={isPending || formIsClean} | |
> | |
{!isPending && t("SETTINGS$SAVE_CHANGES")} | |
{isPending && t("SETTINGS$SAVING")} | |
</BrandButton> | |
</div> | |
</form> | |
); | |
} | |
export default AppSettingsScreen; | |