Skip to content

Commit 6e10f2b

Browse files
Merge pull request #71 from the-collab-lab/nk-use-urgency
[ISSUE 13] - view shopping list items in order of how soon they to need to be bought again
2 parents 8a12ee5 + 9bc640c commit 6e10f2b

21 files changed

+337
-77
lines changed

.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"settings": { "react": { "version": "detect" } },
1616
"rules": {
1717
"no-duplicate-imports": "warn",
18-
"no-unused-vars": "warn",
18+
"no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
1919
"react/jsx-filename-extension": [1, { "allow": "as-needed" }],
2020
"react/prop-types": "off",
2121
"react/jsx-no-target-blank": "off"

src/App.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
22

33
import { Home, Layout, List, ManageList } from './views';
44

5-
import { useAuth, useShoppingListData, useShoppingLists } from './api';
5+
import { useAuth, useShoppingListData, useStateWithStorage } from './hooks';
6+
import { useShoppingLists } from './api';
67

7-
import { useStateWithStorage } from './hooks';
88
import { ToastContainer } from 'react-toastify';
99
import 'react-toastify/dist/ReactToastify.css';
1010

src/api/firebase.js

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -49,50 +49,6 @@ export function useShoppingLists(userId, userEmail) {
4949
return data;
5050
}
5151

52-
// const removeFromShoppingLists = (listPath, listName) => {
53-
54-
// }
55-
56-
/**
57-
* A custom hook that subscribes to a shopping list in our Firestore database
58-
* and returns new data whenever the list changes.
59-
* @param {string | null} listPath
60-
* @see https://firebase.google.com/docs/firestore/query-data/listen
61-
*/
62-
export function useShoppingListData(listPath) {
63-
// Start with an empty array for our data.
64-
/** @type {import('firebase/firestore').DocumentData[]} */
65-
const initialState = [];
66-
const [data, setData] = useState(initialState);
67-
68-
useEffect(() => {
69-
if (!listPath) return;
70-
71-
// When we get a listPath, we use it to subscribe to real-time updates
72-
// from Firestore.
73-
return onSnapshot(collection(db, listPath, 'items'), (snapshot) => {
74-
// The snapshot is a real-time update. We iterate over the documents in it
75-
// to get the data.
76-
const nextData = snapshot.docs.map((docSnapshot) => {
77-
// Extract the document's data from the snapshot.
78-
const item = docSnapshot.data();
79-
80-
// The document's id is not in the data,
81-
// but it is very useful, so we add it to the data ourselves.
82-
item.id = docSnapshot.id;
83-
84-
return item;
85-
});
86-
87-
// Update our React state with the new data.
88-
setData(nextData);
89-
});
90-
}, [listPath]);
91-
92-
// Return the data so it can be used by our React components.
93-
return data;
94-
}
95-
9652
/**
9753
* Add a new user to the users collection in Firestore.
9854
* @param {Object} user The user object from Firebase Auth.

src/api/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
export * from './firebase';
2-
export { useAuth } from './useAuth';

src/components/ListItem.jsx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,43 @@ import { DeleteIconWithTooltip, tooltipStyle } from './DeleteIconWithTooltip';
88
import {
99
ListItem as MaterialListItem,
1010
Tooltip,
11+
IconButton,
1112
ListItemButton,
1213
ListItemIcon,
1314
ListItemText,
1415
Checkbox,
1516
} from '@mui/material';
17+
import {
18+
Restore as OverdueIcon,
19+
RestartAlt as SoonIcon,
20+
RadioButtonUnchecked as KindOfSoonIcon,
21+
RemoveCircle as NotSoonIcon,
22+
RadioButtonChecked as InactiveIcon,
23+
} from '@mui/icons-material';
1624

1725
import './ListItem.css';
1826

1927
const currentDate = new Date();
2028

29+
const urgencyStatusIcons = {
30+
overdue: OverdueIcon,
31+
soon: SoonIcon,
32+
kindOfSoon: KindOfSoonIcon,
33+
notSoon: NotSoonIcon,
34+
inactive: InactiveIcon,
35+
};
36+
37+
const urgencyStatusStyle = {
38+
fontSize: '2.5rem',
39+
color: 'white',
40+
};
41+
42+
const toolTipStyle = {
43+
fontSize: '1.5rem',
44+
marginBlockStart: '0',
45+
marginBlockEnd: '0',
46+
};
47+
2148
const calculateIsPurchased = (dateLastPurchased) => {
2249
if (!dateLastPurchased) {
2350
return false;
@@ -30,7 +57,7 @@ const calculateIsPurchased = (dateLastPurchased) => {
3057
return currentDate < oneDayLater;
3158
};
3259

33-
export function ListItem({ item, listPath }) {
60+
export function ListItem({ item, listPath, itemUrgencyStatus }) {
3461
const { open, isOpen, toggleDialog } = useConfirmDialog();
3562
const [isPurchased, setIsPurchased] = useState(() =>
3663
calculateIsPurchased(item.dateLastPurchased),
@@ -69,6 +96,8 @@ export function ListItem({ item, listPath }) {
6996
return;
7097
};
7198

99+
const UrgencyStatusIcon = urgencyStatusIcons[itemUrgencyStatus];
100+
72101
const props = {
73102
handleDelete: handleDeleteItem,
74103
title: `Are you sure you want to delete ${name}?`,
@@ -84,6 +113,17 @@ export function ListItem({ item, listPath }) {
84113
<>
85114
{open && <ConfirmDialog props={props} />}
86115
<MaterialListItem className="ListItem">
116+
{UrgencyStatusIcon && (
117+
<Tooltip
118+
title={<p style={toolTipStyle}>{itemUrgencyStatus}</p>}
119+
placement="left"
120+
arrow
121+
>
122+
<IconButton aria-label={itemUrgencyStatus}>
123+
<UrgencyStatusIcon sx={urgencyStatusStyle} fontSize="large" />
124+
</IconButton>
125+
</Tooltip>
126+
)}
87127
<ListItemButton role={undefined} onClick={handleChange} dense>
88128
<ListItemIcon>
89129
<Tooltip

src/components/RadioInputElement.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export function RadioInputElement({ label, id, value, required }) {
1+
export const RadioInputElement = ({ label, id, value, required }) => {
22
return (
33
<>
44
<input
@@ -12,4 +12,4 @@ export function RadioInputElement({ label, id, value, required }) {
1212
<br />
1313
</>
1414
);
15-
}
15+
};

src/components/ShareList.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { shareList, useAuth } from '../api';
2-
import { useStateWithStorage } from '../hooks';
1+
import { shareList } from '../api';
2+
import { useStateWithStorage, useAuth } from '../hooks';
33
import { TextInputElement } from './index.js';
44
import { toast } from 'react-toastify';
55

src/components/SingleList.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { useState } from 'react';
33
import { toast } from 'react-toastify';
44
import { PushPin, PushPinOutlined } from '@mui/icons-material';
55
import { Tooltip, IconButton, Button } from '@mui/material';
6-
import { useAuth, deleteList } from '../api';
6+
import { deleteList } from '../api';
7+
import { useAuth } from '../hooks';
78
import { useConfirmDialog } from '../hooks/useConfirmDialog';
89
import { ConfirmDialog } from './ConfirmDialog';
910
import { tooltipStyle, DeleteIconWithTooltip } from './DeleteIconWithTooltip';

src/hooks/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
export * from './useAuth';
2+
export * from './useUrgency';
13
export * from './useEnsureListPath';
2-
export * from './useImportance';
34
export * from './useStateWithStorage';
5+
export * from './useShoppingListData';
6+
export * from './useImportance';
47
export * from './useConfirmDialog';

src/api/useAuth.jsx renamed to src/hooks/useAuth.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect, useState } from 'react';
2-
import { auth } from './config.js';
2+
import { auth } from '../api/config.js';
33
import { GoogleAuthProvider, signInWithPopup } from 'firebase/auth';
4-
import { addUserToDatabase } from './firebase.js';
4+
import { addUserToDatabase } from '../api/firebase.js';
55

66
/**
77
* A button that signs the user in using Google OAuth. When clicked,

0 commit comments

Comments
 (0)