add auth, format

This commit is contained in:
Phuoc Nguyen
2025-11-07 11:52:06 +07:00
parent 24a8508fce
commit 3803bd26e0
173 changed files with 8505 additions and 7116 deletions

View File

@@ -47,9 +47,8 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
}
@override
Size get preferredSize => Size.fromHeight(
AppBarSpecs.height + (bottom?.preferredSize.height ?? 0),
);
Size get preferredSize =>
Size.fromHeight(AppBarSpecs.height + (bottom?.preferredSize.height ?? 0));
}
/// Transparent app bar for overlay scenarios
@@ -110,7 +109,8 @@ class SearchAppBar extends StatelessWidget implements PreferredSizeWidget {
@override
Widget build(BuildContext context) {
return AppBar(
leading: leading ??
leading:
leading ??
IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Navigator.of(context).pop(),

View File

@@ -113,7 +113,8 @@ class _DatePickerFieldState extends State<DatePickerField> {
readOnly: true,
enabled: widget.enabled,
onTap: () => _selectDate(context),
decoration: widget.decoration ??
decoration:
widget.decoration ??
InputDecoration(
labelText: widget.labelText ?? 'Ngày',
hintText: widget.hintText ?? 'dd/MM/yyyy',
@@ -124,8 +125,7 @@ class _DatePickerFieldState extends State<DatePickerField> {
),
contentPadding: InputFieldSpecs.contentPadding,
),
validator: widget.validator ??
(widget.required ? Validators.date : null),
validator: widget.validator ?? (widget.required ? Validators.date : null),
);
}
}

View File

@@ -41,7 +41,8 @@ class GradientCard extends StatelessWidget {
decoration: BoxDecoration(
gradient: gradient,
borderRadius: BorderRadius.circular(borderRadius),
boxShadow: shadows ??
boxShadow:
shadows ??
[
BoxShadow(
color: Colors.black.withOpacity(0.1 * (elevation / 4)),

View File

@@ -37,7 +37,8 @@ class PriceDisplay extends StatelessWidget {
return Text(
formattedPrice,
style: style ??
style:
style ??
TextStyle(
color: color,
fontWeight: fontWeight ?? FontWeight.w600,
@@ -76,7 +77,8 @@ class SalePriceDisplay extends StatelessWidget {
// Sale price (larger, prominent)
Text(
CurrencyFormatter.format(salePrice, showSymbol: showSymbol),
style: salePriceStyle ??
style:
salePriceStyle ??
const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
@@ -87,7 +89,8 @@ class SalePriceDisplay extends StatelessWidget {
// Original price (smaller, strikethrough)
Text(
CurrencyFormatter.format(originalPrice, showSymbol: showSymbol),
style: originalPriceStyle ??
style:
originalPriceStyle ??
TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
@@ -131,7 +134,8 @@ class PriceWithDiscount extends StatelessWidget {
// Sale price
Text(
CurrencyFormatter.format(salePrice, showSymbol: showSymbol),
style: salePriceStyle ??
style:
salePriceStyle ??
const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
@@ -161,7 +165,8 @@ class PriceWithDiscount extends StatelessWidget {
// Original price
Text(
CurrencyFormatter.format(originalPrice, showSymbol: showSymbol),
style: originalPriceStyle ??
style:
originalPriceStyle ??
TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
@@ -217,10 +222,7 @@ class CompactPriceDisplay extends StatelessWidget {
return Text(
CurrencyFormatter.format(price, showSymbol: showSymbol),
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
);
}
}
@@ -246,13 +248,7 @@ class LargePriceDisplay extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (label != null) ...[
Text(
label!,
style: TextStyle(
fontSize: 14,
color: Colors.grey[600],
),
),
Text(label!, style: TextStyle(fontSize: 14, color: Colors.grey[600])),
const SizedBox(height: 4),
],
Text(

View File

@@ -30,104 +30,66 @@ class StatusBadge extends StatelessWidget {
});
/// Order status badges
factory StatusBadge.orderPending() => const StatusBadge(
label: 'Chờ xử lý',
color: AppColors.info,
);
factory StatusBadge.orderPending() =>
const StatusBadge(label: 'Chờ xử lý', color: AppColors.info);
factory StatusBadge.orderProcessing() => const StatusBadge(
label: 'Đang xử lý',
color: AppColors.warning,
);
factory StatusBadge.orderProcessing() =>
const StatusBadge(label: 'Đang xử lý', color: AppColors.warning);
factory StatusBadge.orderShipping() => const StatusBadge(
label: 'Đang giao',
color: AppColors.lightBlue,
);
factory StatusBadge.orderShipping() =>
const StatusBadge(label: 'Đang giao', color: AppColors.lightBlue);
factory StatusBadge.orderCompleted() => const StatusBadge(
label: 'Hoàn thành',
color: AppColors.success,
);
factory StatusBadge.orderCompleted() =>
const StatusBadge(label: 'Hoàn thành', color: AppColors.success);
factory StatusBadge.orderCancelled() => const StatusBadge(
label: 'Đã hủy',
color: AppColors.danger,
);
factory StatusBadge.orderCancelled() =>
const StatusBadge(label: 'Đã hủy', color: AppColors.danger);
/// Payment status badges
factory StatusBadge.paymentPending() => const StatusBadge(
label: 'Chờ thanh toán',
color: AppColors.warning,
);
factory StatusBadge.paymentPending() =>
const StatusBadge(label: 'Chờ thanh toán', color: AppColors.warning);
factory StatusBadge.paymentProcessing() => const StatusBadge(
label: 'Đang xử lý',
color: AppColors.info,
);
factory StatusBadge.paymentProcessing() =>
const StatusBadge(label: 'Đang xử lý', color: AppColors.info);
factory StatusBadge.paymentCompleted() => const StatusBadge(
label: 'Đã thanh toán',
color: AppColors.success,
);
factory StatusBadge.paymentCompleted() =>
const StatusBadge(label: 'Đã thanh toán', color: AppColors.success);
factory StatusBadge.paymentFailed() => const StatusBadge(
label: 'Thất bại',
color: AppColors.danger,
);
factory StatusBadge.paymentFailed() =>
const StatusBadge(label: 'Thất bại', color: AppColors.danger);
/// Project status badges
factory StatusBadge.projectPlanning() => const StatusBadge(
label: 'Lập kế hoạch',
color: AppColors.info,
);
factory StatusBadge.projectPlanning() =>
const StatusBadge(label: 'Lập kế hoạch', color: AppColors.info);
factory StatusBadge.projectInProgress() => const StatusBadge(
label: 'Đang thực hiện',
color: AppColors.warning,
);
factory StatusBadge.projectInProgress() =>
const StatusBadge(label: 'Đang thực hiện', color: AppColors.warning);
factory StatusBadge.projectCompleted() => const StatusBadge(
label: 'Hoàn thành',
color: AppColors.success,
);
factory StatusBadge.projectCompleted() =>
const StatusBadge(label: 'Hoàn thành', color: AppColors.success);
factory StatusBadge.projectOnHold() => const StatusBadge(
label: 'Tạm dừng',
color: AppColors.grey500,
);
factory StatusBadge.projectOnHold() =>
const StatusBadge(label: 'Tạm dừng', color: AppColors.grey500);
/// Gift status badges
factory StatusBadge.giftActive() => const StatusBadge(
label: 'Còn hạn',
color: AppColors.success,
);
factory StatusBadge.giftActive() =>
const StatusBadge(label: 'Còn hạn', color: AppColors.success);
factory StatusBadge.giftUsed() => const StatusBadge(
label: 'Đã sử dụng',
color: AppColors.grey500,
);
factory StatusBadge.giftUsed() =>
const StatusBadge(label: 'Đã sử dụng', color: AppColors.grey500);
factory StatusBadge.giftExpired() => const StatusBadge(
label: 'Hết hạn',
color: AppColors.danger,
);
factory StatusBadge.giftExpired() =>
const StatusBadge(label: 'Hết hạn', color: AppColors.danger);
/// Member tier badges
factory StatusBadge.tierDiamond() => const StatusBadge(
label: 'Kim Cương',
color: Color(0xFF4A00E0),
);
factory StatusBadge.tierDiamond() =>
const StatusBadge(label: 'Kim Cương', color: Color(0xFF4A00E0));
factory StatusBadge.tierPlatinum() => const StatusBadge(
label: 'Bạch Kim',
color: Color(0xFF7F8C8D),
);
factory StatusBadge.tierPlatinum() =>
const StatusBadge(label: 'Bạch Kim', color: Color(0xFF7F8C8D));
factory StatusBadge.tierGold() => const StatusBadge(
label: 'Vàng',
color: Color(0xFFf7b733),
);
factory StatusBadge.tierGold() =>
const StatusBadge(label: 'Vàng', color: Color(0xFFf7b733));
@override
Widget build(BuildContext context) {
@@ -224,11 +186,7 @@ class IconStatusBadge extends StatelessWidget {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
icon,
size: iconSize,
color: textColor ?? Colors.white,
),
Icon(icon, size: iconSize, color: textColor ?? Colors.white),
const SizedBox(width: 4),
Text(
label,

View File

@@ -6,9 +6,9 @@ library;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../core/utils/validators.dart';
import '../../core/utils/formatters.dart';
import '../../core/constants/ui_constants.dart';
import 'package:worker/core/constants/ui_constants.dart';
import 'package:worker/core/utils/formatters.dart';
import 'package:worker/core/utils/validators.dart';
/// Phone number input field with Vietnamese formatting
class VietnamesePhoneField extends StatefulWidget {
@@ -89,15 +89,15 @@ class _VietnamesePhoneFieldState extends State<VietnamesePhoneField> {
decoration: InputDecoration(
labelText: widget.labelText ?? 'Số điện thoại',
hintText: widget.hintText ?? '0xxx xxx xxx',
prefixIcon: widget.prefixIcon ??
const Icon(Icons.phone),
prefixIcon: widget.prefixIcon ?? const Icon(Icons.phone),
suffixIcon: widget.suffixIcon,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
),
contentPadding: InputFieldSpecs.contentPadding,
),
validator: widget.validator ??
validator:
widget.validator ??
(widget.required ? Validators.phone : Validators.phoneOptional),
onChanged: widget.onChanged,
onFieldSubmitted: widget.onSubmitted,