Files
Handwerks_app/screens/onboarding/onboarding_screen.dart
JUSN 9ddce354c0 Feature
ein paar feature aber datenbank macht probleme wenn man aufträge speichern möchge
2026-04-05 12:47:57 +02:00

165 lines
5.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
),
),
],
),
);
}
}