diff --git a/app/__init__.py b/app/__init__.py index 1720146613c00a5161c7a4bc8d7c03665a0dc81c..fa820921732be9191433ca5234e11d733f48ace4 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -147,7 +147,6 @@ def register_blueprints(app): blueprints = [ ('main', None), ('bookings', '/bookings'), - ('api', '/api'), ('admin', '/admin'), ('profile', '/profile'), ('errors', '/errors'), diff --git a/app/api/__init__.py b/app/api/__init__.py deleted file mode 100644 index fac61f01ec4bf6b6ba794945eeab35f3291437f2..0000000000000000000000000000000000000000 --- a/app/api/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from flask import Blueprint - -bp = Blueprint('api', __name__) - -from app.api import routes diff --git a/app/api/routes.py b/app/api/routes.py deleted file mode 100644 index 18ed516aeced8b596b8ec044ae597b76a3aa2d99..0000000000000000000000000000000000000000 --- a/app/api/routes.py +++ /dev/null @@ -1,85 +0,0 @@ -from flask import jsonify -from app.api import bp -from app.models import User, Listings - -@bp.route('/user_id/<int:id>', methods=['GET']) -def get_user_by_id(id): - try: - result = User.search_user_id(id) - - if result is None: - return jsonify({'error': 'User not found'}), 404 - - user_data = { - 'id': result.id, - 'username': result.username, - 'email': result.email - } - return jsonify(user_data), 200 - - #If something falls over throw nice error for debugging, will change for admin only users to see errors otherwise throw generic 500 - except Exception as e: - return jsonify({'error': str(e)}), 500 - -@bp.route('/user/create', methods=['GET']) -def create_user(): - try: - #Hardcoded for now as when running upgrade on new db no users exist yet, will change at some point - result = User.create_user('ethan_root', 'ethan2.clay@live.uwe.ac.uk', 'password1234', 2) # Role ID 2 is for admins - - if result is None: - return jsonify({'error': 'User not found'}), 404 - - user_data = { - 'id': result.id, - 'username': result.username, - 'email': result.email - } - return jsonify(user_data), 200 - - #If something falls over throw nice error for debugging, will change for admin only users to see errors otherwise throw generic 500 - except Exception as e: - return jsonify({'error': str(e)}), 500 - -@bp.route('/listing/create', methods=['GET']) -def create_listing(): - - #Temporary import - from datetime import datetime - - - try: - #Hardcoded for now as when running upgrade on new db no users exist yet, will change at some point - data = { - "depart_location": "New York", - "depart_time": "2024-12-01T08:00:00", - "destination_location": "London", - "destination_time": "2024-12-01T18:00:00", - "fair_cost": 500.00, - "transport_type": "Airplane", - } - - # Extract the required fields - depart_location = data['depart_location'] - depart_time = datetime.strptime(data['depart_time'], '%Y-%m-%dT%H:%M:%S') # Ensure date is in correct format - destination_location = data['destination_location'] - destination_time = datetime.strptime(data['destination_time'], '%Y-%m-%dT%H:%M:%S') - fair_cost = data['fair_cost'] - transport_type = data['transport_type'] - - result = Listings.create_listing(depart_location, depart_time, destination_location, destination_time, fair_cost, transport_type) - - if result is None: - return jsonify({'error': 'User not found'}), 404 - - user_data = { - 'depart_location': result.depart_location, - 'depart_time': result.depart_time, - 'id': result.id - } - return jsonify(user_data), 200 - - #If something falls over throw nice error for debugging, will change for admin only users to see errors otherwise throw generic 500 - except Exception as e: - return jsonify({'error': str(e)}), 500 - diff --git a/app/bookings/routes.py b/app/bookings/routes.py index 26b74645c2775b016b03684e7860b1be58cc0225..718660be4eeb699a9993c06105221862011d082f 100644 --- a/app/bookings/routes.py +++ b/app/bookings/routes.py @@ -6,6 +6,7 @@ from app.logger import error_logger from app.main.utils import calculate_discount, pretty_time import json from datetime import datetime +from app import user_permission, permission_required @bp.route('/') @@ -84,13 +85,13 @@ def checkout(): listing.depart_time = pretty_time(listing.depart_time) listing.destination_time = pretty_time(listing.destination_time) - # Parse depart_date as a date object depart_date_obj = datetime.strptime(depart_date, '%Y-%m-%d') depart_date_formatted = depart_date_obj.strftime('%d-%m-%Y') return render_template('bookings/checkout.html', listing=listing, num_seats=num_seats, depart_date=depart_date_formatted) @bp.route('/payment') +@permission_required(user_permission) def payment(): depart_date = request.args.get('date') num_seats = request.args.get('seats') @@ -101,6 +102,7 @@ def payment(): return redirect(url_for('bookings.listings')) session['checkout_cache'] = { + 'listing_id': listing_id, 'depart_date': depart_date, 'num_seats': num_seats, 'listing_id': listing_id diff --git a/app/templates/api/index.html b/app/templates/api/index.html deleted file mode 100644 index 547f91650053f49756483c7a3af2ffa536ec230e..0000000000000000000000000000000000000000 --- a/app/templates/api/index.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'base.html' %} - -{% block content %} - <div class="content"> - <h2>Index of bookings.html</h2> - </div> -{% endblock %} \ No newline at end of file diff --git a/app/templates/bookings/checkout.html b/app/templates/bookings/checkout.html index cc8a28eb875384fea555fbd6b09ab7f419b6e99b..196d9b14ecba810593007c83b79a3e913a568b89 100644 --- a/app/templates/bookings/checkout.html +++ b/app/templates/bookings/checkout.html @@ -18,5 +18,97 @@ </div> </div> </div> + + <div class="row"> + <div class="col-md-12"> + <div class="card mb-4"> + <div class="card-body"> + <h2 class="card-title">Payment Information</h2> + <form id="paymentForm"> + <div class="form-group"> + <label for="cardNumber">Credit Card Number</label> + <input type="text" class="form-control" id="cardNumber" name="cardNumber" placeholder="Enter your credit card number"> + </div> + <div class="form-group"> + <label for="cardExpiry">Expiry Date</label> + <input type="text" class="form-control" id="cardExpiry" name="cardExpiry" placeholder="MM/YY"> + </div> + <div class="form-group"> + <label for="cardCVC">CVC</label> + <input type="text" class="form-control" id="cardCVC" name="cardCVC" placeholder="CVC"> + </div> + <button type="submit" class="btn btn-primary" style="margin-top:10px;">Pay Now</button> + </form> + </div> + </div> + </div> + </div> </div> + +<script src="https://cdn.jsdelivr.net/npm/pristinejs/dist/pristine.min.js"></script> +<script> + document.addEventListener('DOMContentLoaded', function () { + var form = document.getElementById('paymentForm'); + var pristine = new Pristine(form); + + pristine.addValidator( + document.getElementById('cardNumber'), + function (value) { + return /^[0-9]{16}$/.test(value); // Check if the card number is 16 digits + }, + "Credit card number must be 16 digits", + 2, + false + ); + + pristine.addValidator( + document.getElementById('cardExpiry'), + function (value) { + var parts = value.split('/'); + if (parts.length !== 2) return false; + var month = parseInt(parts[0], 10); + var year = parseInt(parts[1], 10) + 2000; // Assuming the year is in YY format + var expiryDate = new Date(year, month - 1); + return expiryDate >= new Date(); + }, + "Expiry date cannot be in the past", + 2, + false + ); + + pristine.addValidator( + document.getElementById('cardCVC'), + function (value) { + return /^[0-9]{3}$/.test(value); // Check if the CVC is 3 digits + }, + "CVC must be 3 digits", + 2, + false + ); + + form.addEventListener('submit', function (e) { + e.preventDefault(); + var valid = pristine.validate(); // returns true or false + + if (valid) { + alert('Payment information is valid!'); + form.submit(); + } + }); + + // Validate on blur (focus lost) + var inputs = form.querySelectorAll('input'); + inputs.forEach(function (input) { + input.addEventListener('blur', function () { + pristine.validate(input); + }); + }); + + // Add CSS to show error messages in red + var style = document.createElement('style'); + style.innerHTML = '.pristine-error { color: red; }'; + document.head.appendChild(style); + }); +</script> + {% endblock %}