Skip to content

Commit

Permalink
Added bug report screen + provider + model
Browse files Browse the repository at this point in the history
  • Loading branch information
CosmicRaptor committed Jun 29, 2024
1 parent d3e257e commit c88e1f8
Show file tree
Hide file tree
Showing 8 changed files with 317 additions and 14 deletions.
31 changes: 31 additions & 0 deletions lib/models/bugreport_model/bugreport_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class Bugreport {
final String title;
final String description;
final List<String?> attachments;
bool isResolved;
DateTime reportTime;
String userUid;
Bugreport({required this.title, required this.description, required this.attachments, required this.isResolved, required this.reportTime, required this.userUid});

Map<String, dynamic> toJson(){
return {
'title': title,
'description': description,
'attachments': attachments,
'isResolved': isResolved,
'reportTime': reportTime.toIso8601String(),
'userUid': userUid,
};
}

factory Bugreport.fromjson(Map<String, dynamic> json){
return Bugreport(
title: json['title'],
description: json['description'],
attachments: List<String?>.from(json['attachments']),
isResolved: json['isResolved'],
reportTime: DateTime.parse(json['reportTime']),
userUid: json['userUid'],
);
}
}
112 changes: 112 additions & 0 deletions lib/new_ui/screens/bug_report_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tsec_app/new_ui/screens/main_screen/widgets/common_basic_appbar.dart';
import 'package:tsec_app/provider/auth_provider.dart';
import 'package:tsec_app/provider/bug_report_provider.dart';
import 'package:tsec_app/provider/firebase_provider.dart';
import 'package:tsec_app/utils/custom_snackbar.dart';
import 'package:tsec_app/utils/image_pick.dart';

