add handling of no stores and fix app naming
All checks were successful
Build & Deploy Costco Grocery List / build (push) Successful in 11s
Build & Deploy Costco Grocery List / verify-images (push) Successful in 2s
Build & Deploy Costco Grocery List / deploy (push) Successful in 5s
Build & Deploy Costco Grocery List / notify (push) Successful in 1s
All checks were successful
Build & Deploy Costco Grocery List / build (push) Successful in 11s
Build & Deploy Costco Grocery List / verify-images (push) Successful in 2s
Build & Deploy Costco Grocery List / deploy (push) Successful in 5s
Build & Deploy Costco Grocery List / notify (push) Successful in 1s
This commit is contained in:
parent
e9b678c7be
commit
dfaab1dfcb
@ -1,12 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Costco Grocery List</title>
|
||||
<title>Grocery App</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -1,4 +1,5 @@
|
||||
import { useCallback, useContext, useEffect, useMemo, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
addItem,
|
||||
getClassification,
|
||||
@ -30,13 +31,16 @@ import { findSimilarItems } from "../utils/stringSimilarity";
|
||||
|
||||
|
||||
export default function GroceryList() {
|
||||
const pageTitle = "Grocery List";
|
||||
const { role: systemRole } = useContext(AuthContext);
|
||||
const { activeHousehold } = useContext(HouseholdContext);
|
||||
const { activeStore } = useContext(StoreContext);
|
||||
const { activeStore, stores, loading: storeLoading } = useContext(StoreContext);
|
||||
const { settings } = useContext(SettingsContext);
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Get household role for permissions
|
||||
const householdRole = activeHousehold?.role;
|
||||
const isHouseholdAdmin = householdRole === "admin";
|
||||
|
||||
// === State === //
|
||||
const [items, setItems] = useState([]);
|
||||
@ -494,13 +498,68 @@ export default function GroceryList() {
|
||||
};
|
||||
|
||||
|
||||
if (!activeHousehold || !activeStore) {
|
||||
if (!activeHousehold) {
|
||||
return (
|
||||
<div className="glist-body">
|
||||
<div className="glist-container">
|
||||
<h1 className="glist-title">Costco Grocery List</h1>
|
||||
<h1 className="glist-title">{pageTitle}</h1>
|
||||
<p style={{ textAlign: 'center', marginTop: '2rem', color: 'var(--text-secondary)' }}>
|
||||
{!activeHousehold ? 'Loading households...' : 'Loading stores...'}
|
||||
Loading households...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (storeLoading) {
|
||||
return (
|
||||
<div className="glist-body">
|
||||
<div className="glist-container">
|
||||
<h1 className="glist-title">{pageTitle}</h1>
|
||||
<p style={{ textAlign: 'center', marginTop: '2rem', color: 'var(--text-secondary)' }}>
|
||||
Loading stores...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!storeLoading && stores.length === 0) {
|
||||
return (
|
||||
<div className="glist-body">
|
||||
<div className="glist-container">
|
||||
<h1 className="glist-title">{pageTitle}</h1>
|
||||
<div className="glist-empty-state">
|
||||
<h2 className="glist-empty-title">No stores found</h2>
|
||||
<p className="glist-empty-text">
|
||||
This household doesn’t have any stores yet.
|
||||
</p>
|
||||
{isHouseholdAdmin ? (
|
||||
<button
|
||||
className="btn-primary"
|
||||
onClick={() => navigate("/manage?tab=stores")}
|
||||
>
|
||||
Go to Manage Stores
|
||||
</button>
|
||||
) : (
|
||||
<p className="glist-empty-text">
|
||||
Please notify a household admin to add a store.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!activeStore) {
|
||||
return (
|
||||
<div className="glist-body">
|
||||
<div className="glist-container">
|
||||
<h1 className="glist-title">{pageTitle}</h1>
|
||||
<StoreTabs />
|
||||
<p style={{ textAlign: 'center', marginTop: '2rem', color: 'var(--text-secondary)' }}>
|
||||
Loading stores...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -511,7 +570,7 @@ export default function GroceryList() {
|
||||
return (
|
||||
<div className="glist-body">
|
||||
<div className="glist-container">
|
||||
<h1 className="glist-title">Costco Grocery List</h1>
|
||||
<h1 className="glist-title">{pageTitle}</h1>
|
||||
<StoreTabs />
|
||||
<p style={{ textAlign: 'center', marginTop: '2rem' }}>Loading grocery list...</p>
|
||||
</div>
|
||||
@ -523,7 +582,7 @@ export default function GroceryList() {
|
||||
return (
|
||||
<div className="glist-body">
|
||||
<div className="glist-container">
|
||||
<h1 className="glist-title">Costco Grocery List</h1>
|
||||
<h1 className="glist-title">{pageTitle}</h1>
|
||||
|
||||
<StoreTabs />
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { useContext, useState } from "react";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import ManageHousehold from "../components/manage/ManageHousehold";
|
||||
import ManageStores from "../components/manage/ManageStores";
|
||||
import { HouseholdContext } from "../context/HouseholdContext";
|
||||
@ -7,6 +8,14 @@ import "../styles/pages/Manage.css";
|
||||
export default function Manage() {
|
||||
const { activeHousehold } = useContext(HouseholdContext);
|
||||
const [activeTab, setActiveTab] = useState("household");
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
useEffect(() => {
|
||||
const tab = searchParams.get("tab");
|
||||
if (tab === "household" || tab === "stores") {
|
||||
setActiveTab(tab);
|
||||
}
|
||||
}, [searchParams]);
|
||||
|
||||
if (!activeHousehold) {
|
||||
return (
|
||||
|
||||
@ -64,6 +64,31 @@
|
||||
padding-top: var(--spacing-md);
|
||||
}
|
||||
|
||||
/* Empty State */
|
||||
.glist-empty-state {
|
||||
margin: var(--spacing-xl) auto;
|
||||
padding: var(--spacing-lg);
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-md);
|
||||
max-width: 32rem;
|
||||
border: var(--border-width-thin) dashed var(--color-border-medium);
|
||||
border-radius: var(--border-radius-lg);
|
||||
background: var(--color-bg-surface);
|
||||
}
|
||||
|
||||
.glist-empty-title {
|
||||
font-size: var(--font-size-lg);
|
||||
color: var(--color-text-primary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.glist-empty-text {
|
||||
color: var(--color-text-secondary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.glist-section-header .glist-section-title {
|
||||
margin: 0;
|
||||
border: none;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user