ft/adds persistence (partial complete)

TODO: Load on start. Not working atm.
This commit is contained in:
itsscb 2023-10-29 23:58:06 +01:00
parent 5bd03eab7c
commit dc3a28ba5f
9 changed files with 642 additions and 441 deletions

View File

@ -0,0 +1,150 @@
import 'dart:async';
import 'package:fixnum/fixnum.dart';
import 'package:app/pb/google/protobuf/timestamp.pb.dart';
import 'package:flutter/services.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class Session {
Session({
this.sessionId,
this.accessToken,
this.accessTokenExpiresAt,
this.refreshToken,
this.refreshTokenExpiresAt,
this.accountId,
}) {
_init();
}
String? sessionId;
String? accessToken;
String? refreshToken;
Timestamp? accessTokenExpiresAt;
Timestamp? refreshTokenExpiresAt;
Int64? accountId;
late Database _database;
Future<Database> get database async => _database;
static Future<Session> get newSession async {
final Database db = await openDatabase(
join(await getDatabasesPath(), 'df_database.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE sessions(accountId INTEGER PRIMARY KEY, sessionId TEXT, accessToken TEXT, accessTokenExpiresAt TEXT, refreshToken TEXT, refreshTokenExpiresAt TEXT)',
);
},
version: 1,
);
Session s = Session();
s._database = db;
return s;
}
void _init() {
_initDatabase();
}
Future<Database> _initDatabase() async {
print('DB: INITIALIZING - start');
_database = await openDatabase(
join(await getDatabasesPath(), 'df_database.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE sessions(accountId INTEGER PRIMARY KEY, sessionId TEXT, accessToken TEXT, accessTokenExpiresAt TEXT, refreshToken TEXT, refreshTokenExpiresAt TEXT)',
);
},
version: 1,
);
print('DB: INITIALIZING - end');
return _database;
}
Map<String, dynamic> toMap() {
return {
'accountId': accountId?.toInt(),
'sessionId': sessionId,
'accessToken': accessToken,
'accessTokenExpiresAt': accessTokenExpiresAt?.toDateTime().toString(),
'refreshToken': refreshToken,
'refreshTokenExpiresAt': refreshTokenExpiresAt?.toDateTime().toString(),
};
}
@override
String toString() {
return 'Session{accountId: $accountId, sessionId: $sessionId, accessToken: $accessToken, accessTokenExpiresAt: ${accessTokenExpiresAt.toString()}, refreshToken: $refreshToken, refreshTokenExpiresAt: ${refreshTokenExpiresAt.toString()}}';
}
Future<void> insertSession(Session session) async {
print('INSERTING SESSION: ${session.sessionId}');
final db = _database;
final result = await db.insert(
'sessions',
session.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
print('INSERT RESULT: $result');
}
Future<List<Session>> getSessions() async {
final db = await database;
final List<Map<String, Object?>> maps = await db.query('sessions');
final List<Session> sessions = List.generate(
maps.length,
(i) {
print('GOT MAP: ${maps[i]}');
return Session(
sessionId: maps[i]['sessionId'] as String,
accessToken: maps[i]['accessToken'] as String,
accessTokenExpiresAt: Timestamp.fromDateTime(
DateTime.parse(maps[i]['accessTokenExpiresAt'] as String)),
refreshToken: maps[i]['refreshToken'] as String,
refreshTokenExpiresAt: Timestamp.fromDateTime(
DateTime.parse(maps[i]['refreshTokenExpiresAt'] as String)),
accountId: Int64(maps[i]['accountId'] as int),
);
},
);
return sessions;
}
static Future<Session> getSession(Int64 accountId) async {
final Database db = await openDatabase(
join(await getDatabasesPath(), 'df_database.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE sessions(accountId INTEGER PRIMARY KEY, sessionId TEXT, accessToken TEXT, accessTokenExpiresAt TEXT, refreshToken TEXT, refreshTokenExpiresAt TEXT)',
);
},
version: 1,
);
final List<Map<String, Object?>> maps = await db.query('sessions',
where: 'accountId = ?', whereArgs: [accountId], limit: 1);
final List<Session> sessions = List.generate(
maps.length,
(i) {
return Session(
sessionId: maps[i]['sessionId'] as String,
accessToken: maps[i]['accessToken'] as String,
accessTokenExpiresAt: maps[i]['accessTokenExpiresAt'] as Timestamp,
refreshToken: maps[i]['refreshToken'] as String,
refreshTokenExpiresAt: maps[i]['refreshTokenExpiresAt'] as Timestamp,
accountId: maps[i]['accountId'] as Int64,
);
},
);
return sessions[0];
}
}