class BugReportScreen extends ConsumerWidget {
BugReportScreen({Key? key}) : super(key: key);

final titleController = TextEditingController();
final descriptionController = TextEditingController();
List<File> images = [];

@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(shadowColor: Colors.transparent,
backgroundColor: Colors.transparent,
toolbarHeight: 80,
title: Text('Bug Report',
style: Theme.of(context)
.textTheme
.headlineLarge!
.copyWith(fontSize: 15, color: Colors.white),
maxLines: 1,
overflow: TextOverflow.fade,),
centerTitle: true,
iconTheme: IconThemeData(color: Colors.white),),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
const Text(
"Please provide a title for the bug report. This will help us identify the issue faster.",
style: TextStyle(
fontSize: 16,
color: Colors.white
),
),
const SizedBox(height: 20),
// Add the form here
TextFormField(
//maxLines: 3,
minLines: 1,
decoration: const InputDecoration(
hintText: 'Bug title',
hintStyle: TextStyle(color: Colors.grey, fontSize: 16),
border: OutlineInputBorder(borderSide: BorderSide(color: Colors.blue), borderRadius: BorderRadius.all(Radius.circular(10))),
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
isDense: true),
controller: titleController,
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 20),
const Text(
"Please provide a detailed description of the bug. This will help us understand the issue better. Provide steps to reproduce the bug if possible.",
style: TextStyle(
fontSize: 16,
color: Colors.grey
),
),
const SizedBox(height: 20),
TextFormField(
maxLines: null,
minLines: 1,
decoration: const InputDecoration(
hintText: 'Bug description',
hintStyle: TextStyle(color: Colors.grey, fontSize: 16),
border: OutlineInputBorder(borderSide: BorderSide(color: Colors.blue), borderRadius: BorderRadius.all(Radius.circular(10))),
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
isDense: true),
controller: descriptionController,
style: Theme.of(context).textTheme.bodySmall,
),
const SizedBox(height: 20),
// Add the image picker here
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(onPressed: () async{
images = await pickMultipleImages();
print(images);
}, child: Text('Pick images')),
],
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MaterialButton(onPressed: ()async{
await ref.read(bugreportNotifierProvider.notifier).addBugreport(titleController.text, descriptionController.text, images, ref.read(firebaseAuthProvider).currentUser!.uid);
titleController.clear();
descriptionController.clear();
showSnackBar(context, 'Submitted successfully');
}, color: Colors.green, child: Text('Submit'),),
],
),
],
),
),
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class _OldCommittessScreenState extends State<OldCommittessScreen> {
children: [
Text(
data[_currentPage].name,
style: Theme.of(context).textTheme.headline4,
style: Theme.of(context).textTheme.headlineSmall!.copyWith(fontSize: 4),
textAlign: TextAlign.center,
),
const SizedBox(height: 15),
Expand Down
30 changes: 29 additions & 1 deletion lib/new_ui/screens/main_screen/main_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:tsec_app/models/user_model/user_model.dart';
import 'package:tsec_app/new_ui/colors.dart';
import 'package:tsec_app/new_ui/screens/bug_report_screen.dart';
import 'package:tsec_app/new_ui/screens/coming_soon_screen/coming_soon.dart';
import 'package:tsec_app/new_ui/screens/about_us_screen/about_us.dart';
import 'package:tsec_app/new_ui/screens/erp_screen/erp_screen.dart';
import 'package:tsec_app/new_ui/screens/games/dino_screen/dino_screen.dart';
import 'package:tsec_app/new_ui/screens/home_screen/widgets/home_widget.dart';
import 'package:tsec_app/new_ui/screens/main_screen/widgets/main_bottom_nav_bar.dart';
import 'package:tsec_app/new_ui/screens/notes_screen/notes_screen.dart';
Expand Down Expand Up @@ -684,6 +684,34 @@ class _MainScreenState extends ConsumerState<MainScreen> {
);
},
),
ListTile(
contentPadding: EdgeInsets.zero,
title: Text(
'Report a bug',
style: Theme
.of(context)
.textTheme
.headlineSmall!
.copyWith(
fontSize: 13,
color: currentPage == 5
? Theme
.of(context)
.colorScheme
.onBackground
: Colors.white,
),
),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BugReportScreen(),
),
);
},
),
SizedBox(height: 10,),
Container(
alignment: Alignment.center,
Expand Down
43 changes: 43 additions & 0 deletions lib/provider/bug_report_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'dart:io';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tsec_app/models/bugreport_model/bugreport_model.dart';
import 'package:tsec_app/services/bug_report_service.dart';

final reportServicesProvider = Provider<ReportServices>((ref) {
return ReportServices();
});

class BugreportNotifier extends StateNotifier<List<Bugreport>> {
final ReportServices _reportServices;

BugreportNotifier(this._reportServices) : super([]);

// Add a new report
Future<void> addBugreport(String title, String description, List<File> imagePaths, String uid) async {
try {
List<File> files = imagePaths;
List<String> attachments = await _reportServices.getBugImages(files);

Bugreport newReport = Bugreport(
title: title,
description: description,
attachments: attachments,
isResolved: false,
reportTime: DateTime.now(),
userUid: uid,
);

await _reportServices.addReport(newReport);
state = [...state, newReport];
} catch (e) {
print('Error adding bug report: $e');
}
}

}

final bugreportNotifierProvider = StateNotifierProvider<BugreportNotifier, List<Bugreport>>((ref) {
final reportServices = ref.watch(reportServicesProvider);
return BugreportNotifier(reportServices);
});
37 changes: 37 additions & 0 deletions lib/services/bug_report_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:tsec_app/models/bugreport_model/bugreport_model.dart';

class ReportServices {
static final reportsCollection = FirebaseFirestore.instance.collection("Reports");
static final reportStorage = FirebaseStorage.instance.ref("Reports");
final FirebaseAuth _auth = FirebaseAuth.instance;

// Function to update Firestore by adding the new report
Future<void> addReport(Bugreport report) async {
final doc = reportsCollection.doc("Reports");
final get = await doc.get();
List allReports = get.data()?['allReports'] ?? [];

final newReport = report.toJson();

allReports.add(newReport);
await doc.set({"allReports": allReports});
}

// Function to upload image files to storage and return download URLs
Future<List<String>> getBugImages(List<File> fileImages) async {
List<String> bugImages = [];
for (File image in fileImages) {
final uploadTask = await reportStorage
.child(_auth.currentUser!.uid)
.child(DateTime.now().millisecondsSinceEpoch.toString())
.putFile(image);
final String downloadUrl = await uploadTask.ref.getDownloadURL();
bugImages.add(downloadUrl);
}
return bugImages;
}
}
20 changes: 20 additions & 0 deletions lib/utils/image_pick.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

Expand All @@ -12,3 +14,21 @@ pickImage(ImageSource source) async {
}
print('No image is selected');
}

Future<List<File>> pickMultipleImages() async {
final ImagePicker _picker = ImagePicker();
List<File> imageFiles = [];


final List<XFile?>? selectedFiles = await _picker.pickMultiImage();

if (selectedFiles != null) {
for (XFile? file in selectedFiles) {
if (file != null) {
imageFiles.add(File(file.path));
}
}
}

return imageFiles;
}
Loading

0 comments on commit c88e1f8

Please sign in to comment.