Categories page works!
This commit is contained in:
parent
0dd56cfaa6
commit
c9c3f69886
@ -1,30 +1,63 @@
|
||||
import 'package:appwrite/appwrite.dart';
|
||||
import 'package:appwrite/models.dart';
|
||||
import 'package:ltx_flutter/constants/constants.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:ltx_flutter/appwrite/appwrite.dart';
|
||||
import 'package:ltx_flutter/constants/colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Category {
|
||||
late final Color backgroundColor;
|
||||
late final Color foregroundColor;
|
||||
late final num number;
|
||||
late final num? parent;
|
||||
late final String name;
|
||||
late final String? description;
|
||||
|
||||
Category(Document doc) {
|
||||
backgroundColor = _getBackgroundColor(doc.data['color']);
|
||||
foregroundColor = _getForegroundColor(doc.data['color']);
|
||||
number = doc.data['number'];
|
||||
parent = doc.data['parent'];
|
||||
name = doc.data['name'];
|
||||
description = doc.data['description'];
|
||||
}
|
||||
|
||||
Color _getBackgroundColor(String colorStr) {
|
||||
return Color(int.parse("0xff$colorStr"));
|
||||
}
|
||||
|
||||
Color _getForegroundColor(String colorStr) {
|
||||
return Color(int.parse("0xff$colorStr")).computeLuminance() > 0.5
|
||||
? Colors.black
|
||||
: Colors.white;
|
||||
}
|
||||
|
||||
bool hasParent() {
|
||||
return parent == number ? false : true;
|
||||
}
|
||||
|
||||
double leftPadding() {
|
||||
return hasParent() ? 50.0 : 20.0;
|
||||
}
|
||||
}
|
||||
|
||||
class CategoriesAPI extends ChangeNotifier {
|
||||
Client client = Client();
|
||||
late final Account account;
|
||||
late final Databases databases;
|
||||
late final String userId;
|
||||
final AuthAPI auth = AuthAPI();
|
||||
late List<Document> _categories = [];
|
||||
|
||||
// Constructor
|
||||
CategoriesAPI() {
|
||||
init();
|
||||
getCategories();
|
||||
}
|
||||
|
||||
// loadUser() async {
|
||||
// try {
|
||||
// user = await account.get();
|
||||
// notifyListeners();
|
||||
// } catch (e) {
|
||||
// print(e);
|
||||
// notifyListeners();
|
||||
// }
|
||||
// }
|
||||
// Getters
|
||||
get total => _categories.length;
|
||||
get all => _categories;
|
||||
get isEmpty => _categories.isEmpty;
|
||||
get(n) => Category(_categories[n]);
|
||||
get colors => CategoryColor.values;
|
||||
|
||||
init() {
|
||||
client.setEndpoint(APPWRITE_URL).setProject(APPWRITE_PROJECT_ID);
|
||||
@ -32,24 +65,29 @@ class CategoriesAPI extends ChangeNotifier {
|
||||
databases = Databases(client);
|
||||
}
|
||||
|
||||
Future<DocumentList> getCategories() {
|
||||
print("Getting categories");
|
||||
return databases.listDocuments(
|
||||
getCategories() async {
|
||||
print("Updating categories.");
|
||||
_categories = [];
|
||||
var response = await databases.listDocuments(
|
||||
databaseId: CATEGORIES_DB,
|
||||
collectionId: COLLECTION,
|
||||
queries: [
|
||||
Query.orderAsc("parent"),
|
||||
Query.orderAsc("number"),
|
||||
]);
|
||||
_categories = response.documents;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<Document> addCategory({
|
||||
Future<Document>? addCategory({
|
||||
required String name,
|
||||
required double number,
|
||||
required String color,
|
||||
String? description,
|
||||
int? parentId,
|
||||
}) {
|
||||
return databases.createDocument(
|
||||
}) async {
|
||||
try {
|
||||
return await databases.createDocument(
|
||||
databaseId: CATEGORIES_DB,
|
||||
collectionId: COLLECTION,
|
||||
documentId: "category-${number.toString()}",
|
||||
@ -60,6 +98,12 @@ class CategoriesAPI extends ChangeNotifier {
|
||||
'parent': parentId,
|
||||
'description': description,
|
||||
});
|
||||
} catch (e) {
|
||||
print(e);
|
||||
throw "Didn't work";
|
||||
} finally {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> deleteCategory({required double number}) {
|
||||
|
||||
@ -1,19 +1,28 @@
|
||||
import 'package:appwrite/appwrite.dart';
|
||||
import 'package:appwrite/models.dart';
|
||||
import 'package:ltx_flutter/appwrite/appwrite.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:ltx_flutter/appwrite/auth_api.dart';
|
||||
import 'package:ltx_flutter/constants/constants.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class DatabaseAPI {
|
||||
class DatabaseAPI extends ChangeNotifier {
|
||||
Client client = Client();
|
||||
late final Account account;
|
||||
late final Databases databases;
|
||||
final AuthAPI auth = AuthAPI();
|
||||
|
||||
late List<Document> _entries = [];
|
||||
|
||||
// Getter methods
|
||||
List<Document> get entries => _entries;
|
||||
int? get total => _entries.length;
|
||||
|
||||
final DateFormat formatter = DateFormat('yyyy-MM-dd');
|
||||
|
||||
// Constructor
|
||||
DatabaseAPI() {
|
||||
init();
|
||||
getEntries();
|
||||
}
|
||||
|
||||
init() {
|
||||
@ -25,7 +34,7 @@ class DatabaseAPI {
|
||||
databases = Databases(client);
|
||||
}
|
||||
|
||||
Future<DocumentList> getEntries({int limit = 100, String dateISO = ""}) {
|
||||
getEntries({int limit = 100, String dateISO = ""}) async {
|
||||
if (dateISO == "") {
|
||||
dateISO = DateTime.now().toIso8601String();
|
||||
}
|
||||
@ -37,7 +46,7 @@ class DatabaseAPI {
|
||||
|
||||
print("Getting $limit entries starting from $offset");
|
||||
|
||||
return databases.listDocuments(
|
||||
var response = await databases.listDocuments(
|
||||
databaseId: APPWRITE_DATABASE_ID,
|
||||
collectionId: COLLECTION,
|
||||
queries: [
|
||||
@ -45,6 +54,8 @@ class DatabaseAPI {
|
||||
Query.offset(offset),
|
||||
Query.limit(limit),
|
||||
]);
|
||||
_entries = response.documents;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<Document> addEntry(
|
||||
|
||||
33
ltx_flutter/lib/constants/colors.dart
Normal file
33
ltx_flutter/lib/constants/colors.dart
Normal file
@ -0,0 +1,33 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
enum CategoryColor {
|
||||
black("273036"),
|
||||
blue("00a9b3"),
|
||||
red("c71634"),
|
||||
darkred("ff2816"),
|
||||
lime("bfff55"),
|
||||
green("189749"),
|
||||
pink("ff65ae"),
|
||||
purple("5b3ab1"),
|
||||
cyan("005744"),
|
||||
orange("ff6d01"),
|
||||
yellow("fff336");
|
||||
|
||||
const CategoryColor(this.hex);
|
||||
|
||||
final String hex;
|
||||
|
||||
name() {
|
||||
return this.toString().split('.').last;
|
||||
}
|
||||
|
||||
backgroundColor() {
|
||||
return Color(int.parse("0xff$hex"));
|
||||
}
|
||||
|
||||
foregroundColor() {
|
||||
return Color(int.parse("0xff$hex")).computeLuminance() > 0.3
|
||||
? Colors.black
|
||||
: Colors.white;
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,19 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:ltx_flutter/pages/tabs_page.dart';
|
||||
import 'package:ltx_flutter/appwrite/appwrite.dart';
|
||||
import 'package:ltx_flutter/appwrite/auth_api.dart';
|
||||
import 'package:ltx_flutter/appwrite/database_api.dart';
|
||||
import 'package:ltx_flutter/appwrite/categories_api.dart';
|
||||
import 'package:ltx_flutter/pages/login_page.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
void main() {
|
||||
runApp(ChangeNotifierProvider(
|
||||
create: (context) => AuthAPI(),
|
||||
runApp(MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (context) => AuthAPI()),
|
||||
ChangeNotifierProvider(create: (context) => DatabaseAPI()),
|
||||
ChangeNotifierProvider(create: (context) => CategoriesAPI()),
|
||||
],
|
||||
child: LifetrackerApp(),
|
||||
));
|
||||
}
|
||||
@ -16,19 +23,22 @@ class LifetrackerApp extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final value = context.watch<AuthAPI>().status;
|
||||
print('TOP CHANGE Value changed to: $value!');
|
||||
|
||||
final loginStatus = context.watch<AuthAPI>().status;
|
||||
return MaterialApp(
|
||||
scrollBehavior: const MaterialScrollBehavior().copyWith(dragDevices: {
|
||||
PointerDeviceKind.mouse,
|
||||
PointerDeviceKind.touch,
|
||||
PointerDeviceKind.trackpad,
|
||||
}),
|
||||
title: 'Lifetracker',
|
||||
theme: ThemeData.from(
|
||||
colorScheme: ColorScheme.dark(),
|
||||
),
|
||||
home: value == AuthStatus.uninitialized
|
||||
home: loginStatus == AuthStatus.uninitialized
|
||||
? const Scaffold(
|
||||
body: Center(child: CircularProgressIndicator()),
|
||||
)
|
||||
: value == AuthStatus.authenticated
|
||||
: loginStatus == AuthStatus.authenticated
|
||||
? const TabsPage()
|
||||
: LoginPage());
|
||||
// DefaultTabController(
|
||||
@ -55,88 +65,3 @@ class LifetrackerApp extends StatelessWidget {
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
class AccountPage extends StatefulWidget {
|
||||
const AccountPage({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
AccountPageState createState() {
|
||||
return AccountPageState();
|
||||
}
|
||||
}
|
||||
|
||||
class AccountPageState extends State<AccountPage> {
|
||||
final _loginFormKey = GlobalKey<FormState>();
|
||||
String email = "";
|
||||
String password = "";
|
||||
|
||||
void _logIn(context) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Logging in...')),
|
||||
);
|
||||
// client.login(email, password);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(30.0),
|
||||
child: Form(
|
||||
key: _loginFormKey,
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: TextFormField(
|
||||
obscureText: false,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Email',
|
||||
),
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
onChanged: (value) => setState(() {
|
||||
email = value;
|
||||
}),
|
||||
)),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: TextFormField(
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Password',
|
||||
),
|
||||
keyboardType: TextInputType.visiblePassword,
|
||||
onChanged: (value) => setState(() {
|
||||
password = value;
|
||||
}),
|
||||
)),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
onPressed: () {
|
||||
_logIn(context);
|
||||
},
|
||||
icon: Icon(Icons.login),
|
||||
label: Text("Log in")),
|
||||
Column(
|
||||
children: <Widget>[
|
||||
email.isEmpty ? Text("No data") : Text(email),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
password.isEmpty ? Text("No Data") : Text(password),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:ltx_flutter/appwrite/auth_api.dart';
|
||||
import 'package:ltx_flutter/appwrite/database_api.dart';
|
||||
import 'package:ltx_flutter/appwrite/categories_api.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class AccountPage extends StatefulWidget {
|
||||
const AccountPage({Key? key}) : super(key: key);
|
||||
@ -10,8 +14,47 @@ class AccountPage extends StatefulWidget {
|
||||
class _AccountPageState extends State<AccountPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Center(child: Text("Account")),
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: [
|
||||
Card(
|
||||
child: Consumer<AuthAPI>(builder: (context, account, child) {
|
||||
return ListTile(
|
||||
leading: Icon(Icons.person),
|
||||
title: Text("Account"),
|
||||
trailing: Text("${account.username}"),
|
||||
);
|
||||
}),
|
||||
),
|
||||
Card(
|
||||
child:
|
||||
Consumer<DatabaseAPI>(builder: (context, entries, child) {
|
||||
return ListTile(
|
||||
leading: Icon(Icons.edit_note),
|
||||
title: Text("Entries"),
|
||||
trailing: Text("${entries.total}"),
|
||||
);
|
||||
}),
|
||||
),
|
||||
Card(
|
||||
child: Consumer<CategoriesAPI>(
|
||||
builder: (context, categories, child) {
|
||||
return ListTile(
|
||||
leading: Icon(Icons.category),
|
||||
title: Text("Categories"),
|
||||
trailing: Text("${categories.total}"),
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Placeholder(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import 'package:ltx_flutter/appwrite/categories_api.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:appwrite/models.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
|
||||
class CategoriesPage extends StatefulWidget {
|
||||
const CategoriesPage({Key? key}) : super(key: key);
|
||||
@ -10,53 +12,218 @@ class CategoriesPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CategoriesPageState extends State<CategoriesPage> {
|
||||
final api = CategoriesAPI();
|
||||
late List<Document>? categories = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
loadCategories();
|
||||
}
|
||||
|
||||
Future loadCategories() async {
|
||||
try {
|
||||
final value = await api.getCategories();
|
||||
setState(() {
|
||||
categories = value.documents;
|
||||
});
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: loadCategories,
|
||||
child: Center(
|
||||
child: ListView.builder(
|
||||
itemCount: categories!.length + 1,
|
||||
itemBuilder: (context, index) {
|
||||
if (index >= categories!.length || categories!.isEmpty) {
|
||||
return ListTile(
|
||||
leading: Text("New Category"),
|
||||
);
|
||||
} else {
|
||||
Document? category = categories?[index];
|
||||
Color backgroundColor =
|
||||
Color(int.parse("0x${category!.data['color']}"));
|
||||
Color textColor = backgroundColor.computeLuminance() > 0.2
|
||||
? Colors.black
|
||||
: Colors.white;
|
||||
return ListTile(
|
||||
tileColor: backgroundColor,
|
||||
textColor: textColor,
|
||||
leading: Text(category.data['number'].toString()),
|
||||
title: Text(category.data['name']),
|
||||
return Scaffold(
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => const NewCategoryPage()),
|
||||
).then((value) {
|
||||
setState(() {});
|
||||
}),
|
||||
tooltip: "New Category",
|
||||
child: Icon(Icons.add),
|
||||
),
|
||||
body: Consumer<CategoriesAPI>(builder: (context, categories, child) {
|
||||
return ListView.builder(
|
||||
itemCount: categories.total + 1,
|
||||
itemBuilder: (context, i) {
|
||||
if (i < categories.total) {
|
||||
Category category = categories.get(i);
|
||||
if (!category.hasParent() && category.number != 0) {
|
||||
return Column(
|
||||
children: [
|
||||
Divider(
|
||||
thickness: 1,
|
||||
),
|
||||
CategoryRow(category: category),
|
||||
],
|
||||
);
|
||||
}
|
||||
return CategoryRow(category: category);
|
||||
}
|
||||
},
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryRow extends StatelessWidget {
|
||||
const CategoryRow({
|
||||
super.key,
|
||||
required this.category,
|
||||
});
|
||||
|
||||
final Category category;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Container(
|
||||
color: category.backgroundColor,
|
||||
child: SizedBox.square(
|
||||
dimension: 70,
|
||||
child: Center(
|
||||
child: Text(
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: category.foregroundColor,
|
||||
fontSize: 18,
|
||||
),
|
||||
category.number.toString())),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: category.leftPadding()),
|
||||
child: Text(
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
),
|
||||
category.name,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(15.0),
|
||||
child: Text(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.white38,
|
||||
),
|
||||
"${category.description}",
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NewCategoryPage extends StatefulWidget {
|
||||
const NewCategoryPage({super.key});
|
||||
|
||||
@override
|
||||
State<NewCategoryPage> createState() => _NewCategoryPageState();
|
||||
}
|
||||
|
||||
class _NewCategoryPageState extends State<NewCategoryPage> {
|
||||
String _name = "";
|
||||
final _formKey = GlobalKey<FormBuilderState>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_name = "New Category";
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final CategoriesAPI api = context.watch<CategoriesAPI>();
|
||||
saveCategory(form, context) {
|
||||
var name = form?.fields['categoryName'].value;
|
||||
var number = form?.fields['categoryNumber'].value;
|
||||
var color = form?.fields['categoryColor'].value;
|
||||
var description = form?.fields['categoryDescription'].value;
|
||||
var parent = form?.fields['categoryParent'].value;
|
||||
api.addCategory(
|
||||
name: name,
|
||||
number: double.parse(number),
|
||||
color: color,
|
||||
description: description,
|
||||
parentId: int.parse(parent),
|
||||
);
|
||||
Navigator.pop(context);
|
||||
api.getCategories();
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("New Category"),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.only(left: 50, right: 50),
|
||||
child: Column(
|
||||
children: [
|
||||
FormBuilder(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 25),
|
||||
FormBuilderTextField(
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Number",
|
||||
),
|
||||
name: 'categoryNumber',
|
||||
),
|
||||
SizedBox(height: 25),
|
||||
FormBuilderTextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Name",
|
||||
),
|
||||
name: 'categoryName',
|
||||
),
|
||||
SizedBox(height: 25),
|
||||
Consumer<CategoriesAPI>(
|
||||
builder: (context, categories, child) {
|
||||
print(categories.colors);
|
||||
return FormBuilderDropdown(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Color",
|
||||
),
|
||||
items: [
|
||||
for (var c in categories.colors)
|
||||
DropdownMenuItem(
|
||||
value: c.hex,
|
||||
child: Container(
|
||||
decoration:
|
||||
BoxDecoration(color: c.backgroundColor()),
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Text(
|
||||
c.name(),
|
||||
style: TextStyle(color: c.foregroundColor()),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
name: 'categoryColor',
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(height: 25),
|
||||
FormBuilderTextField(
|
||||
name: 'categoryDescription',
|
||||
decoration: InputDecoration(
|
||||
labelText: "Description",
|
||||
),
|
||||
),
|
||||
SizedBox(height: 25),
|
||||
FormBuilderTextField(
|
||||
keyboardType: TextInputType.number,
|
||||
name: 'categoryParent',
|
||||
decoration: InputDecoration(
|
||||
labelText: "Parent",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 40),
|
||||
OutlinedButton(
|
||||
onPressed: () => saveCategory(_formKey.currentState, context),
|
||||
child: Text("Save"),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import 'package:appwrite/appwrite.dart';
|
||||
import 'package:ltx_flutter/appwrite/appwrite.dart';
|
||||
import 'package:ltx_flutter/appwrite/auth_api.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
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/auth_api.dart';
|
||||
import 'package:ltx_flutter/appwrite/database_api.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:appwrite/models.dart';
|
||||
|
||||
@ -11,7 +11,7 @@ class TabsPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _TabsPageState extends State<TabsPage> {
|
||||
int _selectedIndex = 0;
|
||||
int _selectedIndex = 2;
|
||||
|
||||
static const _widgets = [TodayPage(), CategoriesPage(), AccountPage()];
|
||||
|
||||
@ -25,7 +25,7 @@ class _TabsPageState extends State<TabsPage> {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("LTX Android"),
|
||||
title: Text("Flutter"),
|
||||
),
|
||||
body: _widgets.elementAt(_selectedIndex),
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:ltx_flutter/appwrite/appwrite.dart';
|
||||
import 'dart:math' as math;
|
||||
import 'package:ltx_flutter/appwrite/auth_api.dart';
|
||||
import 'package:ltx_flutter/appwrite/database_api.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -92,6 +93,38 @@ class _TodayPageState extends State<TodayPage> {
|
||||
},
|
||||
).toList()),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
color: Colors.black,
|
||||
child: Row(
|
||||
children: List<int>.generate(10, (i) => i).map(
|
||||
(e) {
|
||||
var generatedColor =
|
||||
math.Random().nextInt(Colors.primaries.length);
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(2.0),
|
||||
child: FilledButton(
|
||||
style: ButtonStyle(
|
||||
shape: MaterialStateProperty.all<
|
||||
RoundedRectangleBorder>(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.zero,
|
||||
side: BorderSide(color: Colors.white))),
|
||||
backgroundColor: MaterialStateProperty.all(
|
||||
Colors.primaries[generatedColor]),
|
||||
),
|
||||
onLongPress: () =>
|
||||
print("Long pressed ${e.toString()}"),
|
||||
onPressed: () => print("Tapped ${e.toString()}"),
|
||||
child: Text(e.toString()),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@ -18,6 +18,7 @@ dependencies:
|
||||
intl: ^0.18.1
|
||||
pluto_grid: ^7.0.2
|
||||
string_to_hex: ^0.2.2
|
||||
flutter_form_builder: ^9.0.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user