elCaribe app - customization and branding

This commit is contained in:
2025-12-12 19:09:42 -04:00
parent 9e5d0d8ebf
commit ba7deac9f3
402 changed files with 31833 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import 'package:news/ui/screens/auth/Widgets/svgPictureWidget.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/utils/uiUtils.dart';
class BottomCommButton extends StatelessWidget {
final Function onTap;
final String img;
final Color? btnColor;
final String btnCaption;
const BottomCommButton({super.key, required this.onTap, required this.img, this.btnColor, required this.btnCaption});
@override
Widget build(BuildContext context) {
String textLbl = "${UiUtils.getTranslatedLabel(context, 'continueWith')} ${UiUtils.getTranslatedLabel(context, btnCaption)}";
return InkWell(
splashColor: Colors.transparent,
child: Container(
height: 45.0,
width: MediaQuery.of(context).size.width * 0.9,
alignment: Alignment.center,
decoration: BoxDecoration(color: UiUtils.getColorScheme(context).surface, borderRadius: BorderRadius.circular(7.0)),
padding: const EdgeInsets.all(9.0),
margin: EdgeInsets.symmetric(vertical: 10),
child: Wrap(
spacing: 15,
children: [
SvgPictureWidget(assetName: img, width: 20, height: 20, fit: BoxFit.contain, assetColor: btnColor != null ? ColorFilter.mode(btnColor!, BlendMode.srcIn) : null),
CustomTextLabel(text: textLbl, textStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w600))
],
)),
onTap: () => onTap());
}
}

View File

@@ -0,0 +1,6 @@
import 'package:flutter/cupertino.dart';
fieldFocusChange(BuildContext context, FocusNode currentFocus, FocusNode nextFocus) {
currentFocus.unfocus();
FocusScope.of(context).requestFocus(nextFocus);
}

View File

@@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
import 'package:news/utils/uiUtils.dart';
class SetConfirmPass extends StatefulWidget {
final FocusNode currFocus;
final TextEditingController confPassC;
late String confPass;
late String pass;
SetConfirmPass({super.key, required this.currFocus, required this.confPassC, required this.confPass, required this.pass});
@override
State<StatefulWidget> createState() {
return _SetConfPassState();
}
}
class _SetConfPassState extends State<SetConfirmPass> {
bool isObscure = true;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 20),
child: TextFormField(
focusNode: widget.currFocus,
textInputAction: TextInputAction.done,
controller: widget.confPassC,
obscureText: isObscure,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: UiUtils.getColorScheme(context).primaryContainer,
),
validator: (value) {
if (value!.isEmpty) {
return UiUtils.getTranslatedLabel(context, 'confPassRequired');
}
if (value.trim() != widget.pass.trim()) {
return UiUtils.getTranslatedLabel(context, 'confPassNotMatch');
} else {
return null;
}
},
onChanged: (String value) {
widget.confPass = value;
},
decoration: InputDecoration(
hintText: UiUtils.getTranslatedLabel(context, 'confpassLbl'),
hintStyle: Theme.of(context).textTheme.titleMedium?.copyWith(
color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.5),
),
suffixIcon: Padding(
padding: const EdgeInsetsDirectional.only(end: 12.0),
child: IconButton(
icon: isObscure
? Icon(Icons.visibility_rounded, size: 20, color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.6))
: Icon(Icons.visibility_off_rounded, size: 20, color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.6)),
splashColor: Colors.transparent,
onPressed: () {
setState(() => isObscure = !isObscure);
},
)),
filled: true,
fillColor: Theme.of(context).colorScheme.surface,
contentPadding: const EdgeInsets.symmetric(horizontal: 25, vertical: 17),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: UiUtils.getColorScheme(context).outline.withOpacity(0.7)),
borderRadius: BorderRadius.circular(10.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
),
),
),
);
}
}

View File

@@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/utils/uiUtils.dart';
class SetDividerOR extends StatelessWidget {
const SetDividerOR({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
Color color = UiUtils.getColorScheme(context).outline.withOpacity(0.9);
return Padding(
padding: const EdgeInsetsDirectional.only(top: 30.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(child: Divider(indent: 10, endIndent: 10, color: color)),
CustomTextLabel(
text: 'orLbl',
textStyle: Theme.of(context).textTheme.titleMedium?.merge(TextStyle(color: color, fontSize: 12.0)),
),
Expanded(child: Divider(indent: 10, endIndent: 10, color: color)),
],
));
}
}

