162 lines
6.1 KiB
Dart
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'),
|
|
),
|
|
);
|
|
}
|
|
}
|