ein paar feature aber datenbank macht probleme wenn man aufträge speichern möchge
This commit is contained in:
2026-04-05 12:47:57 +02:00
parent e1d4bb7edf
commit 9ddce354c0
32 changed files with 3931 additions and 612 deletions

View File

@@ -0,0 +1,164 @@
import 'package:flutter/material.dart';
import '../../theme/app_theme.dart';
class OnboardingScreen extends StatefulWidget {
const OnboardingScreen({super.key, required this.onComplete});
final Future<void> Function() onComplete;
@override
State<OnboardingScreen> createState() => _OnboardingScreenState();
}
class _OnboardingScreenState extends State<OnboardingScreen> {
final _pageController = PageController();
int _page = 0;
static const _total = 4;
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
Future<void> _next() async {
if (_page < _total - 1) {
await _pageController.nextPage(
duration: const Duration(milliseconds: 320),
curve: Curves.easeOutCubic,
);
} else {
await widget.onComplete();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppTheme.background,
body: SafeArea(
child: Column(
children: [
Align(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () => widget.onComplete(),
child: const Text('Überspringen'),
),
),
Expanded(
child: PageView(
controller: _pageController,
onPageChanged: (i) => setState(() => _page = i),
children: const [
_OnboardingPage(
icon: Icons.handyman_rounded,
title: 'Willkommen bei HandwerkPro',
text:
'Erfasse Aufträge mit Fotos, Kundenadresse und '
'Unterschrift alles strukturiert an einem Ort.',
),
_OnboardingPage(
icon: Icons.cloud_done_outlined,
title: 'Deine Daten',
text:
'Nach dem Login werden Aufträge sicher gespeichert. '
'Im Profil findest du Impressum, Datenschutz und einen '
'JSON-Export deiner Auftragsdaten.',
),
_OnboardingPage(
icon: Icons.picture_as_pdf_outlined,
title: 'PDF & Teilen',
text:
'Aus jedem Auftrag erzeugst du eine PDF-Rechnung und '
'teilst sie oder sendest sie per E-Mail ohne '
'Steuerberatung, aber dokumentationsfest.',
),
_OnboardingPage(
icon: Icons.account_balance_wallet_outlined,
title: 'Workflow fürs Handwerk',
text:
'Angebot, Leistung, Rechnung, Mahnung ein Vorgang, '
'ohne doppelte Kundendaten. Kleinunternehmer-Hinweis, '
'Skonto, SEPA-QR und CSV-Export für dein Steuerbüro.',
),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
_total,
(i) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: CircleAvatar(
radius: 4,
backgroundColor: i == _page
? AppTheme.accentCyan
: Colors.grey.shade700,
),
),
),
),
const SizedBox(height: 16),
Padding(
padding: const EdgeInsets.fromLTRB(24, 0, 24, 24),
child: SizedBox(
width: double.infinity,
child: FilledButton(
onPressed: _next,
child: Text(_page < _total - 1 ? 'Weiter' : 'Los gehts'),
),
),
),
],
),
),
);
}
}
class _OnboardingPage extends StatelessWidget {
const _OnboardingPage({
required this.icon,
required this.title,
required this.text,
});
final IconData icon;
final String title;
final String text;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 32),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, size: 72, color: AppTheme.accentCyan),
const SizedBox(height: 28),
Text(
title,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
Text(
text,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.grey.shade400,
height: 1.45,
fontSize: 15,
),
),
],
),
);
}
}