Merge branch 'frontend-team-GEN-68-admin-page' into varun-admin-GEN-59-page

This commit is contained in:
Varun Murlidhar 2024-04-05 14:07:28 -04:00
commit 044fe3e256
46 changed files with 5580 additions and 5055 deletions

View File

@ -1,2 +1,10 @@
from .entity_base import EntityBase
from .sample_entity import SampleEntity
from .tag_entity import TagEntity
from .user_entity import UserEntity
from .resource_entity import ResourceEntity
from .resource_tag_entity import ResourceTagEntity
from .service_entity import ServiceEntity
from .service_tag_entity import ServiceTagEntity
from .program_enum import ProgramEnum
from .user_enum import RoleEnum

View File

@ -0,0 +1,10 @@
from sqlalchemy import Enum
class ProgramEnum(Enum):
ECONOMIC = "economic"
DOMESTIC = "domestic"
COMMUNITY = "community"
def __init__(self):
super().__init__(name="program_enum")

View File

@ -0,0 +1,68 @@
""" Defines the table for storing resources """
# Import our mapped SQL types from SQLAlchemy
from sqlalchemy import Integer, String, DateTime
# Import mapping capabilities from the SQLAlchemy ORM
from sqlalchemy.orm import Mapped, mapped_column, relationship
# Import the EntityBase that we are extending
from .entity_base import EntityBase
# Import datetime for created_at type
from datetime import datetime
# Import self for to model
from typing import Self
from backend.entities.program_enum import ProgramEnum
class ResourceEntity(EntityBase):
# set table name
__tablename__ = "resource"
# set fields
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
name: Mapped[str] = mapped_column(String(32), nullable=False)
summary: Mapped[str] = mapped_column(String(100), nullable=False)
link: Mapped[str] = mapped_column(String, nullable=False)
program: Mapped[ProgramEnum] = mapped_column(ProgramEnum, nullable=False)
# relationships
resourceTags: Mapped[list["ResourceTagEntity"]] = relationship(
back_populates="resource", cascade="all,delete"
)
#
# @classmethod
# def from_model(cls, model: user_model) -> Self:
# """
# Create a UserEntity from a User model.
# Args:
# model (User): The model to create the entity from.
# Returns:
# Self: The entity (not yet persisted).
# """
# return cls (
# id = model.id,
# created_at = model.created_at,
# name = model.name,
# summary = model.summary,
# link = model.link,
# program = model.program,
# )
# def to_model(self) -> user_model:
# return user_model (
# id = self.id,
# created_at = self.created_at,
# name = self.name,
# summary = self.summary,
# link = self.link,
# program = self.program,
# )

View File

@ -0,0 +1,46 @@
""" Defines the table for resource tags """
# Import our mapped SQL types from SQLAlchemy
from sqlalchemy import ForeignKey, Integer, String, DateTime
# Import mapping capabilities from the SQLAlchemy ORM
from sqlalchemy.orm import Mapped, mapped_column, relationship
# Import the EntityBase that we are extending
from .entity_base import EntityBase
# Import datetime for created_at type
from datetime import datetime
# Import self for to model
from typing import Self
class ResourceTagEntity(EntityBase):
# set table name to user in the database
__tablename__ = "resourceTag"
# set fields or 'columns' for the user table
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
resourceId: Mapped[int] = mapped_column(ForeignKey("resource.id"))
tagId: Mapped[int] = mapped_column(ForeignKey("tag.id"))
# relationships
resource: Mapped["ResourceEntity"] = relationship(back_populates="resourceTags")
tag: Mapped["TagEntity"] = relationship(back_populates="resourceTags")
# @classmethod
# def from_model (cls, model: resource_tag_model) -> Self:
# return cls (
# id = model.id,
# resourceId = model.resourceId,
# tagId = model.tagId,
# )
# def to_model (self) -> resource_tag_model:
# return user_model(
# id = self.id,
# resourceId = self.resourceId,
# tagId = self.tagId,
# )

View File

