Skip to content

Initial #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 54 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,51 @@


## Basic Details
### Team Name: [Name]
### Team Name: [Spark]


### Team Members
- Member 1: [Name] - [College]
- Member 2: [Name] - [College]
- Member 3: [Name] - [College]
- Member 1: [Sreepriya K M] - [Model Engineering College]
- Member 2: [Esha Susan Shaji] - [Model Engineering College]
- Member 3: [Rose Francis] - [Model Engineering College]

### Hosted Project Link
[mention your project hosted project link here]

### Project Description
[2-3 lines about what your project does]
[Cancer Support Network - Connecting Donors to Cancer Assistance Organizations

Our website serves as a platform that connects generous donors with organizations dedicated to helping cancer patients. The platform offers valuable information about cancer, its impacts, and available support options.

Key Features:

Login Page: Users can securely log in to their accounts to access personalized content.

User Registration: Users can register as either a Donor or an Organization. Donors can make a significant impact by contributing to organizations in need, while organizations can showcase their work and gain support.

Organization List: Donors can explore a comprehensive list of registered organizations. The list is sortable by:

Emergency Need: Helping donors prioritize organizations in urgent need of assistance.
Number of Patients Helped: Allows donors to understand the scale of support each organization is providing.
Important Cancer Information: The website provides users with essential cancer-related information to raise awareness and educate visitors on various aspects of cancer care and support.

This platform ensures that donors can make informed decisions about where to direct their support, while organizations gain visibility and assistance from the community.]



### The Problem statement
[What ridiculous problem are you solving?]
[Cancer organizations often struggle to secure sufficient funding and support, while donors face difficulty finding trustworthy causes to contribute to. There is a need for a platform that connects donors with organizations helping cancer patients, allowing donors to easily find and support organizations based on urgency and impact. This platform will help donors make informed decisions while ensuring that organizations receive the resources needed to continue their work.]

### The Solution
[How are you solving it? Keep it fun!]
[We’ve created a web platform that connects donors with cancer support organizations. Donors can explore a list of registered organizations, sort them by urgency and impact, and make informed contributions to those in need, helping organizations get the support they require to assist cancer patients.]

## Technical Details
### Technologies/Components Used
For Software:
- [Languages used]
- [Frameworks used]
- [Libraries used]
- [Tools used]
- [html, css, javascript, python]
- [FastApi]
- [React]
- [Nodejs]

For Hardware:
- [List main components]
Expand All @@ -38,23 +56,40 @@ For Hardware:
### Implementation
For Software:
# Installation
[commands]
[winget install OpenJS.NodeJS]
[pip install fastapi uvicorn]
[npm install react react-dom]
[npm install react-router-dom]


# Run
[commands]
[uvicorn app.main:app --reload]
[npm start]


### Project Documentation
For Software:

# Screenshots (Add at least 3)
![Screenshot1](Add screenshot 1 here with proper name)
*Add caption explaining what this shows*
![Screenshot1](assets/home.png)
*This shows our home page*

![Screenshot2](assets/organisationsList.png)
*This shows the list of organisations like NGOs*

![Screenshot3](assets/DonorRegistration.png)
*People who are interested in donating money can register here*

![Screenshot4](assets/SortedList1.png)
*Organisations can be sorted in terms of emergency*

![Screenshot5](assets/SortedList2.png)
*Organisations can be sorted in terms of patients helped *

![Screenshot5](assets/LOGINPAGE.jpg)
*Organisations can be sorted in terms of patients helped *

![Screenshot2](Add screenshot 2 here with proper name)
*Add caption explaining what this shows*

![Screenshot3](Add screenshot 3 here with proper name)
*Add caption explaining what this shows*

# Diagrams
![Workflow](Add your workflow/architecture diagram here)
Expand Down
Binary file added assets/DonorRegistration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/LOGINPAGE.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/SortedList1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/SortedList2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/organisationsList.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Virtual environment
venv/

# Python cache files
__pycache__/
*.pyc
*.pyo
*.pyd

# Logs & temp files
*.log
*.tmp
*.swp
*.swo

