Skip to content

Commit

Permalink
Linked the API endpoints from Django to the React Frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
IslamiTP committed Nov 18, 2024
1 parent b441ffc commit bd2936f
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 38 deletions.
20 changes: 10 additions & 10 deletions Backend/category/artcategories/models.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
from django.db import models # Importing Django's models module to define database models
from django.db import models

# Category Model: Represents a category for Types
class Category(models.Model):
name = models.CharField(max_length=100) # 'name' field to store the category name with a max length of 100 characters
name = models.CharField(max_length=100, unique=True) # Ensuring category names are unique to prevent duplicates

# This method returns the name of the category when the model instance is printed
def __str__(self):
return self.name

# Meta class is used to specify metadata about the model
# Here, we specify the plural name of the model as 'categories'
class Meta:
verbose_name_plural = 'categories'

# Type Model: Represents a specific type, associated with a category
class Type(models.Model):
image = models.ImageField(upload_to='uploads/types/') # 'image' field to store an image file, uploaded to the 'uploads/types/' directory
category = models.ForeignKey(Category, on_delete=models.CASCADE, default=1) # ForeignKey field linking each Type to a Category; default is set to 1
name = models.CharField(max_length=200) # 'name' field to store the type name with a max length of 200 characters
description = models.CharField(max_length=500, default='', blank=True, null=True) # Optional description field with max length of 500 characters
image = models.ImageField(upload_to='uploads/types/') # Image field for storing uploaded images
category = models.ForeignKey(
Category,
on_delete=models.CASCADE,
related_name='types' # Optional: allows reverse access from Category to Type
)
name = models.CharField(max_length=200)
description = models.CharField(max_length=500, default='', blank=True, null=True)

# This method returns the name of the type when the model instance is printed
def __str__(self):
return self.name
12 changes: 12 additions & 0 deletions Backend/category/artcategories/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from rest_framework import serializers
from .models import Type, Category

class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'

class TypeSerializer(serializers.ModelSerializer):
class Meta:
model = Type
fields = '__all__'
3 changes: 0 additions & 3 deletions Backend/category/artcategories/tests.py

This file was deleted.

24 changes: 18 additions & 6 deletions Backend/category/artcategories/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
from django.urls import path # Importing 'path' function for defining URL patterns
from . import views # Importing the views module from the current directory
"""artcategory URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.urls import path
from .views import home # Replace 'home' with the actual view functions you have in views.py

# Defining URL patterns for the app
urlpatterns = [
# Mapping the root URL ('') to the 'home' view function
# When a user visits the root of the site (e.g., '/'), the 'home' function will be executed
path('', views.home, name='home'),
path('', home, name='home'), # Ensure the view name matches what's in views.py
]
4 changes: 2 additions & 2 deletions Backend/category/artcategories/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
from django.db.models import Q

def home(request):
query = request.GET.get('q') # get the search query
query = request.GET.get('q')
if query:
types = Type.objects.filter(
Q(name__icontains=query) |
Q(category__name__icontains=query) # search by type name or category name
Q(category__name__icontains=query)
)
else:
types = Type.objects.all()
Expand Down
3 changes: 3 additions & 0 deletions Backend/category/category/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
# Application definition

INSTALLED_APPS = [
'corsheaders',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
Expand All @@ -49,9 +50,11 @@
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ALLOW_ORIGINS = True
ROOT_URLCONF = 'category.urls'

TEMPLATES = [
Expand Down
16 changes: 16 additions & 0 deletions Backend/category/category/urls.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
"""Category URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""

from django.contrib import admin
from django.urls import path, include
from . import settings
Expand Down
24 changes: 24 additions & 0 deletions src/app/backend/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use client";
import { useState, useEffect } from 'react';


const MyPage = () => {
const [message, setMessage] = useState('');


useEffect(() => {
// Make API call to Django backend
fetch('http://127.0.0.1:8000/')
.then(response => response.json())
.then(data => setMessage(data.message))
.catch(error => console.error('Error fetching data:', error));
}, []);


return (
<div>
<h1>{message}</h1>
</div>
);
};
export default MyPage;
67 changes: 50 additions & 17 deletions src/app/homepage/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import barberLogo from '../../public/barber_logo.png'; // Replace with actual lo
import newLogo from '../../public/new_logo.png'; // Replace with actual logo
import Navbar from '../components/navigationbar';
import Image from 'next/image';
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './filter.css';

