123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- import 'package:flutter/material.dart';
- import 'package:flutter_screenutil/flutter_screenutil.dart';
- import 'package:intl/intl.dart';
- class AlarmModel {
- final int id;
- final TimeOfDay time;
- final List<bool> days; // 7 days from Monday to Sunday
- final String label;
- bool isActive;
- AlarmModel({
- required this.id,
- required this.time,
- required this.days,
- required this.label,
- this.isActive = true,
- });
- String get timeString {
- final hour = time.hour;
- final minute = time.minute;
- return '${hour.toString().padLeft(2, '0')}:${minute.toString().padLeft(2, '0')}';
- }
- String get repeatDaysString {
- List<String> dayShortNames = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
- List<String> activeDays = [];
- for (int i = 0; i < 7; i++) {
- if (days[i]) {
- activeDays.add(dayShortNames[i]);
- }
- }
- if (activeDays.isEmpty) {
- return 'One time';
- } else if (activeDays.length == 7) {
- return 'Every day';
- } else if (activeDays.length == 5 &&
- days[0] && days[1] && days[2] && days[3] && days[4]) {
- return 'Weekdays';
- } else if (activeDays.length == 2 && days[5] && days[6]) {
- return 'Weekends';
- } else {
- return activeDays.join(', ');
- }
- }
- }
- class AlarmPage extends StatefulWidget {
- @override
- State<AlarmPage> createState() => _AlarmPageState();
- }
- class _AlarmPageState extends State<AlarmPage> {
- List<AlarmModel> _alarms = [];
- int _nextId = 0;
- @override
- void initState() {
- super.initState();
- // Add some sample alarms
- _addAlarm(
- TimeOfDay(hour: 8, minute: 0),
- [true, true, true, true, true, false, false],
- 'Wake up',
- );
- _addAlarm(
- TimeOfDay(hour: 18, minute: 30),
- [true, true, true, true, true, true, true],
- 'Evening reminder',
- );
- }
- void _addAlarm(TimeOfDay time, List<bool> days, String label) {
- setState(() {
- _alarms.add(
- AlarmModel(
- id: _nextId++,
- time: time,
- days: days,
- label: label,
- ),
- );
- });
- }
- void _toggleAlarm(int id) {
- setState(() {
- for (int i = 0; i < _alarms.length; i++) {
- if (_alarms[i].id == id) {
- _alarms[i].isActive = !_alarms[i].isActive;
- break;
- }
- }
- });
- }
- void _deleteAlarm(int id) {
- setState(() {
- _alarms.removeWhere((alarm) => alarm.id == id);
- });
- }
- Future<void> _showAddAlarmDialog() async {
- final TimeOfDay initialTime = TimeOfDay.now();
- final List<bool> days = List.generate(7, (_) => false);
- final TextEditingController labelController = TextEditingController();
- await showDialog(
- context: context,
- builder: (BuildContext context) {
- TimeOfDay selectedTime = initialTime;
- return StatefulBuilder(
- builder: (context, setState) {
- return AlertDialog(
- title: Text('Add Alarm'),
- content: SingleChildScrollView(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- // Time picker button
- ListTile(
- title: Text('Time'),
- subtitle: Text(
- '${selectedTime.hour.toString().padLeft(2, '0')}:${selectedTime.minute.toString().padLeft(2, '0')}',
- style: TextStyle(fontSize: 24.sp),
- ),
- onTap: () async {
- final TimeOfDay? picked = await showTimePicker(
- context: context,
- initialTime: selectedTime,
- );
- if (picked != null) {
- setState(() {
- selectedTime = picked;
- });
- }
- },
- ),
- SizedBox(height: 10.h),
- // Repeat days
- Text('Repeat', style: TextStyle(fontWeight: FontWeight.bold)),
- _buildWeekdaySelector(days, setState),
- SizedBox(height: 10.h),
- // Label
- TextField(
- controller: labelController,
- decoration: InputDecoration(
- labelText: 'Label',
- border: OutlineInputBorder(),
- ),
- ),
- ],
- ),
- ),
- actions: [
- TextButton(
- onPressed: () => Navigator.of(context).pop(),
- child: Text('Cancel'),
- ),
- TextButton(
- onPressed: () {
- _addAlarm(
- selectedTime,
- List.from(days),
- labelController.text.isNotEmpty
- ? labelController.text
- : 'Alarm',
- );
- Navigator.of(context).pop();
- },
- child: Text('Save'),
- ),
- ],
- );
- },
- );
- },
- );
- }
- Widget _buildWeekdaySelector(List<bool> days, StateSetter setState) {
- List<String> dayShortNames = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
- return Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: List.generate(7, (index) {
- return InkWell(
- onTap: () {
- setState(() {
- days[index] = !days[index];
- });
- },
- child: CircleAvatar(
- radius: 18.r,
- backgroundColor: days[index] ? Colors.blue : Colors.grey[300],
- child: Text(
- dayShortNames[index],
- style: TextStyle(
- color: days[index] ? Colors.white : Colors.black87,
- fontWeight: FontWeight.bold,
- ),
- ),
- ),
- );
- }),
- );
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- backgroundColor: Colors.white,
- floatingActionButton: FloatingActionButton(
- onPressed: _showAddAlarmDialog,
- child: Icon(Icons.add),
- tooltip: 'Add Alarm',
- ),
- body: _alarms.isEmpty
- ? Center(
- child: Text(
- 'No alarms set',
- style: TextStyle(fontSize: 18.sp, color: Colors.grey),
- ),
- )
- : ListView.builder(
- itemCount: _alarms.length,
- itemBuilder: (context, index) {
- final alarm = _alarms[index];
- return Card(
- margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h),
- child: ListTile(
- title: Text(
- alarm.timeString,
- style: TextStyle(
- fontSize: 24.sp,
- fontWeight: FontWeight.bold,
- color: alarm.isActive ? Colors.black : Colors.grey,
- ),
- ),
- subtitle: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- alarm.repeatDaysString,
- style: TextStyle(
- fontSize: 14.sp,
- color: alarm.isActive ? Colors.black87 : Colors.grey,
- ),
- ),
- Text(
- alarm.label,
- style: TextStyle(
- fontSize: 16.sp,
- fontWeight: FontWeight.w500,
- color: alarm.isActive ? Colors.black87 : Colors.grey,
- ),
- ),
- ],
- ),
- trailing: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Switch(
- value: alarm.isActive,
- onChanged: (_) => _toggleAlarm(alarm.id),
- ),
- IconButton(
- icon: Icon(Icons.delete, color: Colors.red),
- onPressed: () => _deleteAlarm(alarm.id),
- ),
- ],
- ),
- ),
- );
- },
- ),
- );
- }
- }
|