Files
app-hyggecraftery/lib/screens/categories_screen.dart
2026-01-03 15:24:36 +01:00

169 lines
5.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../models/category.dart';
import '../services/woocommerce_service.dart';
import '../services/analytics_service.dart';
import '../widgets/loading_widget.dart';
import '../widgets/retry_widget.dart';
import '../utils/error_handler.dart';
import 'products_screen.dart';
class CategoriesScreen extends StatefulWidget {
const CategoriesScreen({super.key});
@override
State<CategoriesScreen> createState() => _CategoriesScreenState();
}
class _CategoriesScreenState extends State<CategoriesScreen> {
final WooCommerceService _wooCommerceService = WooCommerceService();
List<Category> _categories = [];
bool _isLoading = true;
String? _error;
@override
void initState() {
super.initState();
_loadCategories();
}
Future<void> _loadCategories() async {
setState(() {
_isLoading = true;
_error = null;
});
try {
final categories = await _wooCommerceService.getCategories();
setState(() {
_categories = categories;
_isLoading = false;
});
} catch (e) {
setState(() {
_error = e.toString();
_isLoading = false;
});
ErrorHandler.showError(context, e);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Kategorien'),
),
body: _isLoading
? const LoadingWidget()
: _error != null
? RetryWidget(
message: 'Fehler beim Laden der Kategorien',
onRetry: _loadCategories,
)
: _categories.isEmpty
? Center(
child: Text(
'Keine Kategorien verfügbar',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: Colors.grey[600],
),
),
)
: RefreshIndicator(
onRefresh: _loadCategories,
child: GridView.builder(
padding: const EdgeInsets.all(16),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
childAspectRatio: 0.8,
),
itemCount: _categories.length,
itemBuilder: (context, index) {
final category = _categories[index];
return _buildCategoryCard(category);
},
),
),
);
}
Widget _buildCategoryCard(Category category) {
return Card(
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () {
AnalyticsService.trackCategoryView(category.name);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductsScreen(
categoryId: category.id.toString(),
categoryName: category.name,
),
),
);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
flex: 3,
child: category.imageUrl != null
? CachedNetworkImage(
imageUrl: category.imageUrl!,
fit: BoxFit.cover,
placeholder: (context, url) => Container(
color: Colors.grey[300],
child: const Center(
child: CircularProgressIndicator(),
),
),
errorWidget: (context, url, error) => Container(
color: Colors.grey[300],
child: const Icon(Icons.category, size: 48),
),
)
: Container(
color: Colors.grey[300],
child: const Icon(Icons.category, size: 48),
),
),
Expanded(
flex: 2,
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
category.name,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
if (category.count > 0) ...[
const SizedBox(height: 4),
Text(
'${category.count} Produkte',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Colors.grey[600],
),
),
],
],
),
),
),
],
),
),
);
}
}