diff --git a/app/bookings/routes.py b/app/bookings/routes.py index a26c015a3c3f3515e868a9d96077105728df5688..c032fc762f36335694648c1b113ffa4b9f344919 100644 --- a/app/bookings/routes.py +++ b/app/bookings/routes.py @@ -53,6 +53,21 @@ def listings(): } ) +@bp.route('/listing/apply_update', methods=['POST']) +def listing_apply_update(): + data = request.get_json() + if 'date' not in data: + return jsonify({'error': 'Invalid request'}), 400 + + depart_date = data['date'] + try: + discount, days_away = calculate_discount(depart_date) + return jsonify({'discount': discount, 'days_away': days_away}), 200 + + except ValueError: + error_logger.error("Invalid date format, the data passed was: " + data) + return jsonify({'error': 'Invalid date format'}), 400 + @bp.route('/show_listing/<int:id>', methods=['GET']) def show_listing_dirty(id): @@ -68,7 +83,12 @@ def listing(id): listing.depart_time = pretty_time(listing.depart_time) listing.destination_time = pretty_time(listing.destination_time) filter_data = session.pop('filter_data', None) - return render_template('bookings/listing.html', listing=listing, filter_data=filter_data) + + selected_date = filter_data['date'] if filter_data and 'date' in filter_data else None + discount, days_away = calculate_discount(selected_date) if selected_date else (0, 0) + + return render_template('bookings/listing.html', listing=listing, selected_date=selected_date, discount=discount, days_away=days_away) + @bp.route('/filter_bookings', methods=['POST']) def filter_bookings(): diff --git a/app/templates/bookings/listing.html b/app/templates/bookings/listing.html index 412fcc746ff5eaba5b47a10ee45259dcc0d2875a..e9d27c2aa95365af107cdf72b7b0b2107513bf2f 100644 --- a/app/templates/bookings/listing.html +++ b/app/templates/bookings/listing.html @@ -1,14 +1,14 @@ {% extends 'base.html' %} {% block content %} <div class="container mt-5"> - <div id="discountBanner" class="alert alert-success table" role="alert" style="width:90%; display: none;"> - Special Offer! Get <span id="discountPercent"></span>% off on your booking as you are booking <span id="daysAway"></span> days away! + <div id="discountBanner" class="alert alert-success" role="alert" style="display: {% if discount > 0 %}block{% else %}none{% endif %};"> + Special Offer! Get <span id="discountPercent">{{ discount }}</span>% off on your booking as you are booking <span id="daysAway">{{ days_away }}</span> days away! </div> <div class="date-container"> - <div class="col-md-6 text-start mb-3 d-flex align-items-center flex-md-nowrap flex-wrap" id="dateContainer"> + <div class="col-md-6 text-start mb-3 d-flex align-items-center flex-md-nowrap flex-wrap"> <label class="form-label me-2">Departure Date:</label> <div class="col-md-6"> - <input type="date" class="form-control" id="departDate" name="departDate" required> + <input type="date" class="form-control" id="departDate" name="departDate" required value="{{ selected_date or today }}"> </div> <button type="button" class="btn btn-warning ms-2" id="resetDate"> <i class="fa-solid fa-rotate-right"></i> Reset Date @@ -19,7 +19,7 @@ <i class="fa-solid fa-filter"></i> Filter </button> </div> - </div> + </div> <div class="row"> <div class="col-md-6"> <div class="card mb-4"> @@ -44,7 +44,10 @@ <div class="card-body"> <h2 class="card-title">Transport Information</h2> <p><strong>Transport Type:</strong> {{ listing.transport_type }}</p> - <p><strong>Price:</strong> £{{ listing.FairCost }}</p> + <p><strong>Price:</strong> £<span id="originalPrice">{{ listing.fair_cost }}</span></p> + <p id="discountedPrice" style="display: none;"> + <strong>Discounted Price:</strong> £<span id="discountedPriceValue"></span> + </p> </div> </div> <div class="text-center"> @@ -55,81 +58,86 @@ <div class="alert alert-warning mt-3" role="alert"> You must have an account in order to book. <div class="mt-2"> - <a href="{{ url_for('profile.login_book_cache') }}" class="btn btn-primary me-2">Login</a> - <a href="{{ url_for('profile.signup_book_cache') }}" class="btn btn-warning">Sign Up</a> + <a href="{{ url_for('profile.login', callback=request.path) }}" class="btn btn-primary me-2">Login</a> + <a href="{{ url_for('profile.signup', callback=request.path) }}" class="btn btn-warning">Sign Up</a> </div> </div> {% endif %} </div> - - </div> <script> - $(document).ready(function () { - const filterDataDepartDate = "{{ filter_data.date if filter_data else '' }}"; - const resetDateButton = document.getElementById('resetDate'); +$(document).ready(function () { + const filterDataDepartDate = "{{ selected_date if selected_date else '' }}"; + const resetDateButton = document.getElementById('resetDate'); + const today = new Date().toISOString().split('T')[0]; + const departDateInput = document.getElementById('departDate'); - const today = new Date().toISOString().split('T')[0]; - const departDateInput = document.getElementById('departDate'); + if (!filterDataDepartDate) { + departDateInput.value = today; + } else { + departDateInput.value = filterDataDepartDate; + } - if (!filterDataDepartDate) { - departDateInput.value = today; - } else { - departDateInput.value = filterDataDepartDate; - } + departDateInput.setAttribute('min', today); + let maxDate = new Date(); + maxDate.setDate(maxDate.getDate() + 90); + departDateInput.setAttribute('max', maxDate.toISOString().split('T')[0]); + // Reset date to today when the reset button is clicked + resetDateButton.addEventListener('click', () => { + departDateInput.value = today; + departDateInput.dispatchEvent(new Event('change')); + }); - departDateInput.setAttribute('min', today); - let maxDate = new Date(); - maxDate.setDate(maxDate.getDate() + 90); - departDateInput.setAttribute('max', maxDate.toISOString().split('T')[0]); + // Prevent any dates being changed by the user manually typing + departDateInput.addEventListener('keydown', (event) => { + event.preventDefault(); + }); - // Reset date to today when the reset button is clicked - resetDateButton.addEventListener('click', () => { - departDateInput.value = today; - }); + // Send the updated date to the server to check for discounts + departDateInput.addEventListener('change', (event) => { + const newDate = event.target.value; - // Open date picker when the date field is clicked - departDateInput.addEventListener('focus', (event) => { - event.preventDefault(); - departDateInput.showPicker(); - }); - - // Prevent any dates being changed by the user manually typing - departDateInput.addEventListener('keydown', (event) => { - event.preventDefault(); - }); + $.ajax({ + url: "{{ url_for('bookings.listing_apply_update') }}", + type: 'POST', + contentType: 'application/json', + data: JSON.stringify({ date: newDate }), + success: function (data) { + const discountBanner = document.getElementById('discountBanner'); + const originalPrice = document.getElementById('originalPrice'); + const discountedPrice = document.getElementById('discountedPrice'); + const discountedPriceValue = document.getElementById('discountedPriceValue'); + const discountPercent = document.getElementById('discountPercent'); + const daysAway = document.getElementById('daysAway'); - // Send the updated date to the server to check for discounts - departDateInput.addEventListener('change', (event) => { - const newDate = event.target.value; - fetch('/bookings/check_date', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ date: newDate }) - }) - .then(response => response.json()) - .then(data => { if (data.discount) { - const discountBanner = document.getElementById('discountBanner'); - const discountPercent = document.getElementById('discountPercent'); - const daysAway = document.getElementById('daysAway'); + const originalPriceValue = parseFloat(originalPrice.textContent.replace('£', '')); + const discountValue = originalPriceValue * (1 - data.discount / 100); - discountPercent.textContent = data.discount; - daysAway.textContent = data.days_away; + originalPrice.style.textDecoration = 'line-through'; + discountedPriceValue.textContent = `${discountValue.toFixed(2)}`; + discountedPrice.style.display = 'block'; discountBanner.style.display = 'block'; + discountPercent.textContent = data.discount; + daysAway.textContent = data.days_away; } else { - const discountBanner = document.getElementById('discountBanner'); + originalPrice.style.textDecoration = 'none'; + discountedPrice.style.display = 'none'; discountBanner.style.display = 'none'; } - }) - .catch(error => { - console.error('Error:', error); - }); + }, + error: function () { + alert('Error applying discount. Please try again.'); + } }); + }); + + // Trigger the change event to apply the initial discount if a date is selected + if (filterDataDepartDate) { + departDateInput.dispatchEvent(new Event('change')); + } }); </script> {% endblock %}