diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..808386fd8a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.venv/ +__pycache__/ \ No newline at end of file diff --git a/AUTHORS b/AUTHORS index 64b26acdc14..11835386d66 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,6 +1,9 @@ # This file lists all individuals having contributed content to the repository. +Chinaza Ukwe +Emmanuel Sekyi Jennifer Huang <133@holbertonschool.com> Alexa Orrico <210@holbertonschool.com> Joann Vuong <130@holbertonschool.com> + diff --git a/README.md b/README.md index ae0c24c98f4..49825a0e031 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,9 @@ No known bugs at this time. Alexa Orrico - [Github](https://github.com/alexaorrico) / [Twitter](https://twitter.com/alexa_orrico) Jennifer Huang - [Github](https://github.com/jhuang10123) / [Twitter](https://twitter.com/earthtojhuang) Jhoan Zamora - [Github](https://github.com/jzamora5) / [Twitter](https://twitter.com/JhoanZamora10) -David Ovalle - [Github](https://github.com/Nukemenonai) / [Twitter](https://twitter.com/disartDave) +David Ovalle - [Github](https://github.com/Nukemenonai) / [Twitter](https://twitter.com/disartDave) +Emmanuel Sekyi - [Github](https://github.com/Esekyi) + Second part of Airbnb: Joann Vuong ## License diff --git a/api/v1/app.py b/api/v1/app.py index 2a74f26a1e5..751ed9d6b6f 100755 --- a/api/v1/app.py +++ b/api/v1/app.py @@ -11,8 +11,7 @@ app = Flask(__name__) app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True app.register_blueprint(app_views) -cors = CORS(app, resources={r"/*": {"origins": "0.0.0.0"}}) - +cors = CORS(app, resources={r"/api/v1/*": {"origins": "*"}}) @app.teardown_appcontext def close_db(error): diff --git a/file.json b/file.json new file mode 100644 index 00000000000..b5e05146a0e --- /dev/null +++ b/file.json @@ -0,0 +1,216 @@ +{ + "BaseModel.dd52e210-0a0a-4f48-aba9-129c09d5b083": { + "id": "dd52e210-0a0a-4f48-aba9-129c09d5b083", + "created_at": "2024-08-06T04:50:24.300285", + "updated_at": "2024-08-06T04:50:24.300285", + "__class__": "BaseModel" + }, + "State.965c91e6-1c6b-4001-88de-fde415e4d2ca": { + "name": "Arizona", + "created_at": "2024-08-06T10:12:09.276009", + "updated_at": "2024-08-06T10:12:09.276047", + "id": "965c91e6-1c6b-4001-88de-fde415e4d2ca", + "__class__": "State" + }, + "State.92038c0a-7701-4499-8d9c-e3cf04511298": { + "name": "Ohio", + "created_at": "2024-08-06T10:16:13.211148", + "updated_at": "2024-08-06T10:16:13.211231", + "id": "92038c0a-7701-4499-8d9c-e3cf04511298", + "__class__": "State" + }, + "State.d8e94fa2-2710-40e0-9d3c-40ed5b00c681": { + "name": "Texas", + "created_at": "2024-08-06T10:16:52.657918", + "updated_at": "2024-08-06T10:16:52.658001", + "id": "d8e94fa2-2710-40e0-9d3c-40ed5b00c681", + "__class__": "State" + }, + "State.6e2d673d-ba64-434f-919b-8c5d70193e1b": { + "name": "Florida", + "created_at": "2024-08-06T10:17:02.766481", + "updated_at": "2024-08-06T10:17:02.766538", + "id": "6e2d673d-ba64-434f-919b-8c5d70193e1b", + "__class__": "State" + }, + "State.c76968c7-4d3a-4042-93c1-3c9a3d4c5d9b": { + "name": "California", + "created_at": "2024-08-06T10:17:10.514532", + "updated_at": "2024-08-06T10:17:10.514570", + "id": "c76968c7-4d3a-4042-93c1-3c9a3d4c5d9b", + "__class__": "State" + }, + "State.e45594a4-2824-4075-9a86-70ce3653a144": { + "name": "tr", + "created_at": "2024-08-06T10:53:45.495555", + "updated_at": "2024-08-06T10:53:45.495647", + "id": "e45594a4-2824-4075-9a86-70ce3653a144", + "__class__": "State" + }, + "City.147fbef5-061d-4e79-896b-e2e901bf99b3": { + "name": "Miami", + "created_at": "2024-08-07T04:32:32.007342", + "updated_at": "2024-08-07T04:32:32.007399", + "id": "147fbef5-061d-4e79-896b-e2e901bf99b3", + "state_id": "6e2d673d-ba64-434f-919b-8c5d70193e1b", + "__class__": "City" + }, + "City.d807b069-c052-4f8d-b2c7-a7bd63008892": { + "name": "Orlando", + "created_at": "2024-08-07T04:33:08.636635", + "updated_at": "2024-08-07T04:33:08.636683", + "id": "d807b069-c052-4f8d-b2c7-a7bd63008892", + "state_id": "6e2d673d-ba64-434f-919b-8c5d70193e1b", + "__class__": "City" + }, + "City.3b6f9ce1-ca57-4dc5-8cdc-d734d1c818b8": { + "name": "Tallahassee", + "created_at": "2024-08-07T04:38:45.238888", + "updated_at": "2024-08-07T04:38:45.238924", + "id": "3b6f9ce1-ca57-4dc5-8cdc-d734d1c818b8", + "state_id": "6e2d673d-ba64-434f-919b-8c5d70193e1b", + "__class__": "City" + }, + "City.5200d721-e515-4247-afa9-75e892066b87": { + "name": "Tucson", + "created_at": "2024-08-07T04:40:20.831317", + "updated_at": "2024-08-07T04:40:20.831363", + "id": "5200d721-e515-4247-afa9-75e892066b87", + "state_id": "965c91e6-1c6b-4001-88de-fde415e4d2ca", + "__class__": "City" + }, + "City.0a41acee-1caa-4661-9d45-93ba6e816b24": { + "name": "Yuma", + "created_at": "2024-08-07T04:41:00.856309", + "updated_at": "2024-08-07T04:41:00.856345", + "id": "0a41acee-1caa-4661-9d45-93ba6e816b24", + "state_id": "965c91e6-1c6b-4001-88de-fde415e4d2ca", + "__class__": "City" + }, + "Amenity.63b9e893-f4ad-4a52-af20-666b555fa52e": { + "name": "Cable Tv", + "created_at": "2024-08-11T05:36:27.934054", + "updated_at": "2024-08-11T05:36:27.934446", + "id": "63b9e893-f4ad-4a52-af20-666b555fa52e", + "__class__": "Amenity" + }, + "Amenity.608a70a2-0dd1-46a2-9d6d-2bf0b0878fe7": { + "name": "Air Conditioning", + "created_at": "2024-08-11T05:44:08.346441", + "updated_at": "2024-08-11T05:44:08.346588", + "id": "608a70a2-0dd1-46a2-9d6d-2bf0b0878fe7", + "__class__": "Amenity" + }, + "Amenity.b9fa984a-2db2-4642-a944-c978d1680a1f": { + "name": "Breackfast", + "created_at": "2024-08-11T05:44:31.028926", + "updated_at": "2024-08-11T05:44:31.028973", + "id": "b9fa984a-2db2-4642-a944-c978d1680a1f", + "__class__": "Amenity" + }, + "Amenity.aead74ea-84c2-487d-8a0f-5f4e233d0332": { + "name": "Dogs", + "created_at": "2024-08-11T05:52:54.136181", + "updated_at": "2024-08-11T05:52:54.136390", + "id": "aead74ea-84c2-487d-8a0f-5f4e233d0332", + "__class__": "Amenity" + }, + "Amenity.76f89e99-3a4c-444a-875d-4b331f89c8d4": { + "name": "Doorman", + "created_at": "2024-08-11T05:52:59.947820", + "updated_at": "2024-08-11T05:52:59.947864", + "id": "76f89e99-3a4c-444a-875d-4b331f89c8d4", + "__class__": "Amenity" + }, + "Amenity.f519229f-7571-4569-9130-5739efd2edac": { + "name": "Cat(s)", + "created_at": "2024-08-11T05:53:17.010840", + "updated_at": "2024-08-11T05:53:17.010882", + "id": "f519229f-7571-4569-9130-5739efd2edac", + "__class__": "Amenity" + }, + "User.1e4c7ec4-2711-44a9-96d4-8f04bb4e8b80": { + "email": "sskert10@gmail.com", + "password": "51e2831f7c824b48adb2fb194949003d", + "first_name": "Sekyi", + "last_name": "Skert", + "created_at": "2024-08-11T06:10:52.994434", + "updated_at": "2024-08-11T06:10:52.994912", + "id": "1e4c7ec4-2711-44a9-96d4-8f04bb4e8b80", + "__class__": "User" + }, + "User.08e66463-fd13-4c09-97b4-e7cb03cee6f9": { + "email": "sskert10@gmail.com", + "password": "bb37c85cff2917a43fa8ab7253b40ab6", + "first_name": "Sekyi", + "last_name": "Skert", + "created_at": "2024-08-11T06:11:27.925884", + "updated_at": "2024-08-11T06:11:27.925954", + "id": "08e66463-fd13-4c09-97b4-e7cb03cee6f9", + "__class__": "User" + }, + "Place.9b9a3ac4-61fa-4620-8533-028a76c310d6": { + "city_id": "3b6f9ce1-ca57-4dc5-8cdc-d734d1c818b8", + "user_id": "08e66463-fd13-4c09-97b4-e7cb03cee6f9", + "name": "Beautiful Studio Rooms", + "amenity_ids": "608a70a2-0dd1-46a2-9d6d-2bf0b0878fe7", + "description": "If you use a multi-element selector, like the class selector we used in the previous example, and we know that we're looking for elements of a specific type, it's good practice to specify the element type before the selector. Not only is it more precise, it's also faster for jQuery to process, resulting in more responsive sites. Here is a re-written version of the previous example, where we use this method:", + "max_guest": 2, + "numeber_rooms": 4, + "numeber_bathrooms": 8, + "created_at": "2024-08-11T06:28:11.585076", + "updated_at": "2024-08-11T06:28:11.585344", + "id": "9b9a3ac4-61fa-4620-8533-028a76c310d6", + "__class__": "Place" + }, + "City.a703dc2b-4eb8-4998-badd-82e6f1e8b857": { + "name": "Galveston", + "created_at": "2024-08-11T06:39:55.484038", + "updated_at": "2024-08-11T06:39:55.484190", + "id": "a703dc2b-4eb8-4998-badd-82e6f1e8b857", + "state_id": "d8e94fa2-2710-40e0-9d3c-40ed5b00c681", + "__class__": "City" + }, + "Place.4cabf5b6-552d-4bd1-8943-c0e85aae5981": { + "user_id": "08e66463-fd13-4c09-97b4-e7cb03cee6f9", + "name": "Baywatch Dolphin Tour", + "amenity_ids": [ + "608a70a2-0dd1-46a2-9d6d-2bf0b0878fe7", + "63b9e893-f4ad-4a52-af20-666b555fa52e", + "76f89e99-3a4c-444a-875d-4b331f89c8d4" + ], + "description": "This Galveston Baywatch Dolphin Tour is a great way to see dolphins on the water in just a few hours. Meet your group and captain at Pier 21 and join the boat you\u2019re assigned for this experience. Then, take off on the water to enjoy some time searching for dolphins in their natural habitat. Catch sight of dolphins in their natural habitat during this Galveston tour Perfect for nature lovers who are short on time No need to rush on board\u2014all seats offer great viewing opportunities A captain knows the best areas on the water to spot dolphins", + "max_guest": 6, + "numeber_rooms": 8, + "numeber_bathrooms": 3, + "price_by_night": 329, + "latitude": -94.792802857672, + "longitude": "29.309400464654054", + "city_id": "a703dc2b-4eb8-4998-badd-82e6f1e8b857", + "created_at": "2024-08-11T06:49:19.954826", + "updated_at": "2024-08-11T06:49:19.955034", + "id": "4cabf5b6-552d-4bd1-8943-c0e85aae5981", + "__class__": "Place" + }, + "Place.03f48f7e-7c47-4b20-98c5-729e093be6f7": { + "user_id": "08e66463-fd13-4c09-97b4-e7cb03cee6f9", + "name": "Baywatch Dolphin Tour", + "amenity_ids": [ + "608a70a2-0dd1-46a2-9d6d-2bf0b0878fe7", + "63b9e893-f4ad-4a52-af20-666b555fa52e", + "76f89e99-3a4c-444a-875d-4b331f89c8d4" + ], + "description": "This Galveston Baywatch Dolphin Tour is a great way to see dolphins on the water in just a few hours. Meet your group and captain at Pier 21 and join the boat you\u2019re assigned for this experience. Then, take off on the water to enjoy some time searching for dolphins in their natural habitat. Catch sight of dolphins in their natural habitat during this Galveston tour Perfect for nature lovers who are short on time No need to rush on board\u2014all seats offer great viewing opportunities A captain knows the best areas on the water to spot dolphins", + "max_guest": 6, + "numeber_rooms": 8, + "numeber_bathrooms": 3, + "price_by_night": 329, + "latitude": -94.792802857672, + "longitude": 29.309400464654054, + "city_id": "a703dc2b-4eb8-4998-badd-82e6f1e8b857", + "created_at": "2024-08-11T06:51:43.027322", + "updated_at": "2024-08-11T06:51:43.027374", + "id": "03f48f7e-7c47-4b20-98c5-729e093be6f7", + "__class__": "Place" + } +} \ No newline at end of file diff --git a/web_dynamic/0-hbnb.py b/web_dynamic/0-hbnb.py new file mode 100755 index 00000000000..acbdf35c63d --- /dev/null +++ b/web_dynamic/0-hbnb.py @@ -0,0 +1,47 @@ +#!/usr/bin/python3 +""" Starts a Flash Web Application """ +from models import storage +from models.state import State +from models.city import City +from models.amenity import Amenity +from models.place import Place +from os import environ +from flask import Flask, render_template +import uuid +app = Flask(__name__) +# app.jinja_env.trim_blocks = True +# app.jinja_env.lstrip_blocks = True + + +@app.teardown_appcontext +def close_db(error): + """ Remove the current SQLAlchemy Session """ + storage.close() + + +@app.route('/0-hbnb', strict_slashes=False) +def hbnb(): + """ HBNB is alive! """ + states = storage.all(State).values() + states = sorted(states, key=lambda k: k.name) + st_ct = [] + + for state in states: + st_ct.append([state, sorted(state.cities, key=lambda k: k.name)]) + + amenities = storage.all(Amenity).values() + amenities = sorted(amenities, key=lambda k: k.name) + + places = storage.all(Place).values() + places = sorted(places, key=lambda k: k.name) + + return render_template('0-hbnb.html', + cache_id=uuid.uuid4(), + states=st_ct, + amenities=amenities, + places=places) + + +if __name__ == "__main__": + """ Main Function """ + app.run(host='0.0.0.0', port=5000) diff --git a/web_dynamic/1-hbnb.py b/web_dynamic/1-hbnb.py new file mode 100644 index 00000000000..ee44915c317 --- /dev/null +++ b/web_dynamic/1-hbnb.py @@ -0,0 +1,53 @@ +#!/usr/bin/python3 +""" Starts a Flash Web Application """ +from models import storage +from models.state import State +from models.city import City +from models.amenity import Amenity +from models.place import Place +from models.user import User +from os import environ +from flask import Flask, render_template +import uuid +app = Flask(__name__) +# app.jinja_env.trim_blocks = True +# app.jinja_env.lstrip_blocks = True + + +@app.teardown_appcontext +def close_db(error): + """ Remove the current SQLAlchemy Session """ + storage.close() + + +@app.route('/1-hbnb', strict_slashes=False) +def hbnb(): + """ HBNB is alive! """ + states = storage.all(State).values() + states = sorted(states, key=lambda k: k.name) + st_ct = [] + + for state in states: + st_ct.append([state, sorted(state.cities, key=lambda k: k.name)]) + + amenities = storage.all(Amenity).values() + amenities = sorted(amenities, key=lambda k: k.name) + + places = storage.all(Place).values() + places = sorted(places, key=lambda k: k.name) + + places_with_users = [] + for place in places: + user = storage.get(User, place.user_id) + places_with_users.append((place, user)) + + return render_template('1-hbnb.html', + cache_id=uuid.uuid4(), + states=st_ct, + amenities=amenities, + places=places_with_users) + + +if __name__ == "__main__": + """ Main Function """ + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/100-hbnb.py b/web_dynamic/100-hbnb.py old mode 100755 new mode 100644 similarity index 77% rename from web_flask/100-hbnb.py rename to web_dynamic/100-hbnb.py index cc243d165dc..ce715cc1535 --- a/web_flask/100-hbnb.py +++ b/web_dynamic/100-hbnb.py @@ -5,8 +5,10 @@ from models.city import City from models.amenity import Amenity from models.place import Place +from models.user import User from os import environ from flask import Flask, render_template +import uuid app = Flask(__name__) # app.jinja_env.trim_blocks = True # app.jinja_env.lstrip_blocks = True @@ -18,7 +20,7 @@ def close_db(error): storage.close() -@app.route('/hbnb', strict_slashes=False) +@app.route('/100-hbnb', strict_slashes=False) def hbnb(): """ HBNB is alive! """ states = storage.all(State).values() @@ -34,10 +36,16 @@ def hbnb(): places = storage.all(Place).values() places = sorted(places, key=lambda k: k.name) + places_with_users = [] + for place in places: + user = storage.get(User, place.user_id) + places_with_users.append((place, user)) + return render_template('100-hbnb.html', + cache_id=uuid.uuid4(), states=st_ct, amenities=amenities, - places=places) + places=places_with_users) if __name__ == "__main__": diff --git a/web_dynamic/2-hbnb.py b/web_dynamic/2-hbnb.py new file mode 100644 index 00000000000..054c9646ae4 --- /dev/null +++ b/web_dynamic/2-hbnb.py @@ -0,0 +1,53 @@ +#!/usr/bin/python3 +""" Starts a Flash Web Application """ +from models import storage +from models.state import State +from models.city import City +from models.amenity import Amenity +from models.place import Place +from models.user import User +from os import environ +from flask import Flask, render_template +import uuid +app = Flask(__name__) +# app.jinja_env.trim_blocks = True +# app.jinja_env.lstrip_blocks = True + + +@app.teardown_appcontext +def close_db(error): + """ Remove the current SQLAlchemy Session """ + storage.close() + + +@app.route('/2-hbnb', strict_slashes=False) +def hbnb(): + """ HBNB is alive! """ + states = storage.all(State).values() + states = sorted(states, key=lambda k: k.name) + st_ct = [] + + for state in states: + st_ct.append([state, sorted(state.cities, key=lambda k: k.name)]) + + amenities = storage.all(Amenity).values() + amenities = sorted(amenities, key=lambda k: k.name) + + places = storage.all(Place).values() + places = sorted(places, key=lambda k: k.name) + + places_with_users = [] + for place in places: + user = storage.get(User, place.user_id) + places_with_users.append((place, user)) + + return render_template('2-hbnb.html', + cache_id=uuid.uuid4(), + states=st_ct, + amenities=amenities, + places=places_with_users) + + +if __name__ == "__main__": + """ Main Function """ + app.run(host='0.0.0.0', port=5000) diff --git a/web_dynamic/3-hbnb.py b/web_dynamic/3-hbnb.py new file mode 100644 index 00000000000..8fc1ad4ba24 --- /dev/null +++ b/web_dynamic/3-hbnb.py @@ -0,0 +1,53 @@ +#!/usr/bin/python3 +""" Starts a Flash Web Application """ +from models import storage +from models.state import State +from models.city import City +from models.amenity import Amenity +from models.place import Place +from models.user import User +from os import environ +from flask import Flask, render_template +import uuid +app = Flask(__name__) +# app.jinja_env.trim_blocks = True +# app.jinja_env.lstrip_blocks = True + + +@app.teardown_appcontext +def close_db(error): + """ Remove the current SQLAlchemy Session """ + storage.close() + + +@app.route('/3-hbnb', strict_slashes=False) +def hbnb(): + """ HBNB is alive! """ + states = storage.all(State).values() + states = sorted(states, key=lambda k: k.name) + st_ct = [] + + for state in states: + st_ct.append([state, sorted(state.cities, key=lambda k: k.name)]) + + amenities = storage.all(Amenity).values() + amenities = sorted(amenities, key=lambda k: k.name) + + places = storage.all(Place).values() + places = sorted(places, key=lambda k: k.name) + + places_with_users = [] + for place in places: + user = storage.get(User, place.user_id) + places_with_users.append((place, user)) + + return render_template('3-hbnb.html', + cache_id=uuid.uuid4(), + states=st_ct, + amenities=amenities, + places=places_with_users) + + +if __name__ == "__main__": + """ Main Function """ + app.run(host='0.0.0.0', port=5000) diff --git a/web_dynamic/4-hbnb.py b/web_dynamic/4-hbnb.py new file mode 100644 index 00000000000..3841e345121 --- /dev/null +++ b/web_dynamic/4-hbnb.py @@ -0,0 +1,53 @@ +#!/usr/bin/python3 +""" Starts a Flash Web Application """ +from models import storage +from models.state import State +from models.city import City +from models.amenity import Amenity +from models.place import Place +from models.user import User +from os import environ +from flask import Flask, render_template +import uuid +app = Flask(__name__) +# app.jinja_env.trim_blocks = True +# app.jinja_env.lstrip_blocks = True + + +@app.teardown_appcontext +def close_db(error): + """ Remove the current SQLAlchemy Session """ + storage.close() + + +@app.route('/4-hbnb', strict_slashes=False) +def hbnb(): + """ HBNB is alive! """ + states = storage.all(State).values() + states = sorted(states, key=lambda k: k.name) + st_ct = [] + + for state in states: + st_ct.append([state, sorted(state.cities, key=lambda k: k.name)]) + + amenities = storage.all(Amenity).values() + amenities = sorted(amenities, key=lambda k: k.name) + + places = storage.all(Place).values() + places = sorted(places, key=lambda k: k.name) + + places_with_users = [] + for place in places: + user = storage.get(User, place.user_id) + places_with_users.append((place, user)) + + return render_template('4-hbnb.html', + cache_id=uuid.uuid4(), + states=st_ct, + amenities=amenities, + places=places_with_users) + + +if __name__ == "__main__": + """ Main Function """ + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/__init__.py b/web_dynamic/__init__.py similarity index 100% rename from web_flask/__init__.py rename to web_dynamic/__init__.py diff --git a/web_flask/static/images/icon.png b/web_dynamic/static/images/icon.png similarity index 100% rename from web_flask/static/images/icon.png rename to web_dynamic/static/images/icon.png diff --git a/web_flask/static/images/icon_bath.png b/web_dynamic/static/images/icon_bath.png similarity index 100% rename from web_flask/static/images/icon_bath.png rename to web_dynamic/static/images/icon_bath.png diff --git a/web_flask/static/images/icon_bed.png b/web_dynamic/static/images/icon_bed.png similarity index 100% rename from web_flask/static/images/icon_bed.png rename to web_dynamic/static/images/icon_bed.png diff --git a/web_flask/static/images/icon_group.png b/web_dynamic/static/images/icon_group.png similarity index 100% rename from web_flask/static/images/icon_group.png rename to web_dynamic/static/images/icon_group.png diff --git a/web_flask/static/images/logo.png b/web_dynamic/static/images/logo.png similarity index 100% rename from web_flask/static/images/logo.png rename to web_dynamic/static/images/logo.png diff --git a/web_dynamic/static/scripts/1-hbnb.js b/web_dynamic/static/scripts/1-hbnb.js new file mode 100644 index 00000000000..75b645c05dc --- /dev/null +++ b/web_dynamic/static/scripts/1-hbnb.js @@ -0,0 +1,14 @@ +$(document).ready(function () { + const selectedAmenities = {}; + $('input[type="checkbox"]').change(function () { + const amenityId = $(this).attr('data-id'); + const amenityName = $(this).attr('data-name'); + if ($(this).is(':checked')) { + selectedAmenities[amenityId] = amenityName; + } else { + delete selectedAmenities[amenityId]; + } + const amenitiesList = Object.values(selectedAmenities).join(', '); + $('.selected-amenities').text(amenitiesList); + }); +}); diff --git a/web_dynamic/static/scripts/100-hbnb.js b/web_dynamic/static/scripts/100-hbnb.js new file mode 100644 index 00000000000..2649a591b24 --- /dev/null +++ b/web_dynamic/static/scripts/100-hbnb.js @@ -0,0 +1,99 @@ +$(document).ready(function () { + const selectedAmenities = {}; + + $('input[type="checkbox"]').change(function () { + const amenityId = $(this).attr('data-id'); + const amenityName = $(this).attr('data-name'); + if ($(this).is(':checked')) { + selectedAmenities[amenityId] = amenityName; + } else { + delete selectedAmenities[amenityId]; + } + const amenitiesList = Object.values(selectedAmenities).join(', '); + if (amenitiesList) { + $('.selected-amenities').text(amenitiesList); + } else { + $('.amenities h4').html(' '); + } + }); + + $.get('http://0.0.0.0:5001/api/v1/status/', function (data) { + if (data.status === 'OK') { // If the status is 'OK' + $('#api_status').addClass('available'); + } else { + $('#api_status').removeClass('available'); + } + }).fail(function () { + $('#api_status').removeClass('available'); + }); + + $.ajax({ + url: 'http://0.0.0.0:5001/api/v1/places_search/', + type: 'POST', + contentType: 'application/json', + data: JSON.stringify({}), + success: function (data) { + for (const place of data) { + const article = $('
'); + const titleBox = $('
'); + titleBox.append(`

