Add comprehensive i18n localization for KMM and iOS
KMM (Android/Shared): - Add strings.xml with 200+ localized strings - Add translation files for es, fr, de, pt languages - Update all screens to use stringResource() for i18n - Add Accept-Language header to API client for all platforms iOS: - Add L10n.swift helper with type-safe string accessors - Add Localizable.xcstrings with translations for all 5 languages - Update all SwiftUI views to use L10n.* for localized strings - Localize Auth, Residence, Task, Contractor, Document, and Profile views Supported languages: English, Spanish, French, German, Portuguese 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -21,11 +21,11 @@ struct CompletionHistorySheet: View {
|
||||
completionsList
|
||||
}
|
||||
}
|
||||
.navigationTitle("Completion History")
|
||||
.navigationTitle(L10n.Tasks.completionHistory)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button("Done") {
|
||||
Button(L10n.Common.done) {
|
||||
isPresented = false
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ struct CompletionHistorySheet: View {
|
||||
ProgressView()
|
||||
.progressViewStyle(CircularProgressViewStyle(tint: Color.appPrimary))
|
||||
.scaleEffect(1.5)
|
||||
Text("Loading completions...")
|
||||
Text(L10n.Tasks.loadingCompletions)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(Color.appTextSecondary)
|
||||
}
|
||||
@@ -60,7 +60,7 @@ struct CompletionHistorySheet: View {
|
||||
.font(.system(size: 48))
|
||||
.foregroundColor(Color.appError)
|
||||
|
||||
Text("Failed to load completions")
|
||||
Text(L10n.Tasks.failedToLoad)
|
||||
.font(.headline)
|
||||
.foregroundColor(Color.appTextPrimary)
|
||||
|
||||
@@ -73,7 +73,7 @@ struct CompletionHistorySheet: View {
|
||||
Button(action: {
|
||||
viewModel.loadCompletions(taskId: taskId)
|
||||
}) {
|
||||
Label("Retry", systemImage: "arrow.clockwise")
|
||||
Label(L10n.Common.retry, systemImage: "arrow.clockwise")
|
||||
.foregroundColor(Color.appPrimary)
|
||||
}
|
||||
.padding(.top, AppSpacing.sm)
|
||||
@@ -87,11 +87,11 @@ struct CompletionHistorySheet: View {
|
||||
.font(.system(size: 48))
|
||||
.foregroundColor(Color.appTextSecondary.opacity(0.5))
|
||||
|
||||
Text("No Completions Yet")
|
||||
Text(L10n.Tasks.noCompletionsYet)
|
||||
.font(.headline)
|
||||
.foregroundColor(Color.appTextPrimary)
|
||||
|
||||
Text("This task has not been completed.")
|
||||
Text(L10n.Tasks.notCompleted)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(Color.appTextSecondary)
|
||||
}
|
||||
@@ -110,7 +110,7 @@ struct CompletionHistorySheet: View {
|
||||
.fontWeight(.semibold)
|
||||
.foregroundColor(Color.appTextPrimary)
|
||||
Spacer()
|
||||
Text("\(viewModel.completions.count) \(viewModel.completions.count == 1 ? "completion" : "completions")")
|
||||
Text("\(viewModel.completions.count) \(viewModel.completions.count == 1 ? L10n.Tasks.completion : L10n.Tasks.completions)")
|
||||
.font(.caption)
|
||||
.foregroundColor(Color.appTextSecondary)
|
||||
}
|
||||
@@ -146,7 +146,7 @@ struct CompletionHistoryCard: View {
|
||||
HStack(spacing: 4) {
|
||||
Image(systemName: "person.fill")
|
||||
.font(.caption2)
|
||||
Text("Completed by \(completedBy)")
|
||||
Text("\(L10n.Tasks.completedByName) \(completedBy)")
|
||||
.font(.caption)
|
||||
}
|
||||
.foregroundColor(Color.appTextSecondary)
|
||||
@@ -213,7 +213,7 @@ struct CompletionHistoryCard: View {
|
||||
// Notes
|
||||
if !completion.notes.isEmpty {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("Notes")
|
||||
Text(L10n.Tasks.notes)
|
||||
.font(.caption)
|
||||
.fontWeight(.semibold)
|
||||
.foregroundColor(Color.appTextSecondary)
|
||||
@@ -233,7 +233,7 @@ struct CompletionHistoryCard: View {
|
||||
HStack {
|
||||
Image(systemName: "photo.on.rectangle.angled")
|
||||
.font(.subheadline)
|
||||
Text("View Photos (\(completion.images.count))")
|
||||
Text("\(L10n.Tasks.viewPhotos) (\(completion.images.count))")
|
||||
.font(.subheadline)
|
||||
.fontWeight(.semibold)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user