Feature
ein paar feature aber datenbank macht probleme wenn man aufträge speichern möchge
This commit is contained in:
164
screens/onboarding/onboarding_screen.dart
Normal file
164
screens/onboarding/onboarding_screen.dart
Normal 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 geht’s'),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user