# IDE/Editor files
.vscode/
.idea/

# Environment variables (if needed)
.env

# OS-specific files
.DS_Store
Thumbs.db
24 changes: 24 additions & 0 deletions backend/app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.routes import auth, donor, organisation

app = FastAPI()

# CORS Middleware Configuration (Allow React Frontend to Access API)
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"], # React frontend URL
allow_credentials=True,
allow_methods=["*"], # Allow all HTTP methods (GET, POST, PUT, DELETE, etc.)
allow_headers=["*"], # Allow all headers (e.g., Authorization, Content-Type)
)
Comment on lines +8 to +14
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Secure CORS configuration for production.

The current CORS configuration allows requests only from the development frontend. For production, consider:

  1. Moving the allowed origins to environment variables
  2. Restricting the allowed methods and headers

Apply this diff:

+from typing import List
+from app.config import settings  # Create this file to manage environment variables

 app.add_middleware(
     CORSMiddleware,
-    allow_origins=["http://localhost:3000"],  # React frontend URL
+    allow_origins=settings.ALLOWED_ORIGINS,  # List of allowed origins from environment
     allow_credentials=True,
-    allow_methods=["*"],  # Allow all HTTP methods
-    allow_headers=["*"],  # Allow all headers
+    allow_methods=["GET", "POST", "PUT", "DELETE"],
+    allow_headers=["Authorization", "Content-Type"],
 )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"], # React frontend URL
allow_credentials=True,
allow_methods=["*"], # Allow all HTTP methods (GET, POST, PUT, DELETE, etc.)
allow_headers=["*"], # Allow all headers (e.g., Authorization, Content-Type)
)
from typing import List
from app.config import settings # Create this file to manage environment variables
app.add_middleware(
CORSMiddleware,
allow_origins=settings.ALLOWED_ORIGINS, # List of allowed origins from environment
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE"],
allow_headers=["Authorization", "Content-Type"],
)


# Include API routers
app.include_router(auth.router, prefix="/auth", tags=["Auth"])
app.include_router(donor.router, prefix="/donor", tags=["Donor"])
app.include_router(organisation.router, prefix="/organisation", tags=["Organisation"])

# Test Endpoint to check if backend is running
@app.get("/")
def home():
return {"message": "Welcome to the FastAPI Backend (No Database)"}
75 changes: 75 additions & 0 deletions backend/app/routes/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel
from passlib.context import CryptContext
from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt

Comment on lines +1 to +7
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove unused imports and secure JWT configuration.

The static analysis identified unused imports. Additionally, the JWT configuration needs to be secured.

Apply this diff:

-from fastapi import APIRouter, HTTPException, Depends
+from fastapi import APIRouter, HTTPException
 from pydantic import BaseModel
 from passlib.context import CryptContext
 from datetime import datetime, timedelta
 from typing import Optional
-from jose import JWTError, jwt
+from jose import jwt
+from app.config import settings  # Create this file to manage environment variables
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel
from passlib.context import CryptContext
from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from passlib.context import CryptContext
from datetime import datetime, timedelta
from typing import Optional
from jose import jwt
from app.config import settings # Create this file to manage environment variables
🧰 Tools
🪛 Ruff (0.8.2)

1-1: fastapi.Depends imported but unused

Remove unused import: fastapi.Depends

(F401)


6-6: jose.JWTError imported but unused

Remove unused import: jose.JWTError

(F401)

# FastAPI Router for Authentication
router = APIRouter()

# Password Hashing
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# In-memory storage (Temporary, use a database in production)
users = []
Comment on lines +14 to +15
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace in-memory storage with a database.

Using in-memory storage is not suitable for production as data will be lost when the server restarts.

Consider implementing a proper database solution:

  1. Use SQLAlchemy with PostgreSQL for relational data
  2. Use MongoDB for document-based storage
  3. Implement proper database migrations

Would you like me to help you set up a database solution?


# JWT Token Settings
SECRET_KEY = "your_secret_key_here" # Replace with a strong secret key
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30 # Token expires in 30 minutes

# Pydantic Models
class UserCreate(BaseModel):
name: str
email: str
password: str
Comment on lines +23 to +26
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation for user fields.

