Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Hoàng Văn Đạt
mypoint_flutter_app
Commits
7777aa65
Commit
7777aa65
authored
May 13, 2025
by
DatHV
Browse files
cập nhật cashback affiliate
parent
56e8b038
Changes
44
Hide whitespace changes
Inline
Side-by-side
lib/screen/shopping/sub_widget/build_affiliate_brand.dart
0 → 100644
View file @
7777aa65
import
'package:flutter/material.dart'
;
import
'package:mypoint_flutter_app/extensions/string_extension.dart'
;
import
'../../../resouce/base_color.dart'
;
import
'../model/affiliate_brand_model.dart'
;
class
AffiliateBrand
extends
StatelessWidget
{
final
List
<
AffiliateBrandModel
>
brands
;
const
AffiliateBrand
({
super
.
key
,
required
this
.
brands
});
@override
Widget
build
(
BuildContext
context
)
{
if
(
brands
.
isEmpty
)
{
return
const
SizedBox
.
shrink
();
}
return
Column
(
children:
[
const
SizedBox
(
height:
24
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
const
Text
(
"Thương Hiệu Hoàn Điểm"
,
style:
TextStyle
(
fontWeight:
FontWeight
.
bold
,
fontSize:
20
)),
Text
(
"Xem tất cả"
,
style:
TextStyle
(
color:
BaseColor
.
primary400
,
fontSize:
14
,
fontWeight:
FontWeight
.
w600
)),
],
),
const
SizedBox
(
height:
12
),
GridView
.
builder
(
padding:
EdgeInsets
.
zero
,
shrinkWrap:
true
,
physics:
const
NeverScrollableScrollPhysics
(),
itemCount:
brands
.
length
,
gridDelegate:
const
SliverGridDelegateWithFixedCrossAxisCount
(
crossAxisCount:
3
,
childAspectRatio:
3
/
3.2
,
crossAxisSpacing:
8
,
mainAxisSpacing:
8
,
),
itemBuilder:
(
context
,
index
)
{
final
brand
=
brands
[
index
];
return
_buildAffiliateBrandItem
(
brand
);
},
),
],
);
}
Widget
_buildAffiliateBrandItem
(
AffiliateBrandModel
brand
)
{
return
LayoutBuilder
(
builder:
(
context
,
constraints
)
{
final
double
imageWidth
=
constraints
.
maxWidth
/
2
;
return
Container
(
padding:
const
EdgeInsets
.
all
(
12
),
decoration:
BoxDecoration
(
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
16
),
boxShadow:
[
BoxShadow
(
color:
Colors
.
black
.
withOpacity
(
0.05
),
blurRadius:
5
,
offset:
const
Offset
(
0
,
2
),
)
],
),
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
SizedBox
(
width:
imageWidth
,
height:
imageWidth
,
// ✅ 1:1 tỉ lệ
child:
ClipOval
(
child:
Image
.
network
(
brand
.
logo
??
''
,
fit:
BoxFit
.
contain
,
errorBuilder:
(
_
,
__
,
___
)
=>
const
Icon
(
Icons
.
broken_image
),
),
),
),
const
SizedBox
(
height:
4
),
Text
(
brand
.
brandName
??
""
,
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
style:
const
TextStyle
(
fontWeight:
FontWeight
.
w600
,
fontSize:
16
),
),
const
SizedBox
(
height:
4
),
RichText
(
textAlign:
TextAlign
.
center
,
text:
TextSpan
(
style:
const
TextStyle
(
fontSize:
12
),
children:
[
const
TextSpan
(
text:
"Hoàn đến: "
,
style:
TextStyle
(
color:
Colors
.
grey
),
),
TextSpan
(
text:
"
${(brand.commision ?? '').toNum()?.toString() ?? ''}
%"
,
style:
const
TextStyle
(
color:
Colors
.
orange
,
fontWeight:
FontWeight
.
bold
,
),
),
],
),
),
],
),
);
},
);
}
}
\ No newline at end of file
lib/screen/shopping/sub_widget/build_affiliate_category.dart
0 → 100644
View file @
7777aa65
import
'package:flutter/material.dart'
;
import
'../../../resouce/base_color.dart'
;
import
'../model/affiliate_category_model.dart'
;
class
AffiliateCategory
extends
StatelessWidget
{
final
List
<
AffiliateCategoryModel
>
categories
;
const
AffiliateCategory
({
super
.
key
,
required
this
.
categories
});
@override
Widget
build
(
BuildContext
context
)
{
if
(
categories
.
isEmpty
)
{
return
const
SizedBox
.
shrink
();
}
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
const
SizedBox
(
height:
24
),
Text
(
"Lĩnh Vực Hoàn Điểm"
,
style:
TextStyle
(
fontWeight:
FontWeight
.
bold
,
fontSize:
20
)),
const
SizedBox
(
height:
12
),
Container
(
decoration:
BoxDecoration
(
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
12
),
boxShadow:
[
BoxShadow
(
color:
Colors
.
black
.
withOpacity
(
0.05
),
blurRadius:
5
,
offset:
const
Offset
(
0
,
2
))],
),
child:
GridView
.
count
(
padding:
EdgeInsets
.
zero
,
shrinkWrap:
true
,
physics:
const
NeverScrollableScrollPhysics
(),
crossAxisCount:
4
,
childAspectRatio:
3
/
3.8
,
children:
categories
.
map
((
category
)
=>
_buildAffiliateCategoryItem
(
category
)).
toList
(),
),
),
],
);
}
Widget
_buildAffiliateCategoryItem
(
AffiliateCategoryModel
category
)
{
return
LayoutBuilder
(
builder:
(
context
,
constraints
)
{
final
double
imageWidth
=
constraints
.
maxWidth
/
2
;
return
Container
(
padding:
const
EdgeInsets
.
only
(
top:
12
,
bottom:
8
,
left:
4
,
right:
4
),
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
start
,
children:
[
Image
.
asset
(
'assets/images/cashback/
${category.icon}
.png'
,
width:
imageWidth
,
height:
imageWidth
,),
const
SizedBox
(
height:
4
),
Text
(
category
.
name
,
textAlign:
TextAlign
.
center
,
maxLines:
2
,
overflow:
TextOverflow
.
ellipsis
,
style:
const
TextStyle
(
fontWeight:
FontWeight
.
w600
,
fontSize:
16
,
color:
BaseColor
.
second500
),
),
],
),
);
},
);
}
}
lib/screen/shopping/sub_widget/build_affiliate_product_topsale.dart
0 → 100644
View file @
7777aa65
import
'package:flutter/material.dart'
;
import
'package:intl/intl.dart'
;
import
'package:mypoint_flutter_app/extensions/num_extension.dart'
;
import
'package:mypoint_flutter_app/extensions/string_extension.dart'
;
import
'../model/affiliate_product_top_sale_model.dart'
;
class
AffiliateProductTopSale
extends
StatelessWidget
{
final
List
<
AffiliateProductTopSaleModel
>
products
;
const
AffiliateProductTopSale
({
super
.
key
,
required
this
.
products
});
@override
Widget
build
(
BuildContext
context
)
{
if
(
products
.
isEmpty
)
{
return
const
SizedBox
.
shrink
();
}
final
double
screenWidth
=
MediaQuery
.
of
(
context
).
size
.
width
;
final
double
itemWidth
=
(
screenWidth
-
24
)
/
2
;
final
double
itemHeight
=
itemWidth
+
104
;
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
const
SizedBox
(
height:
24
),
Text
(
"Sản Phẩm Bán Chạy"
,
style:
TextStyle
(
fontWeight:
FontWeight
.
bold
,
fontSize:
20
)),
const
SizedBox
(
height:
12
),
GridView
.
builder
(
padding:
EdgeInsets
.
zero
,
shrinkWrap:
true
,
physics:
const
NeverScrollableScrollPhysics
(),
itemCount:
products
.
length
,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount
(
crossAxisCount:
2
,
childAspectRatio:
itemWidth
/
itemHeight
,
crossAxisSpacing:
8
,
mainAxisSpacing:
8
,
),
itemBuilder:
(
context
,
index
)
{
final
product
=
products
[
index
];
return
_buildAffiliateProductTopSaleItem
(
product
);
},
),
],
);
}
Widget
_buildAffiliateProductTopSaleItem
(
AffiliateProductTopSaleModel
product
)
{
final
price
=
product
.
productPrice
??
''
;
final
formatter
=
NumberFormat
.
currency
(
locale:
'vi_VN'
,
symbol:
'VNĐ'
,
decimalDigits:
0
);
final
formattedPrice
=
formatter
.
format
(
double
.
tryParse
(
price
)
??
0
);
final
commission
=
product
.
commision
??
''
;
final
sold
=
product
.
quantitySold
??
''
;
final
imageUrl
=
product
.
thumnailLink
??
''
;
final
title
=
product
.
productName
??
''
;
return
Container
(
width:
160
,
padding:
const
EdgeInsets
.
all
(
8
),
decoration:
BoxDecoration
(
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
12
),
boxShadow:
[
BoxShadow
(
color:
Colors
.
black
.
withOpacity
(
0.05
),
blurRadius:
4
,
offset:
const
Offset
(
0
,
2
),
)
],
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
8
),
child:
Image
.
network
(
imageUrl
,
scale:
1
,
width:
double
.
infinity
,
fit:
BoxFit
.
cover
,
errorBuilder:
(
_
,
__
,
___
)
=>
Image
.
asset
(
'assets/images/ic_logo.png'
,),
),
),
const
SizedBox
(
height:
6
),
Text
(
title
,
maxLines:
2
,
overflow:
TextOverflow
.
ellipsis
,
style:
const
TextStyle
(
fontSize:
13
),
),
const
SizedBox
(
height:
4
),
Text
(
formattedPrice
,
style:
const
TextStyle
(
color:
Colors
.
blueAccent
,
fontSize:
14
,
fontWeight:
FontWeight
.
bold
,
),
),
const
SizedBox
(
height:
2
),
Row
(
children:
[
RichText
(
text:
TextSpan
(
style:
const
TextStyle
(
fontSize:
12
,
color:
Colors
.
grey
),
children:
[
const
TextSpan
(
text:
"Hoàn đến: "
),
TextSpan
(
text:
"
${(commission ?? '').toNum()?.toString() ?? ''}
%"
,
style:
const
TextStyle
(
color:
Colors
.
orange
,
fontWeight:
FontWeight
.
bold
,
fontSize:
14
),
),
],
),
),
const
Spacer
(),
Text
(
"
${sold.toNum()?.formatCompactNumber()}
đã bán"
,
style:
TextStyle
(
fontSize:
12
,
color:
Colors
.
grey
)),
],
),
],
),
);
}
}
\ No newline at end of file
pubspec.yaml
View file @
7777aa65
...
...
@@ -80,6 +80,7 @@ flutter:
assets
:
-
assets/images/
-
assets/data/
-
assets/images/cashback/
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
...
...
Prev
1
2
3
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment