diff --git a/java-apps/CitiesApp/CitiesGUI.java b/java-apps/CitiesApp/CitiesGUI.java new file mode 100644 index 0000000000..9769b6501c --- /dev/null +++ b/java-apps/CitiesApp/CitiesGUI.java @@ -0,0 +1,56 @@ +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +public class CitiesGUI extends JFrame { + private List cities; + + public CitiesGUI() { + super("Cities Viewer"); + cities = loadCities("../data/cities.txt"); + setupUI(); + } + + private List loadCities(String path) { + List list = new ArrayList<>(); + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + String[] parts = line.split("#"); + if (parts.length == 11) { + String ref = parts[0]; + String nameGR = parts[1]; + String gender = parts[8]; + String nameEN = parts[9]; + String state = parts[10]; + list.add(new City(ref, nameGR, gender, nameEN, state)); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return list; + } + + private void setupUI() { + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + String[] columns = {"Greek Name", "Gender", "English Name", "State"}; + DefaultTableModel model = new DefaultTableModel(columns, 0); + for (City c : cities) { + model.addRow(new Object[]{c.getNameGR(), c.getGender(), c.getNameEN(), c.getState()}); + } + JTable table = new JTable(model); + add(new JScrollPane(table), BorderLayout.CENTER); + setSize(600, 400); + setLocationRelativeTo(null); + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> new CitiesGUI().setVisible(true)); + } +} diff --git a/java-apps/CitiesApp/City.java b/java-apps/CitiesApp/City.java new file mode 100644 index 0000000000..ec4ae9da84 --- /dev/null +++ b/java-apps/CitiesApp/City.java @@ -0,0 +1,21 @@ +public class City { + private String ref; + private String nameGR; + private String gender; + private String nameEN; + private String state; + + public City(String ref, String nameGR, String gender, String nameEN, String state) { + this.ref = ref; + this.nameGR = nameGR; + this.gender = gender; + this.nameEN = nameEN; + this.state = state; + } + + public String getRef() { return ref; } + public String getNameGR() { return nameGR; } + public String getGender() { return gender; } + public String getNameEN() { return nameEN; } + public String getState() { return state; } +} diff --git a/java-apps/NamedEntitiesApp/NamedEntitiesGUI.java b/java-apps/NamedEntitiesApp/NamedEntitiesGUI.java new file mode 100644 index 0000000000..59ee383262 --- /dev/null +++ b/java-apps/NamedEntitiesApp/NamedEntitiesGUI.java @@ -0,0 +1,56 @@ +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +public class NamedEntitiesGUI extends JFrame { + private List entities; + + public NamedEntitiesGUI() { + super("Named Entities Viewer"); + entities = loadEntities("../data/namedEntities.txt"); + setupUI(); + } + + private List loadEntities(String path) { + List list = new ArrayList<>(); + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + String[] parts = line.split("#"); + if (parts.length == 11) { + String ref = parts[0]; + String nameGR = parts[1]; + String gender = parts[8]; + String nameEN = parts[9]; + String type = parts[10]; + list.add(new NamedEntity(ref, nameGR, gender, nameEN, type)); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return list; + } + + private void setupUI() { + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + String[] columns = {"Greek Name", "Gender", "English Name", "Type"}; + DefaultTableModel model = new DefaultTableModel(columns, 0); + for (NamedEntity e : entities) { + model.addRow(new Object[]{e.getNameGR(), e.getGender(), e.getNameEN(), e.getType()}); + } + JTable table = new JTable(model); + add(new JScrollPane(table), BorderLayout.CENTER); + setSize(700, 400); + setLocationRelativeTo(null); + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> new NamedEntitiesGUI().setVisible(true)); + } +} diff --git a/java-apps/NamedEntitiesApp/NamedEntity.java b/java-apps/NamedEntitiesApp/NamedEntity.java new file mode 100644 index 0000000000..575771503b --- /dev/null +++ b/java-apps/NamedEntitiesApp/NamedEntity.java @@ -0,0 +1,21 @@ +public class NamedEntity { + private String ref; + private String nameGR; + private String gender; + private String nameEN; + private String type; + + public NamedEntity(String ref, String nameGR, String gender, String nameEN, String type) { + this.ref = ref; + this.nameGR = nameGR; + this.gender = gender; + this.nameEN = nameEN; + this.type = type; + } + + public String getRef() { return ref; } + public String getNameGR() { return nameGR; } + public String getGender() { return gender; } + public String getNameEN() { return nameEN; } + public String getType() { return type; } +} diff --git a/java-apps/README.md b/java-apps/README.md new file mode 100644 index 0000000000..352d9d91c3 --- /dev/null +++ b/java-apps/README.md @@ -0,0 +1,24 @@ +# Java GUI Applications + +This folder contains two simple Swing applications used for the university course "Methodologies for Application Development". + +- **CitiesApp** – Reads `data/cities.txt` and displays a table with Greek and English names of selected cities. +- **NamedEntitiesApp** – Reads `data/namedEntities.txt` and displays a table with different named entities such as museums or airports. + +Data files are encoded in UTF-8 and follow the format described in the assignment specification. + +To run an application use: + +```bash +javac CitiesApp/*.java +java -cp CitiesApp CitiesGUI +``` + +or + +```bash +javac NamedEntitiesApp/*.java +java -cp NamedEntitiesApp NamedEntitiesGUI +``` + +The GUI simply lists the items and does not implement advanced features. diff --git a/java-apps/data/cities.txt b/java-apps/data/cities.txt new file mode 100644 index 0000000000..9f9cbcb93b --- /dev/null +++ b/java-apps/data/cities.txt @@ -0,0 +1,3 @@ +1#Αθήνα#Αθήνα#Αθήνας#Αθήνα#Αθήνα#Αθήνα#Αθήνα#feminine#Athens#Attica +2#Θεσσαλονίκη#Θεσσαλονίκη#Θεσσαλονίκης#Θεσσαλονίκη#Θεσσαλονίκη#Θεσσαλονίκη#Θεσσαλονίκη#feminine#Thessaloniki#Central Macedonia +3#Πάτρα#Πάτρα#Πάτρας#Πάτρα#Πάτρα#Πάτρα#Πάτρα#feminine#Patras#Western Greece diff --git a/java-apps/data/namedEntities.txt b/java-apps/data/namedEntities.txt new file mode 100644 index 0000000000..b4a1f37072 --- /dev/null +++ b/java-apps/data/namedEntities.txt @@ -0,0 +1,3 @@ +1#Εθνική Πινακοθήκη#Εθνική Πινακοθήκη#Εθνικής Πινακοθήκης#Εθνική Πινακοθήκη#Εθνική Πινακοθήκη#Εθνική Πινακοθήκη#Εθνική Πινακοθήκη#feminine#National Gallery#Museum +2#Πανεπιστήμιο Αθηνών#Πανεπιστήμιο Αθηνών#Πανεπιστημίου Αθηνών#Πανεπιστήμιο Αθηνών#Πανεπιστήμιο Αθηνών#Πανεπιστήμιο Αθηνών#Πανεπιστήμιο Αθηνών#neuter#University of Athens#University +3#Διεθνές Αεροδρόμιο Αθηνών#Διεθνές Αεροδρόμιο Αθηνών#Διεθνούς Αεροδρομίου Αθηνών#Διεθνές Αεροδρόμιο Αθηνών#Διεθνές Αεροδρόμιο Αθηνών#Διεθνές Αεροδρόμιο Αθηνών#Διεθνές Αεροδρόμιο Αθηνών#neuter#Athens International Airport#Airport diff --git a/server/database/app.js b/server/database/app.js index 00f52b2008..6f7b573ad0 100644 --- a/server/database/app.js +++ b/server/database/app.js @@ -13,19 +13,16 @@ const dealerships_data = JSON.parse(fs.readFileSync("dealerships.json", 'utf8')) mongoose.connect("mongodb://mongo_db:27017/",{'dbName':'dealershipsDB'}); - +const Dealerships = require('./dealership'); const Reviews = require('./review'); -const Dealerships = require('./dealership'); + try { - Reviews.deleteMany({}).then(()=>{ - Reviews.insertMany(reviews_data['reviews']); - }); - Dealerships.deleteMany({}).then(()=>{ - Dealerships.insertMany(dealerships_data['dealerships']); - }); - + await Dealerships.deleteMany({}); + await Dealerships.insertMany(dealerships_data['dealerships']); + await Reviews.deleteMany({}); + await Reviews.insertMany(reviews_data['reviews']); } catch (error) { res.status(500).json({ error: 'Error fetching documents' }); } @@ -58,19 +55,45 @@ app.get('/fetchReviews/dealer/:id', async (req, res) => { // Express route to fetch all dealerships app.get('/fetchDealers', async (req, res) => { -//Write your code here + try { + console.log("fetchDealers endpoint hit"); + const dealers = await Dealerships.find(); + res.json(dealers); + } catch (error) { + res.status(500).json({ message: error.message }); + } }); // Express route to fetch Dealers by a particular state -app.get('/fetchDealers/:state', async (req, res) => { -//Write your code here +app.get('/fetchDealer/:state', async (req, res) => { + try { + const dealer = await Dealerships.find({st: req.params.state}); + if (dealer) { + res.status(200).json(dealer); + } else { + res.status(404).json({ message: 'Dealer not found' }); + } + } catch (error) { + res.status(500).json({ message: error.message }); + } }); + // Express route to fetch dealer by a particular id app.get('/fetchDealer/:id', async (req, res) => { -//Write your code here + try { + const dealer = await Dealerships.find({id: req.params.id}); + if (dealer) { + res.status(200).json(dealer); + } else { + res.status(404).json({ message: 'Dealer not found' }); + } + } catch (error) { + res.status(500).json({ message: error.message }); + } }); + //Express route to insert review app.post('/insert_review', express.raw({ type: '*/*' }), async (req, res) => { data = JSON.parse(req.body); diff --git a/server/database/dealership.js b/server/database/dealership.js index b10d6b4730..d045641bf1 100644 --- a/server/database/dealership.js +++ b/server/database/dealership.js @@ -15,6 +15,10 @@ const dealerships = new Schema({ type: String, required: true }, + st :{ + type: String, + required:true + }, address: { type: String, required: true @@ -24,11 +28,11 @@ const dealerships = new Schema({ required: true }, lat: { - type: String, + type: Number, required: true }, long: { - type: String, + type: Number, required: true }, short_name: { diff --git a/server/djangoapp/admin.py b/server/djangoapp/admin.py index 433657fc64..6473e4fdc5 100644 --- a/server/djangoapp/admin.py +++ b/server/djangoapp/admin.py @@ -1,8 +1,8 @@ -# from django.contrib import admin -# from .models import related models - - -# Register your models here. +from django.contrib import admin +from .models import CarMake, CarModel +# Registering models with their respective admins +admin.site.register(CarMake) +admin.site.register(CarModel) # CarModelInline class diff --git a/server/djangoapp/models.py b/server/djangoapp/models.py index eb101a68c8..d518106da6 100644 --- a/server/djangoapp/models.py +++ b/server/djangoapp/models.py @@ -1,25 +1,41 @@ -# Uncomment the following imports before adding the Model code +from django.db import models +from datetime import datetime +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. +class CarMake(models.Model): + name = models.CharField(max_length=100) + description = models.TextField() -# Create a Car Make model `class CarMake(models.Model)`: -# - Name -# - Description -# - Any other fields you would like to include in car make model -# - __str__ method to print a car make object + def __str__(self): + return self.name -# Create a Car Model model `class CarModel(models.Model):`: -# - Many-To-One relationship to Car Make model (One Car Make has many -# Car Models, using ForeignKey field) -# - Name -# - Type (CharField with a choices argument to provide limited choices -# such as Sedan, SUV, WAGON, etc.) -# - 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 CarModel(models.Model): + car_make = models.ForeignKey(CarMake, on_delete=models.CASCADE) # Establishes Many-to-One relationship + name = models.CharField(max_length=100) + dealer_id = models.IntegerField() # Refers to a dealer in another database (e.g., Cloudant) + + # Car types with limited choices + CAR_TYPES = [ + ('SEDAN', 'Sedan'), + ('SUV', 'SUV'), + ('WAGON', 'Wagon'), + # Add more types if needed + ] + type = models.CharField(max_length=10, choices=CAR_TYPES, default='SUV') + + # Year of manufacture with validators + year = models.IntegerField( + validators=[ + MaxValueValidator(datetime.now().year), + MinValueValidator(1980) + ], + default=datetime.now().year + ) + + def __str__(self): + return f"{self.car_make.name} {self.name}" \ No newline at end of file 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..966f603035 100644 --- a/server/djangoapp/restapis.py +++ b/server/djangoapp/restapis.py @@ -2,6 +2,7 @@ # import requests import os from dotenv import load_dotenv +import requests load_dotenv() @@ -11,12 +12,38 @@ 'sentiment_analyzer_url', default="http://localhost:5050/") -# def get_request(endpoint, **kwargs): -# Add code for get requests to back end +def get_request(endpoint, **kwargs): + params = "" + if(kwargs): + for key,value in kwargs.items(): + params=params+key+"="+value+"&" -# def analyze_review_sentiments(text): -# request_url = sentiment_analyzer_url+"analyze/"+text -# Add code for retrieving sentiments + request_url = backend_url+endpoint+"?"+params -# def post_review(data_dict): -# Add code for posting review + 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") + +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): + 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..1e2fc6b6a3 100644 --- a/server/djangoapp/urls.py +++ b/server/djangoapp/urls.py @@ -1,15 +1,22 @@ # 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, name="logout"), + 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('reviews/', views.get_dealer_reviews, name='dealer_reviews'), + 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..e45636744a 100644 --- a/server/djangoapp/views.py +++ b/server/djangoapp/views.py @@ -1,19 +1,20 @@ -# 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 .restapis import get_request,analyze_review_sentiments,post_review +from .populate import initiate +from .models import CarMake, CarModel # Get an instance of a logger @@ -37,29 +38,63 @@ def login_user(request): login(request, user) data = {"userName": username, "status": "Authenticated"} return JsonResponse(data) - -# Create a `logout_request` view to handle sign out request -# def logout_request(request): -# ... +def logout(request): + data = {"userName":""} + return JsonResponse(data) # Create a `registration` view to handle sign up request # @csrf_exempt # def registration(request): # ... +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): -# ... -# Create a `get_dealer_reviews` view to render the reviews of a dealer -# def get_dealer_reviews(request,dealer_id): -# ... +#Update the `get_dealerships` render list of dealerships all by default, particular state if state is passed +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_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 get_dealer_reviews(request, dealer_id): + if dealer_id: + endpoint = f"/fetchReviews/dealer/{dealer_id}" + reviews = get_request(endpoint) + + # Add sentiment analysis for each review + for review in reviews: + review['sentiment'] = analyze_review_sentiments(review["review_text"]) + + return JsonResponse({"status": 200, "reviews": reviews}) + else: + return JsonResponse({"status": 400, "message": "Bad 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..766f0d42d2 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'), + os.path.join(BASE_DIR, 'frontend/build'), + os.path.join(BASE_DIR, 'frontend/build/static'), + ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -134,5 +138,10 @@ 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..c0c2c01684 100644 --- a/server/djangoproj/urls.py +++ b/server/djangoproj/urls.py @@ -22,5 +22,10 @@ urlpatterns = [ path('admin/', admin.site.urls), path('djangoapp/', include('djangoapp.urls')), + path('about/', TemplateView.as_view(template_name="About.html")), + path('contact/', TemplateView.as_view(template_name="Contact.html")), path('', TemplateView.as_view(template_name="Home.html")), + 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")), ] + 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..b9244446c9 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,17 @@ } }, "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, + "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 +1902,17 @@ "@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==", + "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..4e0efc8b8f 100644 --- a/server/frontend/src/App.js +++ b/server/frontend/src/App.js @@ -1,10 +1,14 @@ import LoginPanel from "./components/Login/Login" +import RegisterPannel from "./components/Register/Register" +import Dealers from './components/Dealers/Dealers'; 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..9f1a290327 --- /dev/null +++ b/server/frontend/src/components/Register/Register.jsx @@ -0,0 +1,98 @@ +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 = () => { + + const [userName, setUserName] = useState(""); + const [password, setPassword] = useState(""); + const [email, setEmail] = useState(""); + const [firstName, setFirstName] = useState(""); + const [lastName, setlastName] = useState(""); + + + const gohome = ()=> { + window.location.href = window.location.origin; + } + + const register = async (e) => { + e.preventDefault(); + + let register_url = window.location.origin+"/djangoapp/register"; + + 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) { + 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..904515faa3 100644 --- a/server/frontend/static/About.html +++ b/server/frontend/static/About.html @@ -1,6 +1,8 @@ - + + +