From cb45701e9f18b70f5d467bd9b06a2d2465845577 Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 17 Dec 2024 09:10:59 -0500 Subject: [PATCH 1/3] Make PageLayout component and use it in all existing page components --- Frontend/speedcart-react/src/App.css | 6 ---- .../PageLayout/PageLayout.module.css | 5 ++++ .../src/components/PageLayout/PageLayout.tsx | 18 ++++++++++++ .../src/components/PageLayout/index.ts | 1 + .../components/StatusModal/StatusModal.tsx | 1 - .../src/pages/Dashboard/Dashboard.tsx | 19 +++++++----- .../speedcart-react/src/pages/Home/Home.tsx | 5 ++-- .../speedcart-react/src/pages/Login/Login.tsx | 29 +++++++++---------- .../NewShoppingListWithProvider.tsx | 19 +++++++----- .../ShoppingListDetailWithProvider.tsx | 24 ++++++++------- .../ShoppingListShare/ShoppingListShare.tsx | 5 ++-- 11 files changed, 79 insertions(+), 53 deletions(-) create mode 100644 Frontend/speedcart-react/src/components/PageLayout/PageLayout.module.css create mode 100644 Frontend/speedcart-react/src/components/PageLayout/PageLayout.tsx create mode 100644 Frontend/speedcart-react/src/components/PageLayout/index.ts diff --git a/Frontend/speedcart-react/src/App.css b/Frontend/speedcart-react/src/App.css index 869f0f5..3d5035d 100644 --- a/Frontend/speedcart-react/src/App.css +++ b/Frontend/speedcart-react/src/App.css @@ -15,12 +15,6 @@ body { box-sizing: border-box; } -.main-content { - flex: 1; - overflow-y: auto; /* Allow content area to scroll */ - max-height: calc(100vh - 60px); /* Adjust based on header and footer height */ -} - #policyFooter a { text-decoration: none; color: white; diff --git a/Frontend/speedcart-react/src/components/PageLayout/PageLayout.module.css b/Frontend/speedcart-react/src/components/PageLayout/PageLayout.module.css new file mode 100644 index 0000000..c3308a6 --- /dev/null +++ b/Frontend/speedcart-react/src/components/PageLayout/PageLayout.module.css @@ -0,0 +1,5 @@ +.mainContent { + flex: 1; + overflow-y: auto; /* Allow content area to scroll */ + max-height: calc(100vh - 60px); /* Adjust based on header and footer height */ +} \ No newline at end of file diff --git a/Frontend/speedcart-react/src/components/PageLayout/PageLayout.tsx b/Frontend/speedcart-react/src/components/PageLayout/PageLayout.tsx new file mode 100644 index 0000000..62411de --- /dev/null +++ b/Frontend/speedcart-react/src/components/PageLayout/PageLayout.tsx @@ -0,0 +1,18 @@ +// src/components/PageLayout.tsx +import React from 'react'; +import StatusModal from '@components/StatusModal'; + +import styles from './PageLayout.module.css'; + +const PageLayout = ({ children, status = null, showStatusModal = false, modalProps = null, className=''}) => { + return ( + <> +
+ {children} +
+ {showStatusModal && } + + ); +}; + +export default PageLayout; diff --git a/Frontend/speedcart-react/src/components/PageLayout/index.ts b/Frontend/speedcart-react/src/components/PageLayout/index.ts new file mode 100644 index 0000000..cb4f878 --- /dev/null +++ b/Frontend/speedcart-react/src/components/PageLayout/index.ts @@ -0,0 +1 @@ +export { default } from './PageLayout'; \ No newline at end of file diff --git a/Frontend/speedcart-react/src/components/StatusModal/StatusModal.tsx b/Frontend/speedcart-react/src/components/StatusModal/StatusModal.tsx index 0d39e2f..c92f472 100644 --- a/Frontend/speedcart-react/src/components/StatusModal/StatusModal.tsx +++ b/Frontend/speedcart-react/src/components/StatusModal/StatusModal.tsx @@ -1,4 +1,3 @@ -// src/components/StatusModal.js import React, { useEffect, useState } from 'react'; import styles from './StatusModal.module.css'; import { RequestStatus } from '@constants/enums'; diff --git a/Frontend/speedcart-react/src/pages/Dashboard/Dashboard.tsx b/Frontend/speedcart-react/src/pages/Dashboard/Dashboard.tsx index 62c983c..24b5a29 100644 --- a/Frontend/speedcart-react/src/pages/Dashboard/Dashboard.tsx +++ b/Frontend/speedcart-react/src/pages/Dashboard/Dashboard.tsx @@ -4,12 +4,12 @@ import { Link } from 'react-router-dom'; import { FaTrash, FaEdit, FaShare, FaClipboard } from 'react-icons/fa'; import { useAuth, fetchOwnedShoppingLists, fetchSharedShoppingLists, deleteShoppingList, createShareLink, AuthContextType } from 'shared'; import Modal from '@components/Modal'; -import StatusModal from '@components/StatusModal'; import CustomCheckbox from '@components/CustomCheckbox'; import { RequestStatus } from '@constants/enums'; import styles from './Dashboard.module.css'; +import PageLayout from '@components/PageLayout'; function Dashboard() { const [shoppingListTitles, setShoppingListTitles] = useState([]); @@ -181,7 +181,15 @@ function Dashboard() { return ( <> -
+
-
- + ); } diff --git a/Frontend/speedcart-react/src/pages/Home/Home.tsx b/Frontend/speedcart-react/src/pages/Home/Home.tsx index 3ca2e94..e80693d 100644 --- a/Frontend/speedcart-react/src/pages/Home/Home.tsx +++ b/Frontend/speedcart-react/src/pages/Home/Home.tsx @@ -9,6 +9,7 @@ import adaptabilityImage from '@assets/images/freshProduce.jpg'; // Image from: import reusabilityImage from '@assets/images/phoneAndLaptop.jpg';// Image from: https://unsplash.com/photos/silver-iphone-6-on-macbook-pro--aC2BL0GICs import styles from './Home.module.css'; +import PageLayout from '@components/PageLayout'; const Home: React.FC = (props) => { @@ -17,7 +18,7 @@ const Home: React.FC = (props) => { }, []); return ( -
+