@ -0,0 +1,44 @@
""" Defines the table for storing services """
# Import our mapped SQL types from SQLAlchemy
from sqlalchemy import Integer, String, DateTime, ARRAY
# Import mapping capabilities from the SQLAlchemy ORM
from sqlalchemy.orm import Mapped, mapped_column, relationship
# Import the EntityBase that we are extending
from .entity_base import EntityBase
# Import datetime for created_at type
from datetime import datetime
# Import enums for Program
import enum
from sqlalchemy import Enum
class ProgramEnum(enum.Enum):
"""Determine program for Service"""
DOMESTIC = "DOMESTIC"
ECONOMIC = "ECONOMIC"
COMMUNITY = "COMMUNITY"
class ServiceEntity(EntityBase):
# set table name
__tablename__ = "service"
# set fields
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
name: Mapped[str] = mapped_column(String(32), nullable=False)
summary: Mapped[str] = mapped_column(String(100), nullable=False)
requirements: Mapped[list[str]] = mapped_column(ARRAY(String))
program: Mapped[ProgramEnum] = mapped_column(Enum(ProgramEnum), nullable=False)
# relationships
serviceTags: Mapped[list["ServiceTagEntity"]] = relationship(
back_populates="service", cascade="all,delete"
)

View File

@ -0,0 +1,25 @@
""" Defines the table for service tags """
# Import our mapped SQL types from SQLAlchemy
from sqlalchemy import ForeignKey, Integer
# Import mapping capabilities from the SQLAlchemy ORM
from sqlalchemy.orm import Mapped, mapped_column, relationship
# Import the EntityBase that we are extending
from .entity_base import EntityBase
class ServiceTagEntity(EntityBase):
# set table name to user in the database
__tablename__ = "serviceTag"
# set fields or 'columns' for the user table
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
serviceId: Mapped[int] = mapped_column(ForeignKey("service.id"))
tagId: Mapped[int] = mapped_column(ForeignKey("tag.id"))
# relationships
service: Mapped["ServiceEntity"] = relationship(back_populates="resourceTags")
tag: Mapped["TagEntity"] = relationship(back_populates="resourceTags")

View File

@ -0,0 +1,62 @@
""" Defines the table for storing tags """
# Import our mapped SQL types from SQLAlchemy
from sqlalchemy import Integer, String, DateTime
# Import mapping capabilities from the SQLAlchemy ORM
from sqlalchemy.orm import Mapped, mapped_column, relationship
# Import the EntityBase that we are extending
from .entity_base import EntityBase
# Import datetime for created_at type
from datetime import datetime
class TagEntity(EntityBase):
#set table name
__tablename__ = "tag"
#set fields
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
content: Mapped[str] = mapped_column(String(100), nullable=False)
#relationships
resourceTags: Mapped[list["ResourceTagEntity"]] = relationship(back_populates="tag", cascade="all,delete")
serviceTags: Mapped[list["ServiceTagEntity"]] = relationship(back_populates="tag", cascade="all,delete")
"""
@classmethod
def from_model(cls, model: Tag) -> Self:
Create a user entity from model
Args: model (User): the model to create the entity from
Returns:
self: The entity
return cls(
id=model.id,
content=model.id,
)
def to_model(self) -> Tag:
Create a user model from entity
Returns:
User: A User model for API usage
return Tag(
id=self.id,
content=self.id,
)
"""

View File

