integrate app with backend for auth, users, and products

This commit is contained in:
Mikkel Troels Kongsted 2025-03-13 13:22:56 +01:00
parent 7da92bb9a8
commit 70b8244e62
8 changed files with 45 additions and 38 deletions

View File

@ -38,18 +38,16 @@ class SessionController extends ChangeNotifier {
} }
} }
get sessionToken { String? get sessionToken {
return _sessionToken; return _sessionToken;
} }
Future<void> logout() async { Future<void> logout() async {
final token = _sessionToken; final token = _sessionToken;
if (token != null) { if (token != null) {
server.logout(token); await server.logout(token);
_sessionToken = null; _sessionToken = null;
} }
print(_sessionToken);
print("notifying listeners");
notifyListeners(); notifyListeners();
} }

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:mobile/controllers/session.dart'; import 'package:mobile/controllers/session.dart';
import 'package:mobile/models/user.dart';
import 'package:mobile/pages/dashboard.dart'; import 'package:mobile/pages/dashboard.dart';
import 'package:mobile/pages/log_in_page.dart'; import 'package:mobile/pages/log_in_page.dart';
import 'package:mobile/controllers/add_to_cart_state.dart'; import 'package:mobile/controllers/add_to_cart_state.dart';
@ -11,7 +10,7 @@ import 'package:mobile/controllers/paying_state.dart';
import 'package:mobile/controllers/product.dart'; import 'package:mobile/controllers/product.dart';
import 'package:mobile/controllers/receipt.dart'; import 'package:mobile/controllers/receipt.dart';
import 'package:mobile/controllers/user.dart'; import 'package:mobile/controllers/user.dart';
import 'package:mobile/server/mock_server.dart'; import 'package:mobile/server/backend_server.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:mobile/controllers/routing.dart'; import 'package:mobile/controllers/routing.dart';
@ -24,7 +23,7 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final server = MockServer(); final server = BackendServer();
return MultiProvider( return MultiProvider(
providers: [ providers: [
ChangeNotifierProvider(create: (_) => RoutingController()), ChangeNotifierProvider(create: (_) => RoutingController()),
@ -51,7 +50,9 @@ class MyApp extends StatelessWidget {
), ),
home: Consumer<SessionController>( home: Consumer<SessionController>(
builder: (_, sessionController, __) { builder: (_, sessionController, __) {
if (sessionController.sessionToken is String) return Dashboard(); if (sessionController.sessionToken is String) {
return Dashboard();
}
return const LogInPage(); return const LogInPage();
}, },
)), )),

View File

@ -21,7 +21,7 @@ class Product {
: id = json["id"], : id = json["id"],
name = json["name"], name = json["name"],
description = json["description"], description = json["description"],
priceInDkkCents = json["priceInDkkCents"], priceInDkkCents = json["price_dkk_cent"],
location = null, location = null,
barcode = null; barcode = json["barcode"];
} }

View File

