Created
April 30, 2024 18:10
-
-
Save MonteLogic/798f8b9429449425f782a50afe2628c7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use client'; | |
import { useState, MouseEventHandler, useEffect } from 'react'; // Import MouseEventHandler | |
import Button from './button'; | |
import { updateSummary, createRecordForSummary } from '#/app/utils/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'; | |
import ConfirmingButton from './confirming-button'; | |
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; | |
}) => { | |
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(); | |
console.log(42, entryID); | |
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); | |
} | |
if (!receivedID) { | |
setEntryID(null); | |
} | |
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 | |
console.log('Could not find matching day, setting empty object.'); // Update search result state | |
setSummaryObject({}); // Set the summaryObject state with an empty object | |
setEntryID(null); | |
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]; | |
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; | |
} | |
return ( | |
<> | |
{routeComponents.map((routeComponent, index) => { | |
const key = `${routeComponent.shiftName}-${index}`; // Generate a unique key | |
const shifts = routeIDs[index]; | |
// if (routeIDs.routes[i][0] === routeID) { | |
// 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] }, | |
]; | |
} | |
// Call updateSummaryObject after setting the updated state | |
updateSummaryObject(); | |
return updatedObject; | |
}, | |
); | |
// Run the function updateSummaryObject to save the new image URL | |
alert('Upload Completed'); | |
} | |
}} | |
onUploadError={(error: Error) => { | |
// Do something with the error. | |
alert(`ERROR! ${error.message}`); | |
}} | |
/> | |
</div> | |
); | |
})} | |
<ConfirmingButton | |
onClick={updateSummaryObject} | |
disabled={saveEditedClicked} | |
> | |
{saveEditedClicked ? 'Saving...' : 'Save Edited Stuff'} | |
</ConfirmingButton> | |
</> | |
); | |
}; | |
const [saveEditedClicked, setSaveEditedClicked] = useState(false); | |
const updateSummaryObject: any = async () => { | |
setSaveEditedClicked(true); // Button has been clicked | |
setTimeout(() => { | |
setSaveEditedClicked(false); // Reset button after 1000 milliseconds (1 second) | |
}, 1000); | |
if (summaryObject) { | |
if (entryID) { | |
updateSummary( | |
entryID, | |
dateSelection ?? '', | |
routeIDFromURL ?? '', | |
setSummaryObject, | |
summaryObject, | |
); | |
} | |
if (!entryID) { | |
createRecordForSummary( | |
dateSelection ?? '', | |
routeIDFromURL ?? '', | |
setSummaryObject, | |
summaryObject, | |
); | |
} | |
} | |
}; | |
useEffect(() => { | |
const currentDate = new Date().toISOString().split('T')[0]; | |
searchForSummary(currentDate, routeIDFromURL ?? ''); | |
}, []); | |
const [clicked, setClicked] = useState(false); | |
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 | |
setClicked(true); // Button has been clicked | |
setTimeout(() => { | |
setClicked(false); // Reset button after 1000 milliseconds (1 second) | |
}, 1000); | |
}; | |
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()} | |
<ConfirmingButton | |
onClick={ | |
viewResults as unknown as MouseEventHandler<HTMLButtonElement> | |
} | |
disabled={clicked} // Disable the button if it has been clicked | |
> | |
{clicked ? 'Searching...' : 'View Summary of Day'} | |
</ConfirmingButton> | |
</div> | |
{summaryObjectFunc(summaryObject)} | |
</div> | |
</> | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment