chore(wip): upgrade dependencies, begin refactor

This commit is contained in:
2025-12-23 21:49:54 +01:00
parent 0070e57aec
commit 239b63ca81
82 changed files with 4028 additions and 195 deletions

View File

@@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
class NewTripPage extends StatefulWidget {
const NewTripPage({super.key});
@override
_NewTripPageState createState() => _NewTripPageState();
}
class _NewTripPageState extends State<NewTripPage> {
int _currentStep = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Create New Trip'),
),
body: Stepper(
currentStep: _currentStep,
onStepContinue: () {
if (_currentStep < 1) {
setState(() {
_currentStep += 1;
});
}
},
onStepCancel: () {
if (_currentStep > 0) {
setState(() {
_currentStep -= 1;
});
}
},
steps: [
Step(
title: const Text('Select Location'),
content: const MapWithSearchField(), // Replace with your map module
isActive: _currentStep >= 0,
),
Step(
title: const Text('Choose Options'),
content: const OptionsList(), // Replace with your options module
isActive: _currentStep >= 1,
),
],
),
);
}

View File

@@ -0,0 +1,12 @@
import 'package:flutter/material.dart';
class LoginPage extends StatelessWidget {
const LoginPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Login Page')),
);
}
}

View File

@@ -0,0 +1,172 @@
import 'dart:ui';
import 'package:anyway/core/constants.dart';
import 'package:anyway/presentation/providers/onboarding_state_provider.dart';
import 'package:anyway/presentation/widgets/onbarding_agreement_card.dart';
import 'package:anyway/presentation/widgets/onboarding_card.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
List<Widget> onboardingCards = [
const OnboardingCard(
title: "Welcome to anyway!",
description: "Anyway helps you plan a city trip that suits your wishes.",
imagePath: "assets/cld-server.svg"
),
const OnboardingCard(
title: "Do your thing",
description: "Bored by churches? No problem! Hate shopping? No worries! Instead of suggesting the generic trips that bore you, anyway will try to give you recommendations that really suit you.",
imagePath: "assets/con-drill.svg"
),
const OnboardingCard(
title: "Change your mind",
description: "Feet get sore, the weather changes. Anyway understands that! Move or remove destinations, visit hidden gems along your journey, do your own thing. Anyway adapts to your spontaneous decisions.",
imagePath: "assets/cel-snow-globe.svg"
),
const OnboardingCard(
title: "Feeling lost?",
description: "Whenever you are confused or need help with the app, look out for the question mark in the top right corner. Help is just a tap away!",
imagePath: "assets/gen-lifebelt.svg"
),
];
class OnboardingPage extends ConsumerStatefulWidget {
const OnboardingPage({super.key});
@override
ConsumerState<OnboardingPage> createState() => _OnboardingPageState();
}
class _OnboardingPageState extends ConsumerState<OnboardingPage> {
final PageController _controller = PageController();
late List<Widget> fullCards;
@override
Widget build(BuildContext context) {
Widget agreementCard = OnboardingAgreementCard(
title: "The annoying stuff",
description: "By using anyway, you agree to our terms and conditions and privacy policy. We don't use cookies or tracking, we don't store the data you submit. We are not responsible for any damage or loss caused by using anyway.",
imagePath: "assets/con-warning.svg",
agreementTextPath: "assets/terms_and_conditions.md",
onAgreementChanged: onAgreementChanged,
);
// need to add the agreement from within the function because it needs to be able to call setState
fullCards = onboardingCards + [agreementCard];
return Scaffold(
body: Stack(
children: [
AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Stack(
children: [
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: APP_GRADIENT.colors,
stops: [
(_controller.hasClients ? (_controller.page ?? _controller.initialPage) : _controller.initialPage) / onboardingCards.length,
(_controller.hasClients ? (_controller.page ?? _controller.initialPage) + 1 : _controller.initialPage + 1) / onboardingCards.length,
],
),
),
),
BackdropFilter(
filter: ImageFilter.blur(sigmaX: 100, sigmaY: 100),
child: Container(
color: Colors.black.withValues(alpha: 0.2)
),
),
],
);
},
),
PageView(
controller: _controller,
children: List.generate(
fullCards.length,
(index) {
return Container(
alignment: Alignment.center,
child: fullCards[index],
);
}
),
),
],
),
floatingActionButton: nextButton(_controller)
);
}
Widget nextButton(PageController controller) => AnimatedBuilder(
animation: _controller,
builder: (context, child) {
if ((_controller.hasClients ? (_controller.page ?? _controller.initialPage) : 0) != fullCards.length - 1) {
return FloatingActionButton.extended(
onPressed: () {
controller.nextPage(duration: const Duration(milliseconds: 500), curve: Curves.ease);
},
label: const Icon(Icons.arrow_forward)
);
} else {
// only allow the user to proceed if they have agreed to the terms and conditions
// the information is accessible through ref.watch(onboardingStateProvider)
Widget disabledWidget = FloatingActionButton.extended(
onPressed: null,
label: const Row(
children: [
Text("Start planning!"),
Padding(padding: EdgeInsets.only(right: 8.0)),
Icon(Icons.map_outlined)
],
)
);
return ref.watch(onboardingStateProvider).when(
data: (isOnboarded) {
if (isOnboarded) {
return FloatingActionButton.extended(
onPressed: () {
// proceed to the next page - pop the onboarding page so the StartPage can decide what to show next
Navigator.of(context).pop();
},
label: const Row(
children: [
Text("Start planning!"),
Padding(padding: EdgeInsets.only(right: 8.0)),
Icon(Icons.map_outlined)
],
)
);
} else {
return disabledWidget;
}
},
loading: () => disabledWidget,
error: (error, stack) => disabledWidget,
);
}
}
);
void onAgreementChanged(bool value) async {
await ref.read(onboardingControllerProvider).setOnboarded(value);
setState(() {
// rebuild to show the next button
});
}
}

