Skip to content

Commit

Permalink
Merge branch 'dev' into frontend/31-internal-view-spreadsheet
Browse files Browse the repository at this point in the history
  • Loading branch information
jiyoonchoi committed Dec 3, 2024
2 parents 59c3fc1 + b0b3d9f commit 306f27d
Show file tree
Hide file tree
Showing 13 changed files with 908 additions and 103 deletions.
62 changes: 62 additions & 0 deletions app/api/categories/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();

async function createCategory(data: {
itemName : string,
name: string,
units: string[]
}) {
return await prisma.categories.create(
{ data:
{
itemName: data.itemName,
name: data.name,
units: data.units
}
}
)
}

async function readCategories() {
const categories = await prisma.categories.findMany();
return categories;
}

async function updateCategory(data : {
itemName : string,
name: string,
units: string[]
}) {
const { itemName, name, ...newData } = data;

return await prisma.categories.update({
where: {
itemName_name: {
itemName: itemName,
name: name
}
}, data:
{
units: data.units
},
})
}

async function deleteCategory(data: {
itemName: string,
name: string
}) {
const { itemName, name } = data;

return await prisma.categories.delete({
where: {
itemName_name: {
itemName: itemName,
name: name,
}
}
});
}

module.exports = {createCategory, readCategories, updateCategory, deleteCategory};

63 changes: 63 additions & 0 deletions app/api/categories/testCategoriesCrud.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// testing file for Demographics CRUD functions
// run npx prisma generate, npx prisma migrate dev & prisma db pull
// run testing file using 'tsx testCategoriesCrud.ts'

// importing the CRUD functions
import CRUD from './route';

async function main() {
const testData = {
itemName : 'banana',
name: 'fruit',
units: ['bunch']
};

try {
const testReadEmpty = await CRUD.readCategories();
console.log("read empty database", testReadEmpty);

//TEST CREATE
const testCreate = await CRUD.createCategory(testData);
console.log("created entry", testCreate);

//TEST READ
const testRead = await CRUD.readCategories();
const createdEntry = testRead[0];
if (createdEntry.itemName !== 'banana') {
throw new Error("error creating itemName");
}
if (createdEntry.name !== 'fruit') {
throw new Error("error creating name");
}
if (createdEntry.units[0] !== 'bunch') {
throw new Error("error creating units");
}
console.log("read entry", testRead);

const testUpdateData = {
itemName : 'banana',
name: 'fruit',
units: ['bag']
}
const testUpdate = await CRUD.updateCategory(testUpdateData);
if (testUpdate.units[0] !== 'bag') {
throw new Error("error updating units");
}
console.log("updated entry", testUpdate);

const deleteData = {
itemName: "banana",
name: "fruit"
}
const testDelete = await CRUD.deleteCategory(deleteData);
console.log("deleted entry");
const testReadAfterDelete = await CRUD.readCategories();
console.log("read after delete", testReadAfterDelete);

}
catch (error) {
console.log(error);
}
}

main();
140 changes: 130 additions & 10 deletions app/api/demographics/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// your route file for demographics
// const { PrismaClient } = require ('@prisma/client');
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient();
import { NextRequest, NextResponse } from 'next/server'
const prisma = new PrismaClient()


