diff --git a/.vscode/settings.json b/.vscode/settings.json index 385f27a..7b091dc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "java.configuration.updateBuildConfiguration": "interactive" + "java.configuration.updateBuildConfiguration": "interactive", + "cmake.sourceDirectory": "E:/work/flutter_tutorial/IEDC-Summit23-Admin/build/windows/extracted/firebase_cpp_sdk_windows" } diff --git a/android/app/google-services.json b/android/app/google-services.json index b23b9e0..d1adc38 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,9 +1,8 @@ { "project_info": { - "project_number": "68980353446", - "firebase_url": "https://iedc-app-6754b-default-rtdb.firebaseio.com", - "project_id": "iedc-app-6754b", - "storage_bucket": "iedc-app-6754b.appspot.com" + "project_number": "671098905742", + "project_id": "iedc-pro-app", + "storage_bucket": "iedc-pro-app.appspot.com" }, "client": [ { @@ -27,7 +26,7 @@ }, { "client_info": { - "mobilesdk_app_id": "1:68980353446:android:cd174cc3696d32384c8767", + "mobilesdk_app_id": "1:671098905742:android:efdb479631cd81c60955df", "android_client_info": { "package_name": "com.example.user_iedc" } @@ -35,7 +34,7 @@ "oauth_client": [], "api_key": [ { - "current_key": "AIzaSyB4ghGQuySgMEoihaHRjNg0PkFFkL8tRf4" + "current_key": "AIzaSyA4bJ8fNsjtOPbv9zyIV1FvwddKFdCzHdw" } ], "services": { diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 9af0188..677e906 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,8 @@ + + posterUrl; final String speaker; final String startTime; final String endTime; final String venue; + final String max; final List attendees; final List preregistered; Workshop({ @@ -18,6 +20,7 @@ class Workshop { required this.startTime, required this.endTime, required this.venue, + required this.max, required this.attendees, required this.preregistered, }); @@ -25,13 +28,14 @@ class Workshop { Workshop copyWith({ String? title, String? description, - String? posterUrl, + Map? posterUrl, String? speaker, String? startTime, String? endTime, String? venue, List? attendees, List? preregistered, + String? max, }) { return Workshop( title: title ?? this.title, @@ -43,6 +47,7 @@ class Workshop { venue: venue ?? this.venue, attendees: attendees ?? this.attendees, preregistered: preregistered ?? this.preregistered, + max: max ?? this.max, ); } @@ -57,6 +62,7 @@ class Workshop { 'venue': venue, 'attendees': attendees, 'preregistered': preregistered, + "max": max, }; } @@ -64,13 +70,14 @@ class Workshop { return Workshop( title: map['title'] ?? '', description: map['description'] ?? '', - posterUrl: map['posterUrl'] ?? '', + posterUrl: map["posterUrl"] as Map, speaker: map['speaker'] ?? '', startTime: map['startTime'] ?? '', endTime: map['endTime'] ?? '', venue: map['venue'] ?? '', attendees: List.from(map['attendees']), preregistered: List.from(map['preregistered']), + max: map["max"] ?? "", ); } @@ -81,33 +88,33 @@ class Workshop { @override String toString() { - return 'Workshop(title: $title, description: $description, posterUrl: $posterUrl, speaker: $speaker, startTime: $startTime, endTime: $endTime, venue: $venue, attendees: $attendees, preregistered: $preregistered)'; + return 'Workshop(title: $title, description: $description, posterUrl: $posterUrl, speaker: $speaker, startTime: $startTime, endTime: $endTime, venue: $venue, attendees: $attendees, preregistered: $preregistered. max: $max)'; } } -List dummyWorkshops = List.generate( - 10, - (index) => Workshop( - title: 'Workshop ${index + 1}', - description: 'This is the description for Workshop ${index + 1}', - posterUrl: 'https://example.com/poster${index + 1}.jpg', - speaker: 'Speaker ${index + 1}', - startTime: '2022-01-01 10:00:00', - endTime: '2022-01-01 12:00:00', - venue: 'Venue ${index + 1}', - attendees: [ - 'Attendee 1', - 'Attendee 2', - 'Attendee 3', - 'Attendee 4', - 'Attendee 5', - ], - preregistered: [ - 'Preregistered 1', - 'Preregistered 2', - 'Preregistered 3', - 'Preregistered 4', - 'Preregistered 5', - ], - ), -); +// List dummyWorkshops = List.generate( +// 10, +// (index) => Workshop( +// title: 'Workshop ${index + 1}', +// description: 'This is the description for Workshop ${index + 1}', +// posterUrl: 'https://example.com/poster${index + 1}.jpg', +// speaker: 'Speaker ${index + 1}', +// startTime: '2022-01-01 10:00:00', +// endTime: '2022-01-01 12:00:00', +// venue: 'Venue ${index + 1}', +// attendees: [ +// 'Attendee 1', +// 'Attendee 2', +// 'Attendee 3', +// 'Attendee 4', +// 'Attendee 5', +// ], +// preregistered: [ +// 'Preregistered 1', +// 'Preregistered 2', +// 'Preregistered 3', +// 'Preregistered 4', +// 'Preregistered 5', +// ], +// ), +// ); diff --git a/lib/respository/sanity_repo.dart b/lib/respository/sanity_repo.dart index 3b10156..8e1c7b9 100644 --- a/lib/respository/sanity_repo.dart +++ b/lib/respository/sanity_repo.dart @@ -1,9 +1,5 @@ -import 'dart:convert'; - import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:summit_admin_app/constants/secret.dart'; import 'package:summit_admin_app/models/workshop_model.dart'; -import 'package:http/http.dart' as http; class SanityRepo { final FirebaseFirestore _firestore; @@ -24,28 +20,29 @@ class SanityRepo { } } - Future gettingData() async { - // get data from sanity - final response = await http.get( - Uri.parse( - 'https://i0p2y232.api.sanity.io/v2021-06-07/data/query/production?query=*[_type == "event"]{_id,event_name,start_time,end_time,speaker,status,category,venue}'), - headers: sanityHeader, - ); - var sanityData = jsonDecode(response.body)['result']; - Workshop workshop; - for (var data in sanityData) { - workshop = Workshop( - title: data['event_name'], - startTime: data['start_time'], - endTime: data['end_time'], - speaker: data['speaker'], - description: data['status'], - posterUrl: '', - venue: '', - attendees: [], - preregistered: [], - ); - uploadtoFirebase(workshop); - } - } + // Future gettingData() async { + // // get data from sanity + // final response = await http.get( + // Uri.parse( + // 'https://i0p2y232.api.sanity.io/v2021-06-07/data/query/production?query=*[_type == "event"]{_id,event_name,start_time,end_time,speaker,status,category,venue,posterurl,maxcount}'), + // headers: sanityHeader, + // ); + // var sanityData = jsonDecode(response.body)['result']; + // Workshop workshop; + // for (var data in sanityData) { + // workshop = Workshop( + // title: data['event_name'], + // startTime: data['start_time'], + // endTime: data['end_time'], + // speaker: data['speaker'], + // description: data['status'], + // posterUrl: data["posterurl"], + // venue: data["venue"], + // attendees: [], + // preregistered: [], + // max: data["maxcount"], + // ); + // // uploadtoFirebase(workshop); + // } + // } } diff --git a/lib/respository/workshop_repository.dart b/lib/respository/workshop_repository.dart index 1ccb2e1..737507f 100644 --- a/lib/respository/workshop_repository.dart +++ b/lib/respository/workshop_repository.dart @@ -1,6 +1,13 @@ import 'dart:async'; +import 'dart:io'; import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:csv/csv.dart'; +import 'package:external_path/external_path.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:summit_admin_app/components/utils.dart'; +import 'package:summit_admin_app/models/attendee_model.dart'; import 'package:summit_admin_app/models/workshop_model.dart'; import 'package:summit_admin_app/providers/firebase_providers.dart'; @@ -37,13 +44,14 @@ class WorkshopRepository { Stream> getWorkshops() { return _workshops.snapshots().map( - (event) => event.docs - .map( - (e) => Workshop.fromMap( - e.data() as Map, - ), - ) - .toList(), + (event) => event.docs.map( + (e) { + Workshop workshop = Workshop.fromMap( + e.data() as Map, + ); + return workshop; + }, + ).toList(), ); } @@ -102,4 +110,154 @@ class WorkshopRepository { return _workshops.doc(workshopName).snapshots().map((event) => Workshop.fromMap(event.data() as Map).attendees); } + + Future createCSV() async { + List attendees = []; + await _workshops.doc().snapshots().map( + (event) { + attendees = + (Workshop.fromMap(event.data() as Map).attendees); + print(attendees); + }, + ); + } + + Future printAttendeesForWorkshops(BuildContext context) async { + Map statuses = await [ + Permission.storage, + ].request(); + // Replace "workshopCollectionRef" with your Firestore collection reference to workshops. + final workshopCollectionRef = + FirebaseFirestore.instance.collection('workshops'); + + final workshops = await workshopCollectionRef.get(); + + for (final workshop in workshops.docs) { + print('Workshop: ${workshop.id}'); + List attendees = []; + attendees = (Workshop.fromMap(workshop.data()).attendees); + List> rows = []; + List row = []; + row.add("Name"); + row.add("Attendee_category"); + row.add("CollegeHasIEDC"); + row.add("Email"); + row.add("Mobile"); + row.add("Gender"); + row.add("Address"); + row.add("EmergencyContact"); + row.add("District of Residence"); + rows.add(row); + + for (final attendee in attendees) { + final ticketID = attendee.split("*")[0]; + var atted = + await _firestore.collection('attendees').doc(ticketID).get(); + + Attendee att = Attendee.fromMap( + atted.data() as Map, + ); + List row = []; + row.add(att.name); + row.add(att.attendeeCategory); + row.add(att.collegeHasIEDC); + row.add(att.email); + row.add(att.mobile); + row.add(att.gender); + row.add(att.address); + row.add(att.emergencyContact); + row.add(att.districtOfResidence); + rows.add(row); + } + String csv = const ListToCsvConverter().convert(rows); + var dir = await ExternalPath.getExternalStoragePublicDirectory( + ExternalPath.DIRECTORY_DOWNLOADS); + + print("dir $dir"); + String file = dir; + + File f = File("$dir/${workshop.id}.csv"); + f.writeAsString(csv); + showSnackBar(context, "${workshop.id} : Done"); + print("success"); + } + } + + Future printAttendeesForWorkshops1(BuildContext context) async { + final status = await Permission.storage.request(); + if (status.isDenied) { + // Handle permission denied + return; + } + + if (status.isGranted) { + final workshopCollectionRef = + FirebaseFirestore.instance.collection('workshops'); + final workshops = await workshopCollectionRef.get(); + + for (final workshop in workshops.docs) { + print('Workshop: ${workshop.id}'); + List attendees = []; + attendees = (Workshop.fromMap(workshop.data()).attendees); + List> row = []; + + // Add header row + row.add( + [ + "Name", + "Ticket ID", + "Attendee_category", + "CollegeHasIEDC", + "Email", + "Mobile", + "Gender", + "Address", + "EmergencyContact", + "District of Residence" + ], + ); + + for (final attendee in attendees) { + final ticketID = attendee.split("*")[0]; + var atted = + await _firestore.collection('attendees').doc(ticketID).get(); + + Attendee att = Attendee.fromMap(atted.data() as Map); + + // Add attendee data to the row + row.add( + [ + att.name, + att.iedcRegistrationNumber, + att.attendeeCategory, + att.collegeHasIEDC, + att.email, + att.mobile, + att.gender, + att.address, + att.emergencyContact, + att.districtOfResidence + ], + ); + } + + String csv = const ListToCsvConverter().convert(row); + var dir = await ExternalPath.getExternalStoragePublicDirectory( + ExternalPath.DIRECTORY_DOWNLOADS); + String workshopName = + workshop.id.replaceAll(RegExp(r"[^a-zA-Z0-9]+"), "_"); + String file = "$dir/${workshopName}_final.csv"; + + try { + File f = File(file); + await f.writeAsString(csv); + showSnackBar(context, "${workshop.id} : Done"); + print("Success: $file"); + } catch (e) { + showSnackBar(context, "Error creating CSV for ${workshop.id}: $e"); + print("Error: $e"); + } + } + } + } } diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 16cfd2d..70b2a38 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -4,9 +4,9 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:summit_admin_app/components/home_button.dart'; import 'package:summit_admin_app/components/home_screen_texts.dart'; import 'package:summit_admin_app/controller/attendee_controller.dart'; -// import 'package:summit_admin_app/respository/sanity_repo.dart'; +import 'package:summit_admin_app/respository/workshop_repository.dart'; // import 'package:summit_admin_app/providers/firebase_providers.dart'; -// import 'package:summit_admin_app/respository/townscript_repo.dart'; +// import 'package:summit_admin_app/respository/sanity_repo.dart'; class HomeScreen extends ConsumerStatefulWidget { const HomeScreen({super.key}); @@ -39,18 +39,7 @@ class _HomeScreenState extends ConsumerState { error: (e, s) => "?", ); return Scaffold( - appBar: AppBar( - title: Text( - "IEDC-Summit", - style: GoogleFonts.dmSans( - fontSize: 25, - fontWeight: FontWeight.w500, - height: 0, - ), - ), - centerTitle: true, - elevation: 0, - ), + appBar: homeScreenAppBar(), body: Padding( padding: const EdgeInsets.symmetric(horizontal: 30.0), child: Center( @@ -73,37 +62,51 @@ class _HomeScreenState extends ConsumerState { ], ), ), - HomeButton( - title: "Event Registration", - func: () { - Navigator.pushNamed(context, '/eventScanner'); - }, - ), - const SizedBox( - height: 40, - ), - HomeButton( - title: "Workshops", - func: () { - Navigator.pushNamed(context, '/workshopsList'); - }, - ), - const SizedBox( - height: 40, - ), // HomeButton( - // title: "Upload firebase", + // title: "Event Registration", // func: () { - // TownscriptRepository(firestore: ref.watch(firestoreProvider)) - // .gettingData(); - // SanityRepo(firestore: ref.watch(firestoreProvider)) - // .gettingData(); + // Navigator.pushNamed(context, '/eventScanner'); // }, // ), + // const SizedBox( + // height: 40, + // ), + // HomeButton( + // title: "Workshops", + // func: () async { + // Navigator.pushNamed(context, '/workshopsList'); + // }, + // ), + // const SizedBox( + // height: 40, + // ), + HomeButton( + title: "create csv", + func: () { + ref + .watch(workshopRepositoryProvider) + .printAttendeesForWorkshops1(context); + }, + ), ], ), ), ), ); } + + AppBar homeScreenAppBar() { + return AppBar( + title: Text( + "IEDC-Summit", + style: GoogleFonts.dmSans( + fontSize: 25, + fontWeight: FontWeight.w500, + height: 0, + ), + ), + centerTitle: true, + elevation: 0, + ); + } } diff --git a/lib/screens/spot_admit_screen.dart b/lib/screens/spot_admit_screen.dart index c2fc232..d67fba2 100644 --- a/lib/screens/spot_admit_screen.dart +++ b/lib/screens/spot_admit_screen.dart @@ -134,7 +134,7 @@ class _SpotAdmitScreenState extends ConsumerState { .watch(workshopRepositoryProvider) .addWorkshopAttendence( widget.wsName, - "${attendee.iedcRegistrationNumber} ${attendee.name}", + "${attendee.iedcRegistrationNumber}*${attendee.name}", ); showSnackBar(context, "Spot attendee added"); diff --git a/lib/screens/user_id_screen.dart b/lib/screens/user_id_screen.dart index e69f3f6..fdd581a 100644 --- a/lib/screens/user_id_screen.dart +++ b/lib/screens/user_id_screen.dart @@ -1,8 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:summit_admin_app/components/home_button.dart'; +import 'package:summit_admin_app/components/home_screen_texts.dart'; import 'package:summit_admin_app/components/progress_indicator.dart'; import 'package:summit_admin_app/components/text_spanner.dart'; import 'package:summit_admin_app/components/the_tick.dart'; +import 'package:summit_admin_app/constants/null_attendee.dart'; import 'package:summit_admin_app/controller/attendee_controller.dart'; import 'package:summit_admin_app/models/attendee_model.dart'; @@ -40,151 +43,155 @@ class _UserIDScreenState extends ConsumerState { Widget build(BuildContext context) { return ref.watch(getAttendeeByIDProvider(widget.id)).when( data: (attendee) { - return Scaffold( - appBar: theAppBar(context), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - attendee.isPresent - ? "Attendance Marked" - : 'Scanning Successful!', - style: const TextStyle( - color: Colors.white, - fontSize: 26, - fontWeight: FontWeight.w700, - height: 0, - ), - ), - const SizedBox( - height: 70, - ), - Container( - width: 125, - height: 125, - clipBehavior: Clip.antiAlias, - decoration: ShapeDecoration( - color: const Color.fromARGB(255, 255, 255, 255), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(100), - ), - ), - child: Center( - child: attendee.isPresent - ? const TheTick() - : _isApproved - ? const TheTick() - : const Text("Not Approved"), - ), - ), - const SizedBox( - height: 50, - ), - TextSpanner( - title: "Name : ", - subtitile: attendee.name, - ), - TextSpanner( - title: "Ticket ID : ", - subtitile: attendee.iedcRegistrationNumber, - ), - const SizedBox( - height: 50, - ), - Container( - width: 287.10, - height: 60, - clipBehavior: Clip.antiAlias, - decoration: ShapeDecoration( - color: _isApproved ? Colors.white : Colors.black, - shape: RoundedRectangleBorder( - side: BorderSide( - width: 2.70, - color: attendee.isPresent - ? Colors.grey - : _isApproved - ? Colors.black - : Colors.white, - ), - borderRadius: BorderRadius.circular(18), - ), - ), - child: TextButton( - onPressed: () { - if (attendee.isPresent) { - widget.screenClosed(); - Navigator.of(context).pop(); - } - if (!_isApproved) { - _addAttendence(attendee); - } else { - widget.screenClosed(); - Navigator.of(context).pop(); - } - }, - child: Center( - child: Text( + return attendee == nullAttendee + ? ErrorScafold(widget: widget) + : Scaffold( + appBar: theAppBar(context), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( attendee.isPresent - ? "Go to Scanner" - : _marked - ? "Go to Scanner" - : !_isApproved - ? "Approve " - : 'Go to Scanner', - style: TextStyle( - color: _isApproved ? Colors.black : Colors.white, - fontSize: 20, - fontWeight: FontWeight.w500, + ? "Attendance Marked" + : 'Scanning Successful!', + style: const TextStyle( + color: Colors.white, + fontSize: 26, + fontWeight: FontWeight.w700, height: 0, ), ), - ), - ), - ), - const SizedBox( - height: 30, - ), - Container( - width: 287, - height: 60, - padding: const EdgeInsets.only( - top: 12, - left: 36, - right: 35, - bottom: 8, - ), - clipBehavior: Clip.antiAlias, - decoration: ShapeDecoration( - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20), - ), - ), - child: TextButton( - onPressed: () { - var nav = Navigator.of(context); - nav.pop(); - nav.pop(); - }, - child: const Center( - child: Text( - 'Go to Homepage', - style: TextStyle( - color: Colors.black, - fontSize: 20, - fontWeight: FontWeight.w500, - height: 0, + const SizedBox( + height: 70, + ), + Container( + width: 125, + height: 125, + clipBehavior: Clip.antiAlias, + decoration: ShapeDecoration( + color: const Color.fromARGB(255, 255, 255, 255), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100), + ), + ), + child: Center( + child: attendee.isPresent + ? const TheTick() + : _isApproved + ? const TheTick() + : const Text("Not Approved"), ), ), - ), + const SizedBox( + height: 50, + ), + TextSpanner( + title: "Name : ", + subtitile: attendee.name, + ), + TextSpanner( + title: "Ticket ID : ", + subtitile: attendee.iedcRegistrationNumber, + ), + const SizedBox( + height: 50, + ), + Container( + width: 287.10, + height: 60, + clipBehavior: Clip.antiAlias, + decoration: ShapeDecoration( + color: _isApproved ? Colors.white : Colors.black, + shape: RoundedRectangleBorder( + side: BorderSide( + width: 2.70, + color: attendee.isPresent + ? Colors.grey + : _isApproved + ? Colors.black + : Colors.white, + ), + borderRadius: BorderRadius.circular(18), + ), + ), + child: TextButton( + onPressed: () { + if (attendee.isPresent) { + widget.screenClosed(); + Navigator.of(context).pop(); + } + if (!_isApproved) { + _addAttendence(attendee); + } else { + widget.screenClosed(); + Navigator.of(context).pop(); + } + }, + child: Center( + child: Text( + attendee.isPresent + ? "Go to Scanner" + : _marked + ? "Go to Scanner" + : !_isApproved + ? "Approve " + : 'Go to Scanner', + style: TextStyle( + color: _isApproved + ? Colors.black + : Colors.white, + fontSize: 20, + fontWeight: FontWeight.w500, + height: 0, + ), + ), + ), + ), + ), + const SizedBox( + height: 30, + ), + Container( + width: 287, + height: 60, + padding: const EdgeInsets.only( + top: 12, + left: 36, + right: 35, + bottom: 8, + ), + clipBehavior: Clip.antiAlias, + decoration: ShapeDecoration( + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + ), + child: TextButton( + onPressed: () { + var nav = Navigator.of(context); + nav.pop(); + nav.pop(); + }, + child: const Center( + child: Text( + 'Go to Homepage', + style: TextStyle( + color: Colors.black, + fontSize: 20, + fontWeight: FontWeight.w500, + height: 0, + ), + ), + ), + ), + ), + ], ), ), - ], - ), - ), - ); + ); }, error: (error, stackTrace) => Scaffold( body: Center( @@ -247,3 +254,34 @@ class _UserIDScreenState extends ConsumerState { ); } } + +class ErrorScafold extends StatelessWidget { + const ErrorScafold({ + super.key, + required this.widget, + }); + + final UserIDScreen widget; + + @override + Widget build(BuildContext context) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const HomeScreenText(text: "Invalid ID"), + const SizedBox( + height: 50, + ), + HomeButton( + title: "Retry", + func: () { + widget.screenClosed(); + Navigator.of(context).pop(); + }, + ) + ], + ), + ); + } +} diff --git a/lib/screens/workshop.dart b/lib/screens/workshop.dart index cb339d3..136312f 100644 --- a/lib/screens/workshop.dart +++ b/lib/screens/workshop.dart @@ -38,19 +38,7 @@ class WorkshopScreen extends StatelessWidget { ), //Textstyle ), ), - Padding( - padding: const EdgeInsets.all(8.0), - child: ClipRRect( - borderRadius: BorderRadius.circular(20), - child: SizedBox( - height: MediaQuery.of(context).size.height * 0.25, - child: Image.network( - "https://cdn.sanity.io/images/85e4z8hj/production/44b38df421a37ea5396674058e7f1fb9c346e9d6-1600x1600.jpg", - fit: BoxFit.fill, - ), - ), - ), - ), //CircleAvatar + //CircleAvatar const SizedBox( height: 10, ), diff --git a/lib/screens/workshop_attendees_screen.dart b/lib/screens/workshop_attendees_screen.dart index 83afc0f..d5d4de7 100644 --- a/lib/screens/workshop_attendees_screen.dart +++ b/lib/screens/workshop_attendees_screen.dart @@ -19,19 +19,6 @@ class WorkshopAttendeeListScreen extends ConsumerWidget { height: 0, ), ), - actions: [ - // TODO: Implement export to CSV - optional - TextButton( - onPressed: () {}, - child: const Text( - 'Export to CSV', - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ) - ], elevation: 0, ), body: Column( @@ -45,7 +32,7 @@ class WorkshopAttendeeListScreen extends ConsumerWidget { itemBuilder: (context, index) => ListTile( contentPadding: const EdgeInsets.only(left: 40), title: Text( - attendees[index].split(' ')[1], + attendees[index].split('*')[1], style: const TextStyle( color: Colors.white, fontSize: 20, @@ -53,7 +40,7 @@ class WorkshopAttendeeListScreen extends ConsumerWidget { ), ), subtitle: Text( - "ID : ${attendees[index].split(' ')[0]}", + "ID : ${attendees[index].split('*')[0]}", style: const TextStyle( color: Colors.white, fontSize: 16, diff --git a/lib/screens/workshop_user_id_screen.dart b/lib/screens/workshop_user_id_screen.dart index c8334c7..42daac5 100644 --- a/lib/screens/workshop_user_id_screen.dart +++ b/lib/screens/workshop_user_id_screen.dart @@ -124,7 +124,7 @@ class _WorkshopUserIDScreenState extends ConsumerState { } if (!_isApproved) { _addAttendence( - "${widget.id} ${attendee.name}", widget.wsName); + "${widget.id}*${attendee.name}", widget.wsName); } else { widget.screenClosed(); Navigator.of(context).pop(); diff --git a/lib/screens/workshops_list_screen.dart b/lib/screens/workshops_list_screen.dart index 008f945..fbf0446 100644 --- a/lib/screens/workshops_list_screen.dart +++ b/lib/screens/workshops_list_screen.dart @@ -43,36 +43,46 @@ class WorkshopsListScreen extends ConsumerWidget { data: (workshops) => Expanded( child: ListView.builder( itemCount: workshops.length, - itemBuilder: (context, index) => ListTile( - contentPadding: const EdgeInsets.only(left: 40), - title: Text( - workshops[index].title, - style: const TextStyle( - color: Pallete.whiteColor, - fontSize: 20, - fontWeight: FontWeight.w500, - ), - ), - trailing: Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 25, 0), - child: Text( - "${workshops[index].attendees.length}", - style: const TextStyle( - color: Colors.blueAccent, - fontSize: 20, - fontWeight: FontWeight.w500, + itemBuilder: (context, index) { + return Column( + children: [ + const Divider( + color: Colors.white, ), - ), - ), - onTap: () { - showDialog( - context: context, - builder: (context) => WorkshopScreen( - workshop: workshops[index], + ListTile( + contentPadding: + const EdgeInsets.fromLTRB(15, 15, 5, 15), + title: Text( + workshops[index].title, + style: const TextStyle( + color: Pallete.whiteColor, + fontSize: 20, + fontWeight: FontWeight.w500, + ), + ), + trailing: Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 25, 0), + child: Text( + "${workshops[index].attendees.length}/${workshops[index].max}", + style: const TextStyle( + color: Colors.blueAccent, + fontSize: 20, + fontWeight: FontWeight.w500, + ), + ), + ), + onTap: () { + showDialog( + context: context, + builder: (context) => WorkshopScreen( + workshop: workshops[index], + ), + ); + }, ), - ); - }, - ), + ], + ); + }, ), ), error: (error, stackTrace) => Center( diff --git a/pubspec.lock b/pubspec.lock index d8b9b31..9bdd79e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -137,6 +137,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.6" + external_path: + dependency: "direct main" + description: + name: external_path + sha256: "2095c626fbbefe70d5a4afc9b1137172a68ee2c276e51c3c1283394485bea8f4" + url: "https://pub.dev" + source: hosted + version: "1.0.3" fake_async: dependency: transitive description: @@ -206,6 +214,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.3" + flutter_sanity: + dependency: "direct main" + description: + name: flutter_sanity + sha256: ab794e4f68359099872076b3f8f9419ed4cbb55039424be2434b01aa91bbd4f1 + url: "https://pub.dev" + source: hosted + version: "1.1.0" + flutter_sanity_image_url: + dependency: "direct main" + description: + name: flutter_sanity_image_url + sha256: "133f10e3d275fb69422e6ac54cef24f89e79bb921f6b85d131871d39fc11f4e8" + url: "https://pub.dev" + source: hosted + version: "0.0.3" flutter_test: dependency: "direct dev" description: flutter @@ -220,18 +244,18 @@ packages: dependency: "direct main" description: name: google_fonts - sha256: f0b8d115a13ecf827013ec9fc883390ccc0e87a96ed5347a3114cac177ef18e8 + sha256: "6b6f10f0ce3c42f6552d1c70d2c28d764cf22bb487f50f66cca31dcd5194f4d6" url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "4.0.4" http: dependency: "direct main" description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "0.13.6" http_parser: dependency: transitive description: @@ -360,6 +384,46 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8" + url: "https://pub.dev" + source: hosted + version: "11.0.1" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: f9fddd3b46109bd69ff3f9efa5006d2d309b7aec0f3c1c5637a60a2d5659e76e + url: "https://pub.dev" + source: hosted + version: "11.1.0" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5" + url: "https://pub.dev" + source: hosted + version: "9.1.4" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4" + url: "https://pub.dev" + source: hosted + version: "3.12.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098 + url: "https://pub.dev" + source: hosted + version: "0.1.3" petitparser: dependency: transitive description: @@ -372,10 +436,10 @@ packages: dependency: transitive description: name: platform - sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.3" plugin_platform_interface: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 6bee54f..479923e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,9 +38,13 @@ dependencies: cloud_firestore: ^4.9.2 mobile_scanner: ^3.4.1 flutter_riverpod: ^2.4.1 - http: ^1.1.0 - google_fonts: ^6.1.0 + http: ^0.13.0 + google_fonts: ^4.0.0 csv: ^5.0.2 + flutter_sanity_image_url: ^0.0.3 + flutter_sanity: ^1.1.0 + permission_handler: ^11.0.1 + external_path: ^1.0.3 dev_dependencies: flutter_launcher_icons: ^0.13.1 @@ -70,7 +74,7 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - - assets/event_data.csv + - assets/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 1a82e7d..5893c2f 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,8 +7,11 @@ #include "generated_plugin_registrant.h" #include +#include void RegisterPlugins(flutter::PluginRegistry* registry) { FirebaseCorePluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); + PermissionHandlerWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index fa8a39b..873f19d 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST firebase_core + permission_handler_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST