Skip to content

Commit

Permalink
Merge pull request #55 from ChangePlusPlusVandy/create-program
Browse files Browse the repository at this point in the history
Create program
  • Loading branch information
JiashuHarryHuang authored Mar 8, 2024
2 parents 8de5be7 + ed3daee commit cecb6c9
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 65 deletions.
119 changes: 92 additions & 27 deletions components/Forms/CreateProgramPopupWindow.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,117 @@
import React from 'react';
import React, { useState } from 'react';
import PopupWindow from '@/components/PopupWindow';
import {
CreateEventContainer,
CreateEventForm,
FormLabel,
FormHeader,
InputFlex,
FormInput,
LargeFormInput,
} from '@/styles/components/event.styles';
import { LongFormInput } from '@/styles/components/editEventPopupWindowForm.styles';
LongFormInput,
CreateProgramContainer,
} from '@/styles/components/createProgram.styles';
import {
SubmitButton,
ButtonCenter,
} from '@/styles/components/windowFlow.styles';
import { useForm } from 'react-hook-form';
import { VolunteerProgramData } from 'bookem-shared/src/types/database';
import { fetcher } from '@/utils/utils';
import useSWR from 'swr';
import { Modal, message } from 'antd';

const CreateProgramPopupWindow = ({
setShowPopup,
messageApi,
}: {
setShowPopup: React.Dispatch<React.SetStateAction<boolean>>;
messageApi: any;
}) => {
const { handleSubmit } = useForm({});
const onSubmit = (data: any) => {};
const {
data: allPrograms,
isLoading,
error,
mutate, // Used to refetch the data
} = useSWR<VolunteerProgramData[]>('/api/program/', fetcher, {
onSuccess: data => {
console.log(allPrograms);
},
});
// ANTD message
const [programName, setProgramName] = useState('');
const [programDescription, setProgramDescription] = useState('');

const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

// check if the program name already exists
if (allPrograms?.some(p => p.name === programName)) {
messageApi.open({
type: 'warning',
content: 'Program name already exists.',
});
} else {
const response = await fetch('/api/program/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: programName,
description: programDescription,
}),
});
if (response.ok) {
const resObj = await response.json();
console.log(resObj);
messageApi.open({
type: 'success',
content: resObj.message,
});
mutate();
setShowPopup(false);
} else {
messageApi.open({
type: 'error',
content: 'Failed to create program',
});
}
}
};

return (
<PopupWindow hidePopup={() => setShowPopup(false)}>
<CreateEventContainer>
<CreateEventForm>
<FormHeader>Create Program</FormHeader>
<FormLabel>Program Name</FormLabel>
<InputFlex>
<LongFormInput
type="text"
placeholder="Program Name"
pattern="[A-Za-z]"
title="Input must be text"
/>
</InputFlex>
<>
<PopupWindow hidePopup={() => setShowPopup(false)}>
<CreateProgramContainer>
<CreateEventForm onSubmit={handleSubmit}>
<FormHeader>Create Program</FormHeader>
<FormLabel>Program Name</FormLabel>
<InputFlex>
<LongFormInput
type="text"
placeholder="Program Name"
title="Input must be text"
value={programName}
onChange={e => setProgramName(e.target.value)}
maxLength={50}
/>
</InputFlex>

<FormLabel>Program Description</FormLabel>
<LargeFormInput placeholder="Program Description" />
<FormLabel>Program Description</FormLabel>
<LargeFormInput
placeholder="Program Description"
value={programDescription}
onChange={e => setProgramDescription(e.target.value)}
maxLength={250}
/>

<ButtonCenter>
<SubmitButton onClick={handleSubmit(onSubmit)}>Create</SubmitButton>
</ButtonCenter>
</CreateEventForm>
</CreateEventContainer>
</PopupWindow>
<ButtonCenter>
<SubmitButton type="submit">Create</SubmitButton>
</ButtonCenter>
</CreateEventForm>
</CreateProgramContainer>
</PopupWindow>
</>
);
};

