base_project

This commit is contained in:
2026-09-19 03:57:06 +00:00
commit e497faa322
1528 changed files with 79821 additions and 0 deletions
@@ -0,0 +1,106 @@
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';
import 'dart:typed_data';
import 'dart:convert';
import '../../resources/api_constants.dart';
import '../LogoutService/Logoutservice.dart';
class ApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
Future<List<Map<String, dynamic>>> getEntities(String token) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/Bookmarks/Bookmarks');
if (response.statusCode == 401) {
LogoutService.logout();
}
final entities = (response.data as List).cast<Map<String, dynamic>>();
return entities;
} catch (e) {
throw Exception('Failed to get all entities: $e');
}
}
Future<void> createEntity(
String token, Map<String, dynamic> fData, dynamic selectedFile) async {
try {
String apiUrl = "$baseUrl/Bookmarks/Bookmarks";
final Uint8List fileBytes = selectedFile.bytes!;
final mimeType = lookupMimeType(selectedFile.name!);
FormData formData = FormData.fromMap({
'file': MultipartFile.fromBytes(
fileBytes,
filename: selectedFile.name!,
contentType: MediaType.parse(mimeType!),
),
'data': jsonEncode(
fData), // Convert the map to JSON and include it as a parameter
});
Dio dio = Dio(); // Create a new Dio instance
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.post(apiUrl, data: formData);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode == 200) {
// Handle successful response
print('File uploaded successfully');
} else {
print('Failed to upload file with status: ${response.statusCode}');
}
} catch (error) {
print('Error occurred during form submission: $error');
}
}
String lookupMimeType(String filePath) {
final ext = filePath.split('.').last;
switch (ext) {
case 'jpg':
case 'jpeg':
return 'image/jpeg';
case 'png':
return 'image/png';
case 'pdf':
return 'application/pdf';
// Add more cases for other file types as needed
default:
return 'application/octet-stream'; // Default MIME type
}
}
Future<void> updateEntity(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response =
await dio.put('$baseUrl/Bookmarks/Bookmarks/$entityId', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to update entity: $e');
}
}
Future<void> deleteEntity(String token, int entityId) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio.delete('$baseUrl/Bookmarks/Bookmarks/$entityId');
if (response.statusCode == 401) {
LogoutService.logout();
}
} catch (e) {
throw Exception('Failed to delete entity: $e');
}
}
}
@@ -0,0 +1,111 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../providers/token_manager.dart';
import 'Bookmarks_api_service.dart';
class CreateEntityScreen extends StatefulWidget {
const CreateEntityScreen({super.key});
@override
_CreateEntityScreenState createState() => _CreateEntityScreenState();
}
class _CreateEntityScreenState extends State<CreateEntityScreen> {
final ApiService apiService = ApiService();
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
var selectedFileupload_Field;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Create Bookmarks')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration:
const InputDecoration(labelText: 'bookmark_firstletter'),
onSaved: (value) => formData['bookmark_firstletter'] = value,
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'bookmark_link'),
onSaved: (value) => formData['bookmark_link'] = value,
),
const SizedBox(height: 16),
TextFormField(
decoration:
const InputDecoration(labelText: 'fileupload_field'),
onSaved: (value) => formData['fileupload_field'] = value,
),
const SizedBox(height: 16),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
final token = await TokenManager.getToken();
try {
print("token is : $token");
print(formData);
await apiService.createEntity(
token!, formData, selectedFileupload_Field);
Navigator.pop(context);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to create entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
},
child: Container(
width: double.infinity,
height: 50,
child: const Center(
child: Text(
'SUBMIT',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
],
),
),
),
),
);
}
}
@@ -0,0 +1,562 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../theme/app_decoration.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import 'Bookmarks_api_service.dart';
import 'package:url_launcher/url_launcher.dart';
class bookmarks_entity_list_screen extends StatefulWidget {
static const String routeName = '/entity-list';
@override
_bookmarks_entity_list_screenState createState() =>
_bookmarks_entity_list_screenState();
}
class _bookmarks_entity_list_screenState
extends State<bookmarks_entity_list_screen> {
final ApiService apiService = ApiService();
List<Map<String, dynamic>> entities = [];
bool showCardView = true; // Add this variable to control the view mode
@override
void initState() {
super.initState();
fetchEntities();
}
Future<void> fetchEntities() async {
try {
final token = await TokenManager.getToken();
if (token != null) {
final fetchedEntities = await apiService.getEntities(token);
setState(() {
entities = fetchedEntities;
});
}
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to fetch entities: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
Future<void> deleteEntity(Map<String, dynamic> entity) async {
try {
final token = await TokenManager.getToken();
await apiService.deleteEntity(token!, entity['id']);
setState(() {
entities.remove(entity);
});
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to delete entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Bookmarks")),
body: entities.isEmpty
? const Center(
child: Text('No BookMarks found.'),
)
: Container(
width: double.maxFinite,
padding: getPadding(left: 16, top: 16, right: 16, bottom: 16),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: getPadding(top: 22),
child: entities.length != 0
? ListView.separated(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
separatorBuilder: (context, index) {
return SizedBox(height: getVerticalSize(24));
},
itemCount: entities.length,
itemBuilder: (context, index) {
Map<String, dynamic> entity = entities[index];
return Container(
width: double.maxFinite,
child: Container(
padding: getPadding(
left: 16,
top: 5,
right: 5,
bottom: 17,
),
decoration: AppDecoration.outlineGray70011
.copyWith(
borderRadius: BorderRadiusStyle
.roundedBorder6,
color: Colors.grey[100]),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Padding(
padding: getPadding(
//right: 13,
),
child: Row(
children: [
Container(
width: MediaQuery.of(context)
.size
.width *
0.30,
// getHorizontalSize(
// 147,
// ),
margin: getMargin(
left: 8,
top: 3,
bottom: 1,
),
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
entity['bookmark_firstletter'] ??
'No bookmark_firstletter provided',
overflow: TextOverflow
.ellipsis,
textAlign:
TextAlign.left,
style: AppStyle
.txtGreenSemiBold16,
),
],
),
),
Spacer(),
// PopupMenuButton<String>(
// icon: Icon(Icons.more_vert,color: Colors.black,size: 16,),
// itemBuilder: (BuildContext context) {
// return [
// PopupMenuItem<String>(
// value: 'edit',
// child: Row(
// children: [
// Icon(
// Icons.edit,
// size: 16, // Adjust the icon size as needed
// ),
// SizedBox(width: 8),
// Text(
// 'Edit',
// style: AppStyle.txtGilroySemiBold16, // Adjust the text size as needed
// ),
// ],
// ),
// ),
// PopupMenuItem<String>(
// value: 'delete',
// child: Row(
// children: [
// Icon(
// Icons.delete,
// size: 16, // Adjust the icon size as needed
// ),
// SizedBox(width: 8),
// Text(
// 'Delete',
// style: AppStyle.txtGilroySemiBold16, // Adjust the text size as needed
// ),
// ],
// ),
// ),
// ];
// },
// onSelected: (String value) {
// if (value == 'edit') {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => UpdateDatabseScreen(
// projectId: widget.projectId,
// entity: entity,
// ),
// ),
// ).then((_) {
// fetchEntities();
// });
// } else if (value == 'delete') {
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return AlertDialog(
// title: const Text('Confirm Deletion'),
// content: const Text('Are you sure you want to delete?'),
// actions: [
// TextButton(
// child: const Text('Cancel'),
// onPressed: () {
// Navigator.of(context).pop();
// },
// ),
// TextButton(
// child: const Text('Delete'),
// onPressed: () {
// Navigator.of(context).pop();
// deleteEntity(entity, context).then((value) => {
// fetchEntities()
// });
// },
// ),
// ],
// );
// },
// );
// }
// },
// ),
],
),
),
Padding(
padding: getPadding(
top: 10,
),
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
'BookMark Link',
overflow:
TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800,
),
GestureDetector(
onTap: () {
_launchURL(entity[
'bookmark_link']);
},
child: Text(
entity['bookmark_link'] ??
'No bookmark_link provided',
overflow:
TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Green600,
),
)
],
),
),
],
),
),
);
})
: Container(
height: MediaQuery.of(context).size.height,
child: const Center(
child: Text("No Databases available"),
)),
)
]))
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => const CreateEntityScreen(),
// ),
// ).then((_) {
// fetchEntities();
// });
// },
// child: const Icon(Icons.add),
// ),
);
}
// Function to build list items
Widget _buildListItem(Map<String, dynamic> entity) {
return showCardView ? _buildCardView(entity) : _buildNormalView(entity);
}
// Function to build card view for a list item
Widget _buildCardView(Map<String, dynamic> entity) {
return Card(
elevation: 2,
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: _buildNormalView(entity));
}
// Function to build normal view for a list item
// Widget _buildNormalView(Map<String, dynamic> entity) {
// return ListTile(
// title: Text(entity['id'].toString()),
// subtitle: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
//
// Text(entity['bookmark_firstletter'] ?? 'No bookmark_firstletter provided'),
// const SizedBox(height: 4),
// Text(entity['bookmark_link'] ?? 'No bookmark_link provided'),
// const SizedBox(height: 4),
// Text(entity['fileupload_field'] ?? 'No fileupload_field provided'),
// const SizedBox(height: 4), // Added address text
// ],
//
// ),
// trailing: _buildPopupMenu(entity),
// onTap: () {
// _showAdditionalFieldsDialog(context, entity);
// },
// );
// }
Widget _buildNormalView(Map<String, dynamic> entity) {
return ListTile(
title: Text(entity['id'].toString()),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(entity['bookmark_firstletter'] ??
'No bookmark_firstletter provided'),
const SizedBox(height: 4),
GestureDetector(
onTap: () {
_launchURL(entity['bookmark_link']);
},
child: Text(
entity['bookmark_link'] ?? 'No bookmark_link provided',
style: TextStyle(
color:
Colors.blue, // Change the color to make it look like a link
decoration: TextDecoration.underline, // Underline the link
),
),
),
const SizedBox(height: 4),
Text(entity['fileupload_field'] ?? 'No fileupload_field provided'),
const SizedBox(height: 4),
// Added address text
],
),
// trailing: _buildPopupMenu(entity),
// onTap: () {
// _showAdditionalFieldsDialog(context, entity);
// },
);
}
// Function to launch a URL in the browser
Future<void> _launchURL(String? url) async {
if (url != null) {
try {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to launch URL: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
}
// // Function to build popup menu for a list item
// Widget _buildPopupMenu(Map<String, dynamic> entity) {
// return PopupMenuButton<String>(
// itemBuilder: (BuildContext context) {
// return [
// const PopupMenuItem<String>(
// value: 'edit',
// child: Row(
// children: [
// Icon(Icons.edit),
// SizedBox(width: 8),
// Text('Edit'),
// ],
// ),
// ),
// const PopupMenuItem<String>(
// value: 'delete',
// child: Row(
// children: [
// Icon(Icons.delete),
// SizedBox(width: 8),
// Text('Delete'),
// ],
// ),
// ),
// ];
// },
// onSelected: (String value) {
// if (value == 'edit') {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => UpdateEntityScreen(entity: entity),
// ),
// ).then((_) {
// fetchEntities();
// });
// } else if (value == 'delete') {
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return AlertDialog(
// title: const Text('Confirm Deletion'),
// content:
// const Text('Are you sure you want to delete this entity?'),
// actions: [
// TextButton(
// child: const Text('Cancel'),
// onPressed: () {
// Navigator.of(context).pop();
// },
// ),
// TextButton(
// child: const Text('Delete'),
// onPressed: () {
// Navigator.of(context).pop();
// deleteEntity(entity);
// },
// ),
// ],
// );
// },
// );
// }
// },
// );
// }
// Function to show additional fields in a dialog
void _showAdditionalFieldsDialog(
BuildContext context,
Map<String, dynamic> entity,
) {
final dateFormat =
DateFormat('yyyy-MM-dd HH:mm:ss'); // Define your desired date format
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Additional Fields'),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Created At: ${_formatTimestamp(entity['createdAt'], dateFormat)}'),
Text('Created By: ${entity['createdBy'] ?? 'N/A'}'),
Text('Updated By: ${entity['updatedBy'] ?? 'N/A'}'),
Text(
'Updated At: ${_formatTimestamp(entity['updatedAt'], dateFormat)}'),
Text('Account ID: ${entity['accountId'] ?? 'N/A'}'),
],
),
actions: [
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
String _formatTimestamp(dynamic timestamp, DateFormat dateFormat) {
if (timestamp is int) {
// If it's an integer, assume it's a Unix timestamp in milliseconds
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
return dateFormat.format(dateTime);
} else if (timestamp is String) {
// If it's a string, assume it's already formatted as a date
return timestamp;
} else {
// Handle other cases here if needed
return 'N/A';
}
}
}
@@ -0,0 +1,140 @@
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:flutter/services.dart';
import '../../providers/token_manager.dart';
import 'Bookmarks_api_service.dart';
class UpdateEntityScreen extends StatefulWidget {
final Map<String, dynamic> entity;
UpdateEntityScreen({required this.entity});
@override
_UpdateEntityScreenState createState() => _UpdateEntityScreenState();
}
class _UpdateEntityScreenState extends State<UpdateEntityScreen> {
final ApiService apiService = ApiService();
final _formKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Update Bookmarks')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
initialValue: widget.entity['bookmark_firstletter'],
decoration:
const InputDecoration(labelText: 'bookmark_firstletter'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a bookmark_firstletter';
}
return null;
},
onSaved: (value) {
widget.entity['bookmark_firstletter'] = value;
},
),
const SizedBox(height: 16),
TextFormField(
initialValue: widget.entity['bookmark_link'],
decoration: const InputDecoration(labelText: 'bookmark_link'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a bookmark_link';
}
return null;
},
onSaved: (value) {
widget.entity['bookmark_link'] = value;
},
),
const SizedBox(height: 16),
TextFormField(
initialValue: widget.entity['fileupload_field'],
decoration:
const InputDecoration(labelText: 'fileupload_field'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a fileupload_field';
}
return null;
},
onSaved: (value) {
widget.entity['fileupload_field'] = value;
},
),
const SizedBox(height: 16),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
final token = await TokenManager.getToken();
try {
await apiService.updateEntity(
token!,
widget.entity[
'id'], // Assuming 'id' is the key in your entity map
widget.entity);
Navigator.pop(context);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to update entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
},
child: Container(
width: double.infinity,
height: 50,
child: const Center(
child: Text(
'UPDATE',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
],
),
),
),
),
);
}
}