export: revision UX de estilos, 2 estilos nuevos y copia como texto
- Header elegante: logo fijado a la izquierda y titulo centrado de verdad (ZStack), fecha a la derecha - School transpuesto: dias como columnas y comidas como filas — antes con 1-2 comidas quedaba media pagina A4 apaisada en blanco - Default: las celdas del grid se expanden para llenar la pagina (mismo sintoma de hueco que el school) - Estilo nuevo "Story" (9:16, 2160x3840) para stories de IG/WhatsApp y "Minimal (imprimir)" en A4 con lineas finas sin fondos (ahorro tinta) - Picker del preview pasa de segmentado a chips desplazables (5 estilos) - WeekPlanTextExporter + boton "Copiar como texto (WhatsApp)" en el preview: menu semanal con *negritas* y emojis listo para pegar en WhatsApp/Telegram (evento analytics format=text) - Harness de render en tests: genera PNG de los 5 estilos con datos de ejemplo en /tmp/mealmood-export-previews para revisar el diseno - Nombres de estilos en espanol corregidos (estaban en ingles) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
This commit is contained in:
@@ -1406,6 +1406,7 @@ private struct WeekExportPreviewSheet: View {
|
||||
@State private var selectedStyle: WeekExportStyle
|
||||
@State private var previews: [WeekExportStyle: UIImage] = [:]
|
||||
@State private var shareFile: ShareFile?
|
||||
@State private var didCopyText: Bool = false
|
||||
|
||||
private struct ShareFile: Identifiable {
|
||||
let url: URL
|
||||
@@ -1423,13 +1424,25 @@ private struct WeekExportPreviewSheet: View {
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
VStack(spacing: 14) {
|
||||
Picker("share_export_style_picker_title", selection: $selectedStyle) {
|
||||
ForEach(WeekExportStyle.allCases, id: \.self) { style in
|
||||
Text(LocalizedStringKey(style.localizedKey)).tag(style)
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
HStack(spacing: 8) {
|
||||
ForEach(WeekExportStyle.allCases, id: \.self) { style in
|
||||
Button {
|
||||
selectedStyle = style
|
||||
} label: {
|
||||
Text(LocalizedStringKey(style.localizedKey))
|
||||
.font(.mealMoodSmall.weight(.semibold))
|
||||
.foregroundColor(selectedStyle == style ? .white : .mealMoodTextPrimary)
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 8)
|
||||
.background(selectedStyle == style ? Color.mealMoodCoral : Color.mealMoodSurface)
|
||||
.clipShape(Capsule())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.top, 10)
|
||||
|
||||
Group {
|
||||
@@ -1461,6 +1474,15 @@ private struct WeekExportPreviewSheet: View {
|
||||
isEnabled: previews[selectedStyle] != nil
|
||||
)
|
||||
.padding(.horizontal, 16)
|
||||
|
||||
Button(action: copyAsText) {
|
||||
Label(
|
||||
String(localized: didCopyText ? "share_text_copied" : "share_export_copy_text"),
|
||||
systemImage: didCopyText ? "checkmark.circle.fill" : "doc.on.doc"
|
||||
)
|
||||
.font(.mealMoodBodyBold)
|
||||
.foregroundColor(didCopyText ? .mealMoodSuccess : .mealMoodCoral)
|
||||
}
|
||||
.padding(.bottom, 12)
|
||||
}
|
||||
.background(Color.mealMoodBackground.ignoresSafeArea())
|
||||
@@ -1508,6 +1530,16 @@ private struct WeekExportPreviewSheet: View {
|
||||
AnalyticsService.logWeekPlanShared(format: selectedStyle.rawValue)
|
||||
shareFile = ShareFile(url: url)
|
||||
}
|
||||
|
||||
private func copyAsText() {
|
||||
UIPasteboard.general.string = WeekPlanTextExporter.text(plan: plan, settings: settings, dishes: dishes)
|
||||
AnalyticsService.logWeekPlanShared(format: "text")
|
||||
HapticManager.shared.notification(type: .success)
|
||||
withAnimation { didCopyText = true }
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
withAnimation { didCopyText = false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user