mirror of
https://github.com/Dvorinka/1356.git
synced 2026-06-04 12:02:56 +00:00
Added core data models, repositories, and utilities
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class DateTimeUtils {
|
||||
static const int countdownDays = 1356;
|
||||
|
||||
static DateTime calculateEndDate(DateTime startDate) {
|
||||
return startDate.add(const Duration(days: countdownDays));
|
||||
}
|
||||
|
||||
static Duration calculateRemainingTime(DateTime endDate) {
|
||||
return endDate.difference(DateTime.now());
|
||||
}
|
||||
|
||||
static String formatCountdown(Duration duration) {
|
||||
final days = duration.inDays;
|
||||
final hours = duration.inHours % 24;
|
||||
final minutes = duration.inMinutes % 60;
|
||||
final seconds = duration.inSeconds % 60;
|
||||
|
||||
return '${days}d ${hours}h ${minutes}m ${seconds}s';
|
||||
}
|
||||
|
||||
static String formatCountdownCompact(Duration duration) {
|
||||
final days = duration.inDays;
|
||||
final hours = duration.inHours % 24;
|
||||
final minutes = duration.inMinutes % 60;
|
||||
|
||||
if (days > 0) {
|
||||
return '${days}d ${hours}h';
|
||||
} else if (hours > 0) {
|
||||
return '${hours}h ${minutes}m';
|
||||
} else {
|
||||
return '${minutes}m';
|
||||
}
|
||||
}
|
||||
|
||||
static double calculateProgress(DateTime startDate, DateTime endDate) {
|
||||
final now = DateTime.now();
|
||||
final totalDuration = endDate.difference(startDate).inSeconds;
|
||||
final elapsedDuration = now.difference(startDate).inSeconds;
|
||||
|
||||
if (elapsedDuration >= totalDuration) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
return elapsedDuration / totalDuration;
|
||||
}
|
||||
|
||||
static String formatDate(DateTime date) {
|
||||
return DateFormat('MMM dd, yyyy').format(date);
|
||||
}
|
||||
|
||||
static String formatDateTime(DateTime dateTime) {
|
||||
return DateFormat('MMM dd, yyyy • HH:mm').format(dateTime);
|
||||
}
|
||||
|
||||
static String formatRelativeTime(DateTime dateTime) {
|
||||
final now = DateTime.now();
|
||||
final difference = now.difference(dateTime);
|
||||
|
||||
if (difference.inSeconds < 60) {
|
||||
return 'Just now';
|
||||
} else if (difference.inMinutes < 60) {
|
||||
return '${difference.inMinutes}m ago';
|
||||
} else if (difference.inHours < 24) {
|
||||
return '${difference.inHours}h ago';
|
||||
} else if (difference.inDays < 7) {
|
||||
return '${difference.inDays}d ago';
|
||||
} else {
|
||||
return formatDate(dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
static bool isCountdownFinished(DateTime endDate) {
|
||||
return DateTime.now().isAfter(endDate);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
class Validators {
|
||||
static String? validateEmail(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Email is required';
|
||||
}
|
||||
|
||||
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
|
||||
if (!emailRegex.hasMatch(value)) {
|
||||
return 'Please enter a valid email address';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static String? validatePassword(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Password is required';
|
||||
}
|
||||
|
||||
if (value.length < 6) {
|
||||
return 'Password must be at least 6 characters';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static String? validateUsername(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Username is required';
|
||||
}
|
||||
|
||||
if (value.length < 3) {
|
||||
return 'Username must be at least 3 characters';
|
||||
}
|
||||
|
||||
if (value.length > 20) {
|
||||
return 'Username must not exceed 20 characters';
|
||||
}
|
||||
|
||||
final usernameRegex = RegExp(r'^[a-zA-Z0-9_]+$');
|
||||
if (!usernameRegex.hasMatch(value)) {
|
||||
return 'Username can only contain letters, numbers, and underscores';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static String? validateGoalTitle(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Goal title is required';
|
||||
}
|
||||
|
||||
if (value.length > 100) {
|
||||
return 'Goal title must not exceed 100 characters';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static String? validateGoalDescription(String? value) {
|
||||
if (value != null && value.length > 500) {
|
||||
return 'Description must not exceed 500 characters';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static String? validateGoalProgress(int? value) {
|
||||
if (value == null) {
|
||||
return 'Progress is required';
|
||||
}
|
||||
|
||||
if (value < 0 || value > 100) {
|
||||
return 'Progress must be between 0 and 100';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static String? validateRequired(String? value, String fieldName) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return '$fieldName is required';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user