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
6fcbfba8
Commit
6fcbfba8
authored
Apr 25, 2025
by
DatHV
Browse files
update voucher tab
parent
d86c3328
Changes
41
Show whitespace changes
Inline
Side-by-side
assets/images/bg_header_navi.png
0 → 100644
View file @
6fcbfba8
373 KB
assets/images/ic_logo.png
0 → 100644
View file @
6fcbfba8
5.02 KB
assets/images/ic_logo.svg
deleted
100644 → 0
View file @
d86c3328
<svg
width=
"138"
height=
"138"
viewBox=
"0 0 138 138"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<rect
width=
"138"
height=
"138"
rx=
"10"
fill=
"#D42230"
/>
<path
d=
"M102.755 0.446289V42.2101C102.755 57.5434 90.3969 70.041 75.2347 70.041H61.4571C46.2948 70.041 33.9365 57.5434 33.9365 42.2101V0.446289H47.7141V42.2101C47.7141 49.8767 53.8759 56.1431 61.4571 56.1431H75.2347C82.8158 56.1431 89.0123 49.9117 89.0123 42.2101V0.446289H102.755Z"
fill=
"white"
/>
<path
d=
"M102.751 83.9731C102.751 101.232 88.8694 115.27 71.7685 115.27H64.8797C47.8135 115.27 33.8975 101.232 33.8975 83.9731H47.675C47.675 93.5651 55.3947 101.372 64.8797 101.372H71.7685C81.2536 101.372 88.9732 93.5651 88.9732 83.9731H102.751Z"
fill=
"white"
/>
</svg>
assets/images/ic_point.png
0 → 100644
View file @
6fcbfba8
5.13 KB
assets/images/sample.png
0 → 100644
View file @
6fcbfba8
235 KB
lib/configs/api_paths.dart
View file @
6fcbfba8
...
...
@@ -25,4 +25,6 @@ class APIPaths {
static
const
String
headerHome
=
"/dynamic-home/api/v1.0/header-home"
;
static
const
String
otpDeleteAccountRequest
=
"/user/api/v2.0/me/delete/request"
;
static
const
String
verifyDeleteAccount
=
"/user/api/v2.0/me/delete/verify"
;
static
const
String
getProducts
=
"/product/api/v2.0/products"
;
static
const
String
getSearchProducts
=
"/product/api/v2.0/products/search"
;
}
lib/networking/restful_api_request.dart
View file @
6fcbfba8
...
...
@@ -5,6 +5,7 @@ import 'package:mypoint_flutter_app/configs/constants.dart';
import
'package:mypoint_flutter_app/extensions/string_extension.dart'
;
import
'package:mypoint_flutter_app/networking/restful_api.dart'
;
import
'package:mypoint_flutter_app/preference/data_preference.dart'
;
import
'package:mypoint_flutter_app/screen/voucher/models/product_model.dart'
;
import
'../configs/device_info.dart'
;
import
'../model/auth/biometric_register_response_model.dart'
;
import
'../model/auth/login_token_response_model.dart'
;
...
...
@@ -19,6 +20,7 @@ import '../screen/otp/model/otp_verify_response_model.dart';
import
'../screen/pageDetail/model/campaign_detail_model.dart'
;
import
'../screen/pageDetail/model/detail_page_rule_type.dart'
;
import
'../screen/splash/splash_screen_viewmodel.dart'
;
import
'../screen/voucher/models/search_product_response_model.dart'
;
import
'model_maker.dart'
;
extension
RestfullAPIClientAllApi
on
RestfulAPIClient
{
...
...
@@ -259,4 +261,20 @@ extension RestfullAPIClientAllApi on RestfulAPIClient {
(
data
)
=>
HeaderHomeModel
.
fromJson
(
data
as
Json
),
);
}
Future
<
BaseResponseModel
<
List
<
ProductModel
>>>
getProducts
(
Json
body
)
async
{
return
requestNormal
(
APIPaths
.
getProducts
,
Method
.
GET
,
body
,
(
data
)
{
final
list
=
data
as
List
<
dynamic
>;
return
list
.
map
((
e
)
=>
ProductModel
.
fromJson
(
e
)).
toList
();
});
}
Future
<
BaseResponseModel
<
SearchProductResponseModel
>>
getSearchProducts
(
Json
body
)
async
{
return
requestNormal
(
APIPaths
.
getSearchProducts
,
Method
.
POST
,
body
,
(
data
)
=>
SearchProductResponseModel
.
fromJson
(
data
as
Json
),
);
}
}
lib/resouce/define_image.dart
View file @
6fcbfba8
const
module
=
'assets/images'
;
const
String
icClose
=
'
$module
/ic_close.svg'
;
const
String
icLogo
=
'
$module
/ic_logo.
sv
g'
;
const
String
icLogo
=
'
$module
/ic_logo.
pn
g'
;
const
String
bgAlertHeader
=
'
$module
/bg_alert_header.svg'
;
\ No newline at end of file
lib/screen/main_tab_screen/main_tab_screen.dart
View file @
6fcbfba8
...
...
@@ -3,7 +3,8 @@ import '../game/games_screen.dart';
import
'../home/home_screen.dart'
;
import
'../personal/personal_screen.dart'
;
import
'../shopping/shopping_screen.dart'
;
import
'../voucher/voucher_screen.dart'
;
import
'../support/transaction_history_screen.dart'
;
import
'../voucher/voucher_tab_screen.dart'
;
class
MainTabScreen
extends
StatefulWidget
{
const
MainTabScreen
({
super
.
key
});
...
...
@@ -17,9 +18,9 @@ class _MainTabScreenState extends State<MainTabScreen> {
final
List
<
Widget
>
_pages
=
const
[
HomeScreen
(),
VoucherScreen
(),
Voucher
Tab
Screen
(),
GameScreen
(),
Shopping
Screen
(),
TransactionHistory
Screen
(),
PersonalScreen
(),
];
...
...
lib/screen/support/transaction_history_screen.dart
0 → 100644
View file @
6fcbfba8
import
'package:flutter/material.dart'
;
import
'package:intl/intl.dart'
;
import
'transaction_service.dart'
;
class
TransactionHistoryScreen
extends
StatefulWidget
{
const
TransactionHistoryScreen
({
super
.
key
});
@override
State
<
TransactionHistoryScreen
>
createState
()
=>
_TransactionHistoryScreenState
();
}
class
_TransactionHistoryScreenState
extends
State
<
TransactionHistoryScreen
>
{
final
List
<
String
>
categories
=
[
'Tất cả'
,
'Viện thông'
,
'Mua sắm'
,
'Ưu đãi'
,
'Hóa đơn'
,
];
int
selectedCategoryIndex
=
0
;
DateTime
selectedMonth
=
DateTime
.
now
();
bool
isLoading
=
false
;
List
<
Transaction
>
transactions
=
[];
final
TransactionService
_transactionService
=
TransactionService
();
@override
void
initState
()
{
super
.
initState
();
fetchTransactions
();
}
Future
<
void
>
fetchTransactions
()
async
{
setState
(()
{
isLoading
=
true
;
});
try
{
final
result
=
await
_transactionService
.
getTransactions
(
category:
categories
[
selectedCategoryIndex
],
month:
selectedMonth
,
);
setState
(()
{
transactions
=
result
;
isLoading
=
false
;
});
}
catch
(
e
)
{
setState
(()
{
isLoading
=
false
;
});
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'Không thể tải dữ liệu:
$e
'
)),
);
}
}
void
selectCategory
(
int
index
)
{
setState
(()
{
selectedCategoryIndex
=
index
;
});
fetchTransactions
();
}
void
selectMonth
()
async
{
final
DateTime
?
picked
=
await
showDatePicker
(
context:
context
,
initialDate:
selectedMonth
,
firstDate:
DateTime
(
2020
),
lastDate:
DateTime
(
2026
),
initialDatePickerMode:
DatePickerMode
.
year
,
builder:
(
context
,
child
)
{
return
Theme
(
data:
Theme
.
of
(
context
).
copyWith
(
colorScheme:
ColorScheme
.
light
(
primary:
Colors
.
red
.
shade400
,
onPrimary:
Colors
.
white
,
onSurface:
Colors
.
black
,
),
),
child:
child
!,
);
},
);
if
(
picked
!=
null
)
{
setState
(()
{
selectedMonth
=
picked
;
});
fetchTransactions
();
}
}
@override
Widget
build
(
BuildContext
context
)
{
final
transactionCount
=
transactions
.
length
;
final
hasTransactions
=
transactionCount
>
0
;
// Tính tổng tiền và điểm
int
totalAmount
=
0
;
int
totalPoints
=
0
;
for
(
var
transaction
in
transactions
)
{
totalAmount
+=
transaction
.
amount
;
totalPoints
+=
transaction
.
points
;
}
return
Scaffold
(
backgroundColor:
Colors
.
grey
.
shade50
,
appBar:
AppBar
(
backgroundColor:
Colors
.
white
,
elevation:
0
,
centerTitle:
true
,
title:
const
Text
(
'Lịch sử giao dịch'
,
style:
TextStyle
(
fontSize:
18
,
fontWeight:
FontWeight
.
w500
,
color:
Colors
.
black87
,
),
),
leading:
IconButton
(
icon:
const
Icon
(
Icons
.
arrow_back_ios
,
size:
20
,
color:
Colors
.
black54
),
onPressed:
()
=>
Navigator
.
of
(
context
).
pop
(),
),
),
body:
Column
(
children:
[
// Danh mục
Container
(
height:
60
,
color:
Colors
.
white
,
child:
ListView
.
builder
(
scrollDirection:
Axis
.
horizontal
,
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
12
),
itemCount:
categories
.
length
,
itemBuilder:
(
context
,
index
)
{
final
isSelected
=
selectedCategoryIndex
==
index
;
return
GestureDetector
(
onTap:
()
=>
selectCategory
(
index
),
child:
Container
(
margin:
const
EdgeInsets
.
symmetric
(
horizontal:
4
,
vertical:
10
),
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
),
decoration:
BoxDecoration
(
color:
isSelected
?
Colors
.
red
.
shade50
:
Colors
.
grey
.
shade100
,
borderRadius:
BorderRadius
.
circular
(
20
),
border:
isSelected
?
Border
.
all
(
color:
Colors
.
red
.
shade100
)
:
null
,
),
alignment:
Alignment
.
center
,
child:
Text
(
categories
[
index
],
style:
TextStyle
(
color:
isSelected
?
Colors
.
red
:
Colors
.
grey
.
shade700
,
fontWeight:
isSelected
?
FontWeight
.
w500
:
FontWeight
.
normal
,
),
),
),
);
},
),
),
const
SizedBox
(
height:
8
),
// Tháng và số giao dịch
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
,
vertical:
8
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
Text
(
'Tháng
${DateFormat('MM/yyyy').format(selectedMonth)}
(
${transactionCount}
giao dịch)'
,
style:
const
TextStyle
(
fontSize:
16
,
fontWeight:
FontWeight
.
w500
,
color:
Colors
.
black87
,
),
),
InkWell
(
onTap:
selectMonth
,
child:
Container
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
12
,
vertical:
6
),
decoration:
BoxDecoration
(
border:
Border
.
all
(
color:
Colors
.
grey
.
shade300
),
borderRadius:
BorderRadius
.
circular
(
4
),
),
child:
Row
(
children:
[
const
Text
(
'Tháng'
,
style:
TextStyle
(
fontSize:
14
,
color:
Colors
.
black87
,
),
),
const
SizedBox
(
width:
4
),
Icon
(
Icons
.
keyboard_arrow_down
,
size:
18
,
color:
Colors
.
grey
.
shade700
),
],
),
),
),
],
),
),
// Tổng tiền và điểm
Container
(
margin:
const
EdgeInsets
.
all
(
16
),
padding:
const
EdgeInsets
.
all
(
16
),
decoration:
BoxDecoration
(
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
12
),
border:
Border
.
all
(
color:
Colors
.
grey
.
shade200
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
'
${totalAmount}
đ'
,
style:
const
TextStyle
(
fontSize:
24
,
fontWeight:
FontWeight
.
bold
,
),
),
const
SizedBox
(
height:
8
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
const
Text
(
'Giao dịch bằng tiền'
,
style:
TextStyle
(
color:
Colors
.
black54
,
fontSize:
14
,
),
),
Text
(
'
${totalAmount}
đ'
,
style:
const
TextStyle
(
fontWeight:
FontWeight
.
w500
,
),
),
],
),
const
SizedBox
(
height:
4
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
const
Text
(
'Giao dịch bằng điểm'
,
style:
TextStyle
(
color:
Colors
.
black54
,
fontSize:
14
,
),
),
Row
(
children:
[
Container
(
width:
18
,
height:
18
,
decoration:
const
BoxDecoration
(
color:
Colors
.
amber
,
shape:
BoxShape
.
circle
,
),
child:
const
Center
(
child:
Icon
(
Icons
.
currency_exchange
,
size:
12
,
color:
Colors
.
white
,
),
),
),
const
SizedBox
(
width:
4
),
Text
(
'
$totalPoints
'
,
style:
const
TextStyle
(
fontWeight:
FontWeight
.
w500
,
),
),
],
),
],
),
],
),
),
// Danh sách giao dịch hoặc trạng thái trống
Expanded
(
child:
isLoading
?
const
Center
(
child:
CircularProgressIndicator
())
:
hasTransactions
?
ListView
.
builder
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
),
itemCount:
transactions
.
length
,
itemBuilder:
(
context
,
index
)
{
final
transaction
=
transactions
[
index
];
return
TransactionItem
(
transaction:
transaction
);
},
)
:
const
EmptyTransactionState
(),
),
],
),
);
}
}
class
TransactionItem
extends
StatelessWidget
{
final
Transaction
transaction
;
const
TransactionItem
({
super
.
key
,
required
this
.
transaction
,
});
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
margin:
const
EdgeInsets
.
only
(
bottom:
12
),
child:
Row
(
children:
[
// Icon
Container
(
width:
40
,
height:
40
,
decoration:
BoxDecoration
(
color:
Colors
.
red
.
shade50
,
borderRadius:
BorderRadius
.
circular
(
8
),
),
child:
Stack
(
children:
[
Center
(
child:
Icon
(
transaction
.
icon
,
color:
Colors
.
red
,
size:
20
,
),
),
if
(
transaction
.
status
==
TransactionStatus
.
completed
)
Positioned
(
right:
0
,
bottom:
0
,
child:
Container
(
width:
16
,
height:
16
,
decoration:
BoxDecoration
(
color:
Colors
.
green
,
shape:
BoxShape
.
circle
,
border:
Border
.
all
(
color:
Colors
.
white
,
width:
2
),
),
child:
const
Center
(
child:
Icon
(
Icons
.
check
,
size:
8
,
color:
Colors
.
white
,
),
),
),
),
],
),
),
const
SizedBox
(
width:
12
),
// Thông tin giao dịch
Expanded
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
transaction
.
title
,
style:
const
TextStyle
(
fontWeight:
FontWeight
.
w500
,
fontSize:
15
,
),
),
const
SizedBox
(
height:
2
),
Text
(
'
${DateFormat('HH:mm').format(transaction.date)}
-
${DateFormat('dd/MM/yyyy').format(transaction.date)}
'
,
style:
TextStyle
(
color:
Colors
.
grey
.
shade600
,
fontSize:
13
,
),
),
],
),
),
// Điểm
Row
(
children:
[
Container
(
width:
20
,
height:
20
,
decoration:
const
BoxDecoration
(
color:
Colors
.
amber
,
shape:
BoxShape
.
circle
,
),
child:
const
Center
(
child:
Icon
(
Icons
.
currency_exchange
,
size:
12
,
color:
Colors
.
white
,
),
),
),
const
SizedBox
(
width:
4
),
Text
(
'
${transaction.points}
'
,
style:
const
TextStyle
(
fontWeight:
FontWeight
.
w500
,
fontSize:
15
,
),
),
],
),
],
),
);
}
}
class
EmptyTransactionState
extends
StatelessWidget
{
const
EmptyTransactionState
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
return
Center
(
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Container
(
width:
120
,
height:
120
,
decoration:
BoxDecoration
(
color:
Colors
.
grey
.
shade100
,
shape:
BoxShape
.
circle
,
),
child:
Center
(
child:
Icon
(
Icons
.
receipt_long
,
size:
50
,
color:
Colors
.
grey
.
shade400
,
),
),
),
const
SizedBox
(
height:
16
),
const
Text
(
'Bạn hiện chưa có giao dịch nào'
,
style:
TextStyle
(
fontSize:
16
,
color:
Colors
.
grey
,
),
),
],
),
);
}
}
\ No newline at end of file
lib/screen/support/transaction_service.dart
0 → 100644
View file @
6fcbfba8
import
'dart:convert'
;
import
'package:flutter/material.dart'
;
import
'package:http/http.dart'
as
http
;
enum
TransactionStatus
{
pending
,
completed
,
failed
,
}
class
Transaction
{
final
String
id
;
final
String
title
;
final
int
amount
;
final
int
points
;
final
DateTime
date
;
final
String
category
;
final
IconData
icon
;
final
TransactionStatus
status
;
Transaction
({
required
this
.
id
,
required
this
.
title
,
required
this
.
amount
,
required
this
.
points
,
required
this
.
date
,
required
this
.
category
,
required
this
.
icon
,
required
this
.
status
,
});
factory
Transaction
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
IconData
getIconForCategory
(
String
category
)
{
switch
(
category
)
{
case
'Viện thông'
:
return
Icons
.
phone_android
;
case
'Mua sắm'
:
return
Icons
.
shopping_bag
;
case
'Ưu đãi'
:
return
Icons
.
card_giftcard
;
case
'Hóa đơn'
:
return
Icons
.
receipt
;
default
:
return
Icons
.
receipt_long
;
}
}
TransactionStatus
getStatus
(
String
statusStr
)
{
switch
(
statusStr
)
{
case
'completed'
:
return
TransactionStatus
.
completed
;
case
'pending'
:
return
TransactionStatus
.
pending
;
case
'failed'
:
return
TransactionStatus
.
failed
;
default
:
return
TransactionStatus
.
pending
;
}
}
return
Transaction
(
id:
json
[
'id'
],
title:
json
[
'title'
],
amount:
json
[
'amount'
],
points:
json
[
'points'
],
date:
DateTime
.
parse
(
json
[
'date'
]),
category:
json
[
'category'
],
icon:
getIconForCategory
(
json
[
'category'
]),
status:
getStatus
(
json
[
'status'
]),
);
}
}
class
TransactionService
{
static
const
String
baseUrl
=
'https://api.example.com'
;
Future
<
List
<
Transaction
>>
getTransactions
({
required
String
category
,
required
DateTime
month
,
})
async
{
try
{
final
response
=
await
http
.
get
(
Uri
.
parse
(
'
$baseUrl
/transactions?category=
${Uri.encodeComponent(category)}
&month=
${month.year}
-
${month.month}
'
,
),
headers:
{
'Content-Type'
:
'application/json'
},
);
if
(
response
.
statusCode
==
200
)
{
final
List
<
dynamic
>
data
=
json
.
decode
(
response
.
body
);
return
data
.
map
((
json
)
=>
Transaction
.
fromJson
(
json
)).
toList
();
}
else
{
throw
Exception
(
'Failed to load transactions:
${response.statusCode}
'
);
}
}
catch
(
e
)
{
// Trong môi trường thực tế, bạn nên xử lý lỗi một cách phù hợp
print
(
'Error fetching transactions:
$e
'
);
// Trả về dữ liệu mẫu cho mục đích demo
if
(
category
==
'Ưu đãi'
)
{
return
[
Transaction
(
id:
'1'
,
title:
'Thanh toán mua ưu đãi'
,
amount:
0
,
points:
0
,
date:
DateTime
.
now
(),
category:
'Ưu đãi'
,
icon:
Icons
.
card_giftcard
,
status:
TransactionStatus
.
completed
,
),
Transaction
(
id:
'2'
,
title:
'Thanh toán mua ưu đãi'
,
amount:
0
,
points:
0
,
date:
DateTime
.
now
(),
category:
'Ưu đãi'
,
icon:
Icons
.
card_giftcard
,
status:
TransactionStatus
.
completed
,
),
];
}
return
[];
}
}
}
\ No newline at end of file
lib/screen/voucher/models/cash_type.dart
0 → 100644
View file @
6fcbfba8
enum
CashType
{
all
,
point
,
cash
,
}
extension
CashTypeExt
on
CashType
{
static
CashType
from
(
String
?
value
)
{
switch
(
value
)
{
case
"PAYMENT_METHOD_POINT"
:
return
CashType
.
point
;
case
"PAYMENT_METHOD_CASH"
:
return
CashType
.
cash
;
default
:
return
CashType
.
all
;
}
}
}
extension
IntExtension
on
int
{
String
makeDisplayPrice
(
CashType
type
)
{
if
(
this
==
0
)
return
"Miễn phí"
;
if
(
type
==
CashType
.
point
)
return
"
$this
điểm"
;
return
"
$this
đ"
;
}
}
lib/screen/voucher/models/media_type.dart
0 → 100644
View file @
6fcbfba8
enum
MediaType
{
video
,
avatar
,
banner16_9
,
banner1_1
,
gallery
,
}
extension
MediaTypeExtension
on
MediaType
{
static
MediaType
?
fromRawValue
(
String
?
rawValue
)
{
switch
(
rawValue
)
{
case
'MEDIA_TYPE_VIDEO'
:
return
MediaType
.
video
;
case
'MEDIA_TYPE_AVATAR'
:
return
MediaType
.
avatar
;
case
'MEDIA_TYPE_BANNER_16_9'
:
return
MediaType
.
banner16_9
;
case
'MEDIA_TYPE_BANNER_1_1'
:
return
MediaType
.
banner1_1
;
case
'MEDIA_TYPE_GALLERY'
:
return
MediaType
.
gallery
;
default
:
return
null
;
}
}
String
get
rawValue
{
switch
(
this
)
{
case
MediaType
.
video
:
return
'MEDIA_TYPE_VIDEO'
;
case
MediaType
.
avatar
:
return
'MEDIA_TYPE_AVATAR'
;
case
MediaType
.
banner16_9
:
return
'MEDIA_TYPE_BANNER_16_9'
;
case
MediaType
.
banner1_1
:
return
'MEDIA_TYPE_BANNER_1_1'
;
case
MediaType
.
gallery
:
return
'MEDIA_TYPE_GALLERY'
;
}
}
}
lib/screen/voucher/models/product_brand_model.dart
0 → 100644
View file @
6fcbfba8
import
'package:json_annotation/json_annotation.dart'
;
part
'product_brand_model.g.dart'
;
@JsonSerializable
()
class
ProductBrandModel
{
final
int
?
id
;
final
String
?
logo
;
final
String
?
name
;
final
String
?
email
;
final
String
?
phone
;
final
String
?
website
;
final
String
?
code
;
ProductBrandModel
({
this
.
id
,
this
.
logo
,
this
.
name
,
this
.
email
,
this
.
phone
,
this
.
website
,
this
.
code
,
});
factory
ProductBrandModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$ProductBrandModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$ProductBrandModelToJson
(
this
);
}
lib/screen/voucher/models/product_brand_model.g.dart
0 → 100644
View file @
6fcbfba8
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'product_brand_model.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ProductBrandModel
_$ProductBrandModelFromJson
(
Map
<
String
,
dynamic
>
json
)
=>
ProductBrandModel
(
id:
(
json
[
'id'
]
as
num
?)?.
toInt
(),
logo:
json
[
'logo'
]
as
String
?,
name:
json
[
'name'
]
as
String
?,
email:
json
[
'email'
]
as
String
?,
phone:
json
[
'phone'
]
as
String
?,
website:
json
[
'website'
]
as
String
?,
code:
json
[
'code'
]
as
String
?,
);
Map
<
String
,
dynamic
>
_$ProductBrandModelToJson
(
ProductBrandModel
instance
)
=>
<
String
,
dynamic
>{
'id'
:
instance
.
id
,
'logo'
:
instance
.
logo
,
'name'
:
instance
.
name
,
'email'
:
instance
.
email
,
'phone'
:
instance
.
phone
,
'website'
:
instance
.
website
,
'code'
:
instance
.
code
,
};
lib/screen/voucher/models/product_content_model.dart
0 → 100644
View file @
6fcbfba8
import
'package:json_annotation/json_annotation.dart'
;
part
'product_content_model.g.dart'
;
@JsonSerializable
()
class
ProductContentModel
{
final
String
?
language
;
final
String
?
name
;
final
String
?
detail
;
final
String
?
termAndCondition
;
ProductContentModel
({
this
.
language
,
this
.
name
,
this
.
detail
,
this
.
termAndCondition
,
});
factory
ProductContentModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$ProductContentModelFromJson
(
json
);
get
imageUrl
=>
null
;
Map
<
String
,
dynamic
>
toJson
()
=>
_$ProductContentModelToJson
(
this
);
}
lib/screen/voucher/models/product_content_model.g.dart
0 → 100644
View file @
6fcbfba8
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'product_content_model.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ProductContentModel
_$ProductContentModelFromJson
(
Map
<
String
,
dynamic
>
json
)
=>
ProductContentModel
(
language:
json
[
'language'
]
as
String
?,
name:
json
[
'name'
]
as
String
?,
detail:
json
[
'detail'
]
as
String
?,
termAndCondition:
json
[
'termAndCondition'
]
as
String
?,
);
Map
<
String
,
dynamic
>
_$ProductContentModelToJson
(
ProductContentModel
instance
,
)
=>
<
String
,
dynamic
>{
'language'
:
instance
.
language
,
'name'
:
instance
.
name
,
'detail'
:
instance
.
detail
,
'termAndCondition'
:
instance
.
termAndCondition
,
};
lib/screen/voucher/models/product_media_item.dart
0 → 100644
View file @
6fcbfba8
import
'package:json_annotation/json_annotation.dart'
;
import
'media_type.dart'
;
part
'product_media_item.g.dart'
;
@JsonSerializable
()
class
ProductMediaItem
{
final
String
?
name
;
final
String
?
url
;
@JsonKey
(
name:
'type'
)
final
String
?
rawType
;
ProductMediaItem
({
this
.
name
,
this
.
url
,
this
.
rawType
,
});
MediaType
?
get
type
=>
MediaTypeExtension
.
fromRawValue
(
rawType
);
factory
ProductMediaItem
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$ProductMediaItemFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$ProductMediaItemToJson
(
this
);
}
lib/screen/voucher/models/product_media_item.g.dart
0 → 100644
View file @
6fcbfba8
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'product_media_item.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ProductMediaItem
_$ProductMediaItemFromJson
(
Map
<
String
,
dynamic
>
json
)
=>
ProductMediaItem
(
name:
json
[
'name'
]
as
String
?,
url:
json
[
'url'
]
as
String
?,
rawType:
json
[
'type'
]
as
String
?,
);
Map
<
String
,
dynamic
>
_$ProductMediaItemToJson
(
ProductMediaItem
instance
)
=>
<
String
,
dynamic
>{
'name'
:
instance
.
name
,
'url'
:
instance
.
url
,
'type'
:
instance
.
rawType
,
};
lib/screen/voucher/models/product_model.dart
0 → 100644
View file @
6fcbfba8
import
'package:json_annotation/json_annotation.dart'
;
import
'package:mypoint_flutter_app/screen/voucher/models/product_brand_model.dart'
;
import
'package:mypoint_flutter_app/screen/voucher/models/product_content_model.dart'
;
import
'package:mypoint_flutter_app/screen/voucher/models/product_media_item.dart'
;
import
'package:mypoint_flutter_app/screen/voucher/models/product_price_model.dart'
;
import
'package:mypoint_flutter_app/screen/voucher/models/product_properties_model.dart'
;
import
'media_type.dart'
;
part
'product_model.g.dart'
;
@JsonSerializable
()
class
ProductModel
{
@JsonKey
(
name:
'quantity_available'
)
final
int
?
quantityAvailable
;
final
ProductContentModel
?
content
;
final
ProductPriceModel
?
price
;
final
ProductBrandModel
?
brand
;
@JsonKey
(
name:
'voucher_properties'
)
final
ProductPropertiesModel
?
properties
;
final
List
<
ProductMediaItem
>?
media
;
ProductModel
({
this
.
quantityAvailable
,
this
.
content
,
this
.
price
,
this
.
brand
,
this
.
properties
,
this
.
media
,
});
String
?
get
name
{
if
(
content
==
null
)
return
null
;
return
content
!.
name
;
}
ProductMediaItem
?
get
banner
{
if
(
media
==
null
)
return
null
;
return
media
!.
firstWhere
((
item
)
=>
item
.
type
==
MediaType
.
banner16_9
,
orElse:
()
=>
media
!.
first
);
}
factory
ProductModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$ProductModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$ProductModelToJson
(
this
);
}
\ No newline at end of file
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