Fix translations and icons

Added page layout to customer service screens
This commit is contained in:
2026-02-16 11:20:33 +01:00
parent e581895246
commit f76a88a53c
9 changed files with 236 additions and 233 deletions

View File

@@ -2,26 +2,11 @@ import 'package:customer_service/src/presentation/state/contact_view_model.dart'
import 'package:design_system/design_system.dart'; import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:navigation/navigation.dart'; import 'package:navigation/navigation.dart';
import 'package:sf_localizations/sf_localizations.dart'; import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart'; import 'package:utils/utils.dart';
const Map<String, String> country = <String, String>{
'SPAIN': 'España',
'PORTUGAL': 'Portugal',
'FRANCE': 'France',
'ITALIA': 'Italia',
'GERMANY': 'Deutschland',
'OTHER': I18n.other,
};
const Map<String, String> channel = <String, String>{
'ONLINE_SHOP': I18n.channelOnline,
'AMAZON': I18n.channelAmazon,
'STORE': I18n.channelStore,
'OTHER': I18n.other,
};
class ContactScreen extends ConsumerWidget { class ContactScreen extends ConsumerWidget {
final NavigationContract navigationContract; final NavigationContract navigationContract;
@@ -34,87 +19,88 @@ class ContactScreen extends ConsumerWidget {
final vm = ref.read(contactViewModelProvider.notifier); final vm = ref.read(contactViewModelProvider.notifier);
final viewState = ref.watch(contactViewModelProvider); final viewState = ref.watch(contactViewModelProvider);
return Scaffold( final List<String> country = [
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary), 'España',
body: SafeArea( 'Portugal',
child: Container( 'France',
padding: SizeUtils.getByScreen( 'Italia',
small: EdgeInsets.symmetric(horizontal: 38, vertical: 14), 'Deutschland',
big: EdgeInsets.symmetric(horizontal: 36, vertical: 12) context.translate(I18n.other),
), ];
child: SingleChildScrollView(
child: Column( final List<String> channel = [
children: [ context.translate(I18n.channelOnline),
Stack( context.translate(I18n.channelAmazon),
children: [ context.translate(I18n.channelStore),
SizedBox( context.translate(I18n.other),
height: SizeUtils.getByScreen(small: 36, big: 36), ];
child: Align(
alignment: Alignment.centerLeft, return PageLayout(
child: Icon(Icons.arrow_back, size: SizeUtils.getByScreen(small: 36, big: 34)) title: context.translate(I18n.contactTitle),
) body: Container(
), padding: SizeUtils.getByScreen(
Center(child: Text(context.translate(I18n.contactTitle), small: EdgeInsets.symmetric(horizontal: 38),
style: TextStyle(fontSize: SizeUtils.getByScreen(small: 28, big: 27)))) big: EdgeInsets.symmetric(horizontal: 36)
], ),
child: SingleChildScrollView(child: Column(
children: [
CustomDropdown(
items: country.map(Text.new).toList(growable: false),
onChanged: (x){vm.setCountry(x);},
hint: context.translate(I18n.selectCountry)
),
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
CustomDropdown(
items: channel.map(Text.new).toList(growable: false),
onChanged: (x){vm.setChannel(x);},
hint: context.translate(I18n.selectChannel)
),
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
CustomTextField(
controller: vm.nameController,
hint: context.translate(I18n.enterName),
),
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
CustomTextField(
controller: vm.emailController,
keyboardType: TextInputType.emailAddress,
hint: context.translate(I18n.enterEmail),
),
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
CustomTextField(
controller: vm.subjectController,
hint: context.translate(I18n.enterSubject),
),
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
CustomTextField(
controller: vm.bodyController,
keyboardType: TextInputType.multiline,
hint: context.translate(I18n.enterMessage),
lines: 8,
),
if (viewState.errorMessage.isNotEmpty) ...[
const SizedBox(height: 4),
Text(
viewState.errorMessage,
textAlign: TextAlign.center,
style: const TextStyle(
color: Color.fromRGBO(239, 17, 17, 1),
fontSize: 12,
), ),
SizedBox(height: SizeUtils.getByScreen(small: 40, big: 38)), ),
CustomDropdown( ],
items: country.values.map(Text.new).toList(growable: false), ],
values: country.keys.toList(), )),
onChanged: (x){vm.setCountry(x);}, ),
hint: 'Choose your country' footer: Container(
), padding: SizeUtils.getByScreen(
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)), small: EdgeInsets.symmetric(horizontal: 38, vertical: 14),
CustomDropdown( big: EdgeInsets.symmetric(horizontal: 36, vertical: 12)
items: channel.values.map(Text.new).toList(growable: false), ),
values: channel.keys.toList(), child: PrimaryButton(
onChanged: (x){vm.setChannel(x);}, onPressed: vm.sendEmail,
hint: 'Purchase channel' text: context.translate(I18n.sendEmail),
), color: theme.getColorFor(ThemeCode.buttonPrimary)
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
CustomTextField(
controller: vm.nameController,
hint: 'Enter your name',
),
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
CustomTextField(
controller: vm.emailController,
keyboardType: TextInputType.emailAddress,
hint: 'Enter your email',
),
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
CustomTextField(
controller: vm.subjectController,
hint: 'Your message subject',
),
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
CustomTextField(
controller: vm.bodyController,
keyboardType: TextInputType.multiline,
hint: 'Your message',
lines: 8,
),
if (viewState.errorMessage.isNotEmpty) ...[
const SizedBox(height: 4),
Text(
viewState.errorMessage,
textAlign: TextAlign.center,
style: const TextStyle(
color: Color.fromRGBO(239, 17, 17, 1),
fontSize: 12,
),
),
],
SizedBox(height: SizeUtils.getByScreen(small: 28, big: 27)),
PrimaryButton(
onPressed: vm.sendEmail,
text: 'Send!',
color: theme.getColorFor(ThemeCode.buttonPrimary)
)
],
)
)
) )
), ),
); );

View File

@@ -2,6 +2,7 @@ import 'package:customer_service/src/presentation/contact_screen.dart';
import 'package:design_system/design_system.dart'; import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:navigation/navigation.dart'; import 'package:navigation/navigation.dart';
import 'package:sf_localizations/sf_localizations.dart'; import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart'; import 'package:utils/utils.dart';
@@ -14,80 +15,66 @@ class CustomerServiceScreen extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider); // final theme = ref.watch(themePortProvider);
return Scaffold( return PageLayout(
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary), title: context.translate(I18n.customerService),
body: SafeArea( body: Container(
child: Container( padding: SizeUtils.getByScreen(
padding: SizeUtils.getByScreen( small: EdgeInsets.symmetric(horizontal: 18),
small: EdgeInsets.symmetric(horizontal: 18, vertical: 14), big: EdgeInsets.symmetric(horizontal: 16)
big: EdgeInsets.symmetric(horizontal: 16, vertical: 12) ),
), child: Column(
child: Column( children: [
children: [ SectionButton(
Stack( onPressed: () async {
children: [ final Uri url = Uri.parse('https://www.savefamilygps.com/');
SizedBox( if (!await launchUrl(url)) {
height: SizeUtils.getByScreen(small: 36, big: 36), throw Exception('Could not launch $url');
child: Align( }
alignment: Alignment.centerLeft, },
child: Icon(Icons.arrow_back, size: SizeUtils.getByScreen(small: 36, big: 34)) image: 'assets/images/ui/iso_sf.png',
) text: context.translate(I18n.supportWebsite)
), ),
Center(child: Text(context.translate(I18n.customerService), SizedBox(height: SizeUtils.getByScreen(small: 10, big: 9)),
style: TextStyle(fontSize: SizeUtils.getByScreen(small: 28, big: 27)))) SectionButton(
], onPressed: () async {
), final Uri url = Uri.parse('https://savefamilygpshelp.zendesk.com/hc/es');
SizedBox(height: SizeUtils.getByScreen(small: 40, big: 38)), if (!await launchUrl(url)) {
AppSectionButton( throw Exception('Could not launch $url');
onPressed: () async { }
final Uri url = Uri.parse('https://www.savefamilygps.com/'); },
if (!await launchUrl(url)) { icon: SFIcons.handshake,
throw Exception('Could not launch $url'); text: context.translate(I18n.supportHelp)
} ),
}, SizedBox(height: SizeUtils.getByScreen(small: 10, big: 9)),
icon: Icons.sunny, SectionButton(
text: "Visit our Website"
),
SizedBox(height: SizeUtils.getByScreen(small: 10, big: 9)),
AppSectionButton(
onPressed: () async {
final Uri url = Uri.parse('https://savefamilygpshelp.zendesk.com/hc/es');
if (!await launchUrl(url)) {
throw Exception('Could not launch $url');
}
},
icon: Icons.handshake_outlined,
text: "Can we help you?"
),
SizedBox(height: SizeUtils.getByScreen(small: 10, big: 9)),
AppSectionButton(
onPressed: (){Navigator.push(context, onPressed: (){Navigator.push(context,
MaterialPageRoute( MaterialPageRoute(
builder: (_) => ContactScreen(navigationContract: navigationContract), builder: (_) => ContactScreen(navigationContract: navigationContract),
));}, ));},
icon: Icons.email_outlined, icon: Icons.email_outlined,
text: context.translate(I18n.contactTitle) text: context.translate(I18n.contactTitle)
), ),
], ],
)
) )
), )
); );
} }
} }
class AppSectionButton extends ConsumerWidget { class SectionButton extends ConsumerWidget {
final GestureTapCallback onPressed; final GestureTapCallback onPressed;
final IconData icon; final IconData? icon;
final String? image;
final String text; final String text;
const AppSectionButton({ const SectionButton({
required this.onPressed, required this.onPressed,
required this.icon, this.icon,
this.image,
required this.text, required this.text,
}); });
@@ -96,44 +83,49 @@ class AppSectionButton extends ConsumerWidget {
final theme = ref.read(themePortProvider); final theme = ref.read(themePortProvider);
return GestureDetector( return GestureDetector(
onTap: onPressed, onTap: onPressed,
child: Container( child: Container(
padding: SizeUtils.getByScreen( padding: SizeUtils.getByScreen(
small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), small: EdgeInsets.symmetric(horizontal: 22, vertical: 16),
big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) big: EdgeInsets.symmetric(horizontal: 21, vertical: 12)
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.all( borderRadius: BorderRadius.all(
Radius.circular(SizeUtils.getByScreen(small: 12, big: 18))), Radius.circular(SizeUtils.getByScreen(small: 12, big: 18))),
color: theme.getColorFor(ThemeCode.backgroundSecondary), color: theme.getColorFor(ThemeCode.backgroundSecondary),
), ),
child: Row( child: Row(
children: [ children: [
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: theme.getColorFor(ThemeCode.backgroundPrimary), color: theme.getColorFor(ThemeCode.backgroundPrimary),
), ),
padding: EdgeInsets.all( padding: EdgeInsets.all(
SizeUtils.getByScreen(small: 4, big: 12)), SizeUtils.getByScreen(small: 12, big: 16)),
child: Icon(icon, child: icon != null
size: SizeUtils.getByScreen(small: 40, big: 44), ?Icon(icon,
size: SizeUtils.getByScreen(small: 44, big: 48),
color: Color(0xFF588EA5), color: Color(0xFF588EA5),
weight: 30, weight: 30,
), )
: Image.asset(image!,
width: SizeUtils.getByScreen(small: 44, big: 48),
height: SizeUtils.getByScreen(small: 44, big: 48),
), ),
SizedBox(width: SizeUtils.getByScreen(small: 16, big: 15)), ),
Expanded( SizedBox(width: SizeUtils.getByScreen(small: 16, big: 15)),
child: Text(context.translate(text), Expanded(
style: TextStyle( child: Text(context.translate(text),
fontSize: SizeUtils.getByScreen(small: 18, big: 19), style: TextStyle(
fontWeight: FontWeight.w500 fontSize: SizeUtils.getByScreen(small: 18, big: 19),
) fontWeight: FontWeight.w500
) )
), )
], ),
), ],
) ),
)
); );
} }
} }

