diff --git a/frontend/src/Dashboard.tsx b/frontend/src/Dashboard.tsx index a687b15..c2d91d1 100644 --- a/frontend/src/Dashboard.tsx +++ b/frontend/src/Dashboard.tsx @@ -16,6 +16,7 @@ type Job = { pay: number; start: Date; end: Date; + user_id: string; }; interface Pet { @@ -55,6 +56,17 @@ interface User { username: string; } +const PetCardChip = (props: { title: string; value: string }) => { + return ( +
+ + {props.title} + + {props.value} +
+ ); +}; + const Dashboard = () => { const [activeTab, setActiveTab] = useState("available jobs"); const [jobs, setJobs] = useState([]); @@ -62,6 +74,7 @@ const Dashboard = () => { const [searchTerm, setSearchTerm] = useState(""); const [error, setError] = useState(null); // const [locations, setLocations] = useState([]); + const [petPictures, updatePetPictures] = useState>({}); useEffect(() => { const fetchJobs = async () => { @@ -98,6 +111,31 @@ const Dashboard = () => { fetchJobs(); }, []); + useEffect(() => { + if (jobs.length) { + jobs.forEach(async (job: Job) => { + const petID = job.pet.id; + console.log(job); + axios + .get(`${API_ROUTES.USER.PET_PICTURE}?id=${petID}&owner_id=${job.location.user_id}`, { + responseType: "blob", + }) + .then((response) => { + if (response.status === 200) { + const newPetPicture = URL.createObjectURL(response.data); + updatePetPictures((state) => ({ + ...state, + [petID]: newPetPicture, + })); + } + }) + .catch((err) => { + console.error(`failed to fetch user pet picture with id: ${petID}`, err); + }); + }); + } + }, [jobs.length]); + const fetchMyApplications = async () => { try { const response = await axios.get(`${API_ROUTES.APPLY}`); @@ -213,15 +251,36 @@ const Dashboard = () => {
  • -

    Pet Name: {job.pet.name}

    -

    Job Status: {job.status}

    -

    - Location: {job?.location?.address ?? ""},{" "} - {job?.location?.city ?? ""}, {job?.location?.zipcode ?? ""} -

    -

    Pay: ${job.pay}

    -

    Start: {formatDate(job.start)}

    -

    End: {formatDate(job.end)}

    +
    Pet Name: {job.pet.name}
    +
    + + + + + + +

    + Health Requirements: {job.pet.health_requirements} +

    +
    +
    +
    +
    +

    Job Status: {job.status}

    +

    + Location: {job?.location?.address ?? ""},{" "} + {job?.location?.city ?? ""}, {job?.location?.zipcode ?? ""} +

    +

    Pay: ${job.pay}

    +

    Start: {formatDate(job.start)}

    +

    End: {formatDate(job.end)}

    +
    + {`${job.pet.name} +
    {job.status === "open" && (
    @@ -307,22 +307,30 @@ const JobPage: React.FC = () => { } }; + const getDefaultLocation = (locations: Location[]) => { + const default_location = locations.filter((location: Location) => location.default_location); + if (default_location.length > 0) { + setJobFormData({ ...jobFormData, location: default_location[0].id }); + } + }; + const getLocations = () => { return axios .get(API_ROUTES.USER.LOCATION) .then((response) => { setLocations(response?.data ?? []); - const default_location = response.data.filter( - (location: Location) => location.default_location - ); - if (default_location.length > 0) { - setJobFormData({ ...jobFormData, location: default_location[0].id }); - } }) .catch((err) => { console.error("failed to fetch locations", err); }); }; + + useEffect(() => { + if (jobFormData.location.length === 0) { + getDefaultLocation(locations); + } + }, [getLocations]); + const onClickSave = () => { try { checkDates(); @@ -332,7 +340,6 @@ const JobPage: React.FC = () => { } const saveConsent = window.confirm("Are you sure you want to make these changes?"); if (saveConsent) { - //console.log(jobFormData); jobFormData.status = "open"; axios .post(API_ROUTES.JOBS, jobFormData) @@ -374,13 +381,8 @@ const JobPage: React.FC = () => { const getCurrentDateTime = () => { const now = new Date(); - const year = now.getFullYear(); - const month = (now.getMonth() + 1).toString().padStart(2, "0"); - const day = now.getDate().toString().padStart(2, "0"); - const hour = now.getHours().toString().padStart(2, "0"); - const minute = now.getMinutes().toString().padStart(2, "0"); - - return `${year}-${month}-${day}T${hour}:${minute}`; + const ISOString = now.toISOString(); + return ISOString.slice(0, 16); }; const handleStartUpdate = (e: any) => { @@ -389,7 +391,7 @@ const JobPage: React.FC = () => { const now = new Date(); if (selectedStart > now) { - setJobFormData({ ...jobFormData, start: e.target.value }); + setJobFormData({ ...jobFormData, start: selectedStart.toISOString() }); } else { setJobFormData({ ...jobFormData, start: "" }); toast.error("Start datetime must be in the future."); @@ -403,7 +405,7 @@ const JobPage: React.FC = () => { const selectedEndDate = new Date(e.target.value); if (selectedEndDate > startDate) { - setJobFormData({ ...jobFormData, end: e.target.value }); + setJobFormData({ ...jobFormData, end: selectedEndDate.toISOString() }); } else { toast.error("End datetime must be after start."); } @@ -422,6 +424,12 @@ const JobPage: React.FC = () => { } }; + const displayDate = (date: string) => { + const newDate = new Date(date); + newDate.setTime(newDate.getTime() - 5 * 60 * 60 * 1000); + return newDate.toISOString().slice(0, 16); + }; + return (
    @@ -508,12 +516,13 @@ const JobPage: React.FC = () => { + handleStartUpdate(e)} className="border border-gray-300 rounded-md p-2 mt-1" /> @@ -525,8 +534,8 @@ const JobPage: React.FC = () => { type="datetime-local" name="end" id="job-end" - min={jobFormData.start} - value={jobFormData.end} + min={jobFormData.start ? displayDate(jobFormData.start) : getCurrentDateTime()} + value={jobFormData.end ? displayDate(jobFormData.end) : jobFormData.end} onChange={(e) => handleEndUpdate(e)} className="border border-gray-300 rounded-md p-2 mt-1" /> diff --git a/frontend/src/Locations.tsx b/frontend/src/Locations.tsx index df01bf9..1d7c43c 100644 --- a/frontend/src/Locations.tsx +++ b/frontend/src/Locations.tsx @@ -94,6 +94,18 @@ const Locations = () => { setZipcode(location.zipcode); }; + const onClickDelete = (location: FurbabyLocation) => { + axios + .delete(API_ROUTES.USER.LOCATION, { data: { id: location.id } }) + .then((resp) => { + console.log(resp); + getLocations(); + }) + .catch((err) => { + console.error(err); + }); + }; + const renderCards = React.useMemo(() => { //console.log(locations); @@ -113,18 +125,41 @@ const Locations = () => { {loc.city}, {loc.country} - {loc.zipcode}

    - +
    + + +
    {loc.default_location ? ( ) : (