Files
zhinian_manage/lib/pages/help_page.dart

229 lines
6.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import '../theme.dart';
import '../l10n/app_localizations.dart';
class HelpPage extends StatelessWidget {
const HelpPage({super.key});
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final faqs = [
(
l10n.faq1Q,
l10n.faq1A
),
(
l10n.faq2Q,
l10n.faq2A
),
(
l10n.faq3Q,
l10n.faq3A
),
(
l10n.faq4Q,
l10n.faq4A
),
(
l10n.faq5Q,
l10n.faq5A
),
(
l10n.faq6Q,
l10n.faq6A
),
];
return Scaffold(
backgroundColor: AppColors.background,
appBar: AppBar(title: Text(l10n.helpCenter)),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: AppGradients.primary,
borderRadius: BorderRadius.circular(16),
),
child: Row(
children: [
const Icon(Icons.support_agent, color: Colors.white, size: 40),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
l10n.needHelp,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(height: 4),
Text(
l10n.faqSubtitle,
style: const TextStyle(fontSize: 14, color: Colors.white70),
),
],
),
),
],
),
),
const SizedBox(height: 20),
Text(
l10n.faq,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColors.textPrimary,
),
),
const SizedBox(height: 12),
...faqs.asMap().entries.map((entry) {
return _FaqItem(
question: entry.value.$1,
answer: entry.value.$2,
index: entry.key,
);
}).toList(),
const SizedBox(height: 24),
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: BorderRadius.circular(16),
),
child: Column(
children: [
const Icon(Icons.headset_mic_outlined, size: 40, color: AppColors.primary),
const SizedBox(height: 12),
Text(
l10n.stillQuestions,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColors.textPrimary,
),
),
const SizedBox(height: 8),
Text(
l10n.contactTeam,
style: TextStyle(fontSize: 14, color: AppColors.textSecondary),
),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () async {
final uri = Uri.parse('tel:4008888888');
if (await canLaunchUrl(uri)) {
await launchUrl(uri);
}
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 14),
),
child: Text(l10n.contactService),
),
),
],
),
),
],
),
);
}
}
class _FaqItem extends StatefulWidget {
final String question;
final String answer;
final int index;
const _FaqItem({
required this.question,
required this.answer,
required this.index,
});
@override
State<_FaqItem> createState() => _FaqItemState();
}
class _FaqItemState extends State<_FaqItem> {
bool _expanded = false;
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
ListTile(
leading: Container(
width: 28,
height: 28,
decoration: BoxDecoration(
color: AppColors.primary.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(6),
),
child: Center(
child: Text(
'${widget.index + 1}',
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold,
color: AppColors.primary,
),
),
),
),
title: Text(
widget.question,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.textPrimary,
),
),
trailing: AnimatedRotation(
turns: _expanded ? 0.5 : 0,
duration: const Duration(milliseconds: 200),
child: Icon(Icons.keyboard_arrow_down, color: AppColors.textTertiary),
),
onTap: () => setState(() => _expanded = !_expanded),
),
AnimatedCrossFade(
firstChild: const SizedBox.shrink(),
secondChild: Padding(
padding: const EdgeInsets.fromLTRB(72, 0, 16, 16),
child: Text(
widget.answer,
style: TextStyle(
fontSize: 14,
color: AppColors.textSecondary,
height: 1.6,
),
),
),
crossFadeState: _expanded
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
duration: const Duration(milliseconds: 200),
),
],
),
);
}
}