First Commit

This commit is contained in:
='fauz
2025-03-17 14:54:44 +07:00
commit 4e58e23d9b
193 changed files with 9041 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:furibase/components/navbar_container.dart';
import 'package:furibase/components/navbar_shape_1.dart';
import 'package:furibase/components/navbar_shape_2.dart';
import 'package:furibase/components/navbar_shape_3.dart';
class BottomNavbar extends StatefulWidget {
const BottomNavbar({super.key});
@override
State<BottomNavbar> createState() => _BottomNavbarState();
}
class _BottomNavbarState extends State<BottomNavbar> {
Widget build(BuildContext context) {
final Size screenSize = MediaQuery.of(context).size;
return CustomPaint(
size: Size(screenSize.width, 100.0),
painter:
// BNBCustomPainter1(),
// BNBCustomPainter2(),
BNBCustomPainter3(),
// MyShape(),
);
}
}
+80
View File
@@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
class BuildcardInfo extends StatelessWidget {
final IconData icon;
final String text;
final double? width; // = 120,
final IconData? extraIcon; //,
final String? extraText; //,
const BuildcardInfo({
super.key,
required this.icon,
required this.text,
required this.width,
this.extraIcon,
this.extraText,
});
@override
Widget build(BuildContext context) {
return Container(
height: 36,
width: width ?? 120,
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 5),
decoration: BoxDecoration(
color: Color.fromARGB(133, 240, 235, 235),
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
// color: Color.fromARGB(255, 214, 213, 121),
blurRadius: 0,
spreadRadius: 0,
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconTheme(
data: IconThemeData(
size: 12,
color: Color.fromARGB(255, 244, 189, 72),
),
child: Icon(icon),
),
SizedBox(width: 4),
Expanded(
child: Text(
text,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
color: const Color.fromARGB(255, 255, 255, 255),
),
overflow: TextOverflow.ellipsis,
),
),
if (extraIcon != null && extraText != null) ...[
SizedBox(width: 6),
IconTheme(
data: IconThemeData(
size: 18,
color: Color.fromARGB(255, 244, 189, 72),
),
child: Icon(extraIcon),
),
SizedBox(width: 4),
Text(
extraText ?? '',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
color: Color.fromARGB(255, 255, 255, 255),
),
),
],
],
),
);
}
}
@@ -0,0 +1,105 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
class CollectionContainer extends StatelessWidget {
final String? label;
final String? imagesrc;
final String? imageSvg;
final double? width;
final double? height;
final VoidCallback onTapAc;
final Color? textColor;
const CollectionContainer({
super.key,
this.label,
this.imagesrc,
this.width,
this.height,
required this.onTapAc,
this.textColor,
this.imageSvg,
});
@override
Widget build(BuildContext context) {
return Container(
width: width ?? 130,
height: height ?? 150,
decoration: BoxDecoration(
// color: const Color.fromARGB(26, 24, 24, 180),
color: Colors.grey.withOpacity(0),
borderRadius: BorderRadius.circular(10),
// boxShadow: [
// BoxShadow(
// // color: Colors.grey.withOpacity(1),
// spreadRadius: 1,
// blurRadius: 5,
// offset: Offset(0, 3), // Changes position of shadow
// ),
// ],
),
child: GestureDetector(
onTap: onTapAc,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
color: const Color.fromARGB(255, 255, 255, 255).withOpacity(0.5),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(12),
child:
imageSvg != null && imageSvg!.isNotEmpty
? SvgPicture.asset(
imageSvg!,
width: 60,
height: 60,
colorFilter: const ColorFilter.mode(
Colors.white,
BlendMode.srcIn,
),
)
: imagesrc != null && imagesrc!.isNotEmpty
? Image.asset(
imagesrc!,
width: 60,
// height: 60,
fit: BoxFit.cover,
)
: const SizedBox(
width: 60,
height: 60,
child: Center(
child: Icon(
Icons.image_not_supported,
color: Colors.white,
),
),
),
),
SizedBox(height: 8),
Positioned(
bottom: 0,
child: Container(
// color: Colors.amber,
child: Text(
label ?? '',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: textColor,
),
),
),
),
],
),
),
),
);
}
}
+91
View File
@@ -0,0 +1,91 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class CollectionContainer extends StatelessWidget {
final String? label;
final String? imagesrc;
final String? imageSvg;
final double? width;
final double? height;
final VoidCallback onTapAc;
final Color? textColor;
const CollectionContainer({
Key? key,
this.label,
this.imagesrc,
this.imageSvg,
this.width,
this.height,
required this.onTapAc,
this.textColor,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTapAc,
child: Container(
width: width ?? 130,
height: height ?? 150,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(10),
),
child: Card(
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(10.0),
// ),
elevation: 5,
color: const Color.fromARGB(255, 255, 255, 255).withOpacity(0.5),
child: Stack(
children: [
Center(
child: Padding(
padding: const EdgeInsets.only(bottom: 30.0),
child:
imageSvg != null && imageSvg!.isNotEmpty
? SvgPicture.asset(
imageSvg!,
width: 60,
height: 60,
colorFilter: const ColorFilter.mode(
Colors.white,
BlendMode.srcIn,
),
)
: imagesrc != null && imagesrc!.isNotEmpty
? Image.asset(imagesrc!, width: 60, fit: BoxFit.cover)
: const SizedBox(
width: 60,
height: 60,
child: Center(
child: Icon(
Icons.image_not_supported,
color: Colors.white,
),
),
),
),
),
Positioned(
bottom: 10,
left: 0,
right: 0,
child: Text(
label ?? '',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: textColor ?? Colors.black,
),
),
),
],
),
),
),
);
}
}
+72
View File
@@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'package:furibase/components/bottom_navbar.dart';
import 'package:furibase/components/menu_button.dart';
import 'package:furibase/components/scan_button.dart';
import 'package:furibase/screen/Home_screen.dart';
import 'package:furibase/screen/koleksi_screen.dart';
import 'package:furibase/screen/pustaka_screen.dart';
import 'package:furibase/screen/saya/profile_screen.dart';
class MainMenu extends StatelessWidget {
const MainMenu({super.key});
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Container(
color: Colors.transparent,
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: [
MenuButton(
label: "E-furibuddy",
icon: 'icons/furrybuddy.svg',
onPress:
() => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
),
},
),
MenuButton(
label: "Koleksi",
icon: 'icons/koleksi.svg',
onPress:
() => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => KoleksiScreen()),
),
},
),
SizedBox(width: 120),
MenuButton(
label: "Pustaka",
icon: 'icons/Pustaka.svg',
onPress:
() => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => PustakaScreen()),
),
},
),
MenuButton(
label: "Saya",
icon: 'icons/Saya.svg',
onPress:
() => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ProfileScreen()),
),
},
),
],
),
);
}
}
+52
View File
@@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
class MenuButton extends StatelessWidget {
final String? label;
final String? icon;
final VoidCallback? onPress;
final bool? isSelected;
final double? w;
final double? h;
const MenuButton({
super.key,
this.label,
this.icon,
this.onPress,
this.isSelected,
this.w,
this.h,
});
@override
Widget build(BuildContext context) {
return Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: SvgPicture.asset(
icon ?? '',
width: w ?? 28,
height: h ?? 28,
// allowDrawingOutsideViewBox: true,
colorFilter: ColorFilter.mode(
Color.fromARGB(255, 255, 255, 255),
BlendMode.srcIn,
),
),
onPressed: onPress,
),
Text(
label ?? '',
style: TextStyle(
color: Color.fromARGB(255, 239, 224, 232),
fontWeight: FontWeight.bold,
),
),
],
),
);
}
}
+113
View File
@@ -0,0 +1,113 @@
import 'package:flutter/material.dart';
import 'package:furibase/components/navbar_shape_2.dart';
class NavbarContainer extends StatelessWidget {
const NavbarContainer({super.key});
@override
Widget build(BuildContext context) {
var screen = MediaQuery.of(context).size;
return Positioned(
child: Container(
width: screen.width,
height: screen.height,
color: const Color.fromARGB(255, 38, 139, 92),
child: CustomPaint(child: CustomPaint(painter: MyShape())),
),
);
}
}
class MyShape extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
Paint paint =
new Paint()
..color = const Color.fromARGB(255, 166, 12, 66)
..style = PaintingStyle.fill;
Path path = Path();
path.moveTo(20, size.height / 2); // Start at bottom-left
// shape curve kiri
path.quadraticBezierTo(
size.width * 0.04,
size.height * 0.7, // Control point
size.width * 0.09, // almost half
size.height * 0.8, // End point
);
path.lineTo(size.width * 0.92, size.height - 20);
// Curve kanan bawah
path.quadraticBezierTo(
size.width * 0.96,
size.height * 0.7, // Control point
size.width * 0.964,
size.height / 2, // End point (bottom-right)
);
// curve ujung kanan atas
path.quadraticBezierTo(
size.width * 0.95,
size.height * 0.28, // Control point
size.width * 0.91,
size.height * 0.23, // End point (bottom-right)
);
path.lineTo(size.width / 2 + 80, size.height * 0.23);
// ==========
// sebelum curve tengah
path.quadraticBezierTo(
size.width / 2 + 30,
18,
size.width / 2 + 10,
5, // End point (bottom-right)
);
// ==========================================
//==========================================
// curve tengah sebelah kanan
path.quadraticBezierTo(
size.width / 2 - 20,
13,
size.width / 2 + 2,
size.height * 0.030,
);
// sebelah kiri curve
path.quadraticBezierTo(
(size.width / 2) * 0.92,
size.height * 0.189,
size.width / 2 - 40,
18,
);
// ===============================================
// setelah curve tengah
path.quadraticBezierTo(
size.width / 2 - 30,
size.height * 0.188, // Control point
size.width / 2 - 80,
20, // End point (bottom-right)
);
path.lineTo(size.width * 0.1, 20);
path.quadraticBezierTo(
24,
size.height * 0.2, // Control point
20,
size.height / 2, // End point (bottom-right)
);
path.close();
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
throw false;
}
}
+159
View File
@@ -0,0 +1,159 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class BNBCustomPainter1 extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
debugPrint("Drawing navbar...");
Paint paint =
new Paint()
..color = const Color.fromARGB(255, 79, 76, 182)
..style = PaintingStyle.fill;
// Path path = Path();
// path.moveTo(0, 10); // Start
// path.quadraticBezierTo(size.width * 0.20, 0, size.width * 0.35, 0);
// path.quadraticBezierTo(size.width * 0.40, 0, size.width * 0.40, 20);
// path.arcToPoint(
// Offset(size.width * 0.60, 20),
// radius: Radius.circular(20.0),
// clockwise: false,
// );
// path.quadraticBezierTo(size.width * 0.60, 0, size.width * 0.63, 0);
// path.quadraticBezierTo(size.width * 0.88, 0, size.width, 10);
// path.lineTo(size.width, size.height);
// path.lineTo(0, size.height);
// path.lineTo(0, 20);
// canvas.drawShadow(path, Colors.black, 5, true);
// canvas.drawPath(path, paint);
// Path path = Path();
// double cornerRadius = 35; // Radius untuk sisi kiri & kanan
// double centerCircleRadius = 40; // Radius untuk lengkungan tengah
// // Mulai dari sisi kiri bawah
// path.moveTo(cornerRadius, size.height);
// // Buat lengkungan di sisi kiri
// path.quadraticBezierTo(0, size.height, 0, size.height - cornerRadius);
// // Tarik garis lurus ke atas sebelum lengkungan tengah
// path.lineTo(0, cornerRadius);
// // Kurva sisi kiri menuju bagian atas
// path.quadraticBezierTo(0, 0, cornerRadius, 0);
// // Garis lurus ke bagian tengah sebelum lekukan
// path.lineTo(size.width / 2 - centerCircleRadius - 20, 0);
// // *** Lengkungan ke atas untuk ikon tengah ***
// path.quadraticBezierTo(
// size.width / 2 - centerCircleRadius,
// -centerCircleRadius,
// size.width / 2,
// -centerCircleRadius,
// );
// path.quadraticBezierTo(
// size.width / 2 + centerCircleRadius,
// -centerCircleRadius,
// size.width / 2 + centerCircleRadius + 20,
// 0,
// );
// // Lanjutkan garis ke kanan
// path.lineTo(size.width - cornerRadius, 0);
// // Kurva sisi kanan
// path.quadraticBezierTo(size.width, 0, size.width, cornerRadius);
// // Tarik garis lurus ke bawah
// path.lineTo(size.width, size.height - cornerRadius);
// // Buat lengkungan di sisi kanan
// path.quadraticBezierTo(
// size.width,
// size.height,
// size.width - cornerRadius,
// size.height,
// );
// // Tarik garis ke kiri hingga kembali ke titik awal
// path.close();
// canvas.drawPath(path, paint);
Path path = Path();
double cornerRadius = 45; // Radius sudut kiri & kanan
double centerCircleRadius = 40; // Meningkatkan puncak 10px dari sebelumnya
// Mulai dari sisi kiri bawah
path.moveTo(cornerRadius, size.height);
// Buat lengkungan di sisi kiri
path.quadraticBezierTo(0, size.height, 0, size.height - cornerRadius);
// Tarik garis lurus ke atas sebelum lengkungan tengah
path.lineTo(0, cornerRadius);
// Kurva sisi kiri menuju bagian atas
path.quadraticBezierTo(0, 0, cornerRadius, 0);
// Garis lurus ke bagian tengah sebelum lekukan
path.lineTo(size.width / 2 - centerCircleRadius - 55, 0);
// *** Transisi menuju puncak gunung lebih smooth ***
path.quadraticBezierTo(
size.width / 2 - centerCircleRadius - 20,
-20,
size.width / 2 - centerCircleRadius,
-35,
);
// *** Puncak lebih tinggi & curve lebih halus ***
path.quadraticBezierTo(
size.width / 2,
-centerCircleRadius - 20,
size.width / 2 + centerCircleRadius,
-35,
);
path.quadraticBezierTo(
size.width / 2 + centerCircleRadius + 20,
-20,
size.width / 2 + centerCircleRadius + 55,
0,
);
// Lanjutkan garis ke kanan
path.lineTo(size.width - cornerRadius, 0);
// Kurva sisi kanan
path.quadraticBezierTo(size.width, 0, size.width, cornerRadius);
// Tarik garis lurus ke bawah
path.lineTo(size.width, size.height - cornerRadius);
// Buat lengkungan di sisi kanan
path.quadraticBezierTo(
size.width,
size.height,
size.width - cornerRadius,
size.height,
);
// Tutup path
path.close();
// Gambar path
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
+93
View File
@@ -0,0 +1,93 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class BNBCustomPainter2 extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
debugPrint("Drawing navbar...");
Paint paint =
new Paint()
..color = const Color.fromARGB(255, 79, 76, 182)
..style = PaintingStyle.fill;
// Path path = Path();
// path.moveTo(0, 10); // Start
// path.quadraticBezierTo(size.width * 0.20, 0, size.width * 0.35, 0);
// path.quadraticBezierTo(size.width * 0.40, 0, size.width * 0.40, 20);
// path.arcToPoint(
// Offset(size.width * 0.60, 20),
// radius: Radius.circular(20.0),
// clockwise: false,
// );
// path.quadraticBezierTo(size.width * 0.60, 0, size.width * 0.63, 0);
// path.quadraticBezierTo(size.width * 0.88, 0, size.width, 10);
// path.lineTo(size.width, size.height);
// path.lineTo(0, size.height);
// path.lineTo(0, 20);
// canvas.drawShadow(path, Colors.black, 5, true);
// canvas.drawPath(path, paint);
Path path = Path();
double cornerRadius = 35; // Radius untuk sisi kiri & kanan
double centerCircleRadius = 40; // Radius untuk lengkungan tengah
// Mulai dari sisi kiri bawah
path.moveTo(cornerRadius, size.height);
// Buat lengkungan di sisi kiri
path.quadraticBezierTo(0, size.height, 0, size.height - cornerRadius);
// Tarik garis lurus ke atas sebelum lengkungan tengah
path.lineTo(0, cornerRadius);
// Kurva sisi kiri menuju bagian atas
path.quadraticBezierTo(0, 0, cornerRadius, 0);
// Garis lurus ke bagian tengah sebelum lekukan
path.lineTo(size.width / 2 - centerCircleRadius - 20, 0);
// *** Lengkungan ke atas untuk ikon tengah ***
path.quadraticBezierTo(
size.width / 2 - centerCircleRadius,
-centerCircleRadius,
size.width / 2,
-centerCircleRadius,
);
path.quadraticBezierTo(
size.width / 2 + centerCircleRadius,
-centerCircleRadius,
size.width / 2 + centerCircleRadius + 20,
0,
);
// Lanjutkan garis ke kanan
path.lineTo(size.width - cornerRadius, 0);
// Kurva sisi kanan
path.quadraticBezierTo(size.width, 0, size.width, cornerRadius);
// Tarik garis lurus ke bawah
path.lineTo(size.width, size.height - cornerRadius);
// Buat lengkungan di sisi kanan
path.quadraticBezierTo(
size.width,
size.height,
size.width - cornerRadius,
size.height,
);
// Tarik garis ke kiri hingga kembali ke titik awal
path.close();
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class BNBCustomPainter3 extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
debugPrint("Drawing navbar...");
Paint paint =
new Paint()
..color = const Color.fromARGB(255, 79, 76, 182)
..style = PaintingStyle.fill;
Path path = Path();
path.moveTo(0, 10); // Start
path.quadraticBezierTo(size.width * 0.20, 0, size.width * 0.35, 0);
path.quadraticBezierTo(size.width * 0.40, 0, size.width * 0.40, 20);
path.arcToPoint(
Offset(size.width * 0.60, 20),
radius: Radius.circular(20.0),
clockwise: false,
);
path.quadraticBezierTo(size.width * 0.60, 0, size.width * 0.63, 0);
path.quadraticBezierTo(size.width * 0.88, 0, size.width, 10);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
path.lineTo(0, 20);
canvas.drawShadow(path, Colors.black, 5, true);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
+32
View File
@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
class ScanButton extends StatelessWidget {
const ScanButton({super.key});
static const Color transparent = Color(0xFFFFFFF);
@override
Widget build(BuildContext context) {
return Expanded(
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: const Color.fromARGB(99, 240, 12, 12),
),
padding: EdgeInsets.all(10),
child: IconButton(
icon: SvgPicture.asset(
'icons/Scan.svg',
width: 60,
height: 60,
colorFilter: ColorFilter.mode(
Color.fromARGB(255, 52, 79, 231),
BlendMode.srcIn,
),
),
onPressed: () {},
),
),
);
}
}
+73
View File
@@ -0,0 +1,73 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class TabMenuButton extends StatelessWidget {
final String? label;
final String? icon;
final VoidCallback onPress;
final bool isSelected;
const TabMenuButton({
super.key,
this.label,
this.icon,
required this.onPress,
this.isSelected = false,
});
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null && icon!.isNotEmpty)
IconButton(
icon: SvgPicture.asset(
icon!,
width: 28,
height: 28,
colorFilter: ColorFilter.mode(
isSelected
? const Color.fromARGB(255, 106, 24, 207)
: Colors.white,
BlendMode.srcIn,
),
),
onPressed: onPress, // Semua aksi klik hanya lewat satu function
),
GestureDetector(
onTap: onPress, // Menggunakan satu event handler saja
child: Container(
width: 120,
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
decoration: BoxDecoration(
color:
isSelected
? const Color.fromARGB(
255,
199,
204,
212,
).withOpacity(0.3)
: Colors.transparent,
borderRadius: BorderRadius.circular(20),
),
child: Center(
child: Text(
label ?? '',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color:
isSelected
? const Color.fromARGB(255, 0, 0, 0)
: const Color.fromARGB(255, 0, 0, 0),
),
),
),
),
),
],
);
}
}
+25
View File
@@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
class TopbarContainer extends StatefulWidget {
const TopbarContainer({super.key});
@override
State<TopbarContainer> createState() => _TopbarContainerState();
}
class _TopbarContainerState extends State<TopbarContainer> {
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Container(
width: size.width,
height: 120,
decoration: BoxDecoration(
color: const Color.fromARGB(255, 79, 76, 182),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(25),
bottomRight: Radius.circular(25),
),
),
);
}
}