Initial commit

This commit is contained in:
2026-01-13 22:09:40 +01:00
commit cc849be7c4
139 changed files with 5445 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
import 'package:get/get.dart';
class HomeController extends GetxController {
void loadFilaments() {}
void downloadFilaments() {}
void restoreFilaments() {}
}

View File

@@ -0,0 +1,153 @@
import 'dart:convert';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import '../model/filament_model.dart';
class FilamentRepository extends GetxService {
static FilamentRepository get to => Get.find();
final GetStorage _storage = GetStorage();
static const String _storageKey = 'filaments';
Future<FilamentRepository> init() async {
await GetStorage.init();
return this;
}
// Create - Füge ein neues Filament hinzu
Future<bool> createFilament(FilamentModel filament) async {
try {
final filaments = getAllFilaments();
filaments.add(filament);
await _storage.write(
_storageKey,
filaments.map((f) => f.toJson()).toList(),
);
return true;
} catch (e) {
print('Error creating filament: $e');
return false;
}
}
// Read - Alle Filamente abrufen
List<FilamentModel> getAllFilaments() {
try {
final data = _storage.read(_storageKey);
if (data == null) return [];
return (data as List)
.map((json) => FilamentModel.fromJson(json))
.toList();
} catch (e) {
print('Error reading filaments: $e');
return [];
}
}
// Read - Einzelnes Filament nach ID
FilamentModel? getFilamentById(String id) {
try {
final filaments = getAllFilaments();
return filaments.firstWhereOrNull((f) => f.id == id);
} catch (e) {
print('Error getting filament by id: $e');
return null;
}
}
// Update - Aktualisiere ein Filament
Future<bool> updateFilament(FilamentModel filament) async {
try {
final filaments = getAllFilaments();
final index = filaments.indexWhere((f) => f.id == filament.id);
if (index == -1) return false;
filaments[index] = filament;
await _storage.write(
_storageKey,
filaments.map((f) => f.toJson()).toList(),
);
return true;
} catch (e) {
print('Error updating filament: $e');
return false;
}
}
// Delete - Lösche ein Filament
Future<bool> deleteFilament(String id) async {
try {
final filaments = getAllFilaments();
filaments.removeWhere((f) => f.id == id);
await _storage.write(
_storageKey,
filaments.map((f) => f.toJson()).toList(),
);
return true;
} catch (e) {
print('Error deleting filament: $e');
return false;
}
}
// Delete All - Lösche alle Filamente
Future<bool> deleteAllFilaments() async {
try {
await _storage.remove(_storageKey);
return true;
} catch (e) {
print('Error deleting all filaments: $e');
return false;
}
}
// Backup - Exportiere als JSON String
String exportToJson() {
try {
final filaments = getAllFilaments();
return jsonEncode(filaments.map((f) => f.toJson()).toList());
} catch (e) {
print('Error exporting to JSON: $e');
return '[]';
}
}
// Restore - Importiere von JSON String
Future<bool> importFromJson(String jsonString) async {
try {
final List<dynamic> data = jsonDecode(jsonString);
final filaments = data
.map((json) => FilamentModel.fromJson(json))
.toList();
await _storage.write(
_storageKey,
filaments.map((f) => f.toJson()).toList(),
);
return true;
} catch (e) {
print('Error importing from JSON: $e');
return false;
}
}
// Zähle alle Filamente
int getCount() {
return getAllFilaments().length;
}
// Suche Filamente nach Name
List<FilamentModel> searchByName(String query) {
final filaments = getAllFilaments();
return filaments
.where((f) => f.name.toLowerCase().contains(query.toLowerCase()))
.toList();
}
// Filtere nach Typ (z.B. PLA, ABS, PETG)
List<FilamentModel> filterByType(String type) {
final filaments = getAllFilaments();
return filaments.where((f) => f.type == type).toList();
}
}

View File

@@ -0,0 +1,14 @@
import 'package:get/get.dart';
import '../controllers/home_controller.dart';
class SampleBindings extends Bindings {
@override
void dependencies() {
// Define your dependencies here no permanent Binding
Get.lazyPut<HomeController>(() => HomeController());
}
}

View File

@@ -0,0 +1,19 @@
import 'package:get/get.dart';
import '../pages/home_view.dart';
import 'sample_bindings.dart';
class SampleRouts {
static final sampleBindings = SampleBindings();
static List<GetPage<dynamic>> samplePages = [
GetPage(
name: HomePage.namedRoute,
page: () => const HomePage(),
binding: sampleBindings,
),
];
}

28
lib/main.dart Normal file
View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'helpers/filament_repository.dart';
import 'helpers/sample_bindings.dart';
import 'helpers/sample_routes.dart';
import 'pages/home_view.dart';
void main() async {
await Get.putAsync(() => FilamentRepository().init());
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(colorScheme: .fromSeed(seedColor: Colors.deepPurple)),
initialBinding: SampleBindings(),
initialRoute: HomePage.namedRoute,
getPages: SampleRouts.samplePages,
);
}
}

View File