//CREATE
async function createDemographic(data: {
Expand Down Expand Up @@ -67,11 +67,131 @@ return await prisma.demographics.delete({
})
}

//export the functions
module.exports = {
createDemographic,
getDemographic,
updateDemographic,
deleteDemographic
};
// POST
export async function POST(req: NextRequest) {

try {
const record = await req.json()
if (!validDemographic(record)) {
return NextResponse.json(
{ response : "Invalid data format" },
{ status : 400 }
)
}

record.lastVisitDate = new Date()
const response = await createDemographic({ ...record })

return NextResponse.json(response, {status : 201})
} catch (error) {
console.log(error)
return NextResponse.json(
{ response : "Failed to create record" },
{ status : 500 })
}
}

// GET
export async function GET() {
try {
const items = await getDemographic()
return NextResponse.json(items, { status : 200 })
} catch (error) {
console.log(error)
return NextResponse.json(
{ response : "Failed to get records" },
{ status : 500 }
)
}
}

// PUT
export async function PUT(
req: NextRequest,
) {
try {
const record = await req.json()
if (!validDemographic(record)) {
return NextResponse.json(
{ response : "Invalid data format" },
{ status : 400 }
)
}

record.lastVisitDate = new Date()
const item = await updateDemographic({ ...record });

return NextResponse.json(item, { status : 200 })
} catch (error) {
console.log(error)
return NextResponse.json(
{ response : "Failed to update entry" },
{ status : 500 }
)
}
}

// DELETE
export async function DELETE(
req: NextRequest
) {
try {
const data = await req.json()
if (!("phoneNumber" in data)) {
return NextResponse.json(
{ response: "Missing phone number" },
{ status: 400 }
)
}

const item = await deleteDemographic(data.phoneNumber)
return NextResponse.json(item, {status : 200})
} catch (error) {
console.log(error)
return NextResponse.json(
{ response : "Failed to delete record" },
{ status : 500 }
)
}
}

interface DemographicRecord {
phoneNumber: string;
takeCount: number;
donateCount: number;
name: string;
householdSize: number;
address: string;
lastVisitDate: string;
}

function validDemographic(record : DemographicRecord): boolean {

try {
const { lastVisitDate, ...recordWithoutLastVisitDate } = record;

const fields = new Set<string>([
"phoneNumber",
"takeCount",
"donateCount",
"name",
"householdSize",
"address",
]);

const keys = Object.keys(recordWithoutLastVisitDate)
if (keys.length !== fields.size) return false

let fieldsMatch = true
keys.forEach( (field: string) => {
if (!fields.has(field)) fieldsMatch = false
fields.delete(field)
})

return fieldsMatch

} catch (error) {
console.log(error)
return false
}
}
15 changes: 13 additions & 2 deletions app/components/Dropdowns.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
//implements rounded dropdown menu
export function NameDropdown() {

interface NameDropdownProps {
options: string[];
onSelect?: (selected: string) => void;
}

export function NameDropdown({ options = [], onSelect = () => {} }: NameDropdownProps) {
return (
<select
className="select select-bordered w-full max-w-m -mt-10 rounded-xl border-light-gray"
defaultValue=""
onChange={(e) => onSelect(e.target.value)}
>
<option disabled value=""/>
<option>Placeholder</option>
{options.map((option, index) => (
<option key={index} value={option}>
{option}
</option>
))}
</select>
)
}
40 changes: 40 additions & 0 deletions app/components/ExitModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use client';

import React from 'react';
import { useRouter } from 'next/navigation';
import { ButtonCancel, ButtonExit } from '@app/components/SurveyButtons';

interface ExitModalProps {
closeModal: () => void;
}

const ExitModal: React.FC<ExitModalProps> = ({ closeModal }) => {
const router = useRouter();

const handleExitAnyway = () => {
router.push('/volunteer-unsaved');
};

return (
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
<div
className="h-[240px] w-[550px] bg-modal-gray font-crimson
fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2
pt-8 shadow-lg rounded-lg"
>
<div className="flex flex-col">
<p className="flex justify-center text-[28px] crimson-bold">Warning!</p>
<p className="flex justify-center text-[28px] crimson-bold">
Your changes will not be saved.
</p>
</div>
<div className="flex flex-row justify-around pt-8">
<ButtonCancel onClick={closeModal} />
<ButtonExit onClick={handleExitAnyway} />
</div>
</div>
</div>
);
};

export default ExitModal;
28 changes: 28 additions & 0 deletions app/components/PhoneNumberInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { useState } from 'react';
import PhoneInput from 'react-phone-input-2';
import 'react-phone-input-2/lib/style.css';

interface PhoneNumberInputProps {
value?: string;
onChange?: (newValue: string | undefined) => void;
}

export default function PhoneNumberInput({ value, onChange }: PhoneNumberInputProps) {
const handleChange = (newValue: string | undefined) => {
if (onChange) {
onChange(newValue);
}
};

return (
<div className="flex flex-col items-center">
<PhoneInput
country="us"
value={value}
onChange={handleChange}
placeholder=""
inputClass="bg-gray-50 border border-light-gray text-gray-900 rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-6 text-8xl"
/>
</div>
);
}
Loading

0 comments on commit 306f27d

Please sign in to comment.