Initial commit: Penyerahan final Source code Tugas Akhir
This commit is contained in:
198
lib/widgets/announcement_user.dart
Normal file
198
lib/widgets/announcement_user.dart
Normal file
@ -0,0 +1,198 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:initial_folder/models/announcement_model.dart';
|
||||
import 'package:initial_folder/providers/announcement_provider.dart';
|
||||
import 'package:initial_folder/providers/like_announcement.dart';
|
||||
import 'package:initial_folder/screens/course/component/inside_announcement.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../get_it.dart';
|
||||
import '../size_config.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class AnnouncementUser extends StatefulWidget {
|
||||
const AnnouncementUser({
|
||||
Key? key,
|
||||
required this.id,
|
||||
this.divider,
|
||||
required this.announcementDataModel,
|
||||
required this.index,
|
||||
required this.userId,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget? divider;
|
||||
final id;
|
||||
final AnnouncementDataModel announcementDataModel;
|
||||
final int index;
|
||||
final int userId;
|
||||
|
||||
@override
|
||||
State<AnnouncementUser> createState() => _AnnouncementUserState();
|
||||
}
|
||||
|
||||
class _AnnouncementUserState extends State<AnnouncementUser> {
|
||||
double value = 0;
|
||||
final provider = announcementGetIt<AnnouncementProvider>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
LikeOrAnnouncementProvider _likeOrAnnouncementProvider =
|
||||
Provider.of<LikeOrAnnouncementProvider>(context);
|
||||
|
||||
likeOrAnnouncement(String tokenAnnouncement) async {
|
||||
final provider = announcementGetIt<AnnouncementProvider>();
|
||||
if (await _likeOrAnnouncementProvider
|
||||
.likeOrAnnouncement(tokenAnnouncement)) {
|
||||
provider.getAnnouncement(widget.id);
|
||||
}
|
||||
}
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => InsideAnnouncement(
|
||||
announcementDataModel: widget.announcementDataModel,
|
||||
id: widget.id,
|
||||
index: widget.index,
|
||||
userId: widget.userId,
|
||||
),
|
||||
),
|
||||
).then((value) => provider.getAnnouncement(widget.id));
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor: primaryColor,
|
||||
backgroundImage:
|
||||
widget.announcementDataModel.fotoProfile == null
|
||||
? AssetImage("assets/images/Profile Image.png")
|
||||
: NetworkImage(
|
||||
widget.announcementDataModel.fotoProfile ??
|
||||
'') as ImageProvider,
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(8),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
widget.announcementDataModel.instructorName ?? '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color:
|
||||
Theme.of(context).colorScheme.onBackground,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
widget.announcementDataModel.date ?? '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(9)),
|
||||
Text(
|
||||
widget.announcementDataModel.bodyContent ?? '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
letterSpacing: 1,
|
||||
fontSize: SizeConfig.blockHorizontal! * 3.4,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
kLike(
|
||||
widget.announcementDataModel.isLike == 1
|
||||
? Icons.favorite
|
||||
: Icons.favorite_border_rounded,
|
||||
widget.announcementDataModel.isLike == 1
|
||||
? Colors.red
|
||||
: secondaryColor, () {
|
||||
likeOrAnnouncement(
|
||||
widget.announcementDataModel.tokenAnnouncement!);
|
||||
}),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(3),
|
||||
),
|
||||
Text(
|
||||
"${widget.announcementDataModel.countLike ?? 0}",
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(13)),
|
||||
kComment(widget.announcementDataModel.replies.length),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenWidth(13),
|
||||
),
|
||||
SizedBox(
|
||||
child: widget.divider,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget kLike(IconData icon, Color color, Function onTap) {
|
||||
return GestureDetector(
|
||||
onTap: () => onTap(),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
icon,
|
||||
color: color,
|
||||
size: 12,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget kComment(int value) {
|
||||
return Row(
|
||||
children: [
|
||||
Icon(
|
||||
FontAwesomeIcons.comment,
|
||||
color: secondaryColor,
|
||||
size: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(3),
|
||||
),
|
||||
Text(
|
||||
"$value",
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10), letterSpacing: 0.3),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
124
lib/widgets/announcement_user_page.dart
Normal file
124
lib/widgets/announcement_user_page.dart
Normal file
@ -0,0 +1,124 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/models/announcement_model.dart';
|
||||
import 'package:initial_folder/providers/announcement_provider.dart';
|
||||
import 'package:initial_folder/widgets/announcement_user.dart';
|
||||
import '../get_it.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class AnnouncementUserPage extends StatefulWidget {
|
||||
const AnnouncementUserPage({Key? key, required this.idCourse})
|
||||
: super(key: key);
|
||||
final idCourse;
|
||||
|
||||
@override
|
||||
State<AnnouncementUserPage> createState() => _AnnouncementUserPageState();
|
||||
}
|
||||
|
||||
class _AnnouncementUserPageState extends State<AnnouncementUserPage> {
|
||||
final provider = announcementGetIt<AnnouncementProvider>();
|
||||
int? userId = 0;
|
||||
|
||||
void getUserId() async {
|
||||
userId = await UsersInfo().getIdUser();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
getUserId();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
provider.getAnnouncement(widget.idCourse);
|
||||
late Widget build;
|
||||
|
||||
return StreamBuilder<AnnouncementModel>(
|
||||
stream: provider.announcementStream,
|
||||
builder: (context, AsyncSnapshot<AnnouncementModel> snapshot) {
|
||||
if (snapshot.hasError) {
|
||||
return Center(
|
||||
child: Text(
|
||||
'Terjadi Kesalahan',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
switch (snapshot.connectionState) {
|
||||
case ConnectionState.waiting:
|
||||
build = Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: primaryColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ConnectionState.none:
|
||||
build = Center(
|
||||
child: Text(
|
||||
'Tidak ada koneksi',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ConnectionState.active:
|
||||
if (snapshot.data!.data[0].isEmpty) {
|
||||
build = Center(
|
||||
child: Text(
|
||||
'Tidak Ada Pengumuman',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
build = ListView.builder(
|
||||
itemCount: snapshot.data!.data[0].length,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.vertical,
|
||||
itemBuilder: (context, index) {
|
||||
return AnnouncementUser(
|
||||
divider: Divider(),
|
||||
announcementDataModel: snapshot.data!.data[0][index],
|
||||
id: widget.idCourse,
|
||||
index: index,
|
||||
userId: userId!,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
break;
|
||||
case ConnectionState.done:
|
||||
if (snapshot.data!.data[0].isEmpty) {
|
||||
build = Center(
|
||||
child: Text(
|
||||
'Belum ada pengumuman',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
build = ListView.builder(
|
||||
itemCount: snapshot.data!.data[0].length,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.vertical,
|
||||
itemBuilder: (context, index) {
|
||||
return AnnouncementUser(
|
||||
divider: Divider(),
|
||||
announcementDataModel: snapshot.data!.data[0][index],
|
||||
id: widget.idCourse,
|
||||
index: index,
|
||||
userId: userId!,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return build;
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
20
lib/widgets/counter_qna_comment.dart
Normal file
20
lib/widgets/counter_qna_comment.dart
Normal file
@ -0,0 +1,20 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/models/counter_qna_comment_model.dart';
|
||||
|
||||
import '../size_config.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class CounterQnaComment extends StatelessWidget {
|
||||
const CounterQnaComment({Key? key, required this.counterComment})
|
||||
: super(key: key);
|
||||
|
||||
final String counterComment;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Text(
|
||||
'${counterComment}',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10), letterSpacing: 0.3),
|
||||
);
|
||||
}
|
||||
}
|
64
lib/widgets/counter_qna_comment_page.dart
Normal file
64
lib/widgets/counter_qna_comment_page.dart
Normal file
@ -0,0 +1,64 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/counter_qna_comment_provider.dart';
|
||||
import 'package:initial_folder/widgets/counter_qna_comment.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../theme.dart';
|
||||
|
||||
class CounterQnaCommentPage extends StatelessWidget {
|
||||
const CounterQnaCommentPage({Key? key, required this.idQna})
|
||||
: super(key: key);
|
||||
|
||||
final idQna;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => CounterQnaCommentProvider(idQna: idQna),
|
||||
child: Consumer<CounterQnaCommentProvider>(builder: (context, state, _) {
|
||||
if (state.state == ResultState.loading) {
|
||||
print(idQna);
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: primaryColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultState.noData) {
|
||||
return Center(
|
||||
child: Text(
|
||||
'TIDAK ADA',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultState.hasData) {
|
||||
var counterQna = state.result!.data;
|
||||
|
||||
return CounterQnaComment(
|
||||
counterComment: counterQna!,
|
||||
);
|
||||
// var counterQna = state.result!.data;
|
||||
// return CounterQnaComment(
|
||||
// counterComment: counterQna,
|
||||
// );
|
||||
} else if (state.state == ResultState.error) {
|
||||
return Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'Terjadi Kesalahan Coba Lagi',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
return Center(
|
||||
child: Text(
|
||||
'Terjadi Kesalahan',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
24
lib/widgets/counter_qna_like.dart
Normal file
24
lib/widgets/counter_qna_like.dart
Normal file
@ -0,0 +1,24 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/like_or_unlike_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../size_config.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class CounterQnaLike extends StatelessWidget {
|
||||
const CounterQnaLike({
|
||||
Key? key,
|
||||
required this.counterLike,
|
||||
}) : super(key: key);
|
||||
|
||||
final counterLike;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Text(
|
||||
'${counterLike}',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10), letterSpacing: 0.3),
|
||||
);
|
||||
}
|
||||
}
|
63
lib/widgets/counter_qna_like_page.dart
Normal file
63
lib/widgets/counter_qna_like_page.dart
Normal file
@ -0,0 +1,63 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/counter_qna_like_provider.dart';
|
||||
import 'package:initial_folder/widgets/counter_qna_like.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../theme.dart';
|
||||
|
||||
class CounterQnaLikePage extends StatelessWidget {
|
||||
const CounterQnaLikePage({Key? key, required this.idQna}) : super(key: key);
|
||||
|
||||
final idQna;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => CounterQnaLikeProvider(idQna: idQna),
|
||||
child: Consumer<CounterQnaLikeProvider>(builder: (context, state, _) {
|
||||
if (state.state == ResultState.loading) {
|
||||
print(idQna);
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: primaryColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultState.noData) {
|
||||
return Center(
|
||||
child: Text(
|
||||
'TIDAK ADA',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultState.hasData) {
|
||||
var counterQna = state.result!.data;
|
||||
|
||||
return CounterQnaLike(
|
||||
counterLike: counterQna,
|
||||
);
|
||||
// var counterQna = state.result!.data;
|
||||
// return CounterQnaComment(
|
||||
// counterComment: counterQna,
|
||||
// );
|
||||
} else if (state.state == ResultState.error) {
|
||||
return Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'Terjadi Kesalahan Coba Lagi',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
return Center(
|
||||
child: Text(
|
||||
'Terjadi Kesalahan',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
376
lib/widgets/custom_expansion_tile.dart
Normal file
376
lib/widgets/custom_expansion_tile.dart
Normal file
@ -0,0 +1,376 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
const Duration _kExpand = Duration(milliseconds: 200);
|
||||
|
||||
/// A single-line [ListTile] with an expansion arrow icon that expands or collapses
|
||||
/// the tile to reveal or hide the [children].
|
||||
///
|
||||
/// This widget is typically used with [ListView] to create an
|
||||
/// "expand / collapse" list entry. When used with scrolling widgets like
|
||||
/// [ListView], a unique [PageStorageKey] must be specified to enable the
|
||||
/// [CustomExpansionTile] to save and restore its expanded state when it is scrolled
|
||||
/// in and out of view.
|
||||
///
|
||||
/// This class overrides the [ListTileThemeData.iconColor] and [ListTileThemeData.textColor]
|
||||
/// theme properties for its [ListTile]. These colors animate between values when
|
||||
/// the tile is expanded and collapsed: between [iconColor], [collapsedIconColor] and
|
||||
/// between [textColor] and [collapsedTextColor].
|
||||
///
|
||||
/// The expansion arrow icon is shown on the right by default in left-to-right languages
|
||||
/// (i.e. the trailing edge). This can be changed using [controlAffinity]. This maps
|
||||
/// to the [leading] and [trailing] properties of [CustomExpansionTile].
|
||||
///
|
||||
/// {@tool dartpad}
|
||||
/// This example demonstrates different configurations of CustomExpansionTile.
|
||||
///
|
||||
/// ** See code in examples/api/lib/material/expansion_tile/expansion_tile.0.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [ListTile], useful for creating expansion tile [children] when the
|
||||
/// expansion tile represents a sublist.
|
||||
/// * The "Expand and collapse" section of
|
||||
/// <https://material.io/components/lists#types>
|
||||
class CustomExpansionTile extends StatefulWidget {
|
||||
/// Creates a single-line [ListTile] with an expansion arrow icon that expands or collapses
|
||||
/// the tile to reveal or hide the [children]. The [initiallyExpanded] property must
|
||||
/// be non-null.
|
||||
const CustomExpansionTile({
|
||||
Key? key,
|
||||
this.leading,
|
||||
required this.title,
|
||||
this.subtitle,
|
||||
this.onExpansionChanged,
|
||||
this.children = const <Widget>[],
|
||||
this.initiallyExpanded = false,
|
||||
this.maintainState = false,
|
||||
this.tilePadding,
|
||||
this.expandedCrossAxisAlignment,
|
||||
this.expandedAlignment,
|
||||
this.childrenPadding,
|
||||
this.backgroundColor,
|
||||
this.collapsedBackgroundColor,
|
||||
this.textColor,
|
||||
this.collapsedTextColor,
|
||||
this.iconColor,
|
||||
this.collapsedIconColor,
|
||||
this.controlAffinity,
|
||||
}) : assert(initiallyExpanded != null),
|
||||
assert(maintainState != null),
|
||||
assert(
|
||||
expandedCrossAxisAlignment != CrossAxisAlignment.baseline,
|
||||
'CrossAxisAlignment.baseline is not supported since the expanded children '
|
||||
'are aligned in a column, not a row. Try to use another constant.',
|
||||
),
|
||||
super(key: key);
|
||||
|
||||
/// A widget to display before the title.
|
||||
///
|
||||
/// Typically a [CircleAvatar] widget.
|
||||
///
|
||||
/// Note that depending on the value of [controlAffinity], the [leading] widget
|
||||
/// may replace the rotating expansion arrow icon.
|
||||
final Widget? leading;
|
||||
|
||||
/// The primary content of the list item.
|
||||
///
|
||||
/// Typically a [Text] widget.
|
||||
final Widget title;
|
||||
|
||||
/// Additional content displayed below the title.
|
||||
///
|
||||
/// Typically a [Text] widget.
|
||||
final Widget? subtitle;
|
||||
|
||||
/// Called when the tile expands or collapses.
|
||||
///
|
||||
/// When the tile starts expanding, this function is called with the value
|
||||
/// true. When the tile starts collapsing, this function is called with
|
||||
/// the value false.
|
||||
final ValueChanged<bool>? onExpansionChanged;
|
||||
|
||||
/// The widgets that are displayed when the tile expands.
|
||||
///
|
||||
/// Typically [ListTile] widgets.
|
||||
final List<Widget> children;
|
||||
|
||||
/// The color to display behind the sublist when expanded.
|
||||
final Color? backgroundColor;
|
||||
|
||||
/// When not null, defines the background color of tile when the sublist is collapsed.
|
||||
final Color? collapsedBackgroundColor;
|
||||
|
||||
/// A widget to display after the title.
|
||||
///
|
||||
/// Note that depending on the value of [controlAffinity], the [trailing] widget
|
||||
/// may replace the rotating expansion arrow icon.
|
||||
|
||||
/// Specifies if the list tile is initially expanded (true) or collapsed (false, the default).
|
||||
final bool initiallyExpanded;
|
||||
|
||||
/// Specifies whether the state of the children is maintained when the tile expands and collapses.
|
||||
///
|
||||
/// When true, the children are kept in the tree while the tile is collapsed.
|
||||
/// When false (default), the children are removed from the tree when the tile is
|
||||
/// collapsed and recreated upon expansion.
|
||||
final bool maintainState;
|
||||
|
||||
/// Specifies padding for the [ListTile].
|
||||
///
|
||||
/// Analogous to [ListTile.contentPadding], this property defines the insets for
|
||||
/// the [leading], [title], [subtitle] and [trailing] widgets. It does not inset
|
||||
/// the expanded [children] widgets.
|
||||
///
|
||||
/// When the value is null, the tile's padding is `EdgeInsets.symmetric(horizontal: 16.0)`.
|
||||
final EdgeInsetsGeometry? tilePadding;
|
||||
|
||||
/// Specifies the alignment of [children], which are arranged in a column when
|
||||
/// the tile is expanded.
|
||||
///
|
||||
/// The internals of the expanded tile make use of a [Column] widget for
|
||||
/// [children], and [Align] widget to align the column. The `expandedAlignment`
|
||||
/// parameter is passed directly into the [Align].
|
||||
///
|
||||
/// Modifying this property controls the alignment of the column within the
|
||||
/// expanded tile, not the alignment of [children] widgets within the column.
|
||||
/// To align each child within [children], see [expandedCrossAxisAlignment].
|
||||
///
|
||||
/// The width of the column is the width of the widest child widget in [children].
|
||||
///
|
||||
/// When the value is null, the value of `expandedAlignment` is [Alignment.center].
|
||||
final Alignment? expandedAlignment;
|
||||
|
||||
/// Specifies the alignment of each child within [children] when the tile is expanded.
|
||||
///
|
||||
/// The internals of the expanded tile make use of a [Column] widget for
|
||||
/// [children], and the `crossAxisAlignment` parameter is passed directly into the [Column].
|
||||
///
|
||||
/// Modifying this property controls the cross axis alignment of each child
|
||||
/// within its [Column]. Note that the width of the [Column] that houses
|
||||
/// [children] will be the same as the widest child widget in [children]. It is
|
||||
/// not necessarily the width of [Column] is equal to the width of expanded tile.
|
||||
///
|
||||
/// To align the [Column] along the expanded tile, use the [expandedAlignment] property
|
||||
/// instead.
|
||||
///
|
||||
/// When the value is null, the value of `expandedCrossAxisAlignment` is [CrossAxisAlignment.center].
|
||||
final CrossAxisAlignment? expandedCrossAxisAlignment;
|
||||
|
||||
/// Specifies padding for [children].
|
||||
///
|
||||
/// When the value is null, the value of `childrenPadding` is [EdgeInsets.zero].
|
||||
final EdgeInsetsGeometry? childrenPadding;
|
||||
|
||||
/// The icon color of tile's expansion arrow icon when the sublist is expanded.
|
||||
///
|
||||
/// Used to override to the [ListTileThemeData.iconColor].
|
||||
final Color? iconColor;
|
||||
|
||||
/// The icon color of tile's expansion arrow icon when the sublist is collapsed.
|
||||
///
|
||||
/// Used to override to the [ListTileThemeData.iconColor].
|
||||
final Color? collapsedIconColor;
|
||||
|
||||
/// The color of the tile's titles when the sublist is expanded.
|
||||
///
|
||||
/// Used to override to the [ListTileThemeData.textColor].
|
||||
final Color? textColor;
|
||||
|
||||
/// The color of the tile's titles when the sublist is collapsed.
|
||||
///
|
||||
/// Used to override to the [ListTileThemeData.textColor].
|
||||
final Color? collapsedTextColor;
|
||||
|
||||
/// Typically used to force the expansion arrow icon to the tile's leading or trailing edge.
|
||||
///
|
||||
/// By default, the value of `controlAffinity` is [ListTileControlAffinity.platform],
|
||||
/// which means that the expansion arrow icon will appear on the tile's trailing edge.
|
||||
final ListTileControlAffinity? controlAffinity;
|
||||
|
||||
@override
|
||||
State<CustomExpansionTile> createState() => _CustomExpansionTileState();
|
||||
}
|
||||
|
||||
class _CustomExpansionTileState extends State<CustomExpansionTile>
|
||||
with SingleTickerProviderStateMixin {
|
||||
static final Animatable<double> _easeOutTween =
|
||||
CurveTween(curve: Curves.easeOut);
|
||||
static final Animatable<double> _easeInTween =
|
||||
CurveTween(curve: Curves.easeIn);
|
||||
static final Animatable<double> _halfTween =
|
||||
Tween<double>(begin: 0.0, end: 0.5);
|
||||
|
||||
final ColorTween _borderColorTween = ColorTween();
|
||||
final ColorTween _headerColorTween = ColorTween();
|
||||
final ColorTween _iconColorTween = ColorTween();
|
||||
final ColorTween _backgroundColorTween = ColorTween();
|
||||
|
||||
late AnimationController _controller;
|
||||
late Animation<double> _iconTurns;
|
||||
late Animation<double> _heightFactor;
|
||||
late Animation<Color?> _borderColor;
|
||||
late Animation<Color?> _headerColor;
|
||||
late Animation<Color?> _iconColor;
|
||||
late Animation<Color?> _backgroundColor;
|
||||
|
||||
bool _isExpanded = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = AnimationController(duration: _kExpand, vsync: this);
|
||||
_heightFactor = _controller.drive(_easeInTween);
|
||||
_iconTurns = _controller.drive(_halfTween.chain(_easeInTween));
|
||||
_borderColor = _controller.drive(_borderColorTween.chain(_easeOutTween));
|
||||
_headerColor = _controller.drive(_headerColorTween.chain(_easeInTween));
|
||||
_iconColor = _controller.drive(_iconColorTween.chain(_easeInTween));
|
||||
_backgroundColor =
|
||||
_controller.drive(_backgroundColorTween.chain(_easeOutTween));
|
||||
|
||||
_isExpanded = PageStorage.of(context)?.readState(context) as bool? ??
|
||||
widget.initiallyExpanded;
|
||||
if (_isExpanded) _controller.value = 1.0;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _handleTap() {
|
||||
setState(() {
|
||||
_isExpanded = !_isExpanded;
|
||||
if (_isExpanded) {
|
||||
_controller.forward();
|
||||
} else {
|
||||
_controller.reverse().then<void>((void value) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
// Rebuild without widget.children.
|
||||
});
|
||||
});
|
||||
}
|
||||
PageStorage.of(context)?.writeState(context, _isExpanded);
|
||||
});
|
||||
widget.onExpansionChanged?.call(_isExpanded);
|
||||
}
|
||||
|
||||
// Platform or null affinity defaults to trailing.
|
||||
ListTileControlAffinity _effectiveAffinity(
|
||||
ListTileControlAffinity? affinity) {
|
||||
switch (affinity ?? ListTileControlAffinity.trailing) {
|
||||
case ListTileControlAffinity.leading:
|
||||
return ListTileControlAffinity.leading;
|
||||
case ListTileControlAffinity.trailing:
|
||||
case ListTileControlAffinity.platform:
|
||||
return ListTileControlAffinity.trailing;
|
||||
}
|
||||
}
|
||||
|
||||
Widget? _buildIcon(BuildContext context) {
|
||||
return RotationTransition(
|
||||
turns: _iconTurns,
|
||||
child: const Icon(Icons.add),
|
||||
);
|
||||
}
|
||||
|
||||
Widget? _buildLeadingIcon(BuildContext context) {
|
||||
if (_effectiveAffinity(widget.controlAffinity) !=
|
||||
ListTileControlAffinity.leading) return null;
|
||||
return _buildIcon(context);
|
||||
}
|
||||
|
||||
Widget? _buildTrailingIcon(BuildContext context) {
|
||||
if (_effectiveAffinity(widget.controlAffinity) !=
|
||||
ListTileControlAffinity.trailing) return null;
|
||||
return _buildIcon(context);
|
||||
}
|
||||
|
||||
Widget _buildChildren(BuildContext context, Widget? child) {
|
||||
final Color borderSideColor = _borderColor.value ?? Colors.transparent;
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: _backgroundColor.value ?? Colors.transparent,
|
||||
border: Border(
|
||||
top: BorderSide(color: borderSideColor),
|
||||
bottom: BorderSide(color: borderSideColor),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ListTileTheme.merge(
|
||||
iconColor: _iconColor.value,
|
||||
textColor: _headerColor.value,
|
||||
child: ListTile(
|
||||
onTap: _handleTap,
|
||||
contentPadding: widget.tilePadding,
|
||||
leading: widget.leading ?? _buildLeadingIcon(context),
|
||||
title: widget.title,
|
||||
subtitle: widget.subtitle,
|
||||
trailing: _isExpanded ? Icon(Icons.remove) : Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
ClipRect(
|
||||
child: Align(
|
||||
alignment: widget.expandedAlignment ?? Alignment.center,
|
||||
heightFactor: _heightFactor.value,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
final ColorScheme colorScheme = theme.colorScheme;
|
||||
_borderColorTween.end = theme.dividerColor;
|
||||
_headerColorTween
|
||||
..begin = widget.collapsedTextColor ?? theme.textTheme.subtitle1!.color
|
||||
..end = widget.textColor ?? colorScheme.primary;
|
||||
_iconColorTween
|
||||
..begin = widget.collapsedIconColor ?? theme.unselectedWidgetColor
|
||||
..end = widget.iconColor ?? colorScheme.primary;
|
||||
_backgroundColorTween
|
||||
..begin = widget.collapsedBackgroundColor
|
||||
..end = widget.backgroundColor;
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final bool closed = !_isExpanded && _controller.isDismissed;
|
||||
final bool shouldRemoveChildren = closed && !widget.maintainState;
|
||||
|
||||
final Widget result = Offstage(
|
||||
offstage: closed,
|
||||
child: TickerMode(
|
||||
enabled: !closed,
|
||||
child: Padding(
|
||||
padding: widget.childrenPadding ?? EdgeInsets.zero,
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
widget.expandedCrossAxisAlignment ?? CrossAxisAlignment.center,
|
||||
children: widget.children,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: _controller.view,
|
||||
builder: _buildChildren,
|
||||
child: shouldRemoveChildren ? null : result,
|
||||
);
|
||||
}
|
||||
}
|
22
lib/widgets/custom_navigator.dart
Normal file
22
lib/widgets/custom_navigator.dart
Normal file
@ -0,0 +1,22 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomNavigator extends PageRouteBuilder {
|
||||
CustomNavigator({required this.child})
|
||||
: super(
|
||||
transitionDuration: Duration(milliseconds: 100),
|
||||
pageBuilder: (context, animation, secondaryAnimation) => child,
|
||||
);
|
||||
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation, Widget child) =>
|
||||
SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: Offset(1, 0),
|
||||
end: Offset.zero,
|
||||
).animate(animation),
|
||||
child: child,
|
||||
);
|
||||
}
|
22
lib/widgets/custom_navigator_bottom.dart
Normal file
22
lib/widgets/custom_navigator_bottom.dart
Normal file
@ -0,0 +1,22 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomNavigatorBottom extends PageRouteBuilder {
|
||||
CustomNavigatorBottom({required this.child})
|
||||
: super(
|
||||
transitionDuration: Duration(milliseconds: 100),
|
||||
pageBuilder: (context, animation, secondaryAnimation) => child,
|
||||
);
|
||||
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation, Widget child) =>
|
||||
SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: Offset(0, 1),
|
||||
end: Offset.zero,
|
||||
).animate(animation),
|
||||
child: child,
|
||||
);
|
||||
}
|
22
lib/widgets/custom_navigator_pop.dart
Normal file
22
lib/widgets/custom_navigator_pop.dart
Normal file
@ -0,0 +1,22 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomNavigatorPop extends PageRouteBuilder {
|
||||
CustomNavigatorPop({required this.child})
|
||||
: super(
|
||||
transitionDuration: Duration(milliseconds: 100),
|
||||
pageBuilder: (context, animation, secondaryAnimation) => child,
|
||||
);
|
||||
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation, Widget child) =>
|
||||
SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: Offset(-1, 0),
|
||||
end: Offset.zero,
|
||||
).animate(animation),
|
||||
child: child,
|
||||
);
|
||||
}
|
282
lib/widgets/edit_qna_user.dart
Normal file
282
lib/widgets/edit_qna_user.dart
Normal file
@ -0,0 +1,282 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/main.dart';
|
||||
import 'package:initial_folder/providers/posting_qna_provider.dart';
|
||||
import 'package:initial_folder/providers/qna_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:quill_html_editor/quill_html_editor.dart';
|
||||
|
||||
import '../size_config.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class EditQna extends StatefulWidget {
|
||||
const EditQna(
|
||||
{Key? key,
|
||||
required this.quest,
|
||||
required this.title,
|
||||
required this.id_lesson,
|
||||
required this.id_qna,
|
||||
required this.id_course,})
|
||||
: super(key: key);
|
||||
|
||||
final quest;
|
||||
final id_lesson;
|
||||
final title;
|
||||
final id_qna;
|
||||
final id_course;
|
||||
|
||||
@override
|
||||
State<EditQna> createState() => _EditQnaState();
|
||||
}
|
||||
|
||||
class _EditQnaState extends State<EditQna> {
|
||||
final TextEditingController _controllerTitle = TextEditingController();
|
||||
final QuillEditorController _controllerQuest = QuillEditorController();
|
||||
|
||||
final customToolbar = [
|
||||
ToolBarStyle.headerOne,
|
||||
ToolBarStyle.headerTwo,
|
||||
ToolBarStyle.bold,
|
||||
ToolBarStyle.italic,
|
||||
ToolBarStyle.underline,
|
||||
ToolBarStyle.color,
|
||||
ToolBarStyle.listBullet,
|
||||
ToolBarStyle.listOrdered,
|
||||
];
|
||||
|
||||
late String initialTitle;
|
||||
late String initialQuest;
|
||||
|
||||
double value = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
initialTitle = widget.title;
|
||||
initialQuest = widget.quest;
|
||||
|
||||
_controllerTitle.text = widget.title;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controllerTitle.dispose();
|
||||
_controllerQuest.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
PostingQnaProvider editQnaProvider =
|
||||
Provider.of<PostingQnaProvider>(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
'Edit Pertanyaan',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(16),
|
||||
letterSpacing: 0.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
TextField(
|
||||
controller: _controllerTitle,
|
||||
cursorColor: secondaryColor,
|
||||
scrollPadding: EdgeInsets.zero,
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Theme.of(context).brightness == Brightness.dark
|
||||
? seventeenColor
|
||||
: Colors.grey[200],
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
hintStyle: secondaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
letterSpacing: 0.5,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
hintText: "Masukkan Judul Pertanyaan",
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenWidth(18)),
|
||||
|
||||
ToolBar(
|
||||
toolBarColor: Theme.of(context).brightness == Brightness.dark
|
||||
? seventeenColor
|
||||
: Colors.grey[200]!,
|
||||
activeIconColor: primaryColor,
|
||||
iconColor: secondaryColor,
|
||||
padding: const EdgeInsets.all(8),
|
||||
iconSize: 20,
|
||||
controller: _controllerQuest,
|
||||
toolBarConfig: customToolbar,
|
||||
),
|
||||
|
||||
Container(
|
||||
height: 180,
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(10),
|
||||
bottomRight: Radius.circular(10),
|
||||
),
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey,
|
||||
blurRadius: 0.5,
|
||||
offset: Offset(0, 2),
|
||||
spreadRadius: 0.001,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: QuillHtmlEditor(
|
||||
hintText: 'Edit pertanyaan Anda',
|
||||
controller: _controllerQuest,
|
||||
isEnabled: true,
|
||||
minHeight: 100,
|
||||
backgroundColor:
|
||||
Theme.of(context).brightness == Brightness.dark
|
||||
? seventeenColor
|
||||
: Colors.grey[200]!,
|
||||
textStyle: secondaryTextStyle.copyWith(
|
||||
// color: secondaryColor,
|
||||
fontSize: getProportionateScreenWidth(16),
|
||||
),
|
||||
hintTextStyle: secondaryTextStyle.copyWith(
|
||||
// color: secondaryColor,
|
||||
fontSize: getProportionateScreenWidth(16),
|
||||
),
|
||||
hintTextAlign: TextAlign.start,
|
||||
padding: const EdgeInsets.all(3),
|
||||
hintTextPadding: const EdgeInsets.all(0),
|
||||
loadingBuilder: (context) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 0.4,
|
||||
),
|
||||
);
|
||||
},
|
||||
onEditorCreated: () {
|
||||
if (widget.quest.isNotEmpty) {
|
||||
_controllerQuest.setText(widget.quest);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(4)),
|
||||
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: ElevatedButton(
|
||||
onPressed: () async {
|
||||
String currentTitle = _controllerTitle.text;
|
||||
String currentQuest = await _controllerQuest.getText();
|
||||
|
||||
String currentQuestTrimmed = currentQuest.trim();
|
||||
String initialQuestTrimmed = initialQuest.trim();
|
||||
|
||||
// Cek apakah ada perubahan
|
||||
if (currentTitle == initialTitle &&
|
||||
currentQuestTrimmed == initialQuestTrimmed) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: primaryColor,
|
||||
content: Text(
|
||||
'Tidak ada perubahan',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
bool success = await editQnaProvider.editQna(
|
||||
widget.id_course,
|
||||
currentQuest,
|
||||
int.parse(widget.id_qna.toString()),
|
||||
currentTitle,
|
||||
widget.id_lesson,
|
||||
);
|
||||
if (success) {
|
||||
ScaffoldMessenger.of(globalScaffoldKey.currentContext!)
|
||||
.showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: primaryColor,
|
||||
content: Text(
|
||||
'Pertanyaan berhasil diedit',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color:Colors.white,
|
||||
),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
_controllerQuest.clear();
|
||||
_controllerTitle.clear();
|
||||
Navigator.pop(context);
|
||||
} else {
|
||||
ScaffoldMessenger.of(globalScaffoldKey.currentContext!)
|
||||
.showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: primaryColor,
|
||||
content: Text(
|
||||
'Terjadi kesalahan',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
'Edit Pertanyaan',
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: SizeConfig.blockHorizontal! * 4,
|
||||
),
|
||||
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
171
lib/widgets/edit_reply_qna_user.dart
Normal file
171
lib/widgets/edit_reply_qna_user.dart
Normal file
@ -0,0 +1,171 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/posting_qna_reply_provider.dart';
|
||||
import 'package:initial_folder/screens/course/component/detail_quest_and_answer.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../size_config.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class EditReplyQna extends StatefulWidget {
|
||||
const EditReplyQna(
|
||||
{Key? key,
|
||||
required this.id_qna,
|
||||
required this.text_rep,
|
||||
required this.id_rep})
|
||||
: super(key: key);
|
||||
|
||||
final id_qna;
|
||||
final text_rep;
|
||||
final id_rep;
|
||||
|
||||
@override
|
||||
State<EditReplyQna> createState() => _EditReplyQnaState();
|
||||
}
|
||||
|
||||
class _EditReplyQnaState extends State<EditReplyQna> {
|
||||
final _textControlBalasan = TextEditingController();
|
||||
double value = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
if (widget.text_rep != null) {
|
||||
_textControlBalasan.text = widget.text_rep ?? '';
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_textControlBalasan.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
PostingQnaReplyProvider editQnaReplyProvider =
|
||||
Provider.of<PostingQnaReplyProvider>(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
'Edit Balasan',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(16),
|
||||
letterSpacing: 0.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
TextField(
|
||||
controller: _textControlBalasan,
|
||||
cursorColor: secondaryColor,
|
||||
scrollPadding: EdgeInsets.zero,
|
||||
minLines: 2,
|
||||
keyboardType: TextInputType.multiline,
|
||||
maxLines: null,
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Theme.of(context).brightness == Brightness.dark
|
||||
? seventeenColor
|
||||
: Colors.grey[200],
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
borderSide: BorderSide.none),
|
||||
hintStyle: secondaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
letterSpacing: 0.5,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(4),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: ElevatedButton(
|
||||
onPressed: () async {
|
||||
if (await editQnaReplyProvider
|
||||
.editQnaReply(
|
||||
_textControlBalasan.text,
|
||||
int.parse(widget.id_rep.toString()),
|
||||
widget.id_qna)
|
||||
.whenComplete(
|
||||
() {
|
||||
_textControlBalasan.clear();
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: primaryColor,
|
||||
content: Text(
|
||||
'Balasan berhasil diedit',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
);
|
||||
return Navigator.pop(context, true);
|
||||
// await Provider.of(context)<QnaProvider>(context,
|
||||
// listen: true)
|
||||
// .getQna(widget.id_course);
|
||||
},
|
||||
))
|
||||
;
|
||||
else {
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: primaryColor,
|
||||
content: Text(
|
||||
'Terjadi kesalahan',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: backgroundColor,
|
||||
),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
'Edit Balasan',
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: SizeConfig.blockHorizontal! * 4,
|
||||
),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
10
lib/widgets/list_notifikasi.dart
Normal file
10
lib/widgets/list_notifikasi.dart
Normal file
@ -0,0 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
class ListNotifikasi extends StatelessWidget {
|
||||
const ListNotifikasi({Key? key, required this.data}) : super(key: key);
|
||||
final List data;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Text(data[0].toString());
|
||||
}
|
||||
}
|
136
lib/widgets/loading/loading_my_course.dart
Normal file
136
lib/widgets/loading/loading_my_course.dart
Normal file
@ -0,0 +1,136 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
|
||||
class LoadingMyCourse extends StatelessWidget {
|
||||
const LoadingMyCourse({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(16),
|
||||
right: getProportionateScreenWidth(16),
|
||||
top: getProportionateScreenWidth(10),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 11,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: getProportionateScreenWidth(156),
|
||||
height: getProportionateScreenWidth(88),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: secondaryColor),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(8),
|
||||
),
|
||||
],
|
||||
)),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(9),
|
||||
),
|
||||
Flexible(
|
||||
flex: 10,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 30,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: secondaryColor),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenWidth(8),
|
||||
),
|
||||
Container(
|
||||
height: 8,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: secondaryColor),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenWidth(6),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
height: 10,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: secondaryColor),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(5),
|
||||
),
|
||||
Container(
|
||||
height: 10,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: secondaryColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
height: getProportionateScreenWidth(4),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: secondaryColor),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenWidth(6)),
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Container(
|
||||
width: 30,
|
||||
height: 10,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: secondaryColor),
|
||||
),
|
||||
),
|
||||
Row(children: [
|
||||
Container(
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: secondaryColor),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(10),
|
||||
),
|
||||
Container(
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: secondaryColor),
|
||||
),
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: fourthColor,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
978
lib/widgets/login_regist/custom_font_awesome.dart
Normal file
978
lib/widgets/login_regist/custom_font_awesome.dart
Normal file
@ -0,0 +1,978 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
|
||||
IconData fontAwesomeIconsFromString(String name) {
|
||||
switch (name) {
|
||||
case "FontAwesomeIcons.moneyBillAlt":
|
||||
return FontAwesomeIcons.moneyBillAlt;
|
||||
|
||||
case "FontAwesomeIcons.desktop":
|
||||
return FontAwesomeIcons.desktop;
|
||||
|
||||
case "FontAwesomeIcons.music":
|
||||
return FontAwesomeIcons.music;
|
||||
|
||||
case "FontAwesomeIcons.pencilAlt":
|
||||
return FontAwesomeIcons.pencilAlt;
|
||||
|
||||
case "FontAwesomeIcons.pencilRuler":
|
||||
return FontAwesomeIcons.pencilRuler;
|
||||
|
||||
case "FontAwesomeIcons.shoppingBag":
|
||||
return FontAwesomeIcons.shoppingBag;
|
||||
|
||||
case "FontAwesomeIcons.chartLine":
|
||||
return FontAwesomeIcons.chartLine;
|
||||
|
||||
case "FontAwesomeIcons.clipboardList":
|
||||
return FontAwesomeIcons.clipboardList;
|
||||
|
||||
case "FontAwesomeIcons.chess":
|
||||
return FontAwesomeIcons.chess;
|
||||
|
||||
case "FontAwesomeIcons.cameraRetro":
|
||||
return FontAwesomeIcons.cameraRetro;
|
||||
|
||||
case "FontAwesomeIcons.graduationCap":
|
||||
return FontAwesomeIcons.graduationCap;
|
||||
|
||||
case "FontAwesomeIcons.accessibleIcon":
|
||||
return FontAwesomeIcons.accessibleIcon;
|
||||
|
||||
case "FontawesomeIcons.accusoft":
|
||||
return FontAwesomeIcons.accusoft;
|
||||
|
||||
case "FontAwesomeIcons.acquisitionIncorporated":
|
||||
return FontAwesomeIcons.a;
|
||||
|
||||
case "FontAwesomeIcons.ad":
|
||||
return FontAwesomeIcons.ad;
|
||||
|
||||
case "FontAwesomeIcons.addressBook":
|
||||
return FontAwesomeIcons.addressBook;
|
||||
|
||||
case "FontAwesomeIcons.addressCard":
|
||||
return FontAwesomeIcons.addressCard;
|
||||
|
||||
case "FontAwesomeIcons.adjust":
|
||||
return FontAwesomeIcons.adjust;
|
||||
|
||||
case "FontAwesomeIcons.adn":
|
||||
return FontAwesomeIcons.adn;
|
||||
|
||||
case "FontAwesomeIcons.adversal":
|
||||
return FontAwesomeIcons.adversal;
|
||||
|
||||
case "FontAwesomeIcons.affiliatetheme":
|
||||
return FontAwesomeIcons.affiliatetheme;
|
||||
|
||||
case "FontAwesomeIcons.airFreshener":
|
||||
return FontAwesomeIcons.airFreshener;
|
||||
|
||||
case "FontAwesomeIcons.airbnb":
|
||||
return FontAwesomeIcons.airbnb;
|
||||
|
||||
case "FontAwesomeIcons.algolia":
|
||||
return FontAwesomeIcons.algolia;
|
||||
|
||||
case "FontAwesomeIcons.alignCenter":
|
||||
return FontAwesomeIcons.alignCenter;
|
||||
|
||||
case "FontAwesomeIcons.alignJustify":
|
||||
return FontAwesomeIcons.alignJustify;
|
||||
|
||||
case "FontAwesomeIcons.alignLeft":
|
||||
return FontAwesomeIcons.alignLeft;
|
||||
|
||||
case "FontAwesomeIcons.alignRight":
|
||||
return FontAwesomeIcons.alignRight;
|
||||
|
||||
case "FontAwesomeIcons.alipay":
|
||||
return FontAwesomeIcons.alipay;
|
||||
|
||||
case "FontAwesomeIcons.allergies":
|
||||
return FontAwesomeIcons.allergies;
|
||||
|
||||
case "FontAwesomeIcons.amazon":
|
||||
return FontAwesomeIcons.amazon;
|
||||
|
||||
case "FontAwesomeIcons.amazonPay":
|
||||
return FontAwesomeIcons.amazonPay;
|
||||
|
||||
case "FontAwesomeIcons.ambulance":
|
||||
return FontAwesomeIcons.ambulance;
|
||||
|
||||
case "FontAwesomeIcons.americanSignLanguageInterpreting":
|
||||
return FontAwesomeIcons.americanSignLanguageInterpreting;
|
||||
|
||||
case "FontAwesomeIcons.amilia":
|
||||
return FontAwesomeIcons.amilia;
|
||||
|
||||
case "FontAwesomeIcons.anchor":
|
||||
return FontAwesomeIcons.anchor;
|
||||
|
||||
case "FontAwesomeIcons.android":
|
||||
return FontAwesomeIcons.android;
|
||||
|
||||
case "FontAwesomeIcons.angellist":
|
||||
return FontAwesomeIcons.angellist;
|
||||
|
||||
case "FontAwesomeIcons.angleDoubleDown":
|
||||
return FontAwesomeIcons.angleDoubleDown;
|
||||
|
||||
case "FontAwesomeIcons.angleDoubleLeft":
|
||||
return FontAwesomeIcons.angleDoubleLeft;
|
||||
|
||||
case "FontAwesomeIcons.angleDoubleRight":
|
||||
return FontAwesomeIcons.angleDoubleRight;
|
||||
|
||||
case "FontAwesomeIcons.angleDoubleUp":
|
||||
return FontAwesomeIcons.angleDoubleUp;
|
||||
|
||||
case "FontAwesomeIcons.angleDown":
|
||||
return FontAwesomeIcons.angleDown;
|
||||
|
||||
case "FontAwesomeIcons.angleLeft":
|
||||
return FontAwesomeIcons.angleLeft;
|
||||
|
||||
case "FontAwesomeIcons.angleRight":
|
||||
return FontAwesomeIcons.angleRight;
|
||||
|
||||
case "FontAwesomeIcons.angleUp":
|
||||
return FontAwesomeIcons.angleUp;
|
||||
|
||||
case "FontAwesomeIcons.angry":
|
||||
return FontAwesomeIcons.angry;
|
||||
|
||||
case "FontAwesomeIcons.angrycreative":
|
||||
return FontAwesomeIcons.angrycreative;
|
||||
|
||||
case "FontAwesomeIcons.angular":
|
||||
return FontAwesomeIcons.angular;
|
||||
|
||||
case "FontAwesomeIcons.ankh":
|
||||
return FontAwesomeIcons.ankh;
|
||||
|
||||
case "FontAwesomeIcons.appStore":
|
||||
return FontAwesomeIcons.appStore;
|
||||
|
||||
case "FontAwesomeIcons.appStoreIos":
|
||||
return FontAwesomeIcons.appStoreIos;
|
||||
|
||||
case "FontAwesomeIcons.apper":
|
||||
return FontAwesomeIcons.apper;
|
||||
|
||||
case "FontAwesomeIcons.apple":
|
||||
return FontAwesomeIcons.apple;
|
||||
|
||||
case "FontAwesomeIcons.appleAlt":
|
||||
return FontAwesomeIcons.appleAlt;
|
||||
|
||||
case "FontAwesomeIcons.applePay":
|
||||
return FontAwesomeIcons.applePay;
|
||||
|
||||
case "FontAwesomeIcons.archive":
|
||||
return FontAwesomeIcons.archive;
|
||||
|
||||
case "FontAwesomeIcons.archway":
|
||||
return FontAwesomeIcons.archway;
|
||||
|
||||
case "FontAwesomeIcons.arrowAltCircleDown":
|
||||
return FontAwesomeIcons.arrowAltCircleDown;
|
||||
|
||||
case "FontAwesomeIcons.arrowAltCircleLeft":
|
||||
return FontAwesomeIcons.arrowAltCircleLeft;
|
||||
|
||||
case "FontAwesomeIcons.arrowAltCircleRight":
|
||||
return FontAwesomeIcons.arrowAltCircleRight;
|
||||
|
||||
case "FontAwesomeIcons.arrowAltCircleUp":
|
||||
return FontAwesomeIcons.arrowAltCircleUp;
|
||||
|
||||
case "FontAwesomeIcons.arrowCircleDown":
|
||||
return FontAwesomeIcons.arrowCircleDown;
|
||||
|
||||
case "FontAwesomeIcons.arrowCircleLeft":
|
||||
return FontAwesomeIcons.arrowCircleLeft;
|
||||
|
||||
case "FontAwesomeIcons.arrowCircleRight":
|
||||
return FontAwesomeIcons.arrowCircleRight;
|
||||
|
||||
case "FontAwesomeIcons.arrowCircleUp":
|
||||
return FontAwesomeIcons.arrowCircleUp;
|
||||
|
||||
case "FontAwesomeIcons.arrowDown":
|
||||
return FontAwesomeIcons.arrowDown;
|
||||
|
||||
case "FontAwesomeIcons.arrowLeft":
|
||||
return FontAwesomeIcons.arrowLeft;
|
||||
|
||||
case "FontAwesomeIcons.arrowRight":
|
||||
return FontAwesomeIcons.arrowRight;
|
||||
|
||||
case "FontAwesomeIcons.arrowUp":
|
||||
return FontAwesomeIcons.arrowUp;
|
||||
|
||||
case "FontAwesomeIcons.arrowsAlt":
|
||||
return FontAwesomeIcons.arrowsAlt;
|
||||
|
||||
case "FontAwesomeIcons.arrowsAltH":
|
||||
return FontAwesomeIcons.arrowsAltH;
|
||||
|
||||
case "FontAwesomeIcons.arrowsAltV":
|
||||
return FontAwesomeIcons.arrowsAltV;
|
||||
|
||||
case "FontAwesomeIcons.artstation":
|
||||
return FontAwesomeIcons.artstation;
|
||||
|
||||
case "FontAwesomeIcons.assistiveListeningSystems":
|
||||
return FontAwesomeIcons.assistiveListeningSystems;
|
||||
|
||||
case "FontAwesomeIcons.asterisk":
|
||||
return FontAwesomeIcons.asterisk;
|
||||
|
||||
case "FontAwesomeIcons.asymmetrik":
|
||||
return FontAwesomeIcons.asymmetrik;
|
||||
|
||||
case "FontAwesomeIcons.at":
|
||||
return FontAwesomeIcons.at;
|
||||
|
||||
case "FontAwesomeIcons.atlas":
|
||||
return FontAwesomeIcons.atlas;
|
||||
|
||||
case "FontAwesomeIcons.atlassian":
|
||||
return FontAwesomeIcons.atlassian;
|
||||
|
||||
case "FontAwesomeIcons.atom":
|
||||
return FontAwesomeIcons.atom;
|
||||
|
||||
case "FontAwesomeIcons.audible":
|
||||
return FontAwesomeIcons.audible;
|
||||
|
||||
case "FontAwesomeIcons.audioDescription":
|
||||
return FontAwesomeIcons.audioDescription;
|
||||
|
||||
case "FontAwesomeIcons.autoprefixer":
|
||||
return FontAwesomeIcons.autoprefixer;
|
||||
|
||||
case "FontAwesomeIcons.avianex":
|
||||
return FontAwesomeIcons.avianex;
|
||||
|
||||
case "FontAwesomeIcons.aviato":
|
||||
return FontAwesomeIcons.aviato;
|
||||
|
||||
case "FontAwesomeIcons.award":
|
||||
return FontAwesomeIcons.award;
|
||||
|
||||
case "FontAwesomeIcons.aws":
|
||||
return FontAwesomeIcons.aws;
|
||||
|
||||
case "FontAwesomeIcons.baby":
|
||||
return FontAwesomeIcons.baby;
|
||||
|
||||
case "FontAwesomeIcons.babyCarriage":
|
||||
return FontAwesomeIcons.babyCarriage;
|
||||
|
||||
case "FontAwesomeIcons.backspace":
|
||||
return FontAwesomeIcons.backspace;
|
||||
|
||||
case "FontAwesomeIcons.backward":
|
||||
return FontAwesomeIcons.backward;
|
||||
|
||||
case "FontAwesomeIcons.bacon":
|
||||
return FontAwesomeIcons.bacon;
|
||||
|
||||
case "FontAwesomeIcons.bahai":
|
||||
return FontAwesomeIcons.bahai;
|
||||
|
||||
case "FontAwesomeIcons.balanceScale":
|
||||
return FontAwesomeIcons.balanceScale;
|
||||
|
||||
case "FontAwesomeIcons.balanceScaleLeft":
|
||||
return FontAwesomeIcons.balanceScaleLeft;
|
||||
|
||||
case "FontAwesomeIcons.balanceScaleRight":
|
||||
return FontAwesomeIcons.balanceScaleRight;
|
||||
|
||||
case "FontAwesomeIcons.ban":
|
||||
return FontAwesomeIcons.ban;
|
||||
|
||||
case "FontAwesomeIcons.bandAid":
|
||||
return FontAwesomeIcons.bandAid;
|
||||
|
||||
case "FontAwesomeIcons.bandcamp":
|
||||
return FontAwesomeIcons.bandcamp;
|
||||
|
||||
case "FontAwesomeIcons.barcode":
|
||||
return FontAwesomeIcons.barcode;
|
||||
|
||||
case "FontAwesomeIcons.bars":
|
||||
return FontAwesomeIcons.bars;
|
||||
|
||||
case "FontAwesomeIcons.baseballBall":
|
||||
return FontAwesomeIcons.baseballBall;
|
||||
|
||||
case "FontAwesomeIcons.basketballBall":
|
||||
return FontAwesomeIcons.basketballBall;
|
||||
|
||||
case "FontAwesomeIcons.bath":
|
||||
return FontAwesomeIcons.bath;
|
||||
|
||||
case "FontAwesomeIcons.batteryEmpty":
|
||||
return FontAwesomeIcons.batteryEmpty;
|
||||
|
||||
case "FontAwesomeIcons.batteryFull":
|
||||
return FontAwesomeIcons.batteryFull;
|
||||
|
||||
case "FontAwesomeIcons.batteryHalf":
|
||||
return FontAwesomeIcons.batteryHalf;
|
||||
|
||||
case "FontAwesomeIcons.batteryQuarter":
|
||||
return FontAwesomeIcons.batteryQuarter;
|
||||
|
||||
case "FontAwesomeIcons.batteryThreeQuarters":
|
||||
return FontAwesomeIcons.batteryThreeQuarters;
|
||||
|
||||
case "FontAwesomeIcons.battleNet":
|
||||
return FontAwesomeIcons.battleNet;
|
||||
|
||||
case "FontAwesomeIcons.bed":
|
||||
return FontAwesomeIcons.bed;
|
||||
|
||||
case 'FontAwesomeIcons.beer':
|
||||
return FontAwesomeIcons.beer;
|
||||
|
||||
case "FontAwesomeIcons.behance":
|
||||
return FontAwesomeIcons.behance;
|
||||
|
||||
case "FontAwesomeIcons.behanceSquare":
|
||||
return FontAwesomeIcons.behanceSquare;
|
||||
|
||||
case "FontAwesomeIcons.bell":
|
||||
return FontAwesomeIcons.bell;
|
||||
|
||||
case "FontAwesomeIcons.bellSlash":
|
||||
return FontAwesomeIcons.bellSlash;
|
||||
|
||||
case "FontAwesomeIcons.bezierCurve":
|
||||
return FontAwesomeIcons.bezierCurve;
|
||||
|
||||
case "FontAwesomeIcons.bible":
|
||||
return FontAwesomeIcons.bible;
|
||||
|
||||
case "FontAwesomeIcons.bicycle":
|
||||
return FontAwesomeIcons.bicycle;
|
||||
|
||||
case "FontAwesomeIcons.biking":
|
||||
return FontAwesomeIcons.biking;
|
||||
|
||||
case "FontAwesomeIcons.bimobject":
|
||||
return FontAwesomeIcons.bimobject;
|
||||
|
||||
case "FontAwesomeIcons.binoculars":
|
||||
return FontAwesomeIcons.binoculars;
|
||||
|
||||
case "FontAwesomeIcons.biohazard":
|
||||
return FontAwesomeIcons.biohazard;
|
||||
|
||||
case "FontAwesomeIcons.birthdayCake":
|
||||
return FontAwesomeIcons.birthdayCake;
|
||||
|
||||
case "FontAwesomeIcons.bitbucket":
|
||||
return FontAwesomeIcons.bitbucket;
|
||||
|
||||
case "FontAwesomeIcons.bitcoin":
|
||||
return FontAwesomeIcons.bitcoin;
|
||||
|
||||
case "FontAwesomeIcons.bity":
|
||||
return FontAwesomeIcons.bity;
|
||||
|
||||
case "FontAwesomeIcons.blackTie":
|
||||
return FontAwesomeIcons.blackTie;
|
||||
|
||||
case "FontAwesomeIcons.blackberry":
|
||||
return FontAwesomeIcons.blackberry;
|
||||
|
||||
case "FontAwesomeIcons.blender":
|
||||
return FontAwesomeIcons.blender;
|
||||
|
||||
case "FontAwesomeIcons.blenderPhone":
|
||||
return FontAwesomeIcons.blenderPhone;
|
||||
|
||||
case "FontAwesomeIcons.blind":
|
||||
return FontAwesomeIcons.blind;
|
||||
|
||||
case "FontAwesomeIcons.blog":
|
||||
return FontAwesomeIcons.blog;
|
||||
|
||||
case "FontAwesomeIcons.blogger":
|
||||
return FontAwesomeIcons.blogger;
|
||||
|
||||
case "FontAwesomeIcons.bloggerB":
|
||||
return FontAwesomeIcons.bloggerB;
|
||||
|
||||
case "FontAwesomeIcons.bluetooth":
|
||||
return FontAwesomeIcons.bluetooth;
|
||||
|
||||
case "FontAwesomeIcons.bluetoothB":
|
||||
return FontAwesomeIcons.bluetoothB;
|
||||
|
||||
case "FontAwesomeIcons.bold":
|
||||
return FontAwesomeIcons.bold;
|
||||
|
||||
case "FontAwesomeIcons.bolt":
|
||||
return FontAwesomeIcons.bolt;
|
||||
|
||||
case "FontAwesomeIcons.bomb":
|
||||
return FontAwesomeIcons.bomb;
|
||||
|
||||
case "FontAwesomeIcons.bone":
|
||||
return FontAwesomeIcons.bone;
|
||||
|
||||
case "FontAwesomeIcons.bong":
|
||||
return FontAwesomeIcons.bong;
|
||||
|
||||
case "FontAwesomeIcons.book":
|
||||
return FontAwesomeIcons.book;
|
||||
|
||||
case "FontAwesomeIcons.bookDead":
|
||||
return FontAwesomeIcons.bookDead;
|
||||
|
||||
case "FontAwesomeIcons.bookMedical":
|
||||
return FontAwesomeIcons.bookMedical;
|
||||
|
||||
case "FontAwesomeIcons.bookOpen":
|
||||
return FontAwesomeIcons.bookOpen;
|
||||
|
||||
case "FontAwesomeIcons.bookReader":
|
||||
return FontAwesomeIcons.bookReader;
|
||||
|
||||
case "FontAwesomeIcons.bookmark":
|
||||
return FontAwesomeIcons.bookmark;
|
||||
|
||||
case "FontAwesomeIcons.bootstrap":
|
||||
return FontAwesomeIcons.bootstrap;
|
||||
|
||||
case "FontAwesomeIcons.borderAll":
|
||||
return FontAwesomeIcons.borderAll;
|
||||
|
||||
case "FontAwesomeIcons.borderNone":
|
||||
return FontAwesomeIcons.borderNone;
|
||||
|
||||
case "FontAwesomeIcons.borderStyle":
|
||||
return FontAwesomeIcons.borderStyle;
|
||||
|
||||
case "FontAwesomeIcons.bowlingBall":
|
||||
return FontAwesomeIcons.bowlingBall;
|
||||
|
||||
case "FontAwesomeIcons.box":
|
||||
return FontAwesomeIcons.box;
|
||||
|
||||
case "FontAwesomeIcons.boxOpen":
|
||||
return FontAwesomeIcons.boxOpen;
|
||||
|
||||
case "FontAwesomeIcons.boxTissue":
|
||||
return FontAwesomeIcons.boxTissue;
|
||||
|
||||
case "FontAwesomeIcons.boxes":
|
||||
return FontAwesomeIcons.boxes;
|
||||
|
||||
case "FontAwesomeIcons.braille":
|
||||
return FontAwesomeIcons.braille;
|
||||
|
||||
case "FontAwesomeIcons.brain":
|
||||
return FontAwesomeIcons.brain;
|
||||
|
||||
case "FontAwesomeIcons.breadSlice":
|
||||
return FontAwesomeIcons.breadSlice;
|
||||
|
||||
case "FontAwesomeIcons.briefcase":
|
||||
return FontAwesomeIcons.briefcase;
|
||||
|
||||
case "FontAwesomeIcons.briefcaseMedical":
|
||||
return FontAwesomeIcons.briefcaseMedical;
|
||||
|
||||
case "FontAwesomeIcons.broadcastTower":
|
||||
return FontAwesomeIcons.broadcastTower;
|
||||
|
||||
case "FontAwesomeIcons.broom":
|
||||
return FontAwesomeIcons.broom;
|
||||
|
||||
case "FontAwesomeIcons.brush":
|
||||
return FontAwesomeIcons.brush;
|
||||
|
||||
case "FontAwesomeIcons.btc":
|
||||
return FontAwesomeIcons.btc;
|
||||
|
||||
case "FontAwesomeIcons.buffer":
|
||||
return FontAwesomeIcons.buffer;
|
||||
|
||||
case "FontAwesomeIcons.bug":
|
||||
return FontAwesomeIcons.bug;
|
||||
|
||||
case "FontAwesomeIcons.building":
|
||||
return FontAwesomeIcons.building;
|
||||
|
||||
case "FontAwesomeIcons.bullhorn":
|
||||
return FontAwesomeIcons.bullhorn;
|
||||
|
||||
case "FontAwesomeIcons.bullseye":
|
||||
return FontAwesomeIcons.bullseye;
|
||||
|
||||
case "FontAwesomeIcons.burn":
|
||||
return FontAwesomeIcons.burn;
|
||||
|
||||
case "FontAwesomeIcons.buromobelexperte":
|
||||
return FontAwesomeIcons.buromobelexperte;
|
||||
|
||||
case "FontAwesomeIcons.bus":
|
||||
return FontAwesomeIcons.bus;
|
||||
|
||||
case "FontAwesomeIcons.busAlt":
|
||||
return FontAwesomeIcons.busAlt;
|
||||
|
||||
case "FontAwesomeIcons.businessTime":
|
||||
return FontAwesomeIcons.businessTime;
|
||||
|
||||
case "FontAwesomeIcons.buyNLarge":
|
||||
return FontAwesomeIcons.buyNLarge;
|
||||
|
||||
case "FontAwesomeIcons.buysellads":
|
||||
return FontAwesomeIcons.buysellads;
|
||||
|
||||
case "FontAwesomeIcons.calculator":
|
||||
return FontAwesomeIcons.calculator;
|
||||
|
||||
case "FontAwesomeIcons.calendar":
|
||||
return FontAwesomeIcons.calendar;
|
||||
|
||||
case "FontAwesomeIcons.calendarAlt":
|
||||
return FontAwesomeIcons.calendarAlt;
|
||||
|
||||
case "FontAwesomeIcons.calendarCheck":
|
||||
return FontAwesomeIcons.calendarCheck;
|
||||
|
||||
case "FontAwesomeIcons.calendarDay":
|
||||
return FontAwesomeIcons.calendarDay;
|
||||
|
||||
case "FontAwesomeIcons.calendarMinus":
|
||||
return FontAwesomeIcons.calendarMinus;
|
||||
|
||||
case "FontAwesomeIcons.calendarPlus":
|
||||
return FontAwesomeIcons.calendarPlus;
|
||||
|
||||
case "FontAwesomeIcons.calendarTimes":
|
||||
return FontAwesomeIcons.calendarTimes;
|
||||
|
||||
case "FontAwesomeIcons.calendarWeek":
|
||||
return FontAwesomeIcons.calendarWeek;
|
||||
|
||||
case "FontAwesomeIcons.camera":
|
||||
return FontAwesomeIcons.camera;
|
||||
|
||||
case "FontAwesomeIcons.campground":
|
||||
return FontAwesomeIcons.campground;
|
||||
|
||||
case "FontAwesomeIcons.canadianMapleLeaf":
|
||||
return FontAwesomeIcons.canadianMapleLeaf;
|
||||
|
||||
case "FontAwesomeIcons.candyCane":
|
||||
return FontAwesomeIcons.candyCane;
|
||||
|
||||
case "FontAwesomeIcons.cannabis":
|
||||
return FontAwesomeIcons.cannabis;
|
||||
|
||||
case "FontAwesomeIcons.capsules":
|
||||
return FontAwesomeIcons.capsules;
|
||||
|
||||
case "FontAwesomeIcons.car":
|
||||
return FontAwesomeIcons.car;
|
||||
|
||||
case "FontAwesomeIcons.carAlt":
|
||||
return FontAwesomeIcons.carAlt;
|
||||
|
||||
case "FontAwesomeIcons.carBattery":
|
||||
return FontAwesomeIcons.carBattery;
|
||||
|
||||
case "FontAwesomeIcons.carCrash":
|
||||
return FontAwesomeIcons.carCrash;
|
||||
|
||||
case "FontAwesomeIcons.carSide":
|
||||
return FontAwesomeIcons.carSide;
|
||||
|
||||
case "FontAwesomeIcons.caravan":
|
||||
return FontAwesomeIcons.caravan;
|
||||
|
||||
case "FontAwesomeIcons.caretDown":
|
||||
return FontAwesomeIcons.caretDown;
|
||||
|
||||
case "FontAwesomeIcons.caretLeft":
|
||||
return FontAwesomeIcons.caretLeft;
|
||||
|
||||
case "FontAwesomeIcons.caretRight":
|
||||
return FontAwesomeIcons.caretRight;
|
||||
|
||||
case "FontAwesomeIcons.caretSquareDown":
|
||||
return FontAwesomeIcons.caretSquareDown;
|
||||
|
||||
case "FontAwesomeIcons.caretSquareLeft":
|
||||
return FontAwesomeIcons.caretSquareLeft;
|
||||
|
||||
case "FontAwesomeIcons.caretSquareRight":
|
||||
return FontAwesomeIcons.caretSquareRight;
|
||||
|
||||
case "FontAwesomeIcons.caretSquareUp":
|
||||
return FontAwesomeIcons.caretSquareUp;
|
||||
|
||||
case "FontAwesomeIcons.caretUp":
|
||||
return FontAwesomeIcons.caretUp;
|
||||
|
||||
case "FontAwesomeIcons.carrot":
|
||||
return FontAwesomeIcons.carrot;
|
||||
|
||||
case "FontAwesomeIcons.cartArrowDown":
|
||||
return FontAwesomeIcons.cartArrowDown;
|
||||
|
||||
case "FontAwesomeIcons.cartPlus":
|
||||
return FontAwesomeIcons.cartPlus;
|
||||
|
||||
case "FontAwesomeIcons.cashRegister":
|
||||
return FontAwesomeIcons.cashRegister;
|
||||
|
||||
case "FontAwesomeIcons.cat":
|
||||
return FontAwesomeIcons.cat;
|
||||
|
||||
case "FontAwesomeIcons.ccAmazonPay":
|
||||
return FontAwesomeIcons.ccAmazonPay;
|
||||
|
||||
case "FontAwesomeIcons.ccAmex":
|
||||
return FontAwesomeIcons.ccAmex;
|
||||
|
||||
case "FontAwesomeIcons.ccApplePay":
|
||||
return FontAwesomeIcons.ccApplePay;
|
||||
|
||||
case "FontAwesomeIcons.ccDinersClub":
|
||||
return FontAwesomeIcons.ccDinersClub;
|
||||
|
||||
case "FontAwesomeIcons.ccDiscover":
|
||||
return FontAwesomeIcons.ccDiscover;
|
||||
|
||||
case "FontAwesomeIcons.ccJcb":
|
||||
return FontAwesomeIcons.ccJcb;
|
||||
|
||||
case "FontAwesomeIcons.ccMastercard":
|
||||
return FontAwesomeIcons.ccMastercard;
|
||||
|
||||
case "FontAwesomeIcons.ccPaypal":
|
||||
return FontAwesomeIcons.ccPaypal;
|
||||
|
||||
case "FontAwesomeIcons.ccStripe":
|
||||
return FontAwesomeIcons.ccStripe;
|
||||
|
||||
case "FontAwesomeIcons.ccVisa":
|
||||
return FontAwesomeIcons.ccVisa;
|
||||
|
||||
case "FontAwesomeIcons.centercode":
|
||||
return FontAwesomeIcons.centercode;
|
||||
|
||||
case "FontAwesomeIcons.centos":
|
||||
return FontAwesomeIcons.centos;
|
||||
|
||||
case "FontAwesomeIcons.certificate":
|
||||
return FontAwesomeIcons.certificate;
|
||||
|
||||
case "FontAwesomeIcons.chair":
|
||||
return FontAwesomeIcons.chair;
|
||||
|
||||
case "FontAwesomeIcons.chalkboard":
|
||||
return FontAwesomeIcons.chalkboard;
|
||||
|
||||
case "FontAwesomeIcons.chalkboardTeacher":
|
||||
return FontAwesomeIcons.chalkboardTeacher;
|
||||
|
||||
case "FontAwesomeIcons.chargingStation":
|
||||
return FontAwesomeIcons.chargingStation;
|
||||
|
||||
case "FontAwesomeIcons.chartArea":
|
||||
return FontAwesomeIcons.chartArea;
|
||||
|
||||
case "FontAwesomeIcons.chartBar":
|
||||
return FontAwesomeIcons.chartBar;
|
||||
|
||||
case "FontAwesomeIcons.chartLine":
|
||||
return FontAwesomeIcons.chartLine;
|
||||
|
||||
case "FontAwesomeIcons.chartPie":
|
||||
return FontAwesomeIcons.chartPie;
|
||||
|
||||
case "FontAwesomeIcons.check":
|
||||
return FontAwesomeIcons.check;
|
||||
|
||||
case "FontAwesomeIcons.checkCircle":
|
||||
return FontAwesomeIcons.checkCircle;
|
||||
|
||||
case "FontAwesomeIcons.checkDouble":
|
||||
return FontAwesomeIcons.checkDouble;
|
||||
|
||||
case "FontAwesomeIcons.checkSquare":
|
||||
return FontAwesomeIcons.checkSquare;
|
||||
|
||||
case "FontAwesomeIcons.cheese":
|
||||
return FontAwesomeIcons.cheese;
|
||||
|
||||
case "FontAwesomeIcons.chessBishop":
|
||||
return FontAwesomeIcons.chessBishop;
|
||||
|
||||
case "FontAwesomeIcons.chessBoard":
|
||||
return FontAwesomeIcons.chessBoard;
|
||||
|
||||
case "FontAwesomeIcons.chessKing":
|
||||
return FontAwesomeIcons.chessKing;
|
||||
|
||||
case "FontAwesomeIcons.chessKnight":
|
||||
return FontAwesomeIcons.chessKnight;
|
||||
|
||||
case "FontAwesomeIcons.chessPawn":
|
||||
return FontAwesomeIcons.chessPawn;
|
||||
|
||||
case "FontAwesomeIcons.chessQueen":
|
||||
return FontAwesomeIcons.chessQueen;
|
||||
|
||||
case "FontAwesomeIcons.chessRook":
|
||||
return FontAwesomeIcons.chessRook;
|
||||
|
||||
case "FontAwesomeIcons.chevronCircleDown":
|
||||
return FontAwesomeIcons.chevronCircleDown;
|
||||
|
||||
case "FontAwesomeIcons.chevronCircleLeft":
|
||||
return FontAwesomeIcons.chevronCircleLeft;
|
||||
|
||||
case "FontAwesomeIcons.chevronCircleRight":
|
||||
return FontAwesomeIcons.chevronCircleRight;
|
||||
|
||||
case "FontAwesomeIcons.chevronCircleUp":
|
||||
return FontAwesomeIcons.chevronCircleUp;
|
||||
|
||||
case "FontAwesomeIcons.chevronDown":
|
||||
return FontAwesomeIcons.chevronDown;
|
||||
|
||||
case "FontAwesomeIcons.chevronLeft":
|
||||
return FontAwesomeIcons.chevronLeft;
|
||||
|
||||
case "FontAwesomeIcons.chevronRight":
|
||||
return FontAwesomeIcons.chevronRight;
|
||||
|
||||
case "FontAwesomeIcons.chevronUp":
|
||||
return FontAwesomeIcons.chevronUp;
|
||||
|
||||
case "FontAwesomeIcons.child":
|
||||
return FontAwesomeIcons.child;
|
||||
|
||||
case "FontAwesomeIcons.chrome":
|
||||
return FontAwesomeIcons.chrome;
|
||||
|
||||
case "FontAwesomeIcons.chromecast":
|
||||
return FontAwesomeIcons.chromecast;
|
||||
|
||||
case "FontAwesomeIcons.church":
|
||||
return FontAwesomeIcons.church;
|
||||
|
||||
case "FontAwesomeIcons.circle":
|
||||
return FontAwesomeIcons.circle;
|
||||
|
||||
case "FontAwesomeIcons.circleNotch":
|
||||
return FontAwesomeIcons.circleNotch;
|
||||
|
||||
case "FontAwesomeIcons.city":
|
||||
return FontAwesomeIcons.city;
|
||||
|
||||
case "FontAwesomeIcons.clinicMedical":
|
||||
return FontAwesomeIcons.clinicMedical;
|
||||
|
||||
case "FontAwesomeIcons.clipboard":
|
||||
return FontAwesomeIcons.clipboard;
|
||||
|
||||
case "FontAwesomeIcons.clipboardCheck":
|
||||
return FontAwesomeIcons.clipboardCheck;
|
||||
|
||||
case "FontAwesomeIcons.clipboardList":
|
||||
return FontAwesomeIcons.clipboardList;
|
||||
|
||||
case "FontAwesomeIcons.clock":
|
||||
return FontAwesomeIcons.clock;
|
||||
|
||||
case "FontAwesomeIcons.clone":
|
||||
return FontAwesomeIcons.clone;
|
||||
|
||||
case "FontAwesomeIcons.closedCaptioning":
|
||||
return FontAwesomeIcons.closedCaptioning;
|
||||
|
||||
case "FontAwesomeIcons.cloud":
|
||||
return FontAwesomeIcons.cloud;
|
||||
|
||||
case "FontAwesomeIcons.cloudDownloadAlt":
|
||||
return FontAwesomeIcons.cloudDownloadAlt;
|
||||
|
||||
case "FontAwesomeIcons.cloudMeatball":
|
||||
return FontAwesomeIcons.cloudMeatball;
|
||||
|
||||
case "FontAwesomeIcons.cloudMoon":
|
||||
return FontAwesomeIcons.cloudMoon;
|
||||
|
||||
case "FontAwesomeIcons.cloudMoonRain":
|
||||
return FontAwesomeIcons.cloudMoonRain;
|
||||
|
||||
case "FontAwesomeIcons.cloudRains":
|
||||
return FontAwesomeIcons.cloudRain;
|
||||
|
||||
case "FontAwesomeIcons.cloudShowersHeavy":
|
||||
return FontAwesomeIcons.cloudShowersHeavy;
|
||||
|
||||
case "FontAwesomeIcons.cloudSun":
|
||||
return FontAwesomeIcons.cloudSun;
|
||||
|
||||
case "FontAwesomeIcons.cloudSunRain":
|
||||
return FontAwesomeIcons.cloudSunRain;
|
||||
|
||||
case "FontAwesomeIcons.cloudUploadAlt":
|
||||
return FontAwesomeIcons.cloudUploadAlt;
|
||||
|
||||
case "FontAwesomeIcons.cloudscale":
|
||||
return FontAwesomeIcons.cloudscale;
|
||||
|
||||
case "FontAwesomeIcons.cloudsmith":
|
||||
return FontAwesomeIcons.cloudsmith;
|
||||
|
||||
case "FontAwesomeIcons.cloudversify":
|
||||
return FontAwesomeIcons.cloudversify;
|
||||
|
||||
case "FontAwesomeIcons.cocktail":
|
||||
return FontAwesomeIcons.cocktail;
|
||||
|
||||
case "FontAwesomeIcons.code":
|
||||
return FontAwesomeIcons.code;
|
||||
|
||||
case "FontAwesomeIcons.codeBranch":
|
||||
return FontAwesomeIcons.codeBranch;
|
||||
|
||||
case "FontAwesomeIcons.codepen":
|
||||
return FontAwesomeIcons.codepen;
|
||||
|
||||
case "FontAwesomeIcons.codiepie":
|
||||
return FontAwesomeIcons.codiepie;
|
||||
|
||||
case "FontAwesomeIcons.coffee":
|
||||
return FontAwesomeIcons.coffee;
|
||||
|
||||
case "FontAwesomeIcons.cog":
|
||||
return FontAwesomeIcons.cog;
|
||||
|
||||
case "FontAwesomeIcons.cogs":
|
||||
return FontAwesomeIcons.cogs;
|
||||
|
||||
case "FontAwesomeIcons.coins":
|
||||
return FontAwesomeIcons.coins;
|
||||
|
||||
case "FontAwesomeIcons.columns":
|
||||
return FontAwesomeIcons.columns;
|
||||
|
||||
case "FontAwesomeIcons.comment":
|
||||
return FontAwesomeIcons.comment;
|
||||
|
||||
case "FontAwesomeIcons.commentAlt":
|
||||
return FontAwesomeIcons.commentAlt;
|
||||
|
||||
case "FontAwesomeIcons.commentDollar":
|
||||
return FontAwesomeIcons.commentDollar;
|
||||
|
||||
case "FontAwesomeIcons.commentDots":
|
||||
return FontAwesomeIcons.commentDots;
|
||||
|
||||
case "FontAwesomeIcons.commentMedical":
|
||||
return FontAwesomeIcons.commentMedical;
|
||||
|
||||
case "FontAwesomeIcons.commentSlash":
|
||||
return FontAwesomeIcons.commentSlash;
|
||||
|
||||
case "FontAwesomeIcons.comments":
|
||||
return FontAwesomeIcons.comments;
|
||||
|
||||
case "FontAwesomeIcons.commentsDollar":
|
||||
return FontAwesomeIcons.commentsDollar;
|
||||
|
||||
case "FontAwesomeIcons.compactDisc":
|
||||
return FontAwesomeIcons.compactDisc;
|
||||
|
||||
case "FontAwesomeIcons.compass":
|
||||
return FontAwesomeIcons.compass;
|
||||
|
||||
case "FontAwesomeIcons.compress":
|
||||
return FontAwesomeIcons.compress;
|
||||
|
||||
case "FontAwesomeIcons.compressAlt":
|
||||
return FontAwesomeIcons.compressAlt;
|
||||
|
||||
case "FontAwesomeIcons.compressArrowsAlt":
|
||||
return FontAwesomeIcons.compressArrowsAlt;
|
||||
|
||||
case "FontAwesomeIcons.conciergeBell":
|
||||
return FontAwesomeIcons.conciergeBell;
|
||||
|
||||
case "FontAwesomeIcons.confluence":
|
||||
return FontAwesomeIcons.confluence;
|
||||
|
||||
case "FontAwesomeIcons.connectdevelop":
|
||||
return FontAwesomeIcons.connectdevelop;
|
||||
|
||||
case "FontAwesomeIcons.contao":
|
||||
return FontAwesomeIcons.contao;
|
||||
|
||||
case "FontAwesomeIcons.cookie":
|
||||
return FontAwesomeIcons.cookie;
|
||||
|
||||
case "FontAwesomeIcons.cookieBite":
|
||||
return FontAwesomeIcons.cookieBite;
|
||||
|
||||
case "FontAwesomeIcons.copy":
|
||||
return FontAwesomeIcons.copy;
|
||||
|
||||
case "FontAwesomeIcons.copyright":
|
||||
return FontAwesomeIcons.copyright;
|
||||
|
||||
case "FontAwesomeIcons.cottonBureau":
|
||||
return FontAwesomeIcons.cottonBureau;
|
||||
|
||||
case "FontAwesomeIcons.couch":
|
||||
return FontAwesomeIcons.couch;
|
||||
|
||||
case "FontAwesomeIcons.cpanel":
|
||||
return FontAwesomeIcons.cpanel;
|
||||
|
||||
case "FontAwesomeIcons.creativeCommons":
|
||||
return FontAwesomeIcons.creativeCommons;
|
||||
|
||||
case "FontAwesomeIcons.creativeCommonsBy":
|
||||
return FontAwesomeIcons.creativeCommonsBy;
|
||||
|
||||
case "FontAwesomeIcons.creativeCommonsNc":
|
||||
return FontAwesomeIcons.creativeCommonsNc;
|
||||
|
||||
case "FontAwesomeIcons.creativeCommonsNcEu":
|
||||
return FontAwesomeIcons.creativeCommonsNcEu;
|
||||
|
||||
case "FontAwesomeIcons.creativeCommonsNcJp":
|
||||
return FontAwesomeIcons.creativeCommonsNcJp;
|
||||
|
||||
case "FontAwesomeIcons.creativeCommonsNd":
|
||||
return FontAwesomeIcons.creativeCommonsNd;
|
||||
|
||||
case "FontAwesomeIcons.creativeCommonsPd":
|
||||
return FontAwesomeIcons.creativeCommonsPd;
|
||||
|
||||
case "":
|
||||
return FontAwesomeIcons.creativeCommonsPdAlt;
|
||||
|
||||
default:
|
||||
return FontAwesomeIcons.home;
|
||||
}
|
||||
}
|
175
lib/widgets/login_regist/custom_profile_text_field.dart
Normal file
175
lib/widgets/login_regist/custom_profile_text_field.dart
Normal file
@ -0,0 +1,175 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
|
||||
class CustomProfileTextField extends StatefulWidget {
|
||||
CustomProfileTextField({
|
||||
Key? key,
|
||||
this.length = 999,
|
||||
this.minLines = 1,
|
||||
this.maxLines = 1,
|
||||
this.height = 13,
|
||||
this.noTitle = false,
|
||||
this.prefix,
|
||||
this.suffix,
|
||||
this.color = secondaryColor,
|
||||
this.borderColor = Colors.white,
|
||||
this.keyboardType = TextInputType.text,
|
||||
this.title = '',
|
||||
this.obscuretext = false,
|
||||
this.auto = false,
|
||||
this.validate,
|
||||
this.enable = true,
|
||||
this.onChanged,
|
||||
required this.pad,
|
||||
required this.text,
|
||||
required this.hinttext,
|
||||
this.isErrorManual = false,
|
||||
this.textErrorManual = '',
|
||||
}) : super(key: key);
|
||||
final int length;
|
||||
final Color color;
|
||||
final int minLines;
|
||||
final int maxLines;
|
||||
final bool noTitle;
|
||||
final Color borderColor;
|
||||
final TextInputType keyboardType;
|
||||
final bool auto;
|
||||
final String title;
|
||||
final bool obscuretext;
|
||||
final String text;
|
||||
final String hinttext;
|
||||
final double pad;
|
||||
final double height;
|
||||
|
||||
// variabel untuk menangani error dari frontend
|
||||
final FormFieldValidator<String>? validate;
|
||||
|
||||
final Widget? prefix;
|
||||
final Widget? suffix;
|
||||
final bool enable;
|
||||
final Function(String)? onChanged;
|
||||
|
||||
// variabel untuk menangani error dari backend
|
||||
final bool isErrorManual;
|
||||
final String textErrorManual;
|
||||
|
||||
@override
|
||||
State<CustomProfileTextField> createState() => _CustomProfileTextFieldState();
|
||||
}
|
||||
|
||||
class _CustomProfileTextFieldState extends State<CustomProfileTextField> {
|
||||
late final TextEditingController controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
controller = TextEditingController(text: widget.text);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Brightness brightnessValue =
|
||||
MediaQuery.of(context).platformBrightness;
|
||||
bool isDarkMode = brightnessValue == Brightness.dark;
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: widget.pad),
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
widget.noTitle == false
|
||||
? Text(
|
||||
widget.title,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
)
|
||||
: SizedBox(height: 0),
|
||||
widget.noTitle == false
|
||||
? SizedBox(
|
||||
height: getProportionateScreenHeight(4),
|
||||
)
|
||||
: SizedBox(height: 0),
|
||||
Theme(
|
||||
data: ThemeData.dark().copyWith(errorColor: sevenColor),
|
||||
child: TextFormField(
|
||||
// initialValue: val,
|
||||
enabled: widget.enable,
|
||||
minLines: widget.minLines,
|
||||
maxLines: widget.maxLines,
|
||||
inputFormatters: [
|
||||
LengthLimitingTextInputFormatter(widget.length),
|
||||
],
|
||||
keyboardType: widget.keyboardType,
|
||||
autofocus: widget.auto,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: widget.validate,
|
||||
obscureText: widget.obscuretext,
|
||||
controller: controller,
|
||||
onChanged: widget.onChanged,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? secondaryColor
|
||||
: baruTexthitam,
|
||||
),
|
||||
cursorColor: secondaryColor,
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Theme.of(context).brightness == Brightness.dark
|
||||
? seventeenColor
|
||||
: secondaryColor.withOpacity(0.3),
|
||||
errorStyle: primaryTextStyle,
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: sevenColor),
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
suffixIcon: widget.suffix,
|
||||
prefixIcon: widget.prefix,
|
||||
contentPadding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(15),
|
||||
top: getProportionateScreenHeight(widget.height),
|
||||
bottom: getProportionateScreenHeight(widget.height)),
|
||||
hintText: widget.hinttext,
|
||||
hintStyle: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? widget.color
|
||||
: baruTexthitam,
|
||||
letterSpacing: 0.5),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
borderSide: BorderSide.none),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
// borderSide: BorderSide(
|
||||
// color: widget.borderColor,
|
||||
// ),
|
||||
),
|
||||
errorText: widget.isErrorManual ? widget.textErrorManual : null,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(16),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
149
lib/widgets/login_regist/custom_text_form_field.dart
Normal file
149
lib/widgets/login_regist/custom_text_form_field.dart
Normal file
@ -0,0 +1,149 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
|
||||
class CustomTextField extends StatelessWidget {
|
||||
CustomTextField({
|
||||
Key? key,
|
||||
this.length = 999,
|
||||
this.minLines = 1,
|
||||
this.maxLines = 1,
|
||||
this.height = 13,
|
||||
this.noTitle = false,
|
||||
this.prefix,
|
||||
this.suffix,
|
||||
this.color = secondaryColor,
|
||||
this.borderColor = Colors.white,
|
||||
this.keyboardType = TextInputType.text,
|
||||
this.title = '',
|
||||
this.obscuretext = false,
|
||||
this.auto = false,
|
||||
this.validate,
|
||||
this.enable = true,
|
||||
required this.pad,
|
||||
required this.controler,
|
||||
required this.hinttext,
|
||||
this.textInputAction,
|
||||
this.digitOnly,
|
||||
}) : super(key: key);
|
||||
final int length;
|
||||
final Color color;
|
||||
final bool? digitOnly;
|
||||
final int minLines;
|
||||
final int maxLines;
|
||||
final bool noTitle;
|
||||
final Color borderColor;
|
||||
final TextInputType keyboardType;
|
||||
final bool auto;
|
||||
final String title;
|
||||
final bool obscuretext;
|
||||
final TextEditingController controler;
|
||||
final String hinttext;
|
||||
final double pad;
|
||||
final double height;
|
||||
final FormFieldValidator<String>? validate;
|
||||
final Widget? prefix;
|
||||
final Widget? suffix;
|
||||
final TextInputAction? textInputAction;
|
||||
final bool enable;
|
||||
// final String val;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Brightness brightnessValue =
|
||||
MediaQuery.of(context).platformBrightness;
|
||||
bool isDarkMode = brightnessValue == Brightness.dark;
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: pad),
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
noTitle == false
|
||||
? Text(
|
||||
title,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
// color: baruTexthitam,
|
||||
letterSpacing: 0.5),
|
||||
)
|
||||
: SizedBox(height: 0),
|
||||
noTitle == false
|
||||
? SizedBox(
|
||||
height: getProportionateScreenHeight(4),
|
||||
)
|
||||
: SizedBox(height: 0),
|
||||
Theme(
|
||||
data: ThemeData.dark(),
|
||||
child: TextFormField(
|
||||
// initialValue: val,
|
||||
onChanged: (value) {},
|
||||
enabled: enable,
|
||||
minLines: minLines,
|
||||
maxLines: maxLines,
|
||||
inputFormatters: [
|
||||
(digitOnly != null)
|
||||
? (digitOnly!)
|
||||
? FilteringTextInputFormatter.digitsOnly
|
||||
: LengthLimitingTextInputFormatter(length)
|
||||
: LengthLimitingTextInputFormatter(length)
|
||||
],
|
||||
keyboardType: keyboardType,
|
||||
// autofocus: auto,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: validate,
|
||||
|
||||
obscureText: obscuretext,
|
||||
controller: controler,
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? baruTextutih
|
||||
: baruTexthitam,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
cursorColor: secondaryColor,
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Theme.of(context).brightness == Brightness.dark
|
||||
? seventeenColor
|
||||
: secondaryColor.withOpacity(0.3),
|
||||
// errorStyle: primaryTextStyle,
|
||||
// errorBorder: OutlineInputBorder(
|
||||
// borderSide: BorderSide(color: sevenColor),
|
||||
// borderRadius: BorderRadius.circular(10)),
|
||||
errorStyle: thirdTextStyle.copyWith(color: Colors.red),
|
||||
suffixIcon: suffix,
|
||||
prefixIcon: prefix,
|
||||
contentPadding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(15),
|
||||
top: getProportionateScreenHeight(height),
|
||||
bottom: getProportionateScreenHeight(height)),
|
||||
hintText: hinttext,
|
||||
hintStyle: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: color,
|
||||
letterSpacing: 0.5),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
borderSide: BorderSide.none),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
borderSide: BorderSide.none),
|
||||
),
|
||||
textInputAction: textInputAction,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(16),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
52
lib/widgets/login_regist/default_button.dart
Normal file
52
lib/widgets/login_regist/default_button.dart
Normal file
@ -0,0 +1,52 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/theme_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../theme.dart';
|
||||
import '../../size_config.dart';
|
||||
|
||||
class DefaultButton extends StatelessWidget {
|
||||
const DefaultButton({
|
||||
Key? key,
|
||||
this.text = '',
|
||||
this.weight = semiBold,
|
||||
this.press,
|
||||
this.isCart,
|
||||
}) : super(key: key);
|
||||
|
||||
final String text;
|
||||
final FontWeight weight;
|
||||
final VoidCallback? press;
|
||||
final bool? isCart;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
return SizedBox(
|
||||
width: isCart != null
|
||||
? getProportionateScreenWidth(120)
|
||||
: getProportionateScreenWidth(300),
|
||||
height: isCart != null
|
||||
? getProportionateScreenWidth(40)
|
||||
: getProportionateScreenWidth(44),
|
||||
child: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(getProportionateScreenWidth(10))),
|
||||
backgroundColor: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode),
|
||||
onPressed: press,
|
||||
child: Text(
|
||||
text,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: weight,
|
||||
color: baruTextutih,
|
||||
letterSpacing: 0.3),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
94
lib/widgets/login_regist/default_button_payment.dart
Normal file
94
lib/widgets/login_regist/default_button_payment.dart
Normal file
@ -0,0 +1,94 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/theme_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../theme.dart';
|
||||
import '../../size_config.dart';
|
||||
|
||||
class DefaultButtonPayment extends StatelessWidget {
|
||||
const DefaultButtonPayment({
|
||||
Key? key,
|
||||
this.text = '',
|
||||
this.weight = semiBold,
|
||||
this.press,
|
||||
this.isCart,
|
||||
this.width,
|
||||
this.height,
|
||||
this.isInvoice,
|
||||
}) : super(key: key);
|
||||
|
||||
final String text;
|
||||
final FontWeight weight;
|
||||
final VoidCallback? press;
|
||||
final bool? isCart;
|
||||
final bool? isInvoice;
|
||||
final double? width;
|
||||
final double? height;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
return isInvoice == null
|
||||
? SizedBox(
|
||||
width: getProportionateScreenWidth(width ?? 0),
|
||||
height: getProportionateScreenWidth(height ?? 0),
|
||||
child: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
getProportionateScreenWidth(5),
|
||||
),
|
||||
),
|
||||
backgroundColor: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
),
|
||||
onPressed: press,
|
||||
child: Text(
|
||||
text,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: weight,
|
||||
color: baruTextutih,
|
||||
letterSpacing: 0.3),
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox(
|
||||
width: getProportionateScreenWidth(width ?? 0),
|
||||
height: getProportionateScreenWidth(height ?? 0),
|
||||
child: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
getProportionateScreenWidth(5),
|
||||
),
|
||||
),
|
||||
backgroundColor: primaryColor,
|
||||
),
|
||||
onPressed: press,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.file_download_outlined,
|
||||
color: baruTextutih,
|
||||
size: getProportionateScreenWidth(24),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(3)),
|
||||
Text(
|
||||
text,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: weight,
|
||||
color: baruTextutih,
|
||||
letterSpacing: 0.3),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
64
lib/widgets/login_regist/default_icon_button.dart
Normal file
64
lib/widgets/login_regist/default_icon_button.dart
Normal file
@ -0,0 +1,64 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../theme.dart';
|
||||
import '../../size_config.dart';
|
||||
|
||||
class DefaultIconButton extends StatelessWidget {
|
||||
const DefaultIconButton(
|
||||
{Key? key,
|
||||
required this.icon,
|
||||
required this.iconWidth,
|
||||
required this.iconHeight,
|
||||
this.text = '',
|
||||
this.press,
|
||||
this.color})
|
||||
: super(key: key);
|
||||
final String icon;
|
||||
final String text;
|
||||
final VoidCallback? press;
|
||||
final double iconHeight;
|
||||
final double iconWidth;
|
||||
final Color? color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Brightness brightnessValue =
|
||||
MediaQuery.of(context).platformBrightness;
|
||||
bool isDarkMode = brightnessValue == Brightness.dark;
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenWidth(50),
|
||||
child: TextButton.icon(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: Colors.white,
|
||||
side: BorderSide(
|
||||
width: getProportionateScreenWidth(0.15),
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(getProportionateScreenWidth(10))),
|
||||
|
||||
// backgroundColor: tenthColor,
|
||||
),
|
||||
onPressed: press,
|
||||
icon: Padding(
|
||||
padding: EdgeInsets.only(right: getProportionateScreenWidth(1.0)),
|
||||
child: Image.asset(
|
||||
icon,
|
||||
height: getProportionateScreenWidth(iconHeight),
|
||||
width: getProportionateScreenWidth(iconWidth),
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
label: Text(
|
||||
text,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
fontWeight: reguler,
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
32
lib/widgets/login_regist/failed_login.dart
Normal file
32
lib/widgets/login_regist/failed_login.dart
Normal file
@ -0,0 +1,32 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
|
||||
class FailedLogin extends StatelessWidget {
|
||||
const FailedLogin(
|
||||
{Key? key, this.text = '', required this.style, this.jarak = 8})
|
||||
: super(key: key);
|
||||
final String text;
|
||||
final TextStyle style;
|
||||
final double jarak;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Image.asset(
|
||||
// 'assets/images/VOCASIA logo.png',
|
||||
// width: getProportionateScreenWidth(150),
|
||||
// height: getProportionateScreenHeight(50),
|
||||
// ),
|
||||
// SizedBox(height: getProportionateScreenHeight(jarak)),
|
||||
Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(16)),
|
||||
child: Text(text,
|
||||
maxLines: 2, textAlign: TextAlign.center, style: style),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
64
lib/widgets/login_regist/footer.dart
Normal file
64
lib/widgets/login_regist/footer.dart
Normal file
@ -0,0 +1,64 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/providers/theme_provider.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/terms_and_privacy.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class Footer extends StatelessWidget {
|
||||
const Footer(
|
||||
{Key? key,
|
||||
required this.textOne,
|
||||
required this.textTwo,
|
||||
required this.route,
|
||||
this.height = 48.0})
|
||||
: super(key: key);
|
||||
final String textOne;
|
||||
final String textTwo;
|
||||
final String route;
|
||||
final double height;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
// padding: EdgeInsets.only(
|
||||
// left: getProportionateScreenWidth(5),
|
||||
// top: getProportionateScreenWidth(5)),
|
||||
alignment: Alignment.center,
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
children: <TextSpan>[
|
||||
TextSpan(
|
||||
text: textOne,
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: fifteenColor,
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: textTwo,
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode, fontWeight: bold),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
route, (Route<dynamic> route) => false);
|
||||
//Navigator.pushNamed(context, route);
|
||||
}),
|
||||
],
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: tenthColor,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(35)),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
57
lib/widgets/login_regist/header.dart
Normal file
57
lib/widgets/login_regist/header.dart
Normal file
@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
|
||||
class Header extends StatelessWidget {
|
||||
const Header(
|
||||
{Key? key,
|
||||
this.text = '',
|
||||
this.text2 = '',
|
||||
required this.style,
|
||||
this.jarak = 20,
|
||||
this.title = true})
|
||||
: super(key: key);
|
||||
final String text;
|
||||
final String text2;
|
||||
final TextStyle style;
|
||||
final double jarak;
|
||||
final bool title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Brightness brightnessValue =
|
||||
MediaQuery.of(context).platformBrightness;
|
||||
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
title == true
|
||||
? Image.asset(
|
||||
isDarkMode
|
||||
? 'assets/images/VOCASIA logo.png'
|
||||
: 'assets/images/VOCASIA logo dark.png',
|
||||
width: getProportionateScreenWidth(150),
|
||||
height: getProportionateScreenHeight(50),
|
||||
)
|
||||
: Text(text2,
|
||||
textAlign: TextAlign.center,
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: isDarkMode ? baruTextutih : baruTexthitam,
|
||||
fontWeight: bold,
|
||||
fontSize: getProportionateScreenWidth(20),
|
||||
letterSpacing: 0.23)),
|
||||
SizedBox(height: getProportionateScreenHeight(jarak)),
|
||||
// Padding(
|
||||
// padding:
|
||||
// EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(16)),
|
||||
// child: Text(text,
|
||||
// maxLines: 2,
|
||||
// textAlign: TextAlign.justify,
|
||||
// style: thirdTextStyle.copyWith(
|
||||
// color: isDarkMode ? baruTexthitam : baruTextutih,
|
||||
// )),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
62
lib/widgets/login_regist/loading_button.dart
Normal file
62
lib/widgets/login_regist/loading_button.dart
Normal file
@ -0,0 +1,62 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../theme.dart';
|
||||
import '../../size_config.dart';
|
||||
|
||||
class LoadingButton extends StatelessWidget {
|
||||
const LoadingButton(
|
||||
{Key? key,
|
||||
required this.backgroundButtonColor,
|
||||
required this.textButtonColor})
|
||||
: super(key: key);
|
||||
|
||||
final Color backgroundButtonColor;
|
||||
final Color textButtonColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Brightness brightnessValue =
|
||||
MediaQuery.of(context).platformBrightness;
|
||||
bool isDarkMode = brightnessValue == Brightness.dark;
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenWidth(44),
|
||||
child: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: Colors.black,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(getProportionateScreenWidth(10))),
|
||||
backgroundColor: backgroundButtonColor,
|
||||
),
|
||||
onPressed: () {},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 17,
|
||||
height: 17,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation(
|
||||
Color(0xffFFFFFF),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(6),
|
||||
),
|
||||
Text(
|
||||
'Loading',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
fontWeight: semiBold,
|
||||
color: baruTextutih,
|
||||
letterSpacing: 0.3),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
686
lib/widgets/my_course_list.dart
Normal file
686
lib/widgets/my_course_list.dart
Normal file
@ -0,0 +1,686 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/models/my_course_model.dart';
|
||||
import 'package:initial_folder/providers/current_lesson_provider.dart';
|
||||
import 'package:initial_folder/providers/detail_course_provider.dart';
|
||||
import 'package:initial_folder/providers/instructor_provider.dart';
|
||||
import 'package:initial_folder/providers/lesson_course_provider.dart';
|
||||
import 'package:initial_folder/providers/my_course_provider.dart';
|
||||
import 'package:initial_folder/providers/theme_provider.dart';
|
||||
import 'package:initial_folder/screens/course/play_course_page.dart';
|
||||
import 'package:initial_folder/services/course_service.dart';
|
||||
import 'package:initial_folder/services/instructor_service.dart';
|
||||
import 'package:initial_folder/services/lesson_course_service.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
import 'package:initial_folder/screens/detail_course/detail_course_screen.dart';
|
||||
import 'package:initial_folder/providers/posting_review_provider.dart'
|
||||
as postReviewProvider;
|
||||
|
||||
class MyCourseList extends StatefulWidget {
|
||||
const MyCourseList({
|
||||
Key? key,
|
||||
required this.dataMyCourseModel,
|
||||
this.onDialogClose,
|
||||
}) : super(key: key);
|
||||
|
||||
final DataMyCourseModel dataMyCourseModel;
|
||||
final VoidCallback? onDialogClose;
|
||||
|
||||
@override
|
||||
State<MyCourseList> createState() => _MyCourseListState();
|
||||
}
|
||||
|
||||
class _MyCourseListState extends State<MyCourseList> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
]);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
final Brightness brightnessValue =
|
||||
MediaQuery.of(context).platformBrightness;
|
||||
bool isDarkMode = brightnessValue == Brightness.dark;
|
||||
double value = 0.0;
|
||||
if (widget.dataMyCourseModel.rating.length != 0) {
|
||||
value = double.parse(widget.dataMyCourseModel.rating[0].rating!);
|
||||
}
|
||||
TextEditingController _controller = TextEditingController(
|
||||
text: (widget.dataMyCourseModel.rating.length == 0)
|
||||
? ""
|
||||
: widget.dataMyCourseModel.rating[0].review);
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: isDarkMode ? Colors.black : Colors.grey,
|
||||
spreadRadius: 0.01,
|
||||
blurRadius: 2,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(20),
|
||||
right: getProportionateScreenWidth(20),
|
||||
top: getProportionateScreenWidth(10),
|
||||
bottom: 5),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DetailCourseScreen(
|
||||
resoaktifitas: 'gada',
|
||||
idcourse: widget.dataMyCourseModel.courseId ?? '1',
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: getProportionateScreenWidth(10),
|
||||
left: getProportionateScreenWidth(10),
|
||||
top: getProportionateScreenHeight(10),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.all(3),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 10,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
widget.dataMyCourseModel.title ?? ' ',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: SizeConfig.blockHorizontal! * 3.5,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
SizedBox(height: getProportionateScreenWidth(2)),
|
||||
Text(
|
||||
'${widget.dataMyCourseModel.instructor}',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: light,
|
||||
color: Colors.grey.shade600,
|
||||
fontSize: SizeConfig.blockHorizontal! * 3,
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenWidth(6)),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(9)),
|
||||
Flexible(
|
||||
flex: 11,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CachedNetworkImage(
|
||||
placeholder: (context, url) => Shimmer(
|
||||
child: Container(
|
||||
color: Colors.black,
|
||||
),
|
||||
gradient: LinearGradient(stops: [
|
||||
0.2,
|
||||
0.5,
|
||||
0.6
|
||||
], colors: [
|
||||
ninthColor,
|
||||
fourthColor,
|
||||
ninthColor
|
||||
])),
|
||||
errorWidget: (context, url, error) =>
|
||||
Icon(Icons.error),
|
||||
imageBuilder: (context, imageUrl) => Container(
|
||||
width: getProportionateScreenWidth(156),
|
||||
height: getProportionateScreenWidth(88),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.fill,
|
||||
image: imageUrl,
|
||||
),
|
||||
),
|
||||
),
|
||||
imageUrl: widget.dataMyCourseModel.thumbnail ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(8),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: Text(
|
||||
'Progres ${widget.dataMyCourseModel.totalProgress}%',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: SizeConfig.blockHorizontal! * 3.5,
|
||||
color: Colors.grey.shade600,
|
||||
letterSpacing: 0.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
Stack(
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: getProportionateScreenHeight(10),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: Colors.grey.shade300),
|
||||
),
|
||||
Container(
|
||||
width: (SizeConfig.screenWidth -
|
||||
getProportionateScreenWidth(32)) *
|
||||
int.parse(widget.dataMyCourseModel.totalProgress
|
||||
.toString()) /
|
||||
100,
|
||||
height: getProportionateScreenHeight(10),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenWidth(10)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
RatingBarIndicator(
|
||||
itemSize: SizeConfig.blockHorizontal! * 3.5,
|
||||
rating: double.parse(widget
|
||||
.dataMyCourseModel.rating.isEmpty
|
||||
? '0'
|
||||
: widget.dataMyCourseModel.rating[0].rating ??
|
||||
'5'),
|
||||
direction: Axis.horizontal,
|
||||
itemCount: 5,
|
||||
itemBuilder: (context, index) {
|
||||
if (index <
|
||||
double.parse(
|
||||
widget.dataMyCourseModel.rating.isEmpty
|
||||
? '0'
|
||||
: widget.dataMyCourseModel.rating[0]
|
||||
.rating ??
|
||||
'5')) {
|
||||
return FaIcon(
|
||||
FontAwesomeIcons.solidStar,
|
||||
color: primaryColor,
|
||||
);
|
||||
} else {
|
||||
return FaIcon(
|
||||
FontAwesomeIcons.star,
|
||||
color: primaryColor,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(5)),
|
||||
InkWell(
|
||||
onTap: () => showDialog(
|
||||
context: context,
|
||||
builder: (context) => MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => postReviewProvider
|
||||
.PostingReviewProvider(
|
||||
courseService: CourseService(),
|
||||
),
|
||||
)
|
||||
],
|
||||
child: Consumer<
|
||||
postReviewProvider.PostingReviewProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.state ==
|
||||
postReviewProvider
|
||||
.ResultState.uninitilized) {
|
||||
return AlertDialog(
|
||||
surfaceTintColor: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(5)),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 10, horizontal: 10),
|
||||
insetPadding: EdgeInsets.all(1),
|
||||
backgroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.background,
|
||||
title: Center(
|
||||
child: Text(
|
||||
'Berikan Penilaian',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: 15,
|
||||
fontWeight: reguler,
|
||||
letterSpacing: 0.2,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.background,
|
||||
),
|
||||
),
|
||||
),
|
||||
content: Container(
|
||||
width:
|
||||
getProportionateScreenWidth(300),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width:
|
||||
getProportionateScreenWidth(
|
||||
170),
|
||||
height:
|
||||
getProportionateScreenWidth(
|
||||
100),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
8),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.fill,
|
||||
image: NetworkImage(widget
|
||||
.dataMyCourseModel
|
||||
.thumbnail ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg'),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height:
|
||||
getProportionateScreenWidth(
|
||||
16)),
|
||||
Text(
|
||||
widget.dataMyCourseModel
|
||||
.title ??
|
||||
'',
|
||||
style: thirdTextStyle
|
||||
.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight:
|
||||
reguler),
|
||||
textAlign:
|
||||
TextAlign.center),
|
||||
SizedBox(
|
||||
height:
|
||||
getProportionateScreenWidth(
|
||||
23),
|
||||
),
|
||||
RatingBar.builder(
|
||||
minRating: 1,
|
||||
itemPadding:
|
||||
EdgeInsets.only(
|
||||
left: 9),
|
||||
initialRating: (widget
|
||||
.dataMyCourseModel
|
||||
.rating
|
||||
.length ==
|
||||
0)
|
||||
? double.parse("0")
|
||||
: double.parse(widget
|
||||
.dataMyCourseModel
|
||||
.rating[0]
|
||||
.rating!),
|
||||
itemSize: 25,
|
||||
maxRating: 5,
|
||||
itemBuilder:
|
||||
(context, _) {
|
||||
return FaIcon(
|
||||
FontAwesomeIcons
|
||||
.solidStar,
|
||||
color: Colors
|
||||
.orange[300]);
|
||||
},
|
||||
onRatingUpdate: (val) {
|
||||
value = val;
|
||||
}),
|
||||
SizedBox(
|
||||
height:
|
||||
getProportionateScreenWidth(
|
||||
16)),
|
||||
SizedBox(
|
||||
width:
|
||||
getProportionateScreenWidth(
|
||||
250),
|
||||
child: TextFormField(
|
||||
validator: (val) {
|
||||
print(value);
|
||||
if ((val == null ||
|
||||
val.isEmpty) ||
|
||||
value == 0.0) {
|
||||
return 'Ulasan dan Rating tidak boleh kosong';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
controller: _controller,
|
||||
textInputAction:
|
||||
TextInputAction.done,
|
||||
cursorColor:
|
||||
secondaryColor,
|
||||
scrollPadding:
|
||||
EdgeInsets.zero,
|
||||
minLines: 2,
|
||||
maxLines: null,
|
||||
decoration:
|
||||
InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Theme.of(
|
||||
context)
|
||||
.brightness ==
|
||||
Brightness.dark
|
||||
? seventeenColor
|
||||
: Colors.grey[200],
|
||||
border:
|
||||
OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(
|
||||
10,
|
||||
),
|
||||
borderSide:
|
||||
BorderSide
|
||||
.none),
|
||||
hintStyle:
|
||||
secondaryTextStyle
|
||||
.copyWith(
|
||||
color: secondaryColor,
|
||||
letterSpacing: 0.5,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
12),
|
||||
),
|
||||
hintText:
|
||||
"Tulis Ulasan",
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height:
|
||||
getProportionateScreenWidth(
|
||||
10)),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
if (_formKey.currentState!
|
||||
.validate()) {
|
||||
await state.postingReview(
|
||||
_controller.text,
|
||||
int.parse(widget
|
||||
.dataMyCourseModel
|
||||
.courseId
|
||||
.toString()),
|
||||
value.toInt());
|
||||
await Provider.of<
|
||||
MyCourseProvider>(
|
||||
context,
|
||||
listen: false)
|
||||
.getMyCourse();
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
'Kirim Penilaian',
|
||||
style: thirdTextStyle
|
||||
.copyWith(
|
||||
color:
|
||||
Colors.white),
|
||||
),
|
||||
style: ElevatedButton
|
||||
.styleFrom(
|
||||
minimumSize: Size(
|
||||
getProportionateScreenWidth(
|
||||
150),
|
||||
getProportionateScreenHeight(
|
||||
33)),
|
||||
backgroundColor:
|
||||
primaryColor,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state.state ==
|
||||
postReviewProvider
|
||||
.ResultState.loading) {
|
||||
return AlertDialog(
|
||||
content: Container(
|
||||
height:
|
||||
getProportionateScreenHeight(40),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state.state ==
|
||||
postReviewProvider
|
||||
.ResultState.successUpdate) {
|
||||
_controller.clear();
|
||||
// widget.onDialogClose!();
|
||||
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
),
|
||||
backgroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.background,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
contentPadding:
|
||||
EdgeInsets.fromLTRB(12, 26, 22, 15),
|
||||
content: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom:
|
||||
getProportionateScreenHeight(
|
||||
14)),
|
||||
child: Container(
|
||||
height:
|
||||
getProportionateScreenHeight(
|
||||
30),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Berhasil mengedit ulasan',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
12),
|
||||
letterSpacing: 0.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state.state ==
|
||||
postReviewProvider
|
||||
.ResultState.successAdd) {
|
||||
_controller.clear();
|
||||
// widget.onDialogClose!();
|
||||
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
),
|
||||
backgroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.background,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
contentPadding: EdgeInsets.fromLTRB(
|
||||
12, 26, 22, 15),
|
||||
content: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom:
|
||||
getProportionateScreenHeight(
|
||||
14)),
|
||||
child: Container(
|
||||
height:
|
||||
getProportionateScreenHeight(
|
||||
30),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Berhasil memberikan ulasan',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize:
|
||||
getProportionateScreenWidth(
|
||||
12),
|
||||
letterSpacing: 0.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
} else if (state.state ==
|
||||
postReviewProvider.ResultState.failed) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
'Terjadi Kesalahan',
|
||||
style: primaryTextStyle,
|
||||
),
|
||||
);
|
||||
}
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
'Terjadi Kesalahan',
|
||||
style: primaryTextStyle,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
child: widget.dataMyCourseModel.rating.isEmpty
|
||||
? Text(
|
||||
'Beri Penilaian',
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
fontSize:
|
||||
getProportionateScreenHeight(10),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'Edit Penilaian',
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
fontSize:
|
||||
getProportionateScreenHeight(10),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(
|
||||
create: (context) =>
|
||||
CurrentLessonProvider(),
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => LessonCourseProvider(
|
||||
lessonCourseService:
|
||||
LessonCourseService(),
|
||||
id: int.parse(
|
||||
widget.dataMyCourseModel.courseId ??
|
||||
'0'),
|
||||
),
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => DetailCourseProvider(
|
||||
courseService: CourseService(),
|
||||
id: widget.dataMyCourseModel.courseId ??
|
||||
'1'),
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => InstructorProvider(
|
||||
instructorService: InstructorService(),
|
||||
id: int.parse(widget
|
||||
.dataMyCourseModel.instructorId!),
|
||||
),
|
||||
),
|
||||
],
|
||||
child: PlayCourse(
|
||||
judul: widget.dataMyCourseModel.title ?? '',
|
||||
instruktur:
|
||||
widget.dataMyCourseModel.instructor ?? '',
|
||||
thumbnail: widget
|
||||
.dataMyCourseModel.thumbnail ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
|
||||
courseeid:
|
||||
widget.dataMyCourseModel.courseId ?? '',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
'Mulai',
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: baruTextutih,
|
||||
),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
minimumSize: Size(getProportionateScreenWidth(100),
|
||||
getProportionateScreenHeight(33)),
|
||||
backgroundColor: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10))),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
162
lib/widgets/notifikasi_list.dart
Normal file
162
lib/widgets/notifikasi_list.dart
Normal file
@ -0,0 +1,162 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/models/history_transaction_model.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class NotifikasiList extends StatelessWidget {
|
||||
const NotifikasiList(
|
||||
{Key? key, this.berhasil = true, this.baru = false, required this.data})
|
||||
: super(key: key);
|
||||
final bool berhasil;
|
||||
final bool baru;
|
||||
final HistoryTransactionModel data;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: (baru == false) ? Color(0xFF181818) : Color(0xFF212121),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(16),
|
||||
right: getProportionateScreenWidth(16),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 12),
|
||||
(data.statusPayment == 'Success')
|
||||
? Row(
|
||||
children: [
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
width: getProportionateScreenWidth(120),
|
||||
height: getProportionateScreenWidth(24),
|
||||
child: Text(
|
||||
'Berhasil Dibayar',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: Colors.green[900],
|
||||
fontSize: SizeConfig.blockHorizontal! * 2.6,
|
||||
fontWeight: semiBold),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.green[300],
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
//border: Border.all(color: kPrimaryColor),
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(8)),
|
||||
Icon(Icons.lens_rounded,
|
||||
color: Color(0xffc4c4c4),
|
||||
size: getProportionateScreenWidth(7)),
|
||||
SizedBox(width: getProportionateScreenWidth(8)),
|
||||
Text(
|
||||
DateFormat('Hm').format(data.date!),
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(8)),
|
||||
(baru == true)
|
||||
? Icon(Icons.lens_rounded,
|
||||
color: Color(0xffCD2228),
|
||||
size: getProportionateScreenWidth(12))
|
||||
: SizedBox(height: 0),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
children: [
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
width: getProportionateScreenWidth(165),
|
||||
height: getProportionateScreenWidth(24),
|
||||
child: Text(
|
||||
'Menunggu Pembayaran',
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: Colors.amber[900],
|
||||
fontSize: SizeConfig.blockHorizontal! * 2.6,
|
||||
fontWeight: semiBold),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.amber[200],
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
//border: Border.all(color: kPrimaryColor),
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(8)),
|
||||
Icon(Icons.lens_rounded,
|
||||
color: Color(0xffc4c4c4),
|
||||
size: getProportionateScreenWidth(7)),
|
||||
SizedBox(width: getProportionateScreenWidth(8)),
|
||||
Text(
|
||||
DateFormat('Hm').format(data.date!),
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(8)),
|
||||
(baru == true)
|
||||
? Icon(Icons.lens_rounded,
|
||||
color: Color(0xffCD2228),
|
||||
size: getProportionateScreenWidth(12))
|
||||
: SizedBox(height: 0),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 9),
|
||||
Text(
|
||||
data.courses![0].title!,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
SizedBox(height: 9),
|
||||
(data.statusPayment == 'Success')
|
||||
? Text(
|
||||
"Pembayaran berhasil dilakukan, kamu dapat mengikuti kursus sekarang!",
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)
|
||||
: Text(
|
||||
"Selesaikan pembayaran sebelum ${DateFormat('E, d MMMM y').format(data.date!)} untuk mulai kursus",
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
SizedBox(height: 13),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: fourthColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
30
lib/widgets/point_istruktur.dart
Normal file
30
lib/widgets/point_istruktur.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../size_config.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class PointInstruktur extends StatelessWidget {
|
||||
const PointInstruktur({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(11),
|
||||
),
|
||||
CircleAvatar(
|
||||
backgroundColor: primaryColor,
|
||||
maxRadius: 2,
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(10),
|
||||
),
|
||||
Text(
|
||||
'Instruktur',
|
||||
style: primaryTextStyle.copyWith(fontSize: 10, color: primaryColor),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
123
lib/widgets/q_and_a.dart
Normal file
123
lib/widgets/q_and_a.dart
Normal file
@ -0,0 +1,123 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:initial_folder/models/announcement_model.dart';
|
||||
// import 'package:initial_folder/screens/course/component/detail_quest_and_answer.dart';
|
||||
// import 'package:initial_folder/theme.dart';
|
||||
|
||||
// import '../size_config.dart';
|
||||
|
||||
// class QandA extends StatelessWidget {
|
||||
// const QandA(
|
||||
// {Key? key,
|
||||
// this.divider,
|
||||
// this.pointInstruktur = const SizedBox(),
|
||||
// required this.announcementDataModel})
|
||||
// : super(key: key);
|
||||
// final Widget? divider;
|
||||
// final Widget pointInstruktur;
|
||||
// final AnnouncementDataModel announcementDataModel;
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Container(
|
||||
// margin: EdgeInsets.symmetric(
|
||||
// horizontal: getProportionateScreenWidth(16),
|
||||
// ),
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// InkWell(
|
||||
// onTap: () {
|
||||
// print(announcementDataModel.idAnnouncement);
|
||||
// },
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Row(
|
||||
// children: [
|
||||
// CircleAvatar(
|
||||
// backgroundColor: primaryColor,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: getProportionateScreenWidth(8),
|
||||
// ),
|
||||
// Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// announcementDataModel.instructorName ?? ' ',
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// fontSize: getProportionateScreenWidth(12),
|
||||
// color: tenthColor),
|
||||
// ),
|
||||
// pointInstruktur,
|
||||
// ],
|
||||
// ),
|
||||
// Text(
|
||||
// announcementDataModel.date ?? '',
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// fontSize: getProportionateScreenWidth(12),
|
||||
// color: secondaryColor),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// SizedBox(height: getProportionateScreenHeight(3)),
|
||||
// Text(
|
||||
// announcementDataModel.bodyContent ?? '',
|
||||
// style: secondaryTextStyle.copyWith(
|
||||
// color: Color(0xffFFFFFF),
|
||||
// letterSpacing: 1,
|
||||
// fontSize: SizeConfig.blockHorizontal! * 3.4),
|
||||
// ),
|
||||
// SizedBox(height: getProportionateScreenHeight(16)),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// Row(
|
||||
// children: [
|
||||
// Icon(
|
||||
// Icons.favorite_border,
|
||||
// color: secondaryColor,
|
||||
// size: 12,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: getProportionateScreenWidth(3),
|
||||
// ),
|
||||
// Text(
|
||||
// announcementDataModel.likes ?? '',
|
||||
// style: secondaryTextStyle.copyWith(
|
||||
// fontSize: getProportionateScreenWidth(10),
|
||||
// letterSpacing: 0.3),
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: getProportionateScreenWidth(13),
|
||||
// ),
|
||||
// Icon(
|
||||
// Icons.question_answer_rounded,
|
||||
// color: secondaryColor,
|
||||
// size: 12,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: getProportionateScreenWidth(3),
|
||||
// ),
|
||||
// Text(
|
||||
// '50',
|
||||
// style: secondaryTextStyle.copyWith(
|
||||
// fontSize: getProportionateScreenWidth(10),
|
||||
// letterSpacing: 0.3),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// SizedBox(
|
||||
// height: getProportionateScreenWidth(13),
|
||||
// ),
|
||||
// SizedBox(
|
||||
// child: divider,
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
331
lib/widgets/qna_user.dart
Normal file
331
lib/widgets/qna_user.dart
Normal file
@ -0,0 +1,331 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:initial_folder/main.dart';
|
||||
import 'package:initial_folder/models/comment_qna_model.dart';
|
||||
import 'package:initial_folder/models/qna_model.dart';
|
||||
import 'package:initial_folder/providers/like_or_unlike_provider.dart';
|
||||
import 'package:initial_folder/providers/posting_qna_provider.dart';
|
||||
import 'package:initial_folder/providers/qna_provider.dart';
|
||||
import 'package:initial_folder/screens/course/component/detail_quest_and_answer.dart';
|
||||
import 'package:initial_folder/widgets/counter_qna_comment_page.dart';
|
||||
import 'package:initial_folder/widgets/counter_qna_like_page.dart';
|
||||
import 'package:initial_folder/widgets/edit_qna_user.dart';
|
||||
import 'package:initial_folder/widgets/qna_user_page.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../get_it.dart';
|
||||
import '../size_config.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class QnaUser extends StatefulWidget {
|
||||
const QnaUser({
|
||||
Key? key,
|
||||
required this.id,
|
||||
this.divider,
|
||||
required this.qnaDataModel,
|
||||
required this.index,
|
||||
required this.userId,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget? divider;
|
||||
final id;
|
||||
final QnaDataModel qnaDataModel;
|
||||
final int index;
|
||||
final int userId;
|
||||
|
||||
@override
|
||||
State<QnaUser> createState() => _QnaUserState();
|
||||
}
|
||||
|
||||
class _QnaUserState extends State<QnaUser> {
|
||||
double value = 0;
|
||||
final provider = qnaGetIt<QnaProvider>();
|
||||
// bool selfLike = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
PostingQnaProvider deleteQnaProvider =
|
||||
Provider.of<PostingQnaProvider>(context);
|
||||
|
||||
deleteQna() async {
|
||||
if (await deleteQnaProvider
|
||||
.deleteQna(int.parse(widget.qnaDataModel.idQna.toString()))) {
|
||||
ScaffoldMessenger.of(globalScaffoldKey.currentContext!).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: primaryColor,
|
||||
content: Text(
|
||||
'Pertanyaan berhasil dihapus',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: backgroundColor,
|
||||
),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
action: SnackBarAction(
|
||||
label: 'Lihat',
|
||||
onPressed: () {
|
||||
ScaffoldMessenger.of(globalScaffoldKey.currentContext!)
|
||||
.hideCurrentSnackBar();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
ScaffoldMessenger.of(globalScaffoldKey.currentContext!).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: primaryColor,
|
||||
content: Text(
|
||||
'Terjadi kesalahan',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: backgroundColor,
|
||||
),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
LikeOrUnlikeProvider _likeOrUnlikeProvider =
|
||||
Provider.of<LikeOrUnlikeProvider>(context);
|
||||
|
||||
likeOrUnlikes(int idQna) async {
|
||||
final provider = qnaGetIt<QnaProvider>();
|
||||
if (await _likeOrUnlikeProvider.likeOrUnlike(idQna)) {
|
||||
provider.getQna(widget.id);
|
||||
print("Respon Baik");
|
||||
}
|
||||
}
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DetailQuestAndAnswer(
|
||||
qnaDataModel: widget.qnaDataModel,
|
||||
id: widget.id,
|
||||
index: widget.index,
|
||||
userId: widget.userId,
|
||||
),
|
||||
),
|
||||
).then((value) => provider.getQna(widget.id));
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor: primaryColor,
|
||||
backgroundImage: widget.qnaDataModel.fotoProfile == null
|
||||
? AssetImage("assets/images/Profile Image.png")
|
||||
: NetworkImage(widget.qnaDataModel.fotoProfile ?? '')
|
||||
as ImageProvider,
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(8),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
widget.qnaDataModel.username ?? '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
widget.qnaDataModel.date ?? '',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color:
|
||||
Theme.of(context).colorScheme.onBackground),
|
||||
),
|
||||
],
|
||||
),
|
||||
int.parse(widget.qnaDataModel.sender.toString()) ==
|
||||
widget.userId
|
||||
? Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
PopupMenuButton(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 10),
|
||||
child: Icon(
|
||||
Icons.more_vert,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
),
|
||||
),
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
child: Container(
|
||||
child: Text('Edit'),
|
||||
),
|
||||
value: 'edit',
|
||||
),
|
||||
PopupMenuItem(
|
||||
child: Text('Hapus'),
|
||||
value: 'hapus',
|
||||
),
|
||||
],
|
||||
onSelected: (value) {
|
||||
switch (value) {
|
||||
case 'edit':
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => EditQna(
|
||||
quest: widget.qnaDataModel.quest,
|
||||
title: widget.qnaDataModel.title,
|
||||
id_qna: widget.qnaDataModel.idQna,
|
||||
id_course: widget.id,
|
||||
id_lesson:widget.qnaDataModel.idLesson,
|
||||
),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case 'hapus':
|
||||
deleteQna();
|
||||
break;
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(6)),
|
||||
widget.qnaDataModel.title != ''
|
||||
? Text(
|
||||
widget.qnaDataModel.title!,
|
||||
style: secondaryTextStyle.copyWith(
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
fontSize: SizeConfig.blockHorizontal! * 4.2,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
|
||||
Html(
|
||||
data: widget.qnaDataModel.quest ?? '',
|
||||
style: {
|
||||
"*": Style(margin: Margins.zero),
|
||||
},
|
||||
),
|
||||
|
||||
// Text(
|
||||
// widget.qnaDataModel.quest ?? '',
|
||||
// style: secondaryTextStyle.copyWith(
|
||||
// color: Theme.of(context).colorScheme.onBackground,
|
||||
// letterSpacing: 1,
|
||||
// fontSize: SizeConfig.blockHorizontal! * 3.4),
|
||||
// ),
|
||||
SizedBox(height: getProportionateScreenHeight(16)),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
kLike(
|
||||
widget.qnaDataModel.selfLiked == true
|
||||
? Icons.favorite
|
||||
: Icons.favorite_border_rounded,
|
||||
widget.qnaDataModel.selfLiked == true
|
||||
? Colors.red
|
||||
: secondaryColor, () {
|
||||
likeOrUnlikes(int.parse(widget.qnaDataModel.idQna.toString()));
|
||||
}),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(3),
|
||||
),
|
||||
Text(
|
||||
"${widget.qnaDataModel.countLike ?? 0}",
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10),
|
||||
letterSpacing: 0.3),
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(13),
|
||||
),
|
||||
kComment(
|
||||
widget.qnaDataModel.comment.length,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenWidth(5),
|
||||
),
|
||||
Divider(
|
||||
thickness: 0.3,
|
||||
)
|
||||
// SizedBox(
|
||||
// child: widget.divider,
|
||||
// )
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget kLike(IconData icon, Color color, Function onTap) {
|
||||
return GestureDetector(
|
||||
onTap: () => onTap(),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
icon,
|
||||
color: color,
|
||||
size: 12,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget kComment(int value) {
|
||||
return Row(
|
||||
children: [
|
||||
Icon(
|
||||
FontAwesomeIcons.comment,
|
||||
color: secondaryColor,
|
||||
size: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(3),
|
||||
),
|
||||
Text(
|
||||
"$value",
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(10), letterSpacing: 0.3),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
131
lib/widgets/qna_user_page.dart
Normal file
131
lib/widgets/qna_user_page.dart
Normal file
@ -0,0 +1,131 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
import 'package:initial_folder/models/qna_model.dart';
|
||||
import 'package:initial_folder/providers/qna_provider.dart';
|
||||
import 'package:initial_folder/widgets/qna_user.dart';
|
||||
import '../get_it.dart';
|
||||
|
||||
import '../theme.dart';
|
||||
|
||||
class QnaUserPage extends StatefulWidget {
|
||||
const QnaUserPage({Key? key, required this.idCourse}) : super(key: key);
|
||||
final idCourse;
|
||||
|
||||
@override
|
||||
State<QnaUserPage> createState() => _QnaUserPageState();
|
||||
}
|
||||
|
||||
class _QnaUserPageState extends State<QnaUserPage> {
|
||||
final provider = qnaGetIt<QnaProvider>();
|
||||
int? userId = 0;
|
||||
|
||||
void getUserId() async {
|
||||
userId = await UsersInfo().getIdUser();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
getUserId();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
provider.getQna(widget.idCourse);
|
||||
late Widget build;
|
||||
|
||||
return StreamBuilder<QnaModel>(
|
||||
stream: provider.qnaStream,
|
||||
builder: (context, AsyncSnapshot<QnaModel> snapshot) {
|
||||
if (snapshot.hasError) {
|
||||
return Center(
|
||||
child: Text(
|
||||
'Terjadi Kesalahan',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
switch (snapshot.connectionState) {
|
||||
case ConnectionState.waiting:
|
||||
build = Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: primaryColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ConnectionState.none:
|
||||
build = Center(
|
||||
child: Text(
|
||||
'Tidak ada koneksi',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ConnectionState.active:
|
||||
if (snapshot.data!.data[0].isEmpty) {
|
||||
build = Center(
|
||||
child: Text(
|
||||
'Tidak Ada Pertanyaan',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
print('masuk siniiiiiiiiiii active');
|
||||
// build = Text(snapshot.data!.status.toString());
|
||||
build = ListView.builder(
|
||||
itemCount: snapshot.data!.data[0].length,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.vertical,
|
||||
itemBuilder: (context, index) {
|
||||
return QnaUser(
|
||||
divider: Divider(),
|
||||
qnaDataModel: snapshot.data!.data[0][index],
|
||||
id: widget.idCourse,
|
||||
index: index,
|
||||
userId: userId!,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
break;
|
||||
case ConnectionState.done:
|
||||
if (snapshot.data!.data[0].isEmpty) {
|
||||
build = Center(
|
||||
child: Text(
|
||||
'Belum ada pertanyaan',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
print('masuk siniiiiiiiiiii done');
|
||||
|
||||
build = ListView.builder(
|
||||
itemCount: snapshot.data!.data[0].length,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.vertical,
|
||||
itemBuilder: (context, index) {
|
||||
return QnaUser(
|
||||
divider: Divider(
|
||||
thickness: 3.0,
|
||||
),
|
||||
qnaDataModel: snapshot.data!.data[0][index],
|
||||
id: widget.idCourse,
|
||||
index: index,
|
||||
userId: userId!,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return build;
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
100
lib/widgets/reply_announcement_user.dart
Normal file
100
lib/widgets/reply_announcement_user.dart
Normal file
@ -0,0 +1,100 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/models/announcement_model.dart';
|
||||
import 'package:initial_folder/models/reply_announcement_model.dart';
|
||||
import '../size_config.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class ReplyAnnouncementUser extends StatefulWidget {
|
||||
const ReplyAnnouncementUser(
|
||||
{Key? key,
|
||||
required this.announcementDataModel,
|
||||
required this.divider,
|
||||
required this.replyModel,
|
||||
required this.userId})
|
||||
: super(key: key);
|
||||
|
||||
final Widget? divider;
|
||||
final ReplyModel replyModel;
|
||||
final int userId;
|
||||
final AnnouncementDataModel announcementDataModel;
|
||||
@override
|
||||
State<ReplyAnnouncementUser> createState() => _ReplyAnnouncementUserState();
|
||||
}
|
||||
|
||||
class _ReplyAnnouncementUserState extends State<ReplyAnnouncementUser> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor: primaryColor,
|
||||
backgroundImage: widget.replyModel.fotoProfile == null
|
||||
? AssetImage("assets/images/Profile Image.png")
|
||||
: NetworkImage(widget.replyModel.fotoProfile ?? '')
|
||||
as ImageProvider,
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(8)),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
print(
|
||||
'Print ${widget.announcementDataModel.tokenAnnouncement}');
|
||||
},
|
||||
child: Text(
|
||||
widget.replyModel.name ?? '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
widget.replyModel.createAt ?? '',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: Theme.of(context).colorScheme.onBackground),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Text(
|
||||
widget.replyModel.body ?? '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
letterSpacing: 1,
|
||||
fontSize: SizeConfig.blockHorizontal! * 3.4),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(6)),
|
||||
// SizedBox(child: widget.divider)
|
||||
Divider(
|
||||
thickness: 0.3,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
119
lib/widgets/reply_announcement_user_page.dart
Normal file
119
lib/widgets/reply_announcement_user_page.dart
Normal file
@ -0,0 +1,119 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/models/announcement_model.dart';
|
||||
import 'package:initial_folder/providers/reply_announcement_provider.dart';
|
||||
import 'package:initial_folder/widgets/reply_announcement_user.dart';
|
||||
|
||||
import '../get_it.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class ReplyAnnouncementUserPage extends StatefulWidget {
|
||||
const ReplyAnnouncementUserPage({
|
||||
Key? key,
|
||||
required this.idCourse,
|
||||
required this.index,
|
||||
required this.userId,
|
||||
}) : super(key: key);
|
||||
final idCourse;
|
||||
final int index;
|
||||
final int userId;
|
||||
|
||||
@override
|
||||
State<ReplyAnnouncementUserPage> createState() =>
|
||||
_ReplyAnnouncementUserPageState();
|
||||
}
|
||||
|
||||
class _ReplyAnnouncementUserPageState extends State<ReplyAnnouncementUserPage> {
|
||||
final provider = replyAnnouncementGetIt<ReplyAnnouncementProvider>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
provider.getReplyAnnouncement(widget.idCourse, widget.index);
|
||||
late Widget build;
|
||||
|
||||
return StreamBuilder<AnnouncementModel>(
|
||||
stream: provider.replyAnnouncementStream,
|
||||
builder: (context, AsyncSnapshot<AnnouncementModel> snapshot) {
|
||||
if (snapshot.hasError) {
|
||||
return Center(
|
||||
child: Text(
|
||||
'Terjadi Kesalahan',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
switch (snapshot.connectionState) {
|
||||
case ConnectionState.waiting:
|
||||
build = Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: primaryColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ConnectionState.none:
|
||||
build = Center(
|
||||
child: Text(
|
||||
'Tidak ada koneksi',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ConnectionState.active:
|
||||
build = snapshot.data!.data[0][widget.index].replies.length > 0
|
||||
? ListView.builder(
|
||||
itemCount:
|
||||
snapshot.data!.data[0][widget.index].replies.length,
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
var replyModel =
|
||||
snapshot.data!.data[0][widget.index].replies[index];
|
||||
var announcementuser =
|
||||
snapshot.data!.data[0][widget.index];
|
||||
return ReplyAnnouncementUser(
|
||||
divider: Divider(),
|
||||
replyModel: replyModel,
|
||||
announcementDataModel: announcementuser,
|
||||
userId: widget.userId,
|
||||
);
|
||||
})
|
||||
: Center(
|
||||
child: Text(
|
||||
'Belum ada pengumuman',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ConnectionState.done:
|
||||
build = snapshot.data!.data[0][widget.index].replies.length > 0
|
||||
? ListView.builder(
|
||||
itemCount:
|
||||
snapshot.data!.data[0][widget.index].replies.length,
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
var replyModel =
|
||||
snapshot.data!.data[0][widget.index].replies[index];
|
||||
var announcementuser =
|
||||
snapshot.data!.data[0][widget.index];
|
||||
return ReplyAnnouncementUser(
|
||||
divider: Divider(),
|
||||
replyModel: replyModel,
|
||||
announcementDataModel: announcementuser,
|
||||
userId: widget.userId,
|
||||
);
|
||||
})
|
||||
: Center(
|
||||
child: Text(
|
||||
'Belum ada pertanyaan',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return build;
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
215
lib/widgets/reply_qna_user.dart
Normal file
215
lib/widgets/reply_qna_user.dart
Normal file
@ -0,0 +1,215 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:initial_folder/main.dart';
|
||||
import 'package:initial_folder/models/comment_qna_model.dart';
|
||||
import 'package:initial_folder/models/qna_model.dart';
|
||||
import 'package:initial_folder/providers/posting_qna_reply_provider.dart';
|
||||
import 'package:initial_folder/screens/course/component/detail_quest_and_answer.dart';
|
||||
import 'package:initial_folder/widgets/edit_reply_qna_user.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../size_config.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class ReplyQnaUser extends StatefulWidget {
|
||||
const ReplyQnaUser(
|
||||
{Key? key,
|
||||
required this.qnaDataModel,
|
||||
required this.divider,
|
||||
required this.comment,
|
||||
required this.userId,
|
||||
required this.onDeleteReply,})
|
||||
: super(key: key);
|
||||
|
||||
final Widget? divider;
|
||||
final Comment comment;
|
||||
final int userId;
|
||||
final QnaDataModel qnaDataModel;
|
||||
final Function(String idRep) onDeleteReply;
|
||||
@override
|
||||
State<ReplyQnaUser> createState() => _ReplyQnaUserState();
|
||||
}
|
||||
|
||||
class _ReplyQnaUserState extends State<ReplyQnaUser> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
PostingQnaReplyProvider deleteReplyQnaProvider =
|
||||
Provider.of<PostingQnaReplyProvider>(context);
|
||||
|
||||
deleteReplyQna() async {
|
||||
if (await deleteReplyQnaProvider.deleteReplyQna(int.parse(widget.comment.idRep!))) {
|
||||
// Notify the parent widget about the deletion
|
||||
widget.onDeleteReply(widget.comment.idRep!);
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: primaryColor,
|
||||
content: Text(
|
||||
'Balasan berhasil dihapus',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Handle the error case
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: primaryColor,
|
||||
content: Text(
|
||||
'Terjadi kesalahan',
|
||||
style: primaryTextStyle.copyWith(
|
||||
color: backgroundColor,
|
||||
),
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor: primaryColor,
|
||||
backgroundImage: widget.comment.fotoProfile == null
|
||||
? AssetImage("assets/images/Profile Image.png")
|
||||
: NetworkImage(widget.comment.fotoProfile ?? '')
|
||||
as ImageProvider,
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(8),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
print('Print ${widget.qnaDataModel.idQna}');
|
||||
},
|
||||
child: Text(
|
||||
widget.comment.username ?? '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
widget.comment.createAt ?? '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: Theme.of(context).colorScheme.onBackground),
|
||||
),
|
||||
],
|
||||
),
|
||||
int.parse(widget.comment.sender.toString()) == widget.userId
|
||||
? Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
PopupMenuButton(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 10),
|
||||
child: Icon(
|
||||
Icons.more_vert,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onBackground,
|
||||
),
|
||||
),
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
child: Container(
|
||||
child: Text('Edit'),
|
||||
),
|
||||
value: 'edit',
|
||||
),
|
||||
PopupMenuItem(
|
||||
child: Text('Hapus'),
|
||||
value: 'hapus',
|
||||
),
|
||||
],
|
||||
onSelected: (value) {
|
||||
switch (value) {
|
||||
case 'edit':
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => EditReplyQna(
|
||||
id_qna: widget.qnaDataModel.idQna,
|
||||
text_rep: widget.comment.textRep,
|
||||
id_rep: widget.comment.idRep,
|
||||
),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case 'hapus':
|
||||
print(widget.comment.idRep);
|
||||
deleteReplyQna();
|
||||
break;
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(8)),
|
||||
Html(
|
||||
data: widget.comment.textRep ?? '',
|
||||
style: {
|
||||
"*": Style(margin: Margins.zero),
|
||||
},
|
||||
),
|
||||
// Text(
|
||||
// widget.comment.textRep ?? '',
|
||||
// style: thirdTextStyle.copyWith(
|
||||
// color: Theme.of(context).colorScheme.onBackground,
|
||||
// letterSpacing: 1,
|
||||
// fontSize: SizeConfig.blockHorizontal! * 3.4),
|
||||
// ),
|
||||
SizedBox(height: getProportionateScreenHeight(6)),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
thickness: 0.3,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
123
lib/widgets/reply_qna_user_page.dart
Normal file
123
lib/widgets/reply_qna_user_page.dart
Normal file
@ -0,0 +1,123 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/models/qna_model.dart';
|
||||
import 'package:initial_folder/providers/reply_qna_provider.dart';
|
||||
import 'package:initial_folder/widgets/reply_qna_user.dart';
|
||||
|
||||
import '../get_it.dart';
|
||||
import '../theme.dart';
|
||||
|
||||
class ReplyQnaUserPage extends StatefulWidget {
|
||||
const ReplyQnaUserPage({
|
||||
Key? key,
|
||||
required this.idCourse,
|
||||
required this.idQna,
|
||||
required this.userId, required this.onReplyDeleted,
|
||||
}) : super(key: key);
|
||||
final idCourse;
|
||||
final String idQna;
|
||||
final int userId;
|
||||
final Function(String idRep) onReplyDeleted;
|
||||
|
||||
|
||||
@override
|
||||
State<ReplyQnaUserPage> createState() => _ReplyQnaUserPageState();
|
||||
}
|
||||
|
||||
class _ReplyQnaUserPageState extends State<ReplyQnaUserPage> {
|
||||
final provider = replyQnaGetIt<ReplyQnaProvider>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
provider.getReplyQnaById(widget.idCourse, widget.idQna);
|
||||
late Widget build;
|
||||
|
||||
return StreamBuilder<QnaModel>(
|
||||
stream: provider.replyQnaStream,
|
||||
builder: (context, AsyncSnapshot<QnaModel> snapshot) {
|
||||
if (snapshot.hasError) {
|
||||
return Center(
|
||||
child: Text(
|
||||
'Terjadi Kesalahan',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
switch (snapshot.connectionState) {
|
||||
case ConnectionState.waiting:
|
||||
build = Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: primaryColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ConnectionState.none:
|
||||
build = Center(
|
||||
child: Text(
|
||||
'Tidak ada koneksi',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ConnectionState.active:
|
||||
// build = snapshot.data!.data[0][widget.index].comment.length > 0
|
||||
// ? ListView.builder(
|
||||
// itemCount:
|
||||
// snapshot.data!.data[0][widget.index].comment.length,
|
||||
// shrinkWrap: true,
|
||||
// physics: NeverScrollableScrollPhysics(),
|
||||
// itemBuilder: (context, index) {
|
||||
// var comment = snapshot
|
||||
// .data!.data[0][widget.index].comment[index];
|
||||
// var qnauser = snapshot.data!.data[0][widget.index];
|
||||
// return ReplyQnaUser(
|
||||
// divider: Divider(),
|
||||
// comment: comment,
|
||||
// qnaDataModel: qnauser,
|
||||
// userId: widget.userId,
|
||||
// );
|
||||
// })
|
||||
// : Center(
|
||||
// child: Text(
|
||||
// 'Belum ada pertanyaan',
|
||||
// style: thirdTextStyle,
|
||||
// ),
|
||||
// );
|
||||
// break;
|
||||
case ConnectionState.done:
|
||||
if (snapshot.hasData && snapshot.data!.data.isNotEmpty) {
|
||||
final qnaData = snapshot.data!.data[0];
|
||||
return ListView.builder(
|
||||
itemCount: qnaData.length,
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
var comment = qnaData[index].comment;
|
||||
return Column(
|
||||
children: comment.map((commentItem) {
|
||||
return ReplyQnaUser(
|
||||
divider: Divider(),
|
||||
comment: commentItem,
|
||||
qnaDataModel: qnaData[index],
|
||||
userId: widget.userId,onDeleteReply: widget.onReplyDeleted,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return Center(
|
||||
child: Text(
|
||||
'Belum ada balasan',
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
);
|
||||
}
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
return build;
|
||||
});
|
||||
}
|
||||
}
|
425
lib/widgets/riwayat_list.dart
Normal file
425
lib/widgets/riwayat_list.dart
Normal file
@ -0,0 +1,425 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/models/history_transaction_model.dart';
|
||||
import 'package:initial_folder/providers/theme_provider.dart';
|
||||
import 'package:initial_folder/screens/checkout/snap_payment_page.dart';
|
||||
import 'package:initial_folder/services/history_transactions_service.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
class RiwayatList extends StatelessWidget {
|
||||
RiwayatList({Key? key, required this.dataHistoryTransactionModel})
|
||||
: super(key: key);
|
||||
final HistoryTransactionModel dataHistoryTransactionModel;
|
||||
|
||||
final Map<String, String> status = {
|
||||
'null': "Dibatalkan",
|
||||
'1': 'Berhasil',
|
||||
'0': 'Transaksi Kursus Gratis',
|
||||
'2': 'Menunggu Pembayaran',
|
||||
'-1': 'Pembayaran Ditolak',
|
||||
'-2': 'Melebihi Batas Waktu',
|
||||
'-3': 'Dibatalkan',
|
||||
'-5': 'Belum Pilih Metode Pembayaran',
|
||||
};
|
||||
|
||||
final Map<String, String> paymentType = {
|
||||
'null': "Dibatalkan",
|
||||
'bank transfer': 'Bank Transfer',
|
||||
'echannel': 'Bank Transfer',
|
||||
'credit card': 'Kartu Kredit',
|
||||
'permata': 'Bank Transfer',
|
||||
'gopay': 'GoPay',
|
||||
'cstore': 'Gerai',
|
||||
'free': 'Kursus Gratis',
|
||||
'Coupon Free Course': 'Kursus Gratis',
|
||||
'qris': 'QRIS'
|
||||
};
|
||||
|
||||
Widget _statusLabel(String text, Color color) {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: getProportionateScreenHeight(4),
|
||||
horizontal: getProportionateScreenWidth(5)),
|
||||
child: Text(
|
||||
text,
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: baruTextutih,
|
||||
fontSize: getProportionateScreenWidth(9),
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _customButton({VoidCallback? onTap, String? text}) {
|
||||
return InkWell(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Color.fromARGB(120, 18, 140, 126)),
|
||||
borderRadius: BorderRadius.circular(5)),
|
||||
padding: EdgeInsets.symmetric(vertical: 15),
|
||||
child: Center(
|
||||
child: Text(
|
||||
text!,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold, fontSize: 12, letterSpacing: 0.32),
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: onTap,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _listCourse(String? thumbnail, String? title) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 34,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CachedNetworkImage(
|
||||
imageUrl: thumbnail == null || thumbnail.isEmpty
|
||||
? '$baseUrl/images/default-thumbnail.png'
|
||||
: thumbnail.startsWith("http")
|
||||
? thumbnail
|
||||
: '$baseUrl/uploads/thumbnail/course_thumbnails/$thumbnail',
|
||||
imageBuilder: (context, imageProvider) => Container(
|
||||
width: getProportionateScreenWidth(100),
|
||||
height: getProportionateScreenWidth(43),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: imageProvider,
|
||||
),
|
||||
),
|
||||
),
|
||||
placeholder: (context, url) => Shimmer(
|
||||
child: Container(
|
||||
color: thirdColor,
|
||||
),
|
||||
gradient: LinearGradient(
|
||||
stops: [0.4, 0.5, 0.6],
|
||||
colors: [secondaryColor, thirdColor, secondaryColor],
|
||||
),
|
||||
),
|
||||
errorWidget: (context, url, error) => Container(
|
||||
width: getProportionateScreenWidth(108),
|
||||
height: getProportionateScreenWidth(50),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: NetworkImage(
|
||||
'https://api.vokasia.id/images/default-thumbnail.png'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(10)),
|
||||
Flexible(
|
||||
flex: 96,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
title ?? ' ',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: getProportionateScreenWidth(10),
|
||||
left: getProportionateScreenWidth(16),
|
||||
right: getProportionateScreenWidth(16)),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.transparent
|
||||
: secondaryColor.withOpacity(0.5),
|
||||
offset: Offset(0, 2),
|
||||
blurRadius: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
top: getProportionateScreenWidth(16),
|
||||
left: getProportionateScreenWidth(8),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
// Order ID
|
||||
dataHistoryTransactionModel.orderId ?? '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
dataHistoryTransactionModel.date != null
|
||||
? DateFormat.MMMMEEEEd()
|
||||
.format(dataHistoryTransactionModel.date!)
|
||||
: '',
|
||||
style: thirdTextStyle.copyWith(
|
||||
color: secondaryColor,
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(12)),
|
||||
if (dataHistoryTransactionModel.statusPayment != null &&
|
||||
(dataHistoryTransactionModel.statusPayment == '1' ||
|
||||
dataHistoryTransactionModel.statusPayment == '0'))
|
||||
_statusLabel(
|
||||
status[dataHistoryTransactionModel.statusPayment]! ??
|
||||
'',
|
||||
eightColor)
|
||||
else if (dataHistoryTransactionModel.statusPayment == '2' ||
|
||||
dataHistoryTransactionModel.statusPayment == '0')
|
||||
_statusLabel(
|
||||
status[dataHistoryTransactionModel.statusPayment]! ??
|
||||
'',
|
||||
fiveColor)
|
||||
else if (dataHistoryTransactionModel.statusPayment !=
|
||||
null &&
|
||||
status.containsKey(
|
||||
dataHistoryTransactionModel.statusPayment))
|
||||
_statusLabel(
|
||||
status[dataHistoryTransactionModel.statusPayment]!,
|
||||
sevenColor)
|
||||
else
|
||||
_statusLabel("${status['null']}", sevenColor)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(8)),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
top: getProportionateScreenWidth(12),
|
||||
left: getProportionateScreenWidth(8),
|
||||
right: getProportionateScreenWidth(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Kursus",
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Column(
|
||||
children: dataHistoryTransactionModel.courses != null
|
||||
? dataHistoryTransactionModel.courses!
|
||||
.map((course) =>
|
||||
_listCourse(course.thumbnail, course.title))
|
||||
.toList()
|
||||
: [],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
top: getProportionateScreenHeight(7),
|
||||
left: getProportionateScreenWidth(12),
|
||||
right: getProportionateScreenWidth(20),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
"Jenis Pembayaran",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
dataHistoryTransactionModel.paymentDetail != null &&
|
||||
dataHistoryTransactionModel
|
||||
.paymentDetail!.paymentType !=
|
||||
null &&
|
||||
paymentType.containsKey(dataHistoryTransactionModel
|
||||
.paymentDetail!.paymentType)
|
||||
? paymentType[dataHistoryTransactionModel
|
||||
.paymentDetail!.paymentType]!
|
||||
.toUpperCase()
|
||||
: 'Belum Memilih',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
"Total Pembelian",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
"Rp. ${dataHistoryTransactionModel.paymentDetail?.paymentType != "Coupon Free Course" ? dataHistoryTransactionModel.totalPrice?.toString() ?? '' : "0"}",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: bold,
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
dataHistoryTransactionModel.statusPayment == '1' &&
|
||||
dataHistoryTransactionModel
|
||||
.paymentDetail!.paymentType !=
|
||||
'free'
|
||||
? Column(
|
||||
children: [
|
||||
_customButton(text: 'Receipt'),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(10),
|
||||
),
|
||||
// _customButton(text: 'Invoice'),
|
||||
// SizedBox(
|
||||
// height: getProportionateScreenHeight(20),
|
||||
// ),
|
||||
],
|
||||
)
|
||||
: dataHistoryTransactionModel.statusPayment == '-5'
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 15),
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
|
||||
try {
|
||||
String orderId = dataHistoryTransactionModel.orderId ?? '';
|
||||
await HistoryTransactionService().checkTransactionExpiration(orderId);
|
||||
Navigator.of(context).pop();
|
||||
} catch (e) {
|
||||
Navigator.of(context).pop();
|
||||
print('Error saat memeriksa status transaksi: $e');
|
||||
}
|
||||
var redirectUrl = dataHistoryTransactionModel.token;
|
||||
if (redirectUrl != null && redirectUrl.isNotEmpty) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SnapPaymentPage(
|
||||
transactionToken: redirectUrl,
|
||||
orderId: dataHistoryTransactionModel.orderId ?? '',
|
||||
grossAmount: dataHistoryTransactionModel.totalPrice ?? 0,
|
||||
courseTitle: '',
|
||||
courseThumbnail: '',
|
||||
courseInstructor: '',
|
||||
courseId: '',
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
print("Pembayaran belum dimulai atau URL pembayaran tidak ada.");
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.symmetric(vertical: 15),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Lanjutkan Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: 12,
|
||||
fontWeight: semiBold,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
688
lib/widgets/riwayat_list_delete.dart
Normal file
688
lib/widgets/riwayat_list_delete.dart
Normal file
@ -0,0 +1,688 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/models/history_transaction_model.dart';
|
||||
import 'package:initial_folder/providers/detail_invoice_provider.dart';
|
||||
import 'package:initial_folder/providers/order_provider.dart';
|
||||
import 'package:initial_folder/providers/theme_provider.dart';
|
||||
import 'package:initial_folder/providers/total_price_provider.dart';
|
||||
import 'package:initial_folder/screens/checkout/batas_bayar.dart';
|
||||
import 'package:initial_folder/screens/checkout/gopay/batas_bayar_gopay.dart';
|
||||
import 'package:initial_folder/screens/profile/account_sign_in/detail_transaksi.dart';
|
||||
import 'package:initial_folder/services/cancel_payment_service.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/custom_navigator.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button_payment.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
import '../screens/checkout/snap_payment_page.dart';
|
||||
|
||||
class RiwayatListDelete extends StatefulWidget {
|
||||
RiwayatListDelete({
|
||||
Key? key,
|
||||
required this.dataHistoryTransactionModel,
|
||||
required this.onPaymentCancelled,
|
||||
}) : super(key: key);
|
||||
final HistoryTransactionModel dataHistoryTransactionModel;
|
||||
final Function(String) onPaymentCancelled;
|
||||
|
||||
@override
|
||||
State<RiwayatListDelete> createState() => _RiwayatListDeleteState();
|
||||
}
|
||||
|
||||
class _RiwayatListDeleteState extends State<RiwayatListDelete> {
|
||||
bool isLoading = false;
|
||||
|
||||
final Map<String, String> status = {
|
||||
'null': "Dibatalkan",
|
||||
'1': 'Berhasil',
|
||||
'0': 'Transaksi Kursus Gratis',
|
||||
'2': 'Menunggu Pembayaran',
|
||||
'-1': 'Pembayaran Ditolak',
|
||||
'-2': 'Melebihi Batas Waktu',
|
||||
};
|
||||
|
||||
final Map<String, String> paymentType = {
|
||||
'null': "Kartu Kredit",
|
||||
'credit card': 'Kartu Kredit',
|
||||
'qris': 'QRIS',
|
||||
'free': 'Kursus Gratis'
|
||||
};
|
||||
|
||||
final Map<String, String> bank = {
|
||||
'null': "Kartu Kredit",
|
||||
'bni': 'BNI Virtual Account',
|
||||
'bca': 'BCA Virtual Account',
|
||||
'Mandiri': 'Mandiri Virtual Account',
|
||||
'Permata': 'Permata Virtual Account',
|
||||
'qris': 'QR Code',
|
||||
'free': 'Kursus Gratis'
|
||||
};
|
||||
|
||||
final Map<String, String> store = {
|
||||
'null': "Kartu Kredit",
|
||||
'indomaret': 'Indomaret',
|
||||
'alfamart': 'Alfamart',
|
||||
'free': 'Kursus Gratis'
|
||||
};
|
||||
|
||||
Widget _statusLabel(String text, Color color) {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: getProportionateScreenHeight(5),
|
||||
horizontal: getProportionateScreenWidth(5)),
|
||||
child: Text(
|
||||
text,
|
||||
style: primaryTextStyle.copyWith(
|
||||
letterSpacing: 0.5,
|
||||
color: backgroundColor,
|
||||
fontSize: SizeConfig.blockHorizontal! * 2.5,
|
||||
fontWeight: semiBold),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _customButton({VoidCallback? onTap, String? text}) {
|
||||
return InkWell(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Color.fromARGB(120, 18, 140, 126)),
|
||||
borderRadius: BorderRadius.circular(5)),
|
||||
padding: EdgeInsets.symmetric(vertical: 15),
|
||||
child: Center(
|
||||
child: Text(
|
||||
text!,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold, fontSize: 12, letterSpacing: 0.32),
|
||||
)),
|
||||
),
|
||||
onTap: onTap,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _listCourse(String? thumbnail, String? title) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 34,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CachedNetworkImage(
|
||||
imageUrl: thumbnail != null && thumbnail.isNotEmpty
|
||||
? '$baseUrl/uploads/thumbnail/course_thumbnails/$thumbnail'
|
||||
: '$baseUrl/images/default-thumbnail.png',
|
||||
imageBuilder: (context, imageProvider) => Container(
|
||||
width: getProportionateScreenWidth(100),
|
||||
height: getProportionateScreenWidth(43),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: imageProvider,
|
||||
),
|
||||
),
|
||||
),
|
||||
placeholder: (context, url) => Shimmer(
|
||||
child: Container(
|
||||
color: thirdColor,
|
||||
),
|
||||
gradient: LinearGradient(stops: [
|
||||
0.4,
|
||||
0.5,
|
||||
0.6
|
||||
], colors: [
|
||||
secondaryColor,
|
||||
thirdColor,
|
||||
secondaryColor
|
||||
])),
|
||||
errorWidget: (context, url, error) => Container(
|
||||
width: getProportionateScreenWidth(108),
|
||||
height: getProportionateScreenWidth(50),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: NetworkImage(
|
||||
thumbnail == null || thumbnail.isEmpty
|
||||
? '$baseUrl/images/default-thumbnail.png'
|
||||
: thumbnail.startsWith("http")
|
||||
? thumbnail
|
||||
: '$baseUrl/uploads/thumbnail/course_thumbnails/$thumbnail',
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
SizedBox(width: getProportionateScreenWidth(10)),
|
||||
Flexible(
|
||||
flex: 96,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
title ?? ' ',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var selected = Provider.of<TotalPriceProvider>(context);
|
||||
var selectedInvoice = Provider.of<DetailInvoiceProvider>(context);
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: getProportionateScreenWidth(10),
|
||||
left: getProportionateScreenWidth(16),
|
||||
right: getProportionateScreenWidth(16)),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.transparent
|
||||
: secondaryColor.withOpacity(0.5),
|
||||
offset: Offset(0, 2),
|
||||
blurRadius: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
top: getProportionateScreenHeight(9),
|
||||
left: getProportionateScreenWidth(9),
|
||||
right: getProportionateScreenWidth(9),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"${widget.dataHistoryTransactionModel.orderId!}",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Bayar Sebelum",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
color: secondaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
DateFormat('dd MMMM yyyy')
|
||||
.format(widget.dataHistoryTransactionModel.date!),
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
fontFamily: "Poppins",
|
||||
),
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(8)),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: sevenColor,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(3),
|
||||
vertical: getProportionateScreenHeight(1),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.access_time,
|
||||
size: getProportionateScreenWidth(14),
|
||||
color: baruTextutih,
|
||||
),
|
||||
SizedBox(width: getProportionateScreenWidth(2)),
|
||||
Text(
|
||||
DateFormat('dd MMMM HH:mm').format(widget
|
||||
.dataHistoryTransactionModel.date!
|
||||
.add(Duration(days: 1))),
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
color: baruTextutih,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(8)),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
top: getProportionateScreenWidth(12),
|
||||
left: getProportionateScreenWidth(8),
|
||||
right: getProportionateScreenWidth(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Kursus",
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
children: widget.dataHistoryTransactionModel.courses!
|
||||
.map((course) =>
|
||||
_listCourse(course.thumbnail, course.title))
|
||||
.toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(10),
|
||||
vertical: getProportionateScreenHeight(10)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (widget.dataHistoryTransactionModel.paymentDetail?.paymentType != 'qris') ...[
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
"Metode Pembayaran",
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontFamily: "Poppins",
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
widget.dataHistoryTransactionModel.paymentDetail != null &&
|
||||
bank.containsKey(widget.dataHistoryTransactionModel.paymentDetail!.bank)
|
||||
? toBeginningOfSentenceCase(bank[widget.dataHistoryTransactionModel.paymentDetail!.bank] ?? '') ?? ''
|
||||
: (store.containsKey(widget.dataHistoryTransactionModel.paymentDetail!.store)
|
||||
? toBeginningOfSentenceCase(store[widget.dataHistoryTransactionModel.paymentDetail!.store] ?? '') ?? ''
|
||||
: toBeginningOfSentenceCase(paymentType[widget.dataHistoryTransactionModel.paymentDetail!.paymentType] ?? '') ?? ''),
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
widget.dataHistoryTransactionModel.paymentDetail != null &&
|
||||
bank.containsKey(widget.dataHistoryTransactionModel.paymentDetail!.bank)
|
||||
? "Nomor Virtual Account"
|
||||
: "Kode Pembayaran",
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontFamily: "Poppins",
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
if (widget.dataHistoryTransactionModel.paymentDetail?.paymentType != 'qris')
|
||||
Text(
|
||||
widget.dataHistoryTransactionModel.paymentDetail != null
|
||||
? widget.dataHistoryTransactionModel.paymentDetail!.vaNumber ?? 'QRIS'
|
||||
: 'QRIS',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
],
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"Total Pembayaran",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontFamily: "Poppins",
|
||||
fontSize: getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
"Rp. ${widget.dataHistoryTransactionModel.totalPrice! < 50000 ? (widget.dataHistoryTransactionModel.totalPrice! + 5000) : widget.dataHistoryTransactionModel.totalPrice}",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(13),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
DefaultButtonPayment(
|
||||
height: 35,
|
||||
width: 150,
|
||||
press: () {
|
||||
// Cek payment type, jika qris langsung arahkan ke SnapPaymentPage
|
||||
if (widget.dataHistoryTransactionModel.paymentDetail?.paymentType == 'qris') {
|
||||
var redirectUrl = widget.dataHistoryTransactionModel.token;
|
||||
if (redirectUrl != null && redirectUrl.isNotEmpty) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SnapPaymentPage(
|
||||
transactionToken: redirectUrl,
|
||||
orderId: widget.dataHistoryTransactionModel.orderId ?? '',
|
||||
grossAmount: widget.dataHistoryTransactionModel.totalPrice ?? 0,
|
||||
courseTitle: '',
|
||||
courseThumbnail: '',
|
||||
courseInstructor: '',
|
||||
courseId: '',
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
print("Pembayaran belum dimulai atau URL pembayaran tidak ada.");
|
||||
}
|
||||
} else {
|
||||
selected.selectedTotalPrices = widget.dataHistoryTransactionModel.totalPrice ?? 0;
|
||||
selectedInvoice.selectedThumbnail = widget.dataHistoryTransactionModel.courses![0].thumbnail;
|
||||
|
||||
Navigator.of(context).push(
|
||||
CustomNavigator(
|
||||
child: DetailInvoice(
|
||||
orderId: widget.dataHistoryTransactionModel.orderId!,
|
||||
dataHistoryTransactionModel: widget.dataHistoryTransactionModel,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
text: "Bayar Sekarang",
|
||||
weight: semiBold,
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(150),
|
||||
height: getProportionateScreenHeight(32),
|
||||
child: TextButton(
|
||||
onPressed: () async {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
elevation: 0.0,
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.background,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: getProportionateScreenHeight(20),
|
||||
horizontal: getProportionateScreenWidth(10),
|
||||
),
|
||||
actionsPadding: EdgeInsets.only(
|
||||
right: getProportionateScreenWidth(10),
|
||||
bottom: getProportionateScreenHeight(12),
|
||||
),
|
||||
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
getProportionateScreenWidth(4)),
|
||||
),
|
||||
content: Text(
|
||||
'Apakah Anda yakin ingin membatalkan transaksi?'),
|
||||
actions: [
|
||||
GestureDetector(
|
||||
child: Text(
|
||||
'Ya',
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
Navigator.of(context).pop();
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
CancelPaymentService
|
||||
cancelPaymentService =
|
||||
CancelPaymentService();
|
||||
String message =
|
||||
await cancelPaymentService
|
||||
.cancelPayment(widget
|
||||
.dataHistoryTransactionModel
|
||||
.orderId!);
|
||||
widget.onPaymentCancelled(message);
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
width: getProportionateScreenWidth(5)),
|
||||
GestureDetector(
|
||||
child: Text(
|
||||
'Tidak',
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(11),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: isLoading
|
||||
? Container(
|
||||
width: getProportionateScreenWidth(12),
|
||||
height: getProportionateScreenHeight(10),
|
||||
child: CircularProgressIndicator(
|
||||
color: primaryColor,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
"Batalkan Transaksi",
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
fontWeight: semiBold,
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor:
|
||||
Theme.of(context).colorScheme.background,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode),
|
||||
borderRadius: BorderRadius.circular(
|
||||
getProportionateScreenWidth(5),
|
||||
),
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
widget.dataHistoryTransactionModel.statusPayment == 'Success' &&
|
||||
widget.dataHistoryTransactionModel.paymentDetail!
|
||||
.paymentType !=
|
||||
'free'
|
||||
? Column(
|
||||
children: [
|
||||
_customButton(text: 'Receipt'),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(10),
|
||||
),
|
||||
_customButton(text: 'Invoice'),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(20),
|
||||
),
|
||||
],
|
||||
)
|
||||
: widget.dataHistoryTransactionModel.statusPayment ==
|
||||
'Pending'
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 15),
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => widget
|
||||
.dataHistoryTransactionModel
|
||||
.paymentDetail!
|
||||
.paymentType ==
|
||||
'gopay'
|
||||
? BatasBayarGopay()
|
||||
: BatasBayar(
|
||||
historyTransactionModel: widget
|
||||
.dataHistoryTransactionModel,
|
||||
)));
|
||||
},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.symmetric(vertical: 15),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Detail Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: 12, fontWeight: semiBold),
|
||||
)),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: primaryColor),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Provider.of<OrderProvider>(context,
|
||||
listen: false)
|
||||
.getTotalPrice(widget
|
||||
.dataHistoryTransactionModel
|
||||
.totalPrice
|
||||
.toString());
|
||||
|
||||
Future.wait(widget
|
||||
.dataHistoryTransactionModel.courses!
|
||||
.map((course) async {
|
||||
Provider.of<OrderProvider>(context,
|
||||
listen: false)
|
||||
.addOrder(
|
||||
id: course.courseId,
|
||||
discountPrice: course.price,
|
||||
instructor: course.instructor,
|
||||
price: course.price,
|
||||
title: course.title,
|
||||
imageUrl: '');
|
||||
})).whenComplete(
|
||||
() => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SnapPaymentPage(
|
||||
orderId: widget
|
||||
.dataHistoryTransactionModel
|
||||
.orderId!,
|
||||
grossAmount: widget
|
||||
.dataHistoryTransactionModel
|
||||
.totalPrice!, transactionToken: '', courseTitle: '', courseInstructor: '', courseThumbnail: '', courseId: '',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.symmetric(vertical: 15),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Ubah Metode Pembayaran',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontSize: 12,
|
||||
fontWeight: semiBold,
|
||||
color: primaryColor),
|
||||
)),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: Colors.transparent,
|
||||
border:
|
||||
Border.all(color: primaryColor)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
436
lib/widgets/search_and_filter_course.dart
Normal file
436
lib/widgets/search_and_filter_course.dart
Normal file
@ -0,0 +1,436 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/helper/validator.dart';
|
||||
import 'package:initial_folder/providers/search_provider.dart';
|
||||
import 'package:initial_folder/screens/detail_course/detail_course_screen.dart';
|
||||
import 'package:initial_folder/screens/home/components/body_comp/product_card/product_card.dart';
|
||||
import 'package:initial_folder/screens/search_course/component/filter.dart';
|
||||
import 'package:initial_folder/widgets/custom_navigator.dart';
|
||||
import 'package:initial_folder/widgets/search_not_found.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../providers/theme_provider.dart';
|
||||
import '../size_config.dart';
|
||||
import '../theme.dart';
|
||||
import 'package:initial_folder/providers/filters_course_provider.dart'
|
||||
as filterCourseProvider;
|
||||
|
||||
class SearchAndFilterCourse extends StatefulWidget {
|
||||
const SearchAndFilterCourse({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
static const routeName = '/search-and-filter';
|
||||
|
||||
@override
|
||||
State<SearchAndFilterCourse> createState() => _SearchAndFilterCourseState();
|
||||
}
|
||||
|
||||
class _SearchAndFilterCourseState extends State<SearchAndFilterCourse> {
|
||||
final TextEditingController _controller = TextEditingController();
|
||||
|
||||
void clearTextField() {
|
||||
_controller.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
Provider.of<SearchProvider>(context, listen: false).resetState();
|
||||
Provider.of<filterCourseProvider.FilterCourseProvider>(context,
|
||||
listen: false)
|
||||
.resetState();
|
||||
Provider.of<filterCourseProvider.FilterCourseProvider>(context,
|
||||
listen: false)
|
||||
.resetFilter();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeProvider = Provider.of<ThemeProvider>(context);
|
||||
return Scaffold(
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
appBar: PreferredSize(
|
||||
preferredSize: Size.fromHeight(getProportionateScreenWidth(57)),
|
||||
child: AppBar(
|
||||
scrolledUnderElevation: 0,
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
leadingWidth: 30,
|
||||
actions: [
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: () => Navigator.of(context, rootNavigator: true).push(
|
||||
CustomNavigator(
|
||||
child: Filter(
|
||||
onApplyFilter: clearTextField,
|
||||
),
|
||||
),
|
||||
),
|
||||
icon: Icon(
|
||||
Icons.tune_rounded,
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
),
|
||||
),
|
||||
],
|
||||
title: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? seventeenColor
|
||||
: secondaryColor.withOpacity(0.3),
|
||||
),
|
||||
height: 40,
|
||||
child: Consumer<SearchProvider>(
|
||||
builder: (context, state, _) => TextField(
|
||||
controller: _controller,
|
||||
autofocus: false,
|
||||
onSubmitted: (value) async {
|
||||
Provider.of<filterCourseProvider.FilterCourseProvider>(
|
||||
context,
|
||||
listen: false)
|
||||
.isSearchsFalse();
|
||||
filterCourseProvider.FilterCourseProvider filterCourseProv =
|
||||
Provider.of<filterCourseProvider.FilterCourseProvider>(
|
||||
context,
|
||||
listen: false);
|
||||
|
||||
state.searchTextFilter = "";
|
||||
state.searchText = validatorSearch(value);
|
||||
await state.initSearchCourse(
|
||||
price: filterCourseProv.currentIndexPrice,
|
||||
level: filterCourseProv.levels.join(','),
|
||||
rating: filterCourseProv.currentIndexRating,
|
||||
);
|
||||
},
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
onChanged: (value) {
|
||||
state.searchTextFilter = "";
|
||||
state.searchText = validatorSearch(value);
|
||||
},
|
||||
cursorColor: secondaryColor,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: sevenColor),
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
contentPadding:
|
||||
EdgeInsets.only(top: getProportionateScreenHeight(4)),
|
||||
prefixIcon: Icon(
|
||||
FeatherIcons.search,
|
||||
size: 20,
|
||||
color: themeProvider.themeData == ThemeClass.darkmode
|
||||
?primaryColor : primaryColorligtmode,
|
||||
),
|
||||
hintText: 'Cari Kursus',
|
||||
hintStyle: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: secondaryColor,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: Provider.of<filterCourseProvider.FilterCourseProvider>(context)
|
||||
.isSearch
|
||||
? Consumer<filterCourseProvider.FilterCourseProvider>(
|
||||
builder: (context, state, _) {
|
||||
SearchProvider searchProvider =
|
||||
Provider.of<SearchProvider>(context, listen: false);
|
||||
print("Ini searchan ${searchProvider.search}");
|
||||
if (state.state == filterCourseProvider.ResultState.loading) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: Colors.green,
|
||||
),
|
||||
);
|
||||
} else if (state.state ==
|
||||
filterCourseProvider.ResultState.hasData) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.only(left: getProportionateScreenWidth(2)),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(14),
|
||||
top: getProportionateScreenHeight(5),
|
||||
),
|
||||
child: Text(
|
||||
"Kursus ${searchProvider.searchTextFilter.replaceAll('%', ' ')}",
|
||||
textAlign: TextAlign.left,
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontSize: getProportionateScreenWidth(15),
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
),
|
||||
),
|
||||
GridView.builder(
|
||||
padding: EdgeInsets.only(
|
||||
right: getProportionateScreenWidth(20),
|
||||
top: getProportionateScreenHeight(20),
|
||||
bottom: getProportionateScreenHeight(20),
|
||||
),
|
||||
physics: ScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
gridDelegate:
|
||||
SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: 2.8 / 4,
|
||||
crossAxisSpacing: 10,
|
||||
mainAxisSpacing: 13,
|
||||
),
|
||||
itemCount: state.filterResult.length,
|
||||
itemBuilder: (context, index) {
|
||||
var course = state.filterResult[index];
|
||||
int price = int.tryParse(
|
||||
course.price.replaceAll('.', '')) ??
|
||||
0;
|
||||
int discountPrice = int.tryParse(course
|
||||
.discountPrice
|
||||
.replaceAll('.', '')) ??
|
||||
0;
|
||||
|
||||
int calculatedPrice =
|
||||
(course.discountPrice != '0')
|
||||
? price - discountPrice
|
||||
: price;
|
||||
|
||||
String displayedPrice = (calculatedPrice == 0)
|
||||
? course.price
|
||||
: calculatedPrice.toString();
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: getProportionateScreenHeight(11)),
|
||||
child: ProductCard(
|
||||
totalDiscount: course.totalDiscount ?? 0,
|
||||
students: course.students ?? '0',
|
||||
id: course.idCourse,
|
||||
thumbnail: course.thumbnail ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
|
||||
title: course.title,
|
||||
instructorName: course.instructorName,
|
||||
specificRating: double.parse(
|
||||
course.rating[0]!.avgRating != null
|
||||
? '${course.rating[0]!.avgRating}'
|
||||
: '5.0')
|
||||
.toString(),
|
||||
rating: course.rating[0]!.avgRating != null
|
||||
? '${course.rating[0]!.avgRating}'
|
||||
: '5.0',
|
||||
numberOfRatings:
|
||||
course.rating[0]!.totalReview ?? '0',
|
||||
isTopCourse: course.topCourse ?? '0',
|
||||
price: (course.price == '0')
|
||||
? 'Gratis'
|
||||
: (course.promoPrice != '0')
|
||||
? numberFormat(course.promoPrice)
|
||||
: numberFormat(displayedPrice),
|
||||
realPrice: (course.price == '0')
|
||||
? ''
|
||||
: numberFormat(course.price),
|
||||
press: () {
|
||||
Navigator.of(context, rootNavigator: true)
|
||||
.push(
|
||||
CustomNavigator(
|
||||
child: DetailCourseScreen(
|
||||
idcourse: course.idCourse,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state.state ==
|
||||
filterCourseProvider.ResultState.error ||
|
||||
state.state == filterCourseProvider.ResultState.noData) {
|
||||
return SearchNotFound();
|
||||
} else {
|
||||
return Center(child: Text(''));
|
||||
}
|
||||
},
|
||||
)
|
||||
: Consumer<SearchProvider>(
|
||||
builder: (context, state, _) {
|
||||
SearchProvider searchProvider =
|
||||
Provider.of<SearchProvider>(context, listen: false);
|
||||
|
||||
if (state.state == ResultState.loading) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: primaryColor,
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultState.hasData) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.only(left: getProportionateScreenWidth(2)),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(14),
|
||||
top: getProportionateScreenHeight(5),
|
||||
),
|
||||
child: searchProvider.searchText.isNotEmpty
|
||||
? Text(
|
||||
"Kursus ${searchProvider.searchText.replaceAll('%', ' ')}",
|
||||
textAlign: TextAlign.left,
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontSize: getProportionateScreenWidth(15),
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
"Kursus ${searchProvider.searchTextFilter.replaceAll('%', ' ')}",
|
||||
textAlign: TextAlign.left,
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontSize: getProportionateScreenWidth(15),
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
),
|
||||
),
|
||||
GridView.builder(
|
||||
padding: EdgeInsets.only(
|
||||
right: getProportionateScreenWidth(20),
|
||||
top: getProportionateScreenHeight(20),
|
||||
bottom: getProportionateScreenHeight(20),
|
||||
),
|
||||
physics: ScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
gridDelegate:
|
||||
SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: 2.8 / 4,
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisSpacing: 18,
|
||||
),
|
||||
itemCount: state.result.length,
|
||||
itemBuilder: (context, index) {
|
||||
var othersCourse = state.result[index];
|
||||
|
||||
int price = int.tryParse(
|
||||
othersCourse.price.replaceAll('.', '')) ??
|
||||
0;
|
||||
int discountPrice = int.tryParse(othersCourse
|
||||
.discountPrice
|
||||
.replaceAll('.', '')) ??
|
||||
0;
|
||||
|
||||
int calculatedPrice =
|
||||
(othersCourse.discountPrice != '0')
|
||||
? price - discountPrice
|
||||
: price;
|
||||
|
||||
String displayedPrice = (calculatedPrice == 0)
|
||||
? othersCourse.price.toString()
|
||||
: calculatedPrice.toString();
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: getProportionateScreenHeight(11)),
|
||||
child: ProductCard(
|
||||
totalDiscount:
|
||||
othersCourse.totalDiscount ?? 0,
|
||||
students: othersCourse.students ?? '0',
|
||||
id: othersCourse.idCourse,
|
||||
thumbnail: othersCourse.thumbnail ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
|
||||
title: othersCourse.title,
|
||||
instructorName: othersCourse.instructorName,
|
||||
specificRating: (othersCourse
|
||||
.rating.isNotEmpty &&
|
||||
othersCourse.rating[0]?.avgRating !=
|
||||
null)
|
||||
? othersCourse.rating[0]!.avgRating
|
||||
.toString()
|
||||
: '0',
|
||||
rating: (othersCourse.rating.isNotEmpty &&
|
||||
othersCourse.rating[0]?.avgRating !=
|
||||
null)
|
||||
? othersCourse.rating[0]!.avgRating
|
||||
.toString()
|
||||
: '5.0',
|
||||
numberOfRatings: (othersCourse
|
||||
.rating.isNotEmpty &&
|
||||
othersCourse.rating[0]?.totalReview !=
|
||||
null)
|
||||
? othersCourse.rating[0]!.totalReview!
|
||||
: '0',
|
||||
isTopCourse: othersCourse.topCourse ?? '0',
|
||||
price: (othersCourse.price == '0')
|
||||
? 'Gratis'
|
||||
: (othersCourse.promoPrice != '0')
|
||||
? numberFormat(
|
||||
othersCourse.promoPrice)
|
||||
: numberFormat(displayedPrice),
|
||||
realPrice: (othersCourse.price == '0')
|
||||
? ''
|
||||
: numberFormat(
|
||||
othersCourse.price.toString()),
|
||||
press: () {
|
||||
print('ini ke detail');
|
||||
if (othersCourse.promoPrice != '0') {
|
||||
Navigator.of(context, rootNavigator: true)
|
||||
.push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
DetailCourseScreen(
|
||||
isPromo: true,
|
||||
idcourse: othersCourse.idCourse,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
Navigator.of(context, rootNavigator: true)
|
||||
.push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
DetailCourseScreen(
|
||||
// isPromo: true,
|
||||
idcourse: othersCourse.idCourse,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultState.noData ||
|
||||
state.state == ResultState.error) {
|
||||
return SearchNotFound();
|
||||
} else {
|
||||
return Center(child: Text(''));
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
48
lib/widgets/search_not_found.dart
Normal file
48
lib/widgets/search_not_found.dart
Normal file
@ -0,0 +1,48 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/screens/home/components/body_comp/latest_course.dart';
|
||||
import 'package:initial_folder/screens/home/components/body_comp/populer_course.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
|
||||
class SearchNotFound extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Center(
|
||||
child: Container(
|
||||
child: Image.asset(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? baruTextutih
|
||||
: twelveColor,
|
||||
'assets/images/kursuskosong.png',
|
||||
width: getProportionateScreenHeight(100),
|
||||
),
|
||||
padding: EdgeInsets.only(top: 40, bottom: 16),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Kursus Belum Tersedia',
|
||||
style: secondaryTextStyle.copyWith(
|
||||
fontSize: 14,
|
||||
fontWeight: semiBold,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
'Kursus belum tersedia, silahkan cari kursus yang lain',
|
||||
style: primaryTextStyle.copyWith(fontSize: 12, fontWeight: reguler),
|
||||
),
|
||||
SizedBox(
|
||||
height: 25,
|
||||
),
|
||||
PopulerCourse(text: "Kursus Teratas"),
|
||||
LatestCourse(text: "Kursus Terbaru"),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
73
lib/widgets/terms_and_privacy.dart
Normal file
73
lib/widgets/terms_and_privacy.dart
Normal file
@ -0,0 +1,73 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
class TermsAndCondition extends StatefulWidget {
|
||||
static const routeName = '/article_web';
|
||||
|
||||
final String url;
|
||||
final String? id;
|
||||
|
||||
const TermsAndCondition({Key? key, required this.url, this.id})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<TermsAndCondition> createState() => _TermsAndConditionState();
|
||||
}
|
||||
|
||||
class _TermsAndConditionState extends State<TermsAndCondition> {
|
||||
double progres = 0;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final juduls = {
|
||||
'sk': Text('Syarat dan Ketentuan'),
|
||||
'prv': Text('Kebijakan Privasi'),
|
||||
'about': Text('Tentang Vocasia'),
|
||||
'ctc': Text('Kontak Kami'),
|
||||
'help': Text('Bantuan'),
|
||||
'gopay': Text('Gopay'),
|
||||
};
|
||||
final judul = juduls[widget.id];
|
||||
|
||||
var controller = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..setBackgroundColor(const Color(0x00000000))
|
||||
..setNavigationDelegate(
|
||||
NavigationDelegate(
|
||||
onProgress: (int progress) {
|
||||
// Update loading bar.
|
||||
},
|
||||
onPageStarted: (String url) {},
|
||||
onPageFinished: (String url) {},
|
||||
onWebResourceError: (WebResourceError error) {},
|
||||
onUrlChange: (change) {},
|
||||
onNavigationRequest: (NavigationRequest request) {
|
||||
if (request.url != widget.url) {
|
||||
// Prevent navigation to other URLs and about:blank
|
||||
print("Navigation prevented: ${request.url}");
|
||||
return NavigationDecision.prevent;
|
||||
} else {
|
||||
print("Navigation Accesed: ${request.url}");
|
||||
return NavigationDecision.navigate;
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
..loadRequest(Uri.parse(widget.url));
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: judul),
|
||||
body: Column(
|
||||
children: [
|
||||
LinearProgressIndicator(
|
||||
value: progres,
|
||||
color: sevenColor,
|
||||
backgroundColor: secondaryColor,
|
||||
),
|
||||
Expanded(child: WebViewWidget(controller: controller)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
87
lib/widgets/wishlist_page.dart
Normal file
87
lib/widgets/wishlist_page.dart
Normal file
@ -0,0 +1,87 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/helper/validator.dart';
|
||||
import 'package:initial_folder/models/wishlist_model.dart';
|
||||
import 'package:initial_folder/screens/detail_course/detail_course_screen.dart';
|
||||
import 'package:initial_folder/screens/whislist/wishlist_card.dart';
|
||||
|
||||
class MyWishlistPage extends StatelessWidget {
|
||||
const MyWishlistPage({Key? key, required this.wishlistDataModel})
|
||||
: super(key: key);
|
||||
final DataWihslistModel wishlistDataModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: WishlistCard(
|
||||
id: wishlistDataModel.wishlistId ?? '',
|
||||
thumbnail: wishlistDataModel.thumbnail ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
|
||||
title: wishlistDataModel.title ?? '',
|
||||
numberOfRatings: wishlistDataModel.review[0].totalReview ?? '0',
|
||||
press: () {
|
||||
print(wishlistDataModel.courseId);
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => DetailCourseScreen(
|
||||
// idcourse: wishlistDataModel.courseId ?? '0',
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
},
|
||||
price: (wishlistDataModel.discountPrice == '0')
|
||||
? (wishlistDataModel.price == '0'
|
||||
? 'Gratis'
|
||||
: numberFormat(wishlistDataModel.price))
|
||||
: numberFormat(wishlistDataModel.discountPrice),
|
||||
isTopCourse: '0',
|
||||
instructorName: wishlistDataModel.instructor ?? '',
|
||||
rating: wishlistDataModel.review[0].avgRating != null
|
||||
? '${wishlistDataModel.review[0].avgRating}'
|
||||
: '5.0',
|
||||
realPrice: (wishlistDataModel.discountPrice == '0')
|
||||
? ''
|
||||
: numberFormat(wishlistDataModel.price),
|
||||
specificRating: double.parse(wishlistDataModel.review[0].avgRating != null
|
||||
? '${wishlistDataModel.review[0].avgRating}'
|
||||
: '0')
|
||||
.toString(),
|
||||
courseId: wishlistDataModel.courseId.toString(),
|
||||
));
|
||||
}
|
||||
}
|
||||
// return ProductCard(
|
||||
// id: othersCourse.idCourse,
|
||||
// thumbnail: othersCourse.thumbnail ??
|
||||
// 'http://api.vocasia.pasia.id/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
|
||||
// title: othersCourse.title,
|
||||
// instructorName: othersCourse.instructorName,
|
||||
// specificRating: double.parse(
|
||||
// othersCourse.rating[0]!.avgRating != null
|
||||
// ? '${othersCourse.rating[0]!.avgRating}'
|
||||
// : '0')
|
||||
// .toString(),
|
||||
// rating: othersCourse.rating[0]!.avgRating != null
|
||||
// ? '${othersCourse.rating[0]!.avgRating}'
|
||||
// : '5.0',
|
||||
// numberOfRatings: othersCourse.rating[0]!.totalReview ?? '0',
|
||||
// isTopCourse: othersCourse.topCourse!,
|
||||
// price: (othersCourse.discountPrice == '0')
|
||||
// ? 'Gratis'
|
||||
// : numberFormat(othersCourse.discountPrice),
|
||||
// realPrice: (othersCourse.price == '0')
|
||||
// ? ''
|
||||
// : numberFormat(othersCourse.price),
|
||||
// press: () {
|
||||
// print(othersCourse.idCourse);
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => DetailCourseScreen(
|
||||
// idcourse: othersCourse.idCourse,
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// );
|
Reference in New Issue
Block a user