@@ -0,0 +1,82 @@
class FilamentModel {
final String id;
final String name;
final String type; // PLA, ABS, PETG, etc.
final String color;
final double weight; // in Gramm
final double price; // Preis
final String? manufacturer;
final DateTime? purchaseDate;
final String? notes;
FilamentModel({
required this.id,
required this.name,
required this.type,
required this.color,
required this.weight,
required this.price,
this.manufacturer,
this.purchaseDate,
this.notes,
});
// JSON Serialisierung
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'type': type,
'color': color,
'weight': weight,
'price': price,
'manufacturer': manufacturer,
'purchaseDate': purchaseDate?.toIso8601String(),
'notes': notes,
};
}
// JSON Deserialisierung
factory FilamentModel.fromJson(Map<String, dynamic> json) {
return FilamentModel(
id: json['id'] as String,
name: json['name'] as String,
type: json['type'] as String,
color: json['color'] as String,
weight: (json['weight'] as num).toDouble(),
price: (json['price'] as num).toDouble(),
manufacturer: json['manufacturer'] as String?,
purchaseDate: json['purchaseDate'] != null
? DateTime.parse(json['purchaseDate'] as String)
: null,
notes: json['notes'] as String?,
);
}
// CopyWith für Updates
FilamentModel copyWith({
String? id,
String? name,
String? type,
String? color,
double? weight,
double? price,
String? manufacturer,
DateTime? purchaseDate,
String? notes,
}) {
return FilamentModel(
id: id ?? this.id,
name: name ?? this.name,
type: type ?? this.type,
color: color ?? this.color,
weight: weight ?? this.weight,
price: price ?? this.price,
manufacturer: manufacturer ?? this.manufacturer,
purchaseDate: purchaseDate ?? this.purchaseDate,
notes: notes ?? this.notes,
);
}
}

156
lib/pages/home_view.dart Normal file
View File

@@ -0,0 +1,156 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/home_controller.dart';
import '../widgets/info_item.dart';
import '../widgets/primary_button.dart';
import '../widgets/secondary_button.dart';
class HomePage extends GetView<HomeController> {
static const String namedRoute = '/home-page';
const HomePage({super.key});
@override
Widget build(BuildContext context) {
var homeCtrl = controller;
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Colors.blue.shade50, Colors.purple.shade50],
),
),
child: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24.0,
vertical: 32.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Header & Image
Hero(
tag: 'filament_image',
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(25),
blurRadius: 20,
offset: Offset(0, 10),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.asset(
'assets/images/fillament_pla_home.png',
width: 150,
height: 150,
),
),
),
),
SizedBox(height: 20),
Text(
'Filament Verwaltung',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headlineLarge?.copyWith(
fontWeight: FontWeight.bold,
color: Colors.deepPurple.shade700,
),
),
SizedBox(height: 12),
Text(
'Verwalte deine Filamente einfach und übersichtlich',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Colors.grey.shade700,
),
),
SizedBox(height: 20),
// Info Card
Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
buildInfoItem(
icon: Icons.storage_rounded,
text: 'Lokale Speicherung auf diesem Gerät',
color: Colors.blue,
),
SizedBox(height: 12),
buildInfoItem(
icon: Icons.list_alt_rounded,
text: 'Filament laden → zur Liste',
color: Colors.green,
),
SizedBox(height: 12),
buildInfoItem(
icon: Icons.cloud_download_rounded,
text: 'Backup → Download als JSON',
color: Colors.orange,
),
SizedBox(height: 12),
buildInfoItem(
icon: Icons.cloud_upload_rounded,
text: 'Wiederherstellen → Upload JSON',
color: Colors.purple,
),
],
),
),
),
SizedBox(height: 20),
// Action Buttons
buildPrimaryButton(
context: context,
icon: Icons.inventory_2_rounded,
label: 'Filamente laden',
onPressed: () => homeCtrl.loadFilaments(),
color: Colors.deepPurple,
),
SizedBox(height: 16),
Row(
children: [
Expanded(
child: buildSecondaryButton(
context: context,
icon: Icons.save_alt_rounded,
label: 'Backup',
onPressed: () => homeCtrl.downloadFilaments(),
color: Colors.blue,
),
),
SizedBox(width: 16),
Expanded(
child: buildSecondaryButton(
context: context,
icon: Icons.restore_rounded,
label: 'Wiederherstellen',
onPressed: () => homeCtrl.restoreFilaments(),
color: Colors.teal,
),
),
],
),
],
),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
Widget buildInfoItem({
required IconData icon,
required String text,
required Color color,
}) {
return Row(
children: [
Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: color.withAlpha(25),
borderRadius: BorderRadius.circular(8),
),
child: Icon(icon, color: color, size: 20),
),
SizedBox(width: 12),
Expanded(
child: Text(
text,
style: TextStyle(fontSize: 14, color: Colors.grey.shade700),
),
),
],
);
}

View File

@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
Widget buildPrimaryButton({
required BuildContext context,
required IconData icon,
required String label,
required VoidCallback onPressed,
required Color color,
}) {
return ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: color,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
elevation: 4,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon),
SizedBox(width: 12),
Text(
label,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
],
),
);
}

View File

@@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
Widget buildSecondaryButton({
required BuildContext context,
required IconData icon,
required String label,
required VoidCallback onPressed,
required Color color,
}) {
return ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: color,
padding: EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: BorderSide(color: color.withOpacity(0.3)),
),
elevation: 2,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, size: 28),
SizedBox(height: 4),
Text(
label,
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600),
),
],
),
);
}