View File

@@ -88,27 +88,37 @@ class ContactViewModel extends Notifier<ContactViewState> {
void _onBodyChanged() { void _onBodyChanged() {
final text = bodyController.text; final text = bodyController.text;
if (text == state.body) return; if (text == state.message) return;
state = state.copyWith(body: text, errorMessage: ''); state = state.copyWith(message: text, errorMessage: '');
} }
void sendEmail() async { void sendEmail() async {
final receiver = 'aitorarana@savefamilygps.com'; final receiver = 'info@savefamilygps.com';
//final name = state.name; final name = state.name;
final country = state.country;
final channel = state.channel;
final sender = state.email; final sender = state.email;
final subject = state.subject; final subject = state.subject;
final body = state.body; final message = state.message;
if (sender.isEmpty) { if (sender.isEmpty) {
state = state.copyWith(errorMessage: I18n.errorEmailRequired); state = state.copyWith(errorMessage: I18n.errorEmailRequired);
return; return;
} }
if (_isValidEmail(sender)) { if (!_isValidEmail(sender)) {
state = state.copyWith(errorMessage: I18n.errorEmailInvalid); state = state.copyWith(errorMessage: I18n.errorEmailInvalid);
return;
} }
final body =
'country:$country\n'
'Purchase channel:$channel\n'
'name:$name\n'
'email:$sender\n'
'$message';
final Uri url = Uri.parse('mailto:$receiver?from=$sender&subject=$subject&body=$body'); final Uri url = Uri.parse('mailto:$receiver?from=$sender&subject=$subject&body=$body');
if (!await launchUrl(url)) { if (!await launchUrl(url)) {
throw Exception('Could not launch $url'); throw Exception('Could not launch $url');

View File

@@ -10,7 +10,7 @@ abstract class ContactViewState with _$ContactViewState{
@Default('') String name, @Default('') String name,
@Default('') String email, @Default('') String email,
@Default('') String subject, @Default('') String subject,
@Default('') String body, @Default('') String message,
@Default('') String errorMessage, @Default('') String errorMessage,
@Default('') String emailError, @Default('') String emailError,
}) = _ContactViewState; }) = _ContactViewState;

View File

@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
/// @nodoc /// @nodoc
mixin _$ContactViewState { mixin _$ContactViewState {
String get country; String get channel; String get name; String get email; String get subject; String get body; String get errorMessage; String get emailError; String get country; String get channel; String get name; String get email; String get subject; String get message; String get errorMessage; String get emailError;
/// Create a copy of ContactViewState /// Create a copy of ContactViewState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@@ -25,16 +25,16 @@ $ContactViewStateCopyWith<ContactViewState> get copyWith => _$ContactViewStateCo
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is ContactViewState&&(identical(other.country, country) || other.country == country)&&(identical(other.channel, channel) || other.channel == channel)&&(identical(other.name, name) || other.name == name)&&(identical(other.email, email) || other.email == email)&&(identical(other.subject, subject) || other.subject == subject)&&(identical(other.body, body) || other.body == body)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.emailError, emailError) || other.emailError == emailError)); return identical(this, other) || (other.runtimeType == runtimeType&&other is ContactViewState&&(identical(other.country, country) || other.country == country)&&(identical(other.channel, channel) || other.channel == channel)&&(identical(other.name, name) || other.name == name)&&(identical(other.email, email) || other.email == email)&&(identical(other.subject, subject) || other.subject == subject)&&(identical(other.message, message) || other.message == message)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.emailError, emailError) || other.emailError == emailError));
} }
@override @override
int get hashCode => Object.hash(runtimeType,country,channel,name,email,subject,body,errorMessage,emailError); int get hashCode => Object.hash(runtimeType,country,channel,name,email,subject,message,errorMessage,emailError);
@override @override
String toString() { String toString() {
return 'ContactViewState(country: $country, channel: $channel, name: $name, email: $email, subject: $subject, body: $body, errorMessage: $errorMessage, emailError: $emailError)'; return 'ContactViewState(country: $country, channel: $channel, name: $name, email: $email, subject: $subject, message: $message, errorMessage: $errorMessage, emailError: $emailError)';
} }
@@ -45,7 +45,7 @@ abstract mixin class $ContactViewStateCopyWith<$Res> {
factory $ContactViewStateCopyWith(ContactViewState value, $Res Function(ContactViewState) _then) = _$ContactViewStateCopyWithImpl; factory $ContactViewStateCopyWith(ContactViewState value, $Res Function(ContactViewState) _then) = _$ContactViewStateCopyWithImpl;
@useResult @useResult
$Res call({ $Res call({
String country, String channel, String name, String email, String subject, String body, String errorMessage, String emailError String country, String channel, String name, String email, String subject, String message, String errorMessage, String emailError
}); });
@@ -62,14 +62,14 @@ class _$ContactViewStateCopyWithImpl<$Res>
/// Create a copy of ContactViewState /// Create a copy of ContactViewState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? country = null,Object? channel = null,Object? name = null,Object? email = null,Object? subject = null,Object? body = null,Object? errorMessage = null,Object? emailError = null,}) { @pragma('vm:prefer-inline') @override $Res call({Object? country = null,Object? channel = null,Object? name = null,Object? email = null,Object? subject = null,Object? message = null,Object? errorMessage = null,Object? emailError = null,}) {
return _then(_self.copyWith( return _then(_self.copyWith(
country: null == country ? _self.country : country // ignore: cast_nullable_to_non_nullable country: null == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
as String,channel: null == channel ? _self.channel : channel // ignore: cast_nullable_to_non_nullable as String,channel: null == channel ? _self.channel : channel // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable
as String,subject: null == subject ? _self.subject : subject // ignore: cast_nullable_to_non_nullable as String,subject: null == subject ? _self.subject : subject // ignore: cast_nullable_to_non_nullable
as String,body: null == body ? _self.body : body // ignore: cast_nullable_to_non_nullable as String,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,emailError: null == emailError ? _self.emailError : emailError // ignore: cast_nullable_to_non_nullable as String,emailError: null == emailError ? _self.emailError : emailError // ignore: cast_nullable_to_non_nullable
as String, as String,
@@ -157,10 +157,10 @@ return $default(_that);case _:
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String country, String channel, String name, String email, String subject, String body, String errorMessage, String emailError)? $default,{required TResult orElse(),}) {final _that = this; @optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String country, String channel, String name, String email, String subject, String message, String errorMessage, String emailError)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) { switch (_that) {
case _ContactViewState() when $default != null: case _ContactViewState() when $default != null:
return $default(_that.country,_that.channel,_that.name,_that.email,_that.subject,_that.body,_that.errorMessage,_that.emailError);case _: return $default(_that.country,_that.channel,_that.name,_that.email,_that.subject,_that.message,_that.errorMessage,_that.emailError);case _:
return orElse(); return orElse();
} }
@@ -178,10 +178,10 @@ return $default(_that.country,_that.channel,_that.name,_that.email,_that.subject
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String country, String channel, String name, String email, String subject, String body, String errorMessage, String emailError) $default,) {final _that = this; @optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String country, String channel, String name, String email, String subject, String message, String errorMessage, String emailError) $default,) {final _that = this;
switch (_that) { switch (_that) {
case _ContactViewState(): case _ContactViewState():
return $default(_that.country,_that.channel,_that.name,_that.email,_that.subject,_that.body,_that.errorMessage,_that.emailError);case _: return $default(_that.country,_that.channel,_that.name,_that.email,_that.subject,_that.message,_that.errorMessage,_that.emailError);case _:
throw StateError('Unexpected subclass'); throw StateError('Unexpected subclass');
} }
@@ -198,10 +198,10 @@ return $default(_that.country,_that.channel,_that.name,_that.email,_that.subject
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String country, String channel, String name, String email, String subject, String body, String errorMessage, String emailError)? $default,) {final _that = this; @optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String country, String channel, String name, String email, String subject, String message, String errorMessage, String emailError)? $default,) {final _that = this;
switch (_that) { switch (_that) {
case _ContactViewState() when $default != null: case _ContactViewState() when $default != null:
return $default(_that.country,_that.channel,_that.name,_that.email,_that.subject,_that.body,_that.errorMessage,_that.emailError);case _: return $default(_that.country,_that.channel,_that.name,_that.email,_that.subject,_that.message,_that.errorMessage,_that.emailError);case _:
return null; return null;
} }
@@ -213,7 +213,7 @@ return $default(_that.country,_that.channel,_that.name,_that.email,_that.subject
class _ContactViewState implements ContactViewState { class _ContactViewState implements ContactViewState {
const _ContactViewState({this.country = '', this.channel = '', this.name = '', this.email = '', this.subject = '', this.body = '', this.errorMessage = '', this.emailError = ''}); const _ContactViewState({this.country = '', this.channel = '', this.name = '', this.email = '', this.subject = '', this.message = '', this.errorMessage = '', this.emailError = ''});
@override@JsonKey() final String country; @override@JsonKey() final String country;
@@ -221,7 +221,7 @@ class _ContactViewState implements ContactViewState {
@override@JsonKey() final String name; @override@JsonKey() final String name;
@override@JsonKey() final String email; @override@JsonKey() final String email;
@override@JsonKey() final String subject; @override@JsonKey() final String subject;
@override@JsonKey() final String body; @override@JsonKey() final String message;
@override@JsonKey() final String errorMessage; @override@JsonKey() final String errorMessage;
@override@JsonKey() final String emailError; @override@JsonKey() final String emailError;
@@ -235,16 +235,16 @@ _$ContactViewStateCopyWith<_ContactViewState> get copyWith => __$ContactViewStat
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ContactViewState&&(identical(other.country, country) || other.country == country)&&(identical(other.channel, channel) || other.channel == channel)&&(identical(other.name, name) || other.name == name)&&(identical(other.email, email) || other.email == email)&&(identical(other.subject, subject) || other.subject == subject)&&(identical(other.body, body) || other.body == body)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.emailError, emailError) || other.emailError == emailError)); return identical(this, other) || (other.runtimeType == runtimeType&&other is _ContactViewState&&(identical(other.country, country) || other.country == country)&&(identical(other.channel, channel) || other.channel == channel)&&(identical(other.name, name) || other.name == name)&&(identical(other.email, email) || other.email == email)&&(identical(other.subject, subject) || other.subject == subject)&&(identical(other.message, message) || other.message == message)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.emailError, emailError) || other.emailError == emailError));
} }
@override @override
int get hashCode => Object.hash(runtimeType,country,channel,name,email,subject,body,errorMessage,emailError); int get hashCode => Object.hash(runtimeType,country,channel,name,email,subject,message,errorMessage,emailError);
@override @override
String toString() { String toString() {
return 'ContactViewState(country: $country, channel: $channel, name: $name, email: $email, subject: $subject, body: $body, errorMessage: $errorMessage, emailError: $emailError)'; return 'ContactViewState(country: $country, channel: $channel, name: $name, email: $email, subject: $subject, message: $message, errorMessage: $errorMessage, emailError: $emailError)';
} }
@@ -255,7 +255,7 @@ abstract mixin class _$ContactViewStateCopyWith<$Res> implements $ContactViewSta
factory _$ContactViewStateCopyWith(_ContactViewState value, $Res Function(_ContactViewState) _then) = __$ContactViewStateCopyWithImpl; factory _$ContactViewStateCopyWith(_ContactViewState value, $Res Function(_ContactViewState) _then) = __$ContactViewStateCopyWithImpl;
@override @useResult @override @useResult
$Res call({ $Res call({
String country, String channel, String name, String email, String subject, String body, String errorMessage, String emailError String country, String channel, String name, String email, String subject, String message, String errorMessage, String emailError
}); });
@@ -272,14 +272,14 @@ class __$ContactViewStateCopyWithImpl<$Res>
/// Create a copy of ContactViewState /// Create a copy of ContactViewState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? country = null,Object? channel = null,Object? name = null,Object? email = null,Object? subject = null,Object? body = null,Object? errorMessage = null,Object? emailError = null,}) { @override @pragma('vm:prefer-inline') $Res call({Object? country = null,Object? channel = null,Object? name = null,Object? email = null,Object? subject = null,Object? message = null,Object? errorMessage = null,Object? emailError = null,}) {
return _then(_ContactViewState( return _then(_ContactViewState(
country: null == country ? _self.country : country // ignore: cast_nullable_to_non_nullable country: null == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
as String,channel: null == channel ? _self.channel : channel // ignore: cast_nullable_to_non_nullable as String,channel: null == channel ? _self.channel : channel // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable
as String,subject: null == subject ? _self.subject : subject // ignore: cast_nullable_to_non_nullable as String,subject: null == subject ? _self.subject : subject // ignore: cast_nullable_to_non_nullable
as String,body: null == body ? _self.body : body // ignore: cast_nullable_to_non_nullable as String,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,emailError: null == emailError ? _self.emailError : emailError // ignore: cast_nullable_to_non_nullable as String,emailError: null == emailError ? _self.emailError : emailError // ignore: cast_nullable_to_non_nullable
as String, as String,

View File

@@ -23,18 +23,29 @@ class PageLayout extends StatelessWidget{
children: [ children: [
Container( Container(
padding: SizeUtils.getByScreen( padding: SizeUtils.getByScreen(
small: EdgeInsets.symmetric(horizontal: 22, vertical: 10), small: EdgeInsets.fromLTRB(22, 20, 22, 0),
big: EdgeInsets.symmetric(horizontal: 21, vertical: 8) big: EdgeInsets.fromLTRB(21, 16, 21, 0),
), ),
child: Stack( child: Stack(
children: [ children: [
IconButton(onPressed: () {Navigator.pop(context);}, IconButton(onPressed: () {Navigator.pop(context);},
icon: Icon(Icons.arrow_back)), icon: Icon(Icons.arrow_back,
Center( color: Color(0xFF588EA5),
child: Text(title, size: 32,
style: TextStyle( ),
fontSize: SizeUtils.getByScreen(small: 28, big: 27) padding: EdgeInsets.zero,
), ),
SizedBox(
height: 50,
child: Center(
child: Text(title.toUpperCase(),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 20, big: 19),
fontWeight: FontWeight.w500,
letterSpacing: 0,
color: Color(0xFF588EA5)
),
)
) )
) )
], ],

View File

@@ -144,6 +144,8 @@
"channelAmazon": "Amazon", "channelAmazon": "Amazon",
"channelStore": "Physical store", "channelStore": "Physical store",
"other": "Other", "other": "Other",
"supportWebsite": "Visit our Website",
"supportHelp": "Can we help you?",
"contactTitle": "Contact us", "contactTitle": "Contact us",
"selectCountry": "Choose your country", "selectCountry": "Choose your country",
"selectChannel": "Purchase channel", "selectChannel": "Purchase channel",
@@ -151,8 +153,7 @@
"enterEmail": "Enter your email", "enterEmail": "Enter your email",
"enterSubject": "Your message subject", "enterSubject": "Your message subject",
"enterMessage": "Your message", "enterMessage": "Your message",
"sendEmail": "Send!" "sendEmail": "Send!",
"chat": "Chat",
"personalData": "Personal Data", "personalData": "Personal Data",
"addNewSF": "Add a new SaveFamily", "addNewSF": "Add a new SaveFamily",
"linkedDevices": "Linked Devices", "linkedDevices": "Linked Devices",

View File

@@ -140,19 +140,20 @@
"home": "Inicio", "home": "Inicio",
"location": "Mapa", "location": "Mapa",
"chat": "Chat", "chat": "Chat",
"channelOnline": "Tienda online SF", "channelOnline": "Tienda online de SF",
"channelAmazon": "Amazon", "channelAmazon": "Amazon",
"channelStore": "Tienda física", "channelStore": "Tienda física",
"other": "Otro", "other": "Otro",
"contactTitle": "Contacta con nosotros", "supportWebsite": "Visita nuestro sitio web",
"supportHelp": "¿Podemos ayudarte?",
"contactTitle": "Contáctanos",
"selectCountry": "Selecciona tu país", "selectCountry": "Selecciona tu país",
"selectChannel": "Caal de compra", "selectChannel": "Canal de compra",
"enterName": "Introduce tu nombre", "enterName": "Introduce tu nombre",
"enterEmail": "Introduce tu correo electrónico", "enterEmail": "Introduce tu correo electrónico",
"enterSubject": "Asunto del mensaje", "enterSubject": "Asunto del mensaje",
"enterMessage": "Tu mensaje", "enterMessage": "Tu mensaje",
"sendEmail": "!Enviar!" "sendEmail": "Enviar",
"chat": "Chat",
"personalData": "Datos Personales", "personalData": "Datos Personales",
"addNewSF": "Añadir un nuevo SaveFamily", "addNewSF": "Añadir un nuevo SaveFamily",
"linkedDevices": "Dispositivos vinculados", "linkedDevices": "Dispositivos vinculados",

View File

@@ -174,6 +174,8 @@ class I18n {
static const String channelAmazon = 'channelAmazon'; static const String channelAmazon = 'channelAmazon';
static const String channelStore = 'channelStore'; static const String channelStore = 'channelStore';
static const String other = 'other'; static const String other = 'other';
static const String supportWebsite = 'supportWebsite';
static const String supportHelp = 'supportHelp';
static const String contactTitle = 'contactTitle'; static const String contactTitle = 'contactTitle';
static const String selectCountry = 'selectCountry'; static const String selectCountry = 'selectCountry';
static const String selectChannel = 'selectChannel'; static const String selectChannel = 'selectChannel';