Merge pull request #16 from whtvrboo/i18n-pages-partial
feat: Add missing i18n translations for page components (partial)
This commit is contained in:
commit
b0ec84b8ca
@ -73,7 +73,10 @@
|
|||||||
"groupNameRequired": "DE: Group name is required",
|
"groupNameRequired": "DE: Group name is required",
|
||||||
"createFailed": "DE: Failed to create group. Please try again.",
|
"createFailed": "DE: Failed to create group. Please try again.",
|
||||||
"inviteCodeRequired": "DE: Invite code is required",
|
"inviteCodeRequired": "DE: Invite code is required",
|
||||||
"joinFailed": "DE: Failed to join group. Please check the invite code and try again."
|
"joinFailed": "DE: Failed to join group. Please check the invite code and try again.",
|
||||||
|
"invalidDataFromServer": "[TRANSLATE] Invalid data received from server.",
|
||||||
|
"createFailedConsole": "[TRANSLATE] Error creating group:",
|
||||||
|
"joinFailedConsole": "[TRANSLATE] Error joining group:"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"groupCreatedSuccess": "DE: Group '{groupName}' created successfully.",
|
"groupCreatedSuccess": "DE: Group '{groupName}' created successfully.",
|
||||||
@ -85,7 +88,8 @@
|
|||||||
"authCallbackPage": {
|
"authCallbackPage": {
|
||||||
"redirecting": "DE: Redirecting...",
|
"redirecting": "DE: Redirecting...",
|
||||||
"errors": {
|
"errors": {
|
||||||
"authenticationFailed": "DE: Authentication failed"
|
"authenticationFailed": "DE: Authentication failed",
|
||||||
|
"noTokenProvided": "[TRANSLATE] No token provided"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"choresPage": {
|
"choresPage": {
|
||||||
@ -165,7 +169,17 @@
|
|||||||
"quickDueDateTomorrow": "DE: Tomorrow",
|
"quickDueDateTomorrow": "DE: Tomorrow",
|
||||||
"quickDueDateNextWeek": "DE: Next Week",
|
"quickDueDateNextWeek": "DE: Next Week",
|
||||||
"cancelButton": "DE: Cancel",
|
"cancelButton": "DE: Cancel",
|
||||||
"saveButton": "DE: Save"
|
"saveButton": "DE: Save",
|
||||||
|
"intervalPlaceholder": "[TRANSLATE] e.g., 10"
|
||||||
|
},
|
||||||
|
"consoleErrors": {
|
||||||
|
"loadFailed": "[TRANSLATE] Failed to load all chores:",
|
||||||
|
"loadGroupsFailed": "[TRANSLATE] Failed to load groups",
|
||||||
|
"createAssignmentForNewChoreFailed": "[TRANSLATE] Failed to create assignment for new chore:",
|
||||||
|
"saveFailed": "[TRANSLATE] Failed to save chore:",
|
||||||
|
"deleteFailed": "[TRANSLATE] Failed to delete chore:",
|
||||||
|
"createAssignmentFailed": "[TRANSLATE] Failed to create assignment:",
|
||||||
|
"updateCompletionStatusFailed": "[TRANSLATE] Failed to update chore completion status:"
|
||||||
},
|
},
|
||||||
"deleteDialog": {
|
"deleteDialog": {
|
||||||
"title": "DE: Delete Chore",
|
"title": "DE: Delete Chore",
|
||||||
@ -228,10 +242,14 @@
|
|||||||
"title": "DE: Group Members",
|
"title": "DE: Group Members",
|
||||||
"defaultRole": "DE: Member",
|
"defaultRole": "DE: Member",
|
||||||
"removeButton": "DE: Remove",
|
"removeButton": "DE: Remove",
|
||||||
"emptyState": "DE: No members found."
|
"emptyState": "DE: No members found.",
|
||||||
|
"closeMenuLabel": "[TRANSLATE] Close menu"
|
||||||
},
|
},
|
||||||
"invites": {
|
"invites": {
|
||||||
"title": "DE: Invite Members",
|
"title": "DE: Invite Members",
|
||||||
|
"description": "[TRANSLATE] Invite new members by generating a shareable code.",
|
||||||
|
"addMemberButtonLabel": "[TRANSLATE] Add member",
|
||||||
|
"closeInviteLabel": "[TRANSLATE] Close invite",
|
||||||
"regenerateButton": "DE: Regenerate Invite Code",
|
"regenerateButton": "DE: Regenerate Invite Code",
|
||||||
"generateButton": "DE: Generate Invite Code",
|
"generateButton": "DE: Generate Invite Code",
|
||||||
"activeCodeLabel": "DE: Current Active Invite Code:",
|
"activeCodeLabel": "DE: Current Active Invite Code:",
|
||||||
@ -242,6 +260,15 @@
|
|||||||
"newDataInvalid": "DE: New invite code data is invalid."
|
"newDataInvalid": "DE: New invite code data is invalid."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"errors": {
|
||||||
|
"failedToFetchActiveInvite": "[TRANSLATE] Failed to fetch active invite code.",
|
||||||
|
"failedToFetchGroupDetails": "[TRANSLATE] Failed to fetch group details.",
|
||||||
|
"failedToLoadUpcomingChores": "[TRANSLATE] Error loading upcoming chores:",
|
||||||
|
"failedToLoadRecentExpenses": "[TRANSLATE] Error loading recent expenses:"
|
||||||
|
},
|
||||||
|
"console": {
|
||||||
|
"noActiveInvite": "[TRANSLATE] No active invite code found for this group."
|
||||||
|
},
|
||||||
"chores": {
|
"chores": {
|
||||||
"title": "DE: Group Chores",
|
"title": "DE: Group Chores",
|
||||||
"manageButton": "DE: Manage Chores",
|
"manageButton": "DE: Manage Chores",
|
||||||
@ -252,6 +279,8 @@
|
|||||||
"title": "DE: Group Expenses",
|
"title": "DE: Group Expenses",
|
||||||
"manageButton": "DE: Manage Expenses",
|
"manageButton": "DE: Manage Expenses",
|
||||||
"emptyState": "DE: No expenses recorded. Click \"Manage Expenses\" to add some!",
|
"emptyState": "DE: No expenses recorded. Click \"Manage Expenses\" to add some!",
|
||||||
|
"fallbackUserName": "[TRANSLATE] User ID: {userId}",
|
||||||
|
"activityByUserFallback": "[TRANSLATE] User {userId}",
|
||||||
"splitTypes": {
|
"splitTypes": {
|
||||||
"equal": "DE: Equal",
|
"equal": "DE: Equal",
|
||||||
"exactAmounts": "DE: Exact Amounts",
|
"exactAmounts": "DE: Exact Amounts",
|
||||||
|
@ -73,7 +73,10 @@
|
|||||||
"groupNameRequired": "Group name is required",
|
"groupNameRequired": "Group name is required",
|
||||||
"createFailed": "Failed to create group. Please try again.",
|
"createFailed": "Failed to create group. Please try again.",
|
||||||
"inviteCodeRequired": "Invite code is required",
|
"inviteCodeRequired": "Invite code is required",
|
||||||
"joinFailed": "Failed to join group. Please check the invite code and try again."
|
"joinFailed": "Failed to join group. Please check the invite code and try again.",
|
||||||
|
"invalidDataFromServer": "Invalid data received from server.",
|
||||||
|
"createFailedConsole": "Error creating group:",
|
||||||
|
"joinFailedConsole": "Error joining group:"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"groupCreatedSuccess": "Group '{groupName}' created successfully.",
|
"groupCreatedSuccess": "Group '{groupName}' created successfully.",
|
||||||
@ -85,7 +88,8 @@
|
|||||||
"authCallbackPage": {
|
"authCallbackPage": {
|
||||||
"redirecting": "Redirecting...",
|
"redirecting": "Redirecting...",
|
||||||
"errors": {
|
"errors": {
|
||||||
"authenticationFailed": "Authentication failed"
|
"authenticationFailed": "Authentication failed",
|
||||||
|
"noTokenProvided": "No token provided"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"choresPage": {
|
"choresPage": {
|
||||||
@ -125,7 +129,17 @@
|
|||||||
"save": "Save Changes",
|
"save": "Save Changes",
|
||||||
"create": "Create",
|
"create": "Create",
|
||||||
"editChore": "Edit Chore",
|
"editChore": "Edit Chore",
|
||||||
"createChore": "Create Chore"
|
"createChore": "Create Chore",
|
||||||
|
"intervalPlaceholder": "e.g., 10"
|
||||||
|
},
|
||||||
|
"consoleErrors": {
|
||||||
|
"loadFailed": "Failed to load all chores:",
|
||||||
|
"loadGroupsFailed": "Failed to load groups",
|
||||||
|
"createAssignmentForNewChoreFailed": "Failed to create assignment for new chore:",
|
||||||
|
"saveFailed": "Failed to save chore:",
|
||||||
|
"deleteFailed": "Failed to delete chore:",
|
||||||
|
"createAssignmentFailed": "Failed to create assignment:",
|
||||||
|
"updateCompletionStatusFailed": "Failed to update chore completion status:"
|
||||||
},
|
},
|
||||||
"deleteConfirm": {
|
"deleteConfirm": {
|
||||||
"title": "Confirm Deletion",
|
"title": "Confirm Deletion",
|
||||||
@ -160,10 +174,14 @@
|
|||||||
"title": "Group Members",
|
"title": "Group Members",
|
||||||
"defaultRole": "Member",
|
"defaultRole": "Member",
|
||||||
"removeButton": "Remove",
|
"removeButton": "Remove",
|
||||||
"emptyState": "No members found."
|
"emptyState": "No members found.",
|
||||||
|
"closeMenuLabel": "Close menu"
|
||||||
},
|
},
|
||||||
"invites": {
|
"invites": {
|
||||||
"title": "Invite Members",
|
"title": "Invite Members",
|
||||||
|
"description": "Invite new members by generating a shareable code.",
|
||||||
|
"addMemberButtonLabel": "Add member",
|
||||||
|
"closeInviteLabel": "Close invite",
|
||||||
"regenerateButton": "Regenerate Invite Code",
|
"regenerateButton": "Regenerate Invite Code",
|
||||||
"generateButton": "Generate Invite Code",
|
"generateButton": "Generate Invite Code",
|
||||||
"activeCodeLabel": "Current Active Invite Code:",
|
"activeCodeLabel": "Current Active Invite Code:",
|
||||||
@ -174,6 +192,15 @@
|
|||||||
"newDataInvalid": "New invite code data is invalid."
|
"newDataInvalid": "New invite code data is invalid."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"errors": {
|
||||||
|
"failedToFetchActiveInvite": "Failed to fetch active invite code.",
|
||||||
|
"failedToFetchGroupDetails": "Failed to fetch group details.",
|
||||||
|
"failedToLoadUpcomingChores": "Error loading upcoming chores:",
|
||||||
|
"failedToLoadRecentExpenses": "Error loading recent expenses:"
|
||||||
|
},
|
||||||
|
"console": {
|
||||||
|
"noActiveInvite": "No active invite code found for this group."
|
||||||
|
},
|
||||||
"chores": {
|
"chores": {
|
||||||
"title": "Group Chores",
|
"title": "Group Chores",
|
||||||
"manageButton": "Manage Chores",
|
"manageButton": "Manage Chores",
|
||||||
@ -191,6 +218,8 @@
|
|||||||
"settleShareButton": "Settle My Share",
|
"settleShareButton": "Settle My Share",
|
||||||
"activityLabel": "Activity:",
|
"activityLabel": "Activity:",
|
||||||
"byUser": "by",
|
"byUser": "by",
|
||||||
|
"fallbackUserName": "User ID: {userId}",
|
||||||
|
"activityByUserFallback": "User {userId}",
|
||||||
"splitTypes": {
|
"splitTypes": {
|
||||||
"equal": "Equal",
|
"equal": "Equal",
|
||||||
"exactAmounts": "Exact Amounts",
|
"exactAmounts": "Exact Amounts",
|
||||||
|
@ -73,7 +73,10 @@
|
|||||||
"groupNameRequired": "ES: Group name is required",
|
"groupNameRequired": "ES: Group name is required",
|
||||||
"createFailed": "ES: Failed to create group. Please try again.",
|
"createFailed": "ES: Failed to create group. Please try again.",
|
||||||
"inviteCodeRequired": "ES: Invite code is required",
|
"inviteCodeRequired": "ES: Invite code is required",
|
||||||
"joinFailed": "ES: Failed to join group. Please check the invite code and try again."
|
"joinFailed": "ES: Failed to join group. Please check the invite code and try again.",
|
||||||
|
"invalidDataFromServer": "[TRANSLATE] Invalid data received from server.",
|
||||||
|
"createFailedConsole": "[TRANSLATE] Error creating group:",
|
||||||
|
"joinFailedConsole": "[TRANSLATE] Error joining group:"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"groupCreatedSuccess": "ES: Group '{groupName}' created successfully.",
|
"groupCreatedSuccess": "ES: Group '{groupName}' created successfully.",
|
||||||
@ -85,7 +88,8 @@
|
|||||||
"authCallbackPage": {
|
"authCallbackPage": {
|
||||||
"redirecting": "ES: Redirecting...",
|
"redirecting": "ES: Redirecting...",
|
||||||
"errors": {
|
"errors": {
|
||||||
"authenticationFailed": "ES: Authentication failed"
|
"authenticationFailed": "ES: Authentication failed",
|
||||||
|
"noTokenProvided": "[TRANSLATE] No token provided"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"choresPage": {
|
"choresPage": {
|
||||||
@ -165,7 +169,17 @@
|
|||||||
"quickDueDateTomorrow": "ES: Tomorrow",
|
"quickDueDateTomorrow": "ES: Tomorrow",
|
||||||
"quickDueDateNextWeek": "ES: Next Week",
|
"quickDueDateNextWeek": "ES: Next Week",
|
||||||
"cancelButton": "ES: Cancel",
|
"cancelButton": "ES: Cancel",
|
||||||
"saveButton": "ES: Save"
|
"saveButton": "ES: Save",
|
||||||
|
"intervalPlaceholder": "[TRANSLATE] e.g., 10"
|
||||||
|
},
|
||||||
|
"consoleErrors": {
|
||||||
|
"loadFailed": "[TRANSLATE] Failed to load all chores:",
|
||||||
|
"loadGroupsFailed": "[TRANSLATE] Failed to load groups",
|
||||||
|
"createAssignmentForNewChoreFailed": "[TRANSLATE] Failed to create assignment for new chore:",
|
||||||
|
"saveFailed": "[TRANSLATE] Failed to save chore:",
|
||||||
|
"deleteFailed": "[TRANSLATE] Failed to delete chore:",
|
||||||
|
"createAssignmentFailed": "[TRANSLATE] Failed to create assignment:",
|
||||||
|
"updateCompletionStatusFailed": "[TRANSLATE] Failed to update chore completion status:"
|
||||||
},
|
},
|
||||||
"deleteDialog": {
|
"deleteDialog": {
|
||||||
"title": "ES: Delete Chore",
|
"title": "ES: Delete Chore",
|
||||||
@ -228,10 +242,14 @@
|
|||||||
"title": "ES: Group Members",
|
"title": "ES: Group Members",
|
||||||
"defaultRole": "ES: Member",
|
"defaultRole": "ES: Member",
|
||||||
"removeButton": "ES: Remove",
|
"removeButton": "ES: Remove",
|
||||||
"emptyState": "ES: No members found."
|
"emptyState": "ES: No members found.",
|
||||||
|
"closeMenuLabel": "[TRANSLATE] Close menu"
|
||||||
},
|
},
|
||||||
"invites": {
|
"invites": {
|
||||||
"title": "ES: Invite Members",
|
"title": "ES: Invite Members",
|
||||||
|
"description": "[TRANSLATE] Invite new members by generating a shareable code.",
|
||||||
|
"addMemberButtonLabel": "[TRANSLATE] Add member",
|
||||||
|
"closeInviteLabel": "[TRANSLATE] Close invite",
|
||||||
"regenerateButton": "ES: Regenerate Invite Code",
|
"regenerateButton": "ES: Regenerate Invite Code",
|
||||||
"generateButton": "ES: Generate Invite Code",
|
"generateButton": "ES: Generate Invite Code",
|
||||||
"activeCodeLabel": "ES: Current Active Invite Code:",
|
"activeCodeLabel": "ES: Current Active Invite Code:",
|
||||||
@ -242,6 +260,15 @@
|
|||||||
"newDataInvalid": "ES: New invite code data is invalid."
|
"newDataInvalid": "ES: New invite code data is invalid."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"errors": {
|
||||||
|
"failedToFetchActiveInvite": "[TRANSLATE] Failed to fetch active invite code.",
|
||||||
|
"failedToFetchGroupDetails": "[TRANSLATE] Failed to fetch group details.",
|
||||||
|
"failedToLoadUpcomingChores": "[TRANSLATE] Error loading upcoming chores:",
|
||||||
|
"failedToLoadRecentExpenses": "[TRANSLATE] Error loading recent expenses:"
|
||||||
|
},
|
||||||
|
"console": {
|
||||||
|
"noActiveInvite": "[TRANSLATE] No active invite code found for this group."
|
||||||
|
},
|
||||||
"chores": {
|
"chores": {
|
||||||
"title": "ES: Group Chores",
|
"title": "ES: Group Chores",
|
||||||
"manageButton": "ES: Manage Chores",
|
"manageButton": "ES: Manage Chores",
|
||||||
@ -252,6 +279,8 @@
|
|||||||
"title": "ES: Group Expenses",
|
"title": "ES: Group Expenses",
|
||||||
"manageButton": "ES: Manage Expenses",
|
"manageButton": "ES: Manage Expenses",
|
||||||
"emptyState": "ES: No expenses recorded. Click \"Manage Expenses\" to add some!",
|
"emptyState": "ES: No expenses recorded. Click \"Manage Expenses\" to add some!",
|
||||||
|
"fallbackUserName": "[TRANSLATE] User ID: {userId}",
|
||||||
|
"activityByUserFallback": "[TRANSLATE] User {userId}",
|
||||||
"splitTypes": {
|
"splitTypes": {
|
||||||
"equal": "ES: Equal",
|
"equal": "ES: Equal",
|
||||||
"exactAmounts": "ES: Exact Amounts",
|
"exactAmounts": "ES: Exact Amounts",
|
||||||
|
@ -73,7 +73,10 @@
|
|||||||
"groupNameRequired": "FR: Group name is required",
|
"groupNameRequired": "FR: Group name is required",
|
||||||
"createFailed": "FR: Failed to create group. Please try again.",
|
"createFailed": "FR: Failed to create group. Please try again.",
|
||||||
"inviteCodeRequired": "FR: Invite code is required",
|
"inviteCodeRequired": "FR: Invite code is required",
|
||||||
"joinFailed": "FR: Failed to join group. Please check the invite code and try again."
|
"joinFailed": "FR: Failed to join group. Please check the invite code and try again.",
|
||||||
|
"invalidDataFromServer": "[TRANSLATE] Invalid data received from server.",
|
||||||
|
"createFailedConsole": "[TRANSLATE] Error creating group:",
|
||||||
|
"joinFailedConsole": "[TRANSLATE] Error joining group:"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"groupCreatedSuccess": "FR: Group '{groupName}' created successfully.",
|
"groupCreatedSuccess": "FR: Group '{groupName}' created successfully.",
|
||||||
@ -85,7 +88,8 @@
|
|||||||
"authCallbackPage": {
|
"authCallbackPage": {
|
||||||
"redirecting": "FR: Redirecting...",
|
"redirecting": "FR: Redirecting...",
|
||||||
"errors": {
|
"errors": {
|
||||||
"authenticationFailed": "FR: Authentication failed"
|
"authenticationFailed": "FR: Authentication failed",
|
||||||
|
"noTokenProvided": "[TRANSLATE] No token provided"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"choresPage": {
|
"choresPage": {
|
||||||
@ -165,7 +169,17 @@
|
|||||||
"quickDueDateTomorrow": "FR: Tomorrow",
|
"quickDueDateTomorrow": "FR: Tomorrow",
|
||||||
"quickDueDateNextWeek": "FR: Next Week",
|
"quickDueDateNextWeek": "FR: Next Week",
|
||||||
"cancelButton": "FR: Cancel",
|
"cancelButton": "FR: Cancel",
|
||||||
"saveButton": "FR: Save"
|
"saveButton": "FR: Save",
|
||||||
|
"intervalPlaceholder": "[TRANSLATE] e.g., 10"
|
||||||
|
},
|
||||||
|
"consoleErrors": {
|
||||||
|
"loadFailed": "[TRANSLATE] Failed to load all chores:",
|
||||||
|
"loadGroupsFailed": "[TRANSLATE] Failed to load groups",
|
||||||
|
"createAssignmentForNewChoreFailed": "[TRANSLATE] Failed to create assignment for new chore:",
|
||||||
|
"saveFailed": "[TRANSLATE] Failed to save chore:",
|
||||||
|
"deleteFailed": "[TRANSLATE] Failed to delete chore:",
|
||||||
|
"createAssignmentFailed": "[TRANSLATE] Failed to create assignment:",
|
||||||
|
"updateCompletionStatusFailed": "[TRANSLATE] Failed to update chore completion status:"
|
||||||
},
|
},
|
||||||
"deleteDialog": {
|
"deleteDialog": {
|
||||||
"title": "FR: Delete Chore",
|
"title": "FR: Delete Chore",
|
||||||
@ -228,10 +242,14 @@
|
|||||||
"title": "FR: Group Members",
|
"title": "FR: Group Members",
|
||||||
"defaultRole": "FR: Member",
|
"defaultRole": "FR: Member",
|
||||||
"removeButton": "FR: Remove",
|
"removeButton": "FR: Remove",
|
||||||
"emptyState": "FR: No members found."
|
"emptyState": "FR: No members found.",
|
||||||
|
"closeMenuLabel": "[TRANSLATE] Close menu"
|
||||||
},
|
},
|
||||||
"invites": {
|
"invites": {
|
||||||
"title": "FR: Invite Members",
|
"title": "FR: Invite Members",
|
||||||
|
"description": "[TRANSLATE] Invite new members by generating a shareable code.",
|
||||||
|
"addMemberButtonLabel": "[TRANSLATE] Add member",
|
||||||
|
"closeInviteLabel": "[TRANSLATE] Close invite",
|
||||||
"regenerateButton": "FR: Regenerate Invite Code",
|
"regenerateButton": "FR: Regenerate Invite Code",
|
||||||
"generateButton": "FR: Generate Invite Code",
|
"generateButton": "FR: Generate Invite Code",
|
||||||
"activeCodeLabel": "FR: Current Active Invite Code:",
|
"activeCodeLabel": "FR: Current Active Invite Code:",
|
||||||
@ -242,6 +260,15 @@
|
|||||||
"newDataInvalid": "FR: New invite code data is invalid."
|
"newDataInvalid": "FR: New invite code data is invalid."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"errors": {
|
||||||
|
"failedToFetchActiveInvite": "[TRANSLATE] Failed to fetch active invite code.",
|
||||||
|
"failedToFetchGroupDetails": "[TRANSLATE] Failed to fetch group details.",
|
||||||
|
"failedToLoadUpcomingChores": "[TRANSLATE] Error loading upcoming chores:",
|
||||||
|
"failedToLoadRecentExpenses": "[TRANSLATE] Error loading recent expenses:"
|
||||||
|
},
|
||||||
|
"console": {
|
||||||
|
"noActiveInvite": "[TRANSLATE] No active invite code found for this group."
|
||||||
|
},
|
||||||
"chores": {
|
"chores": {
|
||||||
"title": "FR: Group Chores",
|
"title": "FR: Group Chores",
|
||||||
"manageButton": "FR: Manage Chores",
|
"manageButton": "FR: Manage Chores",
|
||||||
@ -252,6 +279,8 @@
|
|||||||
"title": "FR: Group Expenses",
|
"title": "FR: Group Expenses",
|
||||||
"manageButton": "FR: Manage Expenses",
|
"manageButton": "FR: Manage Expenses",
|
||||||
"emptyState": "FR: No expenses recorded. Click \"Manage Expenses\" to add some!",
|
"emptyState": "FR: No expenses recorded. Click \"Manage Expenses\" to add some!",
|
||||||
|
"fallbackUserName": "[TRANSLATE] User ID: {userId}",
|
||||||
|
"activityByUserFallback": "[TRANSLATE] User {userId}",
|
||||||
"splitTypes": {
|
"splitTypes": {
|
||||||
"equal": "FR: Equal",
|
"equal": "FR: Equal",
|
||||||
"exactAmounts": "FR: Exact Amounts",
|
"exactAmounts": "FR: Exact Amounts",
|
||||||
|
@ -38,7 +38,7 @@ onMounted(async () => {
|
|||||||
const tokenToUse = accessToken || legacyToken;
|
const tokenToUse = accessToken || legacyToken;
|
||||||
|
|
||||||
if (!tokenToUse) {
|
if (!tokenToUse) {
|
||||||
throw new Error('No token provided');
|
throw new Error(t('authCallbackPage.errors.noTokenProvided'));
|
||||||
}
|
}
|
||||||
|
|
||||||
await authStore.setTokens({ access_token: tokenToUse, refresh_token: refreshToken });
|
await authStore.setTokens({ access_token: tokenToUse, refresh_token: refreshToken });
|
||||||
|
@ -80,7 +80,7 @@ const loadChores = async () => {
|
|||||||
cachedChores.value = mappedChores;
|
cachedChores.value = mappedChores;
|
||||||
cachedTimestamp.value = Date.now()
|
cachedTimestamp.value = Date.now()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load all chores:', error)
|
console.error(t('choresPage.consoleErrors.loadFailed'), error)
|
||||||
notificationStore.addNotification({ message: t('choresPage.notifications.loadFailed', 'Failed to load chores.'), type: 'error' })
|
notificationStore.addNotification({ message: t('choresPage.notifications.loadFailed', 'Failed to load chores.'), type: 'error' })
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
@ -91,7 +91,7 @@ const loadGroups = async () => {
|
|||||||
try {
|
try {
|
||||||
groups.value = await groupService.getUserGroups();
|
groups.value = await groupService.getUserGroups();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to load groups", error);
|
console.error(t('choresPage.consoleErrors.loadGroupsFailed'), error);
|
||||||
notificationStore.addNotification({ message: t('choresPage.notifications.loadGroupsFailed', 'Failed to load groups.'), type: 'error' });
|
notificationStore.addNotification({ message: t('choresPage.notifications.loadGroupsFailed', 'Failed to load groups.'), type: 'error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,7 +227,7 @@ const handleFormSubmit = async () => {
|
|||||||
due_date: createdChore.next_due_date
|
due_date: createdChore.next_due_date
|
||||||
});
|
});
|
||||||
} catch (assignmentError) {
|
} catch (assignmentError) {
|
||||||
console.error('Failed to create assignment for new chore:', assignmentError);
|
console.error(t('choresPage.consoleErrors.createAssignmentForNewChoreFailed'), assignmentError);
|
||||||
// Continue anyway since the chore was created
|
// Continue anyway since the chore was created
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ const handleFormSubmit = async () => {
|
|||||||
showChoreModal.value = false;
|
showChoreModal.value = false;
|
||||||
await loadChores();
|
await loadChores();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to save chore:', error);
|
console.error(t('choresPage.consoleErrors.saveFailed'), error);
|
||||||
notificationStore.addNotification({ message: t('choresPage.notifications.saveFailed', 'Failed to save the chore.'), type: 'error' });
|
notificationStore.addNotification({ message: t('choresPage.notifications.saveFailed', 'Failed to save the chore.'), type: 'error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,7 +255,7 @@ const deleteChore = async () => {
|
|||||||
showDeleteDialog.value = false
|
showDeleteDialog.value = false
|
||||||
await loadChores()
|
await loadChores()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to delete chore:', error)
|
console.error(t('choresPage.consoleErrors.deleteFailed'), error)
|
||||||
notificationStore.addNotification({ message: t('choresPage.notifications.deleteFailed', 'Failed to delete chore.'), type: 'error' })
|
notificationStore.addNotification({ message: t('choresPage.notifications.deleteFailed', 'Failed to delete chore.'), type: 'error' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ const toggleCompletion = async (chore: ChoreWithCompletion) => {
|
|||||||
});
|
});
|
||||||
chore.current_assignment_id = assignment.id;
|
chore.current_assignment_id = assignment.id;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to create assignment:', error);
|
console.error(t('choresPage.consoleErrors.createAssignmentFailed'), error);
|
||||||
notificationStore.addNotification({
|
notificationStore.addNotification({
|
||||||
message: t('choresPage.notifications.createAssignmentFailed', 'Failed to create assignment for chore.'),
|
message: t('choresPage.notifications.createAssignmentFailed', 'Failed to create assignment for chore.'),
|
||||||
type: 'error'
|
type: 'error'
|
||||||
@ -299,7 +299,7 @@ const toggleCompletion = async (chore: ChoreWithCompletion) => {
|
|||||||
});
|
});
|
||||||
await loadChores();
|
await loadChores();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to update chore completion status:', error);
|
console.error(t('choresPage.consoleErrors.updateCompletionStatusFailed'), error);
|
||||||
notificationStore.addNotification({ message: t('choresPage.notifications.updateFailed', 'Failed to update chore status.'), type: 'error' });
|
notificationStore.addNotification({ message: t('choresPage.notifications.updateFailed', 'Failed to update chore status.'), type: 'error' });
|
||||||
chore.is_completed = originalCompleted;
|
chore.is_completed = originalCompleted;
|
||||||
} finally {
|
} finally {
|
||||||
@ -403,7 +403,7 @@ const toggleCompletion = async (chore: ChoreWithCompletion) => {
|
|||||||
<label class="form-label" for="chore-interval">{{ t('choresPage.form.interval', 'Interval (days)')
|
<label class="form-label" for="chore-interval">{{ t('choresPage.form.interval', 'Interval (days)')
|
||||||
}}</label>
|
}}</label>
|
||||||
<input id="chore-interval" type="number" v-model.number="choreForm.custom_interval_days"
|
<input id="chore-interval" type="number" v-model.number="choreForm.custom_interval_days"
|
||||||
class="form-input" placeholder="e.g., 10" min="1">
|
class="form-input" :placeholder="t('choresPage.form.intervalPlaceholder')" min="1">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">{{ t('choresPage.form.type', 'Type') }}</label>
|
<label class="form-label">{{ t('choresPage.form.type', 'Type') }}</label>
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
<div class="popup-header">
|
<div class="popup-header">
|
||||||
<span class="font-semibold truncate">{{ member.email }}</span>
|
<span class="font-semibold truncate">{{ member.email }}</span>
|
||||||
<VButton variant="neutral" size="sm" :icon-only="true" iconLeft="x" @click="activeMemberMenu = null"
|
<VButton variant="neutral" size="sm" :icon-only="true" iconLeft="x" @click="activeMemberMenu = null"
|
||||||
aria-label="Close menu" />
|
:aria-label="t('groupDetailPage.members.closeMenuLabel')" />
|
||||||
</div>
|
</div>
|
||||||
<div class="member-menu-content">
|
<div class="member-menu-content">
|
||||||
<VBadge :text="member.role || t('groupDetailPage.members.defaultRole')"
|
<VBadge :text="member.role || t('groupDetailPage.members.defaultRole')"
|
||||||
@ -37,8 +37,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<button ref="addMemberButtonRef" @click="toggleInviteUI" class="add-member-btn"
|
<button ref="addMemberButtonRef" @click="toggleInviteUI" class="add-member-btn"
|
||||||
:aria-label="t('groupDetailPage.invites.title')">
|
:aria-label="t('groupDetailPage.invites.title')">
|
||||||
<!-- <VIcon name="plus" size="md" /> -->
|
{{ t('groupDetailPage.invites.addMemberButtonLabel') }}
|
||||||
+
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Invite Members Popup -->
|
<!-- Invite Members Popup -->
|
||||||
@ -47,9 +46,9 @@
|
|||||||
<VHeading :level="3" class="!m-0 !p-0 !border-none">{{ t('groupDetailPage.invites.title') }}
|
<VHeading :level="3" class="!m-0 !p-0 !border-none">{{ t('groupDetailPage.invites.title') }}
|
||||||
</VHeading>
|
</VHeading>
|
||||||
<VButton variant="neutral" size="sm" :icon-only="true" iconLeft="x" @click="showInviteUI = false"
|
<VButton variant="neutral" size="sm" :icon-only="true" iconLeft="x" @click="showInviteUI = false"
|
||||||
aria-label="Close invite" />
|
:aria-label="t('groupDetailPage.invites.closeInviteLabel')" />
|
||||||
</div>
|
</div>
|
||||||
<p class="text-sm text-gray-500 my-2">Invite new members by generating a shareable code.</p>
|
<p class="text-sm text-gray-500 my-2">{{ t('groupDetailPage.invites.description') }}</p>
|
||||||
<VButton variant="primary" class="w-full" @click="generateInviteCode" :disabled="generatingInvite">
|
<VButton variant="primary" class="w-full" @click="generateInviteCode" :disabled="generatingInvite">
|
||||||
<VSpinner v-if="generatingInvite" size="sm" /> {{ inviteCode ?
|
<VSpinner v-if="generatingInvite" size="sm" /> {{ inviteCode ?
|
||||||
t('groupDetailPage.invites.regenerateButton') :
|
t('groupDetailPage.invites.regenerateButton') :
|
||||||
@ -146,7 +145,7 @@
|
|||||||
<div class="neo-splits-list">
|
<div class="neo-splits-list">
|
||||||
<div v-for="split in expense.splits" :key="split.id" class="neo-split-item">
|
<div v-for="split in expense.splits" :key="split.id" class="neo-split-item">
|
||||||
<div class="split-col split-user">
|
<div class="split-col split-user">
|
||||||
<strong>{{ split.user?.name || split.user?.email || `User ID: ${split.user_id}` }}</strong>
|
<strong>{{ split.user?.name || split.user?.email || t('groupDetailPage.expenses.fallbackUserName', { userId: split.user_id }) }}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="split-col split-owes">
|
<div class="split-col split-owes">
|
||||||
{{ t('groupDetailPage.expenses.owes') }} <strong>{{
|
{{ t('groupDetailPage.expenses.owes') }} <strong>{{
|
||||||
@ -178,8 +177,7 @@
|
|||||||
{{ t('groupDetailPage.expenses.activityLabel') }} {{
|
{{ t('groupDetailPage.expenses.activityLabel') }} {{
|
||||||
formatCurrency(activity.amount_paid) }}
|
formatCurrency(activity.amount_paid) }}
|
||||||
{{
|
{{
|
||||||
t('groupDetailPage.expenses.byUser') }} {{ activity.payer?.name || `User
|
t('groupDetailPage.expenses.byUser') }} {{ activity.payer?.name || t('groupDetailPage.expenses.activityByUserFallback', { userId: activity.paid_by_user_id }) }} {{ t('groupDetailPage.expenses.onDate') }} {{ new
|
||||||
${activity.paid_by_user_id}` }} {{ t('groupDetailPage.expenses.onDate') }} {{ new
|
|
||||||
Date(activity.paid_at).toLocaleDateString() }}
|
Date(activity.paid_at).toLocaleDateString() }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -209,7 +207,7 @@
|
|||||||
<div v-else>
|
<div v-else>
|
||||||
<p>{{ t('groupDetailPage.settleShareModal.settleAmountFor', {
|
<p>{{ t('groupDetailPage.settleShareModal.settleAmountFor', {
|
||||||
userName: selectedSplitForSettlement?.user?.name
|
userName: selectedSplitForSettlement?.user?.name
|
||||||
|| selectedSplitForSettlement?.user?.email || `User ID: ${selectedSplitForSettlement?.user_id}`
|
|| selectedSplitForSettlement?.user?.email || t('groupDetailPage.expenses.fallbackUserName', { userId: selectedSplitForSettlement?.user_id })
|
||||||
}) }}</p>
|
}) }}</p>
|
||||||
<VFormField :label="t('groupDetailPage.settleShareModal.amountLabel')"
|
<VFormField :label="t('groupDetailPage.settleShareModal.amountLabel')"
|
||||||
:error-message="settleAmountError || undefined">
|
:error-message="settleAmountError || undefined">
|
||||||
@ -383,9 +381,9 @@ const fetchActiveInviteCode = async () => {
|
|||||||
inviteCode.value = null; // Explicitly set to null on 404
|
inviteCode.value = null; // Explicitly set to null on 404
|
||||||
inviteExpiresAt.value = null;
|
inviteExpiresAt.value = null;
|
||||||
// Optional: notify user or set a flag to show "generate one" message more prominently
|
// Optional: notify user or set a flag to show "generate one" message more prominently
|
||||||
console.info('No active invite code found for this group.');
|
console.info(t('groupDetailPage.console.noActiveInvite'));
|
||||||
} else {
|
} else {
|
||||||
const message = err instanceof Error ? err.message : 'Failed to fetch active invite code.';
|
const message = err instanceof Error ? err.message : t('groupDetailPage.errors.failedToFetchActiveInvite');
|
||||||
// error.value = message; // This would display a large error banner, might be too much
|
// error.value = message; // This would display a large error banner, might be too much
|
||||||
console.error('Error fetching active invite code:', err);
|
console.error('Error fetching active invite code:', err);
|
||||||
notificationStore.addNotification({ message, type: 'error' });
|
notificationStore.addNotification({ message, type: 'error' });
|
||||||
@ -418,7 +416,7 @@ const fetchGroupDetails = async () => {
|
|||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
};
|
};
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
const message = err instanceof Error ? err.message : 'Failed to fetch group details.';
|
const message = err instanceof Error ? err.message : t('groupDetailPage.errors.failedToFetchGroupDetails');
|
||||||
// Only show the main error banner if we have no data at all to show
|
// Only show the main error banner if we have no data at all to show
|
||||||
if (!group.value) {
|
if (!group.value) {
|
||||||
error.value = message;
|
error.value = message;
|
||||||
@ -524,7 +522,7 @@ const loadUpcomingChores = async () => {
|
|||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading upcoming chores:', error)
|
console.error(t('groupDetailPage.errors.failedToLoadUpcomingChores'), error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,7 +561,7 @@ const loadRecentExpenses = async () => {
|
|||||||
)
|
)
|
||||||
recentExpenses.value = response.data
|
recentExpenses.value = response.data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading recent expenses:', error)
|
console.error(t('groupDetailPage.errors.failedToLoadRecentExpenses'), error)
|
||||||
notificationStore.addNotification({ message: t('groupDetailPage.notifications.loadExpensesFailed'), type: 'error' });
|
notificationStore.addNotification({ message: t('groupDetailPage.notifications.loadExpensesFailed'), type: 'error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,12 +281,12 @@ const handleCreateGroup = async () => {
|
|||||||
cachedGroups.value = groups.value;
|
cachedGroups.value = groups.value;
|
||||||
cachedTimestamp.value = Date.now();
|
cachedTimestamp.value = Date.now();
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Invalid data received from server.');
|
throw new Error(t('groupsPage.errors.invalidDataFromServer'));
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const message = error.response?.data?.detail || (error instanceof Error ? error.message : t('groupsPage.errors.createFailed'));
|
const message = error.response?.data?.detail || (error instanceof Error ? error.message : t('groupsPage.errors.createFailed'));
|
||||||
createGroupFormError.value = message;
|
createGroupFormError.value = message;
|
||||||
console.error('Error creating group:', error);
|
console.error(t('groupsPage.errors.createFailedConsole'), error);
|
||||||
notificationStore.addNotification({ message, type: 'error' });
|
notificationStore.addNotification({ message, type: 'error' });
|
||||||
} finally {
|
} finally {
|
||||||
creatingGroup.value = false;
|
creatingGroup.value = false;
|
||||||
@ -327,7 +327,7 @@ const handleJoinGroup = async () => {
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const message = error.response?.data?.detail || (error instanceof Error ? error.message : t('groupsPage.errors.joinFailed'));
|
const message = error.response?.data?.detail || (error instanceof Error ? error.message : t('groupsPage.errors.joinFailed'));
|
||||||
joinGroupFormError.value = message;
|
joinGroupFormError.value = message;
|
||||||
console.error('Error joining group:', error);
|
console.error(t('groupsPage.errors.joinFailedConsole'), error);
|
||||||
notificationStore.addNotification({ message, type: 'error' });
|
notificationStore.addNotification({ message, type: 'error' });
|
||||||
} finally {
|
} finally {
|
||||||
joiningGroup.value = false;
|
joiningGroup.value = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user