View File

@@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/utils/validators.dart';
import 'fieldFocusChange.dart';
class SetEmail extends StatelessWidget {
final FocusNode? currFocus;
final FocusNode? nextFocus;
final TextEditingController emailC;
late String email;
final double topPad;
SetEmail({super.key, this.currFocus, this.nextFocus, required this.emailC, required this.email, required this.topPad});
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: topPad),
child: TextFormField(
focusNode: currFocus,
textInputAction: TextInputAction.next,
controller: emailC,
style: Theme.of(context).textTheme.titleMedium?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer),
validator: (val) => Validators.emailValidation(val!, context),
onFieldSubmitted: (v) {
if (currFocus != null || nextFocus != null) fieldFocusChange(context, currFocus!, nextFocus!);
},
decoration: InputDecoration(
hintText: UiUtils.getTranslatedLabel(context, 'emailLbl'),
hintStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.5)),
filled: true,
fillColor: Theme.of(context).colorScheme.surface,
contentPadding: const EdgeInsets.symmetric(horizontal: 25, vertical: 17),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: UiUtils.getColorScheme(context).outline.withOpacity(0.7)),
borderRadius: BorderRadius.circular(10.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
),
),
),
);
}
}

View File

@@ -0,0 +1,16 @@
import 'package:flutter/material.dart';
import 'package:news/ui/widgets/customTextBtn.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/app/routes.dart';
setForgotPass(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Align(
alignment: Alignment.topRight,
child: CustomTextButton(
onTap: () => Navigator.of(context).pushNamed(Routes.forgotPass),
buttonStyle: ButtonStyle(overlayColor: WidgetStateProperty.all(Colors.transparent), foregroundColor: WidgetStateProperty.all(UiUtils.getColorScheme(context).outline.withOpacity(0.7))),
textWidget: const CustomTextLabel(text: 'forgotPassLbl'))));
}

View File

@@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:news/ui/styles/colors.dart';
import 'package:news/ui/widgets/customTextLabel.dart';
class SetLoginAndSignUpBtn extends StatelessWidget {
final Function onTap;
final String text;
final double topPad;
const SetLoginAndSignUpBtn({super.key, required this.onTap, required this.text, required this.topPad});
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: topPad),
child: InkWell(
splashColor: Colors.transparent,
child: Container(
height: 45.0,
width: MediaQuery.of(context).size.width * 0.9,
alignment: Alignment.center,
decoration: BoxDecoration(color: Theme.of(context).primaryColor, borderRadius: BorderRadius.circular(7.0)),
child: CustomTextLabel(
text: text,
textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(color: secondaryColor, fontWeight: FontWeight.w600, fontSize: 16, letterSpacing: 0.6),
),
),
onTap: () => onTap()),
);
}
}

View File

@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/utils/validators.dart';
import 'package:news/ui/screens/auth/Widgets/fieldFocusChange.dart';
class SetName extends StatelessWidget {
final FocusNode currFocus;
final FocusNode nextFocus;
final TextEditingController nameC;
late String name;
SetName({super.key, required this.currFocus, required this.nextFocus, required this.nameC, required this.name});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 40),
child: TextFormField(
focusNode: currFocus,
textInputAction: TextInputAction.next,
controller: nameC,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: UiUtils.getColorScheme(context).primaryContainer,
),
validator: (val) => Validators.nameValidation(val!, context),
onFieldSubmitted: (v) {
fieldFocusChange(context, currFocus, nextFocus);
},
decoration: InputDecoration(
hintText: UiUtils.getTranslatedLabel(context, 'nameLbl'),
hintStyle: Theme.of(context).textTheme.titleMedium?.copyWith(
color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.5),
),
filled: true,
fillColor: Theme.of(context).colorScheme.surface,
contentPadding: const EdgeInsets.symmetric(horizontal: 25, vertical: 17),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: UiUtils.getColorScheme(context).outline.withOpacity(0.7)),
borderRadius: BorderRadius.circular(10.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
),
),
),
);
}
}

View File

