Skip to content

Instantly share code, notes, and snippets.

@MonteLogic
Created April 22, 2024 15:15
Show Gist options
  • Select an option

  • Save MonteLogic/573bd7d8e2095ee2831f03ebb149d41b to your computer and use it in GitHub Desktop.

Select an option

Save MonteLogic/573bd7d8e2095ee2831f03ebb149d41b to your computer and use it in GitHub Desktop.
'use client'
import { useState, MouseEventHandler, useEffect } from 'react'; // Import MouseEventHandler
import Button from './button';
import { updateSummary } from '#/app/api/search-shift/network-fns';
import TextareaAutosize from 'react-textarea-autosize';
import { UploadButton } from "#/app/utils/uploadthing";
import { ImageString } from './image-slider';
import StandardModal from './standard-modal';
import { FormattedRouteType } from "#/types/RouteTypes";
import { useSearchParams, usePathname, useRouter } from 'next/navigation';
interface WorkTimeObjectSummary {
earlyMorning?: { text?: string; imgURLs?: string[] }[];
midMorning?: { text?: string; imgURLs?: string[] }[];
midDay?: { text?: string; imgURLs?: string[] }[];
afternoon?: { text?: string; imgURLs?: string[] }[];
}
// I don't even need that routeIDs API call stuff when I can just pipe it in from the server component.
// But how will we get new information from that server component like we can with an API call.
export const SummarySelection = ({ initRoutes }: { initRoutes: FormattedRouteType }) => {
console.log(46, initRoutes);
const [dateSelection, setDateSelection] = useState(new Date().toISOString().split('T')[0]); // Set the initial date format to match the input type
const [routeIDFromURL, setRouteIDFromURL] = useState<string | null>(null);
const [routeIDs, setRouteIDs] = useState(initRoutes); // Add the 'routes' property with an empty array as the default value
const [summaryObject, setSummaryObject] = useState<WorkTimeObjectSummary | null>(null); // Initialize with null
const [entryID, setEntryID] = useState<string | null>(null); // State to hold the new summary value
const [currentPORoute, setCurrentPORoute] = useState<string | null>(null); // State to hold the new summary value
const searchParams = useSearchParams();
const pathname = usePathname();
const { replace } = useRouter();
const RouteSelect = () => {
const defaultValue = searchParams.get('route')?.toString();
const handleChange = (e: any) => {
const selectedRoute = e.target.value;
setSearchURL(dateSelection, selectedRoute);
setRouteIDFromURL(selectedRoute);
searchForSummary(dateSelection, selectedRoute ?? '');
};
return (
<select
className="text-gray-900"
id="routes"
name="routes"
value={routeIDFromURL ?? ''}
defaultValue={defaultValue}
onChange={handleChange}
>
{routeIDs.length > 0 ? (
routeIDs.map((route: any) => (
<option key={route[0]} value={route[0]}>
{`${route[0]}-${route[1]}`}
</option>
))
) : (
<option value="No routes found">No routes found</option>
)}
</select>
);
};
// Route is set but not by default, let's make it default.
const setSearchURL = (date: string, route: string) => {
console.log(62, date);
const params = new URLSearchParams(searchParams);
if (date) {
params.set('date', date);
} else {
params.delete('date');
}
if (route) {
params.set('route', route);
} else {
params.delete('route');
}
replace(`${pathname}?${params.toString()}`);
}
const searchForSummary = async (date: string, routeID: string) => {
try {
const response = await fetch(`/api/search-shift?date=${date}&routeID=${routeID}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (response.ok) {
const data = await response.json();
const receivedID = data["id"];
if (receivedID) {
setEntryID(receivedID);
}
const field = data?.field?.[0]?.summary?.earlyMorning || [];
const routeIDCurrent = data?.field?.[0]?.routeIDFromPostOffice || [];
const fullSummaryResponse = data?.field?.[0]?.summary || [];
setCurrentPORoute(routeIDCurrent);
console.log(107, currentPORoute);
if (fullSummaryResponse) {
console.log(111, fullSummaryResponse);
// Update the state with the fetched route summary
setSummaryObject(fullSummaryResponse); // Set the summaryObject state with the fullSummaryResponse
} else {
console.error('No route summary found');
}
const routeSummaryResponse = field || [];
console.log(87.1, routeSummaryResponse);
return "Has updated"; // It's better to return a value rather than a string
} else {
// Error occurred while updating work time
alert("Could not find matching day."); // Update search result state
console.error('Error updating work time');
}
} catch (error) {
console.error('Error updating work time', error);
alert('Error viewing work time');
}
};
// This could be a variable in a different file, and still need judger in this file to judge whether
// or not to display the relevant shifts.
const routeComponents = [
{
shiftNiceName: "Early Morning",
shiftName: "earlyMorning"
},
{
shiftNiceName: "Mid Morning",
shiftName: "midMorning"
},
{
shiftNiceName: "Mid Day",
shiftName: "midDay"
},
{
shiftNiceName: "Afternoon",
shiftName: "afternoon"
},
]
function getActiveShifts(id: string, index: number): void {
const shifts = routeIDs[index];
console.log(230, shifts);
const location = shifts?.find((entry: any) => entry[0] === id);
if (!location) {
console.log("Location not found.");
return;
}
// @ts-ignore
const shiftInfo = location[2];
if (!shiftInfo) {
console.log("No shift information available for this location.");
return;
}
// @ts-ignore
const activeShifts = Object.entries(shiftInfo.allocatedShifts).filter(
// @ts-ignore
([_, shift]) => shift.active === 1
);
}
const summaryObjectFunc = (summaryObject: any) => {
if (!summaryObject) {
return null
}
console.log(242, routeComponents);
return (
<>
{routeComponents.map((routeComponent, index) => {
const key = `${routeComponent.shiftName}-${index}`; // Generate a unique key
console.log(250, routeIDs);
const shifts = routeIDs[index];
// if (routeIDs.routes[i][0] === routeID) {
console.log(207, shifts);
// Example usage:
getActiveShifts(currentPORoute as string, index);
return (
<div key={key}>
<p>Shift: {routeComponent.shiftNiceName}</p>
<TextareaAutosize
className="text-gray-900"
id="newSummaryInputID"
name="newSummaryInputName"
minRows={3}
// This is WorkTime info but I think it's only showing summary stuff.
value={(summaryObject && (summaryObject as WorkTimeObjectSummary)[routeComponent.shiftName as keyof WorkTimeObjectSummary]?.[0]?.text) || ''}
onChange={(e) => {
setSummaryObject((prevSummaryObject: WorkTimeObjectSummary | null) => ({
...prevSummaryObject,
[routeComponent.shiftName as keyof WorkTimeObjectSummary]: [
{
text: e.target.value || '',
imgURLs: (prevSummaryObject && prevSummaryObject[routeComponent.shiftName as keyof WorkTimeObjectSummary]?.[0]?.imgURLs) || [],
},
],
}));
}} />
{(summaryObject as WorkTimeObjectSummary)[routeComponent.shiftName as keyof WorkTimeObjectSummary]?.[0] ? (
<ImageString
imgStringArray={(summaryObject as WorkTimeObjectSummary)[routeComponent.shiftName as keyof WorkTimeObjectSummary]?.[0]?.imgURLs?.map((image) => image) ?? []} />
) : (
<div>
<p>No images</p>
</div>
)}
<UploadButton
endpoint="imageUploader"
content={{
button({ ready }) {
if (ready) return <div>Upload Image for {routeComponent.shiftNiceName} Shift</div>;
return "Getting ready...";
},
allowedContent({ ready, fileTypes, isUploading }) {
if (!ready) return "Checking what you allow";
if (isUploading) return "Seems like stuff is uploading";
return `Stuff you can upload: ${fileTypes.join(", ")}`;
}
}}
onClientUploadComplete={(res) => {
// Do something with the response
console.log("Files: ", res);
console.log(346, res[0].url);
if (res[0].url) {
setSummaryObject((prevSummaryObject: WorkTimeObjectSummary | null) => {
const updatedObject = { ...prevSummaryObject };
const shiftName = routeComponent.shiftName as keyof WorkTimeObjectSummary;
// Check if the shiftName already exists in the ObjectSummary
if (updatedObject.hasOwnProperty(shiftName)) {
// Find the object corresponding to the shiftName
const existingArray = updatedObject[shiftName] as { text: string; imgURLs?: string[]; }[];
// Update the imgURLs array within the object
updatedObject[shiftName] = existingArray.map((item) => ({
...item,
imgURLs: [...(item.imgURLs || []), res[0].url]
}));
} else {
// If the shiftName doesn't exist, initialize it with a new array containing the new URL
updatedObject[shiftName] = [{ imgURLs: [res[0].url] }];
}
return updatedObject;
});
}
alert("Upload Completed");
}}
onUploadError={(error: Error) => {
// Do something with the error.
alert(`ERROR! ${error.message}`);
}} />
</div>
);
}
)}
<Button onClick={updateSummaryObject} type="submit">
Save Edited stuff</Button>
</>
)
}
const updateSummaryObject: MouseEventHandler<HTMLButtonElement> = async (
event
) => {
if (summaryObject) {
updateSummary(
entryID ?? '', dateSelection ?? '', routeIDFromURL ?? '',
setSummaryObject, summaryObject
);
}
};
useEffect(() => {
const currentDate = new Date().toISOString().split('T')[0];
searchForSummary(currentDate, routeIDFromURL ?? '');
}, []);
const viewResults = async (event: React.FormEvent<HTMLFormElement>) => {
// Here I want to pass the value of the input of the date.
setSearchURL(dateSelection, routeIDFromURL ?? '');
event.preventDefault();
searchForSummary(dateSelection ?? '', routeIDFromURL ?? ''); // Pass dateSelection instead of formData.date
};
const [modalIsOpen, setModalIsOpen] = useState(false);
const closeModal = () => {
setModalIsOpen(false);
};
return (
<><div>
{modalIsOpen && (
// I could have workTimeTop up here and then just watch for
// a change in workTimeEmployee and then just change the whole of
// work time top.
<StandardModal
setIsOpen={setModalIsOpen}
// employeeName={selectedEmployeeName}
// employeeID={selectedEmployeeID}
isOpen={modalIsOpen}
closeModal={closeModal} />
)}
</div>
<div>
<div className="space-y-1">
<label htmlFor="dateID" className="block" >Date to search:</label>
<input
className="text-gray-900"
type="date"
id="dateID"
name="date"
value={dateSelection}
onChange={(e) => {
setSearchURL(e.target.value, routeIDFromURL ?? '');
setDateSelection(e.target.value)
}
}
defaultValue={searchParams.get('date')?.toString()}
/>
<label htmlFor="routes" className="block">Choose a route:</label>
{RouteSelect()}
<Button onClick={viewResults as unknown as MouseEventHandler<HTMLButtonElement>}>View Summary of Day</Button>
</div>
{/* Add other fields for routeID */}
{summaryObjectFunc(summaryObject)}
</div></>
)
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment