first commit
45
.gitignore
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.build/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
.swiftpm/
|
||||||
|
migrate_working_dir/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# The .vscode folder contains launch configuration and tasks you configure in
|
||||||
|
# VS Code which you may wish to be included in version control, so this line
|
||||||
|
# is commented out by default.
|
||||||
|
#.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/doc/api/
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
/build/
|
||||||
|
/coverage/
|
||||||
|
|
||||||
|
# Symbolication related
|
||||||
|
app.*.symbols
|
||||||
|
|
||||||
|
# Obfuscation related
|
||||||
|
app.*.map.json
|
||||||
|
|
||||||
|
# Android Studio will place build artifacts here
|
||||||
|
/android/app/debug
|
||||||
|
/android/app/profile
|
||||||
|
/android/app/release
|
||||||
30
.metadata
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: "3b62efc2a3da49882f43c372e0bc53daef7295a6"
|
||||||
|
channel: "stable"
|
||||||
|
|
||||||
|
project_type: app
|
||||||
|
|
||||||
|
# Tracks metadata for the flutter migrate command
|
||||||
|
migration:
|
||||||
|
platforms:
|
||||||
|
- platform: root
|
||||||
|
create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6
|
||||||
|
base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6
|
||||||
|
- platform: web
|
||||||
|
create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6
|
||||||
|
base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6
|
||||||
|
|
||||||
|
# User provided section
|
||||||
|
|
||||||
|
# List of Local paths (relative to this file) that should be
|
||||||
|
# ignored by the migrate tool.
|
||||||
|
#
|
||||||
|
# Files that are not part of the templates will be ignored by default.
|
||||||
|
unmanaged_files:
|
||||||
|
- 'lib/main.dart'
|
||||||
|
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||||
16
README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# flutter_tank_web_app
|
||||||
|
|
||||||
|
A new Flutter project.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
This project is a starting point for a Flutter application.
|
||||||
|
|
||||||
|
A few resources to get you started if this is your first Flutter project:
|
||||||
|
|
||||||
|
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||||
|
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||||
|
|
||||||
|
For help getting started with Flutter development, view the
|
||||||
|
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||||
|
samples, guidance on mobile development, and a full API reference.
|
||||||
31
analysis_options.yaml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# This file configures the analyzer, which statically analyzes Dart code to
|
||||||
|
# check for errors, warnings, and lints.
|
||||||
|
#
|
||||||
|
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||||
|
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||||
|
# invoked from the command line by running `flutter analyze`.
|
||||||
|
|
||||||
|
# The following line activates a set of recommended lints for Flutter apps,
|
||||||
|
# packages, and plugins designed to encourage good coding practices.
|
||||||
|
analyzer:
|
||||||
|
errors:
|
||||||
|
avoid_print: ignore
|
||||||
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
|
linter:
|
||||||
|
# The lint rules applied to this project can be customized in the
|
||||||
|
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||||
|
# included above or to enable additional rules. A list of all available lints
|
||||||
|
# and their documentation is published at https://dart.dev/lints.
|
||||||
|
#
|
||||||
|
# Instead of disabling a lint rule for the entire project in the
|
||||||
|
# section below, it can also be suppressed for a single line of code
|
||||||
|
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||||
|
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||||
|
# producing the lint.
|
||||||
|
rules:
|
||||||
|
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||||
|
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||||
|
|
||||||
|
# Additional information about this file can be found at
|
||||||
|
# https://dart.dev/guides/language/analysis-options
|
||||||
BIN
assets/images/guru.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
assets/images/guru01.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
7
lib/config/environment.dart
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
class Environment {
|
||||||
|
static const String appwritePublicEndpoint = 'https://appwrite.joshihomeserver.ipv64.net/v1';
|
||||||
|
static const String appwriteProjectId = '6894f2b0001f127bab72';
|
||||||
|
static const String appwriteProjectName = 'Flutter Projects';
|
||||||
|
static const String appwriteRealtimeCollectionId = '68a22f520035a95d6666';
|
||||||
|
static const String appwriteDatabaseId = '68a22ef90021b90f0f43';
|
||||||
|
}
|
||||||
85
lib/controller/home_controller.dart
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import '../models/tank_model.dart';
|
||||||
|
import '../services/appwrite_service.dart';
|
||||||
|
|
||||||
|
class HomeController extends GetxController {
|
||||||
|
final isLoading = false.obs;
|
||||||
|
final listTankModel = <TankModel>[].obs;
|
||||||
|
final appwriteService = AppwriteService();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
_loadListDocument();
|
||||||
|
super.onInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClose() {}
|
||||||
|
|
||||||
|
Future<void> _loadListDocument() async {
|
||||||
|
isLoading.value = true;
|
||||||
|
if(listTankModel.isNotEmpty){
|
||||||
|
listTankModel.clear();
|
||||||
|
}
|
||||||
|
var dateYear = DateTime.now().year;
|
||||||
|
var userId = await appwriteService.getCurrentUserId();
|
||||||
|
if (userId == null) {
|
||||||
|
//User nicht eingeloggt, evtl. zur Login-Seite navigieren
|
||||||
|
update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var resultList = await appwriteService.getDocumentsFromCollection(userId);
|
||||||
|
if (resultList.isEmpty) {
|
||||||
|
//Dokumente erfolgreich geladen, hier können Sie die Liste verarbeiten
|
||||||
|
print('Dokumente wurden nicht geladen: ${resultList.length}');
|
||||||
|
} else {
|
||||||
|
for (var doc in resultList) {
|
||||||
|
var tankModel = TankModel.fromMap(doc.data);
|
||||||
|
listTankModel.add(tankModel);
|
||||||
|
}
|
||||||
|
if (listTankModel.isNotEmpty) {
|
||||||
|
var sortList = listTankModel.where((tank) {
|
||||||
|
var year = (DateTime.tryParse(tank.szDate)!).year;
|
||||||
|
return year == dateYear;
|
||||||
|
}).toList();
|
||||||
|
listTankModel.clear();
|
||||||
|
listTankModel.addAll(sortList);
|
||||||
|
listTankModel.sort((a, b) {
|
||||||
|
var dateA = DateTime.tryParse(a.szDate)!;
|
||||||
|
var dateB = DateTime.tryParse(b.szDate)!;
|
||||||
|
return dateB.compareTo(dateA);
|
||||||
|
});
|
||||||
|
for (var tank in listTankModel) {
|
||||||
|
print(
|
||||||
|
'SortTankModel: ${tank.szDate} - ${tank.szLiters}L - ${tank.szPricePerLiter}€/L - Total: ${tank.szPriceTotal}€',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isLoading.value = false;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> logout() async {
|
||||||
|
var logoutSuccess = await appwriteService.logout();
|
||||||
|
if (logoutSuccess) {
|
||||||
|
Get.snackbar(
|
||||||
|
'Logout erfolgreich',
|
||||||
|
'Sie wurden abgemeldet.',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
);
|
||||||
|
Get.offAllNamed('/login-page');
|
||||||
|
} else {
|
||||||
|
Get.snackbar(
|
||||||
|
'Logout fehlgeschlagen',
|
||||||
|
'Bitte versuchen Sie es erneut.',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
46
lib/controller/login_controller.dart
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import '../pages/home_view.dart';
|
||||||
|
import '../pages/signin_view.dart';
|
||||||
|
import '../services/appwrite_service.dart';
|
||||||
|
|
||||||
|
class LoginController extends GetxController {
|
||||||
|
final emailController = TextEditingController();
|
||||||
|
final passwordController = TextEditingController();
|
||||||
|
final appwriteService = AppwriteService();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClose() {
|
||||||
|
emailController.dispose();
|
||||||
|
passwordController.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void login() async {
|
||||||
|
var email = emailController.text;
|
||||||
|
var password = passwordController.text;
|
||||||
|
// Hier können Sie die Login-Logik implementieren
|
||||||
|
print('Login mit E-Mail: $email, Passwort: $password');
|
||||||
|
var loginSuccess = await appwriteService.login(email, password);
|
||||||
|
if (loginSuccess) {
|
||||||
|
Get.snackbar(
|
||||||
|
'Login erfolgreich',
|
||||||
|
'Willkommen zurück!',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
);
|
||||||
|
Get.offAndToNamed(HomePage.namedRoute);
|
||||||
|
} else {
|
||||||
|
Get.snackbar(
|
||||||
|
'Login fehlgeschlagen',
|
||||||
|
'Bitte überprüfen Sie Ihre E-Mail und Ihr Passwort und versuchen Sie es erneut.',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void goToSignInPage() {
|
||||||
|
Get.offAndToNamed(SigninPage.namedRoute);
|
||||||
|
}
|
||||||
|
}
|
||||||
87
lib/controller/signin_controller.dart
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import '../pages/home_view.dart';
|
||||||
|
import '../pages/login_view.dart';
|
||||||
|
import '../services/appwrite_service.dart';
|
||||||
|
|
||||||
|
class SigninController extends GetxController {
|
||||||
|
final userNameController = TextEditingController();
|
||||||
|
final emailController = TextEditingController();
|
||||||
|
final passwordController = TextEditingController();
|
||||||
|
final appwriteService = AppwriteService();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClose() {
|
||||||
|
userNameController.dispose();
|
||||||
|
emailController.dispose();
|
||||||
|
passwordController.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void register() async {
|
||||||
|
//Eingaben überprüfen
|
||||||
|
if (!_checkInputs()) return;
|
||||||
|
//Registrierungslogik
|
||||||
|
var userName = userNameController.text;
|
||||||
|
var email = emailController.text;
|
||||||
|
var password = passwordController.text;
|
||||||
|
// Testausgabe
|
||||||
|
print(
|
||||||
|
'Registrieren mit Benutzername: $userName, E-Mail: $email, Passwort: $password',
|
||||||
|
);
|
||||||
|
//appwrite Registrierung und login Logik hier einfügen
|
||||||
|
var registrationSuccess = await appwriteService.register(
|
||||||
|
userName,
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
);
|
||||||
|
//Nach erfolgreicher Registrierung Meldung und zur Startseite navigieren
|
||||||
|
if (registrationSuccess) {
|
||||||
|
Get.snackbar(
|
||||||
|
'Registrierung erfolgreich, sie werden weitergeleitet',
|
||||||
|
'Willkommen, $userName!',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
);
|
||||||
|
Get.offAndToNamed(HomePage.namedRoute);
|
||||||
|
} else {
|
||||||
|
Get.snackbar(
|
||||||
|
'Registrierung fehlgeschlagen',
|
||||||
|
'Bitte überprüfen Sie Ihre Eingaben und versuchen Sie es erneut.',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void goToLoginPage() {
|
||||||
|
Get.offAndToNamed(LoginPage.namedRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _checkInputs() {
|
||||||
|
var isOk = false;
|
||||||
|
if (userNameController.text.isEmpty ||
|
||||||
|
emailController.text.isEmpty ||
|
||||||
|
passwordController.text.isEmpty) {
|
||||||
|
Get.snackbar(
|
||||||
|
'Fehler',
|
||||||
|
'Bitte alle Felder ausfüllen',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
);
|
||||||
|
isOk = false;
|
||||||
|
} else {
|
||||||
|
isOk = true;
|
||||||
|
}
|
||||||
|
if (passwordController.text.length < 6) {
|
||||||
|
Get.snackbar(
|
||||||
|
'Fehler',
|
||||||
|
'Passwort muss mindestens 6 Zeichen lang sein',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
);
|
||||||
|
isOk = false;
|
||||||
|
} else {
|
||||||
|
isOk = true;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
lib/helper/helper.dart
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
/// Retrieves the current date in the format "yyyy-MM-dd".
|
||||||
|
///
|
||||||
|
/// @return [String] A formatted date.
|
||||||
|
String getCurrentDate(DateTime date) {
|
||||||
|
return DateFormat("yyyy-MM-dd").format(date);
|
||||||
|
}
|
||||||
19
lib/helper/sample_bindings.dart
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import '../controller/home_controller.dart';
|
||||||
|
import '../controller/login_controller.dart';
|
||||||
|
import '../controller/signin_controller.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SampleBindings extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
// Define your dependencies here no permanent Binding
|
||||||
|
Get.lazyPut<LoginController>(() => LoginController());
|
||||||
|
Get.lazyPut<SigninController>(() => SigninController());
|
||||||
|
Get.lazyPut<HomeController>(() => HomeController());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
27
lib/helper/sample_routes.dart
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'sample_bindings.dart';
|
||||||
|
import '../pages/home_view.dart';
|
||||||
|
import '../pages/signin_view.dart';
|
||||||
|
import '../pages/login_view.dart';
|
||||||
|
|
||||||
|
class SampleRouts {
|
||||||
|
static final sampleBindings = SampleBindings();
|
||||||
|
static List<GetPage<dynamic>> samplePages = [
|
||||||
|
GetPage(
|
||||||
|
name: LoginPage.namedRoute,
|
||||||
|
page: () => const LoginPage(),
|
||||||
|
binding: sampleBindings,
|
||||||
|
),
|
||||||
|
GetPage(
|
||||||
|
name: SigninPage.namedRoute,
|
||||||
|
page: () => const SigninPage(),
|
||||||
|
binding: sampleBindings,
|
||||||
|
),
|
||||||
|
GetPage(
|
||||||
|
name: HomePage.namedRoute,
|
||||||
|
page: () => const HomePage(),
|
||||||
|
binding: sampleBindings,
|
||||||
|
),
|
||||||
|
|
||||||
|
];
|
||||||
|
}
|
||||||
28
lib/main.dart
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'helper/sample_bindings.dart';
|
||||||
|
import 'helper/sample_routes.dart';
|
||||||
|
import 'pages/login_view.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
runApp(const MyApp());
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyApp extends StatelessWidget {
|
||||||
|
const MyApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GetMaterialApp(
|
||||||
|
title: 'Flutter Demo',
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
theme: ThemeData(colorScheme: .fromSeed(seedColor: Colors.deepPurple)),
|
||||||
|
initialBinding: SampleBindings(),
|
||||||
|
initialRoute: LoginPage.namedRoute,
|
||||||
|
getPages: SampleRouts.samplePages,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
82
lib/models/tank_model.dart
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
class TankModel {
|
||||||
|
final String szDocumentId;
|
||||||
|
final String szUserId;
|
||||||
|
final String szDate;
|
||||||
|
final String szOdometer;
|
||||||
|
final String szLiters;
|
||||||
|
final String szPricePerLiter;
|
||||||
|
final String szLocation;
|
||||||
|
final String szPriceTotal;
|
||||||
|
|
||||||
|
TankModel({
|
||||||
|
required this.szDocumentId,
|
||||||
|
required this.szUserId,
|
||||||
|
required this.szDate,
|
||||||
|
required this.szOdometer,
|
||||||
|
required this.szLiters,
|
||||||
|
required this.szPricePerLiter,
|
||||||
|
required this.szLocation,
|
||||||
|
required this.szPriceTotal,
|
||||||
|
});
|
||||||
|
|
||||||
|
TankModel copyWith({
|
||||||
|
String? szDocumentId,
|
||||||
|
String? szUserId,
|
||||||
|
String? szDate,
|
||||||
|
String? szOdometer,
|
||||||
|
String? szLiters,
|
||||||
|
String? szPricePerLiter,
|
||||||
|
String? szLocation,
|
||||||
|
String? szPriceTotal,
|
||||||
|
}) {
|
||||||
|
return TankModel(
|
||||||
|
szDocumentId: szDocumentId ?? this.szDocumentId,
|
||||||
|
szUserId: szUserId ?? this.szUserId,
|
||||||
|
szDate: szDate ?? this.szDate,
|
||||||
|
szOdometer: szOdometer ?? this.szOdometer,
|
||||||
|
szLiters: szLiters ?? this.szLiters,
|
||||||
|
szPricePerLiter: szPricePerLiter ?? this.szPricePerLiter,
|
||||||
|
szLocation: szLocation ?? this.szLocation,
|
||||||
|
szPriceTotal: szPriceTotal ?? this.szPriceTotal,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
final result = <String, dynamic>{};
|
||||||
|
|
||||||
|
result.addAll({'\$id': szDocumentId});
|
||||||
|
result.addAll({'userId': szUserId});
|
||||||
|
result.addAll({'date': szDate});
|
||||||
|
result.addAll({'odometer': szOdometer});
|
||||||
|
result.addAll({'liters': szLiters});
|
||||||
|
result.addAll({'pricePerLiter': szPricePerLiter});
|
||||||
|
result.addAll({'location': szLocation});
|
||||||
|
result.addAll({'priceTotal': szPriceTotal});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
factory TankModel.fromMap(Map<String, dynamic> map) {
|
||||||
|
return TankModel(
|
||||||
|
szDocumentId: map['\$id'] ?? '',
|
||||||
|
szUserId: map['userId'] ?? '',
|
||||||
|
szDate: map['date'] ?? '',
|
||||||
|
szOdometer: map['odometer'] ?? '',
|
||||||
|
szLiters: map['liters'] ?? '',
|
||||||
|
szPricePerLiter: map['pricePerLiter'] ?? '',
|
||||||
|
szLocation: map['location'] ?? '',
|
||||||
|
szPriceTotal: (double.parse(map['liters']?.toString() ?? '0') * double.parse(map['pricePerLiter']?.toString() ?? '0')).toStringAsFixed(2),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toJson() => json.encode(toMap());
|
||||||
|
|
||||||
|
factory TankModel.fromJson(String source) => TankModel.fromMap(json.decode(source));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TankModel(szDocumentId: $szDocumentId, szUserId: $szUserId, szDate: $szDate, szOdometer: $szOdometer, szLiters: $szLiters, szPricePerLiter: $szPricePerLiter, szLocation: $szLocation, szPriceTotal: $szPriceTotal)';
|
||||||
|
}
|
||||||
|
}
|
||||||
56
lib/pages/home_view.dart
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import '../controller/home_controller.dart';
|
||||||
|
|
||||||
|
class HomePage extends GetView<HomeController> {
|
||||||
|
static const String namedRoute = '/home-page';
|
||||||
|
const HomePage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var homCtrl = controller;
|
||||||
|
return PopScope(
|
||||||
|
canPop: false,
|
||||||
|
child: SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.blueGrey,
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
title: const Text('Tank List'),
|
||||||
|
centerTitle: true,
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.refresh),
|
||||||
|
onPressed: () {
|
||||||
|
controller.onInit();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => homCtrl.logout(),
|
||||||
|
icon: Icon(Icons.logout),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Obx(
|
||||||
|
() => homCtrl.isLoading.value == false
|
||||||
|
? ListView.builder(
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
var tank = homCtrl.listTankModel[index];
|
||||||
|
return ListTile(
|
||||||
|
title: Text(
|
||||||
|
'${tank.szDate} - ${tank.szLiters}L - ${tank.szPricePerLiter}€/L',
|
||||||
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
'Total: ${tank.szPriceTotal}€ - Odometer: ${tank.szOdometer}km',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: homCtrl.listTankModel.length,
|
||||||
|
)
|
||||||
|
: Center(child: CircularProgressIndicator()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
36
lib/pages/login_view.dart
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import '../controller/login_controller.dart';
|
||||||
|
import '../widgets/my_login_widget.dart';
|
||||||
|
|
||||||
|
class LoginPage extends GetView<LoginController> {
|
||||||
|
static const String namedRoute = '/login-page';
|
||||||
|
const LoginPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var logCtrl = controller;
|
||||||
|
var displayWidth = MediaQuery.of(context).size.width;
|
||||||
|
var displayHeight = MediaQuery.of(context).size.height;
|
||||||
|
return SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
|
body: Container(
|
||||||
|
height: displayHeight,
|
||||||
|
width: displayWidth,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16.0,
|
||||||
|
vertical: 130.0,
|
||||||
|
),
|
||||||
|
color: Colors.blue.shade100,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: MyLoginWidget(
|
||||||
|
onButtonPressed: () => logCtrl.login(),
|
||||||
|
signInOnTab: () => logCtrl.goToSignInPage(),
|
||||||
|
logCtrl: logCtrl,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
36
lib/pages/signin_view.dart
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import '../controller/signin_controller.dart';
|
||||||
|
import '../widgets/my_signin_widget.dart';
|
||||||
|
|
||||||
|
class SigninPage extends GetView<SigninController> {
|
||||||
|
static const String namedRoute = '/signin-page';
|
||||||
|
const SigninPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var sigCtrl = controller;
|
||||||
|
var displayWidth = MediaQuery.of(context).size.width;
|
||||||
|
var displayHeight = MediaQuery.of(context).size.height;
|
||||||
|
return SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
|
body: Container(
|
||||||
|
height: displayHeight,
|
||||||
|
width: displayWidth,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16.0,
|
||||||
|
vertical: 100.0,
|
||||||
|
),
|
||||||
|
color: Colors.blue.shade100,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: MySigninWidget(
|
||||||
|
signCtrl: sigCtrl,
|
||||||
|
onButtonPressed: () => sigCtrl.register(),
|
||||||
|
logInOnTab: () => sigCtrl.goToLoginPage(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
168
lib/services/appwrite_service.dart
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
import 'package:appwrite/models.dart';
|
||||||
|
import 'package:appwrite/appwrite.dart';
|
||||||
|
import '../config/environment.dart';
|
||||||
|
|
||||||
|
class AppwriteService {
|
||||||
|
static final String endpoint = Environment.appwritePublicEndpoint;
|
||||||
|
static final String projectId = Environment.appwriteProjectId;
|
||||||
|
static final String projectName = Environment.appwriteProjectName;
|
||||||
|
static final String realtimeCollectionId =
|
||||||
|
Environment.appwriteRealtimeCollectionId;
|
||||||
|
static final String databaseId = Environment.appwriteDatabaseId;
|
||||||
|
|
||||||
|
final Client _client = Client().setProject(projectId).setEndpoint(endpoint);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
late final Account _account;
|
||||||
|
// ignore: unused_field
|
||||||
|
late final Databases _databases;
|
||||||
|
|
||||||
|
AppwriteService._internal() {
|
||||||
|
_account = Account(_client);
|
||||||
|
_databases = Databases(_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static final AppwriteService _instance = AppwriteService._internal();
|
||||||
|
|
||||||
|
/// Singleton instance getter
|
||||||
|
factory AppwriteService() => _instance;
|
||||||
|
|
||||||
|
// register new user with userName, e-Mail and password
|
||||||
|
Future<bool> register(String userName, String email, String password) async {
|
||||||
|
try {
|
||||||
|
final user = await _account.create(
|
||||||
|
userId: ID.unique(),
|
||||||
|
email: email,
|
||||||
|
password: password,
|
||||||
|
name: userName,
|
||||||
|
);
|
||||||
|
print('Registrierung erfolgreich: ${user.$id}');
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
print('Registrierung fehlgeschlagen: $e');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// login with e-Mail and password
|
||||||
|
Future<bool> login(String email, String password) async {
|
||||||
|
await logout();
|
||||||
|
try {
|
||||||
|
final session = await _account.createEmailPasswordSession(
|
||||||
|
email: email,
|
||||||
|
password: password,
|
||||||
|
);
|
||||||
|
print('Login erfolgreich: ${session.$id}');
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
print('Login fehlgeschlagen: $e');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// logout current user
|
||||||
|
Future<bool> logout() async {
|
||||||
|
try {
|
||||||
|
await _account.deleteSession(sessionId: 'current');
|
||||||
|
print('Logout erfolgreich');
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
print('Logout fehlgeschlagen: $e');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get current user ID
|
||||||
|
Future<String?> getCurrentUserId() async {
|
||||||
|
try {
|
||||||
|
final user = await _account.get();
|
||||||
|
return user.$id;
|
||||||
|
} catch (e) {
|
||||||
|
print('Fehler beim Abrufen der Benutzer-ID: $e');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get List<Document> from Realtime Collection
|
||||||
|
Future<List<Document>> getDocumentsFromCollection(String userId) async {
|
||||||
|
try {
|
||||||
|
final documents = await _databases.listDocuments(
|
||||||
|
databaseId: databaseId,
|
||||||
|
collectionId: realtimeCollectionId,
|
||||||
|
queries: [Query.equal('userId', userId), Query.orderDesc('date')],
|
||||||
|
);
|
||||||
|
return documents.documents;
|
||||||
|
} catch (e) {
|
||||||
|
print('Fehler beim Abrufen der Dokumente: $e');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Document per Id from Realtime Collection
|
||||||
|
Future<Document?> getDocumentById(String documentId) async {
|
||||||
|
try {
|
||||||
|
final document = await _databases.getDocument(
|
||||||
|
databaseId: databaseId,
|
||||||
|
collectionId: realtimeCollectionId,
|
||||||
|
documentId: documentId,
|
||||||
|
);
|
||||||
|
return document;
|
||||||
|
} catch (e) {
|
||||||
|
print('Fehler beim Abrufen des Dokuments: $e');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save a new document to Realtime Collection
|
||||||
|
Future<bool> createDocumentInCollection(Map<String, dynamic> data) async {
|
||||||
|
try {
|
||||||
|
await _databases.createDocument(
|
||||||
|
databaseId: databaseId,
|
||||||
|
collectionId: realtimeCollectionId,
|
||||||
|
documentId: ID.unique(),
|
||||||
|
data: data,
|
||||||
|
);
|
||||||
|
print('Dokument erfolgreich erstellt');
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
print('Fehler beim Erstellen des Dokuments: $e');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update an existing document in Realtime Collection
|
||||||
|
Future<bool> updateDocumentInCollection(
|
||||||
|
String documentId,
|
||||||
|
Map<String, dynamic> data,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
await _databases.updateDocument(
|
||||||
|
databaseId: databaseId,
|
||||||
|
collectionId: realtimeCollectionId,
|
||||||
|
documentId: documentId,
|
||||||
|
data: data,
|
||||||
|
);
|
||||||
|
print('Dokument erfolgreich aktualisiert');
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
print('Fehler beim Aktualisieren des Dokuments: $e');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a document from Realtime Collection
|
||||||
|
Future<bool> deleteDocumentFromCollection(String documentId) async {
|
||||||
|
try {
|
||||||
|
await _databases.deleteDocument(
|
||||||
|
databaseId: databaseId,
|
||||||
|
collectionId: realtimeCollectionId,
|
||||||
|
documentId: documentId,
|
||||||
|
);
|
||||||
|
print('Dokument erfolgreich gelöscht');
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
print('Fehler beim Löschen des Dokuments: $e');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
134
lib/widgets/my_login_widget.dart
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart' show GoogleFonts;
|
||||||
|
import '../controller/login_controller.dart';
|
||||||
|
|
||||||
|
class MyLoginWidget extends StatelessWidget {
|
||||||
|
final void Function()? onButtonPressed;
|
||||||
|
final void Function()? signInOnTab;
|
||||||
|
final LoginController logCtrl;
|
||||||
|
|
||||||
|
const MyLoginWidget({
|
||||||
|
super.key,
|
||||||
|
this.onButtonPressed,
|
||||||
|
this.signInOnTab,
|
||||||
|
required this.logCtrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final googleFont = GoogleFonts.righteous().fontFamily;
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
// Umriss (Outline)
|
||||||
|
Text(
|
||||||
|
"Login Page",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 44,
|
||||||
|
fontFamily: googleFont,
|
||||||
|
fontStyle: FontStyle.normal,
|
||||||
|
letterSpacing: 5.0,
|
||||||
|
foreground: Paint()
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeWidth = 5
|
||||||
|
..color = Colors.blue.shade900,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Füllung
|
||||||
|
Text(
|
||||||
|
"Login Page",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 44,
|
||||||
|
fontFamily: googleFont,
|
||||||
|
fontStyle: FontStyle.normal,
|
||||||
|
color: Colors.orange.shade300,
|
||||||
|
letterSpacing: 5.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: Colors.orange.shade400, width: 8),
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(18),
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/guru.png',
|
||||||
|
width: 400,
|
||||||
|
height: 400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50.0),
|
||||||
|
child: TextField(
|
||||||
|
controller: logCtrl.emailController,
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'E-Mail',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50.0),
|
||||||
|
child: TextField(
|
||||||
|
obscureText: true,
|
||||||
|
controller: logCtrl.passwordController,
|
||||||
|
keyboardType: TextInputType.visiblePassword,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'Password',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 30),
|
||||||
|
ElevatedButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
backgroundColor: WidgetStatePropertyAll<Color>(
|
||||||
|
Colors.orange.shade500,
|
||||||
|
),
|
||||||
|
foregroundColor: WidgetStatePropertyAll<Color>(
|
||||||
|
Colors.blue.shade900,
|
||||||
|
),
|
||||||
|
minimumSize: WidgetStatePropertyAll<Size>(Size(430, 60)),
|
||||||
|
),
|
||||||
|
onPressed: onButtonPressed,
|
||||||
|
child: Text(
|
||||||
|
'Login',
|
||||||
|
style: TextStyle(fontSize: 34, fontFamily: googleFont),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
style: TextStyle(fontSize: 16, color: Colors.black),
|
||||||
|
children: [
|
||||||
|
TextSpan(text: 'Zum registrieren '),
|
||||||
|
WidgetSpan(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: signInOnTab,
|
||||||
|
child: Text(
|
||||||
|
'Sign in',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: Colors.blue.shade700,
|
||||||
|
decoration: TextDecoration.underline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(text: ' clicken!!'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
146
lib/widgets/my_signin_widget.dart
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart' show GoogleFonts;
|
||||||
|
import '../controller/signin_controller.dart';
|
||||||
|
|
||||||
|
class MySigninWidget extends StatelessWidget {
|
||||||
|
final void Function()? onButtonPressed;
|
||||||
|
final void Function()? logInOnTab;
|
||||||
|
final SigninController signCtrl;
|
||||||
|
|
||||||
|
const MySigninWidget({
|
||||||
|
super.key,
|
||||||
|
this.onButtonPressed,
|
||||||
|
this.logInOnTab,
|
||||||
|
required this.signCtrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final googleFont = GoogleFonts.righteous().fontFamily;
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
// Umriss (Outline)
|
||||||
|
Text(
|
||||||
|
"Signin Page",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 44,
|
||||||
|
fontFamily: googleFont,
|
||||||
|
fontStyle: FontStyle.normal,
|
||||||
|
letterSpacing: 5.0,
|
||||||
|
foreground: Paint()
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeWidth = 5
|
||||||
|
..color = Colors.blue.shade900,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Füllung
|
||||||
|
Text(
|
||||||
|
"Signin Page",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 44,
|
||||||
|
fontFamily: googleFont,
|
||||||
|
fontStyle: FontStyle.normal,
|
||||||
|
color: Colors.orange.shade300,
|
||||||
|
letterSpacing: 5.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: Colors.orange.shade400, width: 8),
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(18),
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/guru01.png',
|
||||||
|
width: 400,
|
||||||
|
height: 400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50.0),
|
||||||
|
child: TextField(
|
||||||
|
controller: signCtrl.userNameController,
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'Username',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50.0),
|
||||||
|
child: TextField(
|
||||||
|
controller: signCtrl.emailController,
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'Email',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50.0),
|
||||||
|
child: TextField(
|
||||||
|
obscureText: true,
|
||||||
|
controller: signCtrl.passwordController,
|
||||||
|
keyboardType: TextInputType.visiblePassword,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'Password',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 30),
|
||||||
|
ElevatedButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
backgroundColor: WidgetStatePropertyAll<Color>(
|
||||||
|
Colors.orange.shade500,
|
||||||
|
),
|
||||||
|
foregroundColor: WidgetStatePropertyAll<Color>(
|
||||||
|
Colors.blue.shade900,
|
||||||
|
),
|
||||||
|
minimumSize: WidgetStatePropertyAll<Size>(Size(430, 60)),
|
||||||
|
),
|
||||||
|
onPressed: onButtonPressed,
|
||||||
|
child: Text(
|
||||||
|
'Register',
|
||||||
|
style: TextStyle(fontSize: 34, fontFamily: googleFont),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
style: TextStyle(fontSize: 16, color: Colors.black),
|
||||||
|
children: [
|
||||||
|
TextSpan(text: 'Zum login '),
|
||||||
|
WidgetSpan(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: logInOnTab,
|
||||||
|
child: Text(
|
||||||
|
'Log in',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: Colors.blue.shade700,
|
||||||
|
decoration: TextDecoration.underline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(text: ' clicken!!'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
610
pubspec.lock
Normal file
@@ -0,0 +1,610 @@
|
|||||||
|
# Generated by pub
|
||||||
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
|
packages:
|
||||||
|
appwrite:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: appwrite
|
||||||
|
sha256: "3e1f618c8f75bafa49ef7b1b445f64c53cf4620a195443f4d119bbc95a666d0a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "14.0.0"
|
||||||
|
async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: async
|
||||||
|
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.13.0"
|
||||||
|
boolean_selector:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: boolean_selector
|
||||||
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
characters:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: characters
|
||||||
|
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
clock:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: clock
|
||||||
|
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
code_assets:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: code_assets
|
||||||
|
sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
|
collection:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: collection
|
||||||
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.19.1"
|
||||||
|
cookie_jar:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cookie_jar
|
||||||
|
sha256: a6ac027d3ed6ed756bfce8f3ff60cb479e266f3b0fdabd6242b804b6765e52de
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.8"
|
||||||
|
crypto:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: crypto
|
||||||
|
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.7"
|
||||||
|
cupertino_icons:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: cupertino_icons
|
||||||
|
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.8"
|
||||||
|
device_info_plus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: device_info_plus
|
||||||
|
sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "10.1.2"
|
||||||
|
device_info_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: device_info_plus_platform_interface
|
||||||
|
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.3"
|
||||||
|
fake_async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fake_async
|
||||||
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.3"
|
||||||
|
ffi:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: ffi
|
||||||
|
sha256: d07d37192dbf97461359c1518788f203b0c9102cfd2c35a716b823741219542c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.5"
|
||||||
|
file:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file
|
||||||
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.1"
|
||||||
|
flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
flutter_lints:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: flutter_lints
|
||||||
|
sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.0"
|
||||||
|
flutter_test:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
flutter_web_auth_2:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_web_auth_2
|
||||||
|
sha256: "4d3d2fd3d26bf1a26b3beafd4b4b899c0ffe10dc99af25abc58ffe24e991133c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.2"
|
||||||
|
flutter_web_auth_2_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_web_auth_2_platform_interface
|
||||||
|
sha256: e8669e262005a8354389ba2971f0fc1c36188481234ff50d013aaf993f30f739
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0"
|
||||||
|
flutter_web_plugins:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
get:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: get
|
||||||
|
sha256: "5ed34a7925b85336e15d472cc4cfe7d9ebf4ab8e8b9f688585bf6b50f4c3d79a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.7.3"
|
||||||
|
glob:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: glob
|
||||||
|
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.3"
|
||||||
|
google_fonts:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: google_fonts
|
||||||
|
sha256: "6996212014b996eaa17074e02b1b925b212f5e053832d9048970dc27255a8fb3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.1.0"
|
||||||
|
hooks:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: hooks
|
||||||
|
sha256: "5d309c86e7ce34cd8e37aa71cb30cb652d3829b900ab145e4d9da564b31d59f7"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
|
http:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.6.0"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.2"
|
||||||
|
intl:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.20.2"
|
||||||
|
leak_tracker:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker
|
||||||
|
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "11.0.2"
|
||||||
|
leak_tracker_flutter_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_flutter_testing
|
||||||
|
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.10"
|
||||||
|
leak_tracker_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_testing
|
||||||
|
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
|
lints:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: lints
|
||||||
|
sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.0"
|
||||||
|
logging:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: logging
|
||||||
|
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0"
|
||||||
|
matcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: matcher
|
||||||
|
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.12.17"
|
||||||
|
material_color_utilities:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: material_color_utilities
|
||||||
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.11.1"
|
||||||
|
meta:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: meta
|
||||||
|
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.17.0"
|
||||||
|
native_toolchain_c:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: native_toolchain_c
|
||||||
|
sha256: "89e83885ba09da5fdf2cdacc8002a712ca238c28b7f717910b34bcd27b0d03ac"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.17.4"
|
||||||
|
objective_c:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: objective_c
|
||||||
|
sha256: "9922a1ad59ac5afb154cc948aa6ded01987a75003651d0a2866afc23f4da624e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.2.3"
|
||||||
|
package_info_plus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_info_plus
|
||||||
|
sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "8.3.1"
|
||||||
|
package_info_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_info_plus_platform_interface
|
||||||
|
sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.1"
|
||||||
|
path:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path
|
||||||
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.9.1"
|
||||||
|
path_provider:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider
|
||||||
|
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.5"
|
||||||
|
path_provider_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_android
|
||||||
|
sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.22"
|
||||||
|
path_provider_foundation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_foundation
|
||||||
|
sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.6.0"
|
||||||
|
path_provider_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_linux
|
||||||
|
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.1"
|
||||||
|
path_provider_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_platform_interface
|
||||||
|
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
path_provider_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_windows
|
||||||
|
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.0"
|
||||||
|
platform:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: platform
|
||||||
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.6"
|
||||||
|
plugin_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: plugin_platform_interface
|
||||||
|
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.8"
|
||||||
|
pub_semver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pub_semver
|
||||||
|
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
sky_engine:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
source_span:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_span
|
||||||
|
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.10.1"
|
||||||
|
stack_trace:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stack_trace
|
||||||
|
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.12.1"
|
||||||
|
stream_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stream_channel
|
||||||
|
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.4"
|
||||||
|
string_scanner:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: string_scanner
|
||||||
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.1"
|
||||||
|
term_glyph:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: term_glyph
|
||||||
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.2"
|
||||||
|
test_api:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test_api
|
||||||
|
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.7"
|
||||||
|
typed_data:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: typed_data
|
||||||
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
universal_io:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: universal_io
|
||||||
|
sha256: f63cbc48103236abf48e345e07a03ce5757ea86285ed313a6a032596ed9301e2
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.1"
|
||||||
|
url_launcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher
|
||||||
|
sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.3.2"
|
||||||
|
url_launcher_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_android
|
||||||
|
sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.3.28"
|
||||||
|
url_launcher_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_ios
|
||||||
|
sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.3.6"
|
||||||
|
url_launcher_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_linux
|
||||||
|
sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.2"
|
||||||
|
url_launcher_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_macos
|
||||||
|
sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.5"
|
||||||
|
url_launcher_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_platform_interface
|
||||||
|
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.2"
|
||||||
|
url_launcher_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_web
|
||||||
|
sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.2"
|
||||||
|
url_launcher_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_windows
|
||||||
|
sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.5"
|
||||||
|
vector_math:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_math
|
||||||
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
vm_service:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vm_service
|
||||||
|
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "15.0.2"
|
||||||
|
web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web
|
||||||
|
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
|
web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket
|
||||||
|
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
|
web_socket_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket_channel
|
||||||
|
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.3"
|
||||||
|
win32:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: win32
|
||||||
|
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.15.0"
|
||||||
|
win32_registry:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: win32_registry
|
||||||
|
sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.5"
|
||||||
|
window_to_front:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: window_to_front
|
||||||
|
sha256: "7aef379752b7190c10479e12b5fd7c0b9d92adc96817d9e96c59937929512aee"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.3"
|
||||||
|
xdg_directories:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xdg_directories
|
||||||
|
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
|
yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: yaml
|
||||||
|
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.3"
|
||||||
|
sdks:
|
||||||
|
dart: ">=3.10.7 <4.0.0"
|
||||||
|
flutter: ">=3.38.4"
|
||||||
29
pubspec.yaml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: flutter_tank_web_app
|
||||||
|
description: "A new Flutter project."
|
||||||
|
|
||||||
|
publish_to: "none"
|
||||||
|
|
||||||
|
version: 1.0.0+1
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ^3.10.7
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
cupertino_icons: ^1.0.8
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
get: ^4.7.3
|
||||||
|
google_fonts: ^7.1.0
|
||||||
|
intl: ^0.20.2
|
||||||
|
appwrite: ^14.0.0
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_lints: ^6.0.0
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
uses-material-design: true
|
||||||
|
|
||||||
|
assets:
|
||||||
|
- assets/images/
|
||||||
30
test/widget_test.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// This is a basic Flutter widget test.
|
||||||
|
//
|
||||||
|
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||||
|
// utility in the flutter_test package. For example, you can send tap and scroll
|
||||||
|
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||||
|
// tree, read text, and verify that the values of widget properties are correct.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import 'package:flutter_tank_web_app/main.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||||
|
// Build our app and trigger a frame.
|
||||||
|
await tester.pumpWidget(const MyApp());
|
||||||
|
|
||||||
|
// Verify that our counter starts at 0.
|
||||||
|
expect(find.text('0'), findsOneWidget);
|
||||||
|
expect(find.text('1'), findsNothing);
|
||||||
|
|
||||||
|
// Tap the '+' icon and trigger a frame.
|
||||||
|
await tester.tap(find.byIcon(Icons.add));
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
// Verify that our counter has incremented.
|
||||||
|
expect(find.text('0'), findsNothing);
|
||||||
|
expect(find.text('1'), findsOneWidget);
|
||||||
|
});
|
||||||
|
}
|
||||||
BIN
web/favicon.png
Normal file
|
After Width: | Height: | Size: 917 B |
BIN
web/icons/Icon-192.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
web/icons/Icon-512.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
web/icons/Icon-maskable-192.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
web/icons/Icon-maskable-512.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
38
web/index.html
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!--
|
||||||
|
If you are serving your web app in a path other than the root, change the
|
||||||
|
href value below to reflect the base path you are serving from.
|
||||||
|
|
||||||
|
The path provided below has to start and end with a slash "/" in order for
|
||||||
|
it to work correctly.
|
||||||
|
|
||||||
|
For more details:
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
||||||
|
|
||||||
|
This is a placeholder for base href that will be replaced by the value of
|
||||||
|
the `--base-href` argument provided to `flutter build`.
|
||||||
|
-->
|
||||||
|
<base href="$FLUTTER_BASE_HREF">
|
||||||
|
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||||
|
<meta name="description" content="A new Flutter project.">
|
||||||
|
|
||||||
|
<!-- iOS meta tags & icons -->
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="flutter_tank_web_app">
|
||||||
|
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||||
|
|
||||||
|
<!-- Favicon -->
|
||||||
|
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||||
|
|
||||||
|
<title>flutter_tank_web_app</title>
|
||||||
|
<link rel="manifest" href="manifest.json">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="flutter_bootstrap.js" async></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
35
web/manifest.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "flutter_tank_web_app",
|
||||||
|
"short_name": "flutter_tank_web_app",
|
||||||
|
"start_url": ".",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#0175C2",
|
||||||
|
"theme_color": "#0175C2",
|
||||||
|
"description": "A new Flutter project.",
|
||||||
|
"orientation": "portrait-primary",
|
||||||
|
"prefer_related_applications": false,
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "icons/Icon-192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/Icon-512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/Icon-maskable-192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/Icon-maskable-512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||