removed home page

This commit is contained in:
venbaittech 2025-04-28 09:14:48 +05:30
parent 5e4a093456
commit 5c31a33ff2
14 changed files with 269 additions and 153 deletions

View File

@ -334,7 +334,7 @@ class _ApprovalListState extends State<ApprovalList> {
String _formatDate(String rawDate) {
try {
final dateTime = DateTime.parse(rawDate);
return DateFormat('dd MMM yy : hh a').format(dateTime);
return DateFormat('dd MMM yy hh:m a').format(dateTime);
} catch (e) {
return rawDate; // fallback if parsing fails
}
@ -612,7 +612,8 @@ class _ApprovalListState extends State<ApprovalList> {
isApprover: true)),
GestureDetector(
onTap: () => viewPlanforApprover(plan.planId,
onTap: () => ApiService.viewPlanForApprover(
context, plan.planId,
isViewMode: false, isApprover: true),
child: Image.asset(
'assets/images/IconsImg/edit.png',

View File

@ -79,7 +79,7 @@ class _LoginWidgetState extends State<LoginWidget> {
backgroundColor: Colors.green, // Set background to green
),
);
context.go('/home'); // Navigate to home
context.go('/listPlan'); // Navigate to home
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
@ -178,7 +178,7 @@ class _LoginWidgetState extends State<LoginWidget> {
),
const SizedBox(height: 2),
const Text(
"Welcome to trip system management",
"Welcome To Travel Spends",
style: TextStyle(
fontSize: 11,
fontFamily: "Nunito",

View File

@ -4,34 +4,31 @@ import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class LoginPage1 extends StatefulWidget {
const LoginPage1({super.key});
@override
_LoginPageState createState() => _LoginPageState();
}
}
class _LoginPageState extends State<LoginPage1> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: LoginWidget(),
body: LoginWidget(),
);
}
}
// StatefulWidget for Body Content
class LoginWidget extends StatefulWidget{
class LoginWidget extends StatefulWidget {
const LoginWidget({super.key});
@override
_LoginWidgetState createState() => _LoginWidgetState();
}
class _LoginWidgetState extends State<LoginWidget>{
class _LoginWidgetState extends State<LoginWidget> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
@ -47,7 +44,8 @@ class _LoginWidgetState extends State<LoginWidget>{
Uri.parse(url),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'},
'Accept': 'application/json'
},
body: jsonEncode({
'email': _emailController.text.trim(),
'password': _passwordController.text.trim(),
@ -61,11 +59,12 @@ class _LoginWidgetState extends State<LoginWidget>{
backgroundColor: Colors.green, // Set background to green
),
);
context.go('/home'); // Login Success
}
else {
context.go('/listPlan'); // Login Success
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Login Failed: ${jsonDecode(response.body)['message']}")),
SnackBar(
content: Text(
"Login Failed: ${jsonDecode(response.body)['message']}")),
);
}
} catch (e) {
@ -76,16 +75,13 @@ class _LoginWidgetState extends State<LoginWidget>{
}
}
@override
Widget build(BuildContext context){
Widget build(BuildContext context) {
double myHeight = MediaQuery.of(context).size.height;
double myWidth = MediaQuery.of(context).size.width;
return Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
@ -94,19 +90,17 @@ class _LoginWidgetState extends State<LoginWidget>{
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Center(
child: Text(
"Hello! , Welcome Back",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.blueAccent
),
color: Colors.blueAccent),
),
),
),
SizedBox(height: myHeight/10),
SizedBox(height: myHeight / 10),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: const Text(
@ -114,33 +108,32 @@ class _LoginWidgetState extends State<LoginWidget>{
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.blueAccent
),
color: Colors.blueAccent),
),
),
SizedBox(height:8),
SizedBox(height: 8),
TextFormField(
controller: _emailController,
style: const TextStyle(fontSize: 12),
decoration: InputDecoration(
labelText: 'Enter the email',
labelStyle: TextStyle(color: Colors.grey,),
labelStyle: TextStyle(
color: Colors.grey,
),
floatingLabelBehavior: FloatingLabelBehavior.never,
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12), // Rounded corners// Remove the default border
borderSide: BorderSide.none
),
borderRadius: BorderRadius.circular(
12), // Rounded corners// Remove the default border
borderSide: BorderSide.none),
),
validator: (value){
if(value == null || value.isEmpty){
validator: (value) {
if (value == null || value.isEmpty) {
return 'Required Email';
}
return null;
},
),
const SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
@ -149,18 +142,19 @@ class _LoginWidgetState extends State<LoginWidget>{
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.blueAccent
),
color: Colors.blueAccent),
),
),
SizedBox(height:8),
SizedBox(height: 8),
TextFormField(
controller:_passwordController,
controller: _passwordController,
style: const TextStyle(fontSize: 12),
obscureText: _obscureText,
decoration: InputDecoration(
labelText: "Enter the password",
labelStyle: TextStyle(color: Colors.grey,),
labelStyle: TextStyle(
color: Colors.grey,
),
floatingLabelBehavior: FloatingLabelBehavior.never,
suffixIcon: IconButton(
icon: Icon(
@ -176,11 +170,9 @@ class _LoginWidgetState extends State<LoginWidget>{
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none
)
),
validator: (value){
if(value == null || value.isEmpty){
borderSide: BorderSide.none)),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Required Password';
}
return null;
@ -189,21 +181,18 @@ class _LoginWidgetState extends State<LoginWidget>{
const SizedBox(height: 20),
Center(
child: ElevatedButton(
onPressed: (){
onPressed: () {
_login(context);
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueAccent, // Change button color
foregroundColor: Colors.white, // Text color
padding: const EdgeInsets.symmetric(horizontal: 24,vertical: 12),
padding: const EdgeInsets.symmetric(
horizontal: 24, vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
)
),
child: const Text(
"Login")
),
)),
child: const Text("Login")),
),
],
),
@ -211,6 +200,3 @@ class _LoginWidgetState extends State<LoginWidget>{
);
}
}