Expand Down
23 changes: 21 additions & 2 deletions components/table/event-table/EventTableImpl.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import { Table, TableProps, Tag, Input, Popover } from 'antd';
import { Table, TableProps, Tag, Input, Popover, Button } from 'antd';
import type {
ColumnType,
ColumnsType,
Expand Down Expand Up @@ -69,6 +69,19 @@ const EventTableImpl = ({
useEffect(() => {
setFilteredDataByTags(dataForTable);
}, [dataForTable, setFilteredDataByTags]);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);

const onSelectChange = newSelectedRowKeys => {
setSelectedRowKeys(newSelectedRowKeys);
};
const rowSelection = {
selectedRowKeys,
onChange: onSelectChange,
};
// const hasSelected = selectedRowKeys.length > 0;
const handleAddEvent = () => {
console.log(selectedRowKeys);
};

// check for errors and loading
if (error) return <div>Failed to load event table</div>;
Expand Down Expand Up @@ -193,15 +206,21 @@ const EventTableImpl = ({
<>
{showPopup && <CreateEventPopupWindow setShowPopup={setShowPopup} />}
{showPopupTag && <TagEventPopupWindow setShowPopup={setShowPopupTag} />}
{/* <Button type="primary" onClick={handleAddEvent} disabled={!hasSelected} /> */}
{/* {hasSelected ? `Selected ${selectedRowKeys.length} items` : ''} */}

<TableHeader
setShowPopup={setShowPopup}
showPopup={showPopup}
setShowPopupTag={setShowPopupTag}
showPopupTag={showPopup}
/>
hasSelected={selectedRowKeys.length > 0}
numSelected={selectedRowKeys.length}></TableHeader>

<TableContainer>
<div id="table-container">
<Table
rowSelection={rowSelection}
dataSource={filteredDataByTags}
onChange={handleChange}
columns={columns}
Expand Down
30 changes: 17 additions & 13 deletions components/table/event-table/TableHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { SearchContainter, TableButton } from '@/styles/table.styles';
import {
SearchContainter,
TableButton,
TableIcon,
} from '@/styles/table.styles';
import React from 'react';
import Image from 'next/image';
import { Button } from 'antd';
Expand All @@ -9,17 +13,21 @@ const TableHeader = ({
showPopup,
setShowPopupTag,
showPopupTag,
hasSelected,
numSelected,
}: {
setShowPopup: (a: boolean) => void;
showPopup: boolean;
setShowPopupTag: (a: boolean) => void;
showPopupTag: boolean;
hasSelected: boolean;
numSelected: number;
}) => {
return (
<>
<div>
<SearchContainter>
<TableButton>
<TableIcon>
<Image
onClick={() => setShowPopup(!showPopup)}
src="/table/addbutton.png"
Expand All @@ -28,8 +36,8 @@ const TableHeader = ({
height={32}
style={{ marginRight: 20 }}
/>
</TableButton>
<TableButton>
</TableIcon>
<TableIcon>
<Image
onClick={() => {
setShowPopup(false);
Expand All @@ -40,17 +48,13 @@ const TableHeader = ({
width={32}
height={32}
/>
</TableIcon>
<TableButton disabled={!hasSelected}>
{numSelected > 0 ? `Add ${numSelected} events` : 'Add event'}
</TableButton>
<Button
onClick={() => handleExport('events')}
style={{
width: 250,
marginLeft: 90,
backgroundColor: 'darkgray',
color: 'whitesmoke',
}}>
<TableButton onClick={() => handleExport('events')}>
Export
</Button>
</TableButton>
</SearchContainter>
</div>
</>
Expand Down
11 changes: 9 additions & 2 deletions components/table/program-table/ProgramTableImpl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import CreateProgramPopupWindow from '@/components/Forms/CreateProgramPopupWindo
import React, { useState } from 'react';
import TableHeader from './TableHeader';
import { TableContainer } from '@/styles/table.styles';
import { Button } from 'antd';
import { Button, message } from 'antd';
import { ProgramDataIndex, ProgramRowData } from '@/utils/table-types';
import { ColumnType, ColumnsType } from 'antd/es/table';
import { Table } from 'antd';
Expand All @@ -17,6 +17,7 @@ const ProgramTableImpl = ({
dataForTable: ProgramRowData[];
}) => {
const [showPopUp, setShowPopUp] = useState(false);
const [messageApi, contextHolder] = message.useMessage();

const columns: ColumnsType<ProgramRowData> = [
{
Expand All @@ -39,7 +40,13 @@ const ProgramTableImpl = ({
];
return (
<>
{showPopUp && <CreateProgramPopupWindow setShowPopup={setShowPopUp} />}
{contextHolder}
{showPopUp && (
<CreateProgramPopupWindow
messageApi={messageApi}
setShowPopup={setShowPopUp}
/>
)}
<div>
<TableHeader setShowPopUp={setShowPopUp} showPopUp={showPopUp} />
<TableContainer>
Expand Down
21 changes: 9 additions & 12 deletions components/table/program-table/TableHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { SearchContainter, TableButton } from '@/styles/table.styles';
import {
SearchContainter,
TableButton,
TableIcon,
} from '@/styles/table.styles';
import React from 'react';
import Image from 'next/image';
import { Button } from 'antd';
Expand All @@ -14,25 +18,18 @@ const TableHeader = ({
return (
<>
<SearchContainter>
<TableButton onClick={() => setShowPopUp(!showPopUp)}>
<TableIcon onClick={() => setShowPopUp(!showPopUp)}>
<Image
src="/table/addbutton.png"
alt=""
width={32}
height={32}
style={{ marginLeft: 150 }}
/>
</TableButton>
<Button
onClick={() => handleExport('programs')}
style={{
width: 250,
marginLeft: 90,
backgroundColor: 'darkgray',
color: 'whitesmoke',
}}>
</TableIcon>
<TableButton onClick={() => handleExport('programs')}>
Export
</Button>
</TableButton>
</SearchContainter>
</>
);
Expand Down
22 changes: 18 additions & 4 deletions pages/api/program/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import dbConnect from '@/lib/dbConnect';
import Users from 'bookem-shared/src/models/Users';
import VolunteerPrograms from 'bookem-shared/src/models/VolunteerPrograms';
import Tags from 'bookem-shared/src/models/Tags';
import {
QueriedUserData,
QueriedVolunteerProgramData,
Expand All @@ -14,9 +13,6 @@ export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
// Get session user
const session = await getServerSession(req, res, authOptions);

switch (req.method) {
/**
* @route GET /api/program/
Expand All @@ -34,6 +30,24 @@ export default async function handler(
}
break;

case 'POST':
try {
await dbConnect();
const { name, description } = req.body;
const program = new VolunteerPrograms({
name: name,
description: description,
});
await program.save();
return res
.status(200)
.json({ message: 'Program created successfully' });
} catch (error) {
console.error(error);
res.status(500).json({ message: 'Server error' });
}
break;

// case 'PUT':
// case 'DELETE':
// default:
Expand Down
Loading

0 comments on commit cecb6c9

Please sign in to comment.