From c49d85bb0f14b05930927a716a2c8b26c1634784 Mon Sep 17 00:00:00 2001 From: Ethan-clay03 <ethanclay2017@gmail.com> Date: Mon, 27 Jan 2025 13:19:54 +0000 Subject: [PATCH] Begin to correctly move get bookings from api to admin and add hidden id to edit/delete buttons to allow for correct row editing --- app/admin/routes.py | 48 ++++++++++++++- app/api/routes.py | 48 --------------- app/templates/admin/manage_bookings.html | 75 ++++++++++++++++++++---- 3 files changed, 111 insertions(+), 60 deletions(-) diff --git a/app/admin/routes.py b/app/admin/routes.py index 1b0a039..bfb17ee 100644 --- a/app/admin/routes.py +++ b/app/admin/routes.py @@ -26,4 +26,50 @@ def manage_users(): @bp.route('/manage_user_bookings') @permission_required(admin_permission) def manage_user_bookings(): - return render_template('admin/index.html') \ No newline at end of file + return render_template('admin/index.html') + + +@bp.route('get_bookings', methods=['GET']) +@permission_required(super_admin_permission) +def get_bookings(): + query = db.session.query(Listings) + + depart_location = request.args.get('depart_location') + destination_location = request.args.get('destination_location') + depart_before_time = request.args.get('depart_before_time') + arrive_after_time = request.args.get('arrive_after_time') + min_fair_cost = request.args.get('min_fair_cost') + max_fair_cost = request.args.get('max_fair_cost') + transport_type = request.args.get('transport_type') + + if depart_location: + depart_locations = depart_location.split(',') + query = query.filter(Listings.depart_location.in_(depart_locations)) + if destination_location: + destination_locations = destination_location.split(',') + query = query.filter(Listings.destination_location.in_(destination_locations)) + if depart_before_time: + query = query.filter(Listings.depart_time <= depart_before_time) + if arrive_after_time: + query = query.filter(Listings.destination_time >= arrive_after_time) + if min_fair_cost: + query = query.filter(Listings.fair_cost >= min_fair_cost) + if max_fair_cost: + query = query.filter(Listings.fair_cost <= max_fair_cost) + if transport_type: + query = query.filter(Listings.transport_type == transport_type) + + filtered_data = query.all() + result = [ + { + 'id': listing.id, + 'depart_location': listing.depart_location, + 'depart_time': listing.depart_time.strftime("%H:%M"), + 'destination_location': listing.destination_location, + 'destination_time': listing.destination_time.strftime("%H:%M"), + 'fair_cost': listing.fair_cost, + 'transport_type': listing.transport_type + } for listing in filtered_data + ] + + return jsonify(result) diff --git a/app/api/routes.py b/app/api/routes.py index 5a89cef..8a37a83 100644 --- a/app/api/routes.py +++ b/app/api/routes.py @@ -86,51 +86,3 @@ def create_listing(): except Exception as e: return jsonify({'error': str(e)}), 500 -# Sample data -data = [ - {"depart_location": "Tiger Nixon", "depart_time": "System Architect", "destination_location": "Edinburgh", "destination_time": 61, "fair_cost": "2011-04-25", "transport_type": "$320,800"}, -] - -@bp.route('get_data', methods=['GET']) -@permission_required(super_admin_permission) -def get_data(): - query = db.session.query(Listings) - - depart_location = request.args.get('depart_location') - destination_location = request.args.get('destination_location') - depart_before_time = request.args.get('depart_before_time') - arrive_after_time = request.args.get('arrive_after_time') - min_fair_cost = request.args.get('min_fair_cost') - max_fair_cost = request.args.get('max_fair_cost') - transport_type = request.args.get('transport_type') - - if depart_location: - depart_locations = depart_location.split(',') - query = query.filter(Listings.depart_location.in_(depart_locations)) - if destination_location: - destination_locations = destination_location.split(',') - query = query.filter(Listings.destination_location.in_(destination_locations)) - if depart_before_time: - query = query.filter(Listings.depart_time <= depart_before_time) - if arrive_after_time: - query = query.filter(Listings.destination_time >= arrive_after_time) - if min_fair_cost: - query = query.filter(Listings.fair_cost >= min_fair_cost) - if max_fair_cost: - query = query.filter(Listings.fair_cost <= max_fair_cost) - if transport_type: - query = query.filter(Listings.transport_type == transport_type) - - filtered_data = query.all() - result = [ - { - 'depart_location': listing.depart_location, - 'depart_time': listing.depart_time.strftime("%H:%M"), - 'destination_location': listing.destination_location, - 'destination_time': listing.destination_time.strftime("%H:%M"), - 'fair_cost': listing.fair_cost, - 'transport_type': listing.transport_type - } for listing in filtered_data - ] - - return jsonify(result) diff --git a/app/templates/admin/manage_bookings.html b/app/templates/admin/manage_bookings.html index ee7f0a2..c25e690 100644 --- a/app/templates/admin/manage_bookings.html +++ b/app/templates/admin/manage_bookings.html @@ -66,6 +66,7 @@ <table id="manage_bookings" class="table table-striped table-bordered display hover" style="width:100%"> <thead> <tr> + <th>Id</th> <th>Depart Location</th> <th>Depart Time</th> <th>Destination Location</th> @@ -79,6 +80,26 @@ </tbody> </table> </div> + <!-- Include this modal in your HTML code --> +<div class="modal fade" id="confirm_booking_deletion" tabindex="-1"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="confirm_booking_deletion">Confirm Deletion</h5> + <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> + </div> + <div class="modal-body"> + <p>Type 'CONFIRM' to delete this entry:</p> + <input type="text" id="conifrmation_input" class="form-control"> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button> + <button type="button" class="btn btn-primary" id="confirm_deletion_button">Delete</button> + </div> + </div> + </div> +</div> + </div> <style> .table-container { @@ -115,7 +136,7 @@ minimumResultsForSearch: Infinity }); - const timeOptions = [ + const time_options = [ "00:00", "00:30", "01:00", "01:30", "02:00", "02:30", "03:00", "03:30", "04:00", "04:30", "05:00", "05:30", "06:00", "06:30", "07:00", "07:30", "08:00", "08:30", "09:00", "09:30", "10:00", "10:30", "11:00", "11:30", "12:00", "12:30", "13:00", "13:30", "14:00", "14:30", @@ -123,25 +144,27 @@ "20:00", "20:30", "21:00", "21:30", "22:00", "22:30", "23:00", "23:30" ]; - timeOptions.forEach(time => { + // Add time_options to filter elements + time_options.forEach(time => { $('#depart_before_time').append(new Option(time, time)); $('#arrive_after_time').append(new Option(time, time)); }); + // Populate location options, TO UPDATE WITH LIVE LOCATIONS const locations = ['USA', 'Budapest', 'Location3'].sort(); locations.forEach(location => { $('#depart_location').append(new Option(location, location)); $('#destination_location').append(new Option(location, location)); }); - // Load data table + // Load table const table = $('#manage_bookings').DataTable({ pageLength: 10, lengthChange: false, searching: false, ordering: false, ajax: { - url: "{{ url_for('api.get_data') }}", + url: "{{ url_for('admin.get_bookings') }}", dataSrc: '', data: function(d) { d.depart_location = $('#depart_location').val() ? $('#depart_location').val().join(',') : ''; @@ -150,10 +173,11 @@ d.arrive_after_time = $('#arrive_after_time').val(); d.min_fair_cost = $('#min_fair_cost').val(); d.max_fair_cost = $('#max_fair_cost').val(); - d.transport_type = 'Airplane'; //Hardcoded cause not offering other transport types currently + d.transport_type = 'Airplane'; // Hardcoded for now } }, columns: [ + { data: 'id', visible: false }, // Hidden id column { data: 'depart_location' }, { data: 'depart_time' }, { data: 'destination_location' }, @@ -177,29 +201,58 @@ ], language: { emptyTable: "No bookings could be found with the current filters" + }, + createdRow: function(row, data, dataIndex) { //Attach ID to edit/delete buttons for use in modifying individual enteries + $(row).find('.edit-btn').attr('data-id', data.id); + $(row).find('.delete-btn').attr('data-id', data.id); } }); - // Apply filters and reload table + // Apply filters and show updated results $('#apply-filters').on('click', function() { table.ajax.reload(); $('#filterModal').modal('hide'); }); - // Edit and Delete buttons functionality $('#manage_bookings tbody').on('click', '.edit-btn', function() { + const id = $(this).data('id'); const data = table.row($(this).parents('tr')).data(); - alert('Edit entry for ' + data.depart_location); + alert('Edit entry for ' + data.depart_location + ' with ID ' + id); }); + let delete_booking; $('#manage_bookings tbody').on('click', '.delete-btn', function() { - const data = table.row($(this).parents('tr')).data(); - alert('Delete entry for ' + data.depart_location); + delete_booking = table.row($(this).parents('tr')); + $('#confirm_booking_deletion').modal('show'); }); - }); + $('#confirm_deletion_button').on('click', function() { + const confirmation_input = $('#conifrmation_input').val().trim(); + if (confirmation_input === 'CONFIRM') { + $.ajax({ + url: "{{ url_for('admin.get_bookings') }}", // TO CHANGE + method: "DELETE", + data: { id: delete_booking.data().id }, + success: function() { + delete_booking.remove().draw(); + $('#confirm_booking_deletion').modal('hide'); + }, + error: function() { + alert('Failed to delete the booking. Please try again.'); + } + }); + } else { + alert('Please type "CONFIRM" to delete the entry.'); + } + }); + $('#confirm_booking_deletion').on('hidden.bs.modal', function () { + $('#conifrmation_input').val(''); + }); + }); </script> + + {% endblock %} -- GitLab