diff --git a/README.md b/README.md index 5884e26a5b..f6b6ebeccb 100644 --- a/README.md +++ b/README.md @@ -1 +1,12 @@ -# coding-project-template \ No newline at end of file +# coding-project-template + +https://github.com/3p1c0w3nd/fullstack_developer_capstone + + +http://127.0.0.1:8000/about + +http://127.0.0.1:8000/contact + + + +http://127.0.0.1:8000/register/ \ No newline at end of file diff --git a/server/database/app.js b/server/database/app.js index 00f52b2008..c73a8ea32b 100644 --- a/server/database/app.js +++ b/server/database/app.js @@ -1,7 +1,7 @@ const express = require('express'); const mongoose = require('mongoose'); const fs = require('fs'); -const cors = require('cors') +const cors = require('cors') const app = express() const port = 3030; @@ -11,7 +11,7 @@ app.use(require('body-parser').urlencoded({ extended: false })); const reviews_data = JSON.parse(fs.readFileSync("reviews.json", 'utf8')); const dealerships_data = JSON.parse(fs.readFileSync("dealerships.json", 'utf8')); -mongoose.connect("mongodb://mongo_db:27017/",{'dbName':'dealershipsDB'}); +mongoose.connect("mongodb://mongo_db:27017/", { 'dbName': 'dealershipsDB' }); const Reviews = require('./review'); @@ -19,13 +19,13 @@ const Reviews = require('./review'); const Dealerships = require('./dealership'); try { - Reviews.deleteMany({}).then(()=>{ + Reviews.deleteMany({}).then(() => { Reviews.insertMany(reviews_data['reviews']); }); - Dealerships.deleteMany({}).then(()=>{ + Dealerships.deleteMany({}).then(() => { Dealerships.insertMany(dealerships_data['dealerships']); }); - + } catch (error) { res.status(500).json({ error: 'Error fetching documents' }); } @@ -33,7 +33,7 @@ try { // Express route to home app.get('/', async (req, res) => { - res.send("Welcome to the Mongoose API") + res.send("Welcome to the Mongoose API") }); // Express route to fetch all reviews @@ -49,7 +49,7 @@ app.get('/fetchReviews', async (req, res) => { // Express route to fetch reviews by a particular dealer app.get('/fetchReviews/dealer/:id', async (req, res) => { try { - const documents = await Reviews.find({dealership: req.params.id}); + const documents = await Reviews.find({ dealership: req.params.id }); res.json(documents); } catch (error) { res.status(500).json({ error: 'Error fetching documents' }); @@ -58,42 +58,60 @@ app.get('/fetchReviews/dealer/:id', async (req, res) => { // Express route to fetch all dealerships app.get('/fetchDealers', async (req, res) => { -//Write your code here + //Write your code here + try { + const documents = await Dealerships.find(); + res.json(documents); + } catch (error) { + res.status(500).json({ error: 'Error fetching documents' }); + } }); // Express route to fetch Dealers by a particular state app.get('/fetchDealers/:state', async (req, res) => { -//Write your code here + //Write your code here + try { + const documents = await Dealerships.find({ state: req.params.state }); + res.json(documents); + } catch (error) { + res.status(500).json({ error: 'Error fetching documents' }); + } }); // Express route to fetch dealer by a particular id app.get('/fetchDealer/:id', async (req, res) => { -//Write your code here + //Write your code here + try { + const documents = await Dealerships.find({ id: req.params.id }); + res.json(documents); + } catch (error) { + res.status(500).json({ error: 'Error fetching documents' }); + } }); //Express route to insert review app.post('/insert_review', express.raw({ type: '*/*' }), async (req, res) => { data = JSON.parse(req.body); - const documents = await Reviews.find().sort( { id: -1 } ) - let new_id = documents[0]['id']+1 + const documents = await Reviews.find().sort({ id: -1 }) + let new_id = documents[0]['id'] + 1 const review = new Reviews({ - "id": new_id, - "name": data['name'], - "dealership": data['dealership'], - "review": data['review'], - "purchase": data['purchase'], - "purchase_date": data['purchase_date'], - "car_make": data['car_make'], - "car_model": data['car_model'], - "car_year": data['car_year'], - }); + "id": new_id, + "name": data['name'], + "dealership": data['dealership'], + "review": data['review'], + "purchase": data['purchase'], + "purchase_date": data['purchase_date'], + "car_make": data['car_make'], + "car_model": data['car_model'], + "car_year": data['car_year'], + }); try { const savedReview = await review.save(); res.json(savedReview); } catch (error) { - console.log(error); + console.log(error); res.status(500).json({ error: 'Error inserting review' }); } }); diff --git a/server/djangoapp/.env b/server/djangoapp/.env index 01822e542a..9f8e6c7ab9 100644 --- a/server/djangoapp/.env +++ b/server/djangoapp/.env @@ -1,2 +1,2 @@ -backend_url =your backend url -sentiment_analyzer_url=your code engine deployment url +backend_url =http://localhost:3030/ +sentiment_analyzer_url=http://127.0.0.1:5000/ diff --git a/server/djangoapp/admin.py b/server/djangoapp/admin.py index 433657fc64..91a2edcb4b 100644 --- a/server/djangoapp/admin.py +++ b/server/djangoapp/admin.py @@ -1,10 +1,12 @@ -# from django.contrib import admin -# from .models import related models +from django.contrib import admin +from .models import CarMake, CarModel # Register your models here. # CarModelInline class +admin.site.register(CarModel) +admin.site.register(CarMake) # CarModelAdmin class diff --git a/server/djangoapp/microservices/Dockerfile b/server/djangoapp/microservices/Dockerfile index 5847b04b5e..d2b6d46673 100644 --- a/server/djangoapp/microservices/Dockerfile +++ b/server/djangoapp/microservices/Dockerfile @@ -7,4 +7,5 @@ COPY requirements.txt requirements.txt RUN pip3 install -r requirements.txt COPY . . RUN ls +EXPOSE 5000 CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"] diff --git a/server/djangoapp/models.py b/server/djangoapp/models.py index eb101a68c8..052a210575 100644 --- a/server/djangoapp/models.py +++ b/server/djangoapp/models.py @@ -1,8 +1,8 @@ # Uncomment the following imports before adding the Model code -# from django.db import models -# from django.utils.timezone import now -# from django.core.validators import MaxValueValidator, MinValueValidator +from django.db import models +from django.utils.timezone import now +from django.core.validators import MaxValueValidator, MinValueValidator # Create your models here. @@ -23,3 +23,30 @@ # - Year (IntegerField) with min value 2015 and max value 2023 # - Any other fields you would like to include in car model # - __str__ method to print a car make object + +class CarMake(models.Model): + name = models.CharField(max_length=100) + description = models.TextField() + #otros campos que se necesiten despues agregar + + def __str__(self): + return self.name + +class CarModel(models.Model): + car_make = models.ForeignKey(CarMake, on_delete=models.CASCADE) + name = models.CharField(max_length=100) + CAR_TYPES = [ + ('SEDAN', 'Sedan'), + ('SUV', 'SUV'), + ('WAGON', 'Wagon'), + ] + typeModel = models.CharField(max_length=100, choices=CAR_TYPES) + year = models.IntegerField(default=2023, + validators=[ + MaxValueValidator(2023), + MinValueValidator(2015) + ]) + #otros campos que se necesiten despues agregar + + def __str__(self): + return self.name diff --git a/server/djangoapp/populate.py b/server/djangoapp/populate.py index 1927e09e18..09cc361f5e 100644 --- a/server/djangoapp/populate.py +++ b/server/djangoapp/populate.py @@ -1,2 +1,38 @@ +from .models import CarMake, CarModel + def initiate(): - print("Populate not implemented. Add data manually") + car_make_data = [ + {"name":"NISSAN", "description":"Great cars. Japanese technology"}, + {"name":"Mercedes", "description":"Great cars. German technology"}, + {"name":"Audi", "description":"Great cars. German technology"}, + {"name":"Kia", "description":"Great cars. Korean technology"}, + {"name":"Toyota", "description":"Great cars. Japanese technology"}, + ] + + car_make_instances = [] + for data in car_make_data: + car_make_instances.append(CarMake.objects.create(name=data['name'], description=data['description'])) + + + # Create CarModel instances with the corresponding CarMake instances + car_model_data = [ + {"name":"Pathfinder", "type":"SUV", "year": 2023, "car_make":car_make_instances[0]}, + {"name":"Qashqai", "type":"SUV", "year": 2023, "car_make":car_make_instances[0]}, + {"name":"XTRAIL", "type":"SUV", "year": 2023, "car_make":car_make_instances[0]}, + {"name":"A-Class", "type":"SUV", "year": 2023, "car_make":car_make_instances[1]}, + {"name":"C-Class", "type":"SUV", "year": 2023, "car_make":car_make_instances[1]}, + {"name":"E-Class", "type":"SUV", "year": 2023, "car_make":car_make_instances[1]}, + {"name":"A4", "type":"SUV", "year": 2023, "car_make":car_make_instances[2]}, + {"name":"A5", "type":"SUV", "year": 2023, "car_make":car_make_instances[2]}, + {"name":"A6", "type":"SUV", "year": 2023, "car_make":car_make_instances[2]}, + {"name":"Sorrento", "type":"SUV", "year": 2023, "car_make":car_make_instances[3]}, + {"name":"Carnival", "type":"SUV", "year": 2023, "car_make":car_make_instances[3]}, + {"name":"Cerato", "type":"Sedan", "year": 2023, "car_make":car_make_instances[3]}, + {"name":"Corolla", "type":"Sedan", "year": 2023, "car_make":car_make_instances[4]}, + {"name":"Camry", "type":"Sedan", "year": 2023, "car_make":car_make_instances[4]}, + {"name":"Kluger", "type":"SUV", "year": 2023, "car_make":car_make_instances[4]}, + # Add more CarModel instances as needed + ] + + for data in car_model_data: + CarModel.objects.create(name=data['name'], car_make=data['car_make'], type=data['type'], year=data['year']) \ No newline at end of file diff --git a/server/djangoapp/restapis.py b/server/djangoapp/restapis.py index 90709d9e3b..8a2229c953 100644 --- a/server/djangoapp/restapis.py +++ b/server/djangoapp/restapis.py @@ -1,5 +1,5 @@ # Uncomment the imports below before you add the function code -# import requests +import requests import os from dotenv import load_dotenv @@ -11,12 +11,41 @@ 'sentiment_analyzer_url', default="http://localhost:5050/") -# def get_request(endpoint, **kwargs): +def get_request(endpoint, **kwargs): + params = "" + if(kwargs): + for key,value in kwargs.items(): + params=params+key+"="+value+"&" + + request_url = backend_url+endpoint+"?"+params + + print("GET from {} ".format(request_url)) + try: + # Call get method of requests library with URL and parameters + response = requests.get(request_url) + return response.json() + except: + # If any error occurs + print("Network exception occurred") # Add code for get requests to back end -# def analyze_review_sentiments(text): -# request_url = sentiment_analyzer_url+"analyze/"+text -# Add code for retrieving sentiments +def analyze_review_sentiments(text): + request_url = sentiment_analyzer_url+"analyze/"+text + try: + # Call get method of requests library with URL and parameters + response = requests.get(request_url) + return response.json() + except Exception as err: + print(f"Unexpected {err=}, {type(err)=}") + print("Network exception occurred") + + -# def post_review(data_dict): -# Add code for posting review +def post_review(data_dict): + request_url = backend_url+"/insert_review" + try: + response = requests.post(request_url,json=data_dict) + print(response.json()) + return response.json() + except: + print("Network exception occurred") diff --git a/server/djangoapp/urls.py b/server/djangoapp/urls.py index 0edc274f90..bd1c6273c3 100644 --- a/server/djangoapp/urls.py +++ b/server/djangoapp/urls.py @@ -1,15 +1,23 @@ # Uncomment the imports before you add the code -# from django.urls import path +from django.urls import path from django.conf.urls.static import static from django.conf import settings -# from . import views +from . import views app_name = 'djangoapp' urlpatterns = [ # # path for registration # path for login - # path(route='login', view=views.login_user, name='login'), + path(route='login', view=views.login_user, name='login'), + path(route='logout', view=views.logout_request, name='logout'), + path(route='register', view=views.registration, name='register'), + path(route='get_cars', view=views.get_cars, name ='getcars'), + path(route='get_dealers', view=views.get_dealerships, name='get_dealers'), + path(route='get_dealers/', view=views.get_dealerships, name='get_dealers_by_state'), + path(route='dealer/', view=views.get_dealer_details, name='dealer_details'), + path(route='reviews/dealer/', view=views.get_dealer_reviews, name='dealer_details'), + path(route='add_review', view=views.add_review, name='add_review'), # path for dealer reviews view diff --git a/server/djangoapp/views.py b/server/djangoapp/views.py index b16409f419..f5e3ae755c 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -1,20 +1,21 @@ # Uncomment the required imports before adding the code -# from django.shortcuts import render -# from django.http import HttpResponseRedirect, HttpResponse -# from django.contrib.auth.models import User -# from django.shortcuts import get_object_or_404, render, redirect -# from django.contrib.auth import logout -# from django.contrib import messages -# from datetime import datetime +from django.shortcuts import render +from django.http import HttpResponseRedirect, HttpResponse +from django.contrib.auth.models import User +from django.shortcuts import get_object_or_404, render, redirect +from django.contrib.auth import logout +from django.contrib import messages +from datetime import datetime from django.http import JsonResponse from django.contrib.auth import login, authenticate import logging import json from django.views.decorators.csrf import csrf_exempt -# from .populate import initiate - +from .models import CarMake, CarModel +from .populate import initiate +from .restapis import get_request, analyze_review_sentiments, post_review # Get an instance of a logger logger = logging.getLogger(__name__) @@ -39,27 +40,100 @@ def login_user(request): return JsonResponse(data) # Create a `logout_request` view to handle sign out request -# def logout_request(request): -# ... +def logout_request(request): + logout(request) # Terminate user session + data = {"userName":""} # Return empty username + return JsonResponse(data) # Create a `registration` view to handle sign up request -# @csrf_exempt -# def registration(request): -# ... +@csrf_exempt +def registration(request): + context = {} + # Load JSON data from the request body + data = json.loads(request.body) + username = data['userName'] + password = data['password'] + first_name = data['firstName'] + last_name = data['lastName'] + email = data['email'] + username_exist = False + email_exist = False + try: + # Check if user already exists + User.objects.get(username=username) + username_exist = True + except: + # If not, simply log this is a new user + logger.debug("{} is new user".format(username)) + # If it is a new user + if not username_exist: + # Create user in auth_user table + user = User.objects.create_user(username=username, first_name=first_name, last_name=last_name,password=password, email=email) + # Login the user and redirect to list page + login(request, user) + data = {"userName":username,"status":"Authenticated"} + return JsonResponse(data) + else : + data = {"userName":username,"error":"Already Registered"} + return JsonResponse(data) + + + +def get_cars(request): + count = CarMake.objects.filter().count() + print(count) + if(count == 0): + initiate() + car_models = CarModel.objects.select_related('car_make') + cars = [] + for car_model in car_models: + cars.append({"CarModel": car_model.name, "CarMake": car_model.car_make.name}) + return JsonResponse({"CarModels":cars}) # # Update the `get_dealerships` view to render the index page with # a list of dealerships -# def get_dealerships(request): +def get_dealerships(request, state="All"): + if(state == "All"): + endpoint = "/fetchDealers" + else: + endpoint = "/fetchDealers/"+state + dealerships = get_request(endpoint) + return JsonResponse({"status":200,"dealers":dealerships}) # ... # Create a `get_dealer_reviews` view to render the reviews of a dealer -# def get_dealer_reviews(request,dealer_id): +def get_dealer_reviews(request, dealer_id): + # if dealer id has been provided + if(dealer_id): + endpoint = "/fetchReviews/dealer/"+str(dealer_id) + reviews = get_request(endpoint) + for review_detail in reviews: + response = analyze_review_sentiments(review_detail['review']) + print(response) + review_detail['sentiment'] = response['sentiment'] + return JsonResponse({"status":200,"reviews":reviews}) + else: + return JsonResponse({"status":400,"message":"Bad Request"}) # ... # Create a `get_dealer_details` view to render the dealer details -# def get_dealer_details(request, dealer_id): +def get_dealer_details(request, dealer_id): + if(dealer_id): + endpoint = "/fetchDealer/"+str(dealer_id) + dealership = get_request(endpoint) + return JsonResponse({"status":200,"dealer":dealership}) + else: + return JsonResponse({"status":400,"message":"Bad Request"}) # ... # Create a `add_review` view to submit a review -# def add_review(request): -# ... +def add_review(request): + if(request.user.is_anonymous == False): + data = json.loads(request.body) + try: + response = post_review(data) + return JsonResponse({"status":200}) + except: + return JsonResponse({"status":401,"message":"Error in posting review"}) + else: + return JsonResponse({"status":403,"message":"Unauthorized"}) diff --git a/server/djangoproj/settings.py b/server/djangoproj/settings.py index e0b1092a5c..9ecd2b7421 100644 --- a/server/djangoproj/settings.py +++ b/server/djangoproj/settings.py @@ -61,7 +61,11 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [ + os.path.join(BASE_DIR, 'frontend/static'),#Para que reconosca los archivos estaticos de la aplicacion + os.path.join(BASE_DIR, 'frontend/build'), + os.path.join(BASE_DIR, 'frontend/build/static'), + ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -134,5 +138,9 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' -STATICFILES_DIRS = [] +STATICFILES_DIRS = [ + os.path.join(BASE_DIR, 'frontend/static'), + os.path.join(BASE_DIR, 'frontend/build'), + os.path.join(BASE_DIR, 'frontend/build/static'), +] diff --git a/server/djangoproj/urls.py b/server/djangoproj/urls.py index 6808da9141..41165289ac 100644 --- a/server/djangoproj/urls.py +++ b/server/djangoproj/urls.py @@ -21,6 +21,13 @@ urlpatterns = [ path('admin/', admin.site.urls), + path('login/', TemplateView.as_view(template_name="index.html")), + path('register/', TemplateView.as_view(template_name="index.html")), + path('dealers/', TemplateView.as_view(template_name="index.html")), + path('dealer/', TemplateView.as_view(template_name="index.html")), + path('postreview/', TemplateView.as_view(template_name="index.html")), path('djangoapp/', include('djangoapp.urls')), path('', TemplateView.as_view(template_name="Home.html")), + path('about', TemplateView.as_view(template_name="About.html")), + path('contact', TemplateView.as_view(template_name="Contact.html")), ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/server/frontend/package-lock.json b/server/frontend/package-lock.json index 0797425307..bdb21fad35 100644 --- a/server/frontend/package-lock.json +++ b/server/frontend/package-lock.json @@ -16,6 +16,9 @@ "react-router-dom": "^6.19.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "@babel/plugin-proposal-private-property-in-object": "^7.21.11" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -646,9 +649,18 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "version": "7.21.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz", + "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, "engines": { "node": ">=6.9.0" }, @@ -1891,6 +1903,18 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", diff --git a/server/frontend/src/App.js b/server/frontend/src/App.js index aceac6974d..88aab7282b 100644 --- a/server/frontend/src/App.js +++ b/server/frontend/src/App.js @@ -1,10 +1,19 @@ import LoginPanel from "./components/Login/Login" +import Register from "./components/Register/Register" +import Dealers from './components/Dealers/Dealers' +import Dealer from './components/Dealers/Dealer' +import PostReview from './components/Dealers/PostReview' import { Routes, Route } from "react-router-dom"; + function App() { return ( } /> + } /> + } /> + } /> + } /> ); } diff --git a/server/frontend/src/components/Register/Register.jsx b/server/frontend/src/components/Register/Register.jsx new file mode 100644 index 0000000000..a38f37a42d --- /dev/null +++ b/server/frontend/src/components/Register/Register.jsx @@ -0,0 +1,101 @@ +import React, { useState } from "react"; +import "./Register.css"; +import user_icon from "../assets/person.png" +import email_icon from "../assets/email.png" +import password_icon from "../assets/password.png" +import close_icon from "../assets/close.png" + +const Register = () => { + // State variables for form inputs + const [userName, setUserName] = useState(""); + const [password, setPassword] = useState(""); + const [email, setEmail] = useState(""); + const [firstName, setFirstName] = useState(""); + const [lastName, setlastName] = useState(""); + + // Redirect to home + const gohome = () => { + window.location.href = window.location.origin; + } + + // Handle form submission + const register = async (e) => { + e.preventDefault(); + + let register_url = window.location.origin + "/djangoapp/register"; + + // Send POST request to register endpoint + const res = await fetch(register_url, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + "userName": userName, + "password": password, + "firstName": firstName, + "lastName": lastName, + "email": email + }), + }); + + const json = await res.json(); + if (json.status) { + // Save username in session and reload home + sessionStorage.setItem('username', json.userName); + window.location.href = window.location.origin; + } + else if (json.error === "Already Registered") { + alert("The user with same username is already registered"); + window.location.href = window.location.origin; + } + }; + + return ( +
+ + +
+
+
+ Username + setUserName(e.target.value)} /> +
+
+ First Name + setFirstName(e.target.value)} /> +
+ +
+ Last Name + setlastName(e.target.value)} /> +
+ +
+ Email + setEmail(e.target.value)} /> +
+ +
+ password + setPassword(e.target.value)} /> +
+ +
+
+ +
+
+
+ ) +} + +export default Register; \ No newline at end of file diff --git a/server/frontend/static/About.html b/server/frontend/static/About.html index 484efd960f..42689b3782 100644 --- a/server/frontend/static/About.html +++ b/server/frontend/static/About.html @@ -1,68 +1,85 @@ + + +
-
+ - + \ No newline at end of file diff --git a/server/frontend/static/Contact.html b/server/frontend/static/Contact.html new file mode 100644 index 0000000000..3e640dbb69 --- /dev/null +++ b/server/frontend/static/Contact.html @@ -0,0 +1,141 @@ + + + + + + + + + + + +
+ +
+ + + + +
+
+
+ +

