296 lines
8.3 KiB
Dart
296 lines
8.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:spreadsheet_table/spreadsheet_table.dart';
|
|
import 'package:pluto_grid/pluto_grid.dart';
|
|
import 'package:ltx_flutter/appwrite/appwrite.dart';
|
|
import 'package:ltx_flutter/appwrite/database_api.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:appwrite/models.dart';
|
|
import 'package:intl/intl.dart';
|
|
|
|
class TablePage extends StatefulWidget {
|
|
const TablePage({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
_TablePageState createState() => _TablePageState();
|
|
}
|
|
|
|
class _TablePageState extends State<TablePage> {
|
|
final database = DatabaseAPI();
|
|
late List<Document>? entries = [];
|
|
|
|
AuthStatus authStatus = AuthStatus.uninitialized;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
final AuthAPI appwrite = context.read<AuthAPI>();
|
|
authStatus = appwrite.status;
|
|
loadEntries();
|
|
}
|
|
|
|
loadEntries() async {
|
|
try {
|
|
final value = await database.getEntries(limit: 25);
|
|
setState(() {
|
|
entries = value.documents;
|
|
});
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
}
|
|
|
|
String formatDate({String format = "", String? dateISO}) {
|
|
final DateFormat dateFormatter = DateFormat(format);
|
|
final date = dateISO!.isEmpty ? DateTime.now() : DateTime.parse(dateISO);
|
|
return dateFormatter.format(date);
|
|
}
|
|
|
|
List<PlutoColumn> hourCols = List<int>.generate(24, (i) => i).map((e) {
|
|
var meridien = "AM";
|
|
var hour = 12;
|
|
if (e > 12) {
|
|
hour = e - 12;
|
|
} else if (e > 0) {
|
|
hour = e;
|
|
}
|
|
if (e > 11) {
|
|
meridien = "PM";
|
|
}
|
|
var hourTitle = "${hour.toString()} $meridien";
|
|
return PlutoColumn(
|
|
title: hourTitle,
|
|
field: "hours[$e]",
|
|
type: PlutoColumnType.number(),
|
|
width: 70,
|
|
enableContextMenu: false,
|
|
enableDropToResize: false,
|
|
textAlign: PlutoColumnTextAlign.center,
|
|
titleTextAlign: PlutoColumnTextAlign.center,
|
|
);
|
|
}).toList();
|
|
|
|
late List<PlutoColumn> columns = <PlutoColumn>[
|
|
PlutoColumn(
|
|
title: 'DATE',
|
|
field: 'date',
|
|
type: PlutoColumnType.text(),
|
|
readOnly: true,
|
|
width: 70,
|
|
enableContextMenu: false,
|
|
enableDropToResize: false,
|
|
textAlign: PlutoColumnTextAlign.center,
|
|
titleTextAlign: PlutoColumnTextAlign.center,
|
|
frozen: PlutoColumnFrozen.start,
|
|
),
|
|
PlutoColumn(
|
|
title: 'DAY',
|
|
field: 'day',
|
|
type: PlutoColumnType.text(),
|
|
readOnly: true,
|
|
width: 53,
|
|
enableContextMenu: false,
|
|
enableDropToResize: false,
|
|
),
|
|
] +
|
|
hourCols +
|
|
[
|
|
PlutoColumn(
|
|
title: 'Mood',
|
|
field: 'mood',
|
|
width: 60,
|
|
textAlign: PlutoColumnTextAlign.center,
|
|
type: PlutoColumnType.text(),
|
|
enableContextMenu: false,
|
|
enableDropToResize: false,
|
|
),
|
|
PlutoColumn(
|
|
title: 'Comments',
|
|
field: 'comments',
|
|
type: PlutoColumnType.text(),
|
|
enableContextMenu: false,
|
|
enableDropToResize: false,
|
|
),
|
|
];
|
|
|
|
late List<PlutoRow> rows = entries!.map((e) {
|
|
var cells = {
|
|
'date': PlutoCell(
|
|
value: formatDate(
|
|
format: "MM/DD",
|
|
dateISO: e.data['date'],
|
|
),
|
|
),
|
|
'day': PlutoCell(
|
|
value: formatDate(
|
|
format: "E",
|
|
dateISO: e.data['date'],
|
|
),
|
|
),
|
|
'mood': PlutoCell(value: e.data['mood']),
|
|
'comments': PlutoCell(value: e.data['comments']),
|
|
};
|
|
var hours = <String, PlutoCell>{};
|
|
for (int i = 0; i < 24; i++) {
|
|
hours.putIfAbsent(
|
|
"hours[$i]",
|
|
() => PlutoCell(
|
|
value: e.data['hours'][i],
|
|
),
|
|
);
|
|
}
|
|
cells.addEntries(hours.entries);
|
|
|
|
return PlutoRow(
|
|
cells: cells,
|
|
);
|
|
}).toList();
|
|
|
|
/// columnGroups that can group columns can be omitted.
|
|
final List<PlutoColumnGroup> columnGroups = [];
|
|
|
|
/// [PlutoGridStateManager] has many methods and properties to dynamically manipulate the grid.
|
|
/// You can manipulate the grid dynamically at runtime by passing this through the [onLoaded] callback.
|
|
late final PlutoGridStateManager stateManager;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Padding(
|
|
padding: const EdgeInsets.all(10),
|
|
child: Column(
|
|
children: [
|
|
Expanded(
|
|
child: entries!.isEmpty
|
|
? Center(child: const CircularProgressIndicator())
|
|
: Scaffold(
|
|
body: InteractiveViewer(
|
|
child: PlutoGrid(
|
|
columns: columns,
|
|
rows: rows,
|
|
columnGroups: columnGroups,
|
|
onLoaded: (PlutoGridOnLoadedEvent event) {
|
|
stateManager = event.stateManager;
|
|
},
|
|
onChanged: (PlutoGridOnChangedEvent event) {
|
|
print(event);
|
|
},
|
|
configuration: const PlutoGridConfiguration.dark(
|
|
style: PlutoGridStyleConfig.dark(
|
|
cellTextStyle: TextStyle(fontFamily: "monospace"),
|
|
rowHeight: 20,
|
|
gridBorderColor: Colors.transparent,
|
|
enableCellBorderHorizontal: false,
|
|
enableCellBorderVertical: false,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
)),
|
|
// Expanded(child: DiagnosticsWidget(entries: entries)),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class DiagnosticsWidget extends StatelessWidget {
|
|
final List<Document>? entries;
|
|
|
|
const DiagnosticsWidget({
|
|
super.key,
|
|
this.entries,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ListView(
|
|
children: [
|
|
ListTile(
|
|
leading: Icon(Icons.date_range_outlined),
|
|
title: Text("Entries"),
|
|
subtitle: Text("${entries?.length}"),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class TableWidget extends StatelessWidget {
|
|
TableWidget({super.key, this.entries});
|
|
|
|
final List<Document>? entries;
|
|
|
|
final DateFormat dateFormatter = DateFormat('MM/dd');
|
|
final DateFormat dayFormatter = DateFormat('E');
|
|
|
|
final List<PlutoColumn> columns = [];
|
|
|
|
final List<PlutoRow> rows = [];
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Text("moot");
|
|
}
|
|
}
|
|
|
|
class SpreadsheetWidget extends StatelessWidget {
|
|
SpreadsheetWidget({super.key, this.entries});
|
|
|
|
final List<Document>? entries;
|
|
|
|
final DateFormat dateFormatter = DateFormat('MM/dd');
|
|
final DateFormat dayFormatter = DateFormat('E');
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return SpreadsheetTable(
|
|
cellWidth: 80,
|
|
rowsCount: entries!.length,
|
|
colCount: 27,
|
|
cellBuilder: (_, int row, int col) {
|
|
var entry = entries?[row];
|
|
var date = DateTime.parse(entry?.data['date']);
|
|
var day = dayFormatter.format(date);
|
|
|
|
List hours = entry?.data['hours'];
|
|
|
|
if (col == 0) {
|
|
return Center(child: Text(day));
|
|
} else if (col > 0 && col < 25) {
|
|
return Center(child: Text(hours[col - 1].toString()));
|
|
} else {
|
|
return Center(child: Text(''));
|
|
}
|
|
},
|
|
legendBuilder: (_) => Center(child: Text("Date".toUpperCase())),
|
|
colHeaderBuilder: (_, index) {
|
|
var cellText = "";
|
|
if (index == 0) {
|
|
cellText = "Day";
|
|
} else if (index == 1) {
|
|
cellText = "12 AM";
|
|
} else if (index > 1 && index < 25) {
|
|
var meridien = "AM";
|
|
var hour = index - 1;
|
|
if (index > 12) {
|
|
meridien = "PM";
|
|
}
|
|
if (index > 13) {
|
|
hour = hour - 12;
|
|
}
|
|
cellText = "${hour.toString()} $meridien";
|
|
} else if (index == 25) {
|
|
cellText = "Mood";
|
|
} else if (index == 26) {
|
|
cellText = "Comments";
|
|
}
|
|
return Center(child: Text(cellText.toUpperCase()));
|
|
},
|
|
rowHeaderBuilder: (_, index) {
|
|
var date = DateTime.parse(entries![index].data["date"]);
|
|
var formattedDate = dateFormatter.format(date);
|
|
return Center(child: Text(formattedDate));
|
|
},
|
|
);
|
|
}
|
|
}
|