From 6d89ba6324e7ac196047b8210036567b1b564e74 Mon Sep 17 00:00:00 2001 From: pmoharana-cmd Date: Sat, 4 Jan 2025 23:26:33 -0500 Subject: [PATCH] Connect create item to backend and add associated frontend routes --- backend/api/resource.py | 25 ++++++++++++--- backend/api/user.py | 2 +- compass/app/api/resource/create/route.ts | 37 ++++++++++++++++++++++ compass/app/api/service/create/route.ts | 37 ++++++++++++++++++++++ compass/app/api/user/create/route.ts | 6 +--- compass/app/resource/page.tsx | 9 +++++- compass/app/service/page.tsx | 9 +++++- compass/components/Table/ResourceTable.tsx | 14 +++++--- compass/components/Table/ServiceTable.tsx | 28 +++++++++------- compass/components/Table/UserTable.tsx | 12 +++---- compass/components/TagsInput/Index.tsx | 9 ++---- compass/components/TagsInput/Tag.tsx | 1 + 12 files changed, 148 insertions(+), 41 deletions(-) create mode 100644 compass/app/api/resource/create/route.ts create mode 100644 compass/app/api/service/create/route.ts diff --git a/backend/api/resource.py b/backend/api/resource.py index 97d25af..ff449e2 100644 --- a/backend/api/resource.py +++ b/backend/api/resource.py @@ -19,7 +19,10 @@ openapi_tags = { # TODO: Create custom exceptions @api.post("", response_model=Resource, tags=["Resource"]) def create( - uuid: str, resource: Resource, user_svc: UserService = Depends(), resource_svc: ResourceService = Depends() + uuid: str, + resource: Resource, + user_svc: UserService = Depends(), + resource_svc: ResourceService = Depends(), ): subject = user_svc.get_user_by_uuid(uuid) return resource_svc.create(subject, resource) @@ -27,14 +30,20 @@ def create( @api.get("", response_model=List[Resource], tags=["Resource"]) def get_all( - uuid: str, user_svc: UserService = Depends(), resource_svc: ResourceService = Depends() + uuid: str, + user_svc: UserService = Depends(), + resource_svc: ResourceService = Depends(), ): subject = user_svc.get_user_by_uuid(uuid) return resource_svc.get_resource_by_user(subject) + @api.get("/{name}", response_model=Resource, tags=["Resource"]) def get_by_name( - name:str, uuid:str, user_svc: UserService = Depends(), resource_svc: ResourceService = Depends() + name: str, + uuid: str, + user_svc: UserService = Depends(), + resource_svc: ResourceService = Depends(), ): subject = user_svc.get_user_by_uuid(uuid) return resource_svc.get_resource_by_name(name, subject) @@ -42,7 +51,10 @@ def get_by_name( @api.put("", response_model=Resource, tags=["Resource"]) def update( - uuid: str, resource: Resource, user_svc: UserService = Depends(), resource_svc: ResourceService = Depends() + uuid: str, + resource: Resource, + user_svc: UserService = Depends(), + resource_svc: ResourceService = Depends(), ): subject = user_svc.get_user_by_uuid(uuid) return resource_svc.update(subject, resource) @@ -50,7 +62,10 @@ def update( @api.delete("", response_model=None, tags=["Resource"]) def delete( - uuid: str, resource: Resource, user_svc: UserService = Depends(), resource_svc: ResourceService = Depends() + uuid: str, + resource: Resource, + user_svc: UserService = Depends(), + resource_svc: ResourceService = Depends(), ): subject = user_svc.get_user_by_uuid(uuid) resource_svc.delete(subject, resource) diff --git a/backend/api/user.py b/backend/api/user.py index cda0a58..9066d71 100644 --- a/backend/api/user.py +++ b/backend/api/user.py @@ -30,7 +30,7 @@ def get_by_uuid(user_id: str, user_svc: UserService = Depends()): return user_svc.get_user_by_uuid(user_id) -@api.post("/create", response_model=User, tags=["Users"]) +@api.post("/", response_model=User, tags=["Users"]) def create_user(uuid: str, user: User, user_svc: UserService = Depends()): subject = user_svc.get_user_by_uuid(uuid) if subject.role != UserTypeEnum.ADMIN: diff --git a/compass/app/api/resource/create/route.ts b/compass/app/api/resource/create/route.ts new file mode 100644 index 0000000..8698b16 --- /dev/null +++ b/compass/app/api/resource/create/route.ts @@ -0,0 +1,37 @@ +import { NextResponse } from "next/server"; +import User from "@/utils/models/User"; + +export async function POST(request: Request) { + const apiEndpoint = `${process.env.NEXT_PUBLIC_API_HOST}/api/resource`; + + try { + const resourceData = await request.json(); + + console.log("RESOURCE DATA", JSON.stringify(resourceData)); + + const { searchParams } = new URL(request.url); + const uuid = searchParams.get("uuid"); + + // Send the POST request to the backend + const response = await fetch(`${apiEndpoint}?uuid=${uuid}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(resourceData), + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const createdResource: User = await response.json(); + return NextResponse.json(createdResource, { status: response.status }); + } catch (error) { + console.error("Error creating resource:", error); + return NextResponse.json( + { error: "Failed to create resource" }, + { status: 500 } + ); + } +} diff --git a/compass/app/api/service/create/route.ts b/compass/app/api/service/create/route.ts new file mode 100644 index 0000000..957911d --- /dev/null +++ b/compass/app/api/service/create/route.ts @@ -0,0 +1,37 @@ +import { NextResponse } from "next/server"; +import User from "@/utils/models/User"; + +export async function POST(request: Request) { + const apiEndpoint = `${process.env.NEXT_PUBLIC_API_HOST}/api/service`; + + try { + const serviceData = await request.json(); + + console.log("SERVICE DATA", JSON.stringify(serviceData)); + + const { searchParams } = new URL(request.url); + const uuid = searchParams.get("uuid"); + + // Send the POST request to the backend + const response = await fetch(`${apiEndpoint}?uuid=${uuid}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(serviceData), + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const createdService: User = await response.json(); + return NextResponse.json(createdService, { status: response.status }); + } catch (error) { + console.error("Error creating service:", error); + return NextResponse.json( + { error: "Failed to create service" }, + { status: 500 } + ); + } +} diff --git a/compass/app/api/user/create/route.ts b/compass/app/api/user/create/route.ts index 8aa152c..d7ea091 100644 --- a/compass/app/api/user/create/route.ts +++ b/compass/app/api/user/create/route.ts @@ -2,14 +2,10 @@ import { NextResponse } from "next/server"; import User from "@/utils/models/User"; export async function POST(request: Request) { - const apiEndpoint = `${process.env.NEXT_PUBLIC_API_HOST}/api/user/create`; + const apiEndpoint = `${process.env.NEXT_PUBLIC_API_HOST}/api/user`; try { const userData = await request.json(); - userData.role = userData.role.toUpperCase(); - userData.program = userData.program.map((program: string) => - program.toUpperCase() - ); console.log("USER DATA", JSON.stringify(userData)); diff --git a/compass/app/resource/page.tsx b/compass/app/resource/page.tsx index 7cbd2c1..6a886d3 100644 --- a/compass/app/resource/page.tsx +++ b/compass/app/resource/page.tsx @@ -10,6 +10,7 @@ import { useEffect, useState } from "react"; export default function Page() { const [resources, setResources] = useState([]); + const [uuid, setUuid] = useState(""); useEffect(() => { async function getResources() { @@ -22,6 +23,8 @@ export default function Page() { return; } + setUuid(data.user.id); + const userListData = await fetch( `${process.env.NEXT_PUBLIC_HOST}/api/resource/all?uuid=${data.user.id}` ); @@ -38,7 +41,11 @@ export default function Page() {
{/* icon + title */} }> - +
); diff --git a/compass/app/service/page.tsx b/compass/app/service/page.tsx index efe6337..3366430 100644 --- a/compass/app/service/page.tsx +++ b/compass/app/service/page.tsx @@ -10,6 +10,7 @@ import { useEffect, useState } from "react"; export default function Page() { const [services, setServices] = useState([]); + const [uuid, setUuid] = useState(""); useEffect(() => { async function getServices() { @@ -22,6 +23,8 @@ export default function Page() { return; } + setUuid(data.user.id); + const serviceListData = await fetch( `${process.env.NEXT_PUBLIC_HOST}/api/service/all?uuid=${data.user.id}` ); @@ -37,7 +40,11 @@ export default function Page() {
{/* icon + title */} }> - +
); diff --git a/compass/components/Table/ResourceTable.tsx b/compass/components/Table/ResourceTable.tsx index e2b5a50..a85ffdd 100644 --- a/compass/components/Table/ResourceTable.tsx +++ b/compass/components/Table/ResourceTable.tsx @@ -18,6 +18,7 @@ import { Tag } from "../TagsInput/Tag"; type ResourceTableProps = { data: Resource[]; setData: Dispatch>; + uuid: string; }; /** @@ -25,13 +26,17 @@ type ResourceTableProps = { * @param props.data Stateful list of resources to be displayed by the table * @param props.setData State setter for the list of resources */ -export default function ResourceTable({ data, setData }: ResourceTableProps) { +export default function ResourceTable({ + data, + setData, + uuid, +}: ResourceTableProps) { const columnHelper = createColumnHelper(); const [programPresets, setProgramPresets] = useState([ - "domestic", - "community", - "economic", + "DOMESTIC", + "COMMUNITY", + "ECONOMIC", ]); const resourceDetails: Details[] = [ @@ -137,6 +142,7 @@ export default function ResourceTable({ data, setData }: ResourceTableProps) { setData={setData} columns={columns} details={resourceDetails} + createEndpoint={`/api/resource/create?uuid=${uuid}`} /> ); } diff --git a/compass/components/Table/ServiceTable.tsx b/compass/components/Table/ServiceTable.tsx index 02bd1be..a4cfad3 100644 --- a/compass/components/Table/ServiceTable.tsx +++ b/compass/components/Table/ServiceTable.tsx @@ -16,6 +16,7 @@ import { Tag } from "../TagsInput/Tag"; type ServiceTableProps = { data: Service[]; setData: Dispatch>; + uuid: string; }; /** @@ -23,23 +24,27 @@ type ServiceTableProps = { * @param props.data Stateful list of services to be displayed by the table * @param props.setData State setter for the list of services */ -export default function ServiceTable({ data, setData }: ServiceTableProps) { +export default function ServiceTable({ + data, + setData, + uuid, +}: ServiceTableProps) { const columnHelper = createColumnHelper(); const [programPresets, setProgramPresets] = useState([ - "domestic", - "community", - "economic", + "DOMESTIC", + "COMMUNITY", + "ECONOMIC", ]); const [requirementPresets, setRequirementPresets] = useState([ - "anonymous", - "confidential", - "referral required", - "safety assessment", - "intake required", - "income eligibility", - "initial assessment", + "ANONYMOUS", + "CONFIDENTIAL", + "REFERRAL REQUIRED", + "SAFETY ASSESSMENT", + "INTAKE REQUIRED", + "INCOME ELIGIBILITY", + "INITIAL ASSESSMENT", ]); const serviceDetails: Details[] = [ @@ -165,6 +170,7 @@ export default function ServiceTable({ data, setData }: ServiceTableProps) { setData={setData} columns={columns} details={serviceDetails} + createEndpoint={`/api/service/create?uuid=${uuid}`} /> ); } diff --git a/compass/components/Table/UserTable.tsx b/compass/components/Table/UserTable.tsx index d4b1a38..6914e46 100644 --- a/compass/components/Table/UserTable.tsx +++ b/compass/components/Table/UserTable.tsx @@ -31,15 +31,15 @@ export default function UserTable({ data, setData, uuid }: UserTableProps) { const columnHelper = createColumnHelper(); const [rolePresets, setRolePresets] = useState([ - "admin", - "volunteer", - "employee", + "ADMIN", + "VOLUNTEER", + "EMPLOYEE", ]); const [programPresets, setProgramPresets] = useState([ - "domestic", - "community", - "economic", + "DOMESTIC", + "COMMUNITY", + "ECONOMIC", ]); const userDetails: Details[] = [ diff --git a/compass/components/TagsInput/Index.tsx b/compass/components/TagsInput/Index.tsx index e02a661..fd54caf 100644 --- a/compass/components/TagsInput/Index.tsx +++ b/compass/components/TagsInput/Index.tsx @@ -23,12 +23,8 @@ const TagsInput: React.FC = ({ const [cellSelected, setCellSelected] = useState(false); // TODO: Add tags to the database and remove the presetValue and lowercasing - const [tags, setTags] = useState>( - new Set(presetValue.map((tag) => tag.toLowerCase())) - ); - const [options, setOptions] = useState>( - new Set(presetOptions.map((option) => option.toLowerCase())) - ); + const [tags, setTags] = useState>(new Set(presetValue)); + const [options, setOptions] = useState>(new Set(presetOptions)); const [filteredOptions, setFilteredOptions] = useState>( new Set(presetOptions) ); @@ -44,7 +40,6 @@ const TagsInput: React.FC = ({ }; const handleOutsideClick = (event: MouseEvent) => { - console.log(dropdown.current); if ( dropdown.current && !dropdown.current.contains(event.target as Node) diff --git a/compass/components/TagsInput/Tag.tsx b/compass/components/TagsInput/Tag.tsx index 044e484..665572e 100644 --- a/compass/components/TagsInput/Tag.tsx +++ b/compass/components/TagsInput/Tag.tsx @@ -11,6 +11,7 @@ export const Tag = ({ children, handleDelete, active = false }: TagProps) => { return ( {children} {active && handleDelete && (