Contact Us

+
+ +
+
+ +
+ +
+
+ +
+ +
+

123-456-7890

+
+
+ +
+ +
+

Colombia, Bogotá

+
+
+
+ + +
+
+ + + + + + \ No newline at end of file diff --git a/server/frontend/static/Home.html b/server/frontend/static/Home.html index fb0c3fb617..ade699e4d9 100644 --- a/server/frontend/static/Home.html +++ b/server/frontend/static/Home.html @@ -1,64 +1,89 @@ + - - + + - + if (curr_user && curr_user !== "") { + document.getElementById("loginlogout").innerHTML = + '' + curr_user + '' + + 'Logout' + } else { + document.getElementById("loginlogout").innerHTML = + 'Login' + + 'Register' + } + } + + - -
-
- ... - -
-
- + + \ No newline at end of file diff --git a/server/frontend/static/person.png b/server/frontend/static/person.png deleted file mode 100644 index 72ce98a965..0000000000 Binary files a/server/frontend/static/person.png and /dev/null differ diff --git a/server/frontend/static/person1.png b/server/frontend/static/person1.png new file mode 100644 index 0000000000..837d338b29 Binary files /dev/null and b/server/frontend/static/person1.png differ diff --git a/server/frontend/static/person2.png b/server/frontend/static/person2.png new file mode 100644 index 0000000000..06595c41e6 Binary files /dev/null and b/server/frontend/static/person2.png differ diff --git a/server/frontend/static/person3.png b/server/frontend/static/person3.png new file mode 100644 index 0000000000..6efcd3315b Binary files /dev/null and b/server/frontend/static/person3.png differ diff --git a/server/frontend/static/style.css b/server/frontend/static/style.css index 0543af014a..e7791eaf59 100644 --- a/server/frontend/static/style.css +++ b/server/frontend/static/style.css @@ -1,81 +1,82 @@ -img{ +img { width: 60%; align-self: center; } -.card{ +.card { border: rgb(103, 102, 105) 3px solid; - display: flex; + display: flex; flex-direction: column; - margin-left:5%; - margin-right:5%; + margin-left: 5%; + margin-right: 5%; margin-top: 1%; margin-bottom: 1%; } -.row{ - display: flex; +.row { + display: flex; flex: 1; flex-direction: row; margin: auto; margin-top: 1%; justify-content: center; - padding:20px; + padding: 20px; } -.container{ +.container { justify-content: center; } -.details{ + +.details { font-size: 20px; color: rgb(97, 64, 128); - padding:20px; + padding: 20px; } -.title{ +.title { font-size: 20px; background-color: rgb(97, 64, 128); color: white; text-align: center; - margin:20px; - padding:5px; + margin: 20px; + padding: 5px; } -.homepage_links{ - color: rgb(97, 64, 128); +.homepage_links { + color: rgb(97, 64, 128); padding: 25%; font-size: larger; - } +} -.loginlink{ +.loginlink { display: flex; flex-direction: row; justify-content: flex-end; } -.banner{ +.banner { display: flex; flex-direction: column; align-items: center; justify-content: center; - flex:1 + flex: 1 } .form_panel { - padding:2%; + padding: 2%; display: flex; flex-direction: column; border-radius: 50px; - text-align:center; + text-align: center; box-shadow: 2px 2px 2px 3px #999; margin: auto; min-width: 350px; width: 80%; - margin-top:3%; + margin-top: 3%; background-color: black; } -.navitems{ +.navitems { display: flex; flex-direction: row; padding: 20px; @@ -84,18 +85,20 @@ img{ justify-self: center; } -.nav_item{ - margin-left:15px; +.nav_item { + margin-left: 15px; font-size: 20px; color: black; align-self: center; } -.username{ + + +.username { font: 30px sans-serif; - color:black; + color: black; justify-content: 'flex-end'; - align-self:flex-end; + align-self: flex-end; vertical-align: middle; } @@ -104,23 +107,23 @@ img{ flex-direction: row; padding: 20px; flex: 1; - justify-content:flex-end; + justify-content: flex-end; align-items: flex-end; vertical-align: middle; } -.small_header{ +.small_header { font: 30px sans-serif; - color:black; + color: black; margin: .5cm; } .img_icon { align-self: center; - width:40px; - background-color:#0C9; - color:#FFF; - border-radius:50px; - text-align:center; - box-shadow: 2px 2px 3px #999; -} + width: 40px; + background-color: #0C9; + color: #FFF; + border-radius: 50px; + text-align: center; + box-shadow: 2px 2px 3px #999; +} \ No newline at end of file