First Commit
This commit is contained in:
42
lib/widgets/app_toast.dart
Normal file
42
lib/widgets/app_toast.dart
Normal file
@ -0,0 +1,42 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AppToast extends StatelessWidget {
|
||||
const AppToast({
|
||||
super.key,
|
||||
required this.text,
|
||||
this.bottomPadding,
|
||||
this.color,
|
||||
this.textStyle,
|
||||
});
|
||||
|
||||
final String text;
|
||||
final double? bottomPadding;
|
||||
final Color? color;
|
||||
final TextStyle? textStyle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: bottomPadding ?? 100),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: color ?? Theme.of(context).scaffoldBackgroundColor,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.4),
|
||||
offset: const Offset(2, 2),
|
||||
blurRadius: 5,
|
||||
spreadRadius: 1
|
||||
)
|
||||
]
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
style: textStyle ?? Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
73
lib/widgets/baligh_card.dart
Normal file
73
lib/widgets/baligh_card.dart
Normal file
@ -0,0 +1,73 @@
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:baligh/screens/report_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BlighCard extends StatelessWidget {
|
||||
const BlighCard({
|
||||
super.key,
|
||||
required this.icon,
|
||||
required this.label,
|
||||
required this.iconColor,
|
||||
});
|
||||
|
||||
final IconData icon;
|
||||
final String label;
|
||||
final Color iconColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ReportScreen(
|
||||
headerText: label,
|
||||
)));
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).cardColor,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Center(
|
||||
child: SizedBox(
|
||||
height: MediaQuery.sizeOf(context).width * 0.2,
|
||||
child: Icon(
|
||||
icon,
|
||||
size: 45,
|
||||
color: iconColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
AutoSizeText(
|
||||
label,
|
||||
maxLines: 2,
|
||||
minFontSize: 10,
|
||||
maxFontSize: 18,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
86
lib/widgets/custom_button.dart
Normal file
86
lib/widgets/custom_button.dart
Normal file
@ -0,0 +1,86 @@
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:baligh/constants/theme.dart';
|
||||
import 'package:baligh/widgets/small_spinner.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomButton extends StatelessWidget {
|
||||
const CustomButton({
|
||||
super.key,
|
||||
required this.onPressed,
|
||||
required this.label,
|
||||
required this.isElevated,
|
||||
this.isLoading = false,
|
||||
this.textStyle,
|
||||
this.color,
|
||||
});
|
||||
|
||||
final void Function() onPressed;
|
||||
final String label;
|
||||
final bool isLoading;
|
||||
final bool isElevated;
|
||||
final TextStyle? textStyle;
|
||||
final Color? color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return isElevated
|
||||
? ElevatedButton(
|
||||
onPressed: isLoading ? null : onPressed,
|
||||
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
|
||||
backgroundColor: WidgetStatePropertyAll(color ?? MyCustomTheme.primaryColor)
|
||||
),
|
||||
child: isLoading
|
||||
? const SmallSpinner()
|
||||
: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 3),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: AutoSizeText(
|
||||
label,
|
||||
minFontSize: 8,
|
||||
maxFontSize: 14,
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center,
|
||||
style: textStyle ?? Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
color: MyCustomTheme.bgColor,
|
||||
)
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: OutlinedButton(
|
||||
onPressed: isLoading ? null : onPressed,
|
||||
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
|
||||
backgroundColor: WidgetStatePropertyAll(Theme.of(context).scaffoldBackgroundColor),
|
||||
side: WidgetStatePropertyAll(BorderSide(
|
||||
width: 1.5,
|
||||
color: color ?? MyCustomTheme.primaryColor,
|
||||
))
|
||||
),
|
||||
child: isLoading
|
||||
? SmallSpinner(color: MyCustomTheme.primaryColor,)
|
||||
: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 3),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: AutoSizeText(
|
||||
label,
|
||||
minFontSize: 8,
|
||||
maxFontSize: 14,
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center,
|
||||
style: textStyle ?? Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
color: color ?? MyCustomTheme.primaryColor,
|
||||
)
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
77
lib/widgets/custom_text_field.dart
Normal file
77
lib/widgets/custom_text_field.dart
Normal file
@ -0,0 +1,77 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomTextField extends StatefulWidget {
|
||||
const CustomTextField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.labelText,
|
||||
required this.inputType,
|
||||
this.errorText,
|
||||
this.isPassword = false,
|
||||
this.maxLines = 1,
|
||||
this.focusNode,
|
||||
});
|
||||
|
||||
final TextEditingController controller;
|
||||
final String labelText;
|
||||
final TextInputType inputType;
|
||||
final String? errorText;
|
||||
final bool isPassword;
|
||||
final int maxLines;
|
||||
final FocusNode? focusNode;
|
||||
|
||||
@override
|
||||
State<CustomTextField> createState() => _CustomTextFieldState();
|
||||
}
|
||||
|
||||
class _CustomTextFieldState extends State<CustomTextField> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
controller: widget.controller,
|
||||
focusNode: widget.focusNode,
|
||||
keyboardType: widget.inputType,
|
||||
obscureText: widget.isPassword,
|
||||
enableSuggestions: !widget.isPassword,
|
||||
autocorrect: false,
|
||||
maxLines: widget.maxLines,
|
||||
textDirection: TextDirection.rtl,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 5, horizontal: 20),
|
||||
labelText: widget.labelText,
|
||||
alignLabelWithHint: true,
|
||||
labelStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).dividerColor),
|
||||
floatingLabelStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).dividerColor),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Theme.of(context).cardColor, width: 1.5)
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Theme.of(context).dividerColor, width: 1)
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Theme.of(context).cardColor,
|
||||
errorText: widget.errorText,
|
||||
errorStyle: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Colors.red
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: const BorderSide(color: Colors.red, width: 1.5)
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: const BorderSide(color: Colors.red, width: 1.5)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
19
lib/widgets/small_spinner.dart
Normal file
19
lib/widgets/small_spinner.dart
Normal file
@ -0,0 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SmallSpinner extends StatelessWidget {
|
||||
final Color? color;
|
||||
|
||||
const SmallSpinner({super.key, this.color});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 3,
|
||||
color: color ?? Colors.white,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user