feat: Add WhatsApp verification & responsive dialogs
✅ COMPLETED FEATURES: 1. WhatsApp Number Verification - Verify phone number is registered on WhatsApp before saving - Use OTP webhook with check_number mode - Show error if number not registered - Translated error messages 2. Responsive Dialog/Drawer System - Created ResponsiveDialog component - Desktop: Uses Dialog (modal) - Mobile: Uses Drawer (bottom sheet) - Applied to WalletDialog & TransactionDialog - Better UX on mobile devices 3. Translation Fixes - Fixed editProfile key placement - All translation keys now consistent - Build passing without errors 📱 MOBILE IMPROVEMENTS: - Form dialogs now slide up from bottom on mobile - Better touch interaction - More native mobile feel 🔧 TECHNICAL: - Added shadcn Drawer component - Created useMediaQuery hook - Responsive context wrapper - Type-safe implementation
This commit is contained in:
@@ -2,6 +2,7 @@ export const en = {
|
||||
common: {
|
||||
search: 'Search',
|
||||
filter: 'Filter',
|
||||
clearAll: 'Clear All',
|
||||
add: 'Add',
|
||||
edit: 'Edit',
|
||||
delete: 'Delete',
|
||||
@@ -23,6 +24,9 @@ export const en = {
|
||||
inactive: 'Inactive',
|
||||
yes: 'Yes',
|
||||
no: 'No',
|
||||
type: 'Type',
|
||||
showFilters: 'Show Filters',
|
||||
hideFilters: 'Hide Filters',
|
||||
},
|
||||
|
||||
nav: {
|
||||
@@ -35,6 +39,11 @@ export const en = {
|
||||
|
||||
overview: {
|
||||
title: 'Overview',
|
||||
description: 'Your financial dashboard and quick actions',
|
||||
overviewPeriod: 'Overview Period',
|
||||
overviewPeriodPlaceholder: 'Select period',
|
||||
customStartDatePlaceholder: 'Pick start date',
|
||||
customEndDatePlaceholder: 'Pick end date',
|
||||
totalBalance: 'Total Balance',
|
||||
totalIncome: 'Total Income',
|
||||
totalExpense: 'Total Expense',
|
||||
@@ -44,23 +53,41 @@ export const en = {
|
||||
recentTransactions: 'Recent Transactions',
|
||||
viewAll: 'View All',
|
||||
noTransactions: 'No transactions yet',
|
||||
addFirstTransaction: 'Add your first transaction',
|
||||
addTransaction: 'Add transaction',
|
||||
wallets: 'Wallets',
|
||||
walletsDescription: 'Balance distribution across wallets',
|
||||
walletTheadName: 'Name',
|
||||
walletTheadCurrencyUnit: 'Currency/Unit',
|
||||
walletTheadTransactions: 'Transactions',
|
||||
walletTheadTotalBalance: 'Total Balance',
|
||||
walletTheadDomination: 'Domination',
|
||||
addWallet: 'Add Wallet',
|
||||
noWallets: 'No wallets yet',
|
||||
createFirstWallet: 'Create your first wallet',
|
||||
incomeByCategory: 'Income by Category',
|
||||
incomeCategoryFor: 'Income category for',
|
||||
expenseByCategory: 'Expense by Category',
|
||||
expenseCategoryFor: 'Expense category for',
|
||||
categoryAllWalletOption: 'All Wallets',
|
||||
last30Days: 'Last 30 days',
|
||||
last7Days: 'Last 7 days',
|
||||
thisMonth: 'This month',
|
||||
lastMonth: 'Last month',
|
||||
thisYear: 'This year',
|
||||
lastYear: 'Last year',
|
||||
allTime: 'All time',
|
||||
custom: 'Custom',
|
||||
financialTrend: 'Financial Trend',
|
||||
financialTrendDescription: 'Income vs Expense over time',
|
||||
financialTrendOverTimeMonthly: 'Monthly',
|
||||
financialTrendOverTimeWeekly: 'Weekly',
|
||||
financialTrendOverTimeDaily: 'Daily',
|
||||
financialTrendOverTimeYearly: 'Yearly',
|
||||
},
|
||||
|
||||
transactions: {
|
||||
title: 'Transactions',
|
||||
description: 'View and manage all your transactions',
|
||||
addTransaction: 'Add Transaction',
|
||||
editTransaction: 'Edit Transaction',
|
||||
deleteConfirm: 'Are you sure you want to delete this transaction?',
|
||||
@@ -69,11 +96,34 @@ export const en = {
|
||||
category: 'Category',
|
||||
memo: 'Memo',
|
||||
wallet: 'Wallet',
|
||||
direction: 'Type',
|
||||
filterByWallet: 'Filter by Wallet',
|
||||
filterByDirection: 'Filter by Type',
|
||||
filterByCategory: 'Filter by Category',
|
||||
searchPlaceholder: 'Search transactions...',
|
||||
direction: 'Direction',
|
||||
tableTitle: 'Transactions',
|
||||
tableDescription: 'All your transactions',
|
||||
tableFiltered: 'Filtered from {count} transactions',
|
||||
tableTheadDate: 'Date',
|
||||
tableTheadAmount: 'Amount',
|
||||
tableTheadDirection: 'Direction',
|
||||
tableTheadCategory: 'Category',
|
||||
tableTheadMemo: 'Memo',
|
||||
tableTheadWallet: 'Wallet',
|
||||
tableTheadActions: 'Actions',
|
||||
filter: {
|
||||
searchMemo: 'Search Memo',
|
||||
searchMemoPlaceholder: 'Search in memo...',
|
||||
wallet: 'Wallet',
|
||||
walletPlaceholder: 'Select wallet',
|
||||
walletAllWallets: 'All Wallets',
|
||||
direction: 'Direction',
|
||||
directionPlaceholder: 'Select direction',
|
||||
minAmount: 'Min Amount',
|
||||
minAmountPlaceholder: '0',
|
||||
maxAmount: 'Max Amount',
|
||||
maxAmountPlaceholder: 'No limit',
|
||||
fromDate: 'From Date',
|
||||
toDate: 'To Date',
|
||||
fromDatePlaceholder: 'Select start date',
|
||||
toDatePlaceholder: 'Select end date',
|
||||
},
|
||||
noTransactions: 'No transactions',
|
||||
stats: {
|
||||
totalIncome: 'Total Income',
|
||||
@@ -84,6 +134,7 @@ export const en = {
|
||||
|
||||
wallets: {
|
||||
title: 'Wallets',
|
||||
description: 'Manage your wallets and accounts',
|
||||
addWallet: 'Add Wallet',
|
||||
editWallet: 'Edit Wallet',
|
||||
deleteConfirm: 'Are you sure you want to delete this wallet? All related transactions will be deleted.',
|
||||
@@ -103,11 +154,14 @@ export const en = {
|
||||
totalBalance: 'Total Balance',
|
||||
moneyWallets: 'Money Wallets',
|
||||
assetWallets: 'Asset Wallets',
|
||||
allWallets: 'All Wallets',
|
||||
filterDesc: 'Filtered from {count} total wallets',
|
||||
},
|
||||
|
||||
walletDialog: {
|
||||
addTitle: 'Add Wallet',
|
||||
editTitle: 'Edit Wallet',
|
||||
description: 'Fill in the details of your wallet',
|
||||
name: 'Wallet Name',
|
||||
namePlaceholder: 'e.g., Main Wallet, Savings',
|
||||
type: 'Wallet Type',
|
||||
@@ -122,11 +176,21 @@ export const en = {
|
||||
pricePerUnit: 'Price per Unit (Optional)',
|
||||
pricePerUnitPlaceholder: '0',
|
||||
pricePerUnitHelper: 'Price per {unit} in IDR',
|
||||
addSuccess: 'Wallet added successfully',
|
||||
editSuccess: 'Wallet updated successfully',
|
||||
saveError: 'Failed to save wallet',
|
||||
deleteSuccess: 'Wallet deleted successfully',
|
||||
deleteError: 'Failed to delete wallet',
|
||||
deleteConfirm: 'Are you sure you want to delete this wallet? All related transactions will be deleted.',
|
||||
deleteConfirmTitle: 'Delete Wallet',
|
||||
deleteConfirmCancel: 'Cancel',
|
||||
deleteConfirmDelete: 'Delete',
|
||||
},
|
||||
|
||||
transactionDialog: {
|
||||
addTitle: 'Add Transaction',
|
||||
editTitle: 'Edit Transaction',
|
||||
description: 'Fill in the details of your transaction',
|
||||
amount: 'Amount',
|
||||
amountPlaceholder: '0',
|
||||
wallet: 'Wallet',
|
||||
@@ -141,17 +205,37 @@ export const en = {
|
||||
memoPlaceholder: 'Add a note...',
|
||||
date: 'Date',
|
||||
selectDate: 'Select date',
|
||||
addSuccess: 'Transaction added successfully',
|
||||
editSuccess: 'Transaction updated successfully',
|
||||
saveError: 'Failed to save transaction',
|
||||
deleteSuccess: 'Transaction deleted successfully',
|
||||
deleteError: 'Failed to delete transaction',
|
||||
deleteConfirm: 'Are you sure you want to delete this transaction? This action cannot be undone.',
|
||||
deleteConfirmTitle: 'Delete Transaction',
|
||||
deleteConfirmCancel: 'Cancel',
|
||||
deleteConfirmDelete: 'Delete',
|
||||
},
|
||||
|
||||
profile: {
|
||||
title: 'Profile',
|
||||
description: 'Manage your account settings and security preferences',
|
||||
editProfile: 'Edit Profile',
|
||||
personalInfo: 'Personal Information',
|
||||
name: 'Name',
|
||||
nameSynced: 'Name is synced from your Google account',
|
||||
edit: 'Edit',
|
||||
save: 'Save',
|
||||
update: 'Update',
|
||||
cancel: 'Cancel',
|
||||
email: 'Email',
|
||||
emailVerified: 'Email Verified',
|
||||
emailNotVerified: 'Email Not Verified',
|
||||
emailCannotBeChanged: 'Email cannot be changed',
|
||||
avatar: 'Avatar',
|
||||
changeAvatar: 'Change Avatar',
|
||||
uploadAvatar: 'Upload Avatar',
|
||||
avatarSynced: 'Avatar is synced from your Google account',
|
||||
clickUploadAvatar: 'Click the upload button to change your avatar',
|
||||
uploading: 'Uploading...',
|
||||
|
||||
security: 'Security',
|
||||
@@ -160,17 +244,27 @@ export const en = {
|
||||
newPassword: 'New Password',
|
||||
confirmPassword: 'Confirm New Password',
|
||||
changePassword: 'Change Password',
|
||||
setPassword: 'Set Password',
|
||||
noPassword: 'You logged in with Google and haven\'t set a password yet',
|
||||
setPasswordDesc: 'Set a password to enable password-based login and account deletion',
|
||||
changePasswordDesc: 'Update your password to keep your account secure',
|
||||
googleAuthDesc: 'Your account uses Google Sign-In. Setting a password will allow you to login with email/password and delete your account if needed.',
|
||||
setting: 'Setting...',
|
||||
updating: 'Updating...',
|
||||
setPassword: 'Set Password',
|
||||
updatePassword: 'Update Password',
|
||||
|
||||
twoFactor: 'Two-Factor Authentication',
|
||||
twoFactorDesc: 'Add an extra layer of security to your account',
|
||||
phoneNumber: 'Phone Number',
|
||||
phoneNumberPlaceholder: '+62812345678',
|
||||
updatePhone: 'Update Phone',
|
||||
phoneNumberDescription: 'Required for WhatsApp OTP verification',
|
||||
|
||||
emailOtp: 'Email OTP',
|
||||
emailOtpDesc: 'Receive verification codes via email',
|
||||
enableEmailOtp: 'Enable Email OTP',
|
||||
disableEmailOtp: 'Disable Email OTP',
|
||||
checkYourEmailForTheVerificationCode: 'Check your email for the verification code',
|
||||
enable: 'Enable',
|
||||
disable: 'Disable',
|
||||
enabled: 'Enabled',
|
||||
@@ -181,20 +275,35 @@ export const en = {
|
||||
|
||||
whatsappOtp: 'WhatsApp OTP',
|
||||
whatsappOtpDesc: 'Receive verification codes via WhatsApp',
|
||||
enableWhatsAppOtp: 'Enable WhatsApp OTP',
|
||||
disableWhatsAppOtp: 'Disable WhatsApp OTP',
|
||||
pleaseAddYourPhoneNumberInTheEditProfileTabFirst: 'Please add your phone number in the Edit Profile tab first',
|
||||
checkYourWhatsAppForTheVerificationCodeOrCheckConsoleInTestMode: 'Check your WhatsApp for the verification code',
|
||||
enterVerificationCode: 'Enter 6 digit code',
|
||||
|
||||
authenticatorApp: 'Authenticator App',
|
||||
authenticatorDesc: 'Use an authenticator app like Google Authenticator',
|
||||
setup: 'Setup',
|
||||
authenticatorSetupInstruction: 'Setup Instructions:',
|
||||
autentucatorSetupInstruction_1: 'Open your authenticator app (Google Authenticator, Authy, etc.)',
|
||||
autentucatorSetupInstruction_2: 'Scan the QR code or manually enter the secret key',
|
||||
autentucatorSetupInstruction_3: 'Enter the 6-digit code from your app below',
|
||||
setupSecretKey: 'Secret Key (if you can\'t scan QR code):',
|
||||
enableAuthenticatorApp: 'Enable Authenticator App',
|
||||
disableAuthenticatorApp: 'Disable Authenticator App',
|
||||
scanQr: 'Scan QR Code',
|
||||
scanQrDesc: 'Scan this QR code with your authenticator app',
|
||||
manualEntry: 'Or enter this code manually:',
|
||||
enterAuthCode: 'Enter code from your authenticator app',
|
||||
|
||||
dangerZone: 'Danger Zone',
|
||||
dangerZoneDesc: 'Irreversible actions that will permanently affect your account',
|
||||
deleteAccount: 'Delete Account',
|
||||
deleteAccountDesc: 'Permanently delete your account. This action cannot be undone.',
|
||||
deleteAccountDesc: 'Once you delete your account, there is no going back. This will permanently delete your account, all your data, transactions, and settings.',
|
||||
deletePasswordRequired: 'You must set a password first before you can delete your account. Go to "Set Password" above.',
|
||||
deleteAccountConfirm: 'Are you sure you want to delete your account? All data will be permanently lost.',
|
||||
enterPasswordToDelete: 'Enter your password to confirm',
|
||||
deleting: 'Deleting...',
|
||||
yesDeleteMyAccount: 'Yes, Delete My Account',
|
||||
},
|
||||
|
||||
dateRange: {
|
||||
|
||||
Reference in New Issue
Block a user