The current model lacks validation for email format and password strength.

Apply this diff to add validation:

+from pydantic import BaseModel, EmailStr, Field
+import re
+
+def validate_password(v: str) -> str:
+    if not re.match(r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$', v):
+        raise ValueError('Password must be at least 8 characters long and contain both letters and numbers')
+    return v
+
 class UserCreate(BaseModel):
     name: str
-    email: str
-    password: str
+    email: EmailStr
+    password: str = Field(..., min_length=8)
+
+    @validator('password')
+    def password_validation(cls, v):
+        return validate_password(v)

Committable suggestion skipped: line range outside the PR's diff.


class UserLogin(BaseModel):
email: str
password: str

class TokenData(BaseModel):
email: Optional[str] = None

# Utility Functions
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
"""Generates a JWT access token."""
to_encode = data.copy()
expire = datetime.utcnow() + (expires_delta if expires_delta else timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt

def verify_password(plain_password, hashed_password):
"""Verifies if a password matches its hashed version."""
return pwd_context.verify(plain_password, hashed_password)

def get_password_hash(password):
"""Hashes the password."""
return pwd_context.hash(password)

# Routes

@router.post("/register")
def register(user: UserCreate):
"""Registers a new user."""
for u in users:
if u["email"] == user.email:
raise HTTPException(status_code=400, detail="Email already exists")

hashed_password = get_password_hash(user.password)
new_user = {"name": user.name, "email": user.email, "password": hashed_password}
users.append(new_user)
return {"message": "User registered successfully"}
Comment on lines +54 to +64
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add response model and improve error handling.

The registration endpoint needs a proper response model and better error handling.

Apply this diff:

-@router.post("/register")
-def register(user: UserCreate):
+from fastapi import status
+from pydantic import BaseModel
+
+class UserResponse(BaseModel):
+    name: str
+    email: str
+
+@router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
+async def register(user: UserCreate):
     """Registers a new user."""
     for u in users:
         if u["email"] == user.email:
-            raise HTTPException(status_code=400, detail="Email already exists")
+            raise HTTPException(
+                status_code=status.HTTP_409_CONFLICT,
+                detail="A user with this email already exists"
+            )

     hashed_password = get_password_hash(user.password)
     new_user = {"name": user.name, "email": user.email, "password": hashed_password}
     users.append(new_user)
-    return {"message": "User registered successfully"}
+    return UserResponse(name=user.name, email=user.email)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@router.post("/register")
def register(user: UserCreate):
"""Registers a new user."""
for u in users:
if u["email"] == user.email:
raise HTTPException(status_code=400, detail="Email already exists")
hashed_password = get_password_hash(user.password)
new_user = {"name": user.name, "email": user.email, "password": hashed_password}
users.append(new_user)
return {"message": "User registered successfully"}
from fastapi import status, HTTPException
from pydantic import BaseModel
class UserResponse(BaseModel):
name: str
email: str
@router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def register(user: UserCreate):
"""Registers a new user."""
for u in users:
if u["email"] == user.email:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="A user with this email already exists"
)
hashed_password = get_password_hash(user.password)
new_user = {"name": user.name, "email": user.email, "password": hashed_password}
users.append(new_user)
return UserResponse(name=user.name, email=user.email)


@router.post("/login")
def login(user: UserLogin):
"""Logs in a user and returns a JWT token."""
for u in users:
if u["email"] == user.email and verify_password(user.password, u["password"]):
# Create JWT Token
access_token = create_access_token(data={"sub": user.email}, expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
return {"access_token": access_token, "token_type": "bearer"}

raise HTTPException(status_code=400, detail="Invalid email or password")
Comment on lines +66 to +75
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add rate limiting and improve login security.

The login endpoint needs rate limiting to prevent brute force attacks.

Apply this diff:

+from fastapi import Request
+from fastapi.security import OAuth2PasswordRequestForm
+from slowapi import Limiter
+from slowapi.util import get_remote_address
+
+limiter = Limiter(key_func=get_remote_address)
+
-@router.post("/login")
-def login(user: UserLogin):
+@router.post("/login")
+@limiter.limit("5/minute")
+async def login(request: Request, form_data: OAuth2PasswordRequestForm = Depends()):
     """Logs in a user and returns a JWT token."""
     for u in users:
-        if u["email"] == user.email and verify_password(user.password, u["password"]):
+        if u["email"] == form_data.username and verify_password(form_data.password, u["password"]):
             # Create JWT Token
-            access_token = create_access_token(data={"sub": user.email}, expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
+            access_token = create_access_token(
+                data={"sub": form_data.username},
+                expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
+            )
             return {"access_token": access_token, "token_type": "bearer"}
     
-    raise HTTPException(status_code=400, detail="Invalid email or password")
+    raise HTTPException(
+        status_code=status.HTTP_401_UNAUTHORIZED,
+        detail="Invalid credentials",
+        headers={"WWW-Authenticate": "Bearer"},
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@router.post("/login")
def login(user: UserLogin):
"""Logs in a user and returns a JWT token."""
for u in users:
if u["email"] == user.email and verify_password(user.password, u["password"]):
# Create JWT Token
access_token = create_access_token(data={"sub": user.email}, expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
return {"access_token": access_token, "token_type": "bearer"}
raise HTTPException(status_code=400, detail="Invalid email or password")
from fastapi import Request, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from slowapi import Limiter
from slowapi.util import get_remote_address
from datetime import timedelta
limiter = Limiter(key_func=get_remote_address)
@router.post("/login")
@limiter.limit("5/minute")
async def login(request: Request, form_data: OAuth2PasswordRequestForm = Depends()):
"""Logs in a user and returns a JWT token."""
for u in users:
if u["email"] == form_data.username and verify_password(form_data.password, u["password"]):
# Create JWT Token
access_token = create_access_token(
data={"sub": form_data.username},
expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
)
return {"access_token": access_token, "token_type": "bearer"}
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials",
headers={"WWW-Authenticate": "Bearer"},
)

15 changes: 15 additions & 0 deletions backend/app/routes/donor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from fastapi import APIRouter
from pydantic import BaseModel

router = APIRouter()
donors = [] # In-memory storage

class DonorCreate(BaseModel):
name: str
age: int
contact: str
Comment on lines +7 to +10
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation for age and contact fields.

The current model lacks validation constraints. Consider adding:

  • Age range validation
  • Contact number format validation

Apply this diff to add validation:

 class DonorCreate(BaseModel):
     name: str
-    age: int
-    contact: str
+    age: int = Field(..., gt=0, lt=150)
+    contact: str = Field(..., regex=r'^\+?1?\d{9,15}$')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class DonorCreate(BaseModel):
name: str
age: int
contact: str
class DonorCreate(BaseModel):
name: str
age: int = Field(..., gt=0, lt=150)
contact: str = Field(..., regex=r'^\+?1?\d{9,15}$')


@router.post("/register")
def register_donor(donor: DonorCreate):
donors.append(donor.dict())
return {"message": "Donor registered successfully", "donor": donor}
Comment on lines +12 to +15
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling and implement GET endpoint.

The current implementation lacks error handling and a way to retrieve donor information.

Add error handling and a GET endpoint:

+@router.get("/")
+def get_donors():
+    return {"donors": donors}
+
 @router.post("/register")
-def register_donor(donor: DonorCreate):
+async def register_donor(donor: DonorCreate):
+    try:
         donors.append(donor.dict())
         return {"message": "Donor registered successfully", "donor": donor}
+    except Exception as e:
+        raise HTTPException(status_code=500, detail=str(e))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@router.post("/register")
def register_donor(donor: DonorCreate):
donors.append(donor.dict())
return {"message": "Donor registered successfully", "donor": donor}
@router.get("/")
def get_donors():
return {"donors": donors}
@router.post("/register")
async def register_donor(donor: DonorCreate):
try:
donors.append(donor.dict())
return {"message": "Donor registered successfully", "donor": donor}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))

19 changes: 19 additions & 0 deletions backend/app/routes/organisation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from fastapi import APIRouter
from pydantic import BaseModel

router = APIRouter()
organisations = [] # In-memory storage

class OrganisationCreate(BaseModel):
name: str
description: str
contact: str
Comment on lines +7 to +10
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation for organisation fields.

The current model lacks validation constraints for contact and description fields.

Apply this diff to add validation:

 class OrganisationCreate(BaseModel):
-    name: str
-    description: str
-    contact: str
+    name: str = Field(..., min_length=1, max_length=100)
+    description: str = Field(..., min_length=10, max_length=1000)
+    contact: str = Field(..., regex=r'^\+?1?\d{9,15}$')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class OrganisationCreate(BaseModel):
name: str
description: str
contact: str
class OrganisationCreate(BaseModel):
name: str = Field(..., min_length=1, max_length=100)
description: str = Field(..., min_length=10, max_length=1000)
contact: str = Field(..., regex=r'^\+?1?\d{9,15}$')


@router.post("/register")
def register_organisation(org: OrganisationCreate):
organisations.append(org.dict())
return {"message": "Organisation registered successfully", "organisation": org}

@router.get("/")
def get_organisations():
return {"organisations": organisations}
Comment on lines +12 to +19
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling and CRUD operations.

The current implementation lacks error handling and complete CRUD operations.

Add error handling and additional endpoints:

+from fastapi import HTTPException
+
 @router.post("/register")
-def register_organisation(org: OrganisationCreate):
+async def register_organisation(org: OrganisationCreate):
+    try:
         organisations.append(org.dict())
         return {"message": "Organisation registered successfully", "organisation": org}
+    except Exception as e:
+        raise HTTPException(status_code=500, detail=str(e))

 @router.get("/")
-def get_organisations():
+async def get_organisations():
     return {"organisations": organisations}
+
+@router.put("/{org_id}")
+async def update_organisation(org_id: int, org: OrganisationCreate):
+    if org_id >= len(organisations):
+        raise HTTPException(status_code=404, detail="Organisation not found")
+    organisations[org_id] = org.dict()
+    return {"message": "Organisation updated successfully"}
+
+@router.delete("/{org_id}")
+async def delete_organisation(org_id: int):
+    if org_id >= len(organisations):
+        raise HTTPException(status_code=404, detail="Organisation not found")
+    organisations.pop(org_id)
+    return {"message": "Organisation deleted successfully"}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@router.post("/register")
def register_organisation(org: OrganisationCreate):
organisations.append(org.dict())
return {"message": "Organisation registered successfully", "organisation": org}
@router.get("/")
def get_organisations():
return {"organisations": organisations}
from fastapi import HTTPException
@router.post("/register")
async def register_organisation(org: OrganisationCreate):
try:
organisations.append(org.dict())
return {"message": "Organisation registered successfully", "organisation": org}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/")
async def get_organisations():
return {"organisations": organisations}
@router.put("/{org_id}")
async def update_organisation(org_id: int, org: OrganisationCreate):
if org_id >= len(organisations):
raise HTTPException(status_code=404, detail="Organisation not found")
organisations[org_id] = org.dict()
return {"message": "Organisation updated successfully"}
@router.delete("/{org_id}")
async def delete_organisation(org_id: int):
if org_id >= len(organisations):
raise HTTPException(status_code=404, detail="Organisation not found")
organisations.pop(org_id)
return {"message": "Organisation deleted successfully"}

23 changes: 23 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
70 changes: 70 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Getting Started with Create React App

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

## Available Scripts

In the project directory, you can run:

### `npm start`

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.

The page will reload when you make changes.\
You may also see any lint errors in the console.

### `npm test`

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.

### `npm run build`

Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.

### `npm run eject`

**Note: this is a one-way operation. Once you `eject`, you can't go back!**

If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.

You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.

## Learn More

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).

To learn React, check out the [React documentation](https://reactjs.org/).

### Code Splitting

This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)

### Analyzing the Bundle Size

This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)

### Making a Progressive Web App

This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)

### Advanced Configuration

This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)

### Deployment

This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)

### `npm run build` fails to minify

This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
Loading