feat: shared preferenced session auth, and customable widget
This commit is contained in:
parent
fbde7c0ba6
commit
2ac0e09309
|
@ -3,15 +3,15 @@ import 'package:google_fonts/google_fonts.dart';
|
|||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
// =====================color schema=====================
|
||||
Color whiteColor = const Color(0xffF0F1EA);
|
||||
Color blackNavyColor = const Color(0xff101010);
|
||||
Color primaryColor = const Color(0xff018558);
|
||||
Color secondaryColor = const Color(0xffBDE902);
|
||||
Color tersierColor = const Color(0xffFEF031);
|
||||
Color redColor = const Color(0xffFF4438);
|
||||
Color blueColor = const Color(0xff00B5FF);
|
||||
Color greyColor = const Color(0xffCBD4E6);
|
||||
Color greyAbsolutColor = const Color(0xff5C707A);
|
||||
Color whiteColor = Color(0xffF0F1EA);
|
||||
Color blackNavyColor = Color(0xff101010);
|
||||
Color primaryColor = Color(0xff018558);
|
||||
Color secondaryColor = Color(0xffBDE902);
|
||||
Color tersierColor = Color(0xffFEF031);
|
||||
Color redColor = Color(0xffFF4438);
|
||||
Color blueColor = Color(0xff00B5FF);
|
||||
Color greyColor = Color(0xffCBD4E6);
|
||||
Color greyAbsolutColor = Color(0xff5C707A);
|
||||
|
||||
// =====================font weight=====================
|
||||
FontWeight light = FontWeight.w300;
|
||||
|
@ -24,24 +24,30 @@ FontWeight superBold = FontWeight.w900;
|
|||
|
||||
// =====================text behavior=====================
|
||||
class Tulisan {
|
||||
static TextStyle heading = GoogleFonts.spaceGrotesk(
|
||||
static TextStyle heading({Color? color}) {
|
||||
return GoogleFonts.spaceGrotesk(
|
||||
fontSize: 24.sp,
|
||||
fontWeight: bold,
|
||||
color: blackNavyColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: color ?? blackNavyColor,
|
||||
);
|
||||
}
|
||||
|
||||
static TextStyle body = GoogleFonts.spaceMono(
|
||||
static TextStyle body({Color? color}) {
|
||||
return GoogleFonts.spaceMono(
|
||||
fontSize: 16.sp,
|
||||
fontWeight: regular,
|
||||
color: blackNavyColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: color ?? blackNavyColor,
|
||||
);
|
||||
}
|
||||
|
||||
static TextStyle subheading = GoogleFonts.spaceGrotesk(
|
||||
static TextStyle subheading({Color? color}) {
|
||||
return GoogleFonts.spaceGrotesk(
|
||||
fontSize: 18.sp,
|
||||
fontWeight: medium,
|
||||
color: blackNavyColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: color ?? blackNavyColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// =====================padding custom=====================
|
||||
class PaddingCustom {
|
||||
|
@ -68,7 +74,11 @@ class PaddingCustom {
|
|||
double bottom = 0.0,
|
||||
}) {
|
||||
return EdgeInsets.only(
|
||||
left: left.sp, top: top.sp, right: right.sp, bottom: bottom.sp);
|
||||
left: left.sp,
|
||||
top: top.sp,
|
||||
right: right.sp,
|
||||
bottom: bottom.sp,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
import 'package:go_router/go_router.dart';
|
||||
import 'package:rijig_mobile/core/navigation.dart';
|
||||
import 'package:rijig_mobile/screen/app/activity/activity_screen.dart';
|
||||
import 'package:rijig_mobile/screen/app/cart/cart_screen.dart';
|
||||
import 'package:rijig_mobile/screen/app/home/home_screen.dart';
|
||||
import 'package:rijig_mobile/screen/app/profil/profil_screen.dart';
|
||||
import 'package:rijig_mobile/screen/app/requestpick/requestpickup_screen.dart';
|
||||
// import 'package:rijig_mobile/screen/auth/login_screen.dart';
|
||||
import 'package:rijig_mobile/screen/auth/login_screen.dart';
|
||||
import 'package:rijig_mobile/screen/auth/otp_screen.dart';
|
||||
import 'package:rijig_mobile/screen/launch/onboardingpage_screen.dart';
|
||||
import 'package:rijig_mobile/screen/launch/splash_screen.dart';
|
||||
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
// GoRoute(path: '/', builder: (context, state) => SplashScreen()),
|
||||
GoRoute(path: '/', builder: (context, state) => NavigationPage()),
|
||||
GoRoute(path: '/', builder: (context, state) => SplashScreen()),
|
||||
GoRoute(
|
||||
path: '/onboarding',
|
||||
builder: (context, state) => OnboardongPageScreen(),
|
||||
builder: (context, state) => OnboardingPageScreen(),
|
||||
),
|
||||
GoRoute(path: '/login', builder: (context, state) => LoginScreen()),
|
||||
GoRoute(
|
||||
path: '/navigasi',
|
||||
builder: (context, state) {
|
||||
|
@ -29,9 +33,12 @@ final router = GoRouter(
|
|||
},
|
||||
),
|
||||
GoRoute(path: '/home', builder: (context, state) => HomeScreen()),
|
||||
GoRoute(path: '/activity', builder: (context, state) => ActivityScreen()),
|
||||
GoRoute(
|
||||
path: '/requestpickup',
|
||||
builder: (context, state) => RequestPickScreen(),
|
||||
),
|
||||
GoRoute(path: '/cart', builder: (context, state) => CartScreen()),
|
||||
GoRoute(path: '/profil', builder: (context, state) => ProfilScreen()),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -2,8 +2,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:rijig_mobile/model/product.dart';
|
||||
import 'package:rijig_mobile/screen/app/home/components/product_card.dart';
|
||||
|
||||
import 'section_title.dart';
|
||||
|
||||
class PopularProducts extends StatelessWidget {
|
||||
const PopularProducts({super.key});
|
||||
|
||||
|
@ -13,20 +11,25 @@ class PopularProducts extends StatelessWidget {
|
|||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: SectionTitle(
|
||||
title: "Popular Products",
|
||||
// press: () {
|
||||
// Navigator.pushNamed(context, ProductsScreen.routeName);
|
||||
// },
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Artikel",
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
...List.generate(
|
||||
demoProducts.length,
|
||||
(index) {
|
||||
...List.generate(demoProducts.length, (index) {
|
||||
if (demoProducts[index].isPopular) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
|
@ -37,14 +40,12 @@ class PopularProducts extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
return const SizedBox
|
||||
.shrink(); // here by default width and height is 0
|
||||
},
|
||||
),
|
||||
return const SizedBox.shrink(); // here by default width and height is 0
|
||||
}),
|
||||
const SizedBox(width: 20),
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class SectionTitle extends StatelessWidget {
|
||||
const SectionTitle({
|
||||
super.key,
|
||||
required this.title,
|
||||
// this.press,
|
||||
});
|
||||
|
||||
final String title;
|
||||
// GestureTapCallback press;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: (){},
|
||||
style: TextButton.styleFrom(foregroundColor: Colors.grey),
|
||||
child: const Text("See more"),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'section_title.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
|
||||
class SpecialOffers extends StatelessWidget {
|
||||
const SpecialOffers({super.key});
|
||||
|
@ -11,11 +10,25 @@ class SpecialOffers extends StatelessWidget {
|
|||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: SectionTitle(
|
||||
title: "Special for you",
|
||||
// press: () {},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Important!",
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// child: SectionTitle(
|
||||
// title: "Special for you",
|
||||
// // press: () {},
|
||||
// ),
|
||||
),
|
||||
const Gap(15),
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:rijig_mobile/widget/appbar.dart';
|
||||
|
||||
class RequestPickScreen extends StatelessWidget {
|
||||
const RequestPickScreen({super.key});
|
||||
|
@ -6,7 +7,7 @@ class RequestPickScreen extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text("Request Pickup")),
|
||||
appBar: CustomAppBar(judul: "Pilih Sampah"),
|
||||
body: Center(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
|
|
|
@ -46,7 +46,7 @@ class VerifotpScreen extends StatelessWidget {
|
|||
|
||||
if (userVM.authModel?.status == 200) {
|
||||
debugPrint("routing ke halaman home");
|
||||
router.go('/home');
|
||||
router.go('/navigasi');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import 'package:concentric_transition/concentric_transition.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rijig_mobile/core/guide.dart';
|
||||
import 'package:rijig_mobile/core/router.dart';
|
||||
|
||||
final pages = [
|
||||
const PageData(
|
||||
|
@ -22,8 +24,26 @@ final pages = [
|
|||
),
|
||||
];
|
||||
|
||||
class OnboardongPageScreen extends StatelessWidget {
|
||||
const OnboardongPageScreen({super.key});
|
||||
class OnboardingPageScreen extends StatefulWidget {
|
||||
const OnboardingPageScreen({super.key});
|
||||
|
||||
@override
|
||||
OnboardingPageScreenState createState() => OnboardingPageScreenState();
|
||||
}
|
||||
|
||||
class OnboardingPageScreenState extends State<OnboardingPageScreen> {
|
||||
final PageController _controller = PageController();
|
||||
int _currentIndex = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller.addListener(() {
|
||||
setState(() {
|
||||
_currentIndex = _controller.page!.round();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -31,24 +51,35 @@ class OnboardongPageScreen extends StatelessWidget {
|
|||
return Scaffold(
|
||||
body: ConcentricPageView(
|
||||
colors: pages.map((p) => p.bgColor).toList(),
|
||||
pageController: _controller,
|
||||
radius: screenWidth * 0.1,
|
||||
nextButtonBuilder:
|
||||
(context) => Padding(
|
||||
padding: const EdgeInsets.only(left: 3), // visual center
|
||||
child: Icon(Icons.navigate_next, size: screenWidth * 0.08),
|
||||
nextButtonBuilder: (context) {
|
||||
if (_currentIndex == pages.length - 1) {
|
||||
return InkWell(
|
||||
onTap: () => router.go('/login'),
|
||||
child: Center(
|
||||
child: Text(
|
||||
"Go to Login",
|
||||
style: TextStyle(
|
||||
fontSize: screenWidth * 0.04,
|
||||
color: whiteColor,
|
||||
),
|
||||
// enable itemcount to disable infinite scroll
|
||||
// itemCount: pages.length,
|
||||
// opacityFactor: 2.0,
|
||||
// textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 3),
|
||||
child: Icon(Icons.navigate_next, size: screenWidth * 0.08),
|
||||
);
|
||||
},
|
||||
itemCount: pages.length,
|
||||
scaleFactor: 2,
|
||||
duration: Duration(milliseconds: 500),
|
||||
// verticalPosition: 0.7,
|
||||
// direction: Axis.vertical,
|
||||
// itemCount: pages.length,
|
||||
// physics: NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (index) {
|
||||
final page = pages[index % pages.length];
|
||||
return SafeArea(child: _Page(page: page));
|
||||
final page = pages[index];
|
||||
return SafeArea(child: _Page(page: page, index: index));
|
||||
},
|
||||
),
|
||||
);
|
||||
|
@ -71,12 +102,14 @@ class PageData {
|
|||
|
||||
class _Page extends StatelessWidget {
|
||||
final PageData page;
|
||||
final int index;
|
||||
|
||||
const _Page({required this.page});
|
||||
const _Page({required this.page, required this.index});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenHeight = MediaQuery.of(context).size.height;
|
||||
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:rijig_mobile/core/guide.dart';
|
||||
import 'package:rijig_mobile/core/router.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class SplashScreen extends StatelessWidget {
|
||||
const SplashScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Future.delayed(Duration(seconds: 3), () {
|
||||
router.go('/onboarding');
|
||||
});
|
||||
_checkLoginStatus(context);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: whiteColor,
|
||||
|
@ -21,7 +20,6 @@ class SplashScreen extends StatelessWidget {
|
|||
right: 0,
|
||||
child: Image.asset('assets/image/Go_Ride.png', height: 200),
|
||||
),
|
||||
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Padding(
|
||||
|
@ -31,7 +29,7 @@ class SplashScreen extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: primaryColor,
|
||||
color: Colors.blue,
|
||||
fontFamily: 'Roboto',
|
||||
),
|
||||
),
|
||||
|
@ -41,4 +39,17 @@ class SplashScreen extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _checkLoginStatus(BuildContext context) async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
bool isLoggedIn = prefs.getBool('isLoggedIn') ?? false;
|
||||
|
||||
await Future.delayed(Duration(seconds: 3));
|
||||
|
||||
if (isLoggedIn) {
|
||||
router.go('/navigasi');
|
||||
} else {
|
||||
router.go('/onboarding');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ class UserViewModel extends ChangeNotifier {
|
|||
await prefs.setString('token', response['data']['token']);
|
||||
await prefs.setString('user_id', response['data']['user_id']);
|
||||
await prefs.setString('user_role', response['data']['user_role']);
|
||||
await prefs.setBool('isLoggedIn', true);
|
||||
|
||||
debugPrint("berhasil login");
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:iconsax_flutter/iconsax_flutter.dart';
|
||||
import 'package:rijig_mobile/core/guide.dart';
|
||||
import 'package:rijig_mobile/core/router.dart';
|
||||
|
||||
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
final String judul;
|
||||
|
||||
final List<Widget>? actions;
|
||||
|
||||
const CustomAppBar({super.key, required this.judul, this.actions});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppBar(
|
||||
titleSpacing: 3,
|
||||
title: Text(judul, style: Tulisan.subheading(color: whiteColor)),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
router.pop();
|
||||
},
|
||||
icon: Icon(Iconsax.arrow_left_3_copy, color: whiteColor, size: 26),
|
||||
),
|
||||
backgroundColor: primaryColor,
|
||||
elevation: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
actions: actions,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
|
||||
}
|
Loading…
Reference in New Issue