diff --git a/apps/mobile/app.json b/apps/mobile/app.json index ea71dd07..5b01e549 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -59,6 +59,12 @@ "project": "6pm-mobile", "organization": "get6pm" } + ], + [ + "expo-local-authentication", + { + "faceIDPermission": "Allow $(PRODUCT_NAME) to use Face ID to secure your account" + } ] ], "experiments": { diff --git a/apps/mobile/app/(app)/(tabs)/settings.tsx b/apps/mobile/app/(app)/(tabs)/settings.tsx index 2a381d4a..25505149 100644 --- a/apps/mobile/app/(app)/(tabs)/settings.tsx +++ b/apps/mobile/app/(app)/(tabs)/settings.tsx @@ -6,6 +6,8 @@ import { MenuItem } from '@/components/common/menu-item' import { toast } from '@/components/common/toast' import { ProfileCard } from '@/components/setting/profile-card' import { SelectDefaultCurrency } from '@/components/setting/select-default-currency' +import { SetLocalAuth } from '@/components/setting/set-local-auth' +import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Switch } from '@/components/ui/switch' import { Text } from '@/components/ui/text' @@ -29,7 +31,6 @@ import { LockKeyholeIcon, LogOutIcon, MessageSquareQuoteIcon, - ScanFaceIcon, ScrollTextIcon, ShapesIcon, Share2Icon, @@ -94,7 +95,9 @@ export default function SettingsScreen() { label={t(i18n)`Magic inbox`} icon={InboxIcon} rightSection={ - + + {t(i18n)`Coming soon`} + } /> @@ -129,13 +132,7 @@ export default function SettingsScreen() { /> - - } - /> + { @@ -30,6 +33,10 @@ export default function AuthenticatedLayout() { return } + if (shouldAuthLocal) { + return setShouldAuthLocal(false)} /> + } + return ( void +} + +export function AuthLocal({ onAuthenticated }: AuthLocalProps) { + const { i18n } = useLingui() + + const handleAuthenticate = useCallback(async () => { + const result = await LocalAuthentication.authenticateAsync({ + // disableDeviceFallback: true, + }) + if (result.success) { + onAuthenticated?.() + } + }, [onAuthenticated]) + + // biome-ignore lint/correctness/useExhaustiveDependencies: + useEffect(() => { + handleAuthenticate() + }, []) + + return ( + + + {t( + i18n, + )`App is locked. Please authenticate to continue.`} + + + ) +} diff --git a/apps/mobile/components/setting/profile-card.tsx b/apps/mobile/components/setting/profile-card.tsx index cefb4247..c077942d 100644 --- a/apps/mobile/components/setting/profile-card.tsx +++ b/apps/mobile/components/setting/profile-card.tsx @@ -149,13 +149,13 @@ export function ProfileCard() { intensity={15} className="flex flex-row items-center justify-between gap-2 px-4 py-3" > - + - + Saver - + {user?.fullName ?? user?.primaryEmailAddress?.emailAddress} diff --git a/apps/mobile/components/setting/set-local-auth.tsx b/apps/mobile/components/setting/set-local-auth.tsx new file mode 100644 index 00000000..cae52988 --- /dev/null +++ b/apps/mobile/components/setting/set-local-auth.tsx @@ -0,0 +1,51 @@ +import { useUserSettingsStore } from '@/stores/user-settings/store' +import { t } from '@lingui/macro' +import { useLingui } from '@lingui/react' +import * as LocalAuthentication from 'expo-local-authentication' +import { ScanFaceIcon } from 'lucide-react-native' +import { useEffect, useState } from 'react' +import { MenuItem } from '../common/menu-item' +import { toast } from '../common/toast' +import { Switch } from '../ui/switch' + +export function SetLocalAuth() { + const { i18n } = useLingui() + const [isBiometricSupported, setIsBiometricSupported] = useState(false) + const { enabledLocalAuth, setEnabledLocalAuth } = useUserSettingsStore() + + useEffect(() => { + ;(async () => { + const compatible = await LocalAuthentication.hasHardwareAsync() + const enrolled = await LocalAuthentication.isEnrolledAsync() + setIsBiometricSupported(compatible && enrolled) + })() + }, []) + + async function handleToggleLocalAuth(enabled: boolean) { + const result = await LocalAuthentication.authenticateAsync({ + // disableDeviceFallback: true, + }) + if (result.success) { + setEnabledLocalAuth(enabled) + } else { + toast.error(result.warning ?? t(i18n)`Unknown error`) + } + } + + if (!isBiometricSupported) { + return null + } + + return ( + + } + /> + ) +} diff --git a/apps/mobile/hooks/use-local-auth.tsx b/apps/mobile/hooks/use-local-auth.tsx new file mode 100644 index 00000000..5a68a80e --- /dev/null +++ b/apps/mobile/hooks/use-local-auth.tsx @@ -0,0 +1,48 @@ +import { useUserSettingsStore } from '@/stores/user-settings/store' +import AsyncStorage from '@react-native-async-storage/async-storage' +import { useCallback, useEffect, useState } from 'react' +import { AppState, type AppStateStatus } from 'react-native' + +// 30 seconds +const BIO_AUTH_EXPIRATION_TIME = 1000 * 30 + +export function useLocalAuth() { + const [shouldAuthLocal, setShouldAuthLocal] = useState(false) + const { enabledLocalAuth } = useUserSettingsStore() + + const changeAppStateListener = useCallback( + async (status: AppStateStatus) => { + if (!enabledLocalAuth) { + AsyncStorage.removeItem('movedToBackgroundAt') + return + } + + if (status === 'background') { + const date = Date.now() + await AsyncStorage.setItem('movedToBackgroundAt', date.toString()) + } + + if (status === 'active') { + const date = await AsyncStorage.getItem('movedToBackgroundAt') + if (date && Date.now() - Number(date) >= BIO_AUTH_EXPIRATION_TIME) { + await AsyncStorage.removeItem('movedToBackgroundAt') + setShouldAuthLocal(true) + } + } + }, + [enabledLocalAuth], + ) + + useEffect(() => { + const subscription = AppState.addEventListener( + 'change', + changeAppStateListener, + ) + return subscription.remove + }, [changeAppStateListener]) + + return { + shouldAuthLocal, + setShouldAuthLocal, + } +} diff --git a/apps/mobile/locales/en/messages.po b/apps/mobile/locales/en/messages.po index e5639bf7..6f54c08a 100644 --- a/apps/mobile/locales/en/messages.po +++ b/apps/mobile/locales/en/messages.po @@ -21,7 +21,7 @@ msgstr "" msgid "{0} left" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:124 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:127 msgid "{language}" msgstr "" @@ -83,7 +83,11 @@ msgstr "" msgid "An error occurred while updating the transaction" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:105 +#: apps/mobile/components/auth/auth-local.tsx:34 +msgid "App is locked. Please authenticate to continue." +msgstr "" + +#: apps/mobile/app/(app)/(tabs)/settings.tsx:108 msgid "App settings" msgstr "" @@ -91,8 +95,8 @@ msgstr "" msgid "App theme" msgstr "" -#: apps/mobile/app/(app)/_layout.tsx:87 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:110 +#: apps/mobile/app/(app)/_layout.tsx:94 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:113 msgid "Appearance" msgstr "" @@ -104,7 +108,7 @@ msgstr "" msgid "Are you sure you want to delete your account? This action cannot be undone." msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:221 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:218 msgid "Are you sure you want to sign out?" msgstr "" @@ -132,7 +136,7 @@ msgstr "" msgid "Camera permissions are not granted" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:223 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:220 #: apps/mobile/app/(app)/budget/[budgetId]/edit.tsx:43 #: apps/mobile/app/(app)/profile.tsx:120 #: apps/mobile/app/(app)/transaction/[transactionId].tsx:77 @@ -144,8 +148,8 @@ msgstr "" msgid "Cannot extract transaction data" msgstr "" -#: apps/mobile/app/(app)/_layout.tsx:119 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:85 +#: apps/mobile/app/(app)/_layout.tsx:126 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:86 msgid "Categories" msgstr "" @@ -157,6 +161,10 @@ msgstr "" msgid "Choose a preferred theme for the 6pm" msgstr "" +#: apps/mobile/app/(app)/(tabs)/settings.tsx:99 +msgid "Coming soon" +msgstr "" + #: apps/mobile/components/auth/auth-email.tsx:161 msgid "Continue" msgstr "" @@ -213,11 +221,11 @@ msgstr "" msgid "Display name" msgstr "" -#: apps/mobile/app/(app)/_layout.tsx:113 +#: apps/mobile/app/(app)/_layout.tsx:120 msgid "Edit account" msgstr "" -#: apps/mobile/app/(app)/_layout.tsx:140 +#: apps/mobile/app/(app)/_layout.tsx:147 msgid "Edit category" msgstr "" @@ -266,11 +274,11 @@ msgstr "" msgid "From date" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:71 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:72 msgid "General" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:61 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:62 msgid "Get 6pm Pro" msgstr "" @@ -303,8 +311,8 @@ msgstr "" msgid "Keeping up with your spending and budgets." msgstr "" -#: apps/mobile/app/(app)/_layout.tsx:75 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:119 +#: apps/mobile/app/(app)/_layout.tsx:82 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:122 msgid "Language" msgstr "" @@ -320,11 +328,11 @@ msgstr "" msgid "Light" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:133 +#: apps/mobile/components/setting/set-local-auth.tsx:41 msgid "Login using FaceID" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:94 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:95 msgid "Magic inbox" msgstr "" @@ -354,17 +362,17 @@ msgstr "" msgid "New {0}" msgstr "" -#: apps/mobile/app/(app)/_layout.tsx:106 +#: apps/mobile/app/(app)/_layout.tsx:113 #: apps/mobile/app/(app)/wallet/accounts.tsx:26 msgid "New account" msgstr "" -#: apps/mobile/app/(app)/_layout.tsx:147 +#: apps/mobile/app/(app)/_layout.tsx:154 #: apps/mobile/app/(app)/(tabs)/_layout.tsx:80 msgid "New budget" msgstr "" -#: apps/mobile/app/(app)/_layout.tsx:133 +#: apps/mobile/app/(app)/_layout.tsx:140 msgid "New category" msgstr "" @@ -376,7 +384,7 @@ msgstr "" msgid "No transactions found" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:173 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:170 msgid "Others" msgstr "" @@ -400,7 +408,7 @@ msgstr "" msgid "Positive" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:178 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:175 msgid "Privacy policy" msgstr "" @@ -412,7 +420,7 @@ msgstr "" msgid "Processing transaction..." msgstr "" -#: apps/mobile/app/(app)/_layout.tsx:82 +#: apps/mobile/app/(app)/_layout.tsx:89 msgid "Profile" msgstr "" @@ -420,23 +428,23 @@ msgstr "" msgid "Profile updated successfully" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:211 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:208 msgid "Proudly open source" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:140 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:137 msgid "Push notifications" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:162 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:159 msgid "Push notifications are disabled" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:160 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:157 msgid "Push notifications are enabled" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:156 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:153 msgid "Push notifications are not enabled" msgstr "" @@ -444,7 +452,7 @@ msgstr "" msgid "Quarterly" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:195 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:192 msgid "Rate 6pm on App Store" msgstr "" @@ -490,7 +498,7 @@ msgstr "" msgid "Select period type" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:187 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:184 msgid "Send feedback" msgstr "" @@ -510,7 +518,7 @@ msgstr "" msgid "Settings" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:203 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:200 msgid "Share with friends" msgstr "" @@ -526,8 +534,8 @@ msgstr "" msgid "Sign in with Google" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:227 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:240 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:224 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:237 msgid "Sign out" msgstr "" @@ -615,10 +623,15 @@ msgstr "" #: apps/mobile/app/(app)/profile.tsx:50 #: apps/mobile/app/(app)/profile.tsx:61 +#: apps/mobile/components/setting/set-local-auth.tsx:31 msgid "Unknown error" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:64 +#: apps/mobile/components/auth/auth-local.tsx:39 +msgid "Unlock" +msgstr "" + +#: apps/mobile/app/(app)/(tabs)/settings.tsx:65 msgid "Unlocks full AI power and more!" msgstr "" @@ -626,7 +639,7 @@ msgstr "" msgid "Upload new photo" msgstr "" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:248 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:245 msgid "ver." msgstr "" @@ -642,8 +655,8 @@ msgstr "" msgid "Wallet account name" msgstr "" -#: apps/mobile/app/(app)/_layout.tsx:92 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:76 +#: apps/mobile/app/(app)/_layout.tsx:99 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:77 msgid "Wallet accounts" msgstr "" diff --git a/apps/mobile/locales/en/messages.ts b/apps/mobile/locales/en/messages.ts index 72132af4..fce5dd83 100644 --- a/apps/mobile/locales/en/messages.ts +++ b/apps/mobile/locales/en/messages.ts @@ -1,4 +1,4 @@ /*eslint-disable*/ import type { Messages } from '@lingui/core' export const messages: Messages = JSON.parse( - '{"J/hVSQ":[["0"]],"6MIiOI":[["0"]," left"],"FEZKSz":[["language"]],"GDr6hQ":"* you can always change this later.","VE5ikN":"<0><1>Manage your expense seamlessly<2>Let <3>6pm a good time to spend","ejSd6i":"<0>By continuing, you acknowledge that you understand and agree to our <1><2>Privacy Policy","AYTmQ1":"<0>By continuing, you acknowledge that you understand and agree to the <1><2>Terms & Conditions and <3><4>Privacy Policy","LjsgKU":"0.00","y+OdTP":"Account deleted successfully","103Xyi":"Add your first transaction here","sxkWRg":"Advanced","Mxjwaz":"All accounts","pXc4dB":"All Accounts","LcouyV":"All your data will be deleted","Vw8l6h":"An error occurred","bhrKSa":"An error occurred while deleting the transaction","rBd1BM":"An error occurred while updating the transaction","2Yw5Eq":"App settings","rg8lHb":"App theme","aAIQg2":"Appearance","rH4FJH":"Are you sure you want to delete this budget? This action cannot be undone.","TE1tui":"Are you sure you want to delete your account? This action cannot be undone.","apLLSU":"Are you sure you want to sign out?","6foA8n":"Are you sure?","X2pgJW":"Ask AI anything...","kfcRb0":"Avatar","fsBGk0":"Balance","IGsZpB":"Budgets","HjYcC9":"Camera permissions are not granted","dEgA5A":"Cancel","dZYaqU":"Cannot extract transaction data","NUrY9o":"Categories","i+de8A":"Category name","h4wXn9":"Choose a preferred theme for the 6pm","xGVfLh":"Continue","RvVi9c":"Continue with Email","PxMcud":"Current balance","AJToWu":"Current state","7cFjHo":"Daily reminder","Zz6Cxn":"Danger zone","pvnfJD":"Dark","o5ooMr":"Debt","WRwm0h":"Default currency","cnGeoo":"Delete","chkudi":"Delete 6pm account","VbtMs5":"Delete wallet account will also delete all related transactions!","pfa8F0":"Display name","rrOW2A":"Edit account","j1Jl7s":"Edit category","O3oNi5":"Email","QOINDn":"empty","ak+zF8":"Enable Push Notifications","/AHxlh":"Enable spending alerts","lYGfRP":"English","EmV+r3":"Enter the code sent to your email","xRPn3U":"Enter your email address","/o/2Tm":"Expense","aSBbnl":"Expenses","AL8ocL":"Family budget","xRJSOj":"From date","Weq9zb":"General","h52e9T":"Get 6pm Pro","EVORi1":"Get started by setting your monthly budget.","M1w7jC":"Grant camera permissions","Uq/imr":"If you\'re not sure, start with how much you usually spend per month.","xxsw3W":"Income","Z2b5qm":"Incomes","13aTWr":"Investing","AhuqH6":"Keeping up with your spending and budgets.","vXIe7J":"Language","brkKQW":"Left per day","PRzhQh":"Left this month","1njn7W":"Light","UC3YIm":"Login using FaceID","lkAlEG":"Magic inbox","+8Nek/":"Monthly","iBONBd":"Monthly budget","6YtxFj":"Name","xYG/fs":"Negative","XejmNR":"Negative if your content balance is under zero","6WSYbN":["New ",["0"]],"Kcr9Fr":"New account","5OdwzH":"New budget","tl5vsv":"New category","ApQ2nt":"No budget selected","8bNIKG":"No transactions found","NuKR0h":"Others","198luN":"per day","NtQvjo":"Period","66fYpz":"Period end date","QTWhG5":"Period start date","FHx6kz":"Positive","ScJ9fj":"Privacy policy","LcET2C":"Privacy Policy","Z8pOEI":"Processing transaction...","vERlcd":"Profile","kUlL8W":"Profile updated successfully","++8ZXz":"Proudly open source","SZJG6+":"Push notifications","r7QRqI":"Push notifications are disabled","LI1qx1":"Push notifications are enabled","3yhyIW":"Push notifications are not enabled","kCxe8K":"Quarterly","j75BA9":"Rate 6pm on App Store","tfDRzk":"Save","y3aU20":"Save changes","uF9ruK":"Saving","WDgJiV":"Scanner","P9vd26":"Search currency...","+O3PfQ":"Select account","HfaFKV":"Select balance state","PtoMco":"Select budget type","5dfUzo":"Select period type","RoafuO":"Send feedback","wCqgpu":"Set Budget","oyi6Xa":"Set Monthly Budget","dY304N":"Set your monthly spending goal","Tz0i8g":"Settings","RDprz0":"Share with friends","5lWFkC":"Sign in","+EnZBU":"Sign in with Apple","dbWo0h":"Sign in with Google","fcWrnU":"Sign out","e+RpCP":"Sign up","TOm5Xo":"Specific dates","Q14cFX":"Spending","w5QjWi":"Swift up to scan transaction","J8R0ve":"Swipe up to scan transaction","D+NlUC":"System","IL5Ibf":"Take a picture of your transaction","Yrrg+y":"Target","KWUgwY":"Terms & Conditions","Emv+V7":"Terms of use","OR1t9P":"This will delete the transaction. Are you sure you want to continue?","sH0pkc":"Time to enter your expenses!","w4eKlT":"To date","ecUA8p":"Today","BRMXj0":"Tomorrow","38Gho6":"Transaction created","6D8usS":"transaction note","+zy2Nq":"Type","b2vAoQ":"Uncategorized","Ef7StM":"Unknown","29VNqC":"Unknown error","QQX2/q":"Unlocks full AI power and more!","wPTug2":"Upload new photo","KALubG":"ver.","AdWhjZ":"Verification code","fROFIL":"Vietnamese","q19YJ1":"Wallet account name","rUcnTU":"Wallet accounts","mdad9N":"Wallet Accounts","4XSc4l":"Weekly","I+fC9+":"Welcome to 6pm!","zkWmBh":"Yearly","y/0uwd":"Yesterday","kDrMSv":"Your display name"}', + '{"J/hVSQ":[["0"]],"6MIiOI":[["0"]," left"],"FEZKSz":[["language"]],"GDr6hQ":"* you can always change this later.","VE5ikN":"<0><1>Manage your expense seamlessly<2>Let <3>6pm a good time to spend","ejSd6i":"<0>By continuing, you acknowledge that you understand and agree to our <1><2>Privacy Policy","AYTmQ1":"<0>By continuing, you acknowledge that you understand and agree to the <1><2>Terms & Conditions and <3><4>Privacy Policy","LjsgKU":"0.00","y+OdTP":"Account deleted successfully","103Xyi":"Add your first transaction here","sxkWRg":"Advanced","Mxjwaz":"All accounts","pXc4dB":"All Accounts","LcouyV":"All your data will be deleted","Vw8l6h":"An error occurred","bhrKSa":"An error occurred while deleting the transaction","rBd1BM":"An error occurred while updating the transaction","+FI+0t":"App is locked. Please authenticate to continue.","2Yw5Eq":"App settings","rg8lHb":"App theme","aAIQg2":"Appearance","rH4FJH":"Are you sure you want to delete this budget? This action cannot be undone.","TE1tui":"Are you sure you want to delete your account? This action cannot be undone.","apLLSU":"Are you sure you want to sign out?","6foA8n":"Are you sure?","X2pgJW":"Ask AI anything...","kfcRb0":"Avatar","fsBGk0":"Balance","IGsZpB":"Budgets","HjYcC9":"Camera permissions are not granted","dEgA5A":"Cancel","dZYaqU":"Cannot extract transaction data","NUrY9o":"Categories","i+de8A":"Category name","h4wXn9":"Choose a preferred theme for the 6pm","AUYALh":"Coming soon","xGVfLh":"Continue","RvVi9c":"Continue with Email","PxMcud":"Current balance","AJToWu":"Current state","7cFjHo":"Daily reminder","Zz6Cxn":"Danger zone","pvnfJD":"Dark","o5ooMr":"Debt","WRwm0h":"Default currency","cnGeoo":"Delete","chkudi":"Delete 6pm account","VbtMs5":"Delete wallet account will also delete all related transactions!","pfa8F0":"Display name","rrOW2A":"Edit account","j1Jl7s":"Edit category","O3oNi5":"Email","QOINDn":"empty","ak+zF8":"Enable Push Notifications","/AHxlh":"Enable spending alerts","lYGfRP":"English","EmV+r3":"Enter the code sent to your email","xRPn3U":"Enter your email address","/o/2Tm":"Expense","aSBbnl":"Expenses","AL8ocL":"Family budget","xRJSOj":"From date","Weq9zb":"General","h52e9T":"Get 6pm Pro","EVORi1":"Get started by setting your monthly budget.","M1w7jC":"Grant camera permissions","Uq/imr":"If you\'re not sure, start with how much you usually spend per month.","xxsw3W":"Income","Z2b5qm":"Incomes","13aTWr":"Investing","AhuqH6":"Keeping up with your spending and budgets.","vXIe7J":"Language","brkKQW":"Left per day","PRzhQh":"Left this month","1njn7W":"Light","UC3YIm":"Login using FaceID","lkAlEG":"Magic inbox","+8Nek/":"Monthly","iBONBd":"Monthly budget","6YtxFj":"Name","xYG/fs":"Negative","XejmNR":"Negative if your content balance is under zero","6WSYbN":["New ",["0"]],"Kcr9Fr":"New account","5OdwzH":"New budget","tl5vsv":"New category","ApQ2nt":"No budget selected","8bNIKG":"No transactions found","NuKR0h":"Others","198luN":"per day","NtQvjo":"Period","66fYpz":"Period end date","QTWhG5":"Period start date","FHx6kz":"Positive","ScJ9fj":"Privacy policy","LcET2C":"Privacy Policy","Z8pOEI":"Processing transaction...","vERlcd":"Profile","kUlL8W":"Profile updated successfully","++8ZXz":"Proudly open source","SZJG6+":"Push notifications","r7QRqI":"Push notifications are disabled","LI1qx1":"Push notifications are enabled","3yhyIW":"Push notifications are not enabled","kCxe8K":"Quarterly","j75BA9":"Rate 6pm on App Store","tfDRzk":"Save","y3aU20":"Save changes","uF9ruK":"Saving","WDgJiV":"Scanner","P9vd26":"Search currency...","+O3PfQ":"Select account","HfaFKV":"Select balance state","PtoMco":"Select budget type","5dfUzo":"Select period type","RoafuO":"Send feedback","wCqgpu":"Set Budget","oyi6Xa":"Set Monthly Budget","dY304N":"Set your monthly spending goal","Tz0i8g":"Settings","RDprz0":"Share with friends","5lWFkC":"Sign in","+EnZBU":"Sign in with Apple","dbWo0h":"Sign in with Google","fcWrnU":"Sign out","e+RpCP":"Sign up","TOm5Xo":"Specific dates","Q14cFX":"Spending","w5QjWi":"Swift up to scan transaction","J8R0ve":"Swipe up to scan transaction","D+NlUC":"System","IL5Ibf":"Take a picture of your transaction","Yrrg+y":"Target","KWUgwY":"Terms & Conditions","Emv+V7":"Terms of use","OR1t9P":"This will delete the transaction. Are you sure you want to continue?","sH0pkc":"Time to enter your expenses!","w4eKlT":"To date","ecUA8p":"Today","BRMXj0":"Tomorrow","38Gho6":"Transaction created","6D8usS":"transaction note","+zy2Nq":"Type","b2vAoQ":"Uncategorized","Ef7StM":"Unknown","29VNqC":"Unknown error","VAOn4r":"Unlock","QQX2/q":"Unlocks full AI power and more!","wPTug2":"Upload new photo","KALubG":"ver.","AdWhjZ":"Verification code","fROFIL":"Vietnamese","q19YJ1":"Wallet account name","rUcnTU":"Wallet accounts","mdad9N":"Wallet Accounts","4XSc4l":"Weekly","I+fC9+":"Welcome to 6pm!","zkWmBh":"Yearly","y/0uwd":"Yesterday","kDrMSv":"Your display name"}', ) diff --git a/apps/mobile/locales/vi/messages.po b/apps/mobile/locales/vi/messages.po index f8bd8255..81bab442 100644 --- a/apps/mobile/locales/vi/messages.po +++ b/apps/mobile/locales/vi/messages.po @@ -21,7 +21,7 @@ msgstr "" msgid "{0} left" msgstr "{0} còn lại" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:124 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:127 msgid "{language}" msgstr "" @@ -83,7 +83,11 @@ msgstr "Có lỗi xảy ra khi xóa giao dịch" msgid "An error occurred while updating the transaction" msgstr "Có lỗi xảy ra khi cập nhật giao dịch" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:105 +#: apps/mobile/components/auth/auth-local.tsx:34 +msgid "App is locked. Please authenticate to continue." +msgstr "Ứng dụng đã khóa. Vui lòng xác thực để tiếp tục." + +#: apps/mobile/app/(app)/(tabs)/settings.tsx:108 msgid "App settings" msgstr "Cài đặt ứng dụng" @@ -91,8 +95,8 @@ msgstr "Cài đặt ứng dụng" msgid "App theme" msgstr "Chủ đề ứng dụng" -#: apps/mobile/app/(app)/_layout.tsx:87 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:110 +#: apps/mobile/app/(app)/_layout.tsx:94 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:113 msgid "Appearance" msgstr "Giao diện" @@ -104,7 +108,7 @@ msgstr "Bạn có chắc chắn muốn xóa ngân sách này? Hành động này msgid "Are you sure you want to delete your account? This action cannot be undone." msgstr "Bạn có chắc chắn muốn xóa tài khoản của bạn? Hành động này không thể hoàn tác." -#: apps/mobile/app/(app)/(tabs)/settings.tsx:221 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:218 msgid "Are you sure you want to sign out?" msgstr "Bạn có chắc chắn muốn đăng xuất?" @@ -132,7 +136,7 @@ msgstr "Ngân sách" msgid "Camera permissions are not granted" msgstr "Quyền truy cập camera không được cấp" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:223 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:220 #: apps/mobile/app/(app)/budget/[budgetId]/edit.tsx:43 #: apps/mobile/app/(app)/profile.tsx:120 #: apps/mobile/app/(app)/transaction/[transactionId].tsx:77 @@ -144,8 +148,8 @@ msgstr "Huỷ" msgid "Cannot extract transaction data" msgstr "Không thể xử lý dữ liệu giao dịch" -#: apps/mobile/app/(app)/_layout.tsx:119 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:85 +#: apps/mobile/app/(app)/_layout.tsx:126 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:86 msgid "Categories" msgstr "Danh mục" @@ -157,6 +161,10 @@ msgstr "Tên danh mục" msgid "Choose a preferred theme for the 6pm" msgstr "Chọn chủ đề giao diện cho 6pm" +#: apps/mobile/app/(app)/(tabs)/settings.tsx:99 +msgid "Coming soon" +msgstr "Sắp xong" + #: apps/mobile/components/auth/auth-email.tsx:161 msgid "Continue" msgstr "Tiếp tục" @@ -213,11 +221,11 @@ msgstr "Xóa tài khoản ví sẽ cũng xóa tất cả các giao dịch liên msgid "Display name" msgstr "Tên hiển thị" -#: apps/mobile/app/(app)/_layout.tsx:113 +#: apps/mobile/app/(app)/_layout.tsx:120 msgid "Edit account" msgstr "Chỉnh sửa tài khoản" -#: apps/mobile/app/(app)/_layout.tsx:140 +#: apps/mobile/app/(app)/_layout.tsx:147 msgid "Edit category" msgstr "Chỉnh sửa danh mục" @@ -266,11 +274,11 @@ msgstr "Ngân sách gia đình" msgid "From date" msgstr "Từ ngày" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:71 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:72 msgid "General" msgstr "Chung" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:61 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:62 msgid "Get 6pm Pro" msgstr "Nâng Cấp 6pm Pro" @@ -303,8 +311,8 @@ msgstr "Đầu tư" msgid "Keeping up with your spending and budgets." msgstr "Theo dõi kịp tình hình chi tiêu và ngân sách." -#: apps/mobile/app/(app)/_layout.tsx:75 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:119 +#: apps/mobile/app/(app)/_layout.tsx:82 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:122 msgid "Language" msgstr "Ngôn ngữ" @@ -320,11 +328,11 @@ msgstr "Còn lại tháng này" msgid "Light" msgstr "Sáng" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:133 +#: apps/mobile/components/setting/set-local-auth.tsx:41 msgid "Login using FaceID" msgstr "Đăng nhập bằng FaceID" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:94 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:95 msgid "Magic inbox" msgstr "Hộp thư ma thuật" @@ -354,17 +362,17 @@ msgstr "Âm nếu số dư tài khoản dưới 0" msgid "New {0}" msgstr "Tạo mới {0}" -#: apps/mobile/app/(app)/_layout.tsx:106 +#: apps/mobile/app/(app)/_layout.tsx:113 #: apps/mobile/app/(app)/wallet/accounts.tsx:26 msgid "New account" msgstr "Tạo tài khoản mới" -#: apps/mobile/app/(app)/_layout.tsx:147 +#: apps/mobile/app/(app)/_layout.tsx:154 #: apps/mobile/app/(app)/(tabs)/_layout.tsx:80 msgid "New budget" msgstr "Tạo ngân sách" -#: apps/mobile/app/(app)/_layout.tsx:133 +#: apps/mobile/app/(app)/_layout.tsx:140 msgid "New category" msgstr "Tạo danh mục mới" @@ -376,7 +384,7 @@ msgstr "Chọn ngân sách" msgid "No transactions found" msgstr "Không tìm thấy giao dịch" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:173 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:170 msgid "Others" msgstr "Khác" @@ -400,7 +408,7 @@ msgstr "Ngày bắt đầu" msgid "Positive" msgstr "Dương" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:178 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:175 msgid "Privacy policy" msgstr "Chính sách bảo mật" @@ -412,7 +420,7 @@ msgstr "Chính sách bảo mật" msgid "Processing transaction..." msgstr "Đang xử lý giao dịch..." -#: apps/mobile/app/(app)/_layout.tsx:82 +#: apps/mobile/app/(app)/_layout.tsx:89 msgid "Profile" msgstr "Hồ sơ" @@ -420,23 +428,23 @@ msgstr "Hồ sơ" msgid "Profile updated successfully" msgstr "Cập nhật hồ sơ thành công" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:211 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:208 msgid "Proudly open source" msgstr "Mã nguồn mở" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:140 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:137 msgid "Push notifications" msgstr "Thông báo đẩy" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:162 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:159 msgid "Push notifications are disabled" msgstr "Thông báo đẩy bị vô hiệu hóa" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:160 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:157 msgid "Push notifications are enabled" msgstr "Thông báo đẩy đã được bật" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:156 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:153 msgid "Push notifications are not enabled" msgstr "Thông báo đẩy chưa được bật" @@ -444,7 +452,7 @@ msgstr "Thông báo đẩy chưa được bật" msgid "Quarterly" msgstr "Hàng quý" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:195 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:192 msgid "Rate 6pm on App Store" msgstr "Đánh giá 6pm trên App Store" @@ -490,7 +498,7 @@ msgstr "Chọn loại ngân sách" msgid "Select period type" msgstr "Chọn loại chu kỳ" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:187 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:184 msgid "Send feedback" msgstr "Gửi phản hồi" @@ -510,7 +518,7 @@ msgstr "Đặt mục tiêu chi tiêu hàng tháng" msgid "Settings" msgstr "Cài đặt" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:203 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:200 msgid "Share with friends" msgstr "Chia sẻ với bạn bè" @@ -526,8 +534,8 @@ msgstr "Tiếp tục với Apple" msgid "Sign in with Google" msgstr "Tiếp tục với Google" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:227 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:240 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:224 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:237 msgid "Sign out" msgstr "Đăng xuất" @@ -615,10 +623,15 @@ msgstr "Không xác định" #: apps/mobile/app/(app)/profile.tsx:50 #: apps/mobile/app/(app)/profile.tsx:61 +#: apps/mobile/components/setting/set-local-auth.tsx:31 msgid "Unknown error" msgstr "Lỗi không xác định" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:64 +#: apps/mobile/components/auth/auth-local.tsx:39 +msgid "Unlock" +msgstr "Mở khóa" + +#: apps/mobile/app/(app)/(tabs)/settings.tsx:65 msgid "Unlocks full AI power and more!" msgstr "Mở khóa sức mạnh AI và các tính năng khác!" @@ -626,7 +639,7 @@ msgstr "Mở khóa sức mạnh AI và các tính năng khác!" msgid "Upload new photo" msgstr "Tải lên ảnh mới" -#: apps/mobile/app/(app)/(tabs)/settings.tsx:248 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:245 msgid "ver." msgstr "" @@ -642,8 +655,8 @@ msgstr "Tiếng Việt" msgid "Wallet account name" msgstr "Tên tài khoản ví" -#: apps/mobile/app/(app)/_layout.tsx:92 -#: apps/mobile/app/(app)/(tabs)/settings.tsx:76 +#: apps/mobile/app/(app)/_layout.tsx:99 +#: apps/mobile/app/(app)/(tabs)/settings.tsx:77 msgid "Wallet accounts" msgstr "Quản lý tài khoản ví" diff --git a/apps/mobile/locales/vi/messages.ts b/apps/mobile/locales/vi/messages.ts index b2c3dd0b..261787e5 100644 --- a/apps/mobile/locales/vi/messages.ts +++ b/apps/mobile/locales/vi/messages.ts @@ -1,4 +1,4 @@ /*eslint-disable*/ import type { Messages } from '@lingui/core' export const messages: Messages = JSON.parse( - '{"J/hVSQ":[["0"]],"6MIiOI":[["0"]," còn lại"],"FEZKSz":[["language"]],"GDr6hQ":"* bạn có thể cập nhật lại sau.","VE5ikN":"<0><1>Quản lý chi tiêu hiệu quả<2>Không lo cháy túi mỗi <3>6pm","ejSd6i":"<0>Bằng cách tiếp tục, bạn đã hiểu và đồng ý với <1><2>Chính sách bảo mật của 6pm.","AYTmQ1":"<0>Bằng cách tiếp tục, bạn đã hiểu và đồng ý với <1><2>Điều khoản sử dụng và <3><4>Chính sách bảo mật của 6pm.","LjsgKU":"0.00","y+OdTP":"Xóa tài khoản thành công","103Xyi":"Thêm giao dịch đầu tiên ở đây","sxkWRg":"Nâng cao","Mxjwaz":"Tất cả tài khoản","pXc4dB":"Tất cả tài khoản","LcouyV":"Tất cả dữ liệu của bạn sẽ bị xóa","Vw8l6h":"Có lỗi xảy ra","bhrKSa":"Có lỗi xảy ra khi xóa giao dịch","rBd1BM":"Có lỗi xảy ra khi cập nhật giao dịch","2Yw5Eq":"Cài đặt ứng dụng","rg8lHb":"Chủ đề ứng dụng","aAIQg2":"Giao diện","rH4FJH":"Bạn có chắc chắn muốn xóa ngân sách này? Hành động này không thể hoàn tác.","TE1tui":"Bạn có chắc chắn muốn xóa tài khoản của bạn? Hành động này không thể hoàn tác.","apLLSU":"Bạn có chắc chắn muốn đăng xuất?","6foA8n":"Bạn chắc chưa?","X2pgJW":"Hỏi AI bất kỳ gì...","kfcRb0":"Ảnh đại diện","fsBGk0":"Số dư","IGsZpB":"Ngân sách","HjYcC9":"Quyền truy cập camera không được cấp","dEgA5A":"Huỷ","dZYaqU":"Không thể xử lý dữ liệu giao dịch","NUrY9o":"Danh mục","i+de8A":"Tên danh mục","h4wXn9":"Chọn chủ đề giao diện cho 6pm","xGVfLh":"Tiếp tục","RvVi9c":"Tiếp tục với Email","PxMcud":"Số dư hiện tại","AJToWu":"Trạng thái","7cFjHo":"Nhắc nhở hàng ngày","Zz6Cxn":"Vùng nguy hiểm","pvnfJD":"Tối","o5ooMr":"Nợ","WRwm0h":"Đơn vị mặc định","cnGeoo":"Xóa","chkudi":"Xóa tài khoản 6pm","VbtMs5":"Xóa tài khoản ví sẽ cũng xóa tất cả các giao dịch liên quan!","pfa8F0":"Tên hiển thị","rrOW2A":"Chỉnh sửa tài khoản","j1Jl7s":"Chỉnh sửa danh mục","O3oNi5":"Email","QOINDn":"trống","ak+zF8":"Bật Thông Báo Đẩy","/AHxlh":"Nhận thông báo chi tiêu","lYGfRP":"Tiếng Anh","EmV+r3":"Nhập mã xác nhận gửi đến email của bạn","xRPn3U":"Nhập địa chỉ email của bạn","/o/2Tm":"Chi tiêu","aSBbnl":"Chi tiêu","AL8ocL":"Ngân sách gia đình","xRJSOj":"Từ ngày","Weq9zb":"Chung","h52e9T":"Nâng Cấp 6pm Pro","EVORi1":"Bắt đầu bằng cách đặt ngân sách hàng tháng của bạn.","M1w7jC":"Cấp quyền truy cập camera","Uq/imr":"Nếu không chắc chắn, hãy nhập số tiền bạn thường chi tiêu hàng tháng.","xxsw3W":"Thu nhập","Z2b5qm":"Thu nhập","13aTWr":"Đầu tư","AhuqH6":"Theo dõi kịp tình hình chi tiêu và ngân sách.","vXIe7J":"Ngôn ngữ","brkKQW":"Còn lại mỗi ngày","PRzhQh":"Còn lại tháng này","1njn7W":"Sáng","UC3YIm":"Đăng nhập bằng FaceID","lkAlEG":"Hộp thư ma thuật","+8Nek/":"Hàng tháng","iBONBd":"Ngân sách tháng","6YtxFj":"Tên","xYG/fs":"Âm","XejmNR":"Âm nếu số dư tài khoản dưới 0","6WSYbN":["Tạo mới ",["0"]],"Kcr9Fr":"Tạo tài khoản mới","5OdwzH":"Tạo ngân sách","tl5vsv":"Tạo danh mục mới","ApQ2nt":"Chọn ngân sách","8bNIKG":"Không tìm thấy giao dịch","NuKR0h":"Khác","198luN":"mỗi ngày","NtQvjo":"Period","66fYpz":"Ngày kết thúc","QTWhG5":"Ngày bắt đầu","FHx6kz":"Dương","ScJ9fj":"Chính sách bảo mật","LcET2C":"Chính sách bảo mật","Z8pOEI":"Đang xử lý giao dịch...","vERlcd":"Hồ sơ","kUlL8W":"Cập nhật hồ sơ thành công","++8ZXz":"Mã nguồn mở","SZJG6+":"Thông báo đẩy","r7QRqI":"Thông báo đẩy bị vô hiệu hóa","LI1qx1":"Thông báo đẩy đã được bật","3yhyIW":"Thông báo đẩy chưa được bật","kCxe8K":"Hàng quý","j75BA9":"Đánh giá 6pm trên App Store","tfDRzk":"Lưu","y3aU20":"Lưu thay đổi","uF9ruK":"Đang lưu","WDgJiV":"Quét hoá đơn","P9vd26":"Tìm kiếm đơn vị...","+O3PfQ":"Chọn tài khoản","HfaFKV":"Chọn trạng thái số dư","PtoMco":"Chọn loại ngân sách","5dfUzo":"Chọn loại chu kỳ","RoafuO":"Gửi phản hồi","wCqgpu":"Lưu Ngân Sách","oyi6Xa":"Đặt Ngân Sách Tháng","dY304N":"Đặt mục tiêu chi tiêu hàng tháng","Tz0i8g":"Cài đặt","RDprz0":"Chia sẻ với bạn bè","5lWFkC":"Đăng nhập","+EnZBU":"Tiếp tục với Apple","dbWo0h":"Tiếp tục với Google","fcWrnU":"Đăng xuất","e+RpCP":"Đăng ký","TOm5Xo":"Ngày cụ thể","Q14cFX":"Chi tiêu","w5QjWi":"Vuốt lên để quét giao dịch","J8R0ve":"Vuốt lên để quét giao dịch","D+NlUC":"Hệ thống","IL5Ibf":"Chụp ảnh giao dịch của bạn","Yrrg+y":"Mục tiêu","KWUgwY":"Điều khoản sử dụng","Emv+V7":"Điều khoản sử dụng","OR1t9P":"Hành động này sẽ xóa giao dịch. Bạn có chắc chắn muốn tiếp tục không?","sH0pkc":"Đến giờ nhập chi tiêu hôm nay!","w4eKlT":"Đến ngày","ecUA8p":"Hôm nay","BRMXj0":"Ngày mai","38Gho6":"Giao dịch đã được tạo","6D8usS":"ghi chú giao dịch","+zy2Nq":"Loại","b2vAoQ":"Chưa phân loại","Ef7StM":"Không xác định","29VNqC":"Lỗi không xác định","QQX2/q":"Mở khóa sức mạnh AI và các tính năng khác!","wPTug2":"Tải lên ảnh mới","KALubG":"ver.","AdWhjZ":"Mã xác nhận","fROFIL":"Tiếng Việt","q19YJ1":"Tên tài khoản ví","rUcnTU":"Quản lý tài khoản ví","mdad9N":"Các tài khoản","4XSc4l":"Hàng tuần","I+fC9+":"Chào mừng đến 6pm!","zkWmBh":"Hàng năm","y/0uwd":"Hôm qua","kDrMSv":"Tên hiển thị của bạn"}', + '{"J/hVSQ":[["0"]],"6MIiOI":[["0"]," còn lại"],"FEZKSz":[["language"]],"GDr6hQ":"* bạn có thể cập nhật lại sau.","VE5ikN":"<0><1>Quản lý chi tiêu hiệu quả<2>Không lo cháy túi mỗi <3>6pm","ejSd6i":"<0>Bằng cách tiếp tục, bạn đã hiểu và đồng ý với <1><2>Chính sách bảo mật của 6pm.","AYTmQ1":"<0>Bằng cách tiếp tục, bạn đã hiểu và đồng ý với <1><2>Điều khoản sử dụng và <3><4>Chính sách bảo mật của 6pm.","LjsgKU":"0.00","y+OdTP":"Xóa tài khoản thành công","103Xyi":"Thêm giao dịch đầu tiên ở đây","sxkWRg":"Nâng cao","Mxjwaz":"Tất cả tài khoản","pXc4dB":"Tất cả tài khoản","LcouyV":"Tất cả dữ liệu của bạn sẽ bị xóa","Vw8l6h":"Có lỗi xảy ra","bhrKSa":"Có lỗi xảy ra khi xóa giao dịch","rBd1BM":"Có lỗi xảy ra khi cập nhật giao dịch","+FI+0t":"Ứng dụng đã khóa. Vui lòng xác thực để tiếp tục.","2Yw5Eq":"Cài đặt ứng dụng","rg8lHb":"Chủ đề ứng dụng","aAIQg2":"Giao diện","rH4FJH":"Bạn có chắc chắn muốn xóa ngân sách này? Hành động này không thể hoàn tác.","TE1tui":"Bạn có chắc chắn muốn xóa tài khoản của bạn? Hành động này không thể hoàn tác.","apLLSU":"Bạn có chắc chắn muốn đăng xuất?","6foA8n":"Bạn chắc chưa?","X2pgJW":"Hỏi AI bất kỳ gì...","kfcRb0":"Ảnh đại diện","fsBGk0":"Số dư","IGsZpB":"Ngân sách","HjYcC9":"Quyền truy cập camera không được cấp","dEgA5A":"Huỷ","dZYaqU":"Không thể xử lý dữ liệu giao dịch","NUrY9o":"Danh mục","i+de8A":"Tên danh mục","h4wXn9":"Chọn chủ đề giao diện cho 6pm","AUYALh":"Sắp xong","xGVfLh":"Tiếp tục","RvVi9c":"Tiếp tục với Email","PxMcud":"Số dư hiện tại","AJToWu":"Trạng thái","7cFjHo":"Nhắc nhở hàng ngày","Zz6Cxn":"Vùng nguy hiểm","pvnfJD":"Tối","o5ooMr":"Nợ","WRwm0h":"Đơn vị mặc định","cnGeoo":"Xóa","chkudi":"Xóa tài khoản 6pm","VbtMs5":"Xóa tài khoản ví sẽ cũng xóa tất cả các giao dịch liên quan!","pfa8F0":"Tên hiển thị","rrOW2A":"Chỉnh sửa tài khoản","j1Jl7s":"Chỉnh sửa danh mục","O3oNi5":"Email","QOINDn":"trống","ak+zF8":"Bật Thông Báo Đẩy","/AHxlh":"Nhận thông báo chi tiêu","lYGfRP":"Tiếng Anh","EmV+r3":"Nhập mã xác nhận gửi đến email của bạn","xRPn3U":"Nhập địa chỉ email của bạn","/o/2Tm":"Chi tiêu","aSBbnl":"Chi tiêu","AL8ocL":"Ngân sách gia đình","xRJSOj":"Từ ngày","Weq9zb":"Chung","h52e9T":"Nâng Cấp 6pm Pro","EVORi1":"Bắt đầu bằng cách đặt ngân sách hàng tháng của bạn.","M1w7jC":"Cấp quyền truy cập camera","Uq/imr":"Nếu không chắc chắn, hãy nhập số tiền bạn thường chi tiêu hàng tháng.","xxsw3W":"Thu nhập","Z2b5qm":"Thu nhập","13aTWr":"Đầu tư","AhuqH6":"Theo dõi kịp tình hình chi tiêu và ngân sách.","vXIe7J":"Ngôn ngữ","brkKQW":"Còn lại mỗi ngày","PRzhQh":"Còn lại tháng này","1njn7W":"Sáng","UC3YIm":"Đăng nhập bằng FaceID","lkAlEG":"Hộp thư ma thuật","+8Nek/":"Hàng tháng","iBONBd":"Ngân sách tháng","6YtxFj":"Tên","xYG/fs":"Âm","XejmNR":"Âm nếu số dư tài khoản dưới 0","6WSYbN":["Tạo mới ",["0"]],"Kcr9Fr":"Tạo tài khoản mới","5OdwzH":"Tạo ngân sách","tl5vsv":"Tạo danh mục mới","ApQ2nt":"Chọn ngân sách","8bNIKG":"Không tìm thấy giao dịch","NuKR0h":"Khác","198luN":"mỗi ngày","NtQvjo":"Period","66fYpz":"Ngày kết thúc","QTWhG5":"Ngày bắt đầu","FHx6kz":"Dương","ScJ9fj":"Chính sách bảo mật","LcET2C":"Chính sách bảo mật","Z8pOEI":"Đang xử lý giao dịch...","vERlcd":"Hồ sơ","kUlL8W":"Cập nhật hồ sơ thành công","++8ZXz":"Mã nguồn mở","SZJG6+":"Thông báo đẩy","r7QRqI":"Thông báo đẩy bị vô hiệu hóa","LI1qx1":"Thông báo đẩy đã được bật","3yhyIW":"Thông báo đẩy chưa được bật","kCxe8K":"Hàng quý","j75BA9":"Đánh giá 6pm trên App Store","tfDRzk":"Lưu","y3aU20":"Lưu thay đổi","uF9ruK":"Đang lưu","WDgJiV":"Quét hoá đơn","P9vd26":"Tìm kiếm đơn vị...","+O3PfQ":"Chọn tài khoản","HfaFKV":"Chọn trạng thái số dư","PtoMco":"Chọn loại ngân sách","5dfUzo":"Chọn loại chu kỳ","RoafuO":"Gửi phản hồi","wCqgpu":"Lưu Ngân Sách","oyi6Xa":"Đặt Ngân Sách Tháng","dY304N":"Đặt mục tiêu chi tiêu hàng tháng","Tz0i8g":"Cài đặt","RDprz0":"Chia sẻ với bạn bè","5lWFkC":"Đăng nhập","+EnZBU":"Tiếp tục với Apple","dbWo0h":"Tiếp tục với Google","fcWrnU":"Đăng xuất","e+RpCP":"Đăng ký","TOm5Xo":"Ngày cụ thể","Q14cFX":"Chi tiêu","w5QjWi":"Vuốt lên để quét giao dịch","J8R0ve":"Vuốt lên để quét giao dịch","D+NlUC":"Hệ thống","IL5Ibf":"Chụp ảnh giao dịch của bạn","Yrrg+y":"Mục tiêu","KWUgwY":"Điều khoản sử dụng","Emv+V7":"Điều khoản sử dụng","OR1t9P":"Hành động này sẽ xóa giao dịch. Bạn có chắc chắn muốn tiếp tục không?","sH0pkc":"Đến giờ nhập chi tiêu hôm nay!","w4eKlT":"Đến ngày","ecUA8p":"Hôm nay","BRMXj0":"Ngày mai","38Gho6":"Giao dịch đã được tạo","6D8usS":"ghi chú giao dịch","+zy2Nq":"Loại","b2vAoQ":"Chưa phân loại","Ef7StM":"Không xác định","29VNqC":"Lỗi không xác định","VAOn4r":"Mở khóa","QQX2/q":"Mở khóa sức mạnh AI và các tính năng khác!","wPTug2":"Tải lên ảnh mới","KALubG":"ver.","AdWhjZ":"Mã xác nhận","fROFIL":"Tiếng Việt","q19YJ1":"Tên tài khoản ví","rUcnTU":"Quản lý tài khoản ví","mdad9N":"Các tài khoản","4XSc4l":"Hàng tuần","I+fC9+":"Chào mừng đến 6pm!","zkWmBh":"Hàng năm","y/0uwd":"Hôm qua","kDrMSv":"Tên hiển thị của bạn"}', ) diff --git a/apps/mobile/package.json b/apps/mobile/package.json index a15473bd..6cfe65cb 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -71,6 +71,7 @@ "expo-image-picker": "~15.0.7", "expo-linear-gradient": "~13.0.2", "expo-linking": "~6.3.1", + "expo-local-authentication": "~14.0.1", "expo-localization": "^15.0.3", "expo-notifications": "~0.28.15", "expo-router": "~3.5.15", diff --git a/apps/mobile/stores/user-settings/store.ts b/apps/mobile/stores/user-settings/store.ts index c63dd84c..71505055 100644 --- a/apps/mobile/stores/user-settings/store.ts +++ b/apps/mobile/stores/user-settings/store.ts @@ -7,6 +7,8 @@ interface UserSettingsStore { setPreferredCurrency: (preferredCurrency: string) => void enabledPushNotifications: boolean setEnabledPushNotifications: (enabledPushNotifications: boolean) => void + enabledLocalAuth: boolean + setEnabledLocalAuth: (enabledLocalAuth: boolean) => void } export const useUserSettingsStore = create()( @@ -17,6 +19,8 @@ export const useUserSettingsStore = create()( enabledPushNotifications: false, setEnabledPushNotifications: (enabledPushNotifications) => set({ enabledPushNotifications }), + enabledLocalAuth: false, + setEnabledLocalAuth: (enabledLocalAuth) => set({ enabledLocalAuth }), }), { name: 'user-settings-storage', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 83a583c4..0f32a2f2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -264,6 +264,9 @@ importers: expo-linking: specifier: ~6.3.1 version: 6.3.1(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))) + expo-local-authentication: + specifier: ~14.0.1 + version: 14.0.1(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))) expo-localization: specifier: ^15.0.3 version: 15.0.3(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))) @@ -4254,6 +4257,11 @@ packages: expo-linking@6.3.1: resolution: {integrity: sha512-xuZCntSBGWCD/95iZ+mTUGTwHdy8Sx+immCqbUBxdvZ2TN61P02kKg7SaLS8A4a/hLrSCwrg5tMMwu5wfKr35g==} + expo-local-authentication@14.0.1: + resolution: {integrity: sha512-kAwUD1wEqj1fhwQgIHlP4H/JV9AcX+NO3BJwhPM2HuCFS0kgx2wvcHisnKBSTRyl8u5Jt4odzMyQkDJystwUTg==} + peerDependencies: + expo: '*' + expo-localization@15.0.3: resolution: {integrity: sha512-IfcmlKuKRlowR9qIzL0e+nGHBeNoF7l2GQaOJstc7HZiPjNJ4J1R4D53ZNf483dt7JSkTRJBihdTadOtOEjRdg==} peerDependencies: @@ -12368,6 +12376,11 @@ snapshots: - expo - supports-color + expo-local-authentication@14.0.1(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))): + dependencies: + expo: 51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7)) + invariant: 2.2.4 + expo-localization@15.0.3(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))): dependencies: expo: 51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))