runable
This commit is contained in:
408
lib/core/constants/api_constants.dart
Normal file
408
lib/core/constants/api_constants.dart
Normal file
@@ -0,0 +1,408 @@
|
||||
/// API-related constants for the Worker app
|
||||
///
|
||||
/// This file contains all API endpoints, timeouts, and network-related configurations.
|
||||
/// Base URLs should be configured per environment (dev, staging, production).
|
||||
class ApiConstants {
|
||||
// Private constructor to prevent instantiation
|
||||
ApiConstants._();
|
||||
|
||||
// ============================================================================
|
||||
// Base URLs
|
||||
// ============================================================================
|
||||
|
||||
/// Base URL for development environment
|
||||
static const String devBaseUrl = 'https://dev-api.worker.example.com';
|
||||
|
||||
/// Base URL for staging environment
|
||||
static const String stagingBaseUrl = 'https://staging-api.worker.example.com';
|
||||
|
||||
/// Base URL for production environment
|
||||
static const String prodBaseUrl = 'https://api.worker.example.com';
|
||||
|
||||
/// Current base URL (should be configured based on build flavor)
|
||||
static const String baseUrl = devBaseUrl; // TODO: Configure with flavors
|
||||
|
||||
/// API version prefix
|
||||
static const String apiVersion = '/v1';
|
||||
|
||||
/// Full API base URL with version
|
||||
static String get apiBaseUrl => '$baseUrl$apiVersion';
|
||||
|
||||
// ============================================================================
|
||||
// Timeout Configurations
|
||||
// ============================================================================
|
||||
|
||||
/// Connection timeout in milliseconds (30 seconds)
|
||||
static const Duration connectionTimeout = Duration(milliseconds: 30000);
|
||||
|
||||
/// Receive timeout in milliseconds (30 seconds)
|
||||
static const Duration receiveTimeout = Duration(milliseconds: 30000);
|
||||
|
||||
/// Send timeout in milliseconds (30 seconds)
|
||||
static const Duration sendTimeout = Duration(milliseconds: 30000);
|
||||
|
||||
// ============================================================================
|
||||
// Retry Configurations
|
||||
// ============================================================================
|
||||
|
||||
/// Maximum number of retry attempts for failed requests
|
||||
static const int maxRetryAttempts = 3;
|
||||
|
||||
/// Initial retry delay in milliseconds
|
||||
static const Duration initialRetryDelay = Duration(milliseconds: 1000);
|
||||
|
||||
/// Maximum retry delay in milliseconds
|
||||
static const Duration maxRetryDelay = Duration(milliseconds: 5000);
|
||||
|
||||
/// Retry delay multiplier for exponential backoff
|
||||
static const double retryDelayMultiplier = 2.0;
|
||||
|
||||
// ============================================================================
|
||||
// Cache Configurations
|
||||
// ============================================================================
|
||||
|
||||
/// Default cache duration (1 hour)
|
||||
static const Duration defaultCacheDuration = Duration(hours: 1);
|
||||
|
||||
/// Products cache duration (24 hours)
|
||||
static const Duration productsCacheDuration = Duration(hours: 24);
|
||||
|
||||
/// Profile cache duration (1 hour)
|
||||
static const Duration profileCacheDuration = Duration(hours: 1);
|
||||
|
||||
/// Categories cache duration (48 hours)
|
||||
static const Duration categoriesCacheDuration = Duration(hours: 48);
|
||||
|
||||
/// Maximum cache size in bytes (50 MB)
|
||||
static const int maxCacheSize = 50 * 1024 * 1024;
|
||||
|
||||
// ============================================================================
|
||||
// Request Headers
|
||||
// ============================================================================
|
||||
|
||||
/// Content-Type header for JSON requests
|
||||
static const String contentTypeJson = 'application/json';
|
||||
|
||||
/// Accept header for JSON responses
|
||||
static const String acceptJson = 'application/json';
|
||||
|
||||
/// Accept-Language header for Vietnamese
|
||||
static const String acceptLanguageVi = 'vi';
|
||||
|
||||
/// Accept-Language header for English
|
||||
static const String acceptLanguageEn = 'en';
|
||||
|
||||
// ============================================================================
|
||||
// Authentication Endpoints
|
||||
// ============================================================================
|
||||
|
||||
/// Request OTP for phone number login
|
||||
/// POST /auth/request-otp
|
||||
/// Body: { "phone": "+84912345678" }
|
||||
static const String requestOtp = '/auth/request-otp';
|
||||
|
||||
/// Verify OTP code
|
||||
/// POST /auth/verify-otp
|
||||
/// Body: { "phone": "+84912345678", "otp": "123456" }
|
||||
static const String verifyOtp = '/auth/verify-otp';
|
||||
|
||||
/// Register new user
|
||||
/// POST /auth/register
|
||||
/// Body: { "name": "...", "phone": "...", "email": "...", "userType": "..." }
|
||||
static const String register = '/auth/register';
|
||||
|
||||
/// Refresh access token
|
||||
/// POST /auth/refresh-token
|
||||
/// Headers: { "Authorization": "Bearer {refreshToken}" }
|
||||
static const String refreshToken = '/auth/refresh-token';
|
||||
|
||||
/// Logout user
|
||||
/// POST /auth/logout
|
||||
static const String logout = '/auth/logout';
|
||||
|
||||
/// Get current user profile
|
||||
/// GET /auth/me
|
||||
static const String getCurrentUser = '/auth/me';
|
||||
|
||||
// ============================================================================
|
||||
// Loyalty Program Endpoints
|
||||
// ============================================================================
|
||||
|
||||
/// Get loyalty points and tier information
|
||||
/// GET /loyalty/points
|
||||
static const String getLoyaltyPoints = '/loyalty/points';
|
||||
|
||||
/// Get loyalty points transaction history
|
||||
/// GET /loyalty/transactions?page={page}&limit={limit}
|
||||
static const String getPointsHistory = '/loyalty/transactions';
|
||||
|
||||
/// Get available rewards for redemption
|
||||
/// GET /loyalty/rewards?category={category}
|
||||
static const String getRewards = '/loyalty/rewards';
|
||||
|
||||
/// Redeem a reward
|
||||
/// POST /loyalty/rewards/{rewardId}/redeem
|
||||
static const String redeemReward = '/loyalty/rewards';
|
||||
|
||||
/// Get user's redeemed gifts
|
||||
/// GET /loyalty/gifts?status={active|used|expired}
|
||||
static const String getGifts = '/loyalty/gifts';
|
||||
|
||||
/// Get referral information
|
||||
/// GET /loyalty/referral
|
||||
static const String getReferralInfo = '/loyalty/referral';
|
||||
|
||||
/// Share referral link
|
||||
/// POST /loyalty/referral/share
|
||||
/// Body: { "method": "whatsapp|telegram|sms" }
|
||||
static const String shareReferral = '/loyalty/referral/share';
|
||||
|
||||
// ============================================================================
|
||||
// Product Endpoints
|
||||
// ============================================================================
|
||||
|
||||
/// Get all products with pagination
|
||||
/// GET /products?page={page}&limit={limit}&category={categoryId}
|
||||
static const String getProducts = '/products';
|
||||
|
||||
/// Get product details by ID
|
||||
/// GET /products/{productId}
|
||||
static const String getProductDetails = '/products';
|
||||
|
||||
/// Search products
|
||||
/// GET /products/search?q={query}&page={page}&limit={limit}
|
||||
static const String searchProducts = '/products/search';
|
||||
|
||||
/// Get product categories
|
||||
/// GET /categories
|
||||
static const String getCategories = '/categories';
|
||||
|
||||
/// Get products by category
|
||||
/// GET /categories/{categoryId}/products
|
||||
static const String getProductsByCategory = '/categories';
|
||||
|
||||
// ============================================================================
|
||||
// Order Endpoints
|
||||
// ============================================================================
|
||||
|
||||
/// Create new order
|
||||
/// POST /orders
|
||||
/// Body: { "items": [...], "deliveryAddress": {...}, "paymentMethod": "..." }
|
||||
static const String createOrder = '/orders';
|
||||
|
||||
/// Get user's orders
|
||||
/// GET /orders?status={status}&page={page}&limit={limit}
|
||||
static const String getOrders = '/orders';
|
||||
|
||||
/// Get order details by ID
|
||||
/// GET /orders/{orderId}
|
||||
static const String getOrderDetails = '/orders';
|
||||
|
||||
/// Cancel order
|
||||
/// POST /orders/{orderId}/cancel
|
||||
static const String cancelOrder = '/orders';
|
||||
|
||||
/// Get payment transactions
|
||||
/// GET /payments?page={page}&limit={limit}
|
||||
static const String getPayments = '/payments';
|
||||
|
||||
/// Get payment details
|
||||
/// GET /payments/{paymentId}
|
||||
static const String getPaymentDetails = '/payments';
|
||||
|
||||
// ============================================================================
|
||||
// Project Endpoints
|
||||
// ============================================================================
|
||||
|
||||
/// Create new project
|
||||
/// POST /projects
|
||||
static const String createProject = '/projects';
|
||||
|
||||
/// Get user's projects
|
||||
/// GET /projects?status={status}&page={page}&limit={limit}
|
||||
static const String getProjects = '/projects';
|
||||
|
||||
/// Get project details by ID
|
||||
/// GET /projects/{projectId}
|
||||
static const String getProjectDetails = '/projects';
|
||||
|
||||
/// Update project
|
||||
/// PUT /projects/{projectId}
|
||||
static const String updateProject = '/projects';
|
||||
|
||||
/// Update project progress
|
||||
/// PATCH /projects/{projectId}/progress
|
||||
/// Body: { "progress": 75 }
|
||||
static const String updateProjectProgress = '/projects';
|
||||
|
||||
/// Delete project
|
||||
/// DELETE /projects/{projectId}
|
||||
static const String deleteProject = '/projects';
|
||||
|
||||
// ============================================================================
|
||||
// Quote Endpoints
|
||||
// ============================================================================
|
||||
|
||||
/// Create new quote
|
||||
/// POST /quotes
|
||||
static const String createQuote = '/quotes';
|
||||
|
||||
/// Get user's quotes
|
||||
/// GET /quotes?status={status}&page={page}&limit={limit}
|
||||
static const String getQuotes = '/quotes';
|
||||
|
||||
/// Get quote details by ID
|
||||
/// GET /quotes/{quoteId}
|
||||
static const String getQuoteDetails = '/quotes';
|
||||
|
||||
/// Update quote
|
||||
/// PUT /quotes/{quoteId}
|
||||
static const String updateQuote = '/quotes';
|
||||
|
||||
/// Send quote to client
|
||||
/// POST /quotes/{quoteId}/send
|
||||
/// Body: { "email": "client@example.com" }
|
||||
static const String sendQuote = '/quotes';
|
||||
|
||||
/// Convert quote to order
|
||||
/// POST /quotes/{quoteId}/convert
|
||||
static const String convertQuoteToOrder = '/quotes';
|
||||
|
||||
// ============================================================================
|
||||
// Chat Endpoints
|
||||
// ============================================================================
|
||||
|
||||
/// WebSocket endpoint for real-time chat
|
||||
static const String chatWebSocket = '/ws/chat';
|
||||
|
||||
/// Get chat messages
|
||||
/// GET /chat/messages?roomId={roomId}&before={messageId}&limit={limit}
|
||||
static const String getChatMessages = '/chat/messages';
|
||||
|
||||
/// Send chat message
|
||||
/// POST /chat/messages
|
||||
/// Body: { "roomId": "...", "text": "...", "attachments": [...] }
|
||||
static const String sendChatMessage = '/chat/messages';
|
||||
|
||||
/// Mark messages as read
|
||||
/// POST /chat/messages/read
|
||||
/// Body: { "messageIds": [...] }
|
||||
static const String markMessagesAsRead = '/chat/messages/read';
|
||||
|
||||
// ============================================================================
|
||||
// Account & Profile Endpoints
|
||||
// ============================================================================
|
||||
|
||||
/// Get user profile
|
||||
/// GET /profile
|
||||
static const String getProfile = '/profile';
|
||||
|
||||
/// Update user profile
|
||||
/// PUT /profile
|
||||
static const String updateProfile = '/profile';
|
||||
|
||||
/// Upload avatar
|
||||
/// POST /profile/avatar
|
||||
/// Form-data: { "avatar": File }
|
||||
static const String uploadAvatar = '/profile/avatar';
|
||||
|
||||
/// Change password
|
||||
/// POST /profile/change-password
|
||||
/// Body: { "currentPassword": "...", "newPassword": "..." }
|
||||
static const String changePassword = '/profile/change-password';
|
||||
|
||||
/// Get user addresses
|
||||
/// GET /addresses
|
||||
static const String getAddresses = '/addresses';
|
||||
|
||||
/// Add new address
|
||||
/// POST /addresses
|
||||
static const String addAddress = '/addresses';
|
||||
|
||||
/// Update address
|
||||
/// PUT /addresses/{addressId}
|
||||
static const String updateAddress = '/addresses';
|
||||
|
||||
/// Delete address
|
||||
/// DELETE /addresses/{addressId}
|
||||
static const String deleteAddress = '/addresses';
|
||||
|
||||
/// Set default address
|
||||
/// POST /addresses/{addressId}/set-default
|
||||
static const String setDefaultAddress = '/addresses';
|
||||
|
||||
// ============================================================================
|
||||
// Promotion Endpoints
|
||||
// ============================================================================
|
||||
|
||||
/// Get active promotions
|
||||
/// GET /promotions?category={category}
|
||||
static const String getPromotions = '/promotions';
|
||||
|
||||
/// Get promotion details
|
||||
/// GET /promotions/{promotionId}
|
||||
static const String getPromotionDetails = '/promotions';
|
||||
|
||||
/// Claim promotion
|
||||
/// POST /promotions/{promotionId}/claim
|
||||
static const String claimPromotion = '/promotions';
|
||||
|
||||
// ============================================================================
|
||||
// Notification Endpoints
|
||||
// ============================================================================
|
||||
|
||||
/// Get notifications
|
||||
/// GET /notifications?type={type}&page={page}&limit={limit}
|
||||
static const String getNotifications = '/notifications';
|
||||
|
||||
/// Mark notification as read
|
||||
/// POST /notifications/{notificationId}/read
|
||||
static const String markNotificationAsRead = '/notifications';
|
||||
|
||||
/// Mark all notifications as read
|
||||
/// POST /notifications/read-all
|
||||
static const String markAllNotificationsAsRead = '/notifications/read-all';
|
||||
|
||||
/// Clear all notifications
|
||||
/// DELETE /notifications
|
||||
static const String clearAllNotifications = '/notifications';
|
||||
|
||||
/// Register FCM token for push notifications
|
||||
/// POST /notifications/fcm-token
|
||||
/// Body: { "token": "..." }
|
||||
static const String registerFcmToken = '/notifications/fcm-token';
|
||||
|
||||
// ============================================================================
|
||||
// Helper Methods
|
||||
// ============================================================================
|
||||
|
||||
/// Build full URL for endpoint
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// final url = ApiConstants.buildUrl('/products', {'page': '1', 'limit': '20'});
|
||||
/// // Returns: https://api.worker.example.com/v1/products?page=1&limit=20
|
||||
/// ```
|
||||
static String buildUrl(String endpoint, [Map<String, String>? queryParams]) {
|
||||
final uri = Uri.parse('$apiBaseUrl$endpoint');
|
||||
if (queryParams != null && queryParams.isNotEmpty) {
|
||||
return uri.replace(queryParameters: queryParams).toString();
|
||||
}
|
||||
return uri.toString();
|
||||
}
|
||||
|
||||
/// Build URL with path parameters
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// final url = ApiConstants.buildUrlWithParams('/products/{id}', {'id': '123'});
|
||||
/// // Returns: https://api.worker.example.com/v1/products/123
|
||||
/// ```
|
||||
static String buildUrlWithParams(String endpoint, Map<String, String> params) {
|
||||
String url = endpoint;
|
||||
params.forEach((key, value) {
|
||||
url = url.replaceAll('{$key}', value);
|
||||
});
|
||||
return '$apiBaseUrl$url';
|
||||
}
|
||||
}
|
||||
521
lib/core/constants/app_constants.dart
Normal file
521
lib/core/constants/app_constants.dart
Normal file
@@ -0,0 +1,521 @@
|
||||
/// Application-level constants and configurations
|
||||
///
|
||||
/// This file contains app metadata, loyalty tier definitions, pagination settings,
|
||||
/// and other application-wide configuration values.
|
||||
library;
|
||||
|
||||
// ============================================================================
|
||||
// Loyalty Member Tiers
|
||||
// ============================================================================
|
||||
|
||||
/// Membership tier levels in the loyalty program
|
||||
///
|
||||
/// Ordered from lowest to highest:
|
||||
/// - [MemberTier.gold]: Entry level (0-999 points)
|
||||
/// - [MemberTier.platinum]: Mid level (1000-4999 points)
|
||||
/// - [MemberTier.diamond]: Premium level (5000+ points)
|
||||
enum MemberTier {
|
||||
/// Gold tier - Entry level membership
|
||||
/// Requirements: 0-999 points
|
||||
/// Benefits: 1x points multiplier, basic discounts
|
||||
gold,
|
||||
|
||||
/// Platinum tier - Mid level membership
|
||||
/// Requirements: 1000-4999 points
|
||||
/// Benefits: 1.5x points multiplier, priority support, special offers
|
||||
platinum,
|
||||
|
||||
/// Diamond tier - Premium membership
|
||||
/// Requirements: 5000+ points
|
||||
/// Benefits: 2x points multiplier, exclusive rewards, VIP support, early access
|
||||
diamond,
|
||||
}
|
||||
|
||||
/// Extension methods for MemberTier enum
|
||||
extension MemberTierExtension on MemberTier {
|
||||
/// Get display name for the tier
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case MemberTier.gold:
|
||||
return 'Gold';
|
||||
case MemberTier.platinum:
|
||||
return 'Platinum';
|
||||
case MemberTier.diamond:
|
||||
return 'Diamond';
|
||||
}
|
||||
}
|
||||
|
||||
/// Get Vietnamese display name
|
||||
String get displayNameVi {
|
||||
switch (this) {
|
||||
case MemberTier.gold:
|
||||
return 'Vàng';
|
||||
case MemberTier.platinum:
|
||||
return 'Bạc';
|
||||
case MemberTier.diamond:
|
||||
return 'Kim Cương';
|
||||
}
|
||||
}
|
||||
|
||||
/// Get points multiplier for earning rewards
|
||||
double get pointsMultiplier {
|
||||
switch (this) {
|
||||
case MemberTier.gold:
|
||||
return 1.0;
|
||||
case MemberTier.platinum:
|
||||
return 1.5;
|
||||
case MemberTier.diamond:
|
||||
return 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get minimum points required for this tier
|
||||
int get minPoints {
|
||||
switch (this) {
|
||||
case MemberTier.gold:
|
||||
return 0;
|
||||
case MemberTier.platinum:
|
||||
return 1000;
|
||||
case MemberTier.diamond:
|
||||
return 5000;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get maximum points for this tier (null for diamond = unlimited)
|
||||
int? get maxPoints {
|
||||
switch (this) {
|
||||
case MemberTier.gold:
|
||||
return 999;
|
||||
case MemberTier.platinum:
|
||||
return 4999;
|
||||
case MemberTier.diamond:
|
||||
return null; // Unlimited
|
||||
}
|
||||
}
|
||||
|
||||
/// Get next tier (null if already at highest tier)
|
||||
MemberTier? get nextTier {
|
||||
switch (this) {
|
||||
case MemberTier.gold:
|
||||
return MemberTier.platinum;
|
||||
case MemberTier.platinum:
|
||||
return MemberTier.diamond;
|
||||
case MemberTier.diamond:
|
||||
return null; // Already at top
|
||||
}
|
||||
}
|
||||
|
||||
/// Get tier from points value
|
||||
static MemberTier fromPoints(int points) {
|
||||
if (points >= MemberTier.diamond.minPoints) {
|
||||
return MemberTier.diamond;
|
||||
} else if (points >= MemberTier.platinum.minPoints) {
|
||||
return MemberTier.platinum;
|
||||
} else {
|
||||
return MemberTier.gold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// User Types
|
||||
// ============================================================================
|
||||
|
||||
/// Types of users in the Worker app
|
||||
enum UserType {
|
||||
/// Contractor - Construction project managers (Thầu thợ)
|
||||
contractor,
|
||||
|
||||
/// Architect - Design professionals (Kiến trúc sư)
|
||||
architect,
|
||||
|
||||
/// Distributor - Product resellers (Đại lý phân phối)
|
||||
distributor,
|
||||
|
||||
/// Broker - Real estate and construction brokers (Môi giới)
|
||||
broker,
|
||||
}
|
||||
|
||||
/// Extension methods for UserType enum
|
||||
extension UserTypeExtension on UserType {
|
||||
/// Get display name
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case UserType.contractor:
|
||||
return 'Contractor';
|
||||
case UserType.architect:
|
||||
return 'Architect';
|
||||
case UserType.distributor:
|
||||
return 'Distributor';
|
||||
case UserType.broker:
|
||||
return 'Broker';
|
||||
}
|
||||
}
|
||||
|
||||
/// Get Vietnamese display name
|
||||
String get displayNameVi {
|
||||
switch (this) {
|
||||
case UserType.contractor:
|
||||
return 'Thầu thợ';
|
||||
case UserType.architect:
|
||||
return 'Kiến trúc sư';
|
||||
case UserType.distributor:
|
||||
return 'Đại lý phân phối';
|
||||
case UserType.broker:
|
||||
return 'Môi giới';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Order Status
|
||||
// ============================================================================
|
||||
|
||||
/// Order lifecycle status
|
||||
enum OrderStatus {
|
||||
/// Order placed, awaiting processing
|
||||
pending,
|
||||
|
||||
/// Order is being prepared
|
||||
processing,
|
||||
|
||||
/// Order is out for delivery
|
||||
shipping,
|
||||
|
||||
/// Order delivered successfully
|
||||
completed,
|
||||
|
||||
/// Order cancelled by user or system
|
||||
cancelled,
|
||||
}
|
||||
|
||||
/// Extension methods for OrderStatus enum
|
||||
extension OrderStatusExtension on OrderStatus {
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case OrderStatus.pending:
|
||||
return 'Pending';
|
||||
case OrderStatus.processing:
|
||||
return 'Processing';
|
||||
case OrderStatus.shipping:
|
||||
return 'Shipping';
|
||||
case OrderStatus.completed:
|
||||
return 'Completed';
|
||||
case OrderStatus.cancelled:
|
||||
return 'Cancelled';
|
||||
}
|
||||
}
|
||||
|
||||
String get displayNameVi {
|
||||
switch (this) {
|
||||
case OrderStatus.pending:
|
||||
return 'Chờ xử lý';
|
||||
case OrderStatus.processing:
|
||||
return 'Đang xử lý';
|
||||
case OrderStatus.shipping:
|
||||
return 'Đang giao';
|
||||
case OrderStatus.completed:
|
||||
return 'Hoàn thành';
|
||||
case OrderStatus.cancelled:
|
||||
return 'Đã hủy';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Project Status
|
||||
// ============================================================================
|
||||
|
||||
/// Construction project lifecycle status
|
||||
enum ProjectStatus {
|
||||
/// Project in planning phase
|
||||
planning,
|
||||
|
||||
/// Project actively in progress
|
||||
inProgress,
|
||||
|
||||
/// Project completed
|
||||
completed,
|
||||
|
||||
/// Project on hold
|
||||
onHold,
|
||||
|
||||
/// Project cancelled
|
||||
cancelled,
|
||||
}
|
||||
|
||||
extension ProjectStatusExtension on ProjectStatus {
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case ProjectStatus.planning:
|
||||
return 'Planning';
|
||||
case ProjectStatus.inProgress:
|
||||
return 'In Progress';
|
||||
case ProjectStatus.completed:
|
||||
return 'Completed';
|
||||
case ProjectStatus.onHold:
|
||||
return 'On Hold';
|
||||
case ProjectStatus.cancelled:
|
||||
return 'Cancelled';
|
||||
}
|
||||
}
|
||||
|
||||
String get displayNameVi {
|
||||
switch (this) {
|
||||
case ProjectStatus.planning:
|
||||
return 'Lên kế hoạch';
|
||||
case ProjectStatus.inProgress:
|
||||
return 'Đang thực hiện';
|
||||
case ProjectStatus.completed:
|
||||
return 'Hoàn thành';
|
||||
case ProjectStatus.onHold:
|
||||
return 'Tạm dừng';
|
||||
case ProjectStatus.cancelled:
|
||||
return 'Đã hủy';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Project Types
|
||||
// ============================================================================
|
||||
|
||||
/// Types of construction projects
|
||||
enum ProjectType {
|
||||
/// Residential construction
|
||||
residential,
|
||||
|
||||
/// Commercial construction
|
||||
commercial,
|
||||
|
||||
/// Industrial construction
|
||||
industrial,
|
||||
}
|
||||
|
||||
extension ProjectTypeExtension on ProjectType {
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case ProjectType.residential:
|
||||
return 'Residential';
|
||||
case ProjectType.commercial:
|
||||
return 'Commercial';
|
||||
case ProjectType.industrial:
|
||||
return 'Industrial';
|
||||
}
|
||||
}
|
||||
|
||||
String get displayNameVi {
|
||||
switch (this) {
|
||||
case ProjectType.residential:
|
||||
return 'Dân dụng';
|
||||
case ProjectType.commercial:
|
||||
return 'Thương mại';
|
||||
case ProjectType.industrial:
|
||||
return 'Công nghiệp';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// App Metadata
|
||||
// ============================================================================
|
||||
|
||||
/// Application constants
|
||||
class AppConstants {
|
||||
// Private constructor to prevent instantiation
|
||||
AppConstants._();
|
||||
|
||||
/// Application name
|
||||
static const String appName = 'Worker';
|
||||
|
||||
/// Full application name
|
||||
static const String appFullName = 'Worker - EuroTile & Vasta Stone';
|
||||
|
||||
/// Application version
|
||||
static const String appVersion = '1.0.0';
|
||||
|
||||
/// Build number
|
||||
static const int buildNumber = 1;
|
||||
|
||||
/// Company name
|
||||
static const String companyName = 'EuroTile & Vasta Stone';
|
||||
|
||||
/// Support email
|
||||
static const String supportEmail = 'support@worker.example.com';
|
||||
|
||||
/// Support phone number (Vietnamese format)
|
||||
static const String supportPhone = '1900 xxxx';
|
||||
|
||||
/// Website URL
|
||||
static const String websiteUrl = 'https://worker.example.com';
|
||||
|
||||
// ============================================================================
|
||||
// Pagination Settings
|
||||
// ============================================================================
|
||||
|
||||
/// Default page size for paginated lists
|
||||
static const int defaultPageSize = 20;
|
||||
|
||||
/// Products page size
|
||||
static const int productsPageSize = 20;
|
||||
|
||||
/// Orders page size
|
||||
static const int ordersPageSize = 10;
|
||||
|
||||
/// Projects page size
|
||||
static const int projectsPageSize = 15;
|
||||
|
||||
/// Notifications page size
|
||||
static const int notificationsPageSize = 25;
|
||||
|
||||
/// Points history page size
|
||||
static const int pointsHistoryPageSize = 20;
|
||||
|
||||
/// Maximum items to load at once
|
||||
static const int maxPageSize = 100;
|
||||
|
||||
// ============================================================================
|
||||
// Cache Settings
|
||||
// ============================================================================
|
||||
|
||||
/// Cache duration for products (in hours)
|
||||
static const int productsCacheDuration = 24;
|
||||
|
||||
/// Cache duration for user profile (in hours)
|
||||
static const int profileCacheDuration = 1;
|
||||
|
||||
/// Cache duration for categories (in hours)
|
||||
static const int categoriesCacheDuration = 48;
|
||||
|
||||
/// Maximum cache size (in MB)
|
||||
static const int maxCacheSize = 100;
|
||||
|
||||
// ============================================================================
|
||||
// OTP Settings
|
||||
// ============================================================================
|
||||
|
||||
/// OTP code length (6 digits)
|
||||
static const int otpLength = 6;
|
||||
|
||||
/// OTP resend cooldown (in seconds)
|
||||
static const int otpResendCooldown = 60;
|
||||
|
||||
/// OTP validity duration (in minutes)
|
||||
static const int otpValidityMinutes = 5;
|
||||
|
||||
// ============================================================================
|
||||
// Referral Settings
|
||||
// ============================================================================
|
||||
|
||||
/// Points earned per successful referral
|
||||
static const int pointsPerReferral = 100;
|
||||
|
||||
/// Points earned by the referred user on signup
|
||||
static const int welcomeBonusPoints = 50;
|
||||
|
||||
// ============================================================================
|
||||
// Order Settings
|
||||
// ============================================================================
|
||||
|
||||
/// Minimum order amount (in VND)
|
||||
static const double minOrderAmount = 100000; // 100,000 VND
|
||||
|
||||
/// Free shipping threshold (in VND)
|
||||
static const double freeShippingThreshold = 1000000; // 1,000,000 VND
|
||||
|
||||
/// Standard shipping fee (in VND)
|
||||
static const double standardShippingFee = 30000; // 30,000 VND
|
||||
|
||||
/// Maximum items per order
|
||||
static const int maxItemsPerOrder = 50;
|
||||
|
||||
// ============================================================================
|
||||
// Image Settings
|
||||
// ============================================================================
|
||||
|
||||
/// Maximum avatar size (in MB)
|
||||
static const int maxAvatarSize = 5;
|
||||
|
||||
/// Maximum product image size (in MB)
|
||||
static const int maxProductImageSize = 3;
|
||||
|
||||
/// Supported image formats
|
||||
static const List<String> supportedImageFormats = ['jpg', 'jpeg', 'png', 'webp'];
|
||||
|
||||
/// Image quality for compression (0-100)
|
||||
static const int imageQuality = 85;
|
||||
|
||||
// ============================================================================
|
||||
// Search Settings
|
||||
// ============================================================================
|
||||
|
||||
/// Minimum search query length
|
||||
static const int minSearchLength = 2;
|
||||
|
||||
/// Search debounce delay (in milliseconds)
|
||||
static const int searchDebounceMs = 500;
|
||||
|
||||
/// Maximum search results
|
||||
static const int maxSearchResults = 50;
|
||||
|
||||
// ============================================================================
|
||||
// Date & Time Settings
|
||||
// ============================================================================
|
||||
|
||||
/// Default date format (Vietnamese: dd/MM/yyyy)
|
||||
static const String dateFormat = 'dd/MM/yyyy';
|
||||
|
||||
/// Date time format
|
||||
static const String dateTimeFormat = 'dd/MM/yyyy HH:mm';
|
||||
|
||||
/// Time format (24-hour)
|
||||
static const String timeFormat = 'HH:mm';
|
||||
|
||||
/// Full date time format
|
||||
static const String fullDateTimeFormat = 'EEEE, dd MMMM yyyy HH:mm';
|
||||
|
||||
// ============================================================================
|
||||
// Validation Settings
|
||||
// ============================================================================
|
||||
|
||||
/// Minimum password length
|
||||
static const int minPasswordLength = 8;
|
||||
|
||||
/// Maximum password length
|
||||
static const int maxPasswordLength = 50;
|
||||
|
||||
/// Minimum name length
|
||||
static const int minNameLength = 2;
|
||||
|
||||
/// Maximum name length
|
||||
static const int maxNameLength = 100;
|
||||
|
||||
/// Vietnamese phone number regex pattern
|
||||
/// Matches: 0912345678, +84912345678, 84912345678
|
||||
static const String phoneRegexPattern = r'^(0|\+84|84)[3|5|7|8|9][0-9]{8}$';
|
||||
|
||||
/// Email regex pattern
|
||||
static const String emailRegexPattern = r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$';
|
||||
|
||||
// ============================================================================
|
||||
// Feature Flags
|
||||
// ============================================================================
|
||||
|
||||
/// Enable dark mode
|
||||
static const bool enableDarkMode = true;
|
||||
|
||||
/// Enable biometric authentication
|
||||
static const bool enableBiometric = true;
|
||||
|
||||
/// Enable push notifications
|
||||
static const bool enablePushNotifications = true;
|
||||
|
||||
/// Enable offline mode
|
||||
static const bool enableOfflineMode = true;
|
||||
|
||||
/// Enable analytics
|
||||
static const bool enableAnalytics = true;
|
||||
|
||||
/// Enable crash reporting
|
||||
static const bool enableCrashReporting = true;
|
||||
}
|
||||
211
lib/core/constants/storage_constants.dart
Normal file
211
lib/core/constants/storage_constants.dart
Normal file
@@ -0,0 +1,211 @@
|
||||
/// Storage constants for Hive CE (Community Edition) database
|
||||
///
|
||||
/// This file contains all box names, keys, and type IDs used throughout the app
|
||||
/// for local data persistence and offline-first functionality.
|
||||
library;
|
||||
|
||||
/// Hive Box Names
|
||||
///
|
||||
/// These are the names of Hive boxes used in the application.
|
||||
/// Each box stores a specific type of data for organized storage.
|
||||
class HiveBoxNames {
|
||||
// Private constructor to prevent instantiation
|
||||
HiveBoxNames._();
|
||||
|
||||
/// User authentication and profile data
|
||||
static const String userBox = 'user_box';
|
||||
|
||||
/// Product catalog and details cache
|
||||
static const String productBox = 'product_box';
|
||||
|
||||
/// Shopping cart items
|
||||
static const String cartBox = 'cart_box';
|
||||
|
||||
/// Order history and details
|
||||
static const String orderBox = 'order_box';
|
||||
|
||||
/// Construction projects
|
||||
static const String projectBox = 'project_box';
|
||||
|
||||
/// Loyalty program transactions and points history
|
||||
static const String loyaltyBox = 'loyalty_box';
|
||||
|
||||
/// Rewards and gifts catalog
|
||||
static const String rewardsBox = 'rewards_box';
|
||||
|
||||
/// User settings and preferences
|
||||
static const String settingsBox = 'settings_box';
|
||||
|
||||
/// API response cache for offline access
|
||||
static const String cacheBox = 'cache_box';
|
||||
|
||||
/// Data sync state tracking
|
||||
static const String syncStateBox = 'sync_state_box';
|
||||
|
||||
/// Notifications
|
||||
static const String notificationBox = 'notification_box';
|
||||
|
||||
/// Address book
|
||||
static const String addressBox = 'address_box';
|
||||
|
||||
/// Offline request queue for failed API calls
|
||||
static const String offlineQueueBox = 'offline_queue_box';
|
||||
|
||||
/// Get all box names for initialization
|
||||
static List<String> get allBoxes => [
|
||||
userBox,
|
||||
productBox,
|
||||
cartBox,
|
||||
orderBox,
|
||||
projectBox,
|
||||
loyaltyBox,
|
||||
rewardsBox,
|
||||
settingsBox,
|
||||
cacheBox,
|
||||
syncStateBox,
|
||||
notificationBox,
|
||||
addressBox,
|
||||
offlineQueueBox,
|
||||
];
|
||||
}
|
||||
|
||||
/// Hive Type Adapter IDs
|
||||
///
|
||||
/// Type IDs must be unique across the application.
|
||||
/// Range 0-223 is reserved for user-defined types.
|
||||
/// IMPORTANT: Never change these IDs once assigned, as it will break existing data.
|
||||
class HiveTypeIds {
|
||||
// Private constructor to prevent instantiation
|
||||
HiveTypeIds._();
|
||||
|
||||
// Core Models (0-9)
|
||||
static const int user = 0;
|
||||
static const int product = 1;
|
||||
static const int cartItem = 2;
|
||||
static const int order = 3;
|
||||
static const int project = 4;
|
||||
static const int loyaltyTransaction = 5;
|
||||
|
||||
// Extended Models (10-19)
|
||||
static const int orderItem = 10;
|
||||
static const int address = 11;
|
||||
static const int category = 12;
|
||||
static const int reward = 13;
|
||||
static const int gift = 14;
|
||||
static const int notification = 15;
|
||||
static const int quote = 16;
|
||||
static const int payment = 17;
|
||||
static const int promotion = 18;
|
||||
static const int referral = 19;
|
||||
|
||||
// Enums (20-29)
|
||||
static const int memberTier = 20;
|
||||
static const int userType = 21;
|
||||
static const int orderStatus = 22;
|
||||
static const int projectStatus = 23;
|
||||
static const int projectType = 24;
|
||||
static const int transactionType = 25;
|
||||
static const int giftStatus = 26;
|
||||
static const int paymentStatus = 27;
|
||||
static const int notificationType = 28;
|
||||
static const int paymentMethod = 29;
|
||||
|
||||
// Cache & Sync Models (30-39)
|
||||
static const int cachedData = 30;
|
||||
static const int syncState = 31;
|
||||
static const int offlineRequest = 32;
|
||||
}
|
||||
|
||||
/// Hive Storage Keys
|
||||
///
|
||||
/// Keys used to store and retrieve data from Hive boxes.
|
||||
class HiveKeys {
|
||||
// Private constructor to prevent instantiation
|
||||
HiveKeys._();
|
||||
|
||||
// User Box Keys
|
||||
static const String currentUser = 'current_user';
|
||||
static const String authToken = 'auth_token';
|
||||
static const String refreshToken = 'refresh_token';
|
||||
static const String isLoggedIn = 'is_logged_in';
|
||||
|
||||
// Settings Box Keys
|
||||
static const String languageCode = 'language_code';
|
||||
static const String themeMode = 'theme_mode';
|
||||
static const String notificationsEnabled = 'notifications_enabled';
|
||||
static const String lastSyncTime = 'last_sync_time';
|
||||
static const String schemaVersion = 'schema_version';
|
||||
static const String encryptionEnabled = 'encryption_enabled';
|
||||
|
||||
// Cache Box Keys
|
||||
static const String productsCacheKey = 'products_cache';
|
||||
static const String categoriesCacheKey = 'categories_cache';
|
||||
static const String promotionsCacheKey = 'promotions_cache';
|
||||
static const String loyaltyPointsCacheKey = 'loyalty_points_cache';
|
||||
static const String rewardsCacheKey = 'rewards_cache';
|
||||
|
||||
// Sync State Box Keys
|
||||
static const String productsSyncTime = 'products_sync_time';
|
||||
static const String ordersSyncTime = 'orders_sync_time';
|
||||
static const String projectsSyncTime = 'projects_sync_time';
|
||||
static const String loyaltySyncTime = 'loyalty_sync_time';
|
||||
static const String lastFullSyncTime = 'last_full_sync_time';
|
||||
|
||||
// App State Keys
|
||||
static const String firstLaunch = 'first_launch';
|
||||
static const String onboardingCompleted = 'onboarding_completed';
|
||||
static const String appVersion = 'app_version';
|
||||
}
|
||||
|
||||
/// Cache Duration Constants
|
||||
///
|
||||
/// Default cache expiration durations for different data types.
|
||||
class CacheDuration {
|
||||
// Private constructor to prevent instantiation
|
||||
CacheDuration._();
|
||||
|
||||
/// Product data cache (6 hours)
|
||||
static const Duration products = Duration(hours: 6);
|
||||
|
||||
/// Category data cache (24 hours)
|
||||
static const Duration categories = Duration(hours: 24);
|
||||
|
||||
/// Loyalty points cache (1 hour)
|
||||
static const Duration loyaltyPoints = Duration(hours: 1);
|
||||
|
||||
/// Rewards cache (12 hours)
|
||||
static const Duration rewards = Duration(hours: 12);
|
||||
|
||||
/// Promotions cache (2 hours)
|
||||
static const Duration promotions = Duration(hours: 2);
|
||||
|
||||
/// User profile cache (30 minutes)
|
||||
static const Duration userProfile = Duration(minutes: 30);
|
||||
|
||||
/// Order history cache (5 minutes)
|
||||
static const Duration orderHistory = Duration(minutes: 5);
|
||||
|
||||
/// Projects cache (10 minutes)
|
||||
static const Duration projects = Duration(minutes: 10);
|
||||
}
|
||||
|
||||
/// Database Configuration
|
||||
class HiveDatabaseConfig {
|
||||
// Private constructor to prevent instantiation
|
||||
HiveDatabaseConfig._();
|
||||
|
||||
/// Current schema version for migrations
|
||||
static const int currentSchemaVersion = 1;
|
||||
|
||||
/// Maximum cache size in MB
|
||||
static const int maxCacheSizeMB = 100;
|
||||
|
||||
/// Maximum number of items in offline queue
|
||||
static const int maxOfflineQueueSize = 100;
|
||||
|
||||
/// Enable encryption for sensitive data
|
||||
static const bool enableEncryption = false; // Set to true in production
|
||||
|
||||
/// Compaction threshold (compact when box size grows by this percentage)
|
||||
static const double compactionThreshold = 0.3; // 30%
|
||||
}
|
||||
467
lib/core/constants/ui_constants.dart
Normal file
467
lib/core/constants/ui_constants.dart
Normal file
@@ -0,0 +1,467 @@
|
||||
/// UI Constants for the Worker App
|
||||
///
|
||||
/// Contains spacing, sizes, border radius, elevation values, and other
|
||||
/// UI-related constants used throughout the app.
|
||||
library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Spacing constants following Material Design 8dp grid system
|
||||
class AppSpacing {
|
||||
AppSpacing._();
|
||||
|
||||
/// Extra small spacing: 4dp
|
||||
static const double xs = 4.0;
|
||||
|
||||
/// Small spacing: 8dp
|
||||
static const double sm = 8.0;
|
||||
|
||||
/// Medium spacing: 16dp
|
||||
static const double md = 16.0;
|
||||
|
||||
/// Large spacing: 24dp
|
||||
static const double lg = 24.0;
|
||||
|
||||
/// Extra large spacing: 32dp
|
||||
static const double xl = 32.0;
|
||||
|
||||
/// Extra extra large spacing: 48dp
|
||||
static const double xxl = 48.0;
|
||||
}
|
||||
|
||||
/// Border radius constants
|
||||
class AppRadius {
|
||||
AppRadius._();
|
||||
|
||||
/// Small radius: 4dp
|
||||
static const double sm = 4.0;
|
||||
|
||||
/// Medium radius: 8dp
|
||||
static const double md = 8.0;
|
||||
|
||||
/// Large radius: 12dp
|
||||
static const double lg = 12.0;
|
||||
|
||||
/// Extra large radius: 16dp
|
||||
static const double xl = 16.0;
|
||||
|
||||
/// Card radius: 12dp
|
||||
static const double card = 12.0;
|
||||
|
||||
/// Button radius: 8dp
|
||||
static const double button = 8.0;
|
||||
|
||||
/// Input field radius: 8dp
|
||||
static const double input = 8.0;
|
||||
|
||||
/// Member card radius: 16dp
|
||||
static const double memberCard = 16.0;
|
||||
|
||||
/// Circular radius for avatars and badges
|
||||
static const double circular = 9999.0;
|
||||
}
|
||||
|
||||
/// Elevation constants for Material Design
|
||||
class AppElevation {
|
||||
AppElevation._();
|
||||
|
||||
/// No elevation
|
||||
static const double none = 0.0;
|
||||
|
||||
/// Low elevation: 2dp
|
||||
static const double low = 2.0;
|
||||
|
||||
/// Medium elevation: 4dp
|
||||
static const double medium = 4.0;
|
||||
|
||||
/// High elevation: 8dp
|
||||
static const double high = 8.0;
|
||||
|
||||
/// Card elevation: 2dp
|
||||
static const double card = 2.0;
|
||||
|
||||
/// Button elevation: 2dp
|
||||
static const double button = 2.0;
|
||||
|
||||
/// FAB elevation: 6dp
|
||||
static const double fab = 6.0;
|
||||
|
||||
/// Member card elevation: 8dp
|
||||
static const double memberCard = 8.0;
|
||||
}
|
||||
|
||||
/// Icon size constants
|
||||
class AppIconSize {
|
||||
AppIconSize._();
|
||||
|
||||
/// Extra small icon: 16dp
|
||||
static const double xs = 16.0;
|
||||
|
||||
/// Small icon: 20dp
|
||||
static const double sm = 20.0;
|
||||
|
||||
/// Medium icon: 24dp
|
||||
static const double md = 24.0;
|
||||
|
||||
/// Large icon: 32dp
|
||||
static const double lg = 32.0;
|
||||
|
||||
/// Extra large icon: 48dp
|
||||
static const double xl = 48.0;
|
||||
}
|
||||
|
||||
/// App bar specifications
|
||||
class AppBarSpecs {
|
||||
AppBarSpecs._();
|
||||
|
||||
/// Standard app bar height
|
||||
static const double height = 56.0;
|
||||
|
||||
/// App bar elevation
|
||||
static const double elevation = 0.0;
|
||||
|
||||
/// App bar icon size
|
||||
static const double iconSize = AppIconSize.md;
|
||||
}
|
||||
|
||||
/// Bottom navigation bar specifications
|
||||
class BottomNavSpecs {
|
||||
BottomNavSpecs._();
|
||||
|
||||
/// Bottom nav bar height
|
||||
static const double height = 72.0;
|
||||
|
||||
/// Icon size for unselected state
|
||||
static const double iconSize = 24.0;
|
||||
|
||||
/// Icon size for selected state
|
||||
static const double selectedIconSize = 28.0;
|
||||
|
||||
/// Label font size
|
||||
static const double labelFontSize = 12.0;
|
||||
|
||||
/// Bottom nav bar elevation
|
||||
static const double elevation = 8.0;
|
||||
}
|
||||
|
||||
/// Floating Action Button specifications
|
||||
class FABSpecs {
|
||||
FABSpecs._();
|
||||
|
||||
/// FAB size
|
||||
static const double size = 56.0;
|
||||
|
||||
/// FAB elevation
|
||||
static const double elevation = 6.0;
|
||||
|
||||
/// FAB icon size
|
||||
static const double iconSize = 24.0;
|
||||
|
||||
/// FAB position from bottom-right
|
||||
static const Offset position = Offset(16, 16);
|
||||
}
|
||||
|
||||
/// Member card specifications
|
||||
class MemberCardSpecs {
|
||||
MemberCardSpecs._();
|
||||
|
||||
/// Card width (full width)
|
||||
static const double width = double.infinity;
|
||||
|
||||
/// Card height
|
||||
static const double height = 200.0;
|
||||
|
||||
/// Border radius
|
||||
static const double borderRadius = AppRadius.memberCard;
|
||||
|
||||
/// Card elevation
|
||||
static const double elevation = AppElevation.memberCard;
|
||||
|
||||
/// Card padding
|
||||
static const EdgeInsets padding = EdgeInsets.all(20.0);
|
||||
|
||||
/// QR code size
|
||||
static const double qrSize = 80.0;
|
||||
|
||||
/// QR code background size
|
||||
static const double qrBackgroundSize = 90.0;
|
||||
|
||||
/// Points display font size
|
||||
static const double pointsFontSize = 28.0;
|
||||
|
||||
/// Points display font weight
|
||||
static const FontWeight pointsFontWeight = FontWeight.bold;
|
||||
|
||||
/// Member ID font size
|
||||
static const double memberIdFontSize = 14.0;
|
||||
|
||||
/// Member name font size
|
||||
static const double memberNameFontSize = 18.0;
|
||||
}
|
||||
|
||||
/// Button specifications
|
||||
class ButtonSpecs {
|
||||
ButtonSpecs._();
|
||||
|
||||
/// Button height
|
||||
static const double height = 48.0;
|
||||
|
||||
/// Button minimum width
|
||||
static const double minWidth = 120.0;
|
||||
|
||||
/// Button border radius
|
||||
static const double borderRadius = AppRadius.button;
|
||||
|
||||
/// Button elevation
|
||||
static const double elevation = AppElevation.button;
|
||||
|
||||
/// Button padding
|
||||
static const EdgeInsets padding = EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.lg,
|
||||
vertical: AppSpacing.md,
|
||||
);
|
||||
|
||||
/// Button font size
|
||||
static const double fontSize = 16.0;
|
||||
|
||||
/// Button font weight
|
||||
static const FontWeight fontWeight = FontWeight.w600;
|
||||
}
|
||||
|
||||
/// Input field specifications
|
||||
class InputFieldSpecs {
|
||||
InputFieldSpecs._();
|
||||
|
||||
/// Input field height
|
||||
static const double height = 56.0;
|
||||
|
||||
/// Input field border radius
|
||||
static const double borderRadius = AppRadius.input;
|
||||
|
||||
/// Input field content padding
|
||||
static const EdgeInsets contentPadding = EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.md,
|
||||
vertical: AppSpacing.md,
|
||||
);
|
||||
|
||||
/// Input field font size
|
||||
static const double fontSize = 16.0;
|
||||
|
||||
/// Label font size
|
||||
static const double labelFontSize = 14.0;
|
||||
|
||||
/// Hint font size
|
||||
static const double hintFontSize = 14.0;
|
||||
}
|
||||
|
||||
/// Card specifications
|
||||
class CardSpecs {
|
||||
CardSpecs._();
|
||||
|
||||
/// Card border radius
|
||||
static const double borderRadius = AppRadius.card;
|
||||
|
||||
/// Card elevation
|
||||
static const double elevation = AppElevation.card;
|
||||
|
||||
/// Card padding
|
||||
static const EdgeInsets padding = EdgeInsets.all(AppSpacing.md);
|
||||
|
||||
/// Card margin
|
||||
static const EdgeInsets margin = EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.md,
|
||||
vertical: AppSpacing.sm,
|
||||
);
|
||||
}
|
||||
|
||||
/// Product card specifications
|
||||
class ProductCardSpecs {
|
||||
ProductCardSpecs._();
|
||||
|
||||
/// Product image aspect ratio (width / height)
|
||||
static const double imageAspectRatio = 1.0;
|
||||
|
||||
/// Product card border radius
|
||||
static const double borderRadius = AppRadius.card;
|
||||
|
||||
/// Product card elevation
|
||||
static const double elevation = AppElevation.card;
|
||||
|
||||
/// Product card padding
|
||||
static const EdgeInsets padding = EdgeInsets.all(AppSpacing.sm);
|
||||
|
||||
/// Product name max lines
|
||||
static const int nameMaxLines = 2;
|
||||
|
||||
/// Product name font size
|
||||
static const double nameFontSize = 14.0;
|
||||
|
||||
/// Product price font size
|
||||
static const double priceFontSize = 16.0;
|
||||
|
||||
/// Product price font weight
|
||||
static const FontWeight priceFontWeight = FontWeight.bold;
|
||||
}
|
||||
|
||||
/// Order card specifications
|
||||
class OrderCardSpecs {
|
||||
OrderCardSpecs._();
|
||||
|
||||
/// Order number font size
|
||||
static const double orderNumberFontSize = 16.0;
|
||||
|
||||
/// Order number font weight
|
||||
static const FontWeight orderNumberFontWeight = FontWeight.w600;
|
||||
|
||||
/// Order date font size
|
||||
static const double dateFontSize = 12.0;
|
||||
|
||||
/// Order total font size
|
||||
static const double totalFontSize = 18.0;
|
||||
|
||||
/// Order total font weight
|
||||
static const FontWeight totalFontWeight = FontWeight.bold;
|
||||
}
|
||||
|
||||
/// Status badge specifications
|
||||
class StatusBadgeSpecs {
|
||||
StatusBadgeSpecs._();
|
||||
|
||||
/// Badge height
|
||||
static const double height = 24.0;
|
||||
|
||||
/// Badge border radius
|
||||
static const double borderRadius = 12.0;
|
||||
|
||||
/// Badge padding
|
||||
static const EdgeInsets padding = EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.sm,
|
||||
vertical: 2.0,
|
||||
);
|
||||
|
||||
/// Badge font size
|
||||
static const double fontSize = 11.0;
|
||||
|
||||
/// Badge font weight
|
||||
static const FontWeight fontWeight = FontWeight.w600;
|
||||
}
|
||||
|
||||
/// Avatar specifications
|
||||
class AvatarSpecs {
|
||||
AvatarSpecs._();
|
||||
|
||||
/// Small avatar size
|
||||
static const double sm = 32.0;
|
||||
|
||||
/// Medium avatar size
|
||||
static const double md = 48.0;
|
||||
|
||||
/// Large avatar size
|
||||
static const double lg = 64.0;
|
||||
|
||||
/// Extra large avatar size
|
||||
static const double xl = 96.0;
|
||||
}
|
||||
|
||||
/// Animation durations
|
||||
class AppDuration {
|
||||
AppDuration._();
|
||||
|
||||
/// Short animation: 200ms
|
||||
static const Duration short = Duration(milliseconds: 200);
|
||||
|
||||
/// Medium animation: 300ms
|
||||
static const Duration medium = Duration(milliseconds: 300);
|
||||
|
||||
/// Long animation: 500ms
|
||||
static const Duration long = Duration(milliseconds: 500);
|
||||
|
||||
/// Page transition duration
|
||||
static const Duration pageTransition = medium;
|
||||
|
||||
/// Fade in duration
|
||||
static const Duration fadeIn = medium;
|
||||
|
||||
/// Shimmer animation duration
|
||||
static const Duration shimmer = Duration(milliseconds: 1500);
|
||||
}
|
||||
|
||||
/// Grid specifications
|
||||
class GridSpecs {
|
||||
GridSpecs._();
|
||||
|
||||
/// Product grid cross axis count (columns)
|
||||
static const int productGridColumns = 2;
|
||||
|
||||
/// Product grid cross axis spacing
|
||||
static const double productGridCrossSpacing = AppSpacing.md;
|
||||
|
||||
/// Product grid main axis spacing
|
||||
static const double productGridMainSpacing = AppSpacing.md;
|
||||
|
||||
/// Quick action grid cross axis count
|
||||
static const int quickActionColumns = 3;
|
||||
|
||||
/// Quick action grid cross axis spacing
|
||||
static const double quickActionCrossSpacing = AppSpacing.md;
|
||||
|
||||
/// Quick action grid main axis spacing
|
||||
static const double quickActionMainSpacing = AppSpacing.md;
|
||||
}
|
||||
|
||||
/// List specifications
|
||||
class ListSpecs {
|
||||
ListSpecs._();
|
||||
|
||||
/// List item padding
|
||||
static const EdgeInsets itemPadding = EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.md,
|
||||
vertical: AppSpacing.sm,
|
||||
);
|
||||
|
||||
/// List item divider height
|
||||
static const double dividerHeight = 1.0;
|
||||
|
||||
/// List item divider indent
|
||||
static const double dividerIndent = AppSpacing.md;
|
||||
}
|
||||
|
||||
/// Image specifications
|
||||
class ImageSpecs {
|
||||
ImageSpecs._();
|
||||
|
||||
/// Product image cache width
|
||||
static const int productImageCacheWidth = 400;
|
||||
|
||||
/// Product image cache height
|
||||
static const int productImageCacheHeight = 400;
|
||||
|
||||
/// Avatar image cache width
|
||||
static const int avatarImageCacheWidth = 200;
|
||||
|
||||
/// Avatar image cache height
|
||||
static const int avatarImageCacheHeight = 200;
|
||||
|
||||
/// Banner image cache width
|
||||
static const int bannerImageCacheWidth = 800;
|
||||
|
||||
/// Banner image cache height
|
||||
static const int bannerImageCacheHeight = 400;
|
||||
}
|
||||
|
||||
/// Screen breakpoints for responsive design
|
||||
class Breakpoints {
|
||||
Breakpoints._();
|
||||
|
||||
/// Small screen (phone)
|
||||
static const double sm = 600.0;
|
||||
|
||||
/// Medium screen (tablet)
|
||||
static const double md = 960.0;
|
||||
|
||||
/// Large screen (desktop)
|
||||
static const double lg = 1280.0;
|
||||
|
||||
/// Extra large screen
|
||||
static const double xl = 1920.0;
|
||||
}
|
||||
Reference in New Issue
Block a user