Welcome to SpeedCart

@@ -74,7 +75,7 @@ const Home: React.FC = (props) => {

-
+ ); } diff --git a/Frontend/speedcart-react/src/pages/Login/Login.tsx b/Frontend/speedcart-react/src/pages/Login/Login.tsx index 077d5dc..a4f4322 100644 --- a/Frontend/speedcart-react/src/pages/Login/Login.tsx +++ b/Frontend/speedcart-react/src/pages/Login/Login.tsx @@ -4,12 +4,11 @@ import { GoogleLogin } from '@react-oauth/google'; import { useAuth } from 'shared'; -import StatusModal from '@components/StatusModal'; - import { RequestStatus } from '@constants/enums'; import { AppRoute } from '@constants/routes'; import styles from './Login.module.css'; +import PageLayout from '@components/PageLayout'; function Login() { const navigate = useNavigate(); @@ -56,26 +55,26 @@ function Login() { }; return ( - <> -
+ +
{isAuthenticated ? ( - <> - - - + ) : ( )} -
- - + + ); } diff --git a/Frontend/speedcart-react/src/pages/NewShoppingListWithProvider/NewShoppingListWithProvider.tsx b/Frontend/speedcart-react/src/pages/NewShoppingListWithProvider/NewShoppingListWithProvider.tsx index b9cdca3..2dfc6b9 100644 --- a/Frontend/speedcart-react/src/pages/NewShoppingListWithProvider/NewShoppingListWithProvider.tsx +++ b/Frontend/speedcart-react/src/pages/NewShoppingListWithProvider/NewShoppingListWithProvider.tsx @@ -4,7 +4,6 @@ import { useAuth, AuthContextType } from 'shared'; import SaveButton from '@components/SaveButton'; import AddShoppingListItemButton from '@components/AddShoppingListItemButton'; -import StatusModal from '@components/StatusModal'; // Import StatusModal to provide UI info on list save status import ShoppingListSection from '@components/ShoppingListSection'; import { ShoppingListProvider, useShoppingListContext } from '@customHooks/ShoppingListContext'; @@ -14,6 +13,7 @@ import { CrudMode } from '@constants/crudmodes'; import styles from './NewShoppingListWithProvider.module.css'; import inputStyles from '@modularStyles/inputs.module.css'; +import PageLayout from '@components/PageLayout'; const NewShoppingList: React.FC = () => { const navigate = useNavigate(); @@ -71,7 +71,15 @@ const NewShoppingList: React.FC = () => { return ( <> -
+
@@ -103,12 +111,7 @@ const NewShoppingList: React.FC = () => { crudMode={crudMode} /> -
- + ); }; diff --git a/Frontend/speedcart-react/src/pages/ShoppingListDetailWithProvider/ShoppingListDetailWithProvider.tsx b/Frontend/speedcart-react/src/pages/ShoppingListDetailWithProvider/ShoppingListDetailWithProvider.tsx index 015bbd1..7b74836 100644 --- a/Frontend/speedcart-react/src/pages/ShoppingListDetailWithProvider/ShoppingListDetailWithProvider.tsx +++ b/Frontend/speedcart-react/src/pages/ShoppingListDetailWithProvider/ShoppingListDetailWithProvider.tsx @@ -1,5 +1,4 @@ import React, { useEffect, useState } from 'react'; -import { v4 as uuidv4 } from 'uuid'; // Import uuid library for unique item identification import { useParams } from 'react-router-dom'; import { @@ -9,7 +8,6 @@ import { import SaveButton from '@components/SaveButton'; import AddShoppingListItemButton from '@components/AddShoppingListItemButton'; -import StatusModal from '@components/StatusModal'; import ShoppingListSection from '@components/ShoppingListSection'; import { ShoppingListProvider, useShoppingListContext } from '@customHooks/ShoppingListContext'; @@ -19,6 +17,7 @@ import { RequestStatus } from '@constants/enums'; // CSS style imports import inputStyles from '@modularStyles/inputs.module.css'; import styles from './ShoppingListDetailWithProvider.module.css'; +import PageLayout from '@components/PageLayout'; const ShoppingListDetail = () => { const { id } = useParams() as { id: string }; @@ -141,16 +140,24 @@ const ShoppingListDetail = () => { }; if (loading) { - return
Loading...
; + return Loading...; } if (error) { - return
Error: {error}
; + return Error: {error}; } return ( <> -
+
-
- + ); }; diff --git a/Frontend/speedcart-react/src/pages/ShoppingListShare/ShoppingListShare.tsx b/Frontend/speedcart-react/src/pages/ShoppingListShare/ShoppingListShare.tsx index e62602e..e37641f 100644 --- a/Frontend/speedcart-react/src/pages/ShoppingListShare/ShoppingListShare.tsx +++ b/Frontend/speedcart-react/src/pages/ShoppingListShare/ShoppingListShare.tsx @@ -5,6 +5,7 @@ import { GoogleLogin } from '@react-oauth/google'; import { useAuth, createSharingPermissions } from 'shared'; import { AppRoute } from "@constants/routes"; +import PageLayout from "@components/PageLayout"; function ShoppingListShare() { @@ -81,7 +82,7 @@ function ShoppingListShare() { }; return ( -
+ {/* Make sure user is signed in */} {!isAuthenticated ? ( <> @@ -96,7 +97,7 @@ function ShoppingListShare() { {shareInteractionStatus} )} -
+ ); } From a07efbf6110b1fbc18bdd7495b25237898d82746 Mon Sep 17 00:00:00 2001 From: Cameron Green Date: Thu, 19 Dec 2024 19:09:29 -0500 Subject: [PATCH 2/3] Make adjustable styling of CustomCheckbox component for better modularity and reuse across different components --- .../CustomCheckbox/CustomCheckbox.module.css | 15 ++++++++++++--- .../components/CustomCheckbox/CustomCheckbox.tsx | 6 +++--- .../src/pages/Dashboard/Dashboard.tsx | 6 +++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Frontend/speedcart-react/src/components/CustomCheckbox/CustomCheckbox.module.css b/Frontend/speedcart-react/src/components/CustomCheckbox/CustomCheckbox.module.css index cd14b6c..9a98351 100644 --- a/Frontend/speedcart-react/src/components/CustomCheckbox/CustomCheckbox.module.css +++ b/Frontend/speedcart-react/src/components/CustomCheckbox/CustomCheckbox.module.css @@ -1,13 +1,19 @@ .labelContainer { - display: flex; align-items: center; /* Vertically center the checkbox and label */ - justify-content: center; /* Horizontally center the checkbox and label */ position: relative; cursor: pointer; user-select: none; text-align: center; /* Ensures text is also centered if used */ } +.flex { + display: flex; +} + +.inlineFlex { + display: inline-flex; +} + .input { position: absolute; opacity: 0; @@ -22,12 +28,15 @@ width: 16px; background-color: #eee; border-radius: 4px; - margin-right: 8px; display: flex; /* Use flex to center the checkmark visually */ align-items: center; /* Vertical center */ justify-content: center; /* Horizontal center */ } +.marginRightDistance { + margin-right: 8px; +} + .labelContainer:hover .checkmark { background-color: #ccc; } diff --git a/Frontend/speedcart-react/src/components/CustomCheckbox/CustomCheckbox.tsx b/Frontend/speedcart-react/src/components/CustomCheckbox/CustomCheckbox.tsx index 7310ad3..0970938 100644 --- a/Frontend/speedcart-react/src/components/CustomCheckbox/CustomCheckbox.tsx +++ b/Frontend/speedcart-react/src/components/CustomCheckbox/CustomCheckbox.tsx @@ -1,9 +1,9 @@ import React from 'react'; import styles from './CustomCheckbox.module.css'; -const CustomCheckbox = ({ name = '', className = '', checked = false, onChange = null, disabled = false, children = null}) => { +const CustomCheckbox = ({ name = '', className = '', flexType = 'inlineFlex', checked = false, onChange = null, disabled = false, children = null}) => { return ( -