${place.name || ''}

`); + titleBox.append(`
$${place.price_by_night || 0}
`); + article.append(titleBox); + + const infoBox = $('
'); + infoBox.append(`
${place.max_guest || 0} Guest${place.max_guest !== 1 ? 's' : ''}
`); + infoBox.append(`
${place.number_rooms || 0} Bedroom${place.number_rooms !== 1 ? 's' : ''}
`); + infoBox.append(`
${place.number_bathrooms || 0} Bathroom${place.number_bathrooms !== 1 ? 's' : ''}
`); + article.append(infoBox); + + const description = $('
'); + description.html(place.description || ''); + article.append(description); + + $('.places').append(article); + } + }, + error: function (error) { + console.error('Error fetching places:', error); + } + + }); + function fetchPlaces(data) { + $.ajax({ + url: 'http://0.0.0.0:5001/api/v1/places_search/', + type: 'POST', + contentType: 'application/json', + data: JSON.stringify(data), + success: function (places) { + $('.places').empty(); + for (const place of places) { + const article = $('
'); + const titleBox = $('
'); + titleBox.append(`

${place.name || ''}

`); + titleBox.append(`
$${place.price_by_night || 0}
`); + article.append(titleBox); + + const infoBox = $('
'); + infoBox.append(`
${place.max_guest || 0} Guest${place.max_guest !== 1 ? 's' : ''}
`); + infoBox.append(`
${place.number_rooms || 0} Bedroom${place.number_rooms !== 1 ? 's' : ''}
`); + infoBox.append(`
${place.number_bathrooms || 0} Bathroom${place.number_bathrooms !== 1 ? 's' : ''}
`); + article.append(infoBox); + + const description = $('
'); + description.html(place.description || ''); + article.append(description); + + $('.places').append(article); + } + }, + error: function (error) { + console.error('Error fetching places:', error); + } + }); + } + fetchPlaces({}); + $('button').click(function () { + const amenities = Object.keys(selectedAmenities); + fetchPlaces({ amenities: amenities }); + }); +}); diff --git a/web_dynamic/static/scripts/2-hbnb.js b/web_dynamic/static/scripts/2-hbnb.js new file mode 100644 index 00000000000..4056243b698 --- /dev/null +++ b/web_dynamic/static/scripts/2-hbnb.js @@ -0,0 +1,38 @@ +$(document).ready(function () { + // Object to keep track of selected amenities + const selectedAmenities = {}; + + /** + * Event listener for checkbox changes + * Adds or removes amenities from the selectedAmenities object + * Updates the text of the .selected-amenities element with the list of selected amenities + */ + $('input[type="checkbox"]').change(function () { + const amenityId = $(this).attr('data-id'); // Get the data-id attribute of the checkbox + const amenityName = $(this).attr('data-name'); // Get the data-name attribute of the checkbox + if ($(this).is(':checked')) { // If the checkbox is checked + selectedAmenities[amenityId] = amenityName; // Add the amenity to the selectedAmenities object + } else { // If the checkbox is unchecked + delete selectedAmenities[amenityId]; // Remove the amenity from the selectedAmenities object + } + // Update the text of the .selected-amenities element with the list of selected amenities + const amenitiesList = Object.values(selectedAmenities).join(', '); + $('.selected-amenities').text(amenitiesList); + }); + + /** + * Function to check the API status + * Sends a GET request to the API endpoint + * Adds the 'available' class to the #api_status element if the status is 'OK' + * Removes the 'available' class from the #api_status element if the status is not 'OK' or the request fails + */ + $.get('http://0.0.0.0:5001/api/v1/status/', function (data) { + if (data.status === 'OK') { // If the status is 'OK' + $('#api_status').addClass('available'); // Add the 'available' class to the #api_status element + } else { // If the status is not 'OK' + $('#api_status').removeClass('available'); // Remove the 'available' class from the #api_status element + } + }).fail(function () { + $('#api_status').removeClass('available'); // Remove the 'available' class from the #api_status element if the request fails + }); +}); diff --git a/web_dynamic/static/scripts/3-hbnb.js b/web_dynamic/static/scripts/3-hbnb.js new file mode 100644 index 00000000000..f6f4f380539 --- /dev/null +++ b/web_dynamic/static/scripts/3-hbnb.js @@ -0,0 +1,57 @@ +$(document).ready(function () { + const selectedAmenities = {}; + + $('input[type="checkbox"]').change(function () { + const amenityId = $(this).attr('data-id'); + const amenityName = $(this).attr('data-name'); + if ($(this).is(':checked')) { + selectedAmenities[amenityId] = amenityName; + } else { + delete selectedAmenities[amenityId]; + } + const amenitiesList = Object.values(selectedAmenities).join(', '); + $('.selected-amenities').text(amenitiesList); + }); + + $.get('http://0.0.0.0:5001/api/v1/status/', function (data) { + if (data.status === 'OK') { // If the status is 'OK' + $('#api_status').addClass('available'); + } else { + $('#api_status').removeClass('available'); + } + }).fail(function () { + $('#api_status').removeClass('available'); + }); + + $.ajax({ + url: 'http://0.0.0.0:5001/api/v1/places_search/', + type: 'POST', + contentType: 'application/json', + data: JSON.stringify({}), + success: function (data) { + for (const place of data) { + const article = $('
'); + const titleBox = $('
'); + titleBox.append(`

