ts-tat/lib/Screens/myTemplates/Tempale
2025-06-02 15:13:28 +05:30

563 lines
17 KiB
Plaintext

import 'dart:convert';
import 'dart:io' as io show Directory, File;
import 'package:flutter/cupertino.dart' as dom;
import 'package:flutter_quill/flutter_quill.dart' hide Text;
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart' hide Text;
import 'package:flutter_quill/quill_delta.dart';
import 'package:flutter_quill_delta_from_html/flutter_quill_delta_from_html.dart';
import 'package:vsc_quill_delta_to_html/vsc_quill_delta_to_html.dart';
import 'package:flutter_quill/flutter_quill.dart' as quill;
import 'package:html/parser.dart' show parse;
import 'package:html/dom.dart' as dom hide Element;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_quill/flutter_quill_internal.dart';
import 'package:flutter_quill/quill_delta.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
import 'package:responsive_builder/responsive_builder.dart';
import '../../config/apiUrl.dart';
import '../../routes/custom_appBar.dart';
import '../../routes/custom_drawer.dart';
import '../../services/apiService.dart';
import '../../utils/auth_utils.dart';
import '../../widgets/custom_user_travel.dart';
class Template extends StatefulWidget {
final Map<String, dynamic>? templateData;
const Template({super.key, required this.templateData});
static Template fromState(GoRouterState state) {
return Template(templateData: state.extra as Map<String, dynamic>?);
}
@override
TemplateState createState() => TemplateState();
}
class TemplateState extends State<Template> {
final ApiService apiService = ApiService();
// final QuillController _controller = QuillController.basic();
String? orgId;
String? userId;
Color layoutColor = Colors.redAccent;
Color bodyColor = Colors.white;
final Map<String, TextEditingController> controllers = {};
List<String> dataHeader = ["subject"];
List<String> placeholders = [];
late QuillController _controller = QuillController.basic();
final FocusNode _focusNode = FocusNode();
late int templateId = 0;
late String templateName = "";
late List<Map<String, dynamic>> placeholderList = [];
Map<String, dynamic> get TemplateData {
final data = {
"org_id": orgId,
// "template_id": templateId,
// "template_name": controllers["templateName"]?.text,
"template_id": templateId,
"template_name": templateName,
"subject": controllers["subject"]?.text,
"body_html": jsonEncode(_controller.document.toDelta().toJson()),
// "body_html": _controller,
// "body_html": convertQuillDocToHtml(_controller.document),
// ✅ convert delta to HTML
"placeholder": jsonEncode(placeholderList),
// "created_by": userId
};
// Only add group_id if it's an edit operation
// if (widget.templateData != null && widget.templateData!.containsKey('group_id')) {
// data["template_id"] = templateData;
// }
return data;
}
@override
void initState() {
super.initState();
for (var field in dataHeader) {
controllers[field] = TextEditingController();
}
updateData();
loadinitializeData();
loadInitialData();
}
@override
// void dispose() {
// // controllers.dispose();
// // _editorScrollController.dispose();
// _editorFocusNode.dispose();
// super.dispose();
// }
void loadinitializeData() async {
orgId = await getOrgId();
userId = await getUserId();
}
void loadInitialData() async {
String? layoutString = await getLayoutColor();
String? bodyStringColor = await getBodyColor();
setState(() {
layoutColor =
layoutString != null
? Color(int.parse(layoutString))
: Colors.redAccent;
bodyColor =
bodyStringColor != null
? Color(int.parse(bodyStringColor))
: Colors.white;
});
}
// String convertQuillDocToHtml(quill.Document doc) {
// final buffer = StringBuffer();
//
// print("convertQuillDocToHtml");
// for (final op in doc.toDelta().toList()) {
// final insert = op.data;
// final attrs = op.attributes ?? {};
//
// if (insert is String) {
// var content = insert;
//
// // Handle formatting (bold, italic, etc.)
// if (attrs.containsKey('bold')) {
// content = '<strong>$content</strong>';
// }
// if (attrs.containsKey('italic')) {
// content = '<em>$content</em>';
// }
//
// // Wrap each paragraph with <p>
// if (content.trim().isNotEmpty) {
// buffer.write('<p>${content.trim()}</p>');
// }
// }
// }
//
// return buffer.toString();
// }
//
// String convertQuillDocToHtml2(quill.Document doc) {
// final buffer = StringBuffer();
// final lines = <String>[];
// final delta = doc.toDelta();
//
// String applyStyles(String text, Map<String, dynamic>? attrs) {
// if (attrs == null) return text;
// if (attrs.containsKey('bold')) {
// text = '<strong>$text</strong>';
// }
// if (attrs.containsKey('italic')) {
// text = '<em>$text</em>';
// }
// return text;
// }
//
// for (final op in delta.toList()) {
// final insert = op.data;
// final attrs = op.attributes;
//
// if (insert is String) {
// final parts = insert.split('\n');
// for (int i = 0; i < parts.length; i++) {
// final part = applyStyles(parts[i], attrs);
// lines.add(part);
//
// if (i < parts.length - 1) {
// // End of line: wrap accumulated content into <p>
// final joined = lines.join('');
// if (joined.trim().isNotEmpty) {
// buffer.writeln('<p>${joined.trim()}</p>');
// }
// lines.clear();
// }
// }
// }
// }
//
// // Add remaining lines
// final joined = lines.join('');
// if (joined.trim().isNotEmpty) {
// buffer.writeln('<p>${joined.trim()}</p>');
// }
//
// return buffer.toString();
// }
//
// String extractPlainTextFromHtml(String html) {
// final regex = RegExp(r'<p>(.*?)<\/p>', multiLine: true, dotAll: true);
// final matches = regex.allMatches(html);
//
// final buffer = StringBuffer();
// for (final match in matches) {
// final text = match.group(1)?.replaceAll(RegExp(r'<[^>]*>'), '') ?? '';
// buffer.writeln(text.trim());
// }
// return buffer.toString();
// }
//
// String decodeHtmlEntities(String text) {
// return text
// .replaceAll('&nbsp;', ' ')
// .replaceAll('&amp;', '&')
// .replaceAll('&lt;', '<')
// .replaceAll('&gt;', '>')
// .replaceAll('&quot;', '"')
// .replaceAll('&#39;', "'"); // add more as needed
// }
Future<void> updateData() async {
// Ensure apiselectedUser is not null before printing
if (widget.templateData != null) {
print("API Selected User Has Data - ${widget.templateData}");
print(
"API Selected User Has - ${widget.templateData?["templateData"]?["subject"]}",
);
setState(() {
// ✅ Wrap in setState to update the UI
controllers["templateName"]?.text =
widget.templateData?["templateData"]?["template_name"] ?? "";
controllers["subject"]?.text =
widget.templateData?["templateData"]?["subject"] ?? "";
final bodyHtml =
widget.templateData?["templateData"]?["body_html"] ?? "";
print("bodyHtml - $bodyHtml");
// /*inal converter = DeltaFromHTML();
// final delta = converter.convert(bodyHtml); // Convert HTML → Delta
// final quillDoc = quill.Document.fromDelta(delta);
// */
// final plainText = extractPlainTextFromHtml(bodyHtml);
// final decodedText = decodeHtmlEntities(plainText);
//
// final quillDoc = quill.Document()..insert(0, decodedText);
// // final quillDoc = convertBasicHtmlToQuill(bodyHtml);
// // final quillDoc = quill.Document()..insert(0, plainText);
// // final quillDoc = quill.Document.fromDelta(delta);
// _controller = quill.QuillController(
// document: quillDoc,
// selection: const TextSelection.collapsed(offset: 0),
// );
final deltaJsonString =
widget.templateData?["templateData"]?["body_delta"];
if (deltaJsonString != null) {
final deltaJson = jsonDecode(deltaJsonString);
final quillDoc = quill.Document.fromJson(deltaJson);
_controller = quill.QuillController(
document: quillDoc,
selection: const TextSelection.collapsed(offset: 0),
);
}
templateName =
widget.templateData?["templateData"]?["template_name"] ?? "";
print("Fetched template_name: $templateName");
final rawPlaceholder =
widget.templateData?["templateData"]?["placeholder"];
if (rawPlaceholder is String) {
// If it's a JSON string, decode it first
placeholderList = List<Map<String, dynamic>>.from(
jsonDecode(rawPlaceholder),
);
} else if (rawPlaceholder is List) {
// If it's already a list (ideal case)
placeholderList = List<Map<String, dynamic>>.from(rawPlaceholder);
}
print("Extracted placeholders: $placeholders");
print("Fetched placeholders: $placeholderList");
templateId =
int.tryParse(
widget.templateData?["templateData"]?["template_id"]
?.toString() ??
'0',
) ??
0;
print("Fetched template_id: $templateId");
// if (widget.group?["international_policy_id"] != null) {
// selectedInternational =
// widget.group!["international_policy_id"].toString();
// }
});
} else {
print("API Selected User Has Data - No data available yet");
}
}
Future<void> handleSubmit() async {
Map<String, dynamic> data = TemplateData;
setState(() {
// updateTemplateData(data);
// This triggers UI rebuild with error messages
// if (validateData()) {
// postGroupData();
// }
});
final TemplateData1 = TemplateData;
print("TemplateData - $TemplateData1");
}
Future<void> updateTemplateData(Map<String, dynamic> policyData) async {
final String apiUrldata = '$apiUrl/api/template/update/${templateId}';
final token = await getToken(); // Fetch token
if (token == null) {
throw Exception('Token not found. Please log in.');
}
try {
final response = await http.put(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
body: jsonEncode(policyData), // Convert map to JSON
);
if (response.statusCode == 200) {
print("policyData submitted successfully!");
print("Response: ${response.body}");
context.go('/templateList');
} else {
print("Failed to submit policyData. Status: ${response.statusCode}");
print("Error: ${response.body}");
}
} catch (e) {
print(" Error submitting policyData: $e");
}
}
@override
Widget build(BuildContext context) {
return ResponsiveBuilder(
builder: (context, sizingInfo) {
bool isDesktop =
sizingInfo.deviceScreenType == DeviceScreenType.desktop;
return Scaffold(
backgroundColor: const Color(0xFFf5f5f5),
appBar: CustomAppBar(isDesktop: isDesktop),
drawer: CustomDrawer(isDesktop: false),
body: Padding(
padding:
isDesktop
? EdgeInsets.symmetric(
horizontal:
MediaQuery.of(context).size.width *
0.1, // 30% of screen width as horizontal padding
vertical:
MediaQuery.of(context).size.height *
0, // 5% of screen height as vertical padding
)
: EdgeInsets.all(0),
child: Row(
children: [
// if (isDesktop) CustomDrawer(isDesktop: true),
Expanded(
child: buildUserTable(
isDesktop,
context,
bodyColor,
layoutColor,
),
),
],
),
),
);
},
);
}
Widget buildUserTable(
bool isDesktop,
context,
Color? bodyColor,
Color layoutColor,
) {
return Container(
margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null,
padding: const EdgeInsets.all(28),
decoration: BoxDecoration(
color: isDesktop ? Colors.white : Color(0xFFFCFCFC),
),
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Editor"),
SizedBox(height: 10),
buildTempalteSubject(isDesktop),
SizedBox(height: 10),
buildTempalteBody(isDesktop),
Spacer(),
buildActions(isDesktop),
],
),
),
);
}
Widget buildTempalteSubject(bool isDesktop) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Subject",
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w400,
color: Colors.black,
),
),
SizedBox(height: 5),
CustomTextFieldUserTravellerWrapper(
isFocused: false,
isDesktop: isDesktop,
child: SizedBox(
height: 40,
child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
controller: controllers["subject"],
onChanged: (value) {
// _clearError("local_id_num");
},
decoration: InputDecoration(
labelText: "enter the subject",
labelStyle: GoogleFonts.poppins(
fontSize: 12,
color: Colors.grey,
),
floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16),
),
),
),
),
],
);
}
Widget buildTempalteBody(bool isDesktop) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Content",
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w400,
color: Colors.black,
),
),
const SizedBox(height: 10),
Container(child: QuillSimpleToolbar(controller: _controller)),
const SizedBox(height: 10),
Container(
padding: const EdgeInsets.all(16),
height: 200,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8),
),
child: QuillEditor(
controller: _controller,
scrollController: ScrollController(),
focusNode: _focusNode,
),
),
],
);
}
Widget buildActions(bool isDesktop) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
child: ElevatedButton(
onPressed: () {
context.go('/templateList');
// You can get text from commentController.text
Navigator.of(context).pop(); // Close the modal
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
// backgroundColor: widget.layoutColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: Text(
'Cancel',
style: GoogleFonts.poppins(fontSize: 13, color: Colors.white),
),
),
),
SizedBox(width: 10),
SizedBox(
child: ElevatedButton(
onPressed: () {
handleSubmit();
// You can get text from commentController.text
// Navigator.of(context).pop(); // Close the modal
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
// backgroundColor: widget.layoutColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: Text(
'Save',
style: GoogleFonts.poppins(fontSize: 13, color: Colors.white),
),
),
),
],
);
}
}