Initialer Commit: Projekt Start

This commit is contained in:
Tim Leikauf
2026-01-03 15:24:36 +01:00
commit 3773f94303
168 changed files with 228080 additions and 0 deletions

78
lib/models/address.dart Normal file
View File

@@ -0,0 +1,78 @@
class Address {
final String? firstName;
final String? lastName;
final String? company;
final String? address1;
final String? address2;
final String? city;
final String? state;
final String? postcode;
final String? country;
final String? email;
final String? phone;
Address({
this.firstName,
this.lastName,
this.company,
this.address1,
this.address2,
this.city,
this.state,
this.postcode,
this.country,
this.email,
this.phone,
});
factory Address.fromJson(Map<String, dynamic> json) {
return Address(
firstName: json['first_name'],
lastName: json['last_name'],
company: json['company'],
address1: json['address_1'] ?? json['address1'],
address2: json['address_2'] ?? json['address2'],
city: json['city'],
state: json['state'],
postcode: json['postcode'],
country: json['country'],
email: json['email'],
phone: json['phone'],
);
}
Map<String, dynamic> toJson() {
return {
'first_name': firstName,
'last_name': lastName,
'company': company,
'address_1': address1,
'address_2': address2,
'city': city,
'state': state,
'postcode': postcode,
'country': country,
'email': email,
'phone': phone,
};
}
String get fullAddress {
final parts = <String>[];
if (address1 != null && address1!.isNotEmpty) parts.add(address1!);
if (address2 != null && address2!.isNotEmpty) parts.add(address2!);
if (postcode != null && postcode!.isNotEmpty) parts.add(postcode!);
if (city != null && city!.isNotEmpty) parts.add(city!);
if (state != null && state!.isNotEmpty) parts.add(state!);
if (country != null && country!.isNotEmpty) parts.add(country!);
return parts.join(', ');
}
bool get isEmpty {
return (firstName == null || firstName!.isEmpty) &&
(lastName == null || lastName!.isEmpty) &&
(address1 == null || address1!.isEmpty) &&
(city == null || city!.isEmpty);
}
}

44
lib/models/category.dart Normal file
View File

