Files
Handwerks_app/screens/home/auftraege_home_screen.dart
2026-04-03 20:42:47 +02:00

162 lines
6.1 KiB
Dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../models/auftrag.dart';
import '../../services/auftrag_repository.dart';
import '../auftrag/auftrag_bearbeiten_screen.dart';
class AuftraegeHomeScreen extends StatelessWidget {
const AuftraegeHomeScreen({super.key});
@override
Widget build(BuildContext context) {
final repo = AuftragRepository();
final user = FirebaseAuth.instance.currentUser;
final name = user?.displayName?.trim();
final scheme = Theme.of(context).colorScheme;
return Scaffold(
appBar: AppBar(
title: const Text('Meine Rechnungen'),
actions: [
IconButton(
icon: const Icon(Icons.logout),
tooltip: 'Abmelden',
onPressed: () => FirebaseAuth.instance.signOut(),
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
child: Card(
color: scheme.primaryContainer.withValues(alpha: 0.35),
child: Padding(
padding: const EdgeInsets.all(14),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.info_outline, color: scheme.primary),
const SizedBox(width: 12),
Expanded(
child: Text(
'Nach dem Login bist du hier. Tippe unten auf '
'„Neue Rechnung“: Daten eintragen, Fotos & Unterschrift, '
'dann PDF erzeugen oder per E-Mail senden.\n\n'
'Wichtig: Nach großen Code-Änderungen App neu starten '
'(Stop ▶), kein reines Hot Reload.',
style: Theme.of(context).textTheme.bodySmall,
),
),
],
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 8),
child: Text(
name != null && name.isNotEmpty ? 'Hallo, $name' : 'Übersicht',
style: Theme.of(context).textTheme.titleLarge,
),
),
Expanded(
child: StreamBuilder<List<Auftrag>>(
stream: repo.watchAuftraege(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Text(
'Rechnungen konnten nicht geladen werden.\n'
'Firestore aktiviert und Sicherheitsregeln gesetzt?\n\n'
'${snapshot.error}',
textAlign: TextAlign.center,
),
),
);
}
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
final list = snapshot.data!;
if (list.isEmpty) {
return Center(
child: Padding(
padding: const EdgeInsets.all(32),
child: Text(
'Noch keine Rechnungen.\n'
'Unten auf „Neue Rechnung“ tippen.',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Theme.of(context)
.colorScheme
.onSurfaceVariant,
),
),
),
);
}
return ListView.separated(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 88),
itemCount: list.length,
separatorBuilder: (context, i) => const SizedBox(height: 8),
itemBuilder: (context, i) {
final a = list[i];
final datum = a.createdAt != null
? DateFormat('dd.MM.yyyy').format(a.createdAt!)
: '';
final nr = a.rechnungsnummer.isNotEmpty
? a.rechnungsnummer
: 'ohne Nr.';
return Card(
clipBehavior: Clip.antiAlias,
child: ListTile(
title: Text(
a.titel.isEmpty ? '(Ohne Titel)' : a.titel,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
'$nr · ${a.kundenName.isEmpty ? "Kunde —" : a.kundenName}'
'${datum.isNotEmpty ? " · $datum" : ""}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
trailing: const Icon(Icons.chevron_right),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (_) =>
AuftragBearbeitenScreen(auftragId: a.id),
),
);
},
),
);
},
);
},
),
),
],
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (_) => const AuftragBearbeitenScreen(),
),
);
},
icon: const Icon(Icons.add),
label: const Text('Neue Rechnung'),
),
);
}
}