View File

@@ -0,0 +1,97 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:anyway/presentation/providers/onboarding_state_provider.dart';
import 'package:anyway/presentation/pages/login.dart';
import 'package:anyway/presentation/pages/onboarding.dart';
// Example providers (replace these with your actual providers)
// final onboardingStateProvider = Provider<bool>((ref) => true); // Replace with actual onboarding state logic
final authStateProvider = FutureProvider<bool>((ref) async => true); // Replace with actual auth state logic
final tripsAvailableProvider = FutureProvider<bool>((ref) async => false); // Replace with actual trips availability logic
class StartPage extends ConsumerWidget {
const StartPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
// the home page is dependent on the state of the providers:
// - if the user is not onboarded, show the onboarding flow
// - if the user is not logged in, show the login page
// - if there are no trips available, show the trip creation page
// - else: show the overview page that shows the last trip
final onboardingState = ref.watch(onboardingStateProvider);
final authState = ref.watch(authStateProvider);
final tripsAvailable = ref.watch(tripsAvailableProvider);
return onboardingState.when(
data: (isOnboarded) {
if (!isOnboarded) {
return const OnboardingPage();
}
return authState.when(
data: (isLoggedIn) {
if (!isLoggedIn) {
return const LoginPage();
}
return tripsAvailable.when(
data: (hasTrips) {
if (!hasTrips) {
return const TripCreationPage();
}
return const OverviewPage();
},
loading: () => const Scaffold(
body: Center(child: CircularProgressIndicator()),
),
error: (error, stack) => Scaffold(
body: Center(child: Text('Error: $error')),
),
);
},
loading: () => const Scaffold(
body: Center(child: CircularProgressIndicator()),
),
error: (error, stack) => Scaffold(
body: Center(child: Text('Error: $error')),
),
);
},
loading: () => const Scaffold(
body: Center(child: CircularProgressIndicator()),
),
error: (error, stack) => Scaffold(
body: Center(child: Text('Error: $error')
),
),
);
}
}
class TripCreationPage extends StatelessWidget {
const TripCreationPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Trip Creation Page')),
);
}
}
class OverviewPage extends StatelessWidget {
const OverviewPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Overview Page')),
);
}
}