@@ -0,0 +1,44 @@
class Category {
final int id;
final String name;
final String? slug;
final String? description;
final int? parent;
final int count;
final String? imageUrl;
Category({
required this.id,
required this.name,
this.slug,
this.description,
this.parent,
this.count = 0,
this.imageUrl,
});
factory Category.fromJson(Map<String, dynamic> json) {
return Category(
id: json['id'] ?? 0,
name: json['name'] ?? '',
slug: json['slug'],
description: json['description'],
parent: json['parent'],
count: json['count'] ?? 0,
imageUrl: json['image']?['src'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'slug': slug,
'description': description,
'parent': parent,
'count': count,
'image': imageUrl != null ? {'src': imageUrl} : null,
};
}
}

42
lib/models/coupon.dart Normal file
View File

@@ -0,0 +1,42 @@
class Coupon {
final String code;
final String? description;
final String discountType; // fixed_cart, percent, fixed_product, percent_product
final String amount;
final bool isValid;
final String? errorMessage;
Coupon({
required this.code,
this.description,
required this.discountType,
required this.amount,
this.isValid = false,
this.errorMessage,
});
factory Coupon.fromJson(Map<String, dynamic> json) {
return Coupon(
code: json['code'] ?? '',
description: json['description'],
discountType: json['discount_type'] ?? 'fixed_cart',
amount: json['amount'] ?? '0',
isValid: json['is_valid'] ?? false,
errorMessage: json['error_message'],
);
}
String get discountDisplay {
switch (discountType) {
case 'percent':
case 'percent_product':
return '$amount%';
case 'fixed_cart':
case 'fixed_product':
return '$amount';
default:
return amount;
}
}
}

201
lib/models/order.dart Normal file
View File

@@ -0,0 +1,201 @@
class Order {
final int id;
final String status;
final String total;
final String currency;
final DateTime dateCreated;
final List<OrderItem> items;
final BillingAddress? billing;
final ShippingAddress? shipping;
final String? paymentMethod;
final String? paymentMethodTitle;
Order({
required this.id,
required this.status,
required this.total,
required this.currency,
required this.dateCreated,
required this.items,
this.billing,
this.shipping,
this.paymentMethod,
this.paymentMethodTitle,
});
factory Order.fromJson(Map<String, dynamic> json) {
final items = (json['line_items'] as List<dynamic>?)
?.map((item) => OrderItem.fromJson(item))
.toList() ??
[];
return Order(
id: json['id'] ?? 0,
status: json['status'] ?? '',
total: json['total'] ?? '0',
currency: json['currency'] ?? 'EUR',
dateCreated: json['date_created'] != null
? DateTime.parse(json['date_created'])
: DateTime.now(),
items: items,
billing: json['billing'] != null
? BillingAddress.fromJson(json['billing'])
: null,
shipping: json['shipping'] != null
? ShippingAddress.fromJson(json['shipping'])
: null,
paymentMethod: json['payment_method'],
paymentMethodTitle: json['payment_method_title'],
);
}
String get statusDisplay {
switch (status) {
case 'pending':
return 'Ausstehend';
case 'processing':
return 'In Bearbeitung';
case 'on-hold':
return 'Wartend';
case 'completed':
return 'Abgeschlossen';
case 'cancelled':
return 'Storniert';
case 'refunded':
return 'Erstattet';
case 'failed':
return 'Fehlgeschlagen';
default:
return status;
}
}
}
class OrderItem {
final int id;
final String name;
final int quantity;
final String price;
final String? imageUrl;
OrderItem({
required this.id,
required this.name,
required this.quantity,
required this.price,
this.imageUrl,
});
factory OrderItem.fromJson(Map<String, dynamic> json) {
return OrderItem(
id: json['id'] ?? 0,
name: json['name'] ?? '',
quantity: json['quantity'] ?? 0,
price: json['price'] ?? '0',
imageUrl: json['image']?['src'],
);
}
}
class BillingAddress {
final String? firstName;
final String? lastName;
final String? company;
final String? address1;
final String? address2;
final String? city;
final String? state;
final String? postcode;
final String? country;
final String? email;
final String? phone;
BillingAddress({
this.firstName,
this.lastName,
this.company,
this.address1,
this.address2,
this.city,
this.state,
this.postcode,
this.country,
this.email,
this.phone,
});
factory BillingAddress.fromJson(Map<String, dynamic> json) {
return BillingAddress(
firstName: json['first_name'],
lastName: json['last_name'],
company: json['company'],
address1: json['address_1'],
address2: json['address_2'],
city: json['city'],
state: json['state'],
postcode: json['postcode'],
country: json['country'],
email: json['email'],
phone: json['phone'],
);
}
String get fullAddress {
final parts = <String>[];
if (address1 != null && address1!.isNotEmpty) parts.add(address1!);
if (address2 != null && address2!.isNotEmpty) parts.add(address2!);
if (postcode != null && postcode!.isNotEmpty) parts.add(postcode!);
if (city != null && city!.isNotEmpty) parts.add(city!);
if (country != null && country!.isNotEmpty) parts.add(country!);
return parts.join(', ');
}
}
class ShippingAddress {
final String? firstName;
final String? lastName;
final String? company;
final String? address1;
final String? address2;
final String? city;
final String? state;
final String? postcode;
final String? country;
ShippingAddress({
this.firstName,
this.lastName,
this.company,
this.address1,
this.address2,
this.city,
this.state,
this.postcode,
this.country,
});
factory ShippingAddress.fromJson(Map<String, dynamic> json) {
return ShippingAddress(
firstName: json['first_name'],
lastName: json['last_name'],
company: json['company'],
address1: json['address_1'],
address2: json['address_2'],
city: json['city'],
state: json['state'],
postcode: json['postcode'],
country: json['country'],
);
}
String get fullAddress {
final parts = <String>[];
if (address1 != null && address1!.isNotEmpty) parts.add(address1!);
if (address2 != null && address2!.isNotEmpty) parts.add(address2!);
if (postcode != null && postcode!.isNotEmpty) parts.add(postcode!);
if (city != null && city!.isNotEmpty) parts.add(city!);
if (country != null && country!.isNotEmpty) parts.add(country!);
return parts.join(', ');
}
}

96
lib/models/product.dart Normal file
View File

@@ -0,0 +1,96 @@
class Product {
final int id;
final String name;
final String description;
final String price;
final String? regularPrice;
final String? salePrice;
final String? imageUrl;
final List<String> images;
final bool inStock;
final int stockQuantity;
final String? sku;
final List<Map<String, dynamic>>? categories;
final double? rating;
final int? ratingCount;
Product({
required this.id,
required this.name,
required this.description,
required this.price,
this.regularPrice,
this.salePrice,
this.imageUrl,
this.images = const [],
this.inStock = true,
this.stockQuantity = 0,
this.sku,
this.categories,
this.rating,
this.ratingCount,
});
factory Product.fromJson(Map<String, dynamic> json) {
final images = <String>[];
if (json['images'] != null && json['images'] is List) {
for (var img in json['images']) {
if (img['src'] != null) {
images.add(img['src']);
}
}
}
return Product(
id: json['id'] ?? 0,
name: json['name'] ?? '',
description: json['description'] ?? '',
price: json['price'] ?? '0',
regularPrice: json['regular_price'],
salePrice: json['sale_price'],
imageUrl: images.isNotEmpty ? images[0] : null,
images: images,
inStock: json['stock_status'] == 'instock',
stockQuantity: json['stock_quantity'] ?? 0,
sku: json['sku'],
categories: json['categories'] != null
? List<Map<String, dynamic>>.from(json['categories'])
: null,
rating: json['average_rating'] != null
? double.tryParse(json['average_rating'].toString())
: null,
ratingCount: json['rating_count'],
);
}
bool get isOnSale => salePrice != null && salePrice!.isNotEmpty;
double get priceValue {
try {
return double.parse(price);
} catch (e) {
return 0.0;
}
}
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'description': description,
'price': price,
'regular_price': regularPrice,
'sale_price': salePrice,
'image_url': imageUrl,
'images': images,
'in_stock': inStock,
'stock_quantity': stockQuantity,
'sku': sku,
'categories': categories,
'average_rating': rating,
'rating_count': ratingCount,
};
}
}

