eigentliche Handwerksapp
This commit is contained in:
161
screens/home/auftraege_home_screen.dart
Normal file
161
screens/home/auftraege_home_screen.dart
Normal file
@@ -0,0 +1,161 @@
|
||||
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'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user