${place.name || ''}

`); + titleBox.append(`
$${place.price_by_night || 0}
`); + article.append(titleBox); + + const infoBox = $('
'); + infoBox.append(`
${place.max_guest || 0} Guest${place.max_guest !== 1 ? 's' : ''}
`); + infoBox.append(`
${place.number_rooms || 0} Bedroom${place.number_rooms !== 1 ? 's' : ''}
`); + infoBox.append(`
${place.number_bathrooms || 0} Bathroom${place.number_bathrooms !== 1 ? 's' : ''}
`); + article.append(infoBox); + + const description = $('
'); + description.html(place.description || ''); + article.append(description); + + $('.places').append(article); + } + }, + error: function (error) { + console.error('Error fetching places:', error); + } + + }); +}); diff --git a/web_dynamic/static/scripts/4-hbnb.js b/web_dynamic/static/scripts/4-hbnb.js new file mode 100644 index 00000000000..c58396af81d --- /dev/null +++ b/web_dynamic/static/scripts/4-hbnb.js @@ -0,0 +1,102 @@ +$(document).ready(function () { + console.log('DOM is Ready') + const selectedAmenities = {}; + + $('input[type="checkbox"]').change(function () { + const amenityId = $(this).attr('data-id'); + const amenityName = $(this).attr('data-name'); + if ($(this).is(':checked')) { + selectedAmenities[amenityId] = amenityName; + } else { + delete selectedAmenities[amenityId]; + } + const amenitiesList = Object.values(selectedAmenities).join(', '); + if (amenitiesList) { + $('.selected-amenities').text(amenitiesList); + } else { + $('.amenities h4').html(' '); + } + }); + + $.get('http://0.0.0.0:5001/api/v1/status/', function (data) { + if (data.status === 'OK') { // If the status is 'OK' + $('#api_status').addClass('available'); + } else { + $('#api_status').removeClass('available'); + } + }).fail(function () { + $('#api_status').removeClass('available'); + }); + + $.ajax({ + url: 'http://0.0.0.0:5001/api/v1/places_search/', + type: 'POST', + contentType: 'application/json', + data: JSON.stringify({}), + success: function (data) { + for (const place of data) { + const article = $('
'); + const titleBox = $('
'); + titleBox.append(`