80
lib/models/review.dart Normal file
View File

@@ -0,0 +1,80 @@
class Review {
final int id;
final int productId;
final String reviewer;
final String reviewerEmail;
final String review;
final int rating;
final bool verified;
final DateTime dateCreated;
final String? reviewerAvatarUrl;
Review({
required this.id,
required this.productId,
required this.reviewer,
required this.reviewerEmail,
required this.review,
required this.rating,
this.verified = false,
required this.dateCreated,
this.reviewerAvatarUrl,
});
factory Review.fromJson(Map<String, dynamic> json) {
return Review(
id: json['id'] ?? 0,
productId: json['product_id'] ?? 0,
reviewer: json['reviewer'] ?? '',
reviewerEmail: json['reviewer_email'] ?? '',
review: json['review'] ?? '',
rating: json['rating'] ?? 0,
verified: json['verified'] ?? false,
dateCreated: json['date_created'] != null
? DateTime.parse(json['date_created'])
: DateTime.now(),
reviewerAvatarUrl: json['reviewer_avatar_urls']?['96'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'product_id': productId,
'reviewer': reviewer,
'reviewer_email': reviewerEmail,
'review': review,
'rating': rating,
'verified': verified,
'date_created': dateCreated.toIso8601String(),
};
}
}
class ProductRating {
final double averageRating;
final int ratingCount;
final Map<int, int> ratingBreakdown; // rating -> count
ProductRating({
required this.averageRating,
required this.ratingCount,
required this.ratingBreakdown,
});
factory ProductRating.fromJson(Map<String, dynamic> json) {
final breakdown = <int, int>{};
if (json['rating_breakdown'] != null) {
(json['rating_breakdown'] as Map).forEach((key, value) {
breakdown[int.parse(key.toString())] = value as int;
});
}
return ProductRating(
averageRating: (json['average_rating'] ?? 0.0).toDouble(),
ratingCount: json['rating_count'] ?? 0,
ratingBreakdown: breakdown,
);
}
}

51
lib/models/user.dart Normal file
View File

@@ -0,0 +1,51 @@
class User {
final int id;
final String email;
final String? username;
final String? firstName;
final String? lastName;
final String? displayName;
final String? avatarUrl;
User({
required this.id,
required this.email,
this.username,
this.firstName,
this.lastName,
this.displayName,
this.avatarUrl,
});
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'] ?? 0,
email: json['email'] ?? '',
username: json['username'],
firstName: json['first_name'],
lastName: json['last_name'],
displayName: json['display_name'] ?? json['name'],
avatarUrl: json['avatar_url'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'email': email,
'username': username,
'first_name': firstName,
'last_name': lastName,
'display_name': displayName,
'avatar_url': avatarUrl,
};
}
String get fullName {
if (firstName != null && lastName != null) {
return '$firstName $lastName';
}
return displayName ?? email;
}
}