First Commit

This commit is contained in:
Abdullah Salah
2024-12-26 09:10:35 +03:00
commit cf9784f468
34 changed files with 2278 additions and 0 deletions

View 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,
),
),
);
}
}

View File

@@ -0,0 +1,86 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:baligh_dashboard/constants/theme.dart';
import 'package:baligh_dashboard/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,
)
),
),
],
),
),
);
}
}

View 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)
),
),
);
}
}

View File

@@ -0,0 +1,127 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:baligh_dashboard/screens/report_details_screen.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class DashboardTile extends StatelessWidget {
const DashboardTile({
super.key,
required this.id,
required this.name,
required this.address,
required this.school,
required this.type,
required this.status,
required this.age,
required this.attachments,
required this.createdAt,
required this.description,
required this.nationalIdNumber,
required this.phone,
});
final String id;
final String name;
final String address;
final String school;
final String type;
final String status;
final Timestamp createdAt;
final int age;
final String phone;
final int nationalIdNumber;
final String description;
final List attachments;
@override
Widget build(BuildContext context) {
return InkWell(
borderRadius: const BorderRadius.all(Radius.circular(12)),
hoverColor: Colors.transparent,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ReportDetailsScreen(
id: id,
name: name,
age: age,
phone: phone,
address: address,
school: school,
nationalIdNumber: nationalIdNumber,
description: description,
attachments: attachments,
type: type,
createdAt: createdAt,
status: status,
)));
},
child: Container(
width: double.infinity,
clipBehavior: Clip.hardEdge,
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: Row(
children: [
Expanded(
child: AutoSizeText(
name,
style: Theme.of(context).textTheme.bodyMedium,
maxLines: 3,
minFontSize: 8,
),
),
const SizedBox(
width: 5,
),
Expanded(
child: AutoSizeText(
address,
style: Theme.of(context).textTheme.bodyMedium,
maxLines: 3,
minFontSize: 8,
),
),
const SizedBox(
width: 5,
),
Expanded(
child: AutoSizeText(
school,
style: Theme.of(context).textTheme.bodyMedium,
maxLines: 3,
minFontSize: 8,
),
),
const SizedBox(
width: 5,
),
Expanded(
child: AutoSizeText(
type,
style: Theme.of(context).textTheme.bodyMedium,
maxLines: 3,
minFontSize: 8,
),
),
const SizedBox(
width: 5,
),
Expanded(
child: AutoSizeText(
status,
style: Theme.of(context).textTheme.bodyMedium,
maxLines: 3,
minFontSize: 8,
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,94 @@
import 'dart:html' as html;
import 'package:auto_size_text/auto_size_text.dart';
import 'package:baligh_dashboard/widgets/app_toast.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class FileCard extends StatelessWidget {
const FileCard(
{super.key,
required this.type,
required this.filename,
required this.fileUrl});
final String type;
final String filename;
final String fileUrl;
@override
Widget build(BuildContext context) {
return InkWell(
borderRadius: const BorderRadius.all(Radius.circular(12)),
hoverColor: Colors.transparent,
onTap: () async {
try {
html.AnchorElement(href: fileUrl)
..setAttribute('target', '_blank')
..setAttribute('download', '$filename.pdf') // Specify the filename
..click();
BotToast.showCustomText(toastBuilder: (_) {
return const AppToast(text: "تم التحميل");
});
} catch (e) {
print(e);
BotToast.showCustomText(toastBuilder: (_) {
return const AppToast(text: "حدث خطأ ما في التحميل");
});
}
},
child: Container(
width: 180,
clipBehavior: Clip.hardEdge,
padding: const EdgeInsets.all(8),
margin: const EdgeInsets.symmetric(horizontal: 3),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: type == "image"
? Colors.red.withOpacity(0.2)
: type == "video"
? Colors.blue.withOpacity(0.2)
: Colors.grey.withOpacity(0.2),
borderRadius: const BorderRadius.all(Radius.circular(8)),
),
child: Center(
child: Icon(
type == "image"
? FontAwesomeIcons.image
: type == "video"
? FontAwesomeIcons.video
: FontAwesomeIcons.microphone,
color: type == "image"
? Colors.red
: type == "video"
? Colors.blue
: Colors.grey,
size: 18,
),
),
),
const SizedBox(
width: 5,
),
Expanded(
child: AutoSizeText(
filename,
style: Theme.of(context).textTheme.bodySmall,
minFontSize: 6,
),
)
],
),
),
);
}
}

View 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,
),
);
}
}