grepfood-demo/client/lib/main.dart

106 lines
3.2 KiB
Dart
Raw Permalink Normal View History

import 'dart:convert';
2024-10-28 13:38:56 +00:00
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
2024-10-28 13:38:56 +00:00
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(useMaterial3: true),
2024-10-28 13:38:56 +00:00
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class Recipe {
String name;
String icon;
Recipe(this.name, this.icon);
factory Recipe.fromMap(Map<String, dynamic> json) {
return Recipe(json['Name'], json['Icon']);
2024-10-28 13:38:56 +00:00
}
factory Recipe.fromJson(Map<String, dynamic> json) {
return Recipe(json['Name'], json['Icon']);
}
}
2024-10-28 13:38:56 +00:00
Future<List<Recipe>> fetchRecipes() async {
final response = await http.get(
Uri(scheme: "http", host: "localhost", port: 8080, path: "api/recipes"));
if (response.statusCode == 200) {
final parsed = json.decode(response.body).cast<Map<String, dynamic>>();
return parsed.map<Recipe>((json) => Recipe.fromMap(json)).toList();
} else {
throw Exception("Failed to fetch recipes");
}
}
class _MyHomePageState extends State<MyHomePage> {
2024-10-28 13:38:56 +00:00
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Container(
child: Column(children: [
Padding(
padding: EdgeInsetsDirectional.all(16.0),
child: Image(image: AssetImage("assets/banner.png"))),
Text(textAlign: TextAlign.start, "Einkaufsliste"),
FutureBuilder<List<Recipe>>(
future: fetchRecipes(),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
if (snapshot.hasData) {
List<TableRow> rows = List.empty(growable: true);
for (Recipe recipe in snapshot.data!) {
var image = Image.network(fit: BoxFit.fitHeight,
height: 32.0,
"http://localhost:8080/api/image/${recipe.icon}");
rows.add(TableRow(children: [TableCell(child: image), TableCell(child: Text(recipe.name))]));
}
return Table(children: rows);
} else {
return Center(child: CircularProgressIndicator());
}
})
]));
2024-10-28 13:38:56 +00:00
}
}