MobileEasyCook/easycook_mobile/lib/pages/detail_resep.dart
2024-12-31 09:53:57 +07:00

1174 lines
51 KiB
Dart

import 'package:easycook_mobile/blocs/recipe_detail/recipe_detail_cubit.dart';
import 'package:easycook_mobile/pages/rekomendasi_supplier.dart';
import 'package:easycook_mobile/pages/semua_ulasan.dart';
import 'package:easycook_mobile/pages/supplier.dart';
import 'package:easycook_mobile/pages/tulis_ulasan.dart';
import 'package:easycook_mobile/theme.dart';
import 'package:flutter/material.dart';
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:percent_indicator/percent_indicator.dart';
class DetailResepPage extends StatefulWidget {
final int recipeId;
const DetailResepPage({super.key, required this.recipeId});
@override
State<DetailResepPage> createState() => _DetailResepPageState();
}
class _DetailResepPageState extends State<DetailResepPage> {
late RecipeDetailCubit _fetchRecipeDetailCubit;
int counter = 0;
@override
void initState() {
// TODO: implement initState
_fetchRecipeDetailCubit = RecipeDetailCubit()
..recipeDetail(id: widget.recipeId);
super.initState();
}
@override
void dispose() {
// TODO: implement dispose
_fetchRecipeDetailCubit.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Detail Menu'),
centerTitle: true,
foregroundColor: Colors.black,
backgroundColor: Colors.white,
elevation: 0.5,
),
body: Container(
color: Colors.white,
padding: EdgeInsets.all(16),
child: ListView(
children: [
// Card Gambar
Container(
child: BlocProvider(
create: (context) => _fetchRecipeDetailCubit,
child: BlocBuilder(
bloc: _fetchRecipeDetailCubit,
builder: (context, state) {
return state is RecipeDetailLoading
? Center(
child: CircularProgressIndicator(),
)
: state is RecipeDetailFailure
? Center(
child: Text(state.message),
)
: state is RecipeDetailSucces
? Column(
children: [
Container(
width: 360,
height: 250,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
state.recipeDetail.imageUrl),
),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(
top: 160, left: 24),
child: Row(
children: [
Expanded(
child: Text(
state.recipeDetail.title,
style: GoogleFonts
.montserrat()
.copyWith(
fontSize: 16,
fontWeight:
FontWeight.bold,
color: Colors.white,
),
),
),
Padding(
padding:
const EdgeInsets.only(
left: 100),
child: Icon(
Icons.favorite,
color: Colors.white,
size: 24,
),
),
Padding(
padding:
const EdgeInsets.only(
left: 21),
child: SvgPicture.asset(
'assets/icons/ShareNetwork.svg'),
),
],
),
),
Padding(
padding: const EdgeInsets.only(
left: 24, top: 2),
child: Row(
children: [
SvgPicture.asset(
'assets/icons/Star 1.svg'),
Padding(
padding:
const EdgeInsets.only(
left: 4),
child: Text(
'4/5',
style: GoogleFonts
.montserrat()
.copyWith(
fontSize: 12,
fontWeight:
FontWeight.bold,
color: Colors.white,
),
),
),
Padding(
padding:
const EdgeInsets.only(
left: 208),
child: Text(
'1123',
style: GoogleFonts
.montserrat()
.copyWith(
fontSize: 12,
fontWeight:
FontWeight.bold,
color: Colors.white,
),
),
),
Padding(
padding:
const EdgeInsets.only(
left: 14),
child: Text(
'Share',
style: GoogleFonts
.montserrat()
.copyWith(
fontSize: 12,
fontWeight:
FontWeight.bold,
color: Colors.white,
),
),
),
],
),
)
],
),
),
// Container
Container(
width: 360,
height: 56,
color: Colors.amber[50],
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(
top: 16,
left: 16,
bottom: 16),
child: SvgPicture.asset(
'assets/icons/difficulty.svg'),
),
Padding(
padding: const EdgeInsets.only(
left: 4, top: 16, bottom: 16),
child: Text(
state.recipeDetail.difficulty,
style: GoogleFonts.montserrat()
.copyWith(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 16,
bottom: 16,
left: 10),
child: SvgPicture.asset(
'assets/icons/time.svg'),
),
Padding(
padding: const EdgeInsets.only(
top: 16, bottom: 16, left: 4),
child: Row(
children: [
Text(
state.recipeDetail.time
.toString(),
style:
GoogleFonts.montserrat()
.copyWith(
fontSize: 14,
fontWeight:
FontWeight.bold,
),
),
SizedBox(
width: 5,
),
Text(
"Menit",
style:
GoogleFonts.montserrat()
.copyWith(
fontSize: 14,
fontWeight:
FontWeight.bold,
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(
top: 16,
bottom: 16,
left: 12),
child: SvgPicture.asset(
'assets/icons/porsi.svg'),
),
Padding(
padding: const EdgeInsets.only(
top: 16, bottom: 16, left: 4),
child: Row(
children: [
Text(
state.recipeDetail.servings
.toString(),
style:
GoogleFonts.montserrat()
.copyWith(
fontSize: 14,
fontWeight:
FontWeight.bold,
),
),
SizedBox(
width: 5,
),
Text(
"Porsi",
style:
GoogleFonts.montserrat()
.copyWith(
fontSize: 14,
fontWeight:
FontWeight.bold,
),
),
],
),
),
],
),
),
// Resep
Padding(
padding: const EdgeInsets.only(top: 24),
child: Text(
'Bahan-Bahan',
style:
GoogleFonts.montserrat().copyWith(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
),
// Own Ingredient
Container(
child: ListView.builder(
physics:
NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: state.recipeDetail
.ownedIngredients.length,
itemBuilder: (BuildContext context,
int index) {
final data = state.recipeDetail
.ownedIngredients[index];
return ListTile(
leading: SvgPicture.asset(
'assets/icons/tersedia.svg'),
title: Row(
children: [
Text(
data.amount.toString(),
style: GoogleFonts
.montserrat()
.copyWith(
fontSize: 14,
color: Colors.black,
),
),
SizedBox(
width: 10,
),
Text(
data.unit,
style: GoogleFonts
.montserrat()
.copyWith(
fontSize: 14,
color: Colors.black,
),
)
],
),
trailing: Text(
data.name,
style:
GoogleFonts.montserrat()
.copyWith(
fontSize: 14,
color: Colors.black,
),
),
);
}),
),
// Not Own Ingredient
Container(
child: ListView.builder(
physics:
NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: state.recipeDetail
.notOwnedIngredients.length,
itemBuilder: (BuildContext context,
int index) {
final data = state.recipeDetail
.notOwnedIngredients[index];
return ListTile(
leading: SvgPicture.asset(
'assets/icons/kurang.svg'),
title: Row(
children: [
Expanded(
child: Row(
children: [
Text(
data.amount
.toString(),
style: GoogleFonts
.montserrat()
.copyWith(
fontSize: 14,
color:
Colors.black,
),
),
SizedBox(
width: 10,
),
Text(
data.unit
.toString(),
style: GoogleFonts
.montserrat()
.copyWith(
fontSize: 14,
color:
Colors.black,
),
),
],
),
),
Expanded(
child: Text(
data.name,
style: GoogleFonts
.montserrat()
.copyWith(
fontSize: 14,
color: Colors.black,
),
),
)
],
),
);
}),
),
// Button
Padding(
padding: const EdgeInsets.only(top: 24),
child: OutlinedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
KelompokSupplierPage(
recipeId: state
.recipeDetail.id),
),
);
},
child: Text(
'Tambahkan Ke Keranjang',
style: GoogleFonts.montserrat()
.copyWith(
fontSize: 18,
fontWeight: FontWeight.bold,
color: orange,
),
),
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(13),
),
side: BorderSide(
color: orange,
width: 2,
),
),
),
),
// Resep
Padding(
padding: const EdgeInsets.only(
top: 24,
bottom: 20,
),
child: Text(
'Langkah - langkah Memasak',
style:
GoogleFonts.montserrat().copyWith(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
),
Container(
child: ListView.builder(
physics:
NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: state.recipeDetail
.instructions.length,
// itemCount: state.data.first.recipeDetail.first.instructions.length,
itemBuilder: (BuildContext context,
int index) {
final data = state.recipeDetail
.instructions[index];
counter = index + 1;
return ListTileTheme(
style: ListTileStyle.list,
child: ListTile(
leading: Text('$counter'),
title: Text(
data,
style:
GoogleFonts.montserrat()
.copyWith(
fontSize: 14,
color: Colors.black,
),
),
),
);
}),
),
],
)
: SizedBox();
},
),
),
),
// Tags
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text(
'Tags',
style: GoogleFonts.montserrat().copyWith(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Row(
children: [
Container(
width: 56,
height: 23,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Colors.orange),
),
child: Center(
child: Text(
'Murah',
style: GoogleFonts.montserrat().copyWith(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.orange,
),
),
),
),
SizedBox(
width: 4,
),
Container(
width: 56,
height: 23,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Colors.orange),
),
child: Center(
child: Text(
'Mudah',
style: GoogleFonts.montserrat().copyWith(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.orange,
),
),
),
),
SizedBox(
width: 4,
),
Container(
width: 100,
height: 23,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Colors.orange),
),
child: Center(
child: Text(
'Makanan Diet',
style: GoogleFonts.montserrat().copyWith(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.orange,
),
),
),
),
],
),
),
// Divider
Padding(
padding: const EdgeInsets.only(top: 24),
child: const Divider(
thickness: 1,
color: Colors.black26,
),
),
// Rating
Container(
padding: EdgeInsets.only(
left: 16,
right: 16,
),
child: Row(
children: [
// Penilaian & Ulasan
Column(
children: [
Text(
'Penilaian & Ulasan',
style: GoogleFonts.montserrat().copyWith(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
Padding(
padding: const EdgeInsets.only(top: 12),
child: Text(
'3,5',
style: GoogleFonts.montserrat().copyWith(
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 6),
child: Text(
'dari 5',
style: GoogleFonts.montserrat().copyWith(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
),
],
),
Spacer(),
// Bintang
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
children: [
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SemuaUlasanPage(),
),
);
},
child: Text(
'Lihat Semua',
style: GoogleFonts.montserrat().copyWith(
fontSize: 12,
color: Colors.amber,
),
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
children: [
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SizedBox(
width: 5,
),
LinearPercentIndicator(
width: 100,
lineHeight: 8.0,
percent: 1,
backgroundColor: Colors.white,
progressColor: Colors.orange,
),
],
),
Row(
children: [
Container(
child: Row(
children: [
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SizedBox(
width: 5,
),
LinearPercentIndicator(
width: 100,
lineHeight: 8.0,
percent: 0.75,
backgroundColor: Colors.white,
progressColor: Colors.orange,
),
],
),
),
],
),
Row(
children: [
Container(
child: Row(
children: [
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SizedBox(
width: 5,
),
LinearPercentIndicator(
width: 100,
lineHeight: 8.0,
percent: 0.5,
backgroundColor: Colors.white,
progressColor: Colors.orange,
),
],
),
),
],
),
Row(
children: [
Container(
child: Row(
children: [
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SizedBox(
width: 5,
),
LinearPercentIndicator(
width: 100,
lineHeight: 8.0,
percent: 0.25,
backgroundColor: Colors.white,
progressColor: Colors.orange,
),
],
),
),
],
),
Row(
children: [
Container(
child: Row(
children: [
SvgPicture.asset(
'assets/icons/Star 1.svg',
),
SizedBox(
width: 5,
),
LinearPercentIndicator(
width: 100,
lineHeight: 8.0,
percent: 0,
backgroundColor: Colors.white,
progressColor: Colors.orange,
),
],
),
),
],
),
],
),
Text(
'5 Penilaian',
style: GoogleFonts.montserrat().copyWith(
fontSize: 10,
color: Colors.black26,
),
),
],
),
],
),
),
// Komentar
_komentar(),
// Divider
Padding(
padding: const EdgeInsets.only(top: 24, bottom: 24),
child: const Divider(
thickness: 1,
color: Colors.black26,
),
),
Text(
'Mungkin Kamu Suka',
style: GoogleFonts.montserrat().copyWith(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
// Card Resep
Padding(
padding: const EdgeInsets.only(top: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_cardResep(context),
SizedBox(
width: 16,
),
_cardResep(context),
],
),
),
],
),
),
floatingActionButton: Container(
width: 133,
height: 42,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.orange,
),
child: Row(
children: [
SizedBox(
width: 15,
),
SizedBox(
width: 25,
height: 25,
child: SvgPicture.asset(
'assets/icons/ulasan.svg',
),
),
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TulisUlasanPage(),
),
);
},
child: Text(
'Tulis Ulasan',
style: GoogleFonts.montserrat().copyWith(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
),
],
),
),
);
}
}
Widget _cardGambar() {
return Container(
width: 360,
height: 234,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/detail.png'),
),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 160, left: 24),
child: Row(
children: [
Text(
'Tumis Sawi',
style: GoogleFonts.montserrat().copyWith(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
Padding(
padding: const EdgeInsets.only(left: 152),
child: Icon(
Icons.favorite,
color: Colors.white,
size: 24,
),
),
Padding(
padding: const EdgeInsets.only(left: 21),
child: SvgPicture.asset('assets/icons/ShareNetwork.svg'),
),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 24, top: 2),
child: Row(
children: [
SvgPicture.asset('assets/icons/Star 1.svg'),
Padding(
padding: const EdgeInsets.only(left: 4),
child: Text(
'4/5',
style: GoogleFonts.montserrat().copyWith(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.only(left: 208),
child: Text(
'1123',
style: GoogleFonts.montserrat().copyWith(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.only(left: 14),
child: Text(
'Share',
style: GoogleFonts.montserrat().copyWith(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
],
),
)
],
),
);
}
_komentar() {
return Padding(
padding: const EdgeInsets.only(top: 26.5),
child: Container(
width: 328,
height: 166,
padding: const EdgeInsets.only(top: 16, left: 14, right: 16, bottom: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Colors.orange),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Image.asset(
'images/komentar_icon.png',
width: 30,
height: 30,
),
SizedBox(
width: 9,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Rika Kusumawati',
style: GoogleFonts.montserrat().copyWith(
fontSize: 11,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
SvgPicture.asset('assets/icons/Star 1.svg'),
SvgPicture.asset('assets/icons/Star 1.svg'),
SvgPicture.asset('assets/icons/Star 1.svg'),
SvgPicture.asset('assets/icons/Star 1.svg'),
SvgPicture.asset('assets/icons/Star 1.svg'),
],
),
],
),
Spacer(),
Text(
'5 hari yang lalu',
style: GoogleFonts.montserrat().copyWith(
fontSize: 10,
color: Colors.black38,
),
),
],
),
Row(
children: [
SizedBox(
width: 39,
height: 30,
),
Expanded(
child: Text(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore ',
style: GoogleFonts.montserrat().copyWith(fontSize: 10),
),
),
],
),
Row(
children: [
SizedBox(
width: 39,
),
Image.asset(
'images/komentar.png',
width: 56.5,
height: 61,
),
SizedBox(
width: 9,
),
Image.asset(
'images/komentar.png',
width: 56.5,
height: 61,
),
],
),
],
),
),
);
}
Widget _cardResep(BuildContext context) {
return InkWell(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => DetailResepPage(),
// ),
// );
},
child: Container(
width: 156,
height: 216,
padding: const EdgeInsets.only(top: 8, right: 8, left: 8, bottom: 16),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/card_bg.png'),
fit: BoxFit.fitHeight,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
// Rating
SvgPicture.asset('assets/icons/Star 1.svg'),
SizedBox(
width: 4,
),
Text(
'4/5',
style: GoogleFonts.montserrat().copyWith(
fontSize: 10,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
const Spacer(),
// Like Button
OutlinedButton(
onPressed: () {},
child: const Icon(
Icons.favorite,
color: Colors.amber,
),
style: OutlinedButton.styleFrom(
shape: CircleBorder(),
backgroundColor: Colors.white,
side: BorderSide(color: Colors.amber),
),
),
],
),
const Spacer(),
Text(
'Tumis Sawi dengan Terasi',
style: GoogleFonts.montserrat().copyWith(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w900,
),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
'kelengkapan bahan',
style: GoogleFonts.montserrat().copyWith(
color: Colors.white,
fontSize: 10,
),
),
),
Row(
children: [
LinearPercentIndicator(
width: 100.0,
lineHeight: 8.0,
percent: 0.8,
backgroundColor: Colors.white,
progressColor: Colors.orange,
),
Spacer(),
Text(
'80 %',
style: GoogleFonts.montserrat().copyWith(
color: Colors.orange,
),
),
],
),
],
),
),
);
}