Skip to content
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
401 changes: 401 additions & 0 deletions CLIENT/src/components/dashboard/admin-dashboard.tsx

Large diffs are not rendered by default.

44 changes: 38 additions & 6 deletions CLIENT/src/components/dashboard/internship-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,54 @@ interface Internship {
title: string
company: string
location: string
type: string
type: string // Note: This field might need to be added to your database schema
duration: string
description: string
stipend: number
isActive: boolean
}

export default function InternshipList() {
const [internships, setInternships] = useState<Internship[]>([])
const [loading, setLoading] = useState(true)

useEffect(() => {
async function fetchInternships() {
const response = await fetch("http://localhost:8000/api/fetchinternships")
const data = await response.json()
setInternships(data)
try {
setLoading(true)
const response = await fetch("http://localhost:8000/api/fetchinternships")
const data = await response.json()

// Format the data as needed
const formattedData = data.map((item: any) => ({
...item,
// Convert numeric duration to string with "months"
duration: typeof item.duration === 'number' ?
`${item.duration} month${item.duration !== 1 ? 's' : ''}` :
item.duration,
// Set a default type if not provided
type: item.type || "Remote"
}))

setInternships(formattedData)
} catch (error) {
console.error("Error fetching internships:", error)
} finally {
setLoading(false)
}
}

fetchInternships()
}, [])

if (loading) {
return <div className="text-center py-10">Loading internships...</div>
}

if (internships.length === 0) {
return <div className="text-center py-10">No active internships available at the moment.</div>
}

return (
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
{internships.map((internship) => (
Expand All @@ -50,6 +80,9 @@ export default function InternshipList() {
</div>
<Badge className="w-fit mt-2">{internship.type}</Badge>
<p className="mt-2 text-sm">{internship.description}</p>
{internship.stipend > 0 && (
<p className="text-sm font-medium mt-2">Stipend: ₹{internship.stipend}/month</p>
)}
</div>
</CardContent>
<CardFooter>
Expand All @@ -59,5 +92,4 @@ export default function InternshipList() {
))}
</div>
)
}

}
32 changes: 32 additions & 0 deletions CLIENT/src/components/dashboard/internship-portal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useState } from "react"
import InternshipList from "./internship-list"
import AdminDashboard from "./admin-dashboard"
import Navigation from "./navigation"

export default function InternshipPortal() {
const [currentView, setCurrentView] = useState("public")

return (
<div className="flex flex-col min-h-screen">
<Navigation onViewChange={setCurrentView} currentView={currentView} />

<main className="container mx-auto py-8 px-4 flex-1">
{currentView === "public" ? (
<>
<h1 className="text-3xl font-bold mb-6">Available Internships</h1>
<p className="text-muted-foreground mb-6">
Explore our available internship opportunities and apply today!
</p>
<InternshipList />
</>
) : (
<AdminDashboard />
)}
</main>

<footer className="bg-background border-t py-4 text-center text-sm text-muted-foreground">
&copy; {new Date().getFullYear()} Internship Portal. All rights reserved.
</footer>
</div>
)
}
Binary file added SERVER/__pycache__/main.cpython-313.pyc
Binary file not shown.
Binary file added SERVER/api/ats/__pycache__/__init__.cpython-313.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added SERVER/api/auth/__pycache__/login.cpython-313.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 2 additions & 0 deletions SERVER/api/internships/addInternships.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class Internship(BaseModel):
location:str
stipend:int
duration:int


router = APIRouter()

Expand All @@ -21,5 +22,6 @@ async def addInternships(internship:Internship):
"location": internship.location,
"stipend": internship.stipend,
"duration": internship.duration
"isActive": True
})
return {"title": prisma_internship.title, "description": prisma_internship.description, "company": prisma_internship.company, "location": prisma_internship.location, "stipend": prisma_internship.stipend, "duration": prisma_internship.duration}
49 changes: 49 additions & 0 deletions SERVER/api/internships/deleteinternships.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# from fastapi import APIRouter, HTTPException
# from prisma.models import Internship as PrismaInternship

# router = APIRouter()

# @router.delete("/api/deleteinternship/{internship_id}")
# async def delete_internship(internship_id: int):
# try:
# # Instead of deleting, update isActive to False
# await PrismaInternship.prisma().update(
# where={"id": internship_id},
# data={"isActive": False}
# )
# return {"message": "Internship deactivated successfully"}
# except Exception as e:
# raise HTTPException(status_code=404, detail=f"Internship with ID {internship_id} not found")
from fastapi import APIRouter, HTTPException
from prisma.models import Internship as PrismaInternship

router = APIRouter()

@router.put("/api/toggleinternship/{internship_id}")
async def toggle_internship_status(internship_id: int):
try:
# First, get the current status
internship = await PrismaInternship.prisma().find_unique(
where={"id": internship_id}
)

if not internship:
raise HTTPException(status_code=404, detail="Internship not found")

# Toggle the isActive status
new_status = not internship.isActive

# Update the internship
updated = await PrismaInternship.prisma().update(
where={"id": internship_id},
data={"isActive": new_status}
)

status_message = "activated" if new_status else "deactivated"
return {"message": f"Internship {status_message} successfully", "status": new_status}

except Exception as e:
if "not found" in str(e):
raise HTTPException(status_code=404, detail="Internship not found")
raise HTTPException(status_code=500, detail=str(e))

9 changes: 8 additions & 1 deletion SERVER/api/internships/fetchInternships.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,12 @@ class Internship(BaseModel):

@router.get("/api/fetchinternships")
async def fetch_internships():
data = await PrismaInternship.prisma().find_many()
data = await PrismaInternship.prisma().find_many(where={"isActive": True})
return data
@router.get("/api/fetchdeletedinternships")
async def fetch_deleted_internships():
# Fetch only inactive internships
data = await PrismaInternship.prisma().find_many(
where={"isActive": False}
)
return data
8 changes: 7 additions & 1 deletion SERVER/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
from fastapi.middleware.cors import CORSMiddleware
from api.blogs.blogs import router as blog_router
from api.ats.resume_routes import router as ats_router
from api.internships.deleteinternships import router as delete_router
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

from api.auth.register import router as register_router

db = Prisma()
Expand Down Expand Up @@ -39,3 +40,8 @@ async def shutdown():
app.include_router(admin_auth_router)
app.include_router(blog_router)
app.include_router(ats_router)
app.include_router(deleteinternships_router)

@app.get("/")
def read_root():
return {"message": "API is running"}
28 changes: 18 additions & 10 deletions SERVER/prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
generator client {
provider = "prisma-client-py"
}

datasource db {
provider = "sqlite"
provider = "postgresql"
url = env("DATABASE_URL")
}

generator client {
provider = "prisma-client-py"
interface = "asyncio"
recursive_type_depth = 5
}

model User {
id Int @id @default(autoincrement())
id Int @id @default(autoincrement())
fullName String
email String @unique
email String @unique
password String
role String
blogs Blog[]
role ROLE @default(USER)
blogs Blog[]
}

model Internship {
Expand All @@ -24,14 +26,20 @@ model Internship {
location String
stipend Int
duration Int
isActive Boolean @default(true)
}

model Blog {
id Int @id @default(autoincrement())
user_id Int
title String
content String
content Json
author String
date DateTime
user User @relation(fields: [user_id], references: [id])
}

enum ROLE {
ADMIN
USER
}