178 lines
7.2 KiB
Dart
178 lines
7.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
class _FaqEntry {
|
|
final String question;
|
|
final String answer;
|
|
const _FaqEntry(this.question, this.answer);
|
|
}
|
|
|
|
class _FaqSection {
|
|
final String title;
|
|
final List<_FaqEntry> entries;
|
|
const _FaqSection(this.title, this.entries);
|
|
}
|
|
|
|
const _faqSections = <_FaqSection>[
|
|
_FaqSection('Missouri Motor Fuel Tax Refund', [
|
|
_FaqEntry(
|
|
'What is the Missouri Motor Fuel Tax Refund?',
|
|
'Missouri actually offers two separate fuel tax refunds — it\'s worth evaluating '
|
|
'both to see how you could benefit:\n\n'
|
|
'• Highway use — up to 12.5¢ per gallon.\n'
|
|
'• Non-highway use — up to 29.5¢ per gallon.\n\n'
|
|
"This app helps you collect and organize the receipts you'll need to claim "
|
|
"either one. This isn't tax advice — for guidance on which refund(s) fit your "
|
|
'situation, consult a tax professional. Rates and eligibility are set by '
|
|
'Missouri law, which can change at any time, so always confirm current details '
|
|
'with the Missouri Department of Revenue before filing.',
|
|
),
|
|
_FaqEntry(
|
|
'Is this app affiliated with the Missouri Department of Revenue?',
|
|
"No. This is an independent tool for organizing your own receipts — it isn't run by, "
|
|
"endorsed by, or connected to the State of Missouri. It doesn't file anything on "
|
|
'your behalf.',
|
|
),
|
|
_FaqEntry(
|
|
'How do I generate a report for my refund claim?',
|
|
"On the Reports tab, pick a date range to see your totals, then use Share or Print. "
|
|
"There's also a link to Missouri's official Motor Fuel Refund Claim form once "
|
|
"you're ready to file.",
|
|
),
|
|
]),
|
|
_FaqSection('Usage', [
|
|
_FaqEntry(
|
|
'How do I log a fuel purchase?',
|
|
"On the Receipts tab, tap the + button, snap a photo of the receipt, and the app "
|
|
'reads the date, gallons, and price automatically. Review (and correct, if '
|
|
'needed) the values before saving — every field stays editable both before and '
|
|
'after saving.',
|
|
),
|
|
_FaqEntry(
|
|
'What if the app misreads my receipt?',
|
|
'Automatic reading is usually accurate but not perfect — correct any field yourself '
|
|
'before saving, or edit it afterward from the entry\'s detail page.',
|
|
),
|
|
_FaqEntry(
|
|
"Found a receipt, VIN, or error the app couldn't handle?",
|
|
'Send it to ohbrer+ShowMeTheFuelRefund@gmail.com — example receipts or VINs that '
|
|
"didn't scan correctly, screenshots of error screens, or anything else that "
|
|
"didn't work as expected all help improve the app.",
|
|
),
|
|
_FaqEntry(
|
|
'Do I need to add a vehicle before logging a receipt?',
|
|
'Yes — every fuel entry is linked to a vehicle. Add one on the Vehicles tab first '
|
|
"(you'll need its VIN).",
|
|
),
|
|
]),
|
|
_FaqSection('Data Safety', [
|
|
_FaqEntry(
|
|
'Is my data backed up?',
|
|
'Not by default — everything you log lives only on this device until you connect a '
|
|
'cloud storage account (Settings > Data). Once connected, a copy is kept there '
|
|
'too, in storage you control.',
|
|
),
|
|
_FaqEntry(
|
|
'What cloud storage options are supported?',
|
|
'Google Drive, Dropbox, OneDrive, or your own WebDAV server (Nextcloud, ownCloud, or '
|
|
'any self-hosted WebDAV server).',
|
|
),
|
|
_FaqEntry(
|
|
"What happens if I lose my phone, or reinstall the app?",
|
|
"If you never connected cloud storage, that data is gone — it only ever lived on "
|
|
"that device. If you had connected one, reconnect the same account on the new "
|
|
"device (or after reinstalling) and your vehicles, receipts, and photos sync back "
|
|
'down automatically.',
|
|
),
|
|
_FaqEntry(
|
|
'How do I delete my data?',
|
|
'Settings > Data > Advanced has options to purge everything, or just fuel entries in '
|
|
"a specific date range. Both are permanent and can't be undone.",
|
|
),
|
|
]),
|
|
_FaqSection('Advertisements', [
|
|
_FaqEntry(
|
|
'Why do I sometimes see an ad?',
|
|
'Syncing your data to the cloud requires watching a short ad, to help support the '
|
|
"app — at most once every 5 minutes, so it won't show again if you sync "
|
|
'repeatedly in a short span.',
|
|
),
|
|
_FaqEntry(
|
|
'How do I remove ads?',
|
|
'"Remove Ads for a Year" in Settings is a one-time purchase that disables ads for a '
|
|
"year from when you buy it. It doesn't auto-renew or charge you again "
|
|
"automatically — once the year's up, ads come back until you buy again.",
|
|
),
|
|
]),
|
|
];
|
|
|
|
/// A simple, static list of common questions grouped into sections —
|
|
/// reached from [SettingsScreen] (and every tab's AppBar via
|
|
/// [FaqActionButton]), the "back up your data" reminder, and the
|
|
/// first-launch user agreement screen.
|
|
class FaqScreen extends StatelessWidget {
|
|
/// If given, that question's entry starts expanded (and the rest
|
|
/// collapsed) instead of everything starting collapsed — used when a
|
|
/// link elsewhere in the app points at one specific answer, e.g. the
|
|
/// backup reminder dialog jumping straight to the backup question rather
|
|
/// than making the user hunt for it.
|
|
final String? initiallyExpandedQuestion;
|
|
|
|
const FaqScreen({super.key, this.initiallyExpandedQuestion});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final textTheme = Theme.of(context).textTheme;
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('FAQ')),
|
|
body: ListView(
|
|
padding: const EdgeInsets.all(16),
|
|
children: [
|
|
for (final section in _faqSections) ...[
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(4, 8, 4, 8),
|
|
child: Text(
|
|
section.title,
|
|
style: textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w700),
|
|
),
|
|
),
|
|
for (final entry in section.entries)
|
|
Padding(
|
|
padding: const EdgeInsets.only(bottom: 12),
|
|
child: Card(
|
|
child: ExpansionTile(
|
|
title: Text(entry.question, style: textTheme.titleSmall),
|
|
initiallyExpanded: entry.question == initiallyExpandedQuestion,
|
|
childrenPadding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
|
expandedCrossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(entry.answer, style: textTheme.bodyMedium),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
],
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// A "?" AppBar action that jumps straight to [FaqScreen] — added to every
|
|
/// tab's AppBar (Receipts, Vehicles, Reports, Settings; see [MainShell])
|
|
/// so help is reachable the same way no matter which screen the user's on.
|
|
class FaqActionButton extends StatelessWidget {
|
|
const FaqActionButton({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return IconButton(
|
|
icon: const Icon(Icons.help_outline),
|
|
tooltip: 'FAQ',
|
|
onPressed: () => Navigator.of(context).push(
|
|
MaterialPageRoute(builder: (_) => const FaqScreen()),
|
|
),
|
|
);
|
|
}
|
|
}
|