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

refactor/feat: app structure and add confirmation dialog for sign-out #8

Merged
merged 4 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,3 @@
flex: 1;
padding-bottom: 56px; /* Space for the bottom navigation */
}

.bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 10; /* Ensure it's above other elements */
}
34 changes: 6 additions & 28 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
import { useState } from 'react';
import { Link, Route, BrowserRouter as Router, Routes } from 'react-router-dom';
import { Route, BrowserRouter as Router, Routes } from 'react-router-dom';

import FlagIcon from '@mui/icons-material/Flag';
import HomeIcon from '@mui/icons-material/Home';
import BottomNavigation from '@mui/material/BottomNavigation';
import BottomNavigationAction from '@mui/material/BottomNavigationAction';
import { ThemeProvider } from '@mui/material/styles';
import { theme } from '@utils/theme';

import Home from './pages/Home';
import Home from '@pages/Home';
import Streak from '@pages/Streak';

import Footer from '@components/common/Footer';
import Header from '@components/common/Header';
import { UserProvider } from '@contexts/UserContext';
import './App.css';

const App = () => {
const [value, setValue] = useState(0);

return (
<ThemeProvider theme={theme}>
<UserProvider>
<div className="App">
<Router>
<Header />
<div className="content">
<Header />
{/* Main content area where pages will render */}
<Routes>
<Route path="/" element={<Home />} />
Expand All @@ -32,22 +27,7 @@ const App = () => {
</div>

{/* Bottom Navigation with React Router links */}
<BottomNavigation
className="bottom-nav"
value={value}
onChange={(event, newValue) => {
setValue(newValue);
}}
showLabels
>
<BottomNavigationAction label="Home" icon={<HomeIcon />} component={Link} to="/" />
<BottomNavigationAction
label="Steak"
icon={<FlagIcon />}
component={Link}
to="/streak"
/>
</BottomNavigation>
<Footer />
</Router>
</div>
</UserProvider>
Expand All @@ -56,5 +36,3 @@ const App = () => {
};

export default App;

const Streak = () => <h1>Streak</h1>;
26 changes: 26 additions & 0 deletions src/components/common/ConfirmSignOutDialog.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useUser } from '@contexts/UserContext';
import { Button, Dialog, DialogActions, DialogTitle } from '@mui/material';

const ConfirmSignOutDialog = ({ open, onClose }) => {
const { handleSignOut } = useUser();

// Function to confirm sign out
const confirmSignOut = async () => {
await handleSignOut();
onClose();
};

return (
<Dialog open={open} onClose={onClose}>
<DialogTitle>Confirm Sign Out</DialogTitle>
<DialogActions>
<Button onClick={onClose}>Cancel</Button>
<Button onClick={confirmSignOut} color="error">
Sign Out
</Button>
</DialogActions>
</Dialog>
);
};

export default ConfirmSignOutDialog;
39 changes: 39 additions & 0 deletions src/components/common/Footer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import FlagIcon from '@mui/icons-material/Flag';
import HomeIcon from '@mui/icons-material/Home';
import { BottomNavigation, BottomNavigationAction } from '@mui/material';
import { Link, useLocation } from 'react-router-dom';

export default function Footer() {
const location = useLocation();

// Get the index of the page based on the path
const getPageIndex = (path) => {
switch (path) {
case '/':
return 0;
case '/streak':
return 1;
default:
return 0;
}
};

return (
<BottomNavigation
className="bottom-nav"
value={getPageIndex(location.pathname)}
showLabels
sx={{
backgroundColor: 'primary.light',
position: 'fixed',
bottom: 0,
left: 0,
right: 0,
zIndex: 1000, // Ensure the footer is always on top
}}
>
<BottomNavigationAction label="Home" icon={<HomeIcon />} component={Link} to="/" />
<BottomNavigationAction label="Streak" icon={<FlagIcon />} component={Link} to="/streak" />
</BottomNavigation>
);
}
51 changes: 35 additions & 16 deletions src/components/common/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
import { useUser } from '@contexts/UserContext';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import { AppBar, Avatar, Box, Button, IconButton, Toolbar, Typography } from '@mui/material';
import { useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import ConfirmSignOutDialog from './ConfirmSignOutDialog';

const Header = () => {
const { user, handleSignIn, handleSignOut } = useUser();
const { user, handleSignIn } = useUser();
const location = useLocation();
const navigate = useNavigate();

const handleAuthClick = async () => {
if (user) {
await handleSignOut();
} else {
await handleSignIn();
}
};
// State for Dialog visibility
const [openConfirmDialog, setOpenConfirmDialog] = useState(false);

// Show back button only on pages other than Home and Streak
const showBackButton = location.pathname !== '/' && location.pathname !== '/streak';

return (
<AppBar position="sticky" sx={{ backgroundColor: 'primary.light', color: '#000' }}>
<Toolbar sx={{ position: 'relative', justifyContent: 'space-between' }}>
<Toolbar sx={{ justifyContent: 'space-between', position: 'relative' }}>
<Box sx={{ display: 'flex', alignItems: 'center' }}>
{/* Placeholder Box for back button if needed in the future */}
<Box sx={{ width: '48px' }} />
{showBackButton && (
<IconButton
edge="start"
color="inherit"
onClick={() => navigate(-1)} // Back button
>
<ArrowBackIcon />
</IconButton>
)}
</Box>

<Typography
Expand All @@ -26,7 +37,7 @@ const Header = () => {
position: 'absolute',
left: '50%',
transform: 'translateX(-50%)',
fontWeight: '600',
fontWeight: 600,
fontSize: '1.4rem',
}}
>
Expand All @@ -35,11 +46,19 @@ const Header = () => {

<Box sx={{ display: 'flex', alignItems: 'center' }}>
{user ? (
<IconButton edge="end" color="inherit" onClick={handleAuthClick}>
<Avatar alt={user.displayName} src={user.photoURL} />
</IconButton>
<>
<IconButton edge="end" color="inherit" onClick={() => setOpenConfirmDialog(true)}>
<Avatar alt={user.displayName} src={user.photoURL} />
</IconButton>

{/* Dialog for Confirm Sign Out */}
<ConfirmSignOutDialog
open={openConfirmDialog}
onClose={() => setOpenConfirmDialog(false)}
/>
</>
) : (
<Button color="inherit" onClick={handleAuthClick}>
<Button color="inherit" onClick={handleSignIn}>
Sign In
</Button>
)}
Expand Down
11 changes: 11 additions & 0 deletions src/pages/Streak.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Box } from '@mui/material';

const Streak = () => {
return (
<Box sx={{ justifyContent: 'center', display: 'flex' }}>
<h1>Streak</h1>
</Box>
);
};

export default Streak;
Loading