@ -0,0 +1,90 @@
""" Defines the table for storing users """
# Import our mapped SQL types from SQLAlchemy
from sqlalchemy import Integer, String, DateTime, ARRAY
# Import mapping capabilities from the SQLAlchemy ORM
from sqlalchemy.orm import Mapped, mapped_column
# Import the EntityBase that we are extending
from .entity_base import EntityBase
# Import datetime for created_at type
from datetime import datetime
# Import enums for Role and Program
from backend.entities.program_enum import ProgramEnum
from .user_enum import RoleEnum
class UserEntity(EntityBase):
"""Serves as the database model for User table"""
# set table name to user in the database
__tablename__ = "user"
# set fields or 'columns' for the user table
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
username: Mapped[str] = mapped_column(
String(32), nullable=False, default="", unique=True
)
role: Mapped[RoleEnum] = mapped_column(RoleEnum, nullable=False)
username: Mapped[str] = mapped_column(
String(32), nullable=False, default="", unique=True
)
role: Mapped[RoleEnum] = mapped_column(RoleEnum, nullable=False)
email: Mapped[str] = mapped_column(String(50), nullable=False, unique=True)
program: Mapped[list[ProgramEnum]] = mapped_column(
ARRAY(ProgramEnum), nullable=False
)
program: Mapped[list[ProgramEnum]] = mapped_column(
ARRAY(ProgramEnum), nullable=False
)
experience: Mapped[int] = mapped_column(Integer, nullable=False)
group: Mapped[str] = mapped_column(String(50))
"""
@classmethod
def from_model(cls, model: User) -> Self:
Create a user entity from model
Args: model (User): the model to create the entity from
Returns:
self: The entity
return cls(
id=model.id,
username=model.username,
role=model.role,
email=model.email,
program=model.program,
experience=model.experience,
group=model.group,
)
def to_model(self) -> User:
Create a user model from entity
Returns:
User: A User model for API usage
return User(
id=self.id,
username=self.id,
role=self.role,
email=self.email,
program=self.program,
experience=self.experience,
group=self.group,
)
"""

View File

@ -0,0 +1,12 @@
from sqlalchemy import Enum
class RoleEnum(Enum):
"""Determine role for User"""
ADMIN = "ADMIN"
EMPLOYEE = "EMPLOYEE"
VOLUNTEER = "VOLUNTEER"
def __init__(self):
super().__init__(name="role_enum")

View File

@ -0,0 +1,17 @@
from pydantic import BaseModel, Field
from enum import Enum
from typing import List
from datetime import datetime
from typing import Optional
class ProgramTypeEnum(str, Enum):
DOMESTIC = "DOMESTIC"
ECONOMIC = "ECONOMIC"
COMMUNITY = "COMMUNITY"
class UserTypeEnum(str, Enum):
ADMIN = "ADMIN"
EMPLOYEE = "EMPLOYEE"
VOLUNTEER = "VOLUNTEER"

View File

@ -0,0 +1,16 @@
from pydantic import BaseModel, Field
from enum import Enum
from typing import List
from datetime import datetime
from typing import Optional
from .enum_for_models import ProgramTypeEnum
from .resource_model import Resource
class Resource(BaseModel):
id: int | None = None
name: str = Field(..., max_length=150, description="The name of the resource")
summary: str = Field(..., max_length=300, description="The summary of the resource")
link: str = Field(..., max_length=150, description="link to the resource")
programtype: ProgramTypeEnum
created_at: Optional[datetime]

View File

@ -0,0 +1,13 @@
from pydantic import BaseModel, Field
from enum import Enum
from typing import List
from datetime import datetime
from typing import Optional
from .tag_model import Tag
from .resource_model import Resource
class ResourceTag(Resource, BaseModel):
id: int | None = None
resourceid: int | None = None
tagid: List[Tag]

View File

@ -0,0 +1,16 @@
from pydantic import BaseModel, Field
from enum import Enum
from typing import List
from datetime import datetime
from typing import Optional
from .enum_for_models import ProgramTypeEnum
class Service(BaseModel):
id: int | None = None
created_at: datetime | None = None
name: str
status: str
summary: str
requirements: List[str]
program: ProgramTypeEnum

View File

@ -0,0 +1,19 @@
from pydantic import BaseModel, Field
from enum import Enum
from typing import List
from datetime import datetime
from typing import Optional
from .enum_for_models import ProgramTypeEnum
from .enum_for_models import UserTypeEnum
from .service_model import Service
from .tag_model import Tag
from pydantic import BaseModel
from datetime import datetime
class ServiceTag(Service, BaseModel):
id: int | None = None
serviceid: int | None = None
tagId: List[Tag]

View File

@ -0,0 +1,13 @@
from pydantic import BaseModel, Field
from enum import Enum
from typing import List
from datetime import datetime
from typing import Optional
class Tag(BaseModel):
id: int | None = None
content: str = Field(
..., max_length=600, description="content associated with the tag"
)
created_at: datetime | None = None