${place.name || ''}

`); + titleBox.append(`
$${place.price_by_night || 0}
`); + article.append(titleBox); + + const infoBox = $('
'); + infoBox.append(`
${place.max_guest || 0} Guest${place.max_guest !== 1 ? 's' : ''}
`); + infoBox.append(`
${place.number_rooms || 0} Bedroom${place.number_rooms !== 1 ? 's' : ''}
`); + infoBox.append(`
${place.number_bathrooms || 0} Bathroom${place.number_bathrooms !== 1 ? 's' : ''}
`); + article.append(infoBox); + + const description = $('
'); + description.html(place.description || ''); + article.append(description); + + $('.places').append(article); + } + }, + error: function (error) { + console.error('Error fetching places:', error); + } + + }); + function fetchPlaces(data) { + console.log('Data being sent:', data); + $.ajax({ + url: 'http://0.0.0.0:5001/api/v1/places_search/', + type: 'POST', + contentType: 'application/json', + data: JSON.stringify(data), + success: function (places) { + $('.places').empty(); + for (const place of places) { + const article = $('
'); + const titleBox = $('
'); + titleBox.append(`

${place.name || ''}

`); + titleBox.append(`
$${place.price_by_night || 0}
`); + article.append(titleBox); + + const infoBox = $('
'); + infoBox.append(`
${place.max_guest || 0} Guest${place.max_guest !== 1 ? 's' : ''}
`); + infoBox.append(`
${place.number_rooms || 0} Bedroom${place.number_rooms !== 1 ? 's' : ''}
`); + infoBox.append(`
${place.number_bathrooms || 0} Bathroom${place.number_bathrooms !== 1 ? 's' : ''}
`); + article.append(infoBox); + + const description = $('
'); + description.html(place.description || ''); + article.append(description); + + $('.places').append(article); + } + }, + error: function (error) { + console.error('Error fetching places:', error); + } + }); + } + fetchPlaces({}); + $('button').click(function () { + console.log('Button is clicked') + const amenities = Object.keys(selectedAmenities); + fetchPlaces({ amenities: amenities }); + }); +}); diff --git a/web_flask/static/styles/3-footer.css b/web_dynamic/static/styles/3-footer.css similarity index 100% rename from web_flask/static/styles/3-footer.css rename to web_dynamic/static/styles/3-footer.css diff --git a/web_flask/static/styles/3-header.css b/web_dynamic/static/styles/3-header.css similarity index 82% rename from web_flask/static/styles/3-header.css rename to web_dynamic/static/styles/3-header.css index 245cac7c980..3f7385ae3de 100644 --- a/web_flask/static/styles/3-header.css +++ b/web_dynamic/static/styles/3-header.css @@ -9,3 +9,7 @@ header .logo { left: 20px; height: 100%; } + +.available { + background-color: #ff545f; +} \ No newline at end of file diff --git a/web_flask/static/styles/4-common.css b/web_dynamic/static/styles/4-common.css similarity index 100% rename from web_flask/static/styles/4-common.css rename to web_dynamic/static/styles/4-common.css diff --git a/web_flask/static/styles/6-filters.css b/web_dynamic/static/styles/6-filters.css similarity index 100% rename from web_flask/static/styles/6-filters.css rename to web_dynamic/static/styles/6-filters.css diff --git a/web_flask/static/styles/8-places.css b/web_dynamic/static/styles/8-places.css similarity index 100% rename from web_flask/static/styles/8-places.css rename to web_dynamic/static/styles/8-places.css diff --git a/web_flask/static/styles/w3c_validator.py b/web_dynamic/static/styles/w3c_validator.py similarity index 100% rename from web_flask/static/styles/w3c_validator.py rename to web_dynamic/static/styles/w3c_validator.py diff --git a/web_flask/templates/100-hbnb.html b/web_dynamic/templates/0-hbnb.html similarity index 90% rename from web_flask/templates/100-hbnb.html rename to web_dynamic/templates/0-hbnb.html index 776bbb9c999..90beca049f8 100644 --- a/web_flask/templates/100-hbnb.html +++ b/web_dynamic/templates/0-hbnb.html @@ -2,12 +2,12 @@ - - - - - - + + + + + + HBnB diff --git a/web_dynamic/templates/1-hbnb.html b/web_dynamic/templates/1-hbnb.html new file mode 100644 index 00000000000..3179f663203 --- /dev/null +++ b/web_dynamic/templates/1-hbnb.html @@ -0,0 +1,92 @@ + + + + + + HBnB + + + + + + + + + + + + +
+ +
+
+
+
+

States

+

 

+
+
    + {% for state in states %} +
  • +

    {{ state[0].name }}:

    +
      + {% for city in state[1] %} +
    • {{ city.name }}
    • + {% endfor %} +
    +
  • + {% endfor %} +
+
+
+
+

Amenities

+

 

+
+
    + {% for amenity in amenities %} +
  • + + {{ amenity.name }} +
  • + {% endfor %} +
+
+
+ +
+
+

Places

+
+
+ + {% for place, user in places %} +
+
+

{{ place.name }}

+
${{ place.price_by_night }}
+
+
+
{{ place.max_guest }} Guest{% if place.max_guest != 1 %}s{% endif %}
+
{{ place.number_rooms }} Bedroom{% if place.number_rooms != 1 %}s{% endif + %}
+
{{ place.number_bathrooms }} Bathroom{% if place.number_bathrooms != 1 + %}s{% endif %}
+
+
+ Owner: {{ user.first_name }} {{ user.last_name }} +
+
+ {{ place.description | safe }} +
+
+ {% endfor %} +
+
+
+

Holberton School

+
+ + + \ No newline at end of file diff --git a/web_dynamic/templates/100-hbnb.html b/web_dynamic/templates/100-hbnb.html new file mode 100644 index 00000000000..b9e52a5ad61 --- /dev/null +++ b/web_dynamic/templates/100-hbnb.html @@ -0,0 +1,74 @@ + + + + + + HBnB + + + + + + + + + + + + +
+ +
+
+
+
+
+
+

States

+

 

+
+
    + {% for state in states %} +
  • +

    {{ state[0].name }}:

    +
      + {% for city in state[1] %} +
    • {{ city.name }}
    • + {% endfor %} +
    +
  • + {% endfor %} +
+
+
+
+

Amenities

+

 

+
+
    + {% for amenity in amenities %} +
  • + + {{ amenity.name }} +
  • + {% endfor %} +
+
+
+ +
+
+

Places

+
+
+ +
+
+
+

Holberton School

+
+ + + \ No newline at end of file diff --git a/web_dynamic/templates/2-hbnb.html b/web_dynamic/templates/2-hbnb.html new file mode 100644 index 00000000000..3221301f49d --- /dev/null +++ b/web_dynamic/templates/2-hbnb.html @@ -0,0 +1,93 @@ + + + + + + HBnB + + + + + + + + + + + + +
+ +
+
+
+
+
+

States

+

 

+
+
    + {% for state in states %} +
  • +

    {{ state[0].name }}:

    +
      + {% for city in state[1] %} +
    • {{ city.name }}
    • + {% endfor %} +
    +
  • + {% endfor %} +
+
+
+
+

Amenities

+

 

+
+
    + {% for amenity in amenities %} +
  • + + {{ amenity.name }} +
  • + {% endfor %} +
+
+
+ +
+
+

Places

+
+
+ + {% for place, user in places %} +
+
+

{{ place.name }}

+
${{ place.price_by_night }}
+
+
+
{{ place.max_guest }} Guest{% if place.max_guest != 1 %}s{% endif %}
+
{{ place.number_rooms }} Bedroom{% if place.number_rooms != 1 %}s{% endif + %}
+
{{ place.number_bathrooms }} Bathroom{% if place.number_bathrooms != 1 + %}s{% endif %}
+
+
+ Owner: {{ user.first_name }} {{ user.last_name }} +
+
+ {{ place.description | safe }} +
+
+ {% endfor %} +
+
+
+

Holberton School

+
+ + + \ No newline at end of file diff --git a/web_dynamic/templates/3-hbnb.html b/web_dynamic/templates/3-hbnb.html new file mode 100644 index 00000000000..a5d2cea4c2f --- /dev/null +++ b/web_dynamic/templates/3-hbnb.html @@ -0,0 +1,74 @@ + + + + + + HBnB + + + + + + + + + + + + +
+ +
+
+
+
+
+
+

States

+

 

+
+
    + {% for state in states %} +
  • +

    {{ state[0].name }}:

    +
      + {% for city in state[1] %} +
    • {{ city.name }}
    • + {% endfor %} +
    +
  • + {% endfor %} +
+
+
+
+

Amenities

+

 

+
+
    + {% for amenity in amenities %} +
  • + + {{ amenity.name }} +
  • + {% endfor %} +
+
+
+ +
+
+

Places

+
+
+ +
+
+
+

Holberton School

+
+ + + \ No newline at end of file diff --git a/web_dynamic/templates/4-hbnb.html b/web_dynamic/templates/4-hbnb.html new file mode 100644 index 00000000000..dbec52974a7 --- /dev/null +++ b/web_dynamic/templates/4-hbnb.html @@ -0,0 +1,74 @@ + + + + + + HBnB + + + + + + + + + + + + +
+ +
+
+
+
+
+
+

States

+

 

+
+
    + {% for state in states %} +
  • +

    {{ state[0].name }}:

    +
      + {% for city in state[1] %} +
    • {{ city.name }}
    • + {% endfor %} +
    +
  • + {% endfor %} +
+
+
+
+

Amenities

+

 

+
+
    + {% for amenity in amenities %} +
  • + + {{ amenity.name }} +
  • + {% endfor %} +
+
+
+ +
+
+

Places

+
+
+ +
+
+ + + + \ No newline at end of file