@ -16,10 +16,10 @@ class User {
}); });
User.fromJson(Map<String, dynamic> json) User.fromJson(Map<String, dynamic> json)
: id = json["id"], : email = json["email"],
email = json["email"], id = json["id"],
name = json["name"], name = json["name"],
balanceInDkkCents = json["balanceInDkkCents"]; balanceInDkkCents = json["balance_dkk_cent"];
void addBalanceFounds(int amount) { void addBalanceFounds(int amount) {
balanceInDkkCents += amount; balanceInDkkCents += amount;

View File

@ -27,6 +27,7 @@ class RegisterForm extends StatefulWidget {
class RegisterFormState extends State<RegisterForm> { class RegisterFormState extends State<RegisterForm> {
bool registerError = false; bool registerError = false;
String errorText = "Ingen fejlbesked jeg skal ikke vises";
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -43,7 +44,7 @@ class RegisterFormState extends State<RegisterForm> {
), ),
ErrorBox( ErrorBox(
visible: registerError, visible: registerError,
errorText: "Bruger med mailen ${mailController.text}", errorText: errorText,
onClosePressed: () { onClosePressed: () {
setState(() { setState(() {
registerError = false; registerError = false;
@ -70,14 +71,18 @@ class RegisterFormState extends State<RegisterForm> {
placeholderText: "*********", placeholderText: "*********",
obscure: true), obscure: true),
PrimaryButton( PrimaryButton(
onPressed: () { onPressed: () async {
final sessionsRepo = context.read<UsersController>(); final sessionsRepo = context.read<UsersController>();
if (sessionsRepo.register(nameController.text, final res = await sessionsRepo.register(nameController.text,
mailController.text, passwordController.text) is Ok) { mailController.text, passwordController.text);
if (res is Ok<Null, String>) {
setState(() => registerError = false); setState(() => registerError = false);
Navigator.of(context).pop(); if (context.mounted) Navigator.of(context).pop();
} else { } else {
setState(() => registerError = true); setState(() {
registerError = true;
errorText = (res as Err<Null, String>).value;
});
} }
}, },
child: const Text("Opret bruger")), child: const Text("Opret bruger")),

View File

@ -29,10 +29,10 @@ class SettingsPage extends StatelessWidget {
_Page( _Page(
icon: Icons.door_back_door, icon: Icons.door_back_door,
title: "Log ud", title: "Log ud",
action: (context) { action: (context) async {
final sessionsController = context.read<SessionController>(); final sessionsController = context.read<SessionController>();
Navigator.popUntil(context, (_) => false); Navigator.pop(context);
sessionsController.logout(); await sessionsController.logout();
}), }),
]; ];

View File

@ -6,7 +6,8 @@ import 'package:mobile/models/user.dart';
import 'package:mobile/server/server.dart'; import 'package:mobile/server/server.dart';
class BackendServer implements Server { class BackendServer implements Server {
final _apiUrl = "10.135.51.114:8080/api"; final _apiUrl = "http://192.168.1.128:8080/api";
// final _apiUrl = "http://127.0.0.1:8080/api";
Future<http.Response> _post( Future<http.Response> _post(
{required String endpoint, required Map<String, dynamic> body}) async { {required String endpoint, required Map<String, dynamic> body}) async {
@ -26,10 +27,12 @@ class BackendServer implements Server {
) )
.then((res) => json.decode(res.body)); .then((res) => json.decode(res.body));
if (res["ok"]) { if (res["ok"]) {
return Error(message: res["message"]);
} else {
return Success( return Success(
data: res.map(((product) => Product.fromJson(product))).toList()); data: (res["products"] as List<dynamic>)
.map(((product) => Product.fromJson(product)))
.toList());
} else {
return Error(message: res["msg"]);
} }
} }
@ -47,7 +50,7 @@ class BackendServer implements Server {
if (res["ok"]) { if (res["ok"]) {
return Success(data: null); return Success(data: null);
} else { } else {
return Error(message: res["message"]); return Error(message: res["msg"]);
} }
} }
@ -64,7 +67,7 @@ class BackendServer implements Server {
if (res["ok"]) { if (res["ok"]) {
return Success(data: res["token"]); return Success(data: res["token"]);
} else { } else {
return Error(message: res["message"]); return Error(message: res["msg"]);
} }
} }
@ -80,21 +83,21 @@ class BackendServer implements Server {
if (res["ok"]) { if (res["ok"]) {
return Success(data: null); return Success(data: null);
} else { } else {
return Error(message: res["message"]); return Error(message: res["msg"]);
} }
} }
@override @override
Future<Response<User>> sessionUser(String token) async { Future<Response<User>> sessionUser(String token) async {
final res = await http ("sending request fr with token $token");
.get( final res = await http.get(
Uri.parse("$_apiUrl/sessions/user/$token"), Uri.parse("$_apiUrl/sessions/user"),
) headers: {"Session-Token": token},
.then((res) => json.decode(res.body)); ).then((res) => json.decode(res.body));
if (res["ok"]) { if (res["ok"]) {
return Error(message: res["message"]); return Success(data: User.fromJson(res["user"]));
} else { } else {
return Success(data: User.fromJson(res)); return Error(message: res["msg"]);
} }
} }
@ -110,7 +113,7 @@ class BackendServer implements Server {
if (res["ok"]) { if (res["ok"]) {
return Success(data: null); return Success(data: null);
} else { } else {
return Error(message: res["message"]); return Error(message: res["msg"]);
} }
} }
} }

View File

@ -24,7 +24,7 @@ class ErrorBox extends StatelessWidget {
), ),
child: Row( child: Row(
children: [ children: [
const Text("Ugyldigt mail eller password"), Text(errorText),
IconButton(onPressed: onClosePressed, icon: const Icon(Icons.close)) IconButton(onPressed: onClosePressed, icon: const Icon(Icons.close))
], ],
), ),