const SearchBar: React.FC = () => {
const SearchBar: React.FC<{ onSearch: (term: string) => void }> = ({ onSearch }) => {
const [searchTerm, setSearchTerm] = useState('');

const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -25,7 +26,7 @@ const SearchBar: React.FC = () => {

const handleSearchSubmit = (event: React.FormEvent) => {
event.preventDefault();
console.log('Searching for:', searchTerm);
onSearch(searchTerm);
};

return (
Expand All @@ -46,6 +47,29 @@ const SearchBar: React.FC = () => {

export default function Home() {
const router = useRouter();
const [categories, setCategories] = useState([]);
const [searchResults, setSearchResults] = useState([]);

useEffect(() => {
const fetchCategories = async () => {
try {
const response = await axios.get('http://127.0.0.1:8000/api/category/categories/');
setCategories(response.data);
} catch (error) {
console.error('Error fetching categories:', error);
}
};
fetchCategories();
}, []);

const handleSearch = async (term: string) => {
try {
const response = await axios.get(`http://127.0.0.1:8000/api/search/search/?q=${term}`);
setSearchResults(response.data);
} catch (error) {
console.error('Error fetching search results:', error);
}
};

const handleRedirect = () => {
router.push('schedule');
Expand All @@ -55,12 +79,12 @@ export default function Home() {
<div className="min-h-screen flex flex-col bg-white-100">
{/* Logo */}
<div className="bg-black fixed top-0 left-0 inline-flex">
<Image src={logoImage} alt="Logo" width={64} height={30} /> {/* Smaller dimensions */}
<Image src={logoImage} alt="Logo" width={64} height={30} />
</div>

<Navbar />

{/* Main Content Area */}
{/* Header/ Main Content Area */}
<main className="flex-1 p-8 ml-64">
{/* Header */}
<div className="flex flex-col items-center justify-center mb-8 text-center">
Expand All @@ -72,7 +96,27 @@ export default function Home() {
</div>

{/* Search Bar */}
<SearchBar />
<SearchBar onSearch={handleSearch} />

{/* Categories Section */}
<h2 className="text-xl font-bold mt-8">Categories</h2>
<ul className="list-disc ml-6">
{categories.map((category, index) => (
<li key={index}>{category.name}</li>
))}
</ul>

{/* Search Results Section */}
{searchResults.length > 0 && (
<div>
<h2 className="text-xl font-bold mt-8">Search Results</h2>
<ul className="list-disc ml-6">
{searchResults.map((result, index) => (
<li key={index}>{result.name}</li>
))}
</ul>
</div>
)}

{/* Redirect Button */}
<div className="flex justify-center mt-6">
Expand All @@ -96,52 +140,41 @@ export default function Home() {
<nav>
<ul>
<li className="sidebar-item mb-4 flex flex-col items-center group">
{/* Logo for Nail Salon */}
<div className="logo-container">
<Image src={nailSalonLogo} alt="Nail Salon" width={40} height={40} />
</div>
{/* Text for Nail Salon, hidden by default */}
<div className="text-container mt-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<a href="/nailsalon" className="text-lg hover:text-teal-400">Nail Salon</a>
</div>
</li>
<li className="sidebar-item mb-4 flex flex-col items-center group">
{/* Logo for Hair Stylists */}
<div className="logo-container">
<Image src={hairLogo} alt="Hair Stylists" width={40} height={40} />
</div>
{/* Text for Hair Stylists, hidden by default */}
<div className="text-container mt-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<a href="/hair" className="text-lg hover:text-teal-400">Hair Stylists</a>
</div>
</li>
<li className="sidebar-item mb-4 flex flex-col items-center group">
{/* Logo for Tattoo Artists */}
<div className="logo-container">
<Image src={tattooLogo} alt="Tattoo Artist" width={40} height={40} />
</div>
{/* Text for Tattoo Artist, hidden by default */}
<div className="text-container mt-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<a href="/tattoo" className="text-lg hover:text-teal-400">Tattoo Artist</a>
</div>
</li>
<li className="sidebar-item mb-4 flex flex-col items-center group">
{/* Logo for Barber Shops */}
<div className="logo-container">
<Image src={barberLogo} alt="Barber Shops" width={40} height={40} />
</div>
{/* Text for Barber Shops, hidden by default */}
<div className="text-container mt-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<a href="/barber" className="text-lg hover:text-teal-400">Barber Shops</a>
</div>
</li>
{/* New Section: Under 6 Months */}
<li className="sidebar-item mb-4 flex flex-col items-center group">
{/* Logo for Under 6 Months */}
<div className="logo-container">
<Image src={newLogo} alt="Under 6 Months" width={40} height={40} />
</div>
{/* Text for Under 6 Months, hidden by default */}
<div className="text-container mt-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<a href="/under6months" className="text-lg hover:text-teal-400">Under 6 Months</a>
</div>
Expand Down

0 comments on commit bd2936f

Please sign in to comment.