View File

@ -1,3 +1,4 @@
import 'package:app/data/database.dart';
import 'package:fixnum/fixnum.dart';
import 'package:app/pb/rpc_create_account.pb.dart';
import 'package:app/pb/rpc_get_account_info.pb.dart';
@ -6,12 +7,28 @@ import 'package:app/pb/service_df.pbgrpc.dart';
import 'package:grpc/grpc.dart';
class GClient {
GClient() {
// session = Session.newSession();
_init();
}
String baseUrl = 'localhost';
int port = 9090;
Map<String, String> metadata = {'Authorization': ''};
String accessToken = '';
Int64 accountId = Int64();
// String accessToken = '';
// Int64 accountId = Int64();
late Session session;
static Future<GClient> get client async {
Session s = await Session.newSession;
GClient c = GClient();
c.session = s;
final sessions = await c.session.getSessions();
c.session = sessions[0];
return c;
}
dfClient stub = dfClient(
ClientChannel('10.0.2.2',
@ -25,6 +42,19 @@ class GClient {
);
Future<void> main(List<String> args) async {}
void _init() async {
// print('CLIENT: INITIALIZING CLIENT - start');
session = await Session.newSession;
// print('CLIENT: getting sessions from database');
final sessions = await session.getSessions();
print('CLIENT: got sessions from database: ${sessions.toString()}');
session = sessions[0];
// print('CLIENT: INITIALIZING CLIENT - end');
print(session.toString());
}
Future<CreateAccountResponse> createAccount(
CreateAccountRequest request) async {
try {
@ -47,8 +77,19 @@ class GClient {
email: email,
password: password,
));
accessToken = response.accessToken;
accountId = response.accountId;
print(response);
session.accessToken = response.accessToken;
session.accountId = response.accountId;
session.sessionId = response.sessionId;
session.refreshToken = response.refreshToken;
session.accessTokenExpiresAt = response.accessTokenExpiresAt;
session.refreshTokenExpiresAt = response.refreshTokenExpiresAt;
print('GOT: ${session.toString()}');
try {
session.insertSession(session);
} catch (err) {
print('ERROR WRITING DB: $err');
}
metadata['Authorization'] = 'Bearer ${response.accessToken}';
print('auth: ${metadata['Authorization']}');
onSuccess();

View File

@ -1,4 +1,3 @@
import 'package:app/pages/home_page.dart';
import 'package:app/pages/start_page.dart';
import 'package:app/widgets/background.dart';
import 'package:flutter/material.dart';

View File

@ -5,29 +5,8 @@ import 'package:app/widgets/background.dart';
import 'package:app/widgets/loading_widget.dart';
import 'package:flutter/material.dart';
GlobalKey<ScaffoldState> scaffolKey = GlobalKey<ScaffoldState>();
List<BottomNavigationBarItem> bottomBarButtons = const [
BottomNavigationBarItem(
label: 'Zurueck',
backgroundColor: Colors.white,
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'AccountInf',
icon: Icon(
Icons.person,
color: Colors.white,
),
),
];
class DashboardPage extends StatefulWidget {
DashboardPage({super.key, required this.client});
const DashboardPage({super.key, required this.client});
final GClient client;
@ -48,15 +27,15 @@ class _DashboardPageState extends State<DashboardPage> {
@override
void initState() {
super.initState();
if (widget.client.accessToken == '') {
Navigator.of(context).pop();
return;
}
// if (widget.client.session.accessToken == '') {
// Navigator.of(context).pop();
// return;
// }
_setLoading(true);
widget.client.getAccountInfo(
GetAccountInfoRequest(
accountId: widget.client.accountId,
accountId: widget.client.session?.accountId,
),
onError: () {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
@ -73,7 +52,6 @@ class _DashboardPageState extends State<DashboardPage> {
Widget build(BuildContext context) {
return Background(
child: Scaffold(
key: scaffolKey,
appBar: AppBar(
automaticallyImplyLeading: false,
flexibleSpace: Image.asset(
@ -81,10 +59,7 @@ class _DashboardPageState extends State<DashboardPage> {
height: 80,
),
),
bottomNavigationBar: BottomNavigationBar(
items: bottomBarButtons,
backgroundColor: Colors.black,
),
bottomNavigationBar: BottomBar(),
body: !_loading
? Background(
child: Center(
@ -108,3 +83,40 @@ class _DashboardPageState extends State<DashboardPage> {
);
}
}
class BottomBar extends StatelessWidget {
const BottomBar({
super.key,
});
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
items: [
BottomNavigationBarItem(
label: 'back',
backgroundColor: Colors.white,
icon: IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(
Icons.arrow_back,
color: Colors.white,
),
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.person,
color: Colors.white,
),
),
),
],
backgroundColor: Colors.black,
);
}
}

View File

@ -1,158 +0,0 @@
import 'package:app/gapi/client.dart';
import 'package:app/pages/login_page.dart';
import 'package:app/pages/start_page.dart';
import 'package:flutter/material.dart';
import 'package:app/pages/pages.dart';
Map<Pages, List<BottomNavigationBarItem>> bottomBarButtons = {
Pages.start: const [
BottomNavigationBarItem(
label: 'Zurueck',
backgroundColor: Colors.white,
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'AccountInf',
icon: Icon(
Icons.person,
color: Colors.white,
),
),
],
Pages.persons: const [
BottomNavigationBarItem(
label: 'Zurueck',
backgroundColor: Colors.white,
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'AccountInf',
icon: Icon(
Icons.person,
color: Colors.white,
),
),
],
Pages.about: const [
BottomNavigationBarItem(
label: 'Zurueck',
backgroundColor: Colors.white,
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'AccountInf',
icon: Icon(
Icons.person,
color: Colors.white,
),
),
],
Pages.login: const [
BottomNavigationBarItem(
label: 'Zurueck',
backgroundColor: Colors.white,
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'AccountInf',
icon: Icon(
Icons.person,
color: Colors.white,
),
),
]
};
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool _loading = false;
Pages _selectedPage = Pages.start;
Widget _selectPage(Pages page) {
switch (page) {
case Pages.login:
return LoginPage(
// onChangePage: changePage,
);
default:
return StartPage(
// onChangePage: changePage,
);
}
}
Future<bool> _onWillPop() async {
changePage(Pages.start);
return false;
}
void changePage(Pages page) {
if (!Pages.values.contains(page)) {
page = _selectedPage;
}
setState(() {
_selectedPage = page;
});
}
void _setLoading(bool loading) {
setState(() {
_loading = loading;
});
}
final GClient client = GClient();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _selectedPage == Pages.start
? AppBar(
automaticallyImplyLeading: false,
)
: AppBar(
automaticallyImplyLeading: false,
flexibleSpace: Image.asset(
'lib/assets/logo_300x200.png',
height: 80,
),
),
bottomNavigationBar: BottomNavigationBar(
items: bottomBarButtons[_selectedPage]!.toList(),
backgroundColor: Colors.black,
),
body: Container(
padding: const EdgeInsets.fromLTRB(16, 32, 16, 32),
child: Center(
child: WillPopScope(
child: _selectPage(_selectedPage),
onWillPop: () => _onWillPop(),
),
),
),
);
}
}

View File

@ -5,29 +5,7 @@ import 'package:app/widgets/loading_widget.dart';
import 'package:flutter/material.dart';
import 'package:grpc/grpc.dart';
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
List<BottomNavigationBarItem> bottomBarButtons = [
const BottomNavigationBarItem(
label: 'back',
backgroundColor: Colors.white,
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => scaffoldKey.currentState!.openDrawer(),
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
),
];
// GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
class LoginPage extends StatefulWidget {
LoginPage({
@ -43,16 +21,46 @@ class LoginPage extends StatefulWidget {
class _LoginPageState extends State<LoginPage> {
bool _loading = false;
final List<BottomNavigationBarItem> bottombarButtons = [];
List<BottomNavigationBarItem> _selectedBottomBarButtons = bottomBarButtons;
// List<BottomNavigationBarItem> _selectedBottomBarButtons = bottomBarButtons;
@override
void initState() {
super.initState();
_addBottomBarButtons();
}
void _bottomBarAction(int index) {
switch (_selectedBottomBarButtons[index].label?.toLowerCase()) {
switch (bottombarButtons[index].label?.toLowerCase()) {
case 'back':
Navigator.of(context).pop();
}
}
void _addBottomBarButtons() {
bottombarButtons.addAll([
const BottomNavigationBarItem(
label: 'back',
backgroundColor: Colors.white,
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
),
]);
}
void _setLoading(bool loading) {
setState(() {
_loading = loading;
@ -69,7 +77,6 @@ class _LoginPageState extends State<LoginPage> {
Widget build(BuildContext context) {
return Background(
child: Scaffold(
key: scaffoldKey,
appBar: AppBar(
automaticallyImplyLeading: false,
// flexibleSpace: Image.asset(
@ -77,81 +84,8 @@ class _LoginPageState extends State<LoginPage> {
// height: 80,
// ),
),
bottomNavigationBar: BottomNavigationBar(
items: bottomBarButtons,
backgroundColor: Colors.black,
fixedColor: Colors.black,
onTap: (value) => _bottomBarAction(value),
),
drawer: Drawer(
backgroundColor: Colors.black,
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Spacer(),
TextButton(
onPressed: () {
scaffoldKey.currentState!.closeDrawer();
},
child: const Row(
children: [
Text(
'About',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.question_answer,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
scaffoldKey.currentState!.closeDrawer();
},
child: const Row(
children: [
Text(
'Datenschutz',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.privacy_tip,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
scaffoldKey.currentState!.closeDrawer();
},
child: const Row(
children: [
Text(
'Impressum',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.apartment,
color: Colors.white,
),
],
),
),
const SizedBox(
height: 250,
)
],
),
),
),
bottomNavigationBar: const BottomBar(),
drawer: const SideDrawer(),
body: !_loading
? Form(
key: _formKey,
@ -227,7 +161,7 @@ class _LoginPageState extends State<LoginPage> {
return null;
},
),
SizedBox(
const SizedBox(
height: 15,
),
ElevatedButton(
@ -322,3 +256,121 @@ class _LoginPageState extends State<LoginPage> {
);
}
}
class SideDrawer extends StatelessWidget {
const SideDrawer({
super.key,
});
@override
Widget build(BuildContext context) {
return Drawer(
backgroundColor: Colors.black,
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Spacer(),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'About',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.question_answer,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Datenschutz',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.privacy_tip,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Impressum',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.apartment,
color: Colors.white,
),
],
),
),
const SizedBox(
height: 250,
)
],
),
),
);
}
}
class BottomBar extends StatelessWidget {
const BottomBar({
super.key,
});
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
items: [
BottomNavigationBarItem(
label: 'back',
backgroundColor: Colors.white,
icon: IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(
Icons.arrow_back,
color: Colors.white,
),
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
),
],
backgroundColor: Colors.black,
fixedColor: Colors.black,
// onTap: (value) => _bottomBarAction(value),
);
}
}

View File

@ -4,170 +4,41 @@ import 'package:app/widgets/background.dart';
import 'package:flutter/material.dart';
import 'dart:core';
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
List<BottomNavigationBarItem> bottomBarButtons = [
const BottomNavigationBarItem(
label: 'register',
backgroundColor: Colors.white,
icon: Column(
children: [
Icon(
Icons.person_add,
color: Colors.white,
),
Text(
'Registrieren',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
)
],
),
),
const BottomNavigationBarItem(
label: 'login',
backgroundColor: Colors.white,
icon: Column(
children: [
Icon(
Icons.login,
color: Colors.white,
),
Text(
'Login',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
)
],
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => scaffoldKey.currentState!.openDrawer(),
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
),
];
class StartPage extends StatefulWidget {
StartPage({
super.key,
this.client,
});
final GClient? client;
GClient? client;
@override
State<StartPage> createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
List<BottomNavigationBarItem> _selectedBottomBarButtons = bottomBarButtons;
// List<BottomNavigationBarItem> _selectedBottomBarButtons = bottomBarButtons;
final List<BottomNavigationBarItem> bottombarButtons = [];
void _bottomBarAction(int index) {
switch (_selectedBottomBarButtons[index].label?.toLowerCase()) {
case 'login':
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => LoginPage()));
}
void _init() async {
widget.client ??= await GClient.client;
}
@override
void initState() {
_init();
super.initState();
}
@override
Widget build(BuildContext context) {
return Background(
child: Scaffold(
key: scaffoldKey,
appBar: AppBar(
automaticallyImplyLeading: false,
// flexibleSpace: Image.asset(
// 'lib/assets/logo_300x200.png',
// height: 80,
// ),
),
drawer: Drawer(
backgroundColor: Colors.black,
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Spacer(),
TextButton(
onPressed: () {
scaffoldKey.currentState!.closeDrawer();
},
child: const Row(
children: [
Text(
'About',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.question_answer,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
scaffoldKey.currentState!.closeDrawer();
},
child: const Row(
children: [
Text(
'Datenschutz',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.privacy_tip,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
scaffoldKey.currentState!.closeDrawer();
},
child: const Row(
children: [
Text(
'Impressum',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.apartment,
color: Colors.white,
),
],
),
),
const SizedBox(
height: 250,
)
],
),
),
),
bottomNavigationBar: BottomNavigationBar(
onTap: (value) => _bottomBarAction(value),
items: bottomBarButtons,
backgroundColor: Colors.black,
fixedColor: Colors.black,
),
drawer: const SideDrawer(),
bottomNavigationBar: BottomBar(widget: widget),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
@ -192,6 +63,16 @@ class _StartPageState extends State<StartPage> {
letterSpacing: 6,
),
),
TextButton(
onPressed: () {
final s = widget.client?.session.getSessions();
print(s);
print(widget.client?.session.accessToken);
},
child: const Text(
"GET SESSIONS",
),
),
// const Spacer(),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@ -238,3 +119,199 @@ class _StartPageState extends State<StartPage> {
);
}
}
class SideDrawer extends StatelessWidget {
const SideDrawer({
super.key,
});
@override
Widget build(BuildContext context) {
return Drawer(
backgroundColor: Colors.black,
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Spacer(),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'About',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.question_answer,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Datenschutz',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.privacy_tip,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Impressum',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.apartment,
color: Colors.white,
),
],
),
),
const SizedBox(
height: 250,
)
],
),
),
);
}
}
class BottomBar extends StatelessWidget {
const BottomBar({
super.key,
required this.widget,
});
final StartPage widget;
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
// onTap: (value) => _bottomBarAction(value),
items: widget.client?.session.accessToken != null
? [
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Personen',
icon: Column(
children: [
IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.group,
color: Colors.white,
),
),
const Text(
'Personen',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
)
],
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
)
]
: [
BottomNavigationBarItem(
label: 'register',
backgroundColor: Colors.white,
icon: Column(
children: [
IconButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => LoginPage()));
},
icon: const Icon(
Icons.login,
color: Colors.white,
),
),
const Text(
'Registrieren',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
)
],
),
),
BottomNavigationBarItem(
label: 'login',
backgroundColor: Colors.white,
icon: Column(
children: [
IconButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => LoginPage()));
},
icon: const Icon(
Icons.login,
color: Colors.white,
),
),
const Text(
'Login',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
)
],
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
),
],
backgroundColor: Colors.black,
fixedColor: Colors.black,
);
}
}

View File

@ -90,7 +90,7 @@ packages:
source: hosted
version: "1.3.1"
fixnum:
dependency: transitive
dependency: "direct main"
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
@ -196,7 +196,7 @@ packages:
source: hosted
version: "1.9.1"
path:
dependency: transitive
dependency: "direct main"
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
@ -232,6 +232,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.10.0"
sqflite:
dependency: "direct main"
description:
name: sqflite
sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a"
url: "https://pub.dev"
source: hosted
version: "2.5.0"
stack_trace:
dependency: transitive
description:
@ -256,6 +272,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
synchronized:
dependency: transitive
description:
name: synchronized
sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
term_glyph:
dependency: transitive
description:
@ -298,3 +322,4 @@ packages:
version: "0.1.4-beta"
sdks:
dart: ">=3.1.4 <4.0.0"
flutter: ">=3.3.0"

View File

@ -39,6 +39,9 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
grpc: ^3.2.4
sqflite: ^2.3.0
path: ^1.8.3
fixnum: ^1.1.0
dev_dependencies:
lints: ^2.0.0