View File

@ -0,0 +1,17 @@
from pydantic import BaseModel, Field
from enum import Enum
from typing import List
from datetime import datetime
from typing import Optional
from .enum_for_models import UserTypeEnum, ProgramTypeEnum
class User(BaseModel):
id: int | None = None
username: str = Field(..., description="The username of the user")
email: str = Field(..., description="The e-mail of the user")
experience: int = Field(..., description="Years of Experience of the User")
group: str
programtype: List[ProgramTypeEnum]
usertype: UserTypeEnum
created_at: Optional[datetime]

View File

@ -0,0 +1,19 @@
""" Testing Tag Entity """
from sqlalchemy import Engine
from ... import entities
from ...entities.tag_entity import TagEntity
def test_add_sample_data_tag(session: Engine):
"""Inserts a sample data point and verifies it is in the database"""
entity = TagEntity(content="Test tag")
session.add(entity)
session.commit()
data = session.get(TagEntity, 1)
assert data.id == 1
assert data.content == "Test tag"

View File

@ -0,0 +1,24 @@
""" Testing User Entity """
from sqlalchemy import Engine
from ... import entities
from ...entities.user_entity import UserEntity
from ...entities.user_entity import RoleEnum
from ...entities.user_entity import ProgramEnum
def test_add_sample_data_user(session: Engine):
"""Inserts a sample data point and verifies it is in the database"""
entity = UserEntity(id=1, username="emmalynf", role=RoleEnum.ADMIN, email="efoster@unc.edu", program=[ProgramEnum.COMMUNITY, ProgramEnum.DOMESTIC, ProgramEnum.ECONOMIC], experience=10, group="group")
session.add(entity)
session.commit()
data = session.get(UserEntity, 1)
assert data.id == 1
assert data.username == "emmalynf"
assert data.email == "efoster@unc.edu"
assert data.experience == 10
assert data.role == RoleEnum.ADMIN
assert data.program == [ProgramEnum.COMMUNITY, ProgramEnum.DOMESTIC, ProgramEnum.ECONOMIC]

View File

@ -51,7 +51,7 @@ export default function Page() {
height={91}
/>
<h1 className='font-bold text-xl text-purple-800'>Login</h1>
<h1 className='font-bold text-2xl text-purple-800'>Login</h1>
<div className="mb-6">
<Input type='email' valid={emailError == ""} title="Email" placeholder="janedoe@gmail.com" onChange={handleEmailChange} required />

View File

@ -1,6 +1,7 @@
import React from 'react';
import { HomeIcon, ChevronDoubleLeftIcon, BookmarkIcon, ClipboardIcon, BookOpenIcon } from '@heroicons/react/24/solid';
import { SidebarItem } from './SidebarItem';
import { UserProfile } from './UserProfile';
interface SidebarProps {
setIsSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>;
@ -24,13 +25,7 @@ const Sidebar: React.FC<SidebarProps> = ({ setIsSidebarOpen }) => {
{/* user + logout button */}
<div className="flex items-center p-4 space-x-2 border border-gray-200 rounded-md ">
<div className="flex flex-col items-start space-y-2">
<div className="flex flex-col">
<span className="text-sm font-semibold text-gray-800">Compass Center</span>
<span className="text-xs text-gray-500">cssgunc@gmail.com</span>
</div>
<button className="text-red-600 text-xs hover:underline mt-1">Sign out</button>
</div>
<UserProfile />
</div>
{/* navigation menu */}
<div className="flex flex-col space-y-2">

View File

@ -0,0 +1,11 @@
export const UserProfile = () => {
return (
<div className="flex flex-col items-start space-y-2">
<div className="flex flex-col">
<span className="text-sm font-semibold text-gray-800">Compass Center</span>
<span className="text-xs text-gray-500">cssgunc@gmail.com</span>
</div>
<button className="text-red-600 font-semibold text-xs hover:underline mt-1">Sign out</button>
</div>
)
}