Commits (4)
...@@ -24,7 +24,7 @@ android { ...@@ -24,7 +24,7 @@ android {
applicationId = "com.example.nfc_gogole_sheet" applicationId = "com.example.nfc_gogole_sheet"
// You can update the following values to match your application needs. // You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config. // For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion minSdk = 26
targetSdk = flutter.targetSdkVersion targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode versionCode = flutter.versionCode
versionName = flutter.versionName versionName = flutter.versionName
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" /> <uses-feature android:name="android.hardware.nfc" android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application <application
android:label="nfc_gogole_sheet" android:label="nfc_gogole_sheet"
android:name="${applicationName}" android:name="${applicationName}"
......
{
"filieres": [
{
"nom": "M2 IWOCS",
"icon": "school",
"matieres": [
{"nom": "Apprentissage Auto", "icon": "psychology"},
{"nom": "Programmation Mobile", "icon": "smartphone"},
{"nom": "Web Avancé", "icon": "code"},
{"nom": "Docker", "icon": "computer"},
{"nom": "IoT", "icon": "sensors"}
]
},
{
"nom": "M1 IWOCS",
"icon": "school",
"matieres": [
{"nom": "Compilation", "icon": "memory"},
{"nom": "DataViz", "icon": "bar_chart"},
{"nom": "IA", "icon": "smart_toy"},
{"nom": "Parralélisme distribué", "icon": "lan"},
{"nom": "Réseaux d'interaction", "icon": "hub"},
{"nom": "Graphes", "icon": "share"},
{"nom": "Programmation Fonctionnelle", "icon": "functions"},
{"nom": "MSI", "icon": "security"},
{"nom": "BDD Avancé", "icon": "storage"},
{"nom": "OCO", "icon": "calculate"}
]
},
{
"nom": "L3 Informatique",
"icon": "laptop_mac",
"matieres": [
{"nom": "Programmation C++", "icon": "code_off"},
{"nom": "Génie Logiciel", "icon": "build"},
{"nom": "Communication", "icon": "chat"},
{"nom": "IHM", "icon": "mouse"},
{"nom": "Théorie des Langages", "icon": "translate"},
{"nom": "Algo avancée", "icon": "mediation"},
{"nom": "Programmation Scientifique", "icon": "science"},
{"nom": "Web", "icon": "web"},
{"nom": "SGBD", "icon": "dns"},
{"nom": "Réseaux", "icon": "wifi"}
]
},
{
"nom": "L2 Informatique",
"icon": "laptop_windows",
"matieres": [
{"nom": "Système d'exploitation", "icon": "settings_system_daydream"},
{"nom": "Java avancé", "icon": "integration_instructions"},
{"nom": "Algorithmie et Programmation", "icon": "memory"},
{"nom": "Maths pour l'info", "icon": "calculate"},
{"nom": "Programmation C", "icon": "code"},
{"nom": "Web", "icon": "web_asset"},
{"nom": "BDD", "icon": "storage"}
]
},
{
"nom": "L1 MIPSI",
"icon": "book",
"matieres": [
{"nom": "Méthodologie", "icon": "rule"},
{"nom": "SPIP", "icon": "engineering"},
{"nom": "Dessin Technique", "icon": "architecture"},
{"nom": "Projets", "icon": "assignment"},
{"nom": "Algo et Programmation", "icon": "code"},
{"nom": "UEP", "icon": "work"},
{"nom": "OIL", "icon": "lightbulb"},
{"nom": "Physique du Mouvement", "icon": "directions_run"},
{"nom": "Analyse", "icon": "analytics"},
{"nom": "Optique", "icon": "camera"},
{"nom": "Algèbre", "icon": "square_foot"},
{"nom": "Documentation", "icon": "description"}
]
}
]
}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:nfc_google_sheet/context/colories.dart';
class Folder extends StatelessWidget {
final IconData icon;
final String nom;
final VoidCallback onTap;
final bool isSelected;
const Folder({super.key, required this.icon, required this.nom, required this.onTap, this.isSelected = false});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(12),
child: Container(
decoration: BoxDecoration(
color: Colories.subtitle.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(12),
border: isSelected
? Border.all(color: Colories.selected, width: 3)
: null,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
icon,
size: 50,
color: Colories.selected,
),
SizedBox(height: 15),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
nom,
textAlign: TextAlign.center,
style: TextStyle(
color: Colories.unselected,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
],
),
),
);
}
}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:nfc_google_sheet/context/colories.dart';
import 'package:nfc_google_sheet/database/databaseHelper.dart';
import 'package:nfc_google_sheet/model/student.dart';
class StudentForm extends StatefulWidget {
final String cardId;
const StudentForm({Key? key, required this.cardId}) : super(key: key);
@override
_StudentFormState createState() => _StudentFormState();
}
class _StudentFormState extends State<StudentForm> {
final _formKey = GlobalKey<FormState>();
final _studentIdController = TextEditingController();
final _firstNameController = TextEditingController();
final _nameController = TextEditingController();
final _promotionController = TextEditingController();
@override
Widget build(BuildContext context) {
return AlertDialog(
backgroundColor: Colories.background,
title: Text(
'Nouvel étudiant',
style: TextStyle(color: Colories.selected),
),
content: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextFormField(
controller: _studentIdController,
style: TextStyle(color: Colories.unselected),
decoration: InputDecoration(
labelText: 'ID Etudiant',
labelStyle: TextStyle(color: Colories.unselected),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colories.unselected),
),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer l\'ID de l\'étudiant';
}
return null;
},
),
TextFormField(
controller: _firstNameController,
style: TextStyle(color: Colories.unselected),
decoration: InputDecoration(
labelText: 'Prénom',
labelStyle: TextStyle(color: Colories.unselected),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colories.unselected),
),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer le prénom';
}
return null;
},
),
TextFormField(
controller: _nameController,
style: TextStyle(color: Colories.unselected),
decoration: InputDecoration(
labelText: 'Nom',
labelStyle: TextStyle(color: Colories.unselected),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colories.unselected),
),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer le nom';
}
return null;
},
),
TextFormField(
controller: _promotionController,
style: TextStyle(color: Colories.unselected),
decoration: InputDecoration(
labelText: 'Promotion',
labelStyle: TextStyle(color: Colories.unselected),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colories.unselected),
),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer la promotion';
}
return null;
},
),
],
),
),
),
actions: <Widget>[
TextButton(
child: Text('Annuler', style: TextStyle(color: Colories.unselected)),
onPressed: () {
Navigator.of(context).pop();
},
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colories.selected,
),
child: Text('Enregistrer', style: TextStyle(color: Colories.background)),
onPressed: () async {
if (_formKey.currentState!.validate()) {
final student = Student(
cardId: widget.cardId,
studentId: _studentIdController.text,
firstName: _firstNameController.text,
name: _nameController.text,
promotion: _promotionController.text,
);
await DatabaseHelper.instance.insertUser(student);
Navigator.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Etudiant enregistré avec succès!'),
backgroundColor: Colories.selected,
),
);
}
},
),
],
);
}
}
\ No newline at end of file
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:nfc_google_sheet/context/colories.dart'; import 'package:nfc_google_sheet/context/colories.dart';
class TitleCustom extends StatelessWidget{ class TitleCustom extends StatelessWidget{
......
...@@ -8,4 +8,5 @@ class Colories { ...@@ -8,4 +8,5 @@ class Colories {
static Color bordure = Color(0xff171601); static Color bordure = Color(0xff171601);
static Color selected = Color(0xffe8bb5a); static Color selected = Color(0xffe8bb5a);
static Color unselected = Color(0xfffffae8); static Color unselected = Color(0xfffffae8);
static Color warning = Color(0xff750909);
} }
\ No newline at end of file
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqflite.dart';
import '../model/student.dart'; import '../model/student.dart';
import 'package:excel/excel.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
class DatabaseHelper { class DatabaseHelper {
static final DatabaseHelper instance = DatabaseHelper._instance(); static final DatabaseHelper instance = DatabaseHelper._instance();
...@@ -16,18 +20,17 @@ class DatabaseHelper { ...@@ -16,18 +20,17 @@ class DatabaseHelper {
Future<Database> initDb() async { Future<Database> initDb() async {
String databasesPath = await getDatabasesPath(); String databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'student_university.db'); String path = join(databasesPath, 'student_university.db');
return await openDatabase(path, version: 1, onCreate: _onCreate); return await openDatabase(path, version: 1, onCreate: _onCreate);
} }
Future _onCreate(Database db, int version) async { Future _onCreate(Database db, int version) async {
await db.execute(''' await db.execute('''
CREATE TABLE student ( CREATE TABLE IF NOT EXISTS STUDENT (
studentNFCCardId TEXT PRIMARY KEY, cardId TEXT PRIMARY KEY,
studentId TEXT,
firstName TEXT, firstName TEXT,
name TEXT, name TEXT,
promotion TEXT, promotion TEXT
studentId TEXT
) )
'''); ''');
} }
...@@ -44,11 +47,73 @@ class DatabaseHelper { ...@@ -44,11 +47,73 @@ class DatabaseHelper {
Future<int> updateUser(Student student) async { Future<int> updateUser(Student student) async {
Database db = await instance.db; Database db = await instance.db;
return await db.update('student', student.toMap(), where: 'studentNFCCardId = ?', whereArgs: [student.studentNFCCardId]); return await db.update('student', student.toMap(), where: 'cardId = ?', whereArgs: [student.cardId]);
}
Future<int> deleteUser(String cardId) async {
Database db = await instance.db;
return await db.delete('student', where: 'cardId = ?', whereArgs: [cardId]);
} }
Future<int> deleteUser(String studentNFCCardId) async { Future<int> clear() async {
Database db = await instance.db; Database db = await instance.db;
return await db.delete('student', where: 'studentNFCCardId = ?', whereArgs: [studentNFCCardId]); return await db.delete('student');
}
Future<String?> generateExcel(bool includeCardId, {String? filiere, String? matiere}) async {
var status = await Permission.storage.status;
if (!status.isGranted) {
await Permission.storage.request();
}
final List<Map<String, dynamic>> users = await queryAllUsers();
if (users.isEmpty) {
return null;
}
final excel = Excel.createExcel();
Sheet sheetObject = excel['Etudiants'];
List<String> headerStrings = ['ID Étudiant', 'Prénom', 'Nom', 'Promotion'];
if (includeCardId) {
headerStrings.add('ID Carte');
}
List<CellValue> headers = headerStrings.map((header) => TextCellValue(header)).toList();
sheetObject.appendRow(headers);
for (var user in users) {
List<String> rowStrings = [
user['studentId'] ?? '',
user['firstName'] ?? '',
user['name'] ?? '',
user['promotion'] ?? '',
];
if (includeCardId) {
rowStrings.add(user['cardId'] ?? '');
}
List<CellValue> row = rowStrings.map((cell) => TextCellValue(cell)).toList();
sheetObject.appendRow(row);
}
Directory? directory = await getExternalStorageDirectory();
if (directory != null) {
String finalPath = directory.path;
String fileName = 'etudiants.xlsx';
if (filiere != null && filiere.isNotEmpty && matiere != null && matiere.isNotEmpty) {
finalPath = join(directory.path, filiere);
fileName = '$matiere.xlsx';
}
await Directory(finalPath).create(recursive: true);
String filePath = join(finalPath, fileName);
File(filePath)
..createSync(recursive: true)
..writeAsBytesSync(excel.save()!);
return filePath;
}
return null;
} }
} }
\ No newline at end of file
...@@ -2,9 +2,12 @@ import 'package:flutter/material.dart'; ...@@ -2,9 +2,12 @@ import 'package:flutter/material.dart';
import 'package:nfc_google_sheet/context/colories.dart'; import 'package:nfc_google_sheet/context/colories.dart';
import 'package:nfc_google_sheet/pages/home_page.dart'; import 'package:nfc_google_sheet/pages/home_page.dart';
import 'package:nfc_google_sheet/pages/sheet_page.dart'; import 'package:nfc_google_sheet/pages/sheet_page.dart';
import 'package:nfc_google_sheet/pages/stats_page.dart'; import 'package:nfc_google_sheet/pages/exam_page.dart';
import 'package:nfc_google_sheet/database/databaseHelper.dart';
import 'package:sqflite/sqflite.dart';
void main(){ void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp()); runApp(MyApp());
} }
...@@ -13,40 +16,56 @@ class MyApp extends StatefulWidget { ...@@ -13,40 +16,56 @@ class MyApp extends StatefulWidget {
@override @override
State<MyApp> createState() => _MyAppState(); State<MyApp> createState() => _MyAppState();
} }
class _MyAppState extends State<MyApp>{
class _MyAppState extends State<MyApp> {
final instanceBDDHelper = DatabaseHelper.instance;
int _currentIndex = 1; int _currentIndex = 1;
void setCurrentIndex(int index){
@override
void initState() {
super.initState();
initBDD();
}
void setCurrentIndex(int index) {
setState(() { setState(() {
_currentIndex = index; _currentIndex = index;
}); });
} }
Future<Database> initBDD() async {
final Database dbInstance = await DatabaseHelper.instance.initDb();
return dbInstance;
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
home: Scaffold( home: Scaffold(
body: [StatsPage(), HomePage(), SheetPage()][_currentIndex], body: [ExamPage(), HomePage(), SheetPage()][_currentIndex],
bottomNavigationBar: BottomNavigationBar( bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed, type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex, currentIndex: _currentIndex,
selectedItemColor: Colories.selected, selectedItemColor: Colories.selected,
unselectedItemColor: Colories.unselected, unselectedItemColor: Colories.unselected,
backgroundColor: Colories.background, backgroundColor: Colories.background,
selectedFontSize: 14, selectedFontSize: 14,
unselectedFontSize: 14, unselectedFontSize: 14,
iconSize: 24, iconSize: 24,
onTap: (index) { onTap: (index) {
setState(() { setState(() {
_currentIndex = index; _currentIndex = index;
}); });
}, },
items: [ items: [
BottomNavigationBarItem(icon: Icon(Icons.query_stats_rounded, size: 24), label: "STATISTIQUES"), BottomNavigationBarItem(
BottomNavigationBarItem(icon: Icon(Icons.home, size: 24), label: "HOME"), icon: Icon(Icons.file_copy, size: 24), label: "EXAMS"),
BottomNavigationBarItem(icon: Icon(Icons.remove_red_eye, size: 24), label: "SHEET"), BottomNavigationBarItem(
], icon: Icon(Icons.home, size: 24), label: "HOME"),
) BottomNavigationBarItem(
), icon: Icon(Icons.remove_red_eye, size: 24), label: "SHEET"),
],
)),
); );
} }
} }
\ No newline at end of file
class Student { class Student {
final String studentNFCCardId; final String cardId;
final String firstName; final String firstName;
final String name; final String name;
final String promotion; final String promotion;
final String studentId; final String studentId;
Student({ Student({
required this.studentNFCCardId, required this.cardId,
required this.firstName, required this.firstName,
required this.name, required this.name,
required this.promotion, required this.promotion,
...@@ -15,7 +15,7 @@ class Student { ...@@ -15,7 +15,7 @@ class Student {
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return { return {
'studentNFCCardId': studentNFCCardId, 'cardId': cardId,
'firstName': firstName, 'firstName': firstName,
'name': name, 'name': name,
'promotion': promotion, 'promotion': promotion,
...@@ -25,7 +25,7 @@ class Student { ...@@ -25,7 +25,7 @@ class Student {
factory Student.fromMap(Map<String, dynamic> map) { factory Student.fromMap(Map<String, dynamic> map) {
return Student( return Student(
studentNFCCardId: map['studentNFCCardId'], cardId: map['cardId'],
firstName: map['firstName'], firstName: map['firstName'],
name: map['name'], name: map['name'],
promotion: map['promotion'], promotion: map['promotion'],
......
import 'package:flutter/material.dart';
import 'package:nfc_google_sheet/context/colories.dart';
import 'package:nfc_google_sheet/pages/filiere_page.dart';
import '../database/databaseHelper.dart';
class ExamPage extends StatelessWidget {
const ExamPage({super.key});
@override
Widget build(BuildContext context) {
return MyExamPage();
}
}
class MyExamPage extends StatefulWidget{
const MyExamPage({super.key});
@override
State<MyExamPage> createState() => _MyExamPageState();
}
class _MyExamPageState extends State<MyExamPage>{
void _deleteAllUsers() async {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: Colories.background,
title: Text("Confirmer la suppression", style: TextStyle(color: Colories.selected)),
content: Text("Êtes-vous sûr de vouloir supprimer toutes les données des étudiants ?", style: TextStyle(color: Colories.unselected)),
actions: [
TextButton(
child: Text("Annuler", style: TextStyle(color: Colories.unselected)),
onPressed: () => Navigator.of(context).pop(),
),
ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colors.red.shade400),
child: Text("Supprimer", style: TextStyle(color: Colories.background)),
onPressed: () async {
await DatabaseHelper.instance.clear();
Navigator.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Toutes les données ont été supprimées.'),
backgroundColor: Colors.red,
),
);
},
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colories.background,
appBar: AppBar(
title: Text('Options', style: TextStyle(color: Colories.selected)),
backgroundColor: Colories.background,
elevation: 0,
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Gestion des données et examens',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Colories.title,
),
),
SizedBox(height: 40),
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FilierePage()),
);
},
icon: Icon(Icons.school, color: Colories.background),
label: Text(
"VOIR LES FILIÈRES",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
style: ElevatedButton.styleFrom(
backgroundColor: Colories.selected,
foregroundColor: Colories.background,
padding: EdgeInsets.symmetric(vertical: 18),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
),
),
SizedBox(height: 20),
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: _deleteAllUsers,
icon: Icon(Icons.delete_forever, color: Colories.background),
label: Text(
"SUPPRIMER LES DONNÉES",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red.shade400,
foregroundColor: Colories.background,
padding: EdgeInsets.symmetric(vertical: 18),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
),
),
],
),
),
);
}
}
\ No newline at end of file
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:nfc_google_sheet/components/folder.dart';
import 'package:nfc_google_sheet/context/colories.dart';
import 'package:nfc_google_sheet/pages/matiere_page.dart';
import 'package:nfc_google_sheet/pages/sheet_page.dart';
class FilierePage extends StatefulWidget {
const FilierePage({super.key});
@override
_FilierePageState createState() => _FilierePageState();
}
class _FilierePageState extends State<FilierePage> {
List<dynamic> _filieres = [];
int? _selectedFiliereIndex;
@override
void initState() {
super.initState();
_loadFilieres();
}
Future<void> _loadFilieres() async {
final String response = await rootBundle.loadString('assets/filieres.json');
final data = await json.decode(response);
setState(() {
_filieres = data['filieres'];
});
}
IconData _getIconData(String iconName) {
switch (iconName) {
case 'school': return Icons.school;
case 'laptop_mac': return Icons.laptop_mac;
case 'laptop_windows': return Icons.laptop_windows;
case 'book': return Icons.book;
default: return Icons.folder;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colories.background,
appBar: AppBar(
title: Text('Choisir une filière', style: TextStyle(color: Colories.selected)),
backgroundColor: Colories.background,
elevation: 0,
centerTitle: true,
),
body: _filieres.isEmpty
? Center(child: CircularProgressIndicator(color: Colories.selected))
: Padding(
padding: const EdgeInsets.all(16.0),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
childAspectRatio: 1,
),
itemCount: _filieres.length,
itemBuilder: (context, index) {
final filiere = _filieres[index];
return Folder(
nom: filiere['nom'],
icon: _getIconData(filiere['icon']),
isSelected: _selectedFiliereIndex == index,
onTap: () {
setState(() {
_selectedFiliereIndex = index;
});
SheetPage.selectedMatiere = null;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MatierePage(filiere: filiere),
),
);
},
);
},
),
),
);
}
}
\ No newline at end of file
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:nfc_google_sheet/context/colories.dart'; import 'package:nfc_google_sheet/components/studentForm.dart';
import 'package:nfc_google_sheet/components/title.dart'; import 'package:nfc_google_sheet/components/title.dart';
import 'package:nfc_manager/nfc_manager.dart';
import 'package:nfc_manager_ndef/nfc_manager_ndef.dart';
import 'package:nfc_manager_felica/nfc_manager_felica.dart';
import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; import 'package:flutter_nfc_kit/flutter_nfc_kit.dart';
import 'package:nfc_google_sheet/context/colories.dart';
import 'package:nfc_google_sheet/database/databaseHelper.dart';
class HomePage extends StatelessWidget { class HomePage extends StatelessWidget {
const HomePage({super.key}); const HomePage({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MyHomePage();
home: MyHomePage(),
);
} }
} }
class MyHomePage extends StatefulWidget{ class MyHomePage extends StatefulWidget {
const MyHomePage({super.key}); const MyHomePage({super.key});
@override @override
State<MyHomePage> createState() => _MyHomePageState(); State<MyHomePage> createState() => _MyHomePageState();
} }
class _MyHomePageState extends State<MyHomePage>{ class _MyHomePageState extends State<MyHomePage> {
String nfcData = "Tap an NFC tag"; String nfcData = "Appuyez sur une carte NFC";
ScanStatus _scanStatus = ScanStatus.idle;
Future<void> startNFC() async { Future<void> startNFC() async {
NfcAvailability isAvailable = await NfcManager.instance.checkAvailability(); try {
if (isAvailable != NfcAvailability.enabled) { var availability = await FlutterNfcKit.nfcAvailability;
if (availability != NFCAvailability.available) {
setState(() {
nfcData = "NFC non disponible ou désactivé.";
_scanStatus = ScanStatus.error;
});
return;
}
setState(() { setState(() {
nfcData = "NFC is not available on this device"; nfcData = "En attente d'une carte NFC...";
_scanStatus = ScanStatus.scanning;
}); });
return;
}
NfcManager.instance.startSession( NFCTag tag = await FlutterNfcKit.poll(timeout: Duration(seconds: 15));
pollingOptions: {NfcPollingOption.iso14443}, final cardId = tag.id;
onDiscovered: (NfcTag tag) async {
print("data: ${tag.data.toString()}"); List<Map<String, dynamic>> users = await DatabaseHelper.instance.queryAllUsers();
await NfcManager.instance.stopSession(); bool userExists = users.any((user) => user['cardId'] == cardId);
if (userExists) {
setState(() {
nfcData = "Utilisateur déjà inscrit";
_scanStatus = ScanStatus.error;
});
} else {
setState(() {
nfcData = "ID de la carte NFC: $cardId";
_scanStatus = ScanStatus.success;
});
showDialog(
context: context,
builder: (BuildContext context) {
return StudentForm(cardId: cardId);
},
);
} }
); } catch (e) {
setState(() {
nfcData = "Erreur ou scan annulé.";
_scanStatus = ScanStatus.error;
});
} finally {
await FlutterNfcKit.finish();
if (_scanStatus == ScanStatus.scanning) {
setState(() {
_scanStatus = ScanStatus.idle;
nfcData = "Appuyez sur une carte NFC";
});
}
}
} }
Future<void> readNFCTag() async { Widget _buildStatusIcon() {
try { switch (_scanStatus) {
NFCTag tag = await FlutterNfcKit.poll(); case ScanStatus.scanning:
print('NFC Tag Found: ${tag.id}'); return SizedBox(
} catch (e) { width: 120,
print('Error reading NFC tag: $e'); height: 120,
child: CircularProgressIndicator(
color: Colories.selected,
strokeWidth: 6,
),
);
case ScanStatus.success:
return Icon(
Icons.check_circle_outline,
color: Colories.selected,
size: 120,
);
case ScanStatus.error:
return Icon(
Icons.error_outline,
color: Colors.red.shade400,
size: 120,
);
default:
return Icon(
Icons.nfc,
color: Colories.unselected.withValues(alpha: 0.7),
size: 120,
);
} }
} }
Widget _buildStatusText() {
Color textColor;
switch (_scanStatus) {
case ScanStatus.success:
textColor = Colories.selected;
break;
case ScanStatus.error:
textColor = Colors.red.shade400;
break;
default:
textColor = Colories.unselected;
}
return Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
color: Colories.subtitle.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(12),
),
child: Text(
nfcData,
textAlign: TextAlign.center,
style: TextStyle(
color: textColor,
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool isScanning = _scanStatus == ScanStatus.scanning;
return Scaffold( return Scaffold(
body: Container( backgroundColor: Colories.background,
decoration: BoxDecoration( body: SafeArea(
image: DecorationImage( child: Padding(
image: AssetImage('assets/homePageBackground.png'), padding: const EdgeInsets.all(24.0),
fit: BoxFit.cover, child: Column(
children: [
TitleCustom(content: 'ENREGISTREZ - VOUS'),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildStatusIcon(),
SizedBox(height: 30),
_buildStatusText(),
],
),
),
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: isScanning ? null : startNFC,
icon: Icon(
Icons.nfc,
color: Colories.background,
),
label: Text(
isScanning ? "SCAN EN COURS..." : "ENREGISTRER SA CARTE",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
letterSpacing: 1.1,
),
),
style: ElevatedButton.styleFrom(
backgroundColor: Colories.selected,
foregroundColor: Colories.background,
disabledBackgroundColor: Colories.selected.withValues(alpha: 0.5),
padding: EdgeInsets.symmetric(vertical: 18),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
),
),
],
), ),
), ),
child: Column(
children: [
SizedBox(height: 50),
Center(
child: TitleCustom(content: 'ENREGISTREZ - VOUS')
),
SizedBox(height: 50),
ElevatedButton(onPressed: readNFCTag, child: Text("Enregistrer sa carte")),
Center(child: Text(nfcData)),
]
),
), ),
); );
} }
}
enum ScanStatus {
idle,
scanning,
success,
error,
} }
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:nfc_google_sheet/components/folder.dart';
import 'package:nfc_google_sheet/context/colories.dart';
import 'package:nfc_google_sheet/pages/sheet_page.dart';
class MatierePage extends StatefulWidget {
final Map<String, dynamic> filiere;
const MatierePage({Key? key, required this.filiere}) : super(key: key);
@override
_MatierePageState createState() => _MatierePageState();
}
class _MatierePageState extends State<MatierePage> {
int? _selectedMatiereIndex;
IconData _getIconData(String iconName) {
switch (iconName) {
case 'psychology': return Icons.psychology;
case 'smartphone': return Icons.smartphone;
case 'code': return Icons.code;
case 'computer': return Icons.computer;
case 'sensors': return Icons.sensors;
case 'memory': return Icons.memory;
case 'bar_chart': return Icons.bar_chart;
case 'smart_toy': return Icons.smart_toy;
case 'lan': return Icons.lan;
case 'hub': return Icons.hub;
case 'share': return Icons.share;
case 'functions': return Icons.functions;
case 'security': return Icons.security;
case 'storage': return Icons.storage;
case 'calculate': return Icons.calculate;
case 'code_off': return Icons.code_off;
case 'build': return Icons.build;
case 'chat': return Icons.chat;
case 'mouse': return Icons.mouse;
case 'translate': return Icons.translate;
case 'mediation': return Icons.mediation;
case 'science': return Icons.science;
case 'web': return Icons.web;
case 'dns': return Icons.dns;
case 'wifi': return Icons.wifi;
case 'settings_system_daydream': return Icons.settings_system_daydream;
case 'integration_instructions': return Icons.integration_instructions;
case 'web_asset': return Icons.web_asset;
case 'rule': return Icons.rule;
case 'engineering': return Icons.engineering;
case 'architecture': return Icons.architecture;
case 'assignment': return Icons.assignment;
case 'work': return Icons.work;
case 'lightbulb': return Icons.lightbulb;
case 'directions_run': return Icons.directions_run;
case 'analytics': return Icons.analytics;
case 'camera': return Icons.camera;
case 'square_foot': return Icons.square_foot;
case 'description': return Icons.description;
default: return Icons.subject;
}
}
@override
Widget build(BuildContext context) {
final List<dynamic> matieres = widget.filiere['matieres'];
return Scaffold(
backgroundColor: Colories.background,
appBar: AppBar(
title: Text(widget.filiere['nom'], style: TextStyle(color: Colories.selected)),
backgroundColor: Colories.background,
elevation: 0,
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
childAspectRatio: 1,
),
itemCount: matieres.length,
itemBuilder: (context, index) {
final matiere = matieres[index];
return Folder(
nom: matiere['nom'],
icon: _getIconData(matiere['icon']),
isSelected: _selectedMatiereIndex == index,
onTap: () {
setState(() {
_selectedMatiereIndex = index;
});
SheetPage.selectedMatiere = matiere['nom'];
},
);
},
),
),
],
),
),
);
}
}
\ No newline at end of file
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:nfc_google_sheet/context/colories.dart'; import 'package:nfc_google_sheet/context/colories.dart';
import 'package:nfc_google_sheet/database/databaseHelper.dart';
import 'package:nfc_google_sheet/model/student.dart';
class SheetPage extends StatelessWidget { class SheetPage extends StatelessWidget {
const SheetPage({super.key}); const SheetPage({super.key});
static String? selectedFiliere;
static String? selectedMatiere;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MySheetPage();
home: MySheetPage(),
);
} }
} }
class MySheetPage extends StatefulWidget{ class MySheetPage extends StatefulWidget {
const MySheetPage({super.key}); const MySheetPage({super.key});
@override @override
State<MySheetPage> createState() => _MySheetPageState(); State<MySheetPage> createState() => _MySheetPageState();
} }
class _MySheetPageState extends State<MySheetPage>{ class _MySheetPageState extends State<MySheetPage> {
late Future<List<Student>> _students;
@override
void initState() {
super.initState();
_students = _getStudents();
}
Future<List<Student>> _getStudents() async {
final List<Map<String, dynamic>> maps = await DatabaseHelper.instance.queryAllUsers();
return List.generate(maps.length, (i) {
return Student.fromMap(maps[i]);
});
}
void _showWarningMatiereUnselected(){
showDialog(context: context, builder: (BuildContext context) {
return AlertDialog(
backgroundColor: Colories.background,
title: Text("WARNING !", style: TextStyle(color: Colories.warning)),
content: Text("Vous n'avez pas sélectionnez de matière dans l'application. Continuez quand même ?"),
actions: [
TextButton(
child: Text("Non", style: TextStyle(color: Colories.unselected)),
onPressed: () {
// TODO: On annule tout
},
),
ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colories.selected),
child: Text("Oui", style: TextStyle(color: Colories.background)),
onPressed: () {
Navigator.of(context).pop();
_exportData(true);
},
),
],
);
});
}
void _showExportDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: Colories.background,
title: Text("Exporter les données", style: TextStyle(color: Colories.selected)),
content: Text("Voulez-vous inclure la colonne 'ID Carte' dans le fichier Excel ?", style: TextStyle(color: Colories.unselected)),
actions: [
TextButton(
child: Text("Non", style: TextStyle(color: Colories.unselected)),
onPressed: () {
Navigator.of(context).pop();
_exportData(false);
},
),
ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colories.selected),
child: Text("Oui", style: TextStyle(color: Colories.background)),
onPressed: () {
if (SheetPage.selectedMatiere == null) {
_showWarningMatiereUnselected();
} else {
Navigator.of(context).pop();
_exportData(true);
}
},
),
],
);
},
);
}
void _exportData(bool includeCardId) async {
final filePath = await DatabaseHelper.instance.generateExcel(includeCardId);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(filePath != null
? 'Fichier Excel généré : $filePath'
: 'Aucune donnée à exporter.'),
backgroundColor: filePath != null ? Colories.selected : Colors.red,
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: Column( backgroundColor: Colories.background,
children: [ appBar: AppBar(
SizedBox(height: 50), title: Text('Données des étudiants', style: TextStyle(color: Colories.selected)),
Center( backgroundColor: Colories.background,
child: Text( elevation: 0,
'Contenu du fichier sheet_students.xslx', centerTitle: true,
style: TextStyle(fontWeight: FontWeight.bold, color:Colories.title), ),
) body: FutureBuilder<List<Student>>(
) future: _students,
] builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator(color: Colories.selected));
} else if (snapshot.hasError) {
return Center(child: Text('Erreur: ${snapshot.error}', style: TextStyle(color: Colors.red)));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return Center(child: Text('Aucun étudiant enregistré.', style: TextStyle(color: Colories.unselected)));
} else {
final students = snapshot.data!;
return SingleChildScrollView(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columnSpacing: 20.0,
headingRowColor: WidgetStateColor.resolveWith((states) => Colories.subtitle),
columns: [
DataColumn(label: Text('ID Étudiant', style: TextStyle(color: Colories.selected, fontWeight: FontWeight.bold))),
DataColumn(label: Text('Prénom', style: TextStyle(color: Colories.selected, fontWeight: FontWeight.bold))),
DataColumn(label: Text('Nom', style: TextStyle(color: Colories.selected, fontWeight: FontWeight.bold))),
DataColumn(label: Text('Promotion', style: TextStyle(color: Colories.selected, fontWeight: FontWeight.bold))),
],
rows: students.map((student) => DataRow(
cells: [
DataCell(Text(student.studentId, style: TextStyle(color: Colories.unselected))),
DataCell(Text(student.firstName, style: TextStyle(color: Colories.unselected))),
DataCell(Text(student.name, style: TextStyle(color: Colories.unselected))),
DataCell(Text(student.promotion, style: TextStyle(color: Colories.unselected))),
],
)).toList(),
),
),
);
}
},
),
floatingActionButton: FloatingActionButton.extended(
onPressed: _showExportDialog,
label: Text('Générer le fichier', style: TextStyle(color: Colories.background)),
icon: Icon(Icons.download, color: Colories.background),
backgroundColor: Colories.selected,
), ),
); );
} }
......
import 'package:flutter/material.dart';
import 'package:nfc_google_sheet/context/colories.dart';
class StatsPage extends StatelessWidget {
const StatsPage({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyStatsPage(),
);
}
}
class MyStatsPage extends StatefulWidget{
const MyStatsPage({super.key});
@override
State<MyStatsPage> createState() => _MyStatsPageState();
}
class _MyStatsPageState extends State<MyStatsPage>{
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SizedBox(height: 50),
Center(
child: Text(
'Statistiques diverses',
style: TextStyle(fontWeight: FontWeight.bold, color:Colories.title),
)
)
]
),
);
}
}
\ No newline at end of file
...@@ -5,8 +5,10 @@ ...@@ -5,8 +5,10 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import path_provider_foundation
import sqflite_darwin import sqflite_darwin
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
} }
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
archive:
dependency: transitive
description:
name: archive
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
url: "https://pub.dev"
source: hosted
version: "3.6.1"
async: async:
dependency: transitive dependency: transitive
description: description:
...@@ -65,6 +73,22 @@ packages: ...@@ -65,6 +73,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.8" version: "1.0.8"
equatable:
dependency: transitive
description:
name: equatable
sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7"
url: "https://pub.dev"
source: hosted
version: "2.0.7"
excel:
dependency: "direct main"
description:
name: excel
sha256: "1a15327dcad260d5db21d1f6e04f04838109b39a2f6a84ea486ceda36e468780"
url: "https://pub.dev"
source: hosted
version: "4.0.6"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
...@@ -73,6 +97,14 @@ packages: ...@@ -73,6 +97,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.3" version: "1.3.3"
ffi:
dependency: transitive
description:
name: ffi
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
...@@ -192,46 +224,118 @@ packages: ...@@ -192,46 +224,118 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.3.4" version: "0.3.4"
ndef_record: path:
dependency: transitive dependency: transitive
description: description:
name: ndef_record name: path
sha256: "876e2774f18573e8afba1aa9db3998aaf4e3384c825c843c3f86d001bec8510d" sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.3" version: "1.9.1"
nfc_manager: path_provider:
dependency: "direct main" dependency: "direct main"
description: description:
name: nfc_manager name: path_provider
sha256: "24c78b0e5702da53e7f8794d073624c0bee7cd99924f257cbd11f5d1c5866879" sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.1" version: "2.1.5"
nfc_manager_felica: path_provider_android:
dependency: "direct main" dependency: transitive
description: description:
name: nfc_manager_felica name: path_provider_android
sha256: "9f5506efd6bf828605e2cb4fc948c07cc3bfe51d9cf8d9b01860528c735cd8d1" sha256: e122c5ea805bb6773bb12ce667611265980940145be920cd09a4b0ec0285cb16
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "2.2.20"
nfc_manager_ndef: path_provider_foundation:
dependency: "direct main" dependency: transitive
description: description:
name: nfc_manager_ndef name: path_provider_foundation
sha256: "8aacee776120b4d09e3049b26cf4a7397fee3abafc207c0640342ada05c5df7d" sha256: efaec349ddfc181528345c56f8eda9d6cccd71c177511b132c6a0ddaefaa2738
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "2.4.3"
path: path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
url: "https://pub.dev"
source: hosted
version: "2.3.0"
permission_handler:
dependency: "direct main" dependency: "direct main"
description: description:
name: path name: permission_handler
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "12.0.1"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6"
url: "https://pub.dev"
source: hosted
version: "13.0.1"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023
url: "https://pub.dev"
source: hosted
version: "9.4.7"
permission_handler_html:
dependency: transitive
description:
name: permission_handler_html
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
url: "https://pub.dev"
source: hosted
version: "0.1.3+5"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
url: "https://pub.dev"
source: hosted
version: "4.3.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
url: "https://pub.dev"
source: hosted
version: "0.2.1"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1"
url: "https://pub.dev"
source: hosted
version: "7.0.1"
platform: platform:
dependency: transitive dependency: transitive
description: description:
...@@ -261,7 +365,14 @@ packages: ...@@ -261,7 +365,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.10.1" version: "1.10.1"
<<<<<<< HEAD sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
sqflite: sqflite:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -302,16 +413,6 @@ packages: ...@@ -302,16 +413,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.0" version: "2.4.0"
=======
sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
>>>>>>> c12632c (feature: Nfc)
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
...@@ -392,6 +493,30 @@ packages: ...@@ -392,6 +493,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "15.0.2" version: "15.0.2"
web:
dependency: transitive
description:
name: web
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
url: "https://pub.dev"
source: hosted
version: "1.1.1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
xml:
dependency: transitive
description:
name: xml
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
url: "https://pub.dev"
source: hosted
version: "6.6.1"
sdks: sdks:
dart: ">=3.9.2 <4.0.0" dart: ">=3.9.2 <4.0.0"
flutter: ">=3.24.0" flutter: ">=3.35.0"
...@@ -30,19 +30,16 @@ environment: ...@@ -30,19 +30,16 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
<<<<<<< HEAD
sqflite: ^2.4.2 sqflite: ^2.4.2
path: ^1.9.0 # nfc_manager: ^4.1.1
======= flutter_nfc_kit: ^3.6.0
nfc_manager: ^4.1.1 excel: ^4.0.6
nfc_manager_felica: ^1.0.0 path_provider: ^2.1.5
nfc_manager_ndef: ^1.1.0 permission_handler: ^12.0.1
>>>>>>> c12632c (feature: Nfc)
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8 cupertino_icons: ^1.0.8
flutter_nfc_kit: ^3.6.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
...@@ -69,6 +66,7 @@ flutter: ...@@ -69,6 +66,7 @@ flutter:
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
assets: assets:
- assets/homePageBackground.png - assets/homePageBackground.png
- assets/filieres.json
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/to/resolution-aware-images # https://flutter.dev/to/resolution-aware-images
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <permission_handler_windows/permission_handler_windows_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
} }