import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:csv/csv.dart';
import 'dart:html' as html;
import '../utils/csv_helper.dart';
import '../widgets/custom_box.dart';
import '../widgets/primary_key_mapping.dart';
import '../widgets/filter_widget.dart';
import 'merge_screen.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<List<dynamic>> csvData1 = [];
List<List<dynamic>> csvData2 = [];
List<String> fields1 = [];
List<String> fields2 = [];
List<bool> selectedFields1 = [];
List<bool> selectedFields2 = [];
String? selectedPrimaryKey1;
String? selectedPrimaryKey2;
Map<String, String> filters = {};
Future<void> pickCSVFile(int fileNumber) async {
final result = await FilePicker.platform.pickFiles(type: FileType.custom, allowedExtensions: ['csv']);
if (result != null) {
final inputFile = result.files.single.bytes;
List<List<dynamic>> rows = await CsvHelper().getCSVData(inputFile!);
setState(() {
if (fileNumber == 1) {
csvData1 = rows;
fields1 = rows[0].map((field) => field.toString()).toList();
selectedFields1 = List.filled(fields1.length, false);
} else {
csvData2 = rows;
fields2 = rows[0].map((field) => field.toString()).toList();
selectedFields2 = List.filled(fields2.length, false);
}
});
}
}
void mergeCSV() {
List<List<dynamic>> mergedData = CsvHelper().mergeSelectedCSV(
csvData1,
csvData2,
fields1,
fields2,
selectedFields1,
selectedFields2,
selectedPrimaryKey1,
selectedPrimaryKey2,
filters,
);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MergeScreen(mergedData: mergedData)),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('CSV Merger')),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
CustomBox(
title: "Master CSV File",
onTap: () => pickCSVFile(1),
fields: fields1,
selectedFields: selectedFields1,
onSelectionChanged: (index, value) {
setState(() => selectedFields1[index] = value);
},
),
CustomBox(
title: "Source CSV File",
onTap: () => pickCSVFile(2),
fields: fields2,
selectedFields: selectedFields2,
onSelectionChanged: (index, value) {
setState(() => selectedFields2[index] = value);
},
),
PrimaryKeyMapping(
fields1: fields1,
fields2: fields2,
onPrimaryKeySelected: (key1, key2) {
setState(() {
selectedPrimaryKey1 = key1;
selectedPrimaryKey2 = key2;
});
},
),
FilterWidget(
fields1: fields1,
fields2: fields2,
onFilterApplied: (updatedFilters) {
setState(() {
filters = updatedFilters;
});
},
),
],
),
Column(
children: [
ElevatedButton(
onPressed: mergeCSV,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
elevation: 5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
),
child: Text("Merge CSV Files", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
),
],
),
],
),
);
}
}
import 'package:flutter/material.dart';
class PrimaryKeyMapping extends StatefulWidget {
final List<String> fields1;
final List<String> fields2;
final Function(String?, String?) onPrimaryKeySelected;
PrimaryKeyMapping({required this.fields1, required this.fields2, required this.onPrimaryKeySelected});
@override
_PrimaryKeyMappingState createState() => _PrimaryKeyMappingState();
}
class _PrimaryKeyMappingState extends State<PrimaryKeyMapping> {
String? selectedKey1;
String? selectedKey2;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text("Map Primary Key", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DropdownButton<String>(
hint: Text("Select Master CSV Key"),
value: selectedKey1,
items: widget.fields1.map((field) => DropdownMenuItem(value: field, child: Text(field))).toList(),
onChanged: (value) {
setState(() {
selectedKey1 = value;
widget.onPrimaryKeySelected(selectedKey1, selectedKey2);
});
},
),
SizedBox(width: 20),
DropdownButton<String>(
hint: Text("Select Source CSV Key"),
value: selectedKey2,
items: widget.fields2.map((field) => DropdownMenuItem(value: field, child: Text(field))).toList(),
onChanged: (value) {
setState(() {
selectedKey2 = value;
widget.onPrimaryKeySelected(selectedKey1, selectedKey2);
});
},
),
],
),
],
);
}
}
import 'package:flutter/material.dart';
class FilterWidget extends StatefulWidget {
final List<String> fields1;
final List<String> fields2;
final Function(Map<String, String>) onFilterApplied;
FilterWidget({required this.fields1, required this.fields2, required this.onFilterApplied});
@override
_FilterWidgetState createState() => _FilterWidgetState();
}
class _FilterWidgetState extends State<FilterWidget> {
Map<String, TextEditingController> controllers = {};
@override
void initState() {
super.initState();
for (var field in widget.fields1 + widget.fields2) {
controllers[field] = TextEditingController();
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text("Apply Filters", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
...controllers.keys.map((field) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: TextField(
controller: controllers[field],
decoration: InputDecoration(
labelText: "Filter for $field",
border: OutlineInputBorder(),
),
onChanged: (value) {
widget.onFilterApplied({field: value});
},
),
);
}).toList(),
],
);
}
}
<!-- begin snippet: js hide: false console: true babel: false babelPresetReact: false babelPresetTS: false -->
map['key'])