Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions docs/handbook/de/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7496,7 +7496,7 @@ <h2><span class="num">73</span>Support — Ticket erstellen</h2>
</div>
</summary>
<p class="spec-intro">
Das Formular zum Erfassen eines neuen Support-Tickets: Anliegen-Typ per Tag auswählen, Anliegen im Textfeld beschreiben und absenden.
Das Formular zum Erfassen eines neuen Support-Tickets: Anliegen-Typ per Tag auswählen, Anliegen im Textfeld beschreiben, optional ein Bild als <b>Anhang</b> wählen und absenden.
</p>

<div class="tests cols-2">
Expand All @@ -7509,11 +7509,11 @@ <h2><span class="num">73</span>Support — Ticket erstellen</h2>
<div class="img">
<img
src="../screenshots/250-support-create-ticket-page-default.png"
alt="Leeres Formular für neues Ticket"
alt="Leeres Ticket-Formular mit Anhang-Feld"
/>
</div>
<div class="desc">
Das leere Formular <b>Neues Ticket erstellen</b> mit der Auswahl <b>Anliegen auswählen</b> (Tags Allgemeines Anliegen, Fehlerbericht, KYC-Problem), dem Nachrichtenfeld und der noch deaktivierten Schaltfläche <b>Senden</b>. So sieht der Nutzer das Formular direkt beim Öffnen, bevor er einen Typ wählt oder etwas eingibt.
Das leere Formular <b>Neues Ticket erstellen</b> mit der Auswahl <b>Anliegen auswählen</b> (Tags Allgemeines Anliegen, Fehlerbericht, KYC-Problem), dem Nachrichtenfeld, der Sektion <b>Anhang</b> mit dem Rahmenfeld und Platzhalter <b>Anhang wählen</b> sowie der noch deaktivierten Schaltfläche <b>Senden</b>. So sieht der Nutzer das Formular direkt beim Öffnen, bevor er einen Typ wählt oder etwas eingibt.
</div>
</div>
<div class="test" id="251-support-create-ticket-page-filled">
Expand All @@ -7525,11 +7525,11 @@ <h2><span class="num">73</span>Support — Ticket erstellen</h2>
<div class="img">
<img
src="../screenshots/251-support-create-ticket-page-filled.png"
alt="Ticket-Formular ausgefüllt, Senden aktiv"
alt="Ticket-Formular ausgefüllt mit leerem Anhang-Feld, Senden aktiv"
/>
</div>
<div class="desc">
Das ausgefüllte Formular mit ausgewähltem Anliegen-Typ und eingegebener Nachricht: Die Schaltfläche <b>Senden</b> ist nun aktiv. Der Nutzer sieht diesen Zustand, sobald er einen Typ gewählt und eine Nachricht erfasst hat und das Ticket abschicken kann.
Das ausgefüllte Formular mit ausgewähltem Anliegen-Typ und eingegebener Nachricht: Die Schaltfläche <b>Senden</b> ist nun aktiv. Das Anhang-Feld darunter bleibt leer — der Anhang ist optional und muss fürs Absenden nicht gesetzt sein. Der Nutzer sieht diesen Zustand, sobald er einen Typ gewählt und eine Nachricht erfasst hat und das Ticket abschicken kann.
</div>
</div>
<div class="test" id="252-support-create-ticket-page-submitting">
Expand All @@ -7541,11 +7541,11 @@ <h2><span class="num">73</span>Support — Ticket erstellen</h2>
<div class="img">
<img
src="../screenshots/252-support-create-ticket-page-submitting.png"
alt="Ticket wird abgesendet"
alt="Ticket wird abgesendet, Anhang-Feld unverändert"
/>
</div>
<div class="desc">
Das Ticket-Formular während des Absendens: Die Schaltfläche <b>Senden</b> zeigt eine Ladeanimation. Dieser Zustand erscheint, nachdem der Nutzer auf Senden getippt hat, solange das Ticket an den Server übermittelt wird.
Das Ticket-Formular während des Absendens: die Anliegen-Tags und das Nachrichtenfeld sind abgeblendet, die Schaltfläche <b>Senden</b> zeigt eine Ladeanimation. Das Anhang-Feld darunter bleibt unverändert sichtbar. Dieser Zustand erscheint, nachdem der Nutzer auf Senden getippt hat, solange das Ticket an den Server übermittelt wird.
</div>
</div>
</div>
Expand Down Expand Up @@ -7664,7 +7664,7 @@ <h2><span class="num">75</span>Support — Chat</h2>
</div>
</summary>
<p class="spec-intro">
Der Chat-Verlauf zu einem einzelnen Ticket: Nachrichten von Kunde und Support als Sprechblasen, mit Eingabefeld bei offenen Tickets und seinen Lade-, Sende-, Fehler- und Geschlossen-Zuständen.
Der Chat-Verlauf zu einem einzelnen Ticket: Nachrichten von Kunde und Support als Sprechblasen, mit Eingabefeld und Büroklammer zum Anhängen eines Bildes bei offenen Tickets sowie Lade-, Sende-, Fehler- und Geschlossen-Zuständen.
</p>

<div class="tests cols-2">
Expand Down Expand Up @@ -7693,11 +7693,11 @@ <h2><span class="num">75</span>Support — Chat</h2>
<div class="img">
<img
src="../screenshots/258-support-chat-page-loaded.png"
alt="Geladener Chat mit Nachrichten und Eingabefeld"
alt="Geladener Chat mit Nachrichten, Büroklammer und Eingabefeld"
/>
</div>
<div class="desc">
Der geladene Chat eines offenen Tickets: die Kunden-Nachricht als <b>blaue</b>, rechtsbündige Sprechblase und die Antwort des Supports als <b>graue</b>, linksbündige Sprechblase mit Label Support und Uhrzeit. Unten steht das Eingabefeld <b>Nachricht eingeben</b> mit Sende-Schaltfläche bereit.
Der geladene Chat eines offenen Tickets: die Kunden-Nachricht als <b>blaue</b>, rechtsbündige Sprechblase und die Antwort des Supports als <b>graue</b>, linksbündige Sprechblase mit Label Support und Uhrzeit. Unten steht links neben dem Eingabefeld <b>Nachricht eingeben</b> eine Büroklammer-Schaltfläche zum Anhängen eines Bildes, rechts die Sende-Schaltfläche.
</div>
</div>
<div class="test" id="259-support-chat-page-sending">
Expand All @@ -7709,11 +7709,11 @@ <h2><span class="num">75</span>Support — Chat</h2>
<div class="img">
<img
src="../screenshots/259-support-chat-page-sending.png"
alt="Chat-Nachricht wird gesendet"
alt="Chat-Nachricht wird gesendet, Büroklammer sichtbar"
/>
</div>
<div class="desc">
Der offene Chat, während eine Nachricht gesendet wird: Das Eingabefeld ist deaktiviert und die Sende-Schaltfläche zeigt statt des Pfeils eine Ladeanimation. Dieser Zustand erscheint, nachdem der Nutzer auf Senden getippt hat, solange die Nachricht übermittelt wird.
Der offene Chat, während eine Nachricht gesendet wird: dieselbe Büroklammer-Schaltfläche bleibt sichtbar, das Eingabefeld ist deaktiviert und die Sende-Schaltfläche zeigt statt des Pfeils eine Ladeanimation. Dieser Zustand erscheint, nachdem der Nutzer auf Senden getippt hat, solange die Nachricht übermittelt wird.
</div>
</div>
<div class="test" id="260-support-chat-page-closed">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class SupportChatCubit extends Cubit<SupportChatState> {
final base64 = await attachment?.toBase64DataUri();
await _supportService.sendMessage(
_ticketUid,
message: trimmed.isEmpty ? null : message,
message: trimmed.isEmpty ? null : trimmed,
file: base64,
fileName: attachment?.name,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class SupportCreateTicketCubit extends Cubit<SupportCreateTicketState> {
final attachment = state.attachment;
final selectedType = state.selectedType!;
final selectedReason = state.selectedReason!;
final message = state.message;
final message = state.message.trim();
if (isClosed) return;
emit(state.copyWith(isSubmitting: true, error: null));

Expand Down
92 changes: 16 additions & 76 deletions lib/screens/support/widgets/support_attachment_field.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:realunit_wallet/generated/i18n.dart';
import 'package:realunit_wallet/styles/colors.dart';
import 'package:realunit_wallet/widgets/form/file_preview_field.dart';

/// Attachment picker styled like the surrounding ticket-form fields
/// (`support_create_ticket_page`: bodyLarge section labels, radius 12,
Expand All @@ -12,6 +11,7 @@ class SupportAttachmentField extends StatelessWidget {
final XFile? selectedFile;
final VoidCallback onTap;
final VoidCallback onRemove;

/// When false, taps (pick + remove) are ignored — same pattern as the chat
/// input's `onPressed: isSending ? null : …` (no opacity/color change).
final bool enabled;
Expand Down Expand Up @@ -43,80 +43,20 @@ class SupportAttachmentField extends StatelessWidget {
fontWeight: .w600,
),
),
GestureDetector(
onTap: enabled ? onTap : null,
child: Container(
width: .infinity,
padding: const .symmetric(horizontal: 12, vertical: 12),
decoration: BoxDecoration(
borderRadius: .circular(12),
border: .all(
color: selectedFile != null
? RealUnitColors.realUnitBlue
: RealUnitColors.neutral200,
),
),
child: selectedFile != null
? Row(
spacing: 12.0,
children: [
ClipRRect(
borderRadius: .circular(4),
child: Image.file(
File(selectedFile!.path),
width: 48,
height: 48,
fit: .cover,
),
),
Expanded(
child: Text(
selectedFile!.name,
maxLines: 1,
overflow: .ellipsis,
style: theme.textTheme.bodyMedium,
),
),
const Icon(
Icons.edit_rounded,
color: RealUnitColors.realUnitBlue,
),
GestureDetector(
onTap: enabled ? onRemove : null,
behavior: .opaque,
// 48dp minimum tap target (Material accessibility).
child: const SizedBox(
width: 48,
height: 48,
child: Center(
child: Icon(
Icons.close_rounded,
color: RealUnitColors.neutral500,
),
),
),
),
],
)
: Row(
spacing: 8.0,
mainAxisAlignment: .center,
children: [
Icon(
Icons.add_a_photo_rounded,
color: placeholderColor,
),
Flexible(
child: Text(
S.of(context).supportChooseAttachment,
maxLines: 1,
overflow: .ellipsis,
style: placeholderStyle,
),
),
],
),
),
FilePreviewField(
selectedFile: selectedFile,
onTap: onTap,
onRemove: onRemove,
enabled: enabled,
placeholderText: S.of(context).supportChooseAttachment,
placeholderStyle: placeholderStyle,
placeholderIconColor: placeholderColor,
borderColor: selectedFile != null
? RealUnitColors.realUnitBlue
: RealUnitColors.neutral200,
borderRadius: 12,
height: null,
padding: const .symmetric(horizontal: 12, vertical: 12),
),
],
);
Expand Down
73 changes: 13 additions & 60 deletions lib/widgets/form/file_picker_field.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:realunit_wallet/styles/colors.dart';
import 'package:realunit_wallet/widgets/form/file_preview_field.dart';

class FilePickerField extends StatelessWidget {
final String label;
Expand Down Expand Up @@ -36,66 +35,20 @@ class FilePickerField extends StatelessWidget {
),
),
),
GestureDetector(
FilePreviewField(
selectedFile: selectedFile,
onTap: onTap,
child: Container(
width: .infinity,
height: 76,
padding: const .symmetric(horizontal: 10),
decoration: BoxDecoration(
borderRadius: .circular(8),
border: .all(
color: error != null ? RealUnitColors.status.red600 : RealUnitColors.neutral300,
),
),
child: selectedFile != null
? Row(
spacing: 12.0,
children: [
ClipRRect(
borderRadius: .circular(4),
child: Image.file(
File(selectedFile!.path),
width: 48,
height: 48,
fit: BoxFit.cover,
),
),
Expanded(
child: Text(
selectedFile!.name,
maxLines: 1,
overflow: .ellipsis,
style: Theme.of(context).textTheme.bodyMedium,
),
),
const Icon(
Icons.edit_rounded,
color: RealUnitColors.realUnitBlue,
),
],
)
: Row(
spacing: 8.0,
mainAxisAlignment: .center,
children: [
const Icon(
Icons.add_a_photo_rounded,
color: RealUnitColors.neutral400,
),
Flexible(
child: Text(
label,
maxLines: 1,
overflow: .ellipsis,
style: const TextStyle(
color: RealUnitColors.neutral400,
),
),
),
],
),
onRemove: null,
enabled: true,
placeholderText: label,
placeholderStyle: const TextStyle(
color: RealUnitColors.neutral400,
),
placeholderIconColor: RealUnitColors.neutral400,
borderColor: error != null ? RealUnitColors.status.red600 : RealUnitColors.neutral300,
borderRadius: 8,
height: 76,
padding: const .symmetric(horizontal: 10),
),
],
);
Expand Down
Loading
Loading