View File

@ -1,3 +1,4 @@
import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart';
@ -221,7 +222,7 @@ class _FlightScreenState extends State<FlightScreen> {
}
for (int i = 1; i <= rowCount; i++) {
trips.add({
final trip = {
"class": selectedClasses[i],
"from_place": textControllers["_from${i}Controller"]?.text ?? "",
"to_place": textControllers["_to${i}Controller"]?.text ?? "",
@ -229,7 +230,31 @@ class _FlightScreenState extends State<FlightScreen> {
"time": textControllers["_time${i}Controller"]?.text ?? "",
"created_by": widget.loginUser,
"updated_by": widget.loginUser,
});
};
// Check if editing and flight_trip_id exists for this trip
// 🛠 Fix index offset (i - 1)
if (widget.selectedItem != null &&
widget.selectedItem?["trips"] != null &&
widget.selectedItem!["trips"] is List &&
(i - 1) < widget.selectedItem!["trips"].length) {
final existingTrip = widget.selectedItem!["trips"][i - 1];
if (existingTrip["flight_trip_id"] != null) {
trip["flight_trip_id"] = existingTrip["flight_trip_id"];
}
}
trips.add(trip);
// trips.add({
// "class": selectedClasses[i],
// "from_place": textControllers["_from${i}Controller"]?.text ?? "",
// "to_place": textControllers["_to${i}Controller"]?.text ?? "",
// "date": textControllers["_date${i}Controller"]?.text ?? "",
// "time": textControllers["_time${i}Controller"]?.text ?? "",
// "created_by": widget.loginUser,
// "updated_by": widget.loginUser,
// });
}
Map<String, dynamic> data = {
@ -299,6 +324,17 @@ class _FlightScreenState extends State<FlightScreen> {
TextEditingController(text: trip["date"]);
textControllers["_time${index}Controller"] =
TextEditingController(text: trip["time"]);
// Check if editing and flight_trip_id exists for this trip
if (widget.selectedItem != null &&
widget.selectedItem?["trips"] != null &&
widget.selectedItem!["trips"] is List &&
i < widget.selectedItem!["trips"].length) {
final existingTrip = widget.selectedItem!["trips"][i];
if (existingTrip["flight_trip_id"] != null) {
trip["flight_trip_id"] = existingTrip["flight_trip_id"];
}
}
}
print("Selected ITEM - ${widget.selectedItem}");
@ -627,38 +663,86 @@ class _FlightScreenState extends State<FlightScreen> {
: MediaQuery.of(context).size.width * 0.66,
child: SizedBox(
height: 40,
child: DropdownButtonFormField<String>(
isExpanded: true,
// focusNode: _tripTypeFocusNode, // Assign the correct focus node
focusNode: focusNodes["_tripType1FocusNode"],
value: selectedTripType,
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding:
EdgeInsets.symmetric(horizontal: 10), // Proper padding
width: double.infinity,
child: DropdownSearch<String>(
items: purposeList
.map((item) => item['dropdown_value'] as String)
.toList(),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 1),
),
),
onChanged: (newValue) {
setState(() {
selectedTripType = newValue;
if (selectedTripType != "Multitrip") {
multiTripRowCount = 1;
}
errorMessages.clear();
});
print(
"Updating form data: Flight -> trip_type -> $selectedTripType");
_initializeFields();
},
selectedItem: selectedTripType,
dropdownBuilder: (context, selectedItem) => Align(
alignment: Alignment.centerLeft,
child: Text(
selectedItem ?? "Select",
style: TextStyle(fontSize: 12),
),
),
popupProps: PopupProps.menu(
constraints: BoxConstraints(maxHeight: 100),
menuProps: MenuProps(backgroundColor: Colors.white),
itemBuilder: (context, item, isSelected) => Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 6.0),
child: Text(
item,
style: TextStyle(
fontSize: 13), // Custom text size for dropdown items
),
),
),
onChanged: purposeList.isNotEmpty
? (newValue) {
setState(() {
selectedTripType = newValue;
// selectedTripType = "Oneway";
// Reset `multiTripRowCount` when switching away from Multitrip
if (selectedTripType != "Multitrip") {
multiTripRowCount = 1;
}
errorMessages.clear();
});
print(
"Updating form data: Flight -> trip_type -> $selectedTripType");
_initializeFields();
// _initializeRows();
}
: null,
items: dropdownItems,
),
// DropdownButtonFormField<String>(
// isExpanded: true,
// // focusNode: _tripTypeFocusNode, // Assign the correct focus node
// focusNode: focusNodes["_tripType1FocusNode"],
// value: selectedTripType,
// style: TextStyle(fontSize: 12),
// isDense: true,
// dropdownColor: Colors.white,
// decoration: InputDecoration(
// border: InputBorder.none,
// contentPadding:
// EdgeInsets.symmetric(horizontal: 10), // Proper padding
// ),
// onChanged: purposeList.isNotEmpty
// ? (newValue) {
// setState(() {
// selectedTripType = newValue;
// // selectedTripType = "Oneway";
// // Reset `multiTripRowCount` when switching away from Multitrip
// if (selectedTripType != "Multitrip") {
// multiTripRowCount = 1;
// }
// errorMessages.clear();
// });
// print(
// "Updating form data: Flight -> trip_type -> $selectedTripType");
// _initializeFields();
//
// // _initializeRows();
// }
// : null,
//
// items: dropdownItems,
// ),
),
),
];