@@ -0,0 +1,81 @@
import 'package:flutter/material.dart';
import 'package:news/utils/uiUtils.dart';
import 'package:news/utils/validators.dart';
import 'fieldFocusChange.dart';
class SetPassword extends StatefulWidget {
final FocusNode currFocus;
final FocusNode? nextFocus;
final TextEditingController passC;
late String pass;
final double topPad;
final bool isLogin;
SetPassword({super.key, required this.currFocus, this.nextFocus, required this.passC, required this.pass, required this.topPad, required this.isLogin});
@override
State<StatefulWidget> createState() {
return _SetPassState();
}
}
class _SetPassState extends State<SetPassword> {
bool isObscure = true;
@override
Widget build(BuildContext context) {
return StatefulBuilder(builder: (context, StateSetter setStater) {
return Padding(
padding: EdgeInsets.only(top: widget.topPad),
child: TextFormField(
focusNode: widget.currFocus,
textInputAction: widget.isLogin ? TextInputAction.done : TextInputAction.next,
controller: widget.passC,
obscureText: isObscure,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: UiUtils.getColorScheme(context).primaryContainer,
),
validator: (val) => Validators.passValidation(val!, context),
onFieldSubmitted: (v) {
if (!widget.isLogin) {
fieldFocusChange(context, widget.currFocus, widget.nextFocus!);
}
},
onChanged: (String value) {
widget.pass = value;
setStater(() {});
},
decoration: InputDecoration(
hintText: UiUtils.getTranslatedLabel(context, 'passLbl'),
hintStyle: Theme.of(context).textTheme.titleMedium?.copyWith(
color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.5),
),
suffixIcon: Padding(
padding: const EdgeInsetsDirectional.only(end: 12.0),
child: IconButton(
icon: isObscure
? Icon(Icons.visibility_rounded, size: 20, color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.6))
: Icon(Icons.visibility_off_rounded, size: 20, color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.6)),
splashColor: Colors.transparent,
onPressed: () {
setState(() => isObscure = !isObscure);
},
)),
filled: true,
fillColor: Theme.of(context).colorScheme.surface,
contentPadding: const EdgeInsets.symmetric(horizontal: 25, vertical: 17),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: UiUtils.getColorScheme(context).outline.withOpacity(0.7)),
borderRadius: BorderRadius.circular(10.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
),
),
),
);
});
}
}

View File

@@ -0,0 +1,40 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:news/app/routes.dart';
import 'package:news/cubits/privacyTermsCubit.dart';
import 'package:news/utils/uiUtils.dart';
setTermPolicyTxt(BuildContext context, PrivacyTermsFetchSuccess state) {
return Container(
alignment: AlignmentDirectional.bottomCenter,
padding: const EdgeInsets.only(top: 20.0),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(children: [
TextSpan(
text: "${UiUtils.getTranslatedLabel(context, 'agreeTermPolicyLbl')}\n",
style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7), overflow: TextOverflow.ellipsis),
),
TextSpan(
text: UiUtils.getTranslatedLabel(context, 'termLbl'),
style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: Theme.of(context).primaryColor, decoration: TextDecoration.underline, overflow: TextOverflow.ellipsis),
recognizer: TapGestureRecognizer()
..onTap = (() {
Navigator.of(context).pushNamed(Routes.privacy, arguments: {"from": "login", "title": state.termsPolicy.title, "desc": state.termsPolicy.pageContent});
}),
),
TextSpan(
text: "\t${UiUtils.getTranslatedLabel(context, 'andLbl')}\t",
style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7), overflow: TextOverflow.ellipsis),
),
TextSpan(
text: UiUtils.getTranslatedLabel(context, 'priPolicy'),
style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: Theme.of(context).primaryColor, decoration: TextDecoration.underline, overflow: TextOverflow.ellipsis),
recognizer: TapGestureRecognizer()
..onTap = (() {
Navigator.of(context).pushNamed(Routes.privacy, arguments: {"from": "login", "title": state.privacyPolicy.title, "desc": state.privacyPolicy.pageContent});
}),
),
]),
));
}

View File

@@ -0,0 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:news/utils/uiUtils.dart';
class SvgPictureWidget extends StatelessWidget {
String assetName;
ColorFilter? assetColor;
double? height, width;
BoxFit? fit;
SvgPictureWidget({Key? key, required this.assetName, this.assetColor, this.height, this.width, this.fit}) : super(key: key);
@override
Widget build(BuildContext context) {
return SvgPicture.asset(
placeholderBuilder: (_) => Center(child: CircularProgressIndicator()), UiUtils.getSvgImagePath(assetName), colorFilter: assetColor, height: height, width: width, fit: fit ?? BoxFit.fill);
}
}