changed theme to green
This commit is contained in:
parent
f281eb5b50
commit
8c3493b792
@ -19,14 +19,19 @@ enum ContentThemeColor {
|
||||
pink,
|
||||
green,
|
||||
red,
|
||||
brandRed;
|
||||
brandRed,
|
||||
brandGreen;
|
||||
|
||||
Color get color {
|
||||
return (AdminTheme.theme.contentTheme.getMappedIntoThemeColor[this]?['color']) ?? Colors.black;
|
||||
return (AdminTheme.theme.contentTheme.getMappedIntoThemeColor[this]
|
||||
?['color']) ??
|
||||
Colors.black;
|
||||
}
|
||||
|
||||
Color get onColor {
|
||||
return (AdminTheme.theme.contentTheme.getMappedIntoThemeColor[this]?['onColor']) ?? Colors.white;
|
||||
return (AdminTheme.theme.contentTheme.getMappedIntoThemeColor[this]
|
||||
?['onColor']) ??
|
||||
Colors.white;
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +82,9 @@ class TopBarTheme {
|
||||
|
||||
static final TopBarTheme lightTopBarTheme = TopBarTheme();
|
||||
|
||||
static final TopBarTheme darkTopBarTheme = TopBarTheme(background: const Color(0xff2c3036), onBackground: const Color(0xffdcdcdc));
|
||||
static final TopBarTheme darkTopBarTheme = TopBarTheme(
|
||||
background: const Color(0xff2c3036),
|
||||
onBackground: const Color(0xffdcdcdc));
|
||||
}
|
||||
|
||||
class RightBarTheme {
|
||||
@ -121,6 +128,7 @@ class ContentTheme {
|
||||
final Color pink, onPink;
|
||||
final Color red, onRed;
|
||||
final Color brandRed, onBrandRed;
|
||||
final Color brandGreen, onBrandGreen;
|
||||
|
||||
final Color cardBackground, cardShadow, cardBorder, cardText, cardTextMuted;
|
||||
final Color title;
|
||||
@ -130,7 +138,10 @@ class ContentTheme {
|
||||
var c = AdminTheme.theme.contentTheme;
|
||||
return {
|
||||
ContentThemeColor.primary: {'color': c.primary, 'onColor': c.onPrimary},
|
||||
ContentThemeColor.secondary: {'color': c.secondary, 'onColor': c.onSecondary},
|
||||
ContentThemeColor.secondary: {
|
||||
'color': c.secondary,
|
||||
'onColor': c.onSecondary
|
||||
},
|
||||
ContentThemeColor.success: {'color': c.success, 'onColor': c.onSuccess},
|
||||
ContentThemeColor.info: {'color': c.info, 'onColor': c.onInfo},
|
||||
ContentThemeColor.warning: {'color': c.warning, 'onColor': c.onWarning},
|
||||
@ -139,14 +150,21 @@ class ContentTheme {
|
||||
ContentThemeColor.dark: {'color': c.dark, 'onColor': c.onDark},
|
||||
ContentThemeColor.pink: {'color': c.pink, 'onColor': c.onPink},
|
||||
ContentThemeColor.red: {'color': c.red, 'onColor': c.onRed},
|
||||
ContentThemeColor.brandRed: {'color': c.brandRed, 'onColor': c.onBrandRed},
|
||||
ContentThemeColor.brandRed: {
|
||||
'color': c.brandRed,
|
||||
'onColor': c.onBrandRed
|
||||
},
|
||||
ContentThemeColor.green: {
|
||||
'color': c.brandGreen,
|
||||
'onColor': c.onBrandGreen
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ContentTheme({
|
||||
this.background = const Color(0xfffafbfe),
|
||||
this.onBackground = const Color(0xffF1F1F2),
|
||||
this.primary = const Color(0xff663399),
|
||||
this.primary = const Color(0xFF49BF3C),
|
||||
this.onPrimary = const Color(0xffffffff),
|
||||
this.secondary = const Color(0xff6c757d),
|
||||
this.onSecondary = const Color(0xffffffff),
|
||||
@ -178,12 +196,12 @@ class ContentTheme {
|
||||
this.title = const Color(0xff6c757d),
|
||||
this.disabled = const Color(0xffffffff),
|
||||
this.onDisabled = const Color(0xffffffff),
|
||||
this.brandGreen = const Color(0xFF49BF3C),
|
||||
this.onBrandGreen = const Color(0xFFFFFFFF),
|
||||
});
|
||||
|
||||
//-------------------------------------- Left Bar Theme ----------------------------------------//
|
||||
|
||||
static final ContentTheme lightContentTheme = ContentTheme(
|
||||
primary: Color(0xff663399),
|
||||
primary: Color(0xFF49BF3C),
|
||||
background: const Color(0xfffafbfe),
|
||||
onBackground: const Color(0xff313a46),
|
||||
cardBorder: const Color(0xffe8ecf1),
|
||||
@ -197,7 +215,7 @@ class ContentTheme {
|
||||
);
|
||||
|
||||
static final ContentTheme darkContentTheme = ContentTheme(
|
||||
primary: Color(0xff32BFAE),
|
||||
primary: Color(0xFF49BF3C),
|
||||
background: const Color(0xff343a40),
|
||||
onBackground: const Color(0xffF1F1F2),
|
||||
disabled: const Color(0xff444d57),
|
||||
@ -236,9 +254,17 @@ class AdminTheme {
|
||||
|
||||
static void setTheme() {
|
||||
theme = AdminTheme(
|
||||
leftBarTheme: ThemeCustomizer.instance.theme == ThemeMode.dark ? LeftBarTheme.darkLeftBarTheme : LeftBarTheme.lightLeftBarTheme,
|
||||
topBarTheme: ThemeCustomizer.instance.theme == ThemeMode.dark ? TopBarTheme.darkTopBarTheme : TopBarTheme.lightTopBarTheme,
|
||||
rightBarTheme: ThemeCustomizer.instance.theme == ThemeMode.dark ? RightBarTheme.darkRightBarTheme : RightBarTheme.lightRightBarTheme,
|
||||
contentTheme: ThemeCustomizer.instance.theme == ThemeMode.dark ? ContentTheme.darkContentTheme : ContentTheme.lightContentTheme);
|
||||
leftBarTheme: ThemeCustomizer.instance.theme == ThemeMode.dark
|
||||
? LeftBarTheme.darkLeftBarTheme
|
||||
: LeftBarTheme.lightLeftBarTheme,
|
||||
topBarTheme: ThemeCustomizer.instance.theme == ThemeMode.dark
|
||||
? TopBarTheme.darkTopBarTheme
|
||||
: TopBarTheme.lightTopBarTheme,
|
||||
rightBarTheme: ThemeCustomizer.instance.theme == ThemeMode.dark
|
||||
? RightBarTheme.darkRightBarTheme
|
||||
: RightBarTheme.lightRightBarTheme,
|
||||
contentTheme: ThemeCustomizer.instance.theme == ThemeMode.dark
|
||||
? ContentTheme.darkContentTheme
|
||||
: ContentTheme.lightContentTheme);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:marco/helpers/widgets/my_spacing.dart';
|
||||
import 'package:marco/helpers/widgets/my_text.dart';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
|
||||
class BaseBottomSheet extends StatelessWidget {
|
||||
class BaseBottomSheet extends StatefulWidget {
|
||||
final String title;
|
||||
final String? subtitle;
|
||||
final Widget child;
|
||||
@ -10,7 +11,7 @@ class BaseBottomSheet extends StatelessWidget {
|
||||
final VoidCallback onSubmit;
|
||||
final bool isSubmitting;
|
||||
final String submitText;
|
||||
final Color submitColor;
|
||||
final Color? submitColor;
|
||||
final IconData submitIcon;
|
||||
final bool showButtons;
|
||||
final Widget? bottomContent;
|
||||
@ -24,16 +25,23 @@ class BaseBottomSheet extends StatelessWidget {
|
||||
this.subtitle,
|
||||
this.isSubmitting = false,
|
||||
this.submitText = 'Submit',
|
||||
this.submitColor = Colors.indigo,
|
||||
this.submitColor,
|
||||
this.submitIcon = Icons.check_circle_outline,
|
||||
this.showButtons = true,
|
||||
this.bottomContent,
|
||||
});
|
||||
|
||||
@override
|
||||
State<BaseBottomSheet> createState() => _BaseBottomSheetState();
|
||||
}
|
||||
|
||||
class _BaseBottomSheetState extends State<BaseBottomSheet> with UIMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final mediaQuery = MediaQuery.of(context);
|
||||
final effectiveSubmitColor =
|
||||
widget.submitColor ?? contentTheme.primary;
|
||||
|
||||
return SingleChildScrollView(
|
||||
padding: mediaQuery.viewInsets,
|
||||
@ -71,35 +79,31 @@ class BaseBottomSheet extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
MySpacing.height(12),
|
||||
|
||||
// ✅ Centered title
|
||||
Center(
|
||||
child: MyText.titleLarge(
|
||||
title,
|
||||
widget.title,
|
||||
fontWeight: 700,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
|
||||
// ✅ Subtitle shown just below header if provided
|
||||
if (subtitle != null && subtitle!.isNotEmpty) ...[
|
||||
if (widget.subtitle != null &&
|
||||
widget.subtitle!.isNotEmpty) ...[
|
||||
MySpacing.height(4),
|
||||
MyText.bodySmall(
|
||||
subtitle!,
|
||||
widget.subtitle!,
|
||||
fontWeight: 600,
|
||||
color: Colors.grey[700],
|
||||
),
|
||||
],
|
||||
|
||||
MySpacing.height(12),
|
||||
child,
|
||||
widget.child,
|
||||
MySpacing.height(12),
|
||||
if (showButtons) ...[
|
||||
if (widget.showButtons) ...[
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: onCancel,
|
||||
onPressed: widget.onCancel,
|
||||
icon: const Icon(Icons.close, color: Colors.white),
|
||||
label: MyText.bodyMedium(
|
||||
"Cancel",
|
||||
@ -111,34 +115,40 @@ class BaseBottomSheet extends StatelessWidget {
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 8),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: isSubmitting ? null : onSubmit,
|
||||
icon: Icon(submitIcon, color: Colors.white),
|
||||
onPressed:
|
||||
widget.isSubmitting ? null : widget.onSubmit,
|
||||
icon:
|
||||
Icon(widget.submitIcon, color: Colors.white),
|
||||
label: MyText.bodyMedium(
|
||||
isSubmitting ? "Submitting..." : submitText,
|
||||
widget.isSubmitting
|
||||
? "Submitting..."
|
||||
: widget.submitText,
|
||||
color: Colors.white,
|
||||
fontWeight: 600,
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: submitColor,
|
||||
backgroundColor: effectiveSubmitColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 8),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (bottomContent != null) ...[
|
||||
if (widget.bottomContent != null) ...[
|
||||
MySpacing.height(12),
|
||||
bottomContent!,
|
||||
widget.bottomContent!,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
@ -9,6 +9,7 @@ import 'package:marco/helpers/widgets/my_text.dart';
|
||||
import 'package:marco/model/expense/expense_list_model.dart';
|
||||
import 'package:marco/view/expense/expense_detail_screen.dart';
|
||||
import 'package:marco/helpers/widgets/my_confirmation_dialog.dart';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
|
||||
class ExpenseAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
final ProjectController projectController;
|
||||
@ -72,7 +73,7 @@ class ExpenseAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class SearchAndFilter extends StatelessWidget {
|
||||
class SearchAndFilter extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final ValueChanged<String> onChanged;
|
||||
final VoidCallback onFilterTap;
|
||||
@ -86,6 +87,11 @@ class SearchAndFilter extends StatelessWidget {
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<SearchAndFilter> createState() => _SearchAndFilterState();
|
||||
}
|
||||
|
||||
class _SearchAndFilterState extends State<SearchAndFilter> with UIMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
@ -96,8 +102,8 @@ class SearchAndFilter extends StatelessWidget {
|
||||
child: SizedBox(
|
||||
height: 35,
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
onChanged: onChanged,
|
||||
controller: widget.controller,
|
||||
onChanged: widget.onChanged,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
prefixIcon:
|
||||
@ -109,6 +115,11 @@ class SearchAndFilter extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Colors.grey.shade300),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide:
|
||||
BorderSide(color: contentTheme.primary, width: 1.5),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Colors.grey.shade300),
|
||||
@ -124,7 +135,7 @@ class SearchAndFilter extends StatelessWidget {
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
const Icon(Icons.tune, color: Colors.black),
|
||||
if (expenseController.isFilterApplied)
|
||||
if (widget.expenseController.isFilterApplied)
|
||||
Positioned(
|
||||
top: -1,
|
||||
right: -1,
|
||||
@ -140,7 +151,7 @@ class SearchAndFilter extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: onFilterTap,
|
||||
onPressed: widget.onFilterTap,
|
||||
);
|
||||
}),
|
||||
],
|
||||
|
66
lib/helpers/widgets/wave_background.dart
Normal file
66
lib/helpers/widgets/wave_background.dart
Normal file
@ -0,0 +1,66 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class WaveBackground extends StatelessWidget {
|
||||
final Color color;
|
||||
final double heightFactor;
|
||||
|
||||
const WaveBackground({
|
||||
super.key,
|
||||
required this.color,
|
||||
this.heightFactor = 0.2,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CustomPaint(
|
||||
painter: _WavePainter(color, heightFactor),
|
||||
size: Size.infinite,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _WavePainter extends CustomPainter {
|
||||
final Color color;
|
||||
final double heightFactor;
|
||||
|
||||
_WavePainter(this.color, this.heightFactor);
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint1 = Paint()
|
||||
..shader = LinearGradient(
|
||||
colors: [
|
||||
const Color(0xFF49BF3C),
|
||||
const Color(0xFF81C784),
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
).createShader(Rect.fromLTWH(0, 0, size.width, size.height));
|
||||
|
||||
final path1 = Path()
|
||||
..moveTo(0, size.height * heightFactor)
|
||||
..quadraticBezierTo(
|
||||
size.width * 0.25, size.height * 0.05, size.width * 0.5, size.height * 0.15)
|
||||
..quadraticBezierTo(
|
||||
size.width * 0.75, size.height * 0.25, size.width, size.height * 0.1)
|
||||
..lineTo(size.width, 0)
|
||||
..lineTo(0, 0)
|
||||
..close();
|
||||
|
||||
canvas.drawPath(path1, paint1);
|
||||
|
||||
// Secondary wave (overlay) with same green but lighter opacity
|
||||
final paint2 = Paint()..color = const Color(0xFF49BF3C).withOpacity(0.15);
|
||||
final path2 = Path()
|
||||
..moveTo(0, size.height * (heightFactor + 0.05))
|
||||
..quadraticBezierTo(size.width * 0.4, size.height * 0.1, size.width, size.height * 0.2)
|
||||
..lineTo(size.width, 0)
|
||||
..lineTo(0, 0)
|
||||
..close();
|
||||
|
||||
canvas.drawPath(path2, paint2);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(CustomPainter oldDelegate) => false;
|
||||
}
|
@ -94,7 +94,7 @@ class _EmailLoginFormState extends State<EmailLoginForm> with UIMixin {
|
||||
MaterialStateProperty.resolveWith<Color>(
|
||||
(states) =>
|
||||
states.contains(WidgetState.selected)
|
||||
? contentTheme.brandRed
|
||||
? contentTheme.primary
|
||||
: Colors.white,
|
||||
),
|
||||
checkColor: contentTheme.onPrimary,
|
||||
@ -128,7 +128,7 @@ class _EmailLoginFormState extends State<EmailLoginForm> with UIMixin {
|
||||
elevation: 2,
|
||||
padding: MySpacing.xy(80, 16),
|
||||
borderRadiusAll: 10,
|
||||
backgroundColor: contentTheme.brandRed,
|
||||
backgroundColor: contentTheme.primary,
|
||||
child: MyText.labelLarge(
|
||||
'Login',
|
||||
fontWeight: 700,
|
||||
|
@ -8,6 +8,7 @@ import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
import 'package:marco/helpers/widgets/my_button.dart';
|
||||
import 'package:marco/helpers/widgets/my_text.dart';
|
||||
import 'package:marco/images.dart';
|
||||
import 'package:marco/helpers/widgets/wave_background.dart';
|
||||
|
||||
class ForgotPasswordScreen extends StatefulWidget {
|
||||
const ForgotPasswordScreen({super.key});
|
||||
@ -59,7 +60,7 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen>
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
children: [
|
||||
_RedWaveBackground(brandRed: contentTheme.brandRed),
|
||||
WaveBackground(color: contentTheme.brandRed),
|
||||
SafeArea(
|
||||
child: Center(
|
||||
child: Column(
|
||||
@ -230,8 +231,8 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen>
|
||||
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 16),
|
||||
borderRadiusAll: 10,
|
||||
backgroundColor: _isLoading
|
||||
? contentTheme.brandRed.withOpacity(0.6)
|
||||
: contentTheme.brandRed,
|
||||
? contentTheme.primary.withOpacity(0.6)
|
||||
: contentTheme.primary,
|
||||
child: _isLoading
|
||||
? const SizedBox(
|
||||
height: 20,
|
||||
@ -253,68 +254,13 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen>
|
||||
Widget _buildBackButton() {
|
||||
return TextButton.icon(
|
||||
onPressed: () async => await LocalStorage.logout(),
|
||||
icon: const Icon(Icons.arrow_back, size: 18, color: Colors.redAccent),
|
||||
icon: Icon(Icons.arrow_back, size: 18, color: contentTheme.primary),
|
||||
label: MyText.bodyMedium(
|
||||
'Back to Login',
|
||||
color: contentTheme.brandRed,
|
||||
color: contentTheme.primary,
|
||||
fontWeight: 600,
|
||||
fontSize: 14,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _RedWaveBackground extends StatelessWidget {
|
||||
final Color brandRed;
|
||||
const _RedWaveBackground({required this.brandRed});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CustomPaint(
|
||||
painter: _WavePainter(brandRed),
|
||||
size: Size.infinite,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _WavePainter extends CustomPainter {
|
||||
final Color brandRed;
|
||||
|
||||
_WavePainter(this.brandRed);
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint1 = Paint()
|
||||
..shader = LinearGradient(
|
||||
colors: [brandRed, const Color.fromARGB(255, 97, 22, 22)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
).createShader(Rect.fromLTWH(0, 0, size.width, size.height));
|
||||
|
||||
final path1 = Path()
|
||||
..moveTo(0, size.height * 0.2)
|
||||
..quadraticBezierTo(size.width * 0.25, size.height * 0.05,
|
||||
size.width * 0.5, size.height * 0.15)
|
||||
..quadraticBezierTo(
|
||||
size.width * 0.75, size.height * 0.25, size.width, size.height * 0.1)
|
||||
..lineTo(size.width, 0)
|
||||
..lineTo(0, 0)
|
||||
..close();
|
||||
|
||||
canvas.drawPath(path1, paint1);
|
||||
|
||||
final paint2 = Paint()..color = Colors.redAccent.withOpacity(0.15);
|
||||
final path2 = Path()
|
||||
..moveTo(0, size.height * 0.25)
|
||||
..quadraticBezierTo(
|
||||
size.width * 0.4, size.height * 0.1, size.width, size.height * 0.2)
|
||||
..lineTo(size.width, 0)
|
||||
..lineTo(0, 0)
|
||||
..close();
|
||||
|
||||
canvas.drawPath(path2, paint2);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(CustomPainter oldDelegate) => false;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import 'package:marco/view/auth/otp_login_form.dart';
|
||||
import 'package:marco/helpers/services/api_endpoints.dart';
|
||||
import 'package:marco/view/auth/request_demo_bottom_sheet.dart';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
import 'package:marco/helpers/widgets/wave_background.dart';
|
||||
|
||||
enum LoginOption { email, otp }
|
||||
|
||||
@ -101,13 +102,14 @@ class _WelcomeScreenState extends State<WelcomeScreen>
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
children: [
|
||||
_RedWaveBackground(brandRed: contentTheme.brandRed),
|
||||
WaveBackground(color: contentTheme.brandRed),
|
||||
SafeArea(
|
||||
child: Center(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: isNarrow ? double.infinity : 420),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: isNarrow ? double.infinity : 420),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
@ -166,7 +168,10 @@ class _WelcomeScreenState extends State<WelcomeScreen>
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 10, offset: Offset(0, 4))],
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black12, blurRadius: 10, offset: Offset(0, 4))
|
||||
],
|
||||
),
|
||||
child: Image.asset(Images.logoDark),
|
||||
),
|
||||
@ -230,7 +235,7 @@ class _WelcomeScreenState extends State<WelcomeScreen>
|
||||
),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: contentTheme.brandRed,
|
||||
backgroundColor: contentTheme.brandGreen,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
|
||||
elevation: 4,
|
||||
@ -247,55 +252,3 @@ class _WelcomeScreenState extends State<WelcomeScreen>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Red wave background painter
|
||||
class _RedWaveBackground extends StatelessWidget {
|
||||
final Color brandRed;
|
||||
const _RedWaveBackground({required this.brandRed});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CustomPaint(
|
||||
painter: _WavePainter(brandRed),
|
||||
size: Size.infinite,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _WavePainter extends CustomPainter {
|
||||
final Color brandRed;
|
||||
_WavePainter(this.brandRed);
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint1 = Paint()
|
||||
..shader = LinearGradient(
|
||||
colors: [brandRed, const Color.fromARGB(255, 97, 22, 22)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
).createShader(Rect.fromLTWH(0, 0, size.width, size.height));
|
||||
|
||||
final path1 = Path()
|
||||
..moveTo(0, size.height * 0.2)
|
||||
..quadraticBezierTo(size.width * 0.25, size.height * 0.05, size.width * 0.5, size.height * 0.15)
|
||||
..quadraticBezierTo(size.width * 0.75, size.height * 0.25, size.width, size.height * 0.1)
|
||||
..lineTo(size.width, 0)
|
||||
..lineTo(0, 0)
|
||||
..close();
|
||||
|
||||
canvas.drawPath(path1, paint1);
|
||||
|
||||
final paint2 = Paint()..color = Colors.redAccent.withOpacity(0.15);
|
||||
final path2 = Path()
|
||||
..moveTo(0, size.height * 0.25)
|
||||
..quadraticBezierTo(size.width * 0.4, size.height * 0.1, size.width, size.height * 0.2)
|
||||
..lineTo(size.width, 0)
|
||||
..lineTo(0, 0)
|
||||
..close();
|
||||
|
||||
canvas.drawPath(path2, paint2);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(CustomPainter oldDelegate) => false;
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ class _LoginScreenState extends State<LoginScreen> with UIMixin {
|
||||
elevation: 2,
|
||||
padding: MySpacing.xy(24, 16),
|
||||
borderRadiusAll: 5,
|
||||
backgroundColor: Colors.blueAccent,
|
||||
backgroundColor:contentTheme.brandGreen,
|
||||
child: MyText.labelMedium(
|
||||
'Login',
|
||||
fontWeight: 600,
|
||||
|
@ -8,6 +8,7 @@ import 'package:marco/images.dart';
|
||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
||||
import 'package:marco/helpers/services/api_endpoints.dart';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
import 'package:marco/helpers/widgets/wave_background.dart';
|
||||
|
||||
class MPINAuthScreen extends StatefulWidget {
|
||||
const MPINAuthScreen({super.key});
|
||||
@ -51,7 +52,7 @@ class _MPINAuthScreenState extends State<MPINAuthScreen>
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
children: [
|
||||
_RedWaveBackground(brandRed: contentTheme.brandRed),
|
||||
WaveBackground(color: contentTheme.brandRed),
|
||||
SafeArea(
|
||||
child: Center(
|
||||
child: Column(
|
||||
@ -281,8 +282,8 @@ class _MPINAuthScreenState extends State<MPINAuthScreen>
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
|
||||
borderRadiusAll: 5,
|
||||
backgroundColor: controller.isLoading.value
|
||||
? contentTheme.brandRed.withOpacity(0.6)
|
||||
: contentTheme.brandRed,
|
||||
? contentTheme.primary.withOpacity(0.6)
|
||||
: contentTheme.primary,
|
||||
child: controller.isLoading.value
|
||||
? const SizedBox(
|
||||
height: 20,
|
||||
@ -341,57 +342,3 @@ class _MPINAuthScreenState extends State<MPINAuthScreen>
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class _RedWaveBackground extends StatelessWidget {
|
||||
final Color brandRed;
|
||||
const _RedWaveBackground({required this.brandRed});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CustomPaint(
|
||||
painter: _WavePainter(brandRed),
|
||||
size: Size.infinite,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _WavePainter extends CustomPainter {
|
||||
final Color brandRed;
|
||||
const _WavePainter(this.brandRed);
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint1 = Paint()
|
||||
..shader = LinearGradient(
|
||||
colors: [brandRed, const Color.fromARGB(255, 97, 22, 22)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
).createShader(Rect.fromLTWH(0, 0, size.width, size.height));
|
||||
|
||||
final path1 = Path()
|
||||
..moveTo(0, size.height * 0.2)
|
||||
..quadraticBezierTo(size.width * 0.25, size.height * 0.05,
|
||||
size.width * 0.5, size.height * 0.15)
|
||||
..quadraticBezierTo(
|
||||
size.width * 0.75, size.height * 0.25, size.width, size.height * 0.1)
|
||||
..lineTo(size.width, 0)
|
||||
..lineTo(0, 0)
|
||||
..close();
|
||||
|
||||
canvas.drawPath(path1, paint1);
|
||||
|
||||
final paint2 = Paint()..color = Colors.redAccent.withOpacity(0.15);
|
||||
final path2 = Path()
|
||||
..moveTo(0, size.height * 0.25)
|
||||
..quadraticBezierTo(
|
||||
size.width * 0.4, size.height * 0.1, size.width, size.height * 0.2)
|
||||
..lineTo(size.width, 0)
|
||||
..lineTo(0, 0)
|
||||
..close();
|
||||
|
||||
canvas.drawPath(path2, paint2);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(CustomPainter oldDelegate) => false;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ class _OTPLoginScreenState extends State<OTPLoginScreen> with UIMixin {
|
||||
elevation: 2,
|
||||
padding: MySpacing.xy(24, 16),
|
||||
borderRadiusAll: 10,
|
||||
backgroundColor: isDisabled ? Colors.grey : contentTheme.brandRed,
|
||||
backgroundColor: isDisabled ? Colors.grey : contentTheme.primary,
|
||||
child: controller.isSending.value
|
||||
? SizedBox(
|
||||
width: 20,
|
||||
|
@ -166,10 +166,9 @@ class _OrganizationFormState extends State<_OrganizationForm> with UIMixin {
|
||||
onChanged: (val) => setState(() => _agreed = val ?? false),
|
||||
fillColor: MaterialStateProperty.resolveWith((states) =>
|
||||
states.contains(MaterialState.selected)
|
||||
? contentTheme.brandRed
|
||||
? contentTheme.primary
|
||||
: Colors.white),
|
||||
checkColor: Colors.white,
|
||||
side: const BorderSide(color: Colors.red, width: 2),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
@ -179,7 +178,7 @@ class _OrganizationFormState extends State<_OrganizationForm> with UIMixin {
|
||||
),
|
||||
MyText(
|
||||
'privacy policy & terms',
|
||||
color: contentTheme.brandRed,
|
||||
color: contentTheme.primary,
|
||||
fontWeight: 600,
|
||||
),
|
||||
],
|
||||
@ -188,44 +187,44 @@ class _OrganizationFormState extends State<_OrganizationForm> with UIMixin {
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
OutlinedButton.icon(
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon: const Icon(Icons.arrow_back, color: Colors.red),
|
||||
label: MyText.bodyMedium("Back", color: Colors.red),
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: const BorderSide(color: Colors.red),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 28, vertical: 5),
|
||||
),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
onPressed: _loading ? null : _submitForm,
|
||||
icon: _loading
|
||||
? const SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(
|
||||
icon: const Icon(Icons.close, color: Colors.white),
|
||||
label: MyText.bodyMedium(
|
||||
"Cancel",
|
||||
color: Colors.white,
|
||||
strokeWidth: 2,
|
||||
fontWeight: 600,
|
||||
),
|
||||
)
|
||||
: const Icon(Icons.check_circle_outline,
|
||||
color: Colors.white),
|
||||
label: _loading
|
||||
? const SizedBox.shrink()
|
||||
: MyText.bodyMedium("Submit", color: Colors.white),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.indigo,
|
||||
backgroundColor: Colors.grey,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: _loading ? null : _submitForm,
|
||||
icon:
|
||||
Icon(Icons.check_circle_outline, color: Colors.white),
|
||||
label: MyText.bodyMedium(
|
||||
_loading ? "Submitting..." : "Submit",
|
||||
color: Colors.white,
|
||||
fontWeight: 600,
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: contentTheme
|
||||
.primary,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 28, vertical: 5),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -235,11 +234,11 @@ class _OrganizationFormState extends State<_OrganizationForm> with UIMixin {
|
||||
child: TextButton.icon(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon:
|
||||
const Icon(Icons.arrow_back, size: 18, color: Colors.red),
|
||||
Icon(Icons.arrow_back, size: 18, color: contentTheme.primary),
|
||||
label: MyText.bodySmall(
|
||||
'Back to log in',
|
||||
fontWeight: 600,
|
||||
color: contentTheme.brandRed,
|
||||
color: contentTheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -16,6 +16,7 @@ import 'package:marco/helpers/utils/date_time_utils.dart';
|
||||
import 'package:marco/model/directory/add_contact_bottom_sheet.dart';
|
||||
import 'package:marco/helpers/widgets/my_refresh_indicator.dart';
|
||||
import 'package:marco/helpers/widgets/my_confirmation_dialog.dart';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
|
||||
// HELPER: Delta to HTML conversion
|
||||
String _convertDeltaToHtml(dynamic delta) {
|
||||
@ -68,7 +69,7 @@ class ContactDetailScreen extends StatefulWidget {
|
||||
State<ContactDetailScreen> createState() => _ContactDetailScreenState();
|
||||
}
|
||||
|
||||
class _ContactDetailScreenState extends State<ContactDetailScreen> {
|
||||
class _ContactDetailScreenState extends State<ContactDetailScreen> with UIMixin{
|
||||
late final DirectoryController directoryController;
|
||||
late final ProjectController projectController;
|
||||
|
||||
@ -191,7 +192,7 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
|
||||
TabBar(
|
||||
labelColor: Colors.black,
|
||||
unselectedLabelColor: Colors.grey,
|
||||
indicatorColor: Colors.red,
|
||||
indicatorColor: contentTheme.primary,
|
||||
tabs: const [
|
||||
Tab(text: "Details"),
|
||||
Tab(text: "Notes"),
|
||||
@ -308,7 +309,7 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
|
||||
bottom: 20,
|
||||
right: 20,
|
||||
child: FloatingActionButton.extended(
|
||||
backgroundColor: Colors.red,
|
||||
backgroundColor: contentTheme.primary,
|
||||
onPressed: () async {
|
||||
final result = await Get.bottomSheet(
|
||||
AddContactBottomSheet(existingContact: contact),
|
||||
@ -383,7 +384,7 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
|
||||
bottom: 20,
|
||||
right: 20,
|
||||
child: FloatingActionButton.extended(
|
||||
backgroundColor: Colors.red,
|
||||
backgroundColor: contentTheme.primary,
|
||||
onPressed: () async {
|
||||
final result = await Get.bottomSheet(
|
||||
AddCommentBottomSheet(contactId: contactId),
|
||||
|
@ -17,13 +17,15 @@ import 'package:marco/view/directory/contact_detail_screen.dart';
|
||||
import 'package:marco/view/directory/manage_bucket_screen.dart';
|
||||
import 'package:marco/controller/permission_controller.dart';
|
||||
import 'package:marco/helpers/utils/permission_constants.dart';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
|
||||
|
||||
class DirectoryView extends StatefulWidget {
|
||||
@override
|
||||
State<DirectoryView> createState() => _DirectoryViewState();
|
||||
}
|
||||
|
||||
class _DirectoryViewState extends State<DirectoryView> {
|
||||
class _DirectoryViewState extends State<DirectoryView> with UIMixin {
|
||||
final DirectoryController controller = Get.find();
|
||||
final TextEditingController searchController = TextEditingController();
|
||||
final PermissionController permissionController =
|
||||
@ -126,7 +128,7 @@ class _DirectoryViewState extends State<DirectoryView> {
|
||||
child: ElevatedButton(
|
||||
onPressed: () => Navigator.pop(context, true),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.indigo,
|
||||
backgroundColor: contentTheme.primary,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@ -172,7 +174,7 @@ class _DirectoryViewState extends State<DirectoryView> {
|
||||
backgroundColor: Colors.grey[100],
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
heroTag: 'createContact',
|
||||
backgroundColor: Colors.red,
|
||||
backgroundColor: contentTheme.primary,
|
||||
onPressed: _handleCreateContact,
|
||||
icon: const Icon(Icons.person_add_alt_1, color: Colors.white),
|
||||
label: const Text("Add Contact", style: TextStyle(color: Colors.white)),
|
||||
@ -246,7 +248,7 @@ class _DirectoryViewState extends State<DirectoryView> {
|
||||
icon: Icon(Icons.tune,
|
||||
size: 20,
|
||||
color: isFilterActive
|
||||
? Colors.indigo
|
||||
? contentTheme.primary
|
||||
: Colors.black87),
|
||||
onPressed: () {
|
||||
showModalBottomSheet(
|
||||
@ -323,13 +325,13 @@ class _DirectoryViewState extends State<DirectoryView> {
|
||||
PopupMenuItem<int>(
|
||||
value: 2,
|
||||
child: Row(
|
||||
children: const [
|
||||
children: [
|
||||
Icon(Icons.add_box_outlined,
|
||||
size: 20, color: Colors.black87),
|
||||
SizedBox(width: 10),
|
||||
Expanded(child: Text("Create Bucket")),
|
||||
Icon(Icons.chevron_right,
|
||||
size: 20, color: Colors.red),
|
||||
size: 20, color: contentTheme.primary),
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
@ -356,13 +358,13 @@ class _DirectoryViewState extends State<DirectoryView> {
|
||||
PopupMenuItem<int>(
|
||||
value: 1,
|
||||
child: Row(
|
||||
children: const [
|
||||
children: [
|
||||
Icon(Icons.label_outline,
|
||||
size: 20, color: Colors.black87),
|
||||
SizedBox(width: 10),
|
||||
Expanded(child: Text("Manage Buckets")),
|
||||
Icon(Icons.chevron_right,
|
||||
size: 20, color: Colors.red),
|
||||
size: 20, color: contentTheme.primary),
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
@ -401,7 +403,7 @@ class _DirectoryViewState extends State<DirectoryView> {
|
||||
const Expanded(child: Text('Show Deleted Contacts')),
|
||||
Switch.adaptive(
|
||||
value: !controller.isActive.value,
|
||||
activeColor: Colors.indigo,
|
||||
activeColor: contentTheme.primary ,
|
||||
onChanged: (val) {
|
||||
controller.isActive.value = !val;
|
||||
controller.fetchContacts(active: !val);
|
||||
@ -424,7 +426,7 @@ class _DirectoryViewState extends State<DirectoryView> {
|
||||
child: Obx(() {
|
||||
return MyRefreshIndicator(
|
||||
onRefresh: _refreshDirectory,
|
||||
backgroundColor: Colors.indigo,
|
||||
backgroundColor: contentTheme.primary,
|
||||
color: Colors.white,
|
||||
child: controller.isLoading.value
|
||||
? ListView.separated(
|
||||
|
@ -12,6 +12,8 @@ import 'package:marco/helpers/widgets/avatar.dart';
|
||||
import 'package:marco/helpers/utils/date_time_utils.dart';
|
||||
import 'package:marco/helpers/widgets/Directory/comment_editor_card.dart';
|
||||
import 'package:marco/helpers/widgets/my_confirmation_dialog.dart';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
|
||||
|
||||
class NotesView extends StatelessWidget {
|
||||
final NotesController controller = Get.find();
|
||||
|
@ -13,6 +13,7 @@ import 'package:marco/helpers/widgets/my_snackbar.dart';
|
||||
import 'package:marco/model/document/document_edit_bottom_sheet.dart';
|
||||
import 'package:marco/controller/permission_controller.dart';
|
||||
import 'package:marco/helpers/utils/permission_constants.dart';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
|
||||
class DocumentDetailsPage extends StatefulWidget {
|
||||
final String documentId;
|
||||
@ -23,7 +24,7 @@ class DocumentDetailsPage extends StatefulWidget {
|
||||
State<DocumentDetailsPage> createState() => _DocumentDetailsPageState();
|
||||
}
|
||||
|
||||
class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
|
||||
class _DocumentDetailsPageState extends State<DocumentDetailsPage> with UIMixin {
|
||||
final DocumentDetailsController controller =
|
||||
Get.find<DocumentDetailsController>();
|
||||
|
||||
@ -155,7 +156,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
|
||||
if (permissionController
|
||||
.hasPermission(Permissions.modifyDocument))
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit, color: Colors.red),
|
||||
icon: Icon(Icons.edit, color: contentTheme.primary),
|
||||
onPressed: () async {
|
||||
// existing bottom sheet flow
|
||||
await controller
|
||||
|
@ -19,6 +19,7 @@ import 'package:marco/helpers/widgets/my_snackbar.dart';
|
||||
import 'package:marco/controller/permission_controller.dart';
|
||||
import 'package:marco/controller/document/document_details_controller.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
|
||||
class UserDocumentsPage extends StatefulWidget {
|
||||
final String? entityId;
|
||||
@ -34,7 +35,7 @@ class UserDocumentsPage extends StatefulWidget {
|
||||
State<UserDocumentsPage> createState() => _UserDocumentsPageState();
|
||||
}
|
||||
|
||||
class _UserDocumentsPageState extends State<UserDocumentsPage> {
|
||||
class _UserDocumentsPageState extends State<UserDocumentsPage> with UIMixin {
|
||||
final DocumentController docController = Get.put(DocumentController());
|
||||
final PermissionController permissionController =
|
||||
Get.find<PermissionController>();
|
||||
@ -304,6 +305,11 @@ class _UserDocumentsPageState extends State<UserDocumentsPage> {
|
||||
);
|
||||
},
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide:
|
||||
BorderSide(color: contentTheme.primary, width: 1.5),
|
||||
),
|
||||
hintText: 'Search documents...',
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
@ -415,7 +421,7 @@ class _UserDocumentsPageState extends State<UserDocumentsPage> {
|
||||
const Expanded(child: Text('Show Deleted Documents')),
|
||||
Switch.adaptive(
|
||||
value: docController.showInactive.value,
|
||||
activeColor: Colors.indigo,
|
||||
activeColor: contentTheme.primary,
|
||||
onChanged: (val) {
|
||||
docController.showInactive.value = val;
|
||||
docController.fetchDocuments(
|
||||
@ -640,7 +646,7 @@ class _UserDocumentsPageState extends State<UserDocumentsPage> {
|
||||
color: Colors.white,
|
||||
fontWeight: 600,
|
||||
),
|
||||
backgroundColor: Colors.red,
|
||||
backgroundColor: contentTheme.primary,
|
||||
)
|
||||
: null,
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
||||
|
@ -9,6 +9,8 @@ import 'package:marco/helpers/widgets/my_text.dart';
|
||||
import 'package:marco/helpers/utils/launcher_utils.dart';
|
||||
import 'package:marco/helpers/widgets/my_refresh_indicator.dart';
|
||||
import 'package:marco/model/employees/add_employee_bottom_sheet.dart';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
|
||||
|
||||
class EmployeeDetailPage extends StatefulWidget {
|
||||
final String employeeId;
|
||||
@ -24,7 +26,7 @@ class EmployeeDetailPage extends StatefulWidget {
|
||||
State<EmployeeDetailPage> createState() => _EmployeeDetailPageState();
|
||||
}
|
||||
|
||||
class _EmployeeDetailPageState extends State<EmployeeDetailPage> {
|
||||
class _EmployeeDetailPageState extends State<EmployeeDetailPage> with UIMixin {
|
||||
final EmployeesScreenController controller =
|
||||
Get.put(EmployeesScreenController());
|
||||
|
||||
@ -87,7 +89,7 @@ class _EmployeeDetailPageState extends State<EmployeeDetailPage> {
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
color: (isEmail || isPhone) ? Colors.indigo : Colors.black54,
|
||||
color: (isEmail || isPhone) ? contentTheme.primary : Colors.black54,
|
||||
fontSize: 14,
|
||||
decoration: (isEmail || isPhone)
|
||||
? TextDecoration.underline
|
||||
@ -248,7 +250,7 @@ class _EmployeeDetailPageState extends State<EmployeeDetailPage> {
|
||||
),
|
||||
IconButton(
|
||||
icon:
|
||||
const Icon(Icons.edit, size: 24, color: Colors.red),
|
||||
Icon(Icons.edit, size: 24, color: contentTheme.primary),
|
||||
onPressed: () async {
|
||||
final result =
|
||||
await showModalBottomSheet<Map<String, dynamic>>(
|
||||
|
@ -16,6 +16,7 @@ import 'package:marco/helpers/utils/permission_constants.dart';
|
||||
import 'package:marco/helpers/widgets/my_refresh_indicator.dart';
|
||||
import 'package:marco/view/employees/employee_profile_screen.dart';
|
||||
|
||||
|
||||
class EmployeesScreen extends StatefulWidget {
|
||||
const EmployeesScreen({super.key});
|
||||
|
||||
@ -209,14 +210,14 @@ class _EmployeesScreenState extends State<EmployeesScreen> with UIMixin {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
color: contentTheme.primary,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Colors.black26, blurRadius: 6, offset: Offset(0, 3))
|
||||
],
|
||||
),
|
||||
child: const Row(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.add, color: Colors.white),
|
||||
@ -262,6 +263,11 @@ class _EmployeesScreenState extends State<EmployeesScreen> with UIMixin {
|
||||
hintStyle: const TextStyle(fontSize: 13, color: Colors.grey),
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide:
|
||||
BorderSide(color: contentTheme.primary, width: 1.5),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: Colors.grey.shade300, width: 1),
|
||||
|
@ -12,7 +12,6 @@ import 'package:marco/helpers/widgets/expense/expense_main_components.dart';
|
||||
import 'package:marco/helpers/utils/permission_constants.dart';
|
||||
import 'package:marco/helpers/widgets/my_refresh_indicator.dart';
|
||||
|
||||
|
||||
class ExpenseMainScreen extends StatefulWidget {
|
||||
const ExpenseMainScreen({super.key});
|
||||
|
||||
@ -111,7 +110,8 @@ Widget build(BuildContext context) {
|
||||
children: [
|
||||
// ---------------- Search ----------------
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
|
||||
child: SearchAndFilter(
|
||||
controller: searchController,
|
||||
onChanged: (_) => setState(() {}),
|
||||
@ -136,19 +136,21 @@ Widget build(BuildContext context) {
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
floatingActionButton:
|
||||
permissionController.hasPermission(Permissions.expenseUpload)
|
||||
? FloatingActionButton(
|
||||
? FloatingActionButton.extended(
|
||||
backgroundColor: Colors.red,
|
||||
onPressed: showAddExpenseBottomSheet,
|
||||
child: const Icon(Icons.add, color: Colors.white),
|
||||
icon: const Icon(Icons.add, color: Colors.white),
|
||||
label: const Text(
|
||||
"Create New Expense",
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget _buildExpenseList({required bool isHistory}) {
|
||||
return Obx(() {
|
||||
if (expenseController.isLoading.value &&
|
||||
@ -197,4 +199,3 @@ Widget build(BuildContext context) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,8 +194,8 @@ class _UserProfileBarState extends State<UserProfileBar>
|
||||
_menuItemRow(
|
||||
icon: LucideIcons.lock,
|
||||
label: hasMpin ? 'Change MPIN' : 'Set MPIN',
|
||||
iconColor: Colors.redAccent,
|
||||
textColor: Colors.redAccent,
|
||||
iconColor: contentTheme.primary,
|
||||
textColor: contentTheme.primary,
|
||||
onTap: _onMpinTap,
|
||||
),
|
||||
],
|
||||
@ -281,8 +281,8 @@ class _UserProfileBarState extends State<UserProfileBar>
|
||||
foregroundColor: Colors.white,
|
||||
shadowColor: Colors.red.shade200,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: condensed ? 14 : 18,
|
||||
horizontal: condensed ? 14 : 22,
|
||||
vertical: condensed ? 9 : 12,
|
||||
horizontal: condensed ? 6 : 16,
|
||||
),
|
||||
shape:
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
|
||||
|
Loading…
x
Reference in New Issue
Block a user