View File

@ -200,7 +200,7 @@ class ForexListWidget extends StatelessWidget {
Expanded(
flex: 2,
child: Text(
" Currency",
"Currency",
style: TextStyle(
fontSize: 11, fontFamily: "Archivo"),
)),
@ -263,7 +263,7 @@ class ForexListWidget extends StatelessWidget {
Expanded(
flex: 2,
child: Text(
" ${formatDate(item["start_date"]!)} ${formatDate(item["end_date"]!)}",
"${formatDate(item["start_date"]!)} - ${formatDate(item["end_date"]!)}",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,

View File

@ -229,7 +229,7 @@ class InsuranceListWidget extends StatelessWidget {
Expanded(
flex: 2,
child: Text(
"${formatDate(item["start_date"]!)} ${formatDate(item["end_date"]!)}",
"${formatDate(item["start_date"]!)} - ${formatDate(item["end_date"]!)}",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,

View File

@ -214,14 +214,14 @@ class TaxiListWidget extends StatelessWidget {
Expanded(
flex: 2,
child: Text(
"Class",
"Destination",
style: TextStyle(
fontSize: 11, fontFamily: "Archivo"),
)),
Expanded(
flex: 2,
child: Text(
" Planned Trips",
" Location",
style: TextStyle(
fontSize: 11, fontFamily: "Archivo"),
)),

View File

@ -246,7 +246,7 @@ class TrainListWidget extends StatelessWidget {
Expanded(
flex: 2,
child: Text(
"${item["from_station"]!} ${(item["to_station"])}",
"${item["from_station"]!} - ${(item["to_station"])}",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,

View File

@ -298,7 +298,7 @@ class _OrgSetUpState extends State<OrgSetUp> {
if (response.statusCode == 200 || response.statusCode == 201) {
print("✅ User submitted successfully!");
print("📨 Response: ${response.body}");
context.go('/home');
context.go('/listPlan');
} else {
print("❌ Submission failed. Status: ${response.statusCode}");
print("📨 Body: ${response.body}");
@ -827,7 +827,7 @@ class _OrgSetUpState extends State<OrgSetUp> {
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
),
onPressed: () {
context.go('/home');
context.go('/listPlan');
},
child: Text("Cancel")),
SizedBox(

View File

@ -855,6 +855,10 @@ class CreateNewPlansState extends State<CreateNewPlan> {
// data['planId'],planData
// );
print("ViewAAA - $planData");
print("Call viewPlanForApprover");
ApiService.viewPlanForApprover(context, data['plan_id'],
isViewMode: false, isApprover: true);
} else {
print("$methodName failed. Status: ${response.statusCode}");
print("Error: ${response.body}");
@ -876,7 +880,6 @@ class CreateNewPlansState extends State<CreateNewPlan> {
// "${planData['traveller_id']},"
// " ${selectedPlanId}, "
// " ");
postPlanData(planData);
widget.isApprover

View File

@ -11,6 +11,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../../routes/custom_appBar.dart';
import '../../routes/custom_drawer.dart';
import '../../services/apiService.dart';
import '../../utils/auth_utils.dart';
class ListPlans extends StatefulWidget {
@ -21,6 +22,8 @@ class ListPlans extends StatefulWidget {
}
class _ListPlansState extends State<ListPlans> {
final ApiService apiService = ApiService();
late Future<List<Plan>> futurePlans;
String? userId;
String? orgId;
@ -175,47 +178,47 @@ class _ListPlansState extends State<ListPlans> {
}
}
Future<Map<String, dynamic>> getViewPlan(String planId) async {
final String apiUrldata = '$apiUrl/api/plans/find/$planId';
print("API URL: $apiUrldata");
// final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.put(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token', // Add token here
'Content-Type': 'application/json',
},
);
if (response.statusCode == 200) {
final Map<String, dynamic>? resData = json.decode(response.body);
return resData?["data"];
} else {
throw Exception('Failed to load plans');
}
}
void viewPlan(String planId, {bool isViewMode = false}) async {
try {
Map<String, dynamic> planData = await getViewPlan(planId);
print("ViewAAA - $planData");
context.go('/createPlan',
extra: {'planData': planData, 'isViewMode': isViewMode});
} catch (e) {
print("Error fetching plan: $e");
}
}
// Future<Map<String, dynamic>> getViewPlan(String planId) async {
// final String apiUrldata = '$apiUrl/api/plans/find/$planId';
// print("API URL: $apiUrldata");
// // final token = await getToken();
//
// if (token == null) {
// throw Exception('Token not found. Please log in.');
// }
//
// final response = await http.put(
// Uri.parse(apiUrldata),
// headers: {
// 'Authorization': 'Bearer $token', // Add token here
// 'Content-Type': 'application/json',
// },
// );
//
// if (response.statusCode == 200) {
// final Map<String, dynamic>? resData = json.decode(response.body);
//
// return resData?["data"];
// } else {
// throw Exception('Failed to load plans');
// }
// }
//
// void viewPlan(String planId, {bool isViewMode = false}) async {
// try {
// Map<String, dynamic> planData = await getViewPlan(planId);
// print("ViewAAA - $planData");
//
// context.go('/createPlan',
// extra: {'planData': planData, 'isViewMode': isViewMode});
// } catch (e) {
// print("Error fetching plan: $e");
// }
// }
void deletePlan(String planId) async {
try {
Map<String, dynamic> planData = await getViewPlan(planId);
Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
print("ViewAAA - $planData");
postPlanData(planData, planId);
@ -257,7 +260,7 @@ class _ListPlansState extends State<ListPlans> {
String _formatDate(String rawDate) {
try {
final dateTime = DateTime.parse(rawDate);
return DateFormat('dd MMM yy : hh a').format(dateTime);
return DateFormat('dd MMM yy hh:m a').format(dateTime);
} catch (e) {
return rawDate; // fallback if parsing fails
}
@ -607,12 +610,14 @@ class _ListPlansState extends State<ListPlans> {
color: Color(0xFF475569),
size: 18,
),
onPressed: () => viewPlan(plan.planId,
onPressed: () => ApiService.viewPlan(
context, plan.planId,
isViewMode: true)),
GestureDetector(
onTap: () =>
viewPlan(plan.planId, isViewMode: false),
onTap: () => ApiService.viewPlan(
context, plan.planId,
isViewMode: false),
child: Image.asset(
'assets/images/IconsImg/edit.png',
width: 20,

View File

@ -2917,7 +2917,7 @@ class _CreateUserFormState extends State<CreateUserForm> {
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
),
onPressed: () {
isEditProfile ? context.go('/home') : context.go('/listUser');
isEditProfile ? context.go('/listPlan') : context.go('/listUser');
},
child: isEditProfile ? Text("Back") : Text("Cancel")),
SizedBox(

View File

@ -282,7 +282,7 @@ class _CustomDrawerState extends State<CustomDrawer> {
],
),
),
_buildDrawerItem(context, Icons.home_outlined, 'Home', '/home'),
// _buildDrawerItem(context, Icons.home_outlined, 'Home', '/home'),
_buildDrawerItem(context, Icons.request_page_outlined,
'My Travel Request', '/listPlan'),
_buildDrawerItem(context, Icons.assessment_outlined, 'My Approvals',

View File

@ -1,5 +1,7 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:frontend/utils/auth_utils.dart';
import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http;
import '../../config/apiUrl.dart';
@ -346,21 +348,56 @@ class ApiService {
}
}
Future<Map<String, dynamic>> getViewPlan(
String planId, List plansJson) async {
static Future<Map<String, dynamic>> getViewPlan(String planId) async {
final String apiUrldata = '$apiUrl/api/plans/find/$planId';
print("API URL: $apiUrldata");
// final token = await getToken();
final token = await getToken();
final response = await http.put(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token', // Add token here
'Content-Type': 'application/json',
},
);
if (response.statusCode == 200) {
final Map<String, dynamic>? resData = json.decode(response.body);
return resData?["data"];
} else {
throw Exception('Failed to load plans');
}
}
static Future<void> viewPlan(BuildContext context, String planId,
{bool isViewMode = false}) async {
try {
final plan = plansJson.firstWhere(
(item) => item["plan_id"].toString() == planId,
orElse: () => null,
);
Map<String, dynamic> planData = await getViewPlan(planId);
print("ViewAAA - $planData");
if (plan == null) {
throw Exception("Plan with ID $planId not found.");
}
return Map<String, dynamic>.from(plan);
context.go('/createPlan',
extra: {'planData': planData, 'isViewMode': isViewMode});
} catch (e) {
throw Exception("Error finding plan: $e");
print("Error fetching plan: $e");
}
}
static Future<void> viewPlanForApprover(BuildContext context, String planId,
{bool isViewMode = false, bool isApprover = true}) async {
try {
Map<String, dynamic> planData = await getViewPlan(planId);
print("ViewAAA - $planData");
context.replace('/createPlan', extra: {
'planData': planData,
'isViewMode': isViewMode,
'isApprover': isApprover
});
} catch (e) {
print("Error fetching plan: $e");
}
}