devcode_sms 1.0.0
devcode_sms: ^1.0.0 copied to clipboard
A Flutter plugin for the DevCode SMS API. Send single or bulk SMS messages and check your account balance with a simple, typed Dart interface.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:devcode_sms/devcode_sms.dart';
void main() => runApp(const DevcodeSmsExampleApp());
class DevcodeSmsExampleApp extends StatelessWidget {
const DevcodeSmsExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'DevCode SMS Example',
theme: ThemeData(
colorSchemeSeed: Colors.indigo,
useMaterial3: true,
),
home: const SmsDemoPage(),
);
}
}
class SmsDemoPage extends StatefulWidget {
const SmsDemoPage({super.key});
@override
State<SmsDemoPage> createState() => _SmsDemoPageState();
}
class _SmsDemoPageState extends State<SmsDemoPage> {
final _apiKeyCtrl = TextEditingController();
final _senderCtrl = TextEditingController();
final _phoneCtrl = TextEditingController();
final _messageCtrl = TextEditingController();
String _output = '';
bool _loading = false;
DevcodeSms? get _client {
final key = _apiKeyCtrl.text.trim();
return key.isEmpty ? null : DevcodeSms(apiKey: key);
}
Future<void> _send() async {
final client = _client;
if (client == null) return _show('⚠️ Please enter your API key.');
setState(() {
_loading = true;
_output = '';
});
try {
final result = await client.sendSms(
sender: _senderCtrl.text.trim(),
phone: _phoneCtrl.text.trim(),
message: _messageCtrl.text.trim(),
);
_show(result.isSuccess
? '✅ SMS sent!\n${result.message}'
: '❌ Error: ${result.message}');
} on DevcodeSmsException catch (e) {
_show('❌ ${e.message}');
} finally {
setState(() => _loading = false);
}
}
Future<void> _checkBalance() async {
final client = _client;
if (client == null) return _show('⚠️ Please enter your API key.');
setState(() {
_loading = true;
_output = '';
});
try {
final result = await client.getBalance();
_show(result.isSuccess
? '💳 Remaining balance: ${result.balance} SMS'
: '❌ Error: ${result.message}');
} on DevcodeSmsException catch (e) {
_show('❌ ${e.message}');
} finally {
setState(() => _loading = false);
}
}
void _show(String msg) => setState(() => _output = msg);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('DevCode SMS Demo')),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_field(_apiKeyCtrl, 'API Key', Icons.vpn_key, obscure: true),
const SizedBox(height: 12),
_field(_senderCtrl, 'Sender ID', Icons.badge),
const SizedBox(height: 12),
_field(_phoneCtrl, 'Phone (+237...)', Icons.phone),
const SizedBox(height: 12),
_field(_messageCtrl, 'Message', Icons.message, maxLines: 4),
const SizedBox(height: 20),
FilledButton.icon(
onPressed: _loading ? null : _send,
icon: const Icon(Icons.send),
label: const Text('Send SMS'),
),
const SizedBox(height: 8),
OutlinedButton.icon(
onPressed: _loading ? null : _checkBalance,
icon: const Icon(Icons.account_balance_wallet),
label: const Text('Check Balance'),
),
const SizedBox(height: 24),
if (_loading) const Center(child: CircularProgressIndicator()),
if (_output.isNotEmpty)
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceVariant,
borderRadius: BorderRadius.circular(12),
),
child: Text(_output,
style: Theme.of(context).textTheme.bodyLarge),
),
],
),
),
);
}
Widget _field(
TextEditingController ctrl,
String label,
IconData icon, {
bool obscure = false,
int maxLines = 1,
}) {
return TextField(
controller: ctrl,
obscureText: obscure,
maxLines: maxLines,
decoration: InputDecoration(
labelText: label,
prefixIcon: Icon(icon),
border: const OutlineInputBorder(),
),
);
}
@override
void dispose() {
_apiKeyCtrl.dispose();
_senderCtrl.dispose();
_phoneCtrl.dispose();
_messageCtrl.dispose();
super.dispose();
}
}