Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rt el estimate next purchase #26

Merged
merged 13 commits into from
Sep 13, 2024
Merged
31 changes: 21 additions & 10 deletions src/api/firebase.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
} from 'firebase/firestore';
import { useEffect, useState } from 'react';
import { db } from './config';
import { getFutureDate } from '../utils';
import { getFutureDate, getDaysBetweenDates } from '../utils';
import { calculateEstimate } from '@the-collab-lab/shopping-list-utils';

/**
* A custom hook that subscribes to the user's shopping lists in our Firestore
Expand Down Expand Up @@ -182,11 +183,7 @@ export async function addItem(listPath, { itemName, daysUntilNextPurchase }) {
}
}

export async function updateItem(
listPath,
itemId,
{ dateLastPurchased, totalPurchases },
) {
export async function updateItem(listPath, itemId, { totalPurchases }) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I discovered when I create an item and mark it as purchased, the dateNextPurchased is updated to the current date:
Screenshot 2024-09-12 at 09 13 40

I think this is weird bc we are rolling back the dateNextPurchase, and I believe this shouldn't be happening.
This is the item date when it was first created, before being marked as purchased:
Screenshot 2024-09-12 at 09 13 24
What do you think?

/**
* TODO: Fill this out so that it uses the correct Firestore function
* to update an existing item. You'll need to figure out what arguments
Expand All @@ -196,12 +193,26 @@ export async function updateItem(
try {
// Get a reference to the specific item document in Firestore
const itemRef = doc(db, listPath, 'items', itemId);
const docSnap = await getDoc(itemRef);
const data = docSnap.data();

const lastPurchase = data.dateLastPurchased
? data.dateLastPurchased.toDate()
: data.dateCreated.toDate();
const nextPurchase = data.dateNextPurchased.toDate();

const prevEstimate = getDaysBetweenDates(lastPurchase, nextPurchase);
const daysSinceLastPurch = getDaysBetweenDates(lastPurchase, new Date());
const newEstimate = calculateEstimate(
prevEstimate,
daysSinceLastPurch,
data.totalPurchases,
);

await updateDoc(itemRef, {
dateLastPurchased: dateLastPurchased || new Date(), // Use the provided date or the current date
// totalPurchases need to be incremented every time the checkbox is ticked off
totalPurchases: totalPurchases, // Increment totalPurchases or set it to 1 if undefined
// dateNextPurchased will be addressed in the future
dateLastPurchased: new Date(),
totalPurchases: totalPurchases,
dateNextPurchased: getFutureDate(newEstimate),
});
} catch (error) {
console.log(error);
Expand Down
32 changes: 4 additions & 28 deletions src/components/ListItem.jsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,33 @@
import { useState, useEffect } from 'react';
import './ListItem.css';
import { getFutureDate } from '../utils';

export function ListItem({ name, id, dateLastPurchased, onCheck }) {
// State to track whether the item is checked

export function ListItem({ name, dateLastPurchased, onCheck }) {
const [isChecked, setIsChecked] = useState(false);

// to see if `dateLastPurchased` and `isChecked` are working
console.log(`Rendering ListItem for ${name}:`, {
dateLastPurchased,
isChecked,
});

// Update `isChecked` based on the `dateLastPurchased` value

useEffect(() => {
const checkStatus = () => {
if (dateLastPurchased) {
// If dateLastPurchased is a Firestore _Timestamp, convert it to a JavaScript Date
const purchaseDate = dateLastPurchased.toDate
? dateLastPurchased.toDate()
: new Date(dateLastPurchased);
const purchaseDate = dateLastPurchased.toDate();
const timeSinceLastPurchase = new Date() - purchaseDate;
const hasBeenPurchasedRecently =
timeSinceLastPurchase < 24 * 60 * 60 * 1000; // 24 hours
timeSinceLastPurchase < 24 * 60 * 60 * 1000;

// Log check status
console.log(
`${name} was last purchased ${timeSinceLastPurchase} ms ago.`,
);
setIsChecked(hasBeenPurchasedRecently);
} else {
console.log(`${name} has never been purchased.`);
setIsChecked(false);
}
};

// initial check
checkStatus();
}, [dateLastPurchased]);

// old code from here
const handleChecked = () => {
onCheck(id);
};
return (
<li className="ListItem">
<label>
<input
type="checkbox"
checked={isChecked}
onChange={handleChecked}
onChange={onCheck}
disabled={isChecked}
/>
{name}
Expand Down
Empty file removed src/components/SearchForm.jsx
Empty file.
10 changes: 10 additions & 0 deletions src/utils/dates.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,13 @@ const ONE_DAY_IN_MILLISECONDS = 86400000;
export function getFutureDate(offset) {
return new Date(Date.now() + offset * ONE_DAY_IN_MILLISECONDS);
}

/**
* Get a difference of days between two dates.
* @param {Date} lastPurchase
* @param {Date} nextPurchase
* @returns {number}
*/
export function getDaysBetweenDates(lastDate, nextDate) {
return Math.abs(nextDate - lastDate) / ONE_DAY_IN_MILLISECONDS;
}
6 changes: 2 additions & 4 deletions src/views/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { createList } from '../api/firebase';
export function Home({ data, setListPath, userId, userEmail }) {
const [listName, setListName] = useState('');
const [message, setMessage] = useState('');
const navigate = useNavigate(); //to call redirected to the List view
const navigate = useNavigate();

const handleCreateListButton = async (e) => {
e.preventDefault();
Expand All @@ -22,14 +22,12 @@ export function Home({ data, setListPath, userId, userEmail }) {

const createListPath = `${userId}/${listName}}`;
setListPath(createListPath);
navigate('/list'); //redirect to the list view
navigate('/list');
} catch (error) {
//Logging and error messages if list is not created
console.error('error creating a list', error);
setMessage('Failed to create list. Please try again!');
}
};
console.log(data.length);

return (
<div className="Home">
Expand Down
1 change: 0 additions & 1 deletion src/views/Layout.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Outlet, NavLink } from 'react-router-dom';

import './Layout.css';
import { auth } from '../api/config.js';
import { SignInButton, SignOutButton, useAuth } from '../api/useAuth';
Expand Down
21 changes: 4 additions & 17 deletions src/views/List.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { ListItem } from '../components';
import { useState } from 'react';
import { updateItem } from '../api/firebase';
import { getFutureDate } from '../utils';
import { Link } from 'react-router-dom';

export function List({ data, listPath, lists }) {
const [searchItem, setSearchItem] = useState('');
// Log filtered data
console.log('Rendering List with data:', data);

const handleSearch = (e) => {
e.preventDefault();
Expand All @@ -22,23 +19,13 @@ export function List({ data, listPath, lists }) {
item.name.toLowerCase().includes(searchItem.toLocaleLowerCase()),
);

const handleCheck = async (itemId) => {
const handleCheck = async (itemData) => {
let itemId = itemData.id;
const item = data.find((item) => item.id === itemId);
const currentTime = new Date();

const newTotalPurchases = (item.totalPurchases || 0) + 1;

await updateItem(listPath, itemId, {
dateLastPurchased: currentTime,
totalPurchases: newTotalPurchases,
});

setTimeout(async () => {
await updateItem(listPath, itemId, {
dateLastPurchased: null,
totalPurchases: newTotalPurchases,
});
}, getFutureDate);
};

return (
Expand Down Expand Up @@ -88,7 +75,7 @@ export function List({ data, listPath, lists }) {
id={item.id}
name={item.name}
dateLastPurchased={item.dateLastPurchased}
onCheck={handleCheck}
onCheck={() => handleCheck(item)}
/>
))}
</ul>
Expand All @@ -101,7 +88,7 @@ export function List({ data, listPath, lists }) {
name={item.name}
id={item.id}
dateLastPurchased={item.dateLastPurchased}
onCheck={handleCheck}
onCheck={() => handleCheck(item)}
/>
))}
</ul>
Expand Down
Loading