zeba_academy_offline_db 0.0.2
zeba_academy_offline_db: ^0.0.2 copied to clipboard
Offline-first database system for Flutter with hybrid SQLite + Hive storage, automatic background sync, encrypted local data, and offline API request queue.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:zeba_academy_offline_db/zeba_academy_offline_db.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await HiveService.init();
SyncService.start();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Offline DB Demo',
theme: ThemeData(
colorSchemeSeed: Colors.indigo,
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final TextEditingController controller = TextEditingController();
List<Map<String, dynamic>> records = [];
Future<void> addRecord() async {
if(controller.text.isEmpty) return;
await DatabaseService.insertRecord({
"id": DateTime.now().millisecondsSinceEpoch.toString(),
"data": controller.text,
"updatedAt": DateTime.now().millisecondsSinceEpoch
});
controller.clear();
loadRecords();
}
Future<void> loadRecords() async {
final result = await DatabaseService.getRecords();
setState(() {
records = result;
});
}
@override
void initState() {
super.initState();
loadRecords();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text("Offline Database"),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Expanded(
child: TextField(
controller: controller,
decoration: const InputDecoration(
hintText: "Enter offline data...",
border: InputBorder.none,
),
),
),
IconButton(
onPressed: addRecord,
icon: const Icon(Icons.send),
)
],
),
),
const SizedBox(height: 25),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
"Stored Records",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
IconButton(
icon: const Icon(Icons.refresh),
onPressed: loadRecords,
)
],
),
const SizedBox(height: 10),
Expanded(
child: records.isEmpty
? const Center(
child: Text(
"No records yet.\nAdd some offline data.",
textAlign: TextAlign.center,
),
)
: ListView.builder(
itemCount: records.length,
itemBuilder: (context, index) {
final record = records[index];
return Card(
elevation: 2,
margin: const EdgeInsets.symmetric(vertical: 6),
child: ListTile(
leading: const CircleAvatar(
child: Icon(Icons.storage),
),
title: Text(record["data"]),
subtitle: Text("ID: ${record["id"]}"),
),
);
},
),
)
],
),
),
);
}
}