kids and booking forms, instructions

This commit is contained in:
OddlyTimbot 2025-02-21 11:45:42 -05:00
parent e9b71f1993
commit 58ffa8622b
5 changed files with 196 additions and 8 deletions

View File

@ -1,3 +1,27 @@
# MemberPortal
Client for MemberService, used to manage member accounts at member site.
Client for MemberService, used to manage member accounts at member site.
## Installation
`npm install`
## Build and Deploy
In app.jsx switch to the URL of the live service.
`npm run build`
This will output to the dist folder one directory above.
Transfer that build folder to the server.
`scp -r -i ~/Documents/wowza-keys.pem dist ubuntu@107.20.181.47:/home/ubuntu/dist`
If in doubt, you can remove the dist folder on the server to ensure this is a fresh build.
`rm -r dist`
On the server, start the staticserver:
`nodemon staticserver.js`

View File

@ -2,6 +2,8 @@ import React, { useState, useEffect } from "react";
import { format, addMonths } from "date-fns"; // Import date-fns for formatting
import LockerRentalForm from "./lockerRentalForm.jsx"
import CertificationAssignmentForm from "./certAssignmentForm.jsx"
import StorageBookingForm from "./storagebookingform.jsx";
import KidsProgramEnrollmentForm from "./kidsprogramform.jsx";
import Button from "./button.jsx";
import './index.css'
@ -9,8 +11,8 @@ function App() {
const queryParams = new URLSearchParams(window.location.search);
const uuid = queryParams.get("uuid");
const [data, setData] = useState([]);
// const SERVICE_URL = 'https://service.ttlmakerspace.com';
const SERVICE_URL = 'http://localhost:3000';
const SERVICE_URL = 'https://service.ttlmakerspace.com';
//const SERVICE_URL = 'http://localhost:3000';
if(uuid){
useEffect(() => {
@ -145,6 +147,58 @@ function App() {
console.error("Error saving date:", error);
}
}
const handleStorageBooking =async (storage)=>{
console.log(storage)
try {
const response = await fetch(SERVICE_URL+"/member/storage/"+uuid, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(storage),
});
const responseData = await response.json();
if (response.ok) {
let cleanData = {...data};
cleanData.storage = storage;
setData(cleanData)
} else {
console.log("Failed to save data: " + (responseData.error || "Unknown error"));
}
} catch (error) {
console.error("Error saving date:", error);
}
}
const handleKidEnrollment =async (kid)=>{
console.log(kid)
console.log(data.jwb)
const allKids = data.jwb
allKids.push(kid)
let cleanData = {...data};
cleanData.jwb = allKids;
console.log(cleanData)
try {
const response = await fetch(SERVICE_URL+"/member/jwb/"+uuid, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(allKids),
});
const responseData = await response.json();
if (response.ok) {
setData(cleanData)
} else {
console.log("Failed to save data: " + (responseData.error || "Unknown error"));
}
} catch (error) {
console.error("Error saving date:", error);
}
}
if(uuid){
return (
<>
@ -161,16 +215,19 @@ function App() {
<div className="max-w-md mx-auto p-6 bg-white shadow-md rounded-lg">
{data.jwb ? (<><h3 className="text-xl font-semibold mb-4">Junior WorldBuilders:</h3>
<ul>
<KidsProgramEnrollmentForm onSubmit={handleKidEnrollment} />
{data.jwb.map((kid) => (
<li key={kid.name}>{kid.name}</li>
<li key={kid.childName}>{kid.childName}<br />{kid.program} Start Date: {format(addMonths(new Date(kid.startDate),1), "yyyy-MM-dd")}</li>
))}
</ul></>) : (<p>No Kids</p>)}
</>) : (<p>No Kids</p>)}
</div>
<div className="max-w-md mx-auto p-6 bg-white shadow-md rounded-lg">
{data.storage ? (<h4 className="text-xl font-semibold mb-4">Large Storage</h4>):(<></>)}
{data.storage ? (<p>Date Issued: {format(new Date(data.storage.dateIssued), "yyyy-MM-dd")}</p>):(<></>)}
{data.storage ? (<p>Date Issued: {format(new Date(data.storage.startDate), "yyyy-MM-dd")}</p>):(<></>)}
<StorageBookingForm onSubmit={handleStorageBooking} />
</div>
<div className="max-w-md mx-auto p-6 bg-white shadow-md rounded-lg">

View File

@ -11,7 +11,7 @@ const CertificationAssignmentForm = ({ onSubmit }) => {
};
return (
<div className="max-w-md mx-auto p-6 bg-white shadow-md rounded-lg">
<div className="outline-red-300 outline-dashed outline-4 outline-offset-2 max-w-md mx-auto p-6 bg-white shadow-md rounded-lg">
<h2 className="text-xl font-semibold mb-4">Assign Certification</h2>
<form onSubmit={handleSubmit(handleFormSubmit)}>
<div className="mb-4">

70
src/kidsprogramform.jsx Normal file
View File

@ -0,0 +1,70 @@
import React, { useState } from "react";
import { useForm, Controller } from "react-hook-form";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import { RadioGroup, Radio } from "@headlessui/react";
const programs = [
{ name: "Junior Worldbuilders" },
{ name: "Young Worldbuilders" },
];
const Field = ({ children }) => (
<div className="p-2 border rounded cursor-pointer">{children}</div>
);
const KidsProgramEnrollmentForm = ({ onSubmit }) => {
const { handleSubmit, control, register } = useForm();
const [selectedProgram, setSelectedProgram] = useState(programs[0].name);
const handleFormSubmit = (data) => {
const requestData = { ...data, program: selectedProgram };
onSubmit(requestData);
};
return (
<div className="outline-red-300 outline-dashed outline-4 outline-offset-2 max-w-md mx-auto p-6 bg-white shadow-md rounded-lg">
<h2 className="text-xl font-semibold mb-4">Enroll in Kids Program</h2>
<form onSubmit={handleSubmit(handleFormSubmit)}>
<div className="mb-4">
<label className="block text-sm font-medium">Child's Name</label>
<input
type="text"
{...register("childName", { required: true })}
className="border p-2 rounded w-full"
placeholder="Enter child's name"
/>
</div>
<div className="mb-4">
<label className="block text-sm font-medium">Start Date</label>
<Controller
name="startDate"
control={control}
defaultValue={new Date()}
render={({ field }) => (
<DatePicker className="border p-2 rounded w-full" selected={field.value} onChange={field.onChange} />
)}
/>
</div>
<div className="mb-4">
<label className="block text-sm font-medium">Program Selection</label>
<RadioGroup value={selectedProgram} onChange={setSelectedProgram} className="mt-2">
{programs.map(({ name }) => (
<Field key={name}>
<Radio value={name} className="flex items-center space-x-2 p-2 border rounded cursor-pointer data-[checked]:bg-blue-400 data-[disabled]:bg-gray-100">
<span>{name}</span>
</Radio>
</Field>
))}
</RadioGroup>
</div>
<button type="submit" className="w-full p-2 bg-blue-500 text-white rounded">Enroll</button>
</form>
</div>
);
};
export default KidsProgramEnrollmentForm;

View File

@ -0,0 +1,37 @@
import React from "react";
import { useForm, Controller } from "react-hook-form";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
const StorageBookingForm = ({ onSubmit }) => {
const { handleSubmit, control } = useForm();
const handleFormSubmit = (data) => {
onSubmit(data);
};
return (
<div className="outline-red-300 outline-dashed outline-4 outline-offset-2 max-w-md mx-auto p-6 bg-white shadow-md rounded-lg">
<h2 className="text-xl font-semibold mb-4">Book Storage Space</h2>
<form onSubmit={handleSubmit(handleFormSubmit)}>
<div className="mb-4">
<label className="block text-sm font-medium">Start Date</label>
<Controller
name="startDate"
control={control}
defaultValue={new Date()}
render={({ field }) => (
<DatePicker className="border p-2 rounded w-full" selected={field.value} onChange={field.onChange} />
)}
/>
</div>
<button type="submit" className="w-full p-2 bg-blue-500 text-white rounded">
Book Storage
</button>
</form>
</div>
);
};
export default StorageBookingForm;