Flutter Android login vault: local DB (id+base64 content), email/Google auth, dashboard search/edit/swipe-delete, dark/system theme, minSdk 29

This commit is contained in:
cania
2026-08-12 11:41:20 +02:00
commit a8791a5b10
138 changed files with 6285 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
/// Result of [showEntryDialog]: an entry id + content.
class EntryInput {
final String id;
final String content;
EntryInput(this.id, this.content);
}
/// Dialog to add or edit an entry.
/// When [lockedId] is true, the id field is disabled (editing existing entry).
Future<EntryInput?> showEntryDialog(
BuildContext context, {
required String title,
required String id,
required String initialContent,
required bool lockedId,
}) {
final idCtrl = TextEditingController(text: id);
final contentCtrl = TextEditingController(text: initialContent);
return showDialog<EntryInput>(
context: context,
builder: (ctx) => AlertDialog(
title: Text(title),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller: idCtrl,
enabled: !lockedId,
decoration: const InputDecoration(
labelText: 'ID (unik)', border: OutlineInputBorder()),
),
const SizedBox(height: 12),
TextField(
controller: contentCtrl,
maxLines: 5,
decoration: const InputDecoration(
labelText: 'Konten', border: OutlineInputBorder()),
),
],
),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx),
child: const Text('Batal')),
ElevatedButton(
onPressed: () => Navigator.pop(
ctx, EntryInput(idCtrl.text.trim(), contentCtrl.text)),
child: const Text('Simpan'),
),
],
),
);
}
/// Confirmation dialog; returns true if user confirms.
Future<bool?> showConfirmDialog(
BuildContext context, {
required String title,
required String body,
}) {
return showDialog<bool>(
context: context,
builder: (ctx) => AlertDialog(
title: Text(title),
content: Text(body),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx, false),
child: const Text('Batal')),
ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
onPressed: () => Navigator.pop(ctx, true),
child: const Text('Hapus', style: TextStyle(color: Colors.white)),
),
],
),
);
}