feat: adopt material 3 theme and billing adjustments

This commit is contained in:
JiWoong Sul
2025-09-16 14:30:14 +09:00
parent a01d9092ba
commit 44850a53cc
85 changed files with 2957 additions and 2776 deletions

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import '../../theme/app_colors.dart';
// import '../../theme/app_colors.dart';
import '../../widgets/themed_text.dart';
import '../../widgets/common/buttons/primary_button.dart';
import '../../widgets/native_ad_widget.dart';
@@ -32,7 +32,7 @@ class ScanInitialWidget extends StatelessWidget {
padding: const EdgeInsets.only(bottom: 24.0),
child: ThemedText(
errorMessage!,
color: Colors.red,
color: Theme.of(context).colorScheme.error,
textAlign: TextAlign.center,
),
),
@@ -59,7 +59,7 @@ class ScanInitialWidget extends StatelessWidget {
onPressed: onScanPressed,
width: 200,
height: 56,
backgroundColor: AppColors.primaryColor,
backgroundColor: Theme.of(context).colorScheme.primary,
),
],
),

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import '../../theme/app_colors.dart';
// import '../../theme/app_colors.dart';
import '../../widgets/themed_text.dart';
import '../../l10n/app_localizations.dart';
@@ -14,8 +14,8 @@ class ScanLoadingWidget extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(AppColors.primaryColor),
CircularProgressIndicator(
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 16),
ThemedText(

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import '../../theme/app_colors.dart';
// Material colors only
import '../../widgets/themed_text.dart';
class ScanProgressWidget extends StatelessWidget {
@@ -20,7 +20,10 @@ class ScanProgressWidget extends StatelessWidget {
// 진행 상태 표시
LinearProgressIndicator(
value: (currentIndex + 1) / totalCount,
backgroundColor: AppColors.navyGray.withValues(alpha: 0.2),
backgroundColor: Theme.of(context)
.colorScheme
.onSurfaceVariant
.withValues(alpha: 0.2),
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).colorScheme.primary,
),

View File

@@ -10,7 +10,6 @@ import '../../widgets/common/form_fields/base_text_field.dart';
import '../../widgets/common/form_fields/category_selector.dart';
import '../../widgets/common/snackbar/app_snackbar.dart';
import '../../widgets/native_ad_widget.dart';
import '../../theme/app_colors.dart';
import '../../services/currency_util.dart';
import '../../utils/sms_scan/date_formatter.dart';
import '../../utils/sms_scan/category_icon_mapper.dart';
@@ -74,57 +73,50 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// 구독 정보 카드
ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: AppColors.glassCard,
borderRadius: BorderRadius.circular(16.0),
border: Border.all(
color: AppColors.glassBorder,
width: 1,
),
boxShadow: const [
BoxShadow(
color: AppColors.shadowBlack,
blurRadius: 20,
spreadRadius: -5,
offset: Offset(0, 10),
),
],
Card(
elevation: 1,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
side: BorderSide(
color: Theme.of(context)
.colorScheme
.outline
.withValues(alpha: 0.4),
),
child: Column(
children: [
// 클릭 가능한 정보 영역
Material(
color: Colors.transparent,
child: InkWell(
onTap: _handleCardTap,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: _buildInfoSection(categoryProvider),
),
),
child: Column(
children: [
// 클릭 가능한 정보 영역
Material(
color: Colors.transparent,
child: InkWell(
onTap: _handleCardTap,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: _buildInfoSection(categoryProvider),
),
),
),
// 구분선
Container(
height: 1,
color: AppColors.navyGray.withValues(alpha: 0.1),
),
// 구분선
Container(
height: 1,
color: Theme.of(context)
.colorScheme
.onSurfaceVariant
.withValues(alpha: 0.1),
),
// 클릭 불가능한 액션 영역
Padding(
padding: const EdgeInsets.all(16.0),
child: _buildActionSection(categoryProvider),
),
],
),
// 클릭 불가능한 액션 영역
Padding(
padding: const EdgeInsets.all(16.0),
child: _buildActionSection(categoryProvider),
),
],
),
),
],
@@ -143,7 +135,6 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
AppLocalizations.of(context).foundSubscription,
fontSize: 18,
fontWeight: FontWeight.bold,
forceDark: true,
),
const SizedBox(height: 24),
@@ -152,14 +143,12 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
AppLocalizations.of(context).serviceName,
fontWeight: FontWeight.w500,
opacity: 0.7,
forceDark: true,
),
const SizedBox(height: 4),
ThemedText(
widget.subscription.serviceName,
fontSize: 22,
fontWeight: FontWeight.bold,
forceDark: true,
),
const SizedBox(height: 16),
@@ -174,7 +163,6 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
AppLocalizations.of(context).monthlyCost,
fontWeight: FontWeight.w500,
opacity: 0.7,
forceDark: true,
),
const SizedBox(height: 4),
// 언어별 통화 표시
@@ -189,7 +177,6 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
snapshot.data ?? '-',
fontSize: 18,
fontWeight: FontWeight.bold,
forceDark: true,
);
},
),
@@ -204,14 +191,12 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
AppLocalizations.of(context).billingCycle,
fontWeight: FontWeight.w500,
opacity: 0.7,
forceDark: true,
),
const SizedBox(height: 4),
ThemedText(
widget.subscription.billingCycle,
fontSize: 16,
fontWeight: FontWeight.w500,
forceDark: true,
),
],
),
@@ -225,7 +210,6 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
AppLocalizations.of(context).nextBillingDateLabel,
fontWeight: FontWeight.w500,
opacity: 0.7,
forceDark: true,
),
const SizedBox(height: 4),
ThemedText(
@@ -236,7 +220,6 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
),
fontSize: 16,
fontWeight: FontWeight.w500,
forceDark: true,
),
],
);
@@ -252,7 +235,6 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
AppLocalizations.of(context).category,
fontWeight: FontWeight.w500,
opacity: 0.7,
forceDark: true,
),
const SizedBox(height: 8),
CategorySelector(
@@ -261,7 +243,6 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
widget.selectedCategoryId ?? widget.subscription.category,
onChanged: widget.onCategoryChanged,
baseColor: _getCategoryColor(categoryProvider),
isGlassmorphism: true,
),
const SizedBox(height: 24),
@@ -270,14 +251,14 @@ class _SubscriptionCardWidgetState extends State<SubscriptionCardWidget> {
controller: widget.websiteUrlController,
label: AppLocalizations.of(context).websiteUrlAuto,
hintText: AppLocalizations.of(context).websiteUrlHint,
prefixIcon: const Icon(
prefixIcon: Icon(
Icons.language,
color: AppColors.navyGray,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
style: const TextStyle(
color: AppColors.darkNavy,
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
),
fillColor: AppColors.pureWhite.withValues(alpha: 0.8),
fillColor: Theme.of(context).colorScheme.